private static ChangeOfChargesMessage GetValidChangeOfChargesMessage() { var message = new ChangeOfChargesMessage { ChargeTypeMRid = "chargeTypeMRid", CorrelationId = "correlationId", LastUpdatedBy = "lastUpdatedBy", Type = KnownChargeType, ChargeTypeOwnerMRid = KnownChargeOwner, MktActivityRecord = new MktActivityRecord { ChargeType = new Ingestion.Domain.ChangeOfCharges.ChargeType { VATPayer = KnownVatPayer, Name = "shortDescription", Description = "longDescription", }, }, Period = new ChargeTypePeriod { Resolution = KnownResolutionType, Points = new List <Point> { new Point { Position = 1, PriceAmount = 1m, Time = SystemClock.Instance.GetCurrentInstant(), }, }, }, }; return(message); }
private async Task <MarketParticipant?> GetChargeTypeOwnerMRidAsync(ChangeOfChargesMessage chargeMessage) { return(string.IsNullOrWhiteSpace(chargeMessage.ChargeTypeOwnerMRid) ? throw new ArgumentException($"Fails as {nameof(chargeMessage.ChargeTypeOwnerMRid)} is invalid") : await _chargesDatabaseContext.MarketParticipant.SingleOrDefaultAsync(type => type.MRid == chargeMessage.ChargeTypeOwnerMRid)); }
private void HandleValidationRule( ChangeOfChargesMessage changeOfChargesMessage, IValidationRule validationRule, HubRequestValidationResult validationResult) { const string unknownServerError = "Unknown server error"; try { if (_ruleConfigurations == null) { validationResult.Add(new ValidationError("VR900", unknownServerError)); _logger.LogError($"{nameof(_ruleConfigurations)} was null"); return; } var ruleValidationResult = validationRule.Validate(changeOfChargesMessage, _ruleConfigurations); if (ruleValidationResult.ValidatedSuccessfully is false) { validationResult.Add(ruleValidationResult.ValidationError); } } catch (RuleNotFoundException ruleNotFoundException) { validationResult.Add(new ValidationError("VRXYZ", unknownServerError)); _logger.LogError(ruleNotFoundException, "Rule configuration could not be found"); } catch (RuleCouldNotBeMappedException ruleCouldNotBeMappedException) { validationResult.Add(new ValidationError("VRXYZ", unknownServerError)); _logger.LogError(ruleCouldNotBeMappedException, "Rule value could not be mapped"); } }
private async Task <VatPayerType?> GetVatPayerTypeAsync(ChangeOfChargesMessage chargeMessage) { return(string.IsNullOrWhiteSpace(chargeMessage.MktActivityRecord?.ChargeType?.VATPayer) ? throw new ArgumentException($"Fails as {nameof(chargeMessage.MktActivityRecord.ChargeType.VATPayer)} is invalid") : await _chargesDatabaseContext.VatPayerType.SingleOrDefaultAsync(type => type.Name == chargeMessage.MktActivityRecord.ChargeType.VATPayer)); }
public async Task ValidateAsync_HappyFlow_ShouldNotAddAnyValidationResults( [Frozen] Mock <IEnumerable <IValidationRule> > validationRules, [Frozen] Mock <IRuleConfigurationRepository> ruleConfigurationRepository, [Frozen] Mock <ILogger <ChangeOfChargesDomainValidator> > logger) { // Arrange SetupValidationRulesCollection(validationRules); ruleConfigurationRepository.Setup(x => x.GetRuleConfigurationsAsync()) .ReturnsAsync(new List <ValidationRuleConfiguration> { new ValidationRuleConfiguration(ValidationRuleNames.StartOfValidIntervalFromNowInDays, "30"), new ValidationRuleConfiguration(ValidationRuleNames.EndOfValidIntervalFromNowInDays, "1000"), }); var sut = new ChangeOfChargesDomainValidator( validationRules.Object, ruleConfigurationRepository.Object, logger.Object); var changeOfChargesMessage = new ChangeOfChargesMessage { MktActivityRecord = new MktActivityRecord { ValidityStartDate = SystemClock.Instance.GetCurrentInstant() .Plus(Duration.FromDays(500)), }, }; // Act var validationResult = await sut.ValidateAsync(changeOfChargesMessage); // Assert validationResult.Errors.Should().BeEmpty(); }
private ChargeChangeNotificationDocument CreateDocument(string receiverMRid, ChangeOfChargesMessage message) { return(new ChargeChangeNotificationDocument { Recipient = receiverMRid, EffectuationDate = message.MktActivityRecord !.ValidityStartDate, Content = CreateDocumentContent(receiverMRid, message), });
public async Task AcceptAsync_WhenCalled_ShouldVerifyThatLoggerIsCalledWithSuccesfulMessage( [Frozen] Mock <ILogger <ChangeOfChargesCommandHandler> > logger, ChangeOfChargesMessage message, ChangeOfChargesCommandHandlerTestable sut) { await sut.CallAcceptAsync(message).ConfigureAwait(false); logger.VerifyLoggerWasCalled($"{nameof(ChangeOfChargesMessage)} have parsed validation", LogLevel.Information); }
public IEnumerable <ChargeChangeNotificationDocument> Create( IEnumerable <MarketParticipant> energySuppliers, ChangeOfChargesMessage message) { foreach (var energySupplier in energySuppliers) { yield return(CreateDocument(energySupplier !.MRid !, message)); } }
private async Task <ChangeOfChargesMessageResult> HandleTransactionsAsync([NotNull] ChangeOfChargesMessage message) { foreach (ChangeOfChargesTransaction transaction in message.Transactions) { await _changeOfChargesTransactionHandler.HandleAsync(transaction).ConfigureAwait(false); } return(ChangeOfChargesMessageResult.CreateSuccess()); }
public async Task RejectAsync_WhenCalled_ShouldSendEventToReportQueue( [Frozen] Mock <IValidationReportQueueDispatcher> validationReportQueueDispatcher, ChangeOfChargesMessage message, [NotNull] ChangeOfChargesCommandHandlerTestable sut) { await sut.CallRejectAsync(message); validationReportQueueDispatcher .Verify(mock => mock.DispatchAsync(It.IsAny <IHubMessage>()), Times.Once); }
public async Task NotifyAboutChangeOfChargesAsync([NotNull] ChangeOfChargesMessage changeOfChargesMessage) { if (changeOfChargesMessage == null) { throw new ArgumentNullException(nameof(changeOfChargesMessage)); } var energySuppliers = _marketParticipantRepository.GetEnergySuppliers(); var documents = _postOfficeDocumentFactory.Create(energySuppliers, changeOfChargesMessage); await _postOfficeClient.SendAsync(documents); }
public async Task <HubRequestValidationResult> ValidateAsync(ChangeOfChargesMessage changeOfChargesMessage) { _ruleConfigurations ??= await _ruleConfigurationRepository.GetRuleConfigurationsAsync(); var validationResult = new HubRequestValidationResult(changeOfChargesMessage.Transaction.MRID); foreach (var validationRule in _validationRules) { HandleValidationRule(changeOfChargesMessage, validationRule, validationResult); } return(validationResult); }
public async Task <HubRequestValidationResult> ValidateAsync(ChangeOfChargesMessage changeOfChargesMessage) { var result = await _inputValidationRuleEngine.ValidateAsync(changeOfChargesMessage).ConfigureAwait(false); var hubRequestValidationResult = new HubRequestValidationResult(changeOfChargesMessage.Transaction.MRID); foreach (var error in result) { hubRequestValidationResult.Add(new ValidationError(error.RuleNumber, error.Message)); } return(hubRequestValidationResult); }
public void Validate_WhenCalledWithTooLateDate_ShouldReturnFalse(int changeOfChargesStartDay, StartDateVr209ValidationRule sut) { var ruleConfigurations = GetValidationRuleConfigurationCollection(); var messageWithLowStartDate = new ChangeOfChargesMessage { MktActivityRecord = new MktActivityRecord { ValidityStartDate = SystemClock.Instance.GetCurrentInstant().Plus(Duration.FromDays(changeOfChargesStartDay)), }, }; var result = sut.Validate(messageWithLowStartDate, ruleConfigurations); result.Should().NotBeNull(); result.ValidationError !.Code.Should().Be("VR209"); }
public void Validate_WhenCalledWithValidDate_ShouldReturnTrue( int changeOfChargesStartDay, StartDateVr209ValidationRule sut) { var ruleConfigurations = GetValidationRuleConfigurationCollection(); var messageWithLowStartDate = new ChangeOfChargesMessage { MktActivityRecord = new MktActivityRecord { ValidityStartDate = SystemClock.Instance.GetCurrentInstant().Plus(Duration.FromDays(changeOfChargesStartDay)), }, }; var result = sut.Validate(messageWithLowStartDate, ruleConfigurations); result.ValidatedSuccessfully.Should().BeTrue(); }
public ValidationStatus Validate(ChangeOfChargesMessage changeOfChargesMessage, IEnumerable <ValidationRuleConfiguration> ruleConfigurations) { var startOfValidIntervalFromNowInDays = ruleConfigurations .GetSingleRule(ValidationRuleNames.StartOfValidIntervalFromNowInDays).GetValueAsInteger(); var endOfValidIntervalFromNowInDays = ruleConfigurations .GetSingleRule(ValidationRuleNames.EndOfValidIntervalFromNowInDays).GetValueAsInteger(); var startOfValidInterval = SystemClock.Instance.GetCurrentInstant() .Plus(Duration.FromDays(startOfValidIntervalFromNowInDays)); var endOfValidInterval = SystemClock.Instance.GetCurrentInstant() .Plus(Duration.FromDays(endOfValidIntervalFromNowInDays)); var startDate = changeOfChargesMessage.MktActivityRecord?.ValidityStartDate; var success = startDate >= startOfValidInterval && startDate <= endOfValidInterval; return(success ? new ValidationStatus(success, null) : new ValidationStatus(false, new ValidationError("VR209", "Time limits not followed"))); }
public void Ensure_all_properties_are_mapped( [Frozen] Mock <IPostOfficeDocumentFactorySettings> settings, ChangeOfChargesMessage changeOfChargesMessage, MarketParticipant marketParticipant, PostOfficeDocumentFactory sut) { // Arrange settings.Setup(x => x.GetHubMRid()).Returns("MRidFromSettings"); MakeMessageValid(changeOfChargesMessage); var receivers = new List <MarketParticipant> { marketParticipant }; // Act var actual = sut.Create(receivers, changeOfChargesMessage) .ToList(); // Assert actual.ForEach(d => d.Should().NotContainNullsOrEmptyEnumerables()); }
public void Ensure_all_types_of_MarketParticipantRole_are_handled_by_Create( PostOfficeDocumentFactory sut, ChangeOfChargesMessage changeOfChargesMessage, MarketParticipant marketParticipant) { // Arrange MakeMessageValid(changeOfChargesMessage); var receivers = new List <MarketParticipant> { marketParticipant }; var roles = Enum.GetValues(typeof(MarketParticipantRole)).Cast <MarketParticipantRole>(); foreach (var role in roles) { changeOfChargesMessage.MarketDocument !.SenderMarketParticipant !.Role = role; // Act & Assert // Create throws a NotImplemented exception if a value in MarketParticipantRole is not handled. _ = sut.Create(receivers, changeOfChargesMessage).ToList(); } }
public async Task <ChargeStorageStatus> StoreChargeAsync(ChangeOfChargesMessage chargeMessage) { var chargeType = await GetChargeTypeAsync(chargeMessage).ConfigureAwait(false); if (chargeType == null) { return(ChargeStorageStatus.CreateFailure($"No charge type for {chargeMessage.Type}")); } var resolutionType = await GetResolutionTypeAsync(chargeMessage).ConfigureAwait(false); if (resolutionType == null) { return(ChargeStorageStatus.CreateFailure($"No resolution type for {chargeMessage.Period?.Resolution}")); } var vatPayerType = await GetVatPayerTypeAsync(chargeMessage).ConfigureAwait(false); if (vatPayerType == null) { return(ChargeStorageStatus.CreateFailure($"No VAT payer type for {chargeMessage.MktActivityRecord?.ChargeType?.VATPayer}")); } var chargeTypeOwnerMRid = await GetChargeTypeOwnerMRidAsync(chargeMessage) !.ConfigureAwait(false); if (chargeTypeOwnerMRid == null) { return(ChargeStorageStatus.CreateFailure($"No market participant for {chargeMessage.ChargeTypeOwnerMRid}")); } var charge = ChangeOfChargesMapper.MapChangeOfChargesMessageToCharge(chargeMessage, chargeType, chargeTypeOwnerMRid, resolutionType, vatPayerType); await _chargesDatabaseContext.Charge.AddAsync(charge); await _chargesDatabaseContext.SaveChangesAsync().ConfigureAwait(false); return(ChargeStorageStatus.CreateSuccess()); }
public async Task AcceptAsync_WhenAddingDuration_ShouldInvokeStorageProviderWithCalculatedTimeProperty(int numberOfDurations, [Frozen] Mock <IIso8601Durations> iso8601Durations, [Frozen] Mock <IChargeRepository> storageProvider, ChangeOfChargesCommandHandlerTestable sut) { // Arrange var startTime = SystemClock.Instance.GetCurrentInstant(); var message = new ChangeOfChargesMessage { MktActivityRecord = new MktActivityRecord { ValidityStartDate = startTime }, Period = new ChargeTypePeriod { Resolution = "PT1H", Points = new List <Point> { new Point { Position = numberOfDurations, PriceAmount = 1 }, }, }, }; var calculatedInstant = message.MktActivityRecord.ValidityStartDate.Plus(Duration.FromHours(numberOfDurations)); iso8601Durations.Setup(i => i.AddDuration(It.IsAny <Instant>(), It.IsAny <string>(), It.IsAny <int>())) .Returns(calculatedInstant); // Act await sut.CallAcceptAsync(message).ConfigureAwait(false); // Assert storageProvider.Verify(s => s.StoreChargeAsync(It.Is <ChangeOfChargesMessage>(msg => msg.Period != null && msg.Period.Points != null && msg.Period.Points.First().Time == calculatedInstant))); }
private async Task <ResolutionType?> GetResolutionTypeAsync(ChangeOfChargesMessage chargeMessage) { return(string.IsNullOrWhiteSpace(chargeMessage.Period?.Resolution) ? throw new ArgumentException($"Fails as {nameof(chargeMessage.Period.Resolution)} is invalid") : await _chargesDatabaseContext.ResolutionType.SingleOrDefaultAsync(type => type.Name == chargeMessage.Period.Resolution)); }
private static void MakeMessageValid(ChangeOfChargesMessage changeOfChargesMessage) { changeOfChargesMessage.MarketDocument !.SenderMarketParticipant !.MRid = "ads"; changeOfChargesMessage.Type = "D01"; changeOfChargesMessage.MktActivityRecord !.ChargeType !.VATPayer = "D01"; }
public async Task CallRejectAsync(ChangeOfChargesMessage changeOfChargesMessage) { await RejectAsync(changeOfChargesMessage, CancellationToken.None); }
public async Task <bool> CallValidateAsync(ChangeOfChargesMessage changeOfChargesMessage) { return(await ValidateAsync(changeOfChargesMessage, CancellationToken.None).ConfigureAwait(false)); }
private async Task <ChargeType?> GetChargeTypeAsync(ChangeOfChargesMessage chargeMessage) { return(string.IsNullOrWhiteSpace(chargeMessage.Type) ? throw new ArgumentException($"Fails as {nameof(chargeMessage.Type)} is invalid") : await _chargesDatabaseContext.ChargeType.SingleOrDefaultAsync(type => type.Code == chargeMessage.Type)); }
public static Charge MapChangeOfChargesMessageToCharge( ChangeOfChargesMessage chargeMessage, ChargeType chargeType, MarketParticipant chargeTypeOwnerMRid, ResolutionType resolutionType, VatPayerType vatPayerType) { if (string.IsNullOrWhiteSpace(chargeMessage.ChargeTypeMRid)) { throw new ArgumentException($"{nameof(chargeMessage.ChargeTypeMRid)} must have value"); } if (string.IsNullOrWhiteSpace(chargeMessage.CorrelationId)) { throw new ArgumentException($"{nameof(chargeMessage.CorrelationId)} must have value"); } if (string.IsNullOrWhiteSpace(chargeMessage.LastUpdatedBy)) { throw new ArgumentException($"{nameof(chargeMessage.LastUpdatedBy)} must have value"); } if (chargeMessage.MktActivityRecord?.ChargeType == null) { throw new ArgumentException($"{nameof(chargeMessage.MktActivityRecord.ChargeType)} can't be null"); } if (string.IsNullOrWhiteSpace(chargeMessage.MktActivityRecord.ChargeType.Name)) { throw new ArgumentException($"{nameof(chargeMessage.MktActivityRecord.ChargeType.Name)} must have value"); } if (string.IsNullOrWhiteSpace(chargeMessage.MktActivityRecord.ChargeType.Description)) { throw new ArgumentException($"{nameof(chargeMessage.MktActivityRecord.ChargeType.Description)} must have value"); } if (chargeMessage.Period == null) { throw new ArgumentException($"{nameof(chargeMessage.Period)} can't be null"); } if (chargeMessage.Period.Points == null) { throw new ArgumentException($"{nameof(chargeMessage.Period.Points)} can't be null"); } var charge = new Charge { ChargePrices = new List <ChargePrice>(), ChargeType = chargeType, ChargeTypeOwner = chargeTypeOwnerMRid, Description = chargeMessage.MktActivityRecord.ChargeType.Description, LastUpdatedBy = chargeMessage.LastUpdatedBy, LastUpdatedByCorrelationId = chargeMessage.CorrelationId, LastUpdatedByTransactionId = chargeMessage.Transaction.MRID, Name = chargeMessage.MktActivityRecord.ChargeType.Name, RequestDateTime = chargeMessage.RequestDate.ToUnixTimeTicks(), ResolutionType = resolutionType, StartDate = chargeMessage.MktActivityRecord.ValidityStartDate.ToUnixTimeTicks(), EndDate = chargeMessage.MktActivityRecord.ValidityEndDate?.ToUnixTimeTicks(), Status = (int)chargeMessage.MktActivityRecord.Status, TaxIndicator = chargeMessage.MktActivityRecord.ChargeType.TaxIndicator, TransparentInvoicing = chargeMessage.MktActivityRecord.ChargeType.TransparentInvoicing, VatPayer = vatPayerType, MRid = chargeMessage.ChargeTypeMRid, Currency = "DKK", }; foreach (var point in chargeMessage.Period.Points) { var newChargePrice = new ChargePrice { Time = point.Time.ToUnixTimeTicks(), Amount = point.PriceAmount, LastUpdatedByCorrelationId = chargeMessage.CorrelationId, LastUpdatedByTransactionId = chargeMessage.Transaction.MRID, LastUpdatedBy = chargeMessage.LastUpdatedBy, RequestDateTime = chargeMessage.RequestDate.ToUnixTimeTicks(), }; charge.ChargePrices.Add(newChargePrice); } return(charge); }
public async Task <ChangeOfChargesMessageResult> HandleAsync([NotNull] ChangeOfChargesMessage message) { var result = await HandleTransactionsAsync(message).ConfigureAwait(false); return(result); }