public void DoesNotNotifyWhenNewSelectorHasNoRecord() { Guid Id = Guid.NewGuid(); DkimEntityState oldState = new DkimEntityState("", 0, DkimState.PollPending, DateTime.MinValue, DateTime.MinValue, DateTime.MaxValue, new List <DkimSelector> { CreateDkimSelector("selector1", new List <Message> { new Message(Id, "selector 1 record 1 message 1", string.Empty, MessageType.Info) }) }); DkimRecordEvaluationResult newRecord = new DkimRecordEvaluationResult(null, new List <DkimSelectorResult> { CreateDkimSelectorResult("selector1", new List <DkimEvaluatorMessage> { new DkimEvaluatorMessage(Id, EvaluationErrorType.Info, "selector 1 record 1 message 1 same as old", string.Empty) }), new DkimSelectorResult(new Contracts.SharedDomain.DkimSelector("rogueSelector"), null) }); _advisoryChangedNotifier.Handle(oldState, newRecord); A.CallTo(() => _messageDispatcher.Dispatch(A <Common.Messaging.Abstractions.Message> ._, A <string> ._)).MustNotHaveHappened(); }
public void NotifiesWhenSelectorChanges() { Dictionary <string, List <string> > selectorsAndRecords1 = new Dictionary <string, List <string> > { { "selector1", new List <string> { "record1" } } }; Dictionary <string, List <string> > selectorsAndRecords2 = new Dictionary <string, List <string> > { { "selector2", new List <string> { "record1" } } }; DkimEntityState state = CreateDkimEntityState(selectorsAndRecords1); DkimRecordsPolled message = CreateDkimRecordsPolled(selectorsAndRecords2); _recordChangedNotifier.Handle(state, message); A.CallTo(() => _messageDispatcher.Dispatch(A <DkimRecordAdded> ._, A <string> ._)).MustHaveHappenedOnceExactly(); A.CallTo(() => _messageDispatcher.Dispatch(A <DkimRecordRemoved> ._, A <string> ._)).MustHaveHappenedOnceExactly(); A.CallTo(() => _messageDispatcher.Dispatch( A <DkimRecordAdded> .That.Matches(x => x.SelectorRecords[0].Selector == "selector2" && x.SelectorRecords[0].Records[0] == "record1"), A <string> ._)).MustHaveHappenedOnceExactly(); A.CallTo(() => _messageDispatcher.Dispatch( A <DkimRecordRemoved> .That.Matches(x => x.SelectorRecords[0].Selector == "selector1" && x.SelectorRecords[0].Records[0] == "record1"), A <string> ._)).MustHaveHappenedOnceExactly(); }
public void Handle(DkimEntityState state, Common.Messaging.Abstractions.Message message) { foreach (IChangeNotifier changeNotifier in _notifiers) { changeNotifier.Handle(state, message); } }
public void UpdateSelectorWhenNewSelectorsAddsNewSelectors() { DkimEntityState state = CreateState(Domain, DkimState.Evaluated); DkimSelector selector1 = CreateSelector(Selector1); DkimSelector selector2 = CreateSelector(Selector2); DkimSelector selector3 = CreateSelector(Selector3); state.UpdateSelectors(new List <DkimSelector> { selector1, selector2 }, out DkimSelectorsUpdated dkimSelectorsUpdated); bool updated = state.UpdateSelectors(new List <DkimSelector> { selector3 }, out dkimSelectorsUpdated); Assert.That(updated, Is.True); Assert.That(state.Selectors.Count == 3); Assert.That(state.Selectors[0], Is.EqualTo(selector1)); Assert.That(state.Selectors[1], Is.EqualTo(selector2)); Assert.That(state.Selectors[2], Is.EqualTo(selector3)); Assert.That(dkimSelectorsUpdated.Selectors.Count == 3); Assert.That(dkimSelectorsUpdated.Selectors[0] == selector1.Selector); Assert.That(dkimSelectorsUpdated.Selectors[1] == selector2.Selector); Assert.That(dkimSelectorsUpdated.Selectors[2] == selector3.Selector); }
public void DoesNotNotifyWhenNewSelectorHasNoRecord() { Dictionary <string, List <string> > selectorsAndRecords1 = new Dictionary <string, List <string> > { { "selector1", new List <string> { "record" } } }; DkimEntityState state = CreateDkimEntityState(selectorsAndRecords1); DkimRecordsPolled message = new DkimRecordsPolled("", new List <DkimSelectorRecords> { new DkimSelectorRecords(Guid.NewGuid(), "selector1", new List <DkimTxtRecord>() { new DkimTxtRecord(new List <string> { "record" }) }, null, 0), new DkimSelectorRecords(Guid.NewGuid(), "rogueSelector", null, null, 0) }); _recordChangedNotifier.Handle(state, message); A.CallTo(() => _messageDispatcher.Dispatch(A <Common.Messaging.Abstractions.Message> .Ignored, A <string> .Ignored)).MustNotHaveHappened(); }
public void NotifiesWhenSelectorRemoved() { Guid Id1 = Guid.NewGuid(); DkimEntityState oldState = new DkimEntityState("", 0, DkimState.PollPending, DateTime.MinValue, DateTime.MinValue, DateTime.MaxValue, new List <DkimSelector> { CreateDkimSelector("selector1", new List <Message> { new Message(Id1, "selector 1 record 1 message 1", string.Empty, MessageType.Info) }), CreateDkimSelector("selector2", new List <Message> { new Message(Guid.NewGuid(), "selector 2 record 1 message 1", string.Empty, MessageType.Info) }) }); DkimRecordEvaluationResult newRecord = new DkimRecordEvaluationResult(null, new List <DkimSelectorResult> { CreateDkimSelectorResult("selector1", new List <DkimEvaluatorMessage> { new DkimEvaluatorMessage(Id1, EvaluationErrorType.Info, "selector 1 record 1 message 1", string.Empty) }) }); _advisoryChangedNotifier.Handle(oldState, newRecord); A.CallTo(() => _messageDispatcher.Dispatch(A <DkimAdvisoryRemoved> ._, A <string> ._)).MustHaveHappenedOnceExactly(); A.CallTo(() => _messageDispatcher.Dispatch(A <DkimAdvisoryAdded> ._, A <string> ._)).MustNotHaveHappened(); A.CallTo(() => _messageDispatcher.Dispatch( A <DkimAdvisoryRemoved> .That.Matches(x => x.SelectorMessages[0].Selector == "selector2" && (MessageType)x.SelectorMessages[0].Messages[0].MessageType == MessageType.Info && x.SelectorMessages[0].Messages[0].Text == "selector 2 record 1 message 1"), A <string> ._)).MustHaveHappenedOnceExactly(); }
private DateTime GetRecordStartDate(DkimEntityState dkimEntityState) { List <DateTime> dateTimes = dkimEntityState.LastUpdateSources.Values.ToList(); dateTimes.Add(dkimEntityState.Created); return(dateTimes.Max()); }
public async Task HandleDkimEvaluationUpdateCantUpdateDoesNotContinue() { DkimEntityState dkimEntityState = A.Fake <DkimEntityState>(); A.CallTo(() => dkimEntityState.Id).Returns(Id); A.CallTo(() => dkimEntityState.CanUpdate(A <string> ._, A <DateTime> ._)).Returns(false); A.CallTo(() => _dkimEntityDao.Get(Id)).Returns(dkimEntityState); await _dkimEntity.Handle(new DkimRecordEvaluationResult(Id, new List <DkimSelectorResult>())); A.CallTo(() => _dkimEntityDao.Save(A <DkimEntityState> ._)).MustNotHaveHappened(); A.CallTo(() => _dispatcher.Dispatch(A <Common.Messaging.Abstractions.Message> ._, A <string> ._)).MustNotHaveHappened(); }
public async Task SaveStateAlreadyPersistedForVersionThrows() { DkimEntityState state = new DkimEntityState(Id, 1, DkimState.Evaluated, DateTime.UtcNow, DateTime.UtcNow, DateTime.UtcNow, new List <DkimSelector> { new DkimSelector(Selector1) }); await _dao.Save(state); InvalidOperationException exception = Assert.ThrowsAsync <InvalidOperationException>(() => _dao.Save(state)); Assert.That(exception.Message, Is.EqualTo($"Didn\'t update DkimEntityState because version 1 has already been persisted.")); }
public async Task HandleDkimEvaluationUpdateSuccessful() { DkimEntityState dkimEntityState = A.Fake <DkimEntityState>(); A.CallTo(() => dkimEntityState.Id).Returns(Id); A.CallTo(() => dkimEntityState.CanUpdate(A <string> ._, A <DateTime> ._)).Returns(true); A.CallTo(() => _dkimEntityDao.Get(Id)).Returns(dkimEntityState); DkimRecordEvaluationResult dkimRecordEvaluationResult = new DkimRecordEvaluationResult(Id, new List <DkimSelectorResult>()); await _dkimEntity.Handle(dkimRecordEvaluationResult); A.CallTo(() => _dkimEntityDao.Save(dkimEntityState)).MustHaveHappened(); A.CallTo(() => _dispatcher.Dispatch(A <DkimEvaluationUpdated> ._, A <string> ._)).MustHaveHappened(); }
private DkimEntityState CreateDkimEntityState(Dictionary <string, List <string> > selectorsAndRecords) { List <DkimSelector> dkimSelectors = new List <DkimSelector>(); foreach (KeyValuePair <string, List <string> > kvp in selectorsAndRecords) { List <DkimRecord> dkimRecords = kvp.Value.Select(record => new DkimRecord(new DnsRecord(record, null))).ToList(); dkimSelectors.Add(new DkimSelector(kvp.Key, dkimRecords)); } _fixture.Register(() => dkimSelectors); DkimEntityState dkimEntityState = _fixture.Create <DkimEntityState>(); return(dkimEntityState); }
public void UpdatesWithNoChangesRecordEvaluationMessages() { DkimSelector selector1 = CreateSelector(Selector1, CreateRecord(Dkim1)); DkimEntityState state = CreateState(Domain, DkimState.PollPending, selector1); DkimSelector selector2 = CreateSelector(Selector1, CreateRecord(Dkim1)); state.UpdateRecords(new List <DkimSelector> { selector2 }, DateTime.UtcNow); DkimEvaluationUpdated evaluationUpdated = state.UpdateEvaluations(DateTime.UtcNow); Assert.That(evaluationUpdated, Is.Not.Null); }
public void UpdatesEmptyRecordEvaluationMessages() { DkimSelector selector1 = CreateSelector(Selector1, CreateRecord(Dkim1, new Message(Guid.NewGuid(), "oh boy!", string.Empty, MessageType.Warning))); DkimEntityState state = CreateState(Domain, DkimState.PollPending, selector1); DkimSelector selector2 = CreateSelector(Selector1, CreateRecordWithEmptyList(Dkim1)); state.UpdateRecords(new List <DkimSelector> { selector2 }, DateTime.UtcNow); DkimEvaluationUpdated evaluationUpdated = state.UpdateEvaluations(DateTime.UtcNow); Assert.AreEqual(evaluationUpdated.DkimEvaluationResults[0].Records[0].EvaluationMessages.Count, 0); }
public async Task HandleAggregateReportDomainDkimSelectorsCantUpdateDoesNotContinue() { DkimEntityState dkimEntityState = A.Fake <DkimEntityState>(); A.CallTo(() => dkimEntityState.Id).Returns(Id); A.CallTo(() => dkimEntityState.CanUpdate(A <string> ._, A <DateTime> ._)).Returns(false); DkimSelectorsUpdated dkimSelectorsUpdated; A.CallTo(() => dkimEntityState.UpdateSelectors(null, out dkimSelectorsUpdated)).WithAnyArguments().Returns(false); A.CallTo(() => _dkimEntityDao.Get(Id)).Returns(dkimEntityState); await _dkimEntity.Handle(new DkimSelectorsSeen("", "", Id, new List <string>())); A.CallTo(() => _dkimEntityDao.Save(A <DkimEntityState> ._)).MustNotHaveHappened(); A.CallTo(() => _dispatcher.Dispatch(A <Common.Messaging.Abstractions.Message> ._, A <string> ._)).MustNotHaveHappened(); }
public async Task HandleAggregateReportDomainDkimSelectorsStateExistsAndEventCausesUpdate() { DkimEntityState dkimEntityState = A.Fake <DkimEntityState>(); A.CallTo(() => dkimEntityState.Id).Returns(Id); A.CallTo(() => dkimEntityState.CanUpdate(A <string> ._, A <DateTime> ._)).Returns(true); DkimSelectorsUpdated dkimSelectorsUpdated; A.CallTo(() => dkimEntityState.UpdateSelectors(null, out dkimSelectorsUpdated)).WithAnyArguments().Returns(true); A.CallTo(() => _dkimEntityDao.Get(Id)).Returns(dkimEntityState); await _dkimEntity.Handle(new DkimSelectorsSeen("", "", Id, new List <string>())); A.CallTo(() => _dkimEntityDao.Save(A <DkimEntityState> ._)).MustHaveHappenedOnceExactly(); A.CallTo(() => _dkimEntityDao.Save(A <DkimEntityState> ._)).MustHaveHappenedOnceExactly(); }
public void UpdateRecordsWhenNoRecordsFromPollUpdatesErrorWhenNoErrorsExist() { DkimSelector selector1 = CreateSelector(Selector1); DkimEntityState state = CreateState(Domain, DkimState.PollPending, selector1); DkimSelector selector3 = new DkimSelector(Selector1, new List <DkimRecord>(), null); state.UpdateRecords(new List <DkimSelector> { selector3 }, DateTime.UtcNow); Assert.That(state.Selectors[0].Selector, Is.EqualTo(selector3.Selector)); Assert.That(state.Selectors.Count, Is.EqualTo(1)); Assert.That(state.Selectors[0].Records.Count, Is.EqualTo(0)); StringAssert.StartsWith("Didn't find any DNS TXT", state.Selectors[0].PollError.Text); }
public async Task InsertStateAndRetrieveStateCorrectly() { DkimState dkimState = DkimState.Evaluated; DkimEntityState state = new DkimEntityState(Id, 1, dkimState, DateTime.UtcNow, DateTime.UtcNow, DateTime.UtcNow, new List <DkimSelector> { new DkimSelector(Selector1) }); await _dao.Save(state); DkimEntityState stateFromDatabase = await _dao.Get(Id); Assert.That(stateFromDatabase.Id, Is.EqualTo(state.Id)); Assert.That(stateFromDatabase.Version, Is.EqualTo(state.Version)); Assert.That(stateFromDatabase.Selectors.Count, Is.EqualTo(1)); Assert.That(stateFromDatabase.Selectors[0].Selector, Is.EqualTo(Selector1)); Assert.That(stateFromDatabase.State, Is.EqualTo(dkimState)); }
public void UpdateRecordsClearsExistingRecordsAndUpdatesWithNewOnes() { DkimSelector selector1 = CreateSelector(Selector1); DkimSelector selector2 = CreateSelector(Selector2); DkimEntityState state = CreateState(Domain, DkimState.PollPending, selector1, selector2); DkimSelector selector3 = CreateSelector(Selector1, CreateRecord(Dkim1)); state.UpdateRecords(new List <DkimSelector> { selector3 }, DateTime.UtcNow); Assert.That(state.Selectors[0].Selector, Is.EqualTo(selector3.Selector)); Assert.That(state.Selectors.Count, Is.EqualTo(1)); Assert.That(state.Selectors[0].Records.Count, Is.EqualTo(1)); Assert.That(state.Selectors[0].Records[0].DnsRecord.Record, Is.EqualTo(Dkim1)); Assert.That(state.Selectors[0].PollError, Is.Null); }
public async Task HandleDkimRecordsPolledCantUpdateDoesNotContinue() { DkimEntityState dkimEntityState = A.Fake <DkimEntityState>(); A.CallTo(() => dkimEntityState.Id).Returns(Id); A.CallTo(() => dkimEntityState.CanUpdate(A <string> ._, A <DateTime> ._)).Returns(false); DkimSelectorsUpdated dkimSelectorsUpdated; A.CallTo(() => dkimEntityState.UpdateSelectors(null, out dkimSelectorsUpdated)).WithAnyArguments().Returns(false); A.CallTo(() => _dkimEntityDao.Get(Id)).Returns(dkimEntityState); await _dkimEntity.Handle(new DkimRecordEvaluationResult(Id, new List <DkimSelectorResult>())); A.CallTo(() => _changeNotifierComposite.Handle(A <DkimEntityState> ._, A <Message> ._)).MustNotHaveHappened(); A.CallTo(() => _domainStatusPublisher.Publish(A <DkimRecordEvaluationResult> ._)).MustNotHaveHappened(); A.CallTo(() => _dkimEntityDao.Save(A <DkimEntityState> ._)).MustNotHaveHappened(); A.CallTo(() => _dispatcher.Dispatch(A <Common.Messaging.Abstractions.Message> ._, A <string> ._)).MustNotHaveHappened(); }
public async Task HandleDkimRecordEvaluationResultRemovesPolledErrorSelectors() { DkimRecordEvaluationResult message = new DkimRecordEvaluationResult( Id, new List <DkimSelectorResult> { new DkimSelectorResult(new Contracts.SharedDomain.DkimSelector("selector", null, null, new Contracts.SharedDomain.Message(Guid.Empty, Contracts.SharedDomain.MessageType.error, "error", "markdown")), new List <RecordResult>()) }); message.Timestamp = DateTime.UtcNow; DkimEntityState dkimEntityState = new DkimEntityState(Id, 1, DkimState.PollPending, DateTime.Now, null, null, new List <DkimSelector>()); dkimEntityState.Selectors.Add(new DkimSelector("selector1")); A.CallTo(() => _dkimEntityDao.Get(Id)).Returns(dkimEntityState); await _dkimEntity.Handle(message); A.CallTo(() => _dkimEntityDao.Save(A <DkimEntityState> .That.Matches(x => x.Selectors.Count == 0))).MustHaveHappenedOnceExactly(); }
public void UpdateSelectorsWhenNoNewSelectorsNothingChanges() { DkimEntityState state = CreateState(Domain, DkimState.Evaluated); DkimSelector selector1 = CreateSelector(Selector1); DkimSelector selector2 = CreateSelector(Selector2); state.UpdateSelectors(new List <DkimSelector> { selector1, selector2 }, out DkimSelectorsUpdated _); bool updated = state.UpdateSelectors(new List <DkimSelector> { selector1, selector2 }, out _); Assert.That(updated, Is.False); Assert.That(state.Selectors.Count == 2); Assert.That(state.Selectors[0], Is.EqualTo(selector1)); Assert.That(state.Selectors[1], Is.EqualTo(selector2)); }
public async Task Save(DkimEntityState state) { string connectionString = await _connectionInfoAsync.GetConnectionStringAsync(); string serializedState = JsonConvert.SerializeObject(state, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }); int rowsAffected = await MySqlHelper.ExecuteNonQueryAsync(connectionString, DkimEntityDaoResources.InsertDkimEntity, new MySqlParameter("domain", state.Id), new MySqlParameter("version", state.Version), new MySqlParameter("state", serializedState)); if (rowsAffected == 0) { throw new InvalidOperationException( $"Didn't update DkimEntityState because version {state.Version} has already been persisted."); } }
public void DoesNotNotifyWhenNoChanges() { Dictionary <string, List <string> > selectorsAndRecords1 = new Dictionary <string, List <string> > { { "selector1", new List <string> { "record" } } }; Dictionary <string, List <string> > selectorsAndRecords2 = new Dictionary <string, List <string> > { { "selector1", new List <string> { "record" } } }; DkimEntityState state = CreateDkimEntityState(selectorsAndRecords1); DkimRecordsPolled message = CreateDkimRecordsPolled(selectorsAndRecords2); _recordChangedNotifier.Handle(state, message); A.CallTo(() => _messageDispatcher.Dispatch(A <Common.Messaging.Abstractions.Message> .Ignored, A <string> .Ignored)).MustNotHaveHappened(); }
public async Task HandleDkimRecordEvaluationResultUpdatesPolledSelectors() { DkimRecordEvaluationResult message = new DkimRecordEvaluationResult( Id, new List <DkimSelectorResult> { new DkimSelectorResult(new Contracts.SharedDomain.DkimSelector("selector1", null), new List <RecordResult> { new RecordResult("record1", new List <DkimEvaluatorMessage>()) }) }); message.Timestamp = DateTime.UtcNow; DkimEntityState dkimEntityState = new DkimEntityState(Id, 1, DkimState.PollPending, DateTime.Now, null, null, new List <DkimSelector>()); dkimEntityState.Selectors.Add(new DkimSelector("selector1")); A.CallTo(() => _dkimEntityDao.Get(Id)).Returns(dkimEntityState); await _dkimEntity.Handle(message); A.CallTo(() => _dkimEntityDao.Save(A <DkimEntityState> .That.Matches(x => x.Selectors.Count == 1 && x.Selectors[0].Selector == "selector1"))).MustHaveHappenedOnceExactly(); }
public void Handle(DkimEntityState state, Common.Messaging.Abstractions.Message message) { if (message is DkimRecordEvaluationResult evaluationResult) { List <DkimSelector> newRecordsIgnoringEmptyResults = evaluationResult.ToDkimSelectors().Where(x => x.Records != null).ToList(); List <SelectorMessage> currentSelectorMessages = CreateFlattenedSelectorMessages(state.Selectors); List <SelectorMessage> newSelectorMessages = CreateFlattenedSelectorMessages(newRecordsIgnoringEmptyResults); List <SelectorMessages> addedMessages = CreateExclusiveSelectorMessages(newSelectorMessages, currentSelectorMessages); if (addedMessages.Any()) { DkimAdvisoryAdded dkimAdvisoryAdded = new DkimAdvisoryAdded(state.Id, addedMessages); _dispatcher.Dispatch(dkimAdvisoryAdded, _dkimEntityConfig.SnsTopicArn); } List <SelectorMessages> removedMessages = CreateExclusiveSelectorMessages(currentSelectorMessages, newSelectorMessages); if (removedMessages.Any()) { DkimAdvisoryRemoved dkimAdvisoryRemoved = new DkimAdvisoryRemoved(state.Id, removedMessages); _dispatcher.Dispatch(dkimAdvisoryRemoved, _dkimEntityConfig.SnsTopicArn); } } }
public void Handle(DkimEntityState state, Common.Messaging.Abstractions.Message message) { if (message is DkimRecordsPolled polled) { List <SelectorRecord> currentSelectorRecords = state.Selectors .SelectMany(x => x.Records, (y, z) => new SelectorRecord(y.Selector, z.DnsRecord.Record)).ToList(); List <SelectorRecord> newSelectorRecords = polled.DkimSelectorRecords .Where(x => x.Records != null) .SelectMany(x => x.Records, (y, z) => new SelectorRecord(y.Selector, z.Record)).ToList(); List <SelectorRecord> addedRecords = newSelectorRecords.Except(currentSelectorRecords, _selectorRecordEqualityComparer).ToList(); if (addedRecords.Any()) { List <SelectorRecords> selectorRecords = addedRecords .GroupBy(x => x.Selector, y => y.Record) .Select(x => new SelectorRecords(x.Key, x.ToList())) .ToList(); DkimRecordAdded dkimDnsRecordAdded = new DkimRecordAdded(state.Id, selectorRecords); _dispatcher.Dispatch(dkimDnsRecordAdded, _dkimEntityConfig.SnsTopicArn); } List <SelectorRecord> removedRecords = currentSelectorRecords.Except(newSelectorRecords, _selectorRecordEqualityComparer).ToList(); if (removedRecords.Any()) { List <SelectorRecords> selectorRecords = removedRecords .GroupBy(x => x.Selector, y => y.Record) .Select(x => new SelectorRecords(x.Key, x.ToList())) .ToList(); DkimRecordRemoved dkimDnsRecordRemoved = new DkimRecordRemoved(state.Id, selectorRecords); _dispatcher.Dispatch(dkimDnsRecordRemoved, _dkimEntityConfig.SnsTopicArn); } } }
public async Task GetNoStateExistsReturnsNull() { DkimEntityState state = await _dao.Get(Id); Assert.That(state, Is.Null); }