public void Dispose_Connected_TimerDisposed()
        {
            // Arrange
            SetupSolutionBinding(isConnected: true, issues: new List <SonarQubeIssue>());

            var issuesProvider = new SonarQubeIssuesProvider(mockSqService.Object, "sqKey", mockTimerFactory.Object);

            // Act
            issuesProvider.Dispose();
            issuesProvider.Dispose();
            issuesProvider.Dispose();

            // Assert
            mockTimer.Verify(x => x.Dispose(), Times.Once);
        }
        public void GetIssues_NotConnected_NoErrors()
        {
            // Arrange
            SetupSolutionBinding(isConnected: false, issues: null);

            int callCount = 0;

            // This time we want the test to pause until IsConnected is called by the inital fetch task
            mockSqService.Setup(x => x.IsConnected)
            .Returns(false)
            .Callback(() => { InitialFetchWaitHandle.Set(); callCount++; })      // signal so the test can continue
            .Verifiable();

            // 1. Initialise the class
            var issuesProvider = new SonarQubeIssuesProvider(mockSqService.Object, "sqKey",
                                                             mockTimerFactory.Object, testLogger);

            WaitForInitialFetchTaskToStart();

            // 2. Now dispose. Should stop the background fetching
            int callsBeforeDispose = callCount;

            issuesProvider.Dispose();

            // 3. Now try to fetch - should block until the background task has completed
            var issues = issuesProvider.GetSuppressedIssues("dummy guid", "dummy file path");

            issues.Should().BeEmpty();
            VerifyServiceGetIssues(Times.Never());

            // Timing: increment could have afer dispose called but before the cancellation token was set
            callCount.Should().BeLessOrEqualTo(callsBeforeDispose + 1);

            testLogger.AssertNoOutputMessages();
        }
        public void Dispose_Disconnected_TimerDisposed()
        {
            // Arrange
            SetupSolutionBinding(isConnected: true, issues: null);

            var issuesProvider = new SonarQubeIssuesProvider(mockSqService.Object, "sqKey", mockTimerFactory.Object);

            WaitForInitialFetchTaskToStart();

            // Act
            issuesProvider.Dispose();
            issuesProvider.Dispose();
            issuesProvider.Dispose();

            // Assert
            mockTimer.Verify(x => x.Dispose(), Times.Once);
        }
        public void Dispose_BoundSolution_StopsMonitoring()
        {
            // Arrange
            SetupSolutionBinding(isBound: true, isConnected: true, projectKey: "keyXXX", issues: new List <SonarQubeIssue>());

            var issuesProvider = new SonarQubeIssuesProvider(mockSqService.Object, mockTracker.Object, mockTimerFactory.Object);

            // 1. Dispose
            issuesProvider.Dispose();
            issuesProvider.Dispose();
            issuesProvider.Dispose();

            // Assert
            mockTimer.Verify(x => x.Dispose(), Times.Once);

            // 2. Check solution events are no longer being tracked
            mockSqService.ResetCalls();
            RaiseSolutionBoundEvent(true, "keyABC");
            VerifyServiceGetIssues(Times.Never());
        }