public async Task when_httpClient_throw_exception_it_should_log_an_error()
        {
            _searchApiOptionsMock.Setup(x => x.Value).Returns(new SearchApiOptions().AddWebHook("test", "http://test:1234"));

            var handlerMock = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            handlerMock
            .Protected()
            // Setup the PROTECTED method to mock
            .Setup <Task <HttpResponseMessage> >(
                "SendAsync",
                ItExpr.IsAny <HttpRequestMessage>(),
                ItExpr.IsAny <CancellationToken>()
                )
            .Throws(new Exception("unknown error"))
            .Verifiable();

            var httpClient = new HttpClient(handlerMock.Object);

            _sut = new WebHookNotifierSearchEventStatus(httpClient, _searchApiOptionsMock.Object, _loggerMock.Object, _cacheServiceMock.Object);

            await _sut.NotifyEventAsync(fakePersonSearchStatus.SearchRequestId, new FakePersonSearchAdapterEvent(), "Accepted", CancellationToken.None);

            _loggerMock.VerifyLog(LogLevel.Error, "The webHook PersonSearch notification failed for status Accepted for test webHook. [unknown error]", "failed log error");
        }
        public async Task it_should_log_error_when_not_uri()
        {
            _searchApiOptionsMock.Setup(x => x.Value).Returns(new SearchApiOptions()
                                                              .AddWebHook("test", "not_uri"));

            var handlerMock = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            handlerMock
            .Protected()
            // Setup the PROTECTED method to mock
            .Setup <Task <HttpResponseMessage> >(
                "SendAsync",
                ItExpr.IsAny <HttpRequestMessage>(),
                ItExpr.IsAny <CancellationToken>()
                )
            // prepare the expected response of the mocked http call
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.BadRequest,
                Content    = new StringContent("worked!"),
            })
            .Verifiable();

            var httpClient = new HttpClient(handlerMock.Object);

            _sut = new WebHookNotifierSearchEventStatus(httpClient, _searchApiOptionsMock.Object, _loggerMock.Object, _cacheServiceMock.Object);

            await _sut.NotifyEventAsync(fakePersonSearchStatus.SearchRequestId, fakePersonSearchStatus, "Accepted", CancellationToken.None);

            _loggerMock.VerifyLog(LogLevel.Warning, $"The webHook PersonSearch notification uri is not established or is not an absolute Uri for test. Set the WebHook.Uri value on SearchApi.WebHooks settings.", "log warning failed");
        }
        public async Task it_should_send_notification_to_all_subscribers()
        {
            _searchApiOptionsMock.Setup(x => x.Value).Returns(new SearchApiOptions()
                                                              .AddWebHook("test", "http://test:1234")
                                                              .AddWebHook("test2", "http://test:5678"));

            var handlerMock = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            handlerMock
            .Protected()
            // Setup the PROTECTED method to mock
            .Setup <Task <HttpResponseMessage> >(
                "SendAsync",
                ItExpr.IsAny <HttpRequestMessage>(),
                ItExpr.IsAny <CancellationToken>()
                )
            // prepare the expected response of the mocked http call
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.OK,
                Content    = new StringContent("worked!"),
            })
            .Verifiable();

            var httpClient = new HttpClient(handlerMock.Object);

            _sut = new WebHookNotifierSearchEventStatus(httpClient, _searchApiOptionsMock.Object, _loggerMock.Object, _cacheServiceMock.Object);

            await _sut.NotifyEventAsync(fakePersonSearchStatus.SearchRequestId, fakePersonSearchStatus, "Accepted", CancellationToken.None);

            //
            var expectedUri  = new Uri($"http://test:1234/Accepted/{fakePersonSearchStatus.SearchRequestId}");
            var expectedUri2 = new Uri($"http://test:5678/Accepted/{fakePersonSearchStatus.SearchRequestId}");

            handlerMock.Protected().Verify(
                "SendAsync",
                Times.Exactly(1),
                ItExpr.Is <HttpRequestMessage>(req =>
                                               req.Method == HttpMethod.Post &&
                                               req.RequestUri == expectedUri // to this uri
                                               ),
                ItExpr.IsAny <CancellationToken>()
                );

            handlerMock.Protected().Verify(
                "SendAsync",
                Times.Exactly(1),
                ItExpr.Is <HttpRequestMessage>(req =>
                                               req.Method == HttpMethod.Post &&
                                               req.RequestUri == expectedUri2 // to this uri
                                               ),
                ItExpr.IsAny <CancellationToken>()
                );

            _loggerMock.VerifyLog(LogLevel.Information, $"The webHook PersonSearch notification has executed status Accepted successfully for test webHook.", "failed");

            _loggerMock.VerifyLog(LogLevel.Information, $"The webHook PersonSearch notification has executed status Accepted successfully for test2 webHook.", "failed");
        }
        public async Task finalized_it_should_send_zero_notification_to_one_subscribers_when_not_all_dp_completed()
        {
            _searchApiOptionsMock.Setup(x => x.Value).Returns(new SearchApiOptions().AddWebHook("test", "http://test:1234"));

            _cacheServiceMock.Setup(x => x.GetRequest(It.IsAny <Guid>())).Returns(Task.FromResult(_notAllComplete));

            var handlerMock = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            handlerMock
            .Protected()
            // Setup the PROTECTED method to mock
            .Setup <Task <HttpResponseMessage> >(
                "SendAsync",
                ItExpr.IsAny <HttpRequestMessage>(),
                ItExpr.IsAny <CancellationToken>()
                )
            // prepare the expected response of the mocked http call
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.OK,
                Content    = new StringContent("worked!"),
            })
            .Verifiable();

            var httpClient = new HttpClient(handlerMock.Object);

            _sut = new WebHookNotifierSearchEventStatus(httpClient, _searchApiOptionsMock.Object, _loggerMock.Object, _cacheServiceMock.Object);

            await _sut.NotifyEventAsync(fakePersonSearchStatus.SearchRequestId, fakePersonSearchStatus, "Finalized", CancellationToken.None);

            var expectedUri = new Uri($"http://test:1234/Finalized/{fakePersonSearchStatus.SearchRequestId}");

            handlerMock.Protected().Verify(
                "SendAsync",
                Times.Never(),
                ItExpr.Is <HttpRequestMessage>(req =>
                                               req.Method == HttpMethod.Post &&
                                               req.RequestUri.AbsoluteUri == expectedUri.AbsoluteUri // to this uri
                                               ),
                ItExpr.IsAny <CancellationToken>()
                );
        }
        public async Task when_subscriber_return_unhautorized_it_should_log_an_error()
        {
            _searchApiOptionsMock.Setup(x => x.Value).Returns(new SearchApiOptions().AddWebHook("test", "http://test:1234"));

            var handlerMock = new Mock <HttpMessageHandler>(MockBehavior.Strict);

            handlerMock
            .Protected()
            // Setup the PROTECTED method to mock
            .Setup <Task <HttpResponseMessage> >(
                "SendAsync",
                ItExpr.IsAny <HttpRequestMessage>(),
                ItExpr.IsAny <CancellationToken>()
                )
            // prepare the expected response of the mocked http call
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.Unauthorized,
                Content    = new StringContent("worked!"),
            })
            .Verifiable();

            var httpClient = new HttpClient(handlerMock.Object);

            _sut = new WebHookNotifierSearchEventStatus(httpClient, _searchApiOptionsMock.Object, _loggerMock.Object, _deepSearchServiceMock.Object);

            Assert.ThrowsAsync <Exception>(async() => await _sut.NotifyEventAsync(fakePersonSearchStatus.SearchRequestKey, fakePersonSearchStatus, "Accepted", CancellationToken.None));
            //var expectedUri = new Uri($"http://test:1234/Accepted/{fakePersonSearchStatus.SearchRequestKey}");

            //handlerMock.Protected().Verify(
            //    "SendAsync",
            //    Times.Exactly(1),
            //    ItExpr.Is<HttpRequestMessage>(req =>
            //            req.Method == HttpMethod.Post
            //            && req.RequestUri == expectedUri // to this uri
            //    ),
            //    ItExpr.IsAny<CancellationToken>()
            //);

            //_loggerMock.VerifyLog(LogLevel.Error, $"The webHook PersonSearch notification has not executed status Accepted successfully for test webHook. The error code is 401.", "failed log error");
        }