public async Task Run_should_notify_subscribers_of_completion_when_test_file_ends()
        {
            // given
            TestFileRunner runner = CreateRunner();

            var testFile = CreateTestFile(new[]
            {
                new Test()
                {
                    Url = "foo1"
                },
                new Test()
                {
                    Url = "foo2"
                },
                new Test()
                {
                    Url = "foo3"
                }
            });

            var completed = false;

            runner.Subscribe(r => { }, onCompleted: () => completed = true);

            Assume.That(completed, Is.False);

            // when
            await runner.RunAsync(testFile, "development", "bob");

            // then
            Assert.That(completed, Is.True, "Should have notified of completion.");
        }
        public async Task Run_should_notify_observers_of_existing_results()
        {
            // given
            var observedResults = new List <TestResultMessage>();

            TestFileRunner runner = CreateRunner();

            var testFile = CreateTestFile(new[]
            {
                new Test()
                {
                    Url = "foo1"
                },
                new Test()
                {
                    Url = "foo2"
                },
                new Test()
                {
                    Url = "foo3"
                }
            });

            await runner.RunAsync(testFile, "development", "bob");

            // when
            runner.Subscribe(r => { observedResults.Add(r as TestResultMessage); });

            // then
            Assert.That(observedResults.Select(r => r.TestResult.ActualUrl), Is.EquivalentTo(new[] { "foo1", "foo2", "foo3" }), "Should have observed all of the results.");
        }
        public async Task Run_should_notify_subscribers_of_result_on_error()
        {
            // given
            var httpClientMock = new Mock <IHttpClient>();

            // Throw an error.
            httpClientMock
            .Setup(c => c.ExecuteRequestAsync(It.IsAny <IRestRequest>(), new HttpLogWriter()))
            .Throws(new InvalidOperationException("Bad"));

            TestFileRunner runner = new TestFileRunner(httpClientMock.Object, GetRepositoryFactory(), new JsonConfiguration(), _capturedVariableProviderFactory.Object, GetTestFileRunnerLoggerFactory());

            var testFile = CreateTestFile(new[]
            {
                new Test()
                {
                    Url = "foo1"
                },
                new Test()
                {
                    Url = "foo2"
                },
                new Test()
                {
                    Url = "foo3"
                }
            });

            TestResultMessage capturedResult = null;

            runner.Subscribe(r =>
            {
                var item = r as TestResultMessage;
                if (item != null)
                {
                    capturedResult = item;
                }
            });

            // when
            await runner.RunAsync(testFile, "development", "bob");

            // then
            Assert.That(capturedResult, Is.Not.Null, "Should have notified of the result.");
            Assert.That(capturedResult.TestResult, Is.Not.Null, "Should have test result.");
            Assert.That(capturedResult.TestResult.ResultState, Is.EqualTo(TestResultState.Failed), "Should not have succeeded.");
        }
        public async Task Run_should_not_notify_disposed_observers_of_new_results()
        {
            // given
            var         httpClientMock = new Mock <IHttpClient>();
            IDisposable subscription   = null;

            httpClientMock.Setup(c => c.CreateRestRequest(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IEnumerable <HeaderItem> >()));

            // Dispose of the subscription before processing the third request.
            httpClientMock
            .Setup(c => c.CreateRestRequest(It.IsAny <string>(), "http://foo3", It.IsAny <string>(), It.IsAny <IEnumerable <HeaderItem> >()))
            .Callback(() => { subscription?.Dispose(); });

            httpClientMock
            .Setup(c => c.ExecuteRequestAsync(It.IsAny <IRestRequest>(), It.IsAny <HttpLogWriter>()))
            .Returns(Task.FromResult(new HttpResponse()));

            TestFileRunner runner = new TestFileRunner(httpClientMock.Object, GetRepositoryFactory(), new JsonConfiguration(), _capturedVariableProviderFactory.Object, GetTestFileRunnerLoggerFactory());

            var testFile = CreateTestFile(new[]
            {
                new Test()
                {
                    Url = "http://foo1"
                },
                new Test()
                {
                    Url = "http://foo2"
                },
                new Test()
                {
                    Url = "http://foo3"
                }
            });

            var observedResults = new List <TestResultMessage>();

            // when
            subscription = runner.Subscribe(r => { observedResults.Add(r as TestResultMessage); });

            await runner.RunAsync(testFile, "development", "bob");

            // then
            Assert.That(observedResults.Select(r => r.TestResult.ActualUrl), Is.EquivalentTo(new[] { "http://foo1", "http://foo2" }), "Should not have included the result after having been disposed.");
        }
        public async Task Run_should_notify_observers_of_new_results()
        {
            // given
            TestFileRunner runner = CreateRunner();

            var testFile = CreateTestFile(new[]
            {
                new Test()
                {
                    Url = "foo1"
                },
                new Test()
                {
                    Url = "foo2"
                },
                new Test()
                {
                    Url = "foo3"
                }
            });

            var observedResults = new List <TestResultMessage>();

            // when
            runner.Subscribe(r =>
            {
                var item = r as TestResultMessage;
                if (item != null)
                {
                    observedResults.Add(item);
                }
            });

            await runner.RunAsync(testFile, "development", "bob");

            // then
            string[] result = observedResults.Select(r => r.TestResult.ActualUrl).ToArray();
            Assert.That(result, Is.EquivalentTo(new[] { "foo1", "foo2", "foo3" }), "Should have observed all of the results.");
        }
        public async Task Run_should_notify_observers_of_completion()
        {
            // given
            TestFileRunner runner = CreateRunner();

            var testFile = CreateTestFile(new[]
            {
                new Test()
                {
                    Url = "foo1"
                },
                new Test()
                {
                    Url = "foo2"
                },
                new Test()
                {
                    Url = "foo3"
                }
            });

            var observedResults = new List <TestFileGuidMessage>();

            // when
            runner.Subscribe(r =>
            {
                var item = r as TestFileGuidMessage;
                if (item != null)
                {
                    observedResults.Add(item);
                }
            });

            await runner.RunAsync(testFile, "development", "bob");

            // then
            Assert.That(observedResults.Count, Is.EqualTo(1), "Should have observed completion message.");
        }