public void BusResponseSolutionContainsErrors_ErrorsAreLogged_ExceptionIsRaised()
        {
            var key = _orgA1;

            const string mockError        = "mock error";
            const string eventDescription = "Bus response contained errors.";

            _requestStoreMock.Setup(x => x.PublishAndWaitForResponse(
                                        It.IsAny <Message <object, Relationship> >(), ResponseStyle.WholeSolution,
                                        It.IsAny <Func <string, bool> >()))
            .Returns(new JsonBusResponse {
                Solution = null, Errors = mockError
            });

            var mockUtcNow = new DateTime(2017, 2, 2, 4, 3, 1);

            _dateTimeProviderMock.Setup(x => x.UtcNow).Returns(mockUtcNow);

            var sut = new Core.OrganisationHierarchyCache.OrganisationHierarchyCache(_loggerMock.Object, _requestStoreMock.Object, _dateTimeProviderMock.Object, _backplaneMock.Object, _configurationManagerMock.Object);

            try
            {
                sut.GetValue(key);
                Assert.Fail("Should have thrown an exception.");
            }
            catch (InvalidOperationException ex)
            {
                Assert.IsTrue(ex.Message.Equals("mock error", StringComparison.OrdinalIgnoreCase));
            }

            _loggerMock.Verify(x => x.Error("OrganisationHierarchyCache.GetOrganisationTreeItemForOrganisation",
                                            It.Is <LogItem[]>(li =>
                                                              li[0].Key.Equals("Event") &&
                                                              li[0].Value.Invoke().Equals(eventDescription) &&
                                                              li[1].Key.Equals("organisationId") &&
                                                              li[1].Value.Invoke().Equals(_orgA1.ToString()) &&
                                                              li[2].Key.Equals("Errors") &&
                                                              li[2].Value.Invoke().Equals(mockError)
                                                              )));

            _backplaneMock.VerifyNoOtherCalls();
        }
        public void GetValue_WithMatchingKeyNotInInCache_WithMultipleMultilevelRelationships_PublishesMesageOntoBusButReturnsItem()
        {
            var key = _orgA1;

            _requestStoreMock.Setup(x => x.PublishAndWaitForResponse(
                                        It.IsAny <Message <object, Relationship> >(), ResponseStyle.WholeSolution, It.IsAny <Func <string, bool> >()))
            .Returns(new JsonBusResponse {
                Solution = JsonConvert.SerializeObject(_relationshipSampleData)
            });

            var mockUtcNow = new DateTime(2017, 2, 2, 4, 3, 1);

            _dateTimeProviderMock.Setup(x => x.UtcNow).Returns(mockUtcNow);

            var sut = new Core.OrganisationHierarchyCache.OrganisationHierarchyCache(_loggerMock.Object, _requestStoreMock.Object, _dateTimeProviderMock.Object, _backplaneMock.Object, _configurationManagerMock.Object);

            var result = sut.GetValue(key);

            Assert.IsNotNull(result);
            Assert.IsTrue(ResultDataTreeIsCorrect(result));

            _requestStoreMock.Verify(x =>
                                     x.PublishAndWaitForResponse(
                                         It.Is <Message <object, Relationship> >(m =>
                                                                                 m.Method.Equals(QueryChildRelationshipsMethodName) &&
                                                                                 TestUtils.GetPropertyValue <Guid>(m.Need, "StartNodeId").Equals(_orgA1) &&
                                                                                 TestUtils.GetPropertyValue <RelationshipDateRange>(m.Need, "Active").From.Equals(mockUtcNow) &&
                                                                                 TestUtils.GetPropertyValue <RelationshipDateRange>(m.Need, "Active").To == null &&
                                                                                 TestUtils.GetPropertyValue <string[]>(m.Need, "LinkRelationshipTypes").Single().Equals(BusinessToBusinessRelationshipType) &&
                                                                                 TestUtils.GetPropertyValue <string[]>(m.Need, "NodeTypes").Single().Equals(AssetTypeOrganisation)),
                                         ResponseStyle.WholeSolution,
                                         It.IsAny <Func <string, bool> >()
                                         ), Times.Exactly(1)
                                     );

            _backplaneMock.Verify(x => x.Send(It.Is <OrganisationHierarchyCacheItem>(oti => oti.OrganisationId != Guid.Empty)));

            _requestStoreMock.VerifyNoOtherCalls();
            _backplaneMock.VerifyNoOtherCalls();
        }
        public void AddOrUpdate_WithInitialAddEntry_ThenUpdateEntry_AddsAndUpdatesEntryCorrectlyAndNoMessagesArePublished()
        {
            var key          = new Guid("bc44ffe6-0533-47c8-986b-e40347a4d072");
            var initialValue = new OrganisationHierarchyCacheItem {
                OrganisationId = key, ChildOrganisations = null, Metadata = null
            };
            var updatedValue = new OrganisationHierarchyCacheItem {
                OrganisationId = key, ChildOrganisations = new List <OrganisationHierarchyCacheItem>(), Metadata = new CaseInsensitiveDictionary {
                    { "key1", "value1" }
                }
            };

            var sut = new Core.OrganisationHierarchyCache.OrganisationHierarchyCache(_loggerMock.Object, _requestStoreMock.Object, _dateTimeProviderMock.Object, _backplaneMock.Object, _configurationManagerMock.Object);

            sut.AddOrUpdate(key, initialValue);
            Assert.AreEqual(initialValue, sut.GetValue(key));

            sut.AddOrUpdate(key, updatedValue);
            Assert.AreEqual(updatedValue, sut.GetValue(key));

            _requestStoreMock.VerifyNoOtherCalls();
            _backplaneMock.VerifyNoOtherCalls();
        }
        public void GetValue_WithNoMatchingKeyInCache_NoRelationshipsInRelationshipResponse_PublishesGetOrganisationMessage_CachesResponseCorrectlyAndReturnsResult()
        {
            var key = _orgA1;

            //first message to get relationships
            _requestStoreMock.Setup(x => x.PublishAndWaitForResponse(
                                        It.IsAny <Message <object, Relationship> >(), ResponseStyle.WholeSolution,
                                        It.IsAny <Func <string, bool> >()))
            .Returns(new JsonBusResponse {
                Solution = JsonConvert.SerializeObject(new List <Relationship>())
            });

            //second message to get organisation
            _requestStoreMock.Setup(x => x.PublishAndWaitForResponse(
                                        It.IsAny <Message <Guid, OrganisationHierarchyCacheItem> >(), ResponseStyle.FirstOrDefault,
                                        null))
            .Returns(new JsonBusResponse
            {
                Solution = JsonConvert.SerializeObject(new
                {
                    OrganisationId = _orgA1,
                    Metadata       = new CaseInsensitiveDictionary {
                        { "key1", "value1" }
                    }
                })
            });

            var mockUtcNow = new DateTime(2017, 2, 2, 4, 3, 1);

            _dateTimeProviderMock.Setup(x => x.UtcNow).Returns(mockUtcNow);

            var sut = new Core.OrganisationHierarchyCache.OrganisationHierarchyCache(_loggerMock.Object, _requestStoreMock.Object, _dateTimeProviderMock.Object, _backplaneMock.Object, _configurationManagerMock.Object);

            var result = sut.GetValue(key);

            Assert.IsNotNull(result);
            Assert.AreEqual(_orgA1, result.OrganisationId);

            _requestStoreMock.Verify(x =>
                                     x.PublishAndWaitForResponse(
                                         It.Is <Message <object, Relationship> >(m =>
                                                                                 m.Method.Equals(QueryChildRelationshipsMethodName) &&
                                                                                 TestUtils.GetPropertyValue <Guid>(m.Need, "StartNodeId").Equals(_orgA1) &&
                                                                                 TestUtils.GetPropertyValue <RelationshipDateRange>(m.Need, "Active").From.Equals(mockUtcNow) &&
                                                                                 TestUtils.GetPropertyValue <RelationshipDateRange>(m.Need, "Active").To == null &&
                                                                                 TestUtils.GetPropertyValue <string[]>(m.Need, "LinkRelationshipTypes").Single().Equals(BusinessToBusinessRelationshipType) &&
                                                                                 TestUtils.GetPropertyValue <string[]>(m.Need, "NodeTypes").Single().Equals(AssetTypeOrganisation)),
                                         ResponseStyle.WholeSolution,
                                         It.IsAny <Func <string, bool> >()
                                         ), Times.Exactly(1)
                                     );

            _requestStoreMock.Verify(x =>
                                     x.PublishAndWaitForResponse(
                                         It.Is <Message <Guid, OrganisationHierarchyCacheItem> >(m =>
                                                                                                 m.Method.Equals(GetOrganisationMethodName) &&
                                                                                                 m.Need.Equals(_orgA1)),
                                         ResponseStyle.FirstOrDefault,
                                         null),
                                     Times.Exactly(1));

            _backplaneMock.Verify(x => x.Send(It.Is <OrganisationHierarchyCacheItem>(oti => oti.OrganisationId.Equals(_orgA1))));

            _requestStoreMock.VerifyNoOtherCalls();
            _backplaneMock.VerifyNoOtherCalls();
        }
        public void GetValue_RelationshipsReturnedFromQueryChildRelationshipsDoNotContainRequestedOrganisationIdAsAParent_LogsAndThrowsException()
        {
            const string error = "The expected root node for the tree should be a parent and should not appear as a child in any relationship.";

            var key = _orgA1;

            var invalidRelationships = new List <Relationship>
            {
                new Relationship {
                    ChildNodeId = Guid.NewGuid(), ParentNodeId = Guid.NewGuid()
                },
                new Relationship {
                    ChildNodeId = Guid.NewGuid(), ParentNodeId = Guid.NewGuid()
                }
            };

            _requestStoreMock.Setup(x => x.PublishAndWaitForResponse(
                                        It.IsAny <Message <object, Relationship> >(), ResponseStyle.WholeSolution, It.IsAny <Func <string, bool> >()))
            .Returns(new JsonBusResponse {
                Solution = JsonConvert.SerializeObject(invalidRelationships)
            });

            var mockUtcNow = new DateTime(2017, 2, 2, 4, 3, 1);

            _dateTimeProviderMock.Setup(x => x.UtcNow).Returns(mockUtcNow);

            var sut = new Core.OrganisationHierarchyCache.OrganisationHierarchyCache(_loggerMock.Object, _requestStoreMock.Object, _dateTimeProviderMock.Object, _backplaneMock.Object, _configurationManagerMock.Object);

            try
            {
                sut.GetValue(key);
                Assert.Fail("Should have thrown an exception.");
            }
            catch (InvalidOperationException ex)
            {
                Assert.AreEqual(ex.Message, error);
            }

            _requestStoreMock.Verify(x =>
                                     x.PublishAndWaitForResponse(
                                         It.Is <Message <object, Relationship> >(m =>
                                                                                 m.Method.Equals(QueryChildRelationshipsMethodName) &&
                                                                                 TestUtils.GetPropertyValue <Guid>(m.Need, "StartNodeId").Equals(_orgA1) &&
                                                                                 TestUtils.GetPropertyValue <RelationshipDateRange>(m.Need, "Active").From.Equals(mockUtcNow) &&
                                                                                 TestUtils.GetPropertyValue <RelationshipDateRange>(m.Need, "Active").To == null &&
                                                                                 TestUtils.GetPropertyValue <string[]>(m.Need, "LinkRelationshipTypes").Single().Equals(BusinessToBusinessRelationshipType) &&
                                                                                 TestUtils.GetPropertyValue <string[]>(m.Need, "NodeTypes").Single().Equals(AssetTypeOrganisation)
                                                                                 ),
                                         ResponseStyle.WholeSolution,
                                         It.IsAny <Func <string, bool> >()
                                         ), Times.Once
                                     );

            _loggerMock.Verify(x => x.Error("OrganisationHierarchyCache.ConvertRelationshipsToOrganisationTreeItem",
                                            It.Is <LogItem[]>(li => li[0].Key.Equals("Error") &&
                                                              li[0].Value.Invoke().Equals(error) &&
                                                              li[1].Key.Equals("rootNode") &&
                                                              li[1].Value.Invoke().Equals(_orgA1.ToString())
                                                              )));

            _requestStoreMock.VerifyNoOtherCalls();
            _backplaneMock.VerifyNoOtherCalls();
        }