From e095a8c680ec64616abd41e2158d8af029784feb Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Wed, 22 Nov 2023 17:56:54 +0000 Subject: [PATCH 1/2] Use security test helpers and create messaging helpers --- .github/workflows/createrelease.yml | 6 +- .github/workflows/pushtomaster.yml | 4 + .../MessagingService.Client.csproj | 2 +- ...ssagingService.EmailAggregate.Tests.csproj | 2 +- ...ngService.EmailMessage.DomainEvents.csproj | 4 +- ...sagingService.EmailMessageAggregate.csproj | 4 +- ...gService.IntegrationTesting.Helpers.csproj | 25 ++++ .../MessagingSteps.cs | 53 +++++++ .../SpecflowExtensions.cs | 69 +++++++++ .../Common/DockerHelper.cs | 6 +- .../Common/GenericSteps.cs | 3 +- .../Common/SpecflowTableHelper.cs | 136 +++++++++--------- .../Common/TestingContext.cs | 2 +- .../Email/SendEmail.feature | 4 +- .../Email/SendEmail.feature.cs | 6 +- .../Email/SendEmailSteps.cs | 67 ++------- .../MessagingService.IntegrationTests.csproj | 8 +- .../SMS/SendSMS.feature | 2 +- .../SMS/SendSMS.feature.cs | 4 +- .../SMS/SendSMSSteps.cs | 33 ++--- .../Shared/SharedSteps.cs | 113 +++------------ .../Class1.cs | 0 .../Messaging.Models.csproj | 0 ...gingService.SMSMessage.DomainEvents.csproj | 2 +- ...essagingService.SMSMessageAggregate.csproj | 2 +- MessagingService.sln | 7 + .../Bootstrapper/RepositoryRegistry.cs | 5 + MessagingService/Common/Extensions.cs | 3 + MessagingService/MessagingService.csproj | 2 +- 29 files changed, 305 insertions(+), 269 deletions(-) create mode 100644 MessagingService.IntegrationTesting.Helpers/MessagingService.IntegrationTesting.Helpers.csproj create mode 100644 MessagingService.IntegrationTesting.Helpers/MessagingSteps.cs create mode 100644 MessagingService.IntegrationTesting.Helpers/SpecflowExtensions.cs rename {Messaging.Models => MessagingService.Models}/Class1.cs (100%) rename {Messaging.Models => MessagingService.Models}/Messaging.Models.csproj (100%) diff --git a/.github/workflows/createrelease.yml b/.github/workflows/createrelease.yml index d5851aa..7d3e4ff 100644 --- a/.github/workflows/createrelease.yml +++ b/.github/workflows/createrelease.yml @@ -127,4 +127,8 @@ jobs: dotnet pack "MessagingService.Client\MessagingService.Client.csproj" /p:PackageVersion=${{ steps.get_version.outputs.VERSION }} --output Nugets -c Release dotnet nuget push Nugets/MessagingService.Client.${{ steps.get_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} dotnet pack "MessagingService.EmailMessage.DomainEvents\MessagingService.EmailMessage.DomainEvents.csproj" /p:PackageVersion=${{ steps.get_version.outputs.VERSION }} --output Nugets -c Release - dotnet nuget push Nugets/MessagingService.EmailMessage.DomainEvents.${{ steps.get_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} \ No newline at end of file + dotnet nuget push Nugets/MessagingService.EmailMessage.DomainEvents.${{ steps.get_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} + dotnet pack "MessagingService.EmailMessage.DomainEvents\MessagingService.EmailMessage.DomainEvents.csproj" /p:PackageVersion=${{ steps.get_version.outputs.VERSION }} --output Nugets -c Release + dotnet nuget push Nugets/MessagingService.EmailMessage.DomainEvents.${{ steps.get_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} + dotnet pack "MessagingService.IntegrationTesting.Helpers\MessagingService.IntegrationTesting.Helpers.csproj" /p:PackageVersion=${{ steps.get_version.outputs.VERSION }} --output Nugets -c Release + dotnet nuget push Nugets/MessagingService.IntegrationTesting.Helpers.${{ steps.get_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} \ No newline at end of file diff --git a/.github/workflows/pushtomaster.yml b/.github/workflows/pushtomaster.yml index dd3111b..efa10bc 100644 --- a/.github/workflows/pushtomaster.yml +++ b/.github/workflows/pushtomaster.yml @@ -48,6 +48,10 @@ jobs: dotnet nuget push Nugets/MessagingService.Client.${{ steps.next_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} dotnet pack "MessagingService.EmailMessage.DomainEvents\MessagingService.EmailMessage.DomainEvents.csproj" /p:PackageVersion=${{ steps.next_version.outputs.VERSION }} --output Nugets -c Release dotnet nuget push Nugets/MessagingService.EmailMessage.DomainEvents.${{ steps.next_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} + dotnet pack "MessagingService.SMSMessage.DomainEvents\MessagingService.SMSMessage.DomainEvents.csproj" /p:PackageVersion=${{ steps.next_version.outputs.VERSION }} --output Nugets -c Release + dotnet nuget push Nugets/MessagingService.SMSMessage.DomainEvents.${{ steps.next_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} + dotnet pack "MessagingService.IntegrationTesting.Helpers\MessagingService.IntegrationTesting.Helpers.csproj" /p:PackageVersion=${{ steps.next_version.outputs.VERSION }} --output Nugets -c Release + dotnet nuget push Nugets/MessagingService.IntegrationTesting.Helpers.${{ steps.next_version.outputs.VERSION }}.nupkg --api-key ${{ secrets.PRIVATEFEED_APIKEY }} --source ${{ secrets.PRIVATEFEED_URL }} - name: Publish Images to Docker Hub run: | diff --git a/MessagingService.Client/MessagingService.Client.csproj b/MessagingService.Client/MessagingService.Client.csproj index 4dede13..b304f32 100644 --- a/MessagingService.Client/MessagingService.Client.csproj +++ b/MessagingService.Client/MessagingService.Client.csproj @@ -6,7 +6,7 @@ - + diff --git a/MessagingService.EmailAggregate.Tests/MessagingService.EmailAggregate.Tests.csproj b/MessagingService.EmailAggregate.Tests/MessagingService.EmailAggregate.Tests.csproj index f530d8e..40f1223 100644 --- a/MessagingService.EmailAggregate.Tests/MessagingService.EmailAggregate.Tests.csproj +++ b/MessagingService.EmailAggregate.Tests/MessagingService.EmailAggregate.Tests.csproj @@ -8,7 +8,7 @@ - + diff --git a/MessagingService.EmailMessage.DomainEvents/MessagingService.EmailMessage.DomainEvents.csproj b/MessagingService.EmailMessage.DomainEvents/MessagingService.EmailMessage.DomainEvents.csproj index 4cac690..c53b5d2 100644 --- a/MessagingService.EmailMessage.DomainEvents/MessagingService.EmailMessage.DomainEvents.csproj +++ b/MessagingService.EmailMessage.DomainEvents/MessagingService.EmailMessage.DomainEvents.csproj @@ -5,8 +5,8 @@ - - + + diff --git a/MessagingService.EmailMessageAggregate/MessagingService.EmailMessageAggregate.csproj b/MessagingService.EmailMessageAggregate/MessagingService.EmailMessageAggregate.csproj index f9ee6af..c7242d0 100644 --- a/MessagingService.EmailMessageAggregate/MessagingService.EmailMessageAggregate.csproj +++ b/MessagingService.EmailMessageAggregate/MessagingService.EmailMessageAggregate.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/MessagingService.IntegrationTesting.Helpers/MessagingService.IntegrationTesting.Helpers.csproj b/MessagingService.IntegrationTesting.Helpers/MessagingService.IntegrationTesting.Helpers.csproj new file mode 100644 index 0000000..c4e15d3 --- /dev/null +++ b/MessagingService.IntegrationTesting.Helpers/MessagingService.IntegrationTesting.Helpers.csproj @@ -0,0 +1,25 @@ + + + + net7.0 + enable + enable + + + + + + + + + + + + + + + + + + + diff --git a/MessagingService.IntegrationTesting.Helpers/MessagingSteps.cs b/MessagingService.IntegrationTesting.Helpers/MessagingSteps.cs new file mode 100644 index 0000000..45406e7 --- /dev/null +++ b/MessagingService.IntegrationTesting.Helpers/MessagingSteps.cs @@ -0,0 +1,53 @@ +namespace MessagingService.IntegrationTesting.Helpers +{ + using System; + using System.Collections.Generic; + using System.Threading; + using System.Threading.Tasks; + using MessagingService.Client; + using MessagingService.DataTransferObjects; + using Shared.IntegrationTesting; + using Shouldly; + + public class MessagingSteps{ + private readonly IMessagingServiceClient MessagingServiceClient; + + public MessagingSteps(IMessagingServiceClient messagingServiceClient){ + this.MessagingServiceClient = messagingServiceClient; + } + + public async Task> GivenISendTheFollowingEmailMessages(String accessToken, List requests){ + List<(String, SendEmailResponse)> results = new List<(String, SendEmailResponse)>(); + foreach (SendEmailRequest sendEmailRequest in requests){ + SendEmailResponse sendEmailResponse = await this.MessagingServiceClient.SendEmail(accessToken, sendEmailRequest, CancellationToken.None).ConfigureAwait(false); + + sendEmailResponse.MessageId.ShouldNotBe(Guid.Empty); + results.Add((String.Join(",", sendEmailRequest.ToAddresses), sendEmailResponse)); + } + return results; + } + + public async Task GivenISendTheFollowingSMSMessages(String accessToken, List requests) + { + foreach (SendSMSRequest sendSmsRequest in requests) + { + SendSMSResponse sendEmailResponse = await this.MessagingServiceClient.SendSMS(accessToken, sendSmsRequest, CancellationToken.None).ConfigureAwait(false); + + sendEmailResponse.MessageId.ShouldNotBe(Guid.Empty); + } + } + + public async Task WhenIResendTheFollowingMessages(String accessToken, List requests){ + foreach (ResendEmailRequest resendEmailRequest in requests){ + await Retry.For(async () => { + Should.NotThrow(async () => { + await this.MessagingServiceClient.ResendEmail(accessToken, + resendEmailRequest, + CancellationToken.None); + }); + }); + } + } + + } +} diff --git a/MessagingService.IntegrationTesting.Helpers/SpecflowExtensions.cs b/MessagingService.IntegrationTesting.Helpers/SpecflowExtensions.cs new file mode 100644 index 0000000..00521d7 --- /dev/null +++ b/MessagingService.IntegrationTesting.Helpers/SpecflowExtensions.cs @@ -0,0 +1,69 @@ +namespace MessagingService.IntegrationTesting.Helpers; + +using MessagingService.DataTransferObjects; +using Shared.IntegrationTesting; +using TechTalk.SpecFlow; + +public static class SpecflowExtensions{ + public static List ToSendEmailRequests(this TableRows tableRows){ + List requests = new List(); + foreach (TableRow tableRow in tableRows){ + String fromAddress = SpecflowTableHelper.GetStringRowValue(tableRow, "FromAddress"); + String toAddresses = SpecflowTableHelper.GetStringRowValue(tableRow, "ToAddresses"); + String subject = SpecflowTableHelper.GetStringRowValue(tableRow, "Subject"); + String body = SpecflowTableHelper.GetStringRowValue(tableRow, "Body"); + Boolean isHtml = SpecflowTableHelper.GetBooleanValue(tableRow, "IsHtml"); + + SendEmailRequest request = new SendEmailRequest + { + Body = body, + ConnectionIdentifier = Guid.NewGuid(), + FromAddress = fromAddress, + IsHtml = isHtml, + Subject = subject, + ToAddresses = toAddresses.Split(",").ToList() + }; + requests.Add(request); + } + + return requests; + } + + public static List ToResendEmailRequests(this TableRows tableRows, Dictionary sendResponses) + { + List requests = new List(); + + foreach (TableRow tableRow in tableRows){ + String toAddresses = SpecflowTableHelper.GetStringRowValue(tableRow, "ToAddresses"); + SendEmailResponse sendEmailResponse = sendResponses[toAddresses]; + + ResendEmailRequest request = new ResendEmailRequest() + { + ConnectionIdentifier = Guid.NewGuid(), + MessageId = sendEmailResponse.MessageId + }; + requests.Add(request); + } + return requests; + } + + public static List ToSendSMSRequests(this TableRows tableRows){ + List requests = new List(); + + foreach (TableRow tableRow in tableRows){ + String sender = SpecflowTableHelper.GetStringRowValue(tableRow, "Sender"); + String destination = SpecflowTableHelper.GetStringRowValue(tableRow, "Destination"); + String message = SpecflowTableHelper.GetStringRowValue(tableRow, "Message"); + + SendSMSRequest request = new SendSMSRequest + { + ConnectionIdentifier = Guid.NewGuid(), + Sender = sender, + Destination = destination, + Message = message + }; + requests.Add(request); + } + return requests; + } +} \ No newline at end of file diff --git a/MessagingService.IntegrationTests/Common/DockerHelper.cs b/MessagingService.IntegrationTests/Common/DockerHelper.cs index a0fedb0..0a0b771 100644 --- a/MessagingService.IntegrationTests/Common/DockerHelper.cs +++ b/MessagingService.IntegrationTests/Common/DockerHelper.cs @@ -11,6 +11,7 @@ using Ductus.FluentDocker.Model.Builders; using Ductus.FluentDocker.Services; using Ductus.FluentDocker.Services.Extensions; + using global::Shared.IntegrationTesting; using global::Shared.Logger; using SecurityService.Client; @@ -59,9 +60,8 @@ public DockerHelper() /// Starts the containers for scenario run. /// /// Name of the scenario. - public override async Task StartContainersForScenarioRun(String scenarioName) - { - await base.StartContainersForScenarioRun(scenarioName); + public override async Task StartContainersForScenarioRun(String scenarioName, DockerServices dockerServices){ + await base.StartContainersForScenarioRun(scenarioName, dockerServices); // Setup the base address resolvers String SecurityServiceBaseAddressResolver(String api) => $"https://127.0.0.1:{this.SecurityServicePort}"; diff --git a/MessagingService.IntegrationTests/Common/GenericSteps.cs b/MessagingService.IntegrationTests/Common/GenericSteps.cs index 2525f07..ce6ac18 100644 --- a/MessagingService.IntegrationTests/Common/GenericSteps.cs +++ b/MessagingService.IntegrationTests/Common/GenericSteps.cs @@ -45,7 +45,8 @@ public async Task StartSystem() this.TestingContext.Logger = logger; this.TestingContext.Logger.LogInformation("About to Start Containers for Scenario Run"); - await this.TestingContext.DockerHelper.StartContainersForScenarioRun(scenarioName).ConfigureAwait(false); + DockerServices dockerServices = DockerServices.MessagingService | DockerServices.EventStore | DockerServices.SecurityService; + await this.TestingContext.DockerHelper.StartContainersForScenarioRun(scenarioName, dockerServices).ConfigureAwait(false); this.TestingContext.Logger.LogInformation("Containers for Scenario Run Started"); } diff --git a/MessagingService.IntegrationTests/Common/SpecflowTableHelper.cs b/MessagingService.IntegrationTests/Common/SpecflowTableHelper.cs index 8b0ae2c..8fc55dc 100644 --- a/MessagingService.IntegrationTests/Common/SpecflowTableHelper.cs +++ b/MessagingService.IntegrationTests/Common/SpecflowTableHelper.cs @@ -5,83 +5,83 @@ namespace MessagingService.IntegrationTests.Common { - public static class SpecflowTableHelper - { - #region Methods + //public static class SpecflowTableHelper + //{ + // #region Methods - public static Decimal GetDecimalValue(TableRow row, - String key) - { - String field = SpecflowTableHelper.GetStringRowValue(row, key); + // public static Decimal GetDecimalValue(TableRow row, + // String key) + // { + // String field = SpecflowTableHelper.GetStringRowValue(row, key); - return Decimal.TryParse(field, out Decimal value) ? value : -1; - } + // return Decimal.TryParse(field, out Decimal value) ? value : -1; + // } - public static Boolean GetBooleanValue(TableRow row, - String key) - { - String field = SpecflowTableHelper.GetStringRowValue(row, key); + // public static Boolean GetBooleanValue(TableRow row, + // String key) + // { + // String field = SpecflowTableHelper.GetStringRowValue(row, key); - return Boolean.TryParse(field, out Boolean value) && value; - } + // return Boolean.TryParse(field, out Boolean value) && value; + // } - public static Int32 GetIntValue(TableRow row, - String key) - { - String field = SpecflowTableHelper.GetStringRowValue(row, key); + // public static Int32 GetIntValue(TableRow row, + // String key) + // { + // String field = SpecflowTableHelper.GetStringRowValue(row, key); - return Int32.TryParse(field, out Int32 value) ? value : -1; - } + // return Int32.TryParse(field, out Int32 value) ? value : -1; + // } - public static Int16 GetShortValue(TableRow row, - String key) - { - String field = SpecflowTableHelper.GetStringRowValue(row, key); + // public static Int16 GetShortValue(TableRow row, + // String key) + // { + // String field = SpecflowTableHelper.GetStringRowValue(row, key); - if (Int16.TryParse(field, out Int16 value)) - { - return value; - } - else - { - return -1; - } - } + // if (Int16.TryParse(field, out Int16 value)) + // { + // return value; + // } + // else + // { + // return -1; + // } + // } - public static String GetStringRowValue(TableRow row, - String key) - { - return row.TryGetValue(key, out String value) ? value : ""; - } + // public static String GetStringRowValue(TableRow row, + // String key) + // { + // return row.TryGetValue(key, out String value) ? value : ""; + // } - /// - /// Gets the date for date string. - /// - /// The date string. - /// The today. - /// - public static DateTime GetDateForDateString(String dateString, - DateTime today) - { - switch (dateString.ToUpper()) - { - case "TODAY": - return today.Date; - case "YESTERDAY": - return today.AddDays(-1).Date; - case "LASTWEEK": - return today.AddDays(-7).Date; - case "LASTMONTH": - return today.AddMonths(-1).Date; - case "LASTYEAR": - return today.AddYears(-1).Date; - case "TOMORROW": - return today.AddDays(1).Date; - default: - return DateTime.Parse(dateString); - } - } + // /// + // /// Gets the date for date string. + // /// + // /// The date string. + // /// The today. + // /// + // public static DateTime GetDateForDateString(String dateString, + // DateTime today) + // { + // switch (dateString.ToUpper()) + // { + // case "TODAY": + // return today.Date; + // case "YESTERDAY": + // return today.AddDays(-1).Date; + // case "LASTWEEK": + // return today.AddDays(-7).Date; + // case "LASTMONTH": + // return today.AddMonths(-1).Date; + // case "LASTYEAR": + // return today.AddYears(-1).Date; + // case "TOMORROW": + // return today.AddDays(1).Date; + // default: + // return DateTime.Parse(dateString); + // } + // } - #endregion - } + // #endregion + //} } diff --git a/MessagingService.IntegrationTests/Common/TestingContext.cs b/MessagingService.IntegrationTests/Common/TestingContext.cs index b19e39e..14bf334 100644 --- a/MessagingService.IntegrationTests/Common/TestingContext.cs +++ b/MessagingService.IntegrationTests/Common/TestingContext.cs @@ -47,7 +47,7 @@ public SendEmailResponse GetEmailResponse(String identifier) { return this.EmailResponses[identifier]; } - private Dictionary EmailResponses; + public Dictionary EmailResponses; } public class ClientDetails diff --git a/MessagingService.IntegrationTests/Email/SendEmail.feature b/MessagingService.IntegrationTests/Email/SendEmail.feature index a6b423b..8a9694e 100644 --- a/MessagingService.IntegrationTests/Email/SendEmail.feature +++ b/MessagingService.IntegrationTests/Email/SendEmail.feature @@ -8,11 +8,11 @@ Background: | messagingService | Messaging REST Scope | A scope for Messaging REST | Given the following api resources exist - | ResourceName | DisplayName | Secret | Scopes | UserClaims | + | Name | DisplayName | Secret | Scopes | UserClaims | | messagingService | Messaging REST | Secret1 | messagingService | | Given the following clients exist - | ClientId | ClientName | Secret | AllowedScopes | AllowedGrantTypes | + | ClientId | ClientName | Secret | Scopes | GrantTypes | | serviceClient | Service Client | Secret1 | messagingService | client_credentials | Given I have a token to access the messaging service resource diff --git a/MessagingService.IntegrationTests/Email/SendEmail.feature.cs b/MessagingService.IntegrationTests/Email/SendEmail.feature.cs index 66b9bbb..f0e1d25 100644 --- a/MessagingService.IntegrationTests/Email/SendEmail.feature.cs +++ b/MessagingService.IntegrationTests/Email/SendEmail.feature.cs @@ -97,7 +97,7 @@ public virtual void FeatureBackground() testRunner.Given("I create the following api scopes", ((string)(null)), table1, "Given "); #line hidden TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] { - "ResourceName", + "Name", "DisplayName", "Secret", "Scopes", @@ -115,8 +115,8 @@ public virtual void FeatureBackground() "ClientId", "ClientName", "Secret", - "AllowedScopes", - "AllowedGrantTypes"}); + "Scopes", + "GrantTypes"}); table3.AddRow(new string[] { "serviceClient", "Service Client", diff --git a/MessagingService.IntegrationTests/Email/SendEmailSteps.cs b/MessagingService.IntegrationTests/Email/SendEmailSteps.cs index 5f3bbe3..4f5b315 100644 --- a/MessagingService.IntegrationTests/Email/SendEmailSteps.cs +++ b/MessagingService.IntegrationTests/Email/SendEmailSteps.cs @@ -3,6 +3,7 @@ namespace MessagingService.IntegrationTests.Email { + using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; @@ -13,9 +14,10 @@ namespace MessagingService.IntegrationTests.Email using Common; using DataTransferObjects; using global::Shared.IntegrationTesting; + using IntegrationTesting.Helpers; using Newtonsoft.Json; + using Shared; using Shouldly; - using SpecflowTableHelper = Common.SpecflowTableHelper; [Binding] [Scope(Tag = "email")] @@ -25,74 +27,31 @@ public class SendEmailSteps private readonly TestingContext TestingContext; + private readonly MessagingSteps MessagingSteps; + public SendEmailSteps(ScenarioContext scenarioContext, TestingContext testingContext) { this.ScenarioContext = scenarioContext; this.TestingContext = testingContext; + this.MessagingSteps = new MessagingSteps(this.TestingContext.DockerHelper.MessagingServiceClient); } [Given(@"I send the following Email Messages")] - public async Task GivenISendTheFollowingEmailMessages(Table table) - { - foreach (TableRow tableRow in table.Rows) - { - await this.SendEmail(tableRow); + public async Task GivenISendTheFollowingEmailMessages(Table table){ + List requests = table.Rows.ToSendEmailRequests(); + List<(String, SendEmailResponse)> results = await this.MessagingSteps.GivenISendTheFollowingEmailMessages(this.TestingContext.AccessToken, requests); + foreach ((String, SendEmailResponse) result in results){ + this.TestingContext.AddEmailResponse(result.Item1, result.Item2); } } [When(@"I resend the following messages")] public async Task WhenIResendTheFollowingMessages(Table table) { - foreach (TableRow tableRow in table.Rows) - { - await this.ResendEmail(tableRow); - } - } - - private async Task SendEmail(TableRow tableRow) - { - String fromAddress = SpecflowTableHelper.GetStringRowValue(tableRow, "FromAddress"); - String toAddresses = SpecflowTableHelper.GetStringRowValue(tableRow, "ToAddresses"); - String subject = SpecflowTableHelper.GetStringRowValue(tableRow, "Subject"); - String body = SpecflowTableHelper.GetStringRowValue(tableRow, "Body"); - Boolean isHtml = SpecflowTableHelper.GetBooleanValue(tableRow, "IsHtml"); - - SendEmailRequest request = new SendEmailRequest - { - Body = body, - ConnectionIdentifier = Guid.NewGuid(), - FromAddress = fromAddress, - IsHtml = isHtml, - Subject = subject, - ToAddresses = toAddresses.Split(",").ToList() - }; - - SendEmailResponse sendEmailResponse = await this.TestingContext.DockerHelper.MessagingServiceClient.SendEmail(this.TestingContext.AccessToken, request, CancellationToken.None).ConfigureAwait(false); - - sendEmailResponse.MessageId.ShouldNotBe(Guid.Empty); - - this.TestingContext.AddEmailResponse(toAddresses, sendEmailResponse); + List requests = table.Rows.ToResendEmailRequests(this.TestingContext.EmailResponses); + await this.MessagingSteps.WhenIResendTheFollowingMessages(this.TestingContext.AccessToken, requests); } - private async Task ResendEmail(TableRow tableRow) - { - String toAddresses = SpecflowTableHelper.GetStringRowValue(tableRow, "ToAddresses"); - SendEmailResponse sendEmailResponse = this.TestingContext.GetEmailResponse(toAddresses); - - ResendEmailRequest request = new ResendEmailRequest() - { - ConnectionIdentifier = Guid.NewGuid(), - MessageId = sendEmailResponse.MessageId - }; - - await Retry.For(async () => { - Should.NotThrow(async () => { - await this.TestingContext.DockerHelper.MessagingServiceClient.ResendEmail(this.TestingContext.AccessToken, - request, - CancellationToken.None); - }); - }); - } } } diff --git a/MessagingService.IntegrationTests/MessagingService.IntegrationTests.csproj b/MessagingService.IntegrationTests/MessagingService.IntegrationTests.csproj index 82cb7ef..4aca44a 100644 --- a/MessagingService.IntegrationTests/MessagingService.IntegrationTests.csproj +++ b/MessagingService.IntegrationTests/MessagingService.IntegrationTests.csproj @@ -6,11 +6,12 @@ - + - - + + + @@ -26,6 +27,7 @@ + diff --git a/MessagingService.IntegrationTests/SMS/SendSMS.feature b/MessagingService.IntegrationTests/SMS/SendSMS.feature index fc685f7..e5a6861 100644 --- a/MessagingService.IntegrationTests/SMS/SendSMS.feature +++ b/MessagingService.IntegrationTests/SMS/SendSMS.feature @@ -12,7 +12,7 @@ Background: | messagingService | Messaging REST | Secret1 | messagingService | | Given the following clients exist - | ClientId | ClientName | Secret | AllowedScopes | AllowedGrantTypes | + | ClientId | ClientName | Secret | Scopes | GrantTypes | | serviceClient | Service Client | Secret1 | messagingService | client_credentials | Given I have a token to access the messaging service resource diff --git a/MessagingService.IntegrationTests/SMS/SendSMS.feature.cs b/MessagingService.IntegrationTests/SMS/SendSMS.feature.cs index 74ea19e..006d2c0 100644 --- a/MessagingService.IntegrationTests/SMS/SendSMS.feature.cs +++ b/MessagingService.IntegrationTests/SMS/SendSMS.feature.cs @@ -115,8 +115,8 @@ public virtual void FeatureBackground() "ClientId", "ClientName", "Secret", - "AllowedScopes", - "AllowedGrantTypes"}); + "Scopes", + "GrantTypes"}); table10.AddRow(new string[] { "serviceClient", "Service Client", diff --git a/MessagingService.IntegrationTests/SMS/SendSMSSteps.cs b/MessagingService.IntegrationTests/SMS/SendSMSSteps.cs index d176f6f..2806127 100644 --- a/MessagingService.IntegrationTests/SMS/SendSMSSteps.cs +++ b/MessagingService.IntegrationTests/SMS/SendSMSSteps.cs @@ -3,11 +3,14 @@ namespace MessagingService.IntegrationTests.SMS { + using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Common; using DataTransferObjects; + using IntegrationTesting.Helpers; + using Shared; using Shouldly; [Binding] @@ -18,39 +21,19 @@ public class SendSMSSteps private readonly TestingContext TestingContext; + private readonly MessagingSteps MessagingSteps; public SendSMSSteps(ScenarioContext scenarioContext, TestingContext testingContext) { this.ScenarioContext = scenarioContext; this.TestingContext = testingContext; + this.MessagingSteps = new MessagingSteps(testingContext.DockerHelper.MessagingServiceClient); } [Given(@"I send the following SMS Messages")] - public async Task GivenISendTheFollowingSMSMessages(Table table) - { - foreach (TableRow tableRow in table.Rows) - { - await this.SendSMS(tableRow); - } - } - - private async Task SendSMS(TableRow tableRow) - { - String sender = SpecflowTableHelper.GetStringRowValue(tableRow, "Sender"); - String destination = SpecflowTableHelper.GetStringRowValue(tableRow, "Destination"); - String message = SpecflowTableHelper.GetStringRowValue(tableRow, "Message"); - - SendSMSRequest request = new SendSMSRequest - { - ConnectionIdentifier = Guid.NewGuid(), - Sender = sender, - Destination = destination, - Message = message - }; - - SendSMSResponse sendEmailResponse = await this.TestingContext.DockerHelper.MessagingServiceClient.SendSMS(this.TestingContext.AccessToken, request, CancellationToken.None).ConfigureAwait(false); - - sendEmailResponse.MessageId.ShouldNotBe(Guid.Empty); + public async Task GivenISendTheFollowingSMSMessages(Table table){ + List requests = table.Rows.ToSendSMSRequests(); + await this.MessagingSteps.GivenISendTheFollowingSMSMessages(this.TestingContext.AccessToken, requests); } } } diff --git a/MessagingService.IntegrationTests/Shared/SharedSteps.cs b/MessagingService.IntegrationTests/Shared/SharedSteps.cs index 122e3ba..3152d78 100644 --- a/MessagingService.IntegrationTests/Shared/SharedSteps.cs +++ b/MessagingService.IntegrationTests/Shared/SharedSteps.cs @@ -12,7 +12,9 @@ namespace MessagingService.IntegrationTests.Shared { + using global::Shared.IntegrationTesting; using SecurityService.DataTransferObjects; + using SecurityService.IntegrationTesting.Helpers; using ClientDetails = Common.ClientDetails; [Binding] @@ -23,130 +25,49 @@ public class SharedSteps private readonly TestingContext TestingContext; + private readonly SecurityServiceSteps SecurityServiceSteps; + public SharedSteps(ScenarioContext scenarioContext, TestingContext testingContext) { this.ScenarioContext = scenarioContext; this.TestingContext = testingContext; + this.SecurityServiceSteps = new SecurityServiceSteps(testingContext.DockerHelper.SecurityServiceClient); } [Given(@"I create the following api scopes")] public async Task GivenICreateTheFollowingApiScopes(Table table) { - foreach (TableRow tableRow in table.Rows) - { - CreateApiScopeRequest createApiScopeRequest = new CreateApiScopeRequest - { - Name = SpecflowTableHelper.GetStringRowValue(tableRow, "Name"), - Description = SpecflowTableHelper.GetStringRowValue(tableRow, "Description"), - DisplayName = SpecflowTableHelper.GetStringRowValue(tableRow, "DisplayName") - }; - var createApiScopeResponse = - await this.CreateApiScope(createApiScopeRequest, CancellationToken.None).ConfigureAwait(false); - - createApiScopeResponse.ShouldNotBeNull(); - createApiScopeResponse.ApiScopeName.ShouldNotBeNullOrEmpty(); - } - } - - private async Task CreateApiScope(CreateApiScopeRequest createApiScopeRequest, - CancellationToken cancellationToken) - { - CreateApiScopeResponse createApiScopeResponse = await this.TestingContext.DockerHelper.SecurityServiceClient.CreateApiScope(createApiScopeRequest, cancellationToken).ConfigureAwait(false); - return createApiScopeResponse; + List requests = table.Rows.ToCreateApiScopeRequests(); + await this.SecurityServiceSteps.GivenICreateTheFollowingApiScopes(requests); } [Given(@"the following api resources exist")] public async Task GivenTheFollowingApiResourcesExist(Table table) { - foreach (TableRow tableRow in table.Rows) - { - String resourceName = SpecflowTableHelper.GetStringRowValue(tableRow, "ResourceName"); - String displayName = SpecflowTableHelper.GetStringRowValue(tableRow, "DisplayName"); - String secret = SpecflowTableHelper.GetStringRowValue(tableRow, "Secret"); - String scopes = SpecflowTableHelper.GetStringRowValue(tableRow, "Scopes"); - String userClaims = SpecflowTableHelper.GetStringRowValue(tableRow, "UserClaims"); - - List splitScopes = scopes.Split(",").ToList(); - List splitUserClaims = userClaims.Split(",").ToList(); - - CreateApiResourceRequest createApiResourceRequest = new CreateApiResourceRequest - { - Description = String.Empty, - DisplayName = displayName, - Name = resourceName, - Scopes = new List(), - Secret = secret, - UserClaims = new List() - }; - splitScopes.ForEach(a => - { - createApiResourceRequest.Scopes.Add(a.Trim()); - }); - splitUserClaims.ForEach(a => - { - createApiResourceRequest.UserClaims.Add(a.Trim()); - }); - - CreateApiResourceResponse createApiResourceResponse = await this.TestingContext.DockerHelper.SecurityServiceClient.CreateApiResource(createApiResourceRequest, CancellationToken.None).ConfigureAwait(false); - - createApiResourceResponse.ApiResourceName.ShouldBe(resourceName); - } + List requests = table.Rows.ToCreateApiResourceRequests(); + await this.SecurityServiceSteps.GivenTheFollowingApiResourcesExist(requests); } [Given(@"the following clients exist")] public async Task GivenTheFollowingClientsExist(Table table) { - foreach (TableRow tableRow in table.Rows) + List requests = table.Rows.ToCreateClientRequests(); + List<(String clientId, String secret, List allowedGrantTypes)> clients = await this.SecurityServiceSteps.GivenTheFollowingClientsExist(requests); + foreach ((String clientId, String secret, List allowedGrantTypes) client in clients) { - String clientId = SpecflowTableHelper.GetStringRowValue(tableRow, "ClientId"); - String clientName = SpecflowTableHelper.GetStringRowValue(tableRow, "ClientName"); - String secret = SpecflowTableHelper.GetStringRowValue(tableRow, "Secret"); - String allowedScopes = SpecflowTableHelper.GetStringRowValue(tableRow, "AllowedScopes"); - String allowedGrantTypes = SpecflowTableHelper.GetStringRowValue(tableRow, "AllowedGrantTypes"); - - List splitAllowedScopes = allowedScopes.Split(",").ToList(); - List splitAllowedGrantTypes = allowedGrantTypes.Split(",").ToList(); - - CreateClientRequest createClientRequest = new CreateClientRequest - { - Secret = secret, - AllowedGrantTypes = new List(), - AllowedScopes = new List(), - ClientDescription = String.Empty, - ClientId = clientId, - ClientName = clientName - }; - - splitAllowedScopes.ForEach(a => { createClientRequest.AllowedScopes.Add(a.Trim()); }); - splitAllowedGrantTypes.ForEach(a => { createClientRequest.AllowedGrantTypes.Add(a.Trim()); }); - - CreateClientResponse createClientResponse = await this.TestingContext.DockerHelper.SecurityServiceClient - .CreateClient(createClientRequest, CancellationToken.None).ConfigureAwait(false); - - createClientResponse.ClientId.ShouldBe(clientId); - - this.TestingContext.AddClientDetails(clientId, secret, allowedGrantTypes); + this.TestingContext.AddClientDetails(client.clientId, client.secret, String.Join(",", client.allowedGrantTypes)); } } [Given(@"I have a token to access the messaging service resource")] public async Task GivenIHaveATokenToAccessTheMessagingServiceResource(Table table) { - foreach (TableRow tableRow in table.Rows) - { - String clientId = SpecflowTableHelper.GetStringRowValue(tableRow, "ClientId"); - - ClientDetails clientDetails = this.TestingContext.GetClientDetails(clientId); + TableRow firstRow = table.Rows.First(); + String clientId = SpecflowTableHelper.GetStringRowValue(firstRow, "ClientId"); + ClientDetails clientDetails = this.TestingContext.GetClientDetails(clientId); - if (clientDetails.GrantType == "client_credentials") - { - TokenResponse tokenResponse = await this.TestingContext.DockerHelper.SecurityServiceClient - .GetToken(clientId, clientDetails.ClientSecret, CancellationToken.None).ConfigureAwait(false); - - this.TestingContext.AccessToken = tokenResponse.AccessToken; - } - } + this.TestingContext.AccessToken = await this.SecurityServiceSteps.GetClientToken(clientDetails.ClientId, clientDetails.ClientSecret, CancellationToken.None); } } diff --git a/Messaging.Models/Class1.cs b/MessagingService.Models/Class1.cs similarity index 100% rename from Messaging.Models/Class1.cs rename to MessagingService.Models/Class1.cs diff --git a/Messaging.Models/Messaging.Models.csproj b/MessagingService.Models/Messaging.Models.csproj similarity index 100% rename from Messaging.Models/Messaging.Models.csproj rename to MessagingService.Models/Messaging.Models.csproj diff --git a/MessagingService.SMSMessage.DomainEvents/MessagingService.SMSMessage.DomainEvents.csproj b/MessagingService.SMSMessage.DomainEvents/MessagingService.SMSMessage.DomainEvents.csproj index a689551..5cd96fe 100644 --- a/MessagingService.SMSMessage.DomainEvents/MessagingService.SMSMessage.DomainEvents.csproj +++ b/MessagingService.SMSMessage.DomainEvents/MessagingService.SMSMessage.DomainEvents.csproj @@ -5,7 +5,7 @@ - + diff --git a/MessagingService.SMSMessageAggregate/MessagingService.SMSMessageAggregate.csproj b/MessagingService.SMSMessageAggregate/MessagingService.SMSMessageAggregate.csproj index 7be6d50..c997b7e 100644 --- a/MessagingService.SMSMessageAggregate/MessagingService.SMSMessageAggregate.csproj +++ b/MessagingService.SMSMessageAggregate/MessagingService.SMSMessageAggregate.csproj @@ -6,7 +6,7 @@ - + diff --git a/MessagingService.sln b/MessagingService.sln index 0185196..07cff92 100644 --- a/MessagingService.sln +++ b/MessagingService.sln @@ -37,6 +37,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagingService.SMSAggrega EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagingService.Models", "MessagingService.Models\MessagingService.Models.csproj", "{327FAE7D-AF25-4380-AA8B-9FF7FCF46FBB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessagingService.IntegrationTesting.Helpers", "MessagingService.IntegrationTesting.Helpers\MessagingService.IntegrationTesting.Helpers.csproj", "{B0C7F0FC-926D-407E-9301-A828BD215F3A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -103,6 +105,10 @@ Global {327FAE7D-AF25-4380-AA8B-9FF7FCF46FBB}.Debug|Any CPU.Build.0 = Debug|Any CPU {327FAE7D-AF25-4380-AA8B-9FF7FCF46FBB}.Release|Any CPU.ActiveCfg = Release|Any CPU {327FAE7D-AF25-4380-AA8B-9FF7FCF46FBB}.Release|Any CPU.Build.0 = Release|Any CPU + {B0C7F0FC-926D-407E-9301-A828BD215F3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B0C7F0FC-926D-407E-9301-A828BD215F3A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B0C7F0FC-926D-407E-9301-A828BD215F3A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B0C7F0FC-926D-407E-9301-A828BD215F3A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -123,6 +129,7 @@ Global {6699EB4E-7F56-468D-9F1A-D094B8A19BAA} = {BF2482A1-13C0-4305-B732-AB62EBD9429B} {883DEFD0-7DDB-4F79-9996-2279E71CAF5B} = {9AEE6ADE-DD45-4605-A933-E06CF0BA4203} {327FAE7D-AF25-4380-AA8B-9FF7FCF46FBB} = {BF2482A1-13C0-4305-B732-AB62EBD9429B} + {B0C7F0FC-926D-407E-9301-A828BD215F3A} = {9AEE6ADE-DD45-4605-A933-E06CF0BA4203} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {1929C0FE-8CEB-4D0E-BD22-9E5E16E2B49F} diff --git a/MessagingService/Bootstrapper/RepositoryRegistry.cs b/MessagingService/Bootstrapper/RepositoryRegistry.cs index f3a8eca..9072344 100644 --- a/MessagingService/Bootstrapper/RepositoryRegistry.cs +++ b/MessagingService/Bootstrapper/RepositoryRegistry.cs @@ -14,6 +14,7 @@ using Shared.EntityFramework.ConnectionStringConfiguration; using Shared.EventStore.Aggregate; using Shared.EventStore.EventStore; +using Shared.EventStore.SubscriptionWorker; using Shared.General; using Shared.Repositories; using SMSMessageAggregate; @@ -72,5 +73,9 @@ public RepositoryRegistry() this.AddSingleton, AggregateRepository>(); this.AddSingleton, AggregateRepository>(); + + this.AddSingleton>(cont => (esConnString, cacheDuration) => { + return SubscriptionRepository.Create(esConnString, cacheDuration); + }); } } \ No newline at end of file diff --git a/MessagingService/Common/Extensions.cs b/MessagingService/Common/Extensions.cs index b2adf8d..a816425 100644 --- a/MessagingService/Common/Extensions.cs +++ b/MessagingService/Common/Extensions.cs @@ -72,11 +72,14 @@ public static void PreWarm(this IApplicationBuilder applicationBuilder) {"Main", mainEventHandlerResolver} }; + Func subscriptionRepositoryResolver = Startup.Container.GetInstance>(); + applicationBuilder.ConfigureSubscriptionService(subscriptionWorkersRoot, eventStoreConnectionString, Startup.EventStoreClientSettings, eventHandlerResolvers, Extensions.log, + subscriptionRepositoryResolver, CancellationToken.None).Wait(CancellationToken.None); } } \ No newline at end of file diff --git a/MessagingService/MessagingService.csproj b/MessagingService/MessagingService.csproj index eaac880..191042b 100644 --- a/MessagingService/MessagingService.csproj +++ b/MessagingService/MessagingService.csproj @@ -18,7 +18,7 @@ - + From dc20dff104b67b543a78b7682e4b2a3c4cde8203 Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Wed, 22 Nov 2023 18:05:02 +0000 Subject: [PATCH 2/2] :| --- .../MessagingService.IntegrationTests.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/MessagingService.IntegrationTests/MessagingService.IntegrationTests.csproj b/MessagingService.IntegrationTests/MessagingService.IntegrationTests.csproj index 4aca44a..b5bc4e6 100644 --- a/MessagingService.IntegrationTests/MessagingService.IntegrationTests.csproj +++ b/MessagingService.IntegrationTests/MessagingService.IntegrationTests.csproj @@ -30,6 +30,7 @@ +