diff --git a/Directory.Packages.props b/Directory.Packages.props index 76b5f7658..ec7ab75d9 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -23,7 +23,7 @@ - + @@ -55,10 +55,8 @@ - - - + - + diff --git a/tests/LondonTravel.Site.Tests/BrowserTest.cs b/tests/LondonTravel.Site.Tests/BrowserTest.cs index fdcc445b6..7fbcb5129 100644 --- a/tests/LondonTravel.Site.Tests/BrowserTest.cs +++ b/tests/LondonTravel.Site.Tests/BrowserTest.cs @@ -45,14 +45,18 @@ public void Dispose() } /// - public Task InitializeAsync() + public ValueTask InitializeAsync() { InstallPlaywright(); - return Task.CompletedTask; + return ValueTask.CompletedTask; } /// - public Task DisposeAsync() => Task.CompletedTask; + public ValueTask DisposeAsync() + { + GC.SuppressFinalize(this); + return ValueTask.CompletedTask; + } /// /// Runs the specified test with a new instance of as an asynchronous operation. diff --git a/tests/LondonTravel.Site.Tests/EndToEnd/ApiTests.cs b/tests/LondonTravel.Site.Tests/EndToEnd/ApiTests.cs index eac559de3..a88d2aa0d 100644 --- a/tests/LondonTravel.Site.Tests/EndToEnd/ApiTests.cs +++ b/tests/LondonTravel.Site.Tests/EndToEnd/ApiTests.cs @@ -7,18 +7,18 @@ namespace MartinCostello.LondonTravel.Site.EndToEnd; -[Collection(WebsiteCollection.Name)] +[Collection] [Trait("Category", "EndToEnd")] public class ApiTests(WebsiteFixture fixture) { - [SkippableFact] + [Fact] public async Task Cannot_Get_Preferences_Unauthenticated() { // Arrange using var client = fixture.CreateClient(); // Act - using var response = await client.GetAsync("/api/preferences"); + using var response = await client.GetAsync("/api/preferences", TestContext.Current.CancellationToken); // Assert response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized); @@ -32,7 +32,7 @@ public async Task Cannot_Get_Preferences_Unauthenticated() result.RootElement.GetStringArray("details").ShouldBeEmpty(); } - [SkippableFact] + [Fact] public async Task Cannot_Get_Preferences_With_Invalid_Token() { // Arrange @@ -42,7 +42,7 @@ public async Task Cannot_Get_Preferences_With_Invalid_Token() client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", accessToken); // Act - using var response = await client.GetAsync("/api/preferences"); + using var response = await client.GetAsync("/api/preferences", TestContext.Current.CancellationToken); // Assert response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized); diff --git a/tests/LondonTravel.Site.Tests/EndToEnd/BrowserEndToEndTest.cs b/tests/LondonTravel.Site.Tests/EndToEnd/BrowserEndToEndTest.cs index 14e22d6aa..8e2bb2e82 100644 --- a/tests/LondonTravel.Site.Tests/EndToEnd/BrowserEndToEndTest.cs +++ b/tests/LondonTravel.Site.Tests/EndToEnd/BrowserEndToEndTest.cs @@ -6,7 +6,7 @@ namespace MartinCostello.LondonTravel.Site.EndToEnd; /// /// The base class for end-to-end tests. /// -[Collection(WebsiteCollection.Name)] +[Collection] [Trait("Category", "EndToEnd")] public abstract class BrowserEndToEndTest : BrowserTest { diff --git a/tests/LondonTravel.Site.Tests/EndToEnd/ResourceTests.cs b/tests/LondonTravel.Site.Tests/EndToEnd/ResourceTests.cs index e5937d263..844121d0d 100644 --- a/tests/LondonTravel.Site.Tests/EndToEnd/ResourceTests.cs +++ b/tests/LondonTravel.Site.Tests/EndToEnd/ResourceTests.cs @@ -6,11 +6,11 @@ namespace MartinCostello.LondonTravel.Site.EndToEnd; -[Collection(WebsiteCollection.Name)] +[Collection] [Trait("Category", "EndToEnd")] public class ResourceTests(WebsiteFixture fixture) { - [SkippableTheory] + [Theory] [InlineData("/", MediaTypeNames.Text.Html)] [InlineData("/.well-known/apple-app-site-association", MediaTypeNames.Application.Json)] [InlineData("/.well-known/assetlinks.json", MediaTypeNames.Application.Json)] @@ -49,16 +49,16 @@ public async Task Can_Load_Resource(string requestUri, string contentType) using var client = fixture.CreateClient(); // Act - using var response = await client.GetAsync(requestUri); + using var response = await client.GetAsync(requestUri, TestContext.Current.CancellationToken); // Assert - response.StatusCode.ShouldBe(HttpStatusCode.OK, $"Failed to get {requestUri}. {await response.Content!.ReadAsStringAsync()}"); + response.StatusCode.ShouldBe(HttpStatusCode.OK, $"Failed to get {requestUri}. {await response.Content!.ReadAsStringAsync(TestContext.Current.CancellationToken)}"); response.Content.Headers.ContentType?.MediaType.ShouldBe(contentType); response.Content.Headers.ContentLength.ShouldNotBeNull(); response.Content.Headers.ContentLength.ShouldNotBe(0); } - [SkippableFact] + [Fact] public async Task Response_Headers_Contains_Expected_Headers() { // Arrange @@ -81,7 +81,7 @@ public async Task Response_Headers_Contains_Expected_Headers() // Act using var client = fixture.CreateClient(); - var response = await client.GetAsync("/"); + var response = await client.GetAsync("/", TestContext.Current.CancellationToken); // Assert foreach (string expected in expectedHeaders) diff --git a/tests/LondonTravel.Site.Tests/EndToEnd/SocialLoginTests.cs b/tests/LondonTravel.Site.Tests/EndToEnd/SocialLoginTests.cs index c32fec808..20354bb5b 100644 --- a/tests/LondonTravel.Site.Tests/EndToEnd/SocialLoginTests.cs +++ b/tests/LondonTravel.Site.Tests/EndToEnd/SocialLoginTests.cs @@ -8,10 +8,10 @@ namespace MartinCostello.LondonTravel.Site.EndToEnd; public class SocialLoginTests(WebsiteFixture fixture, ITestOutputHelper outputHelper) : BrowserEndToEndTest(fixture, outputHelper) { - [SkippableFact] + [Fact] public async Task Can_Sign_In_With_Google() { - Skip.IfNot( + Assert.SkipUnless( string.IsNullOrEmpty(Environment.GetEnvironmentVariable("GITHUB_ACTIONS")), "Sign-in blocked when run in GitHub Actions."); @@ -28,10 +28,10 @@ await SignInAsync( }); } - [SkippableFact] + [Fact] public async Task Can_Sign_In_With_Microsoft_Account() { - Skip.IfNot( + Assert.SkipUnless( string.IsNullOrEmpty(Environment.GetEnvironmentVariable("GITHUB_ACTIONS")), "Sign-in is being flaky in GitHub Actions."); @@ -48,10 +48,10 @@ await SignInAsync( }); } - [SkippableFact] + [Fact] public async Task Can_Sign_In_With_Twitter() { - Skip.IfNot( + Assert.SkipUnless( string.IsNullOrEmpty(Environment.GetEnvironmentVariable("GITHUB_ACTIONS")), "Sign-in blocked when run in GitHub Actions."); @@ -72,8 +72,8 @@ private async Task SignInWithSocialProviderAsync(string providerName, Func( diff --git a/tests/LondonTravel.Site.Tests/EndToEnd/WebsiteFixture.cs b/tests/LondonTravel.Site.Tests/EndToEnd/WebsiteFixture.cs index 756c2c072..e54c6e3e3 100644 --- a/tests/LondonTravel.Site.Tests/EndToEnd/WebsiteFixture.cs +++ b/tests/LondonTravel.Site.Tests/EndToEnd/WebsiteFixture.cs @@ -24,7 +24,7 @@ public Uri ServerAddress { get { - Skip.If(_serverAddress is null, $"The {WebsiteUrl} environment variable is not set or is not a valid absolute URI."); + Assert.SkipWhen(_serverAddress is null, $"The {WebsiteUrl} environment variable is not set or is not a valid absolute URI."); return _serverAddress!; } } diff --git a/tests/LondonTravel.Site.Tests/Integration/AccountTests.cs b/tests/LondonTravel.Site.Tests/Integration/AccountTests.cs index 6bf52414e..672bcae92 100644 --- a/tests/LondonTravel.Site.Tests/Integration/AccountTests.cs +++ b/tests/LondonTravel.Site.Tests/Integration/AccountTests.cs @@ -19,7 +19,7 @@ namespace MartinCostello.LondonTravel.Site.Integration; /// /// The fixture to use. /// The to use. -[Collection(TestServerCollection.Name)] +[Collection] public class AccountTests(TestServerFixture fixture, ITestOutputHelper outputHelper) : IntegrationTest(fixture, outputHelper) { [Fact] @@ -51,7 +51,7 @@ static IUserStore GetUserStore(IServiceProvider serviceProvide using var store = GetUserStore(scope.ServiceProvider); // Act - var createResult = await store.CreateAsync(user, default); + var createResult = await store.CreateAsync(user, CancellationToken); // Assert Assert.NotNull(createResult); @@ -63,7 +63,7 @@ static IUserStore GetUserStore(IServiceProvider serviceProvide userId = user.Id!; // Act - var actual = await store.FindByIdAsync(userId, default); + var actual = await store.FindByIdAsync(userId, CancellationToken); // Assert Assert.NotNull(actual); @@ -87,14 +87,14 @@ static IUserStore GetUserStore(IServiceProvider serviceProvide actual.FavoriteLines = favoriteLines; // Act - var updateResult = await store.UpdateAsync(actual, default); + var updateResult = await store.UpdateAsync(actual, CancellationToken); // Assert Assert.NotNull(updateResult); Assert.True(updateResult.Succeeded); // Act - actual = await store.FindByNameAsync(emailAddress, default); + actual = await store.FindByNameAsync(emailAddress, CancellationToken); // Assert Assert.NotNull(actual); @@ -112,7 +112,7 @@ static IUserStore GetUserStore(IServiceProvider serviceProvide // Act using var client = Fixture.CreateClient(); - using var response = await client.SendAsync(message); + using var response = await client.SendAsync(message, CancellationToken); // Assert response.StatusCode.ShouldBe(HttpStatusCode.OK); @@ -121,7 +121,7 @@ static IUserStore GetUserStore(IServiceProvider serviceProvide response.Content!.Headers!.ContentType.ShouldNotBeNull(); response.Content.Headers.ContentType!.MediaType.ShouldBe(MediaTypeNames.Application.Json); - string json = await response.Content.ReadAsStringAsync(); + string json = await response.Content.ReadAsStringAsync(CancellationToken); using var preferences = JsonDocument.Parse(json); Assert.Equal(userId, preferences.RootElement.GetString("userId")); @@ -134,7 +134,7 @@ static IUserStore GetUserStore(IServiceProvider serviceProvide using var store = GetUserStore(scope.ServiceProvider); // Act - var updateResult = await store.DeleteAsync(new LondonTravelUser() { Id = userId }, default); + var updateResult = await store.DeleteAsync(new LondonTravelUser() { Id = userId }, CancellationToken); // Assert Assert.NotNull(updateResult); @@ -148,7 +148,7 @@ static IUserStore GetUserStore(IServiceProvider serviceProvide // Act using var client = Fixture.CreateClient(); - using var response = await client.SendAsync(message); + using var response = await client.SendAsync(message, CancellationToken); // Assert response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized); diff --git a/tests/LondonTravel.Site.Tests/Integration/AlexaTests.cs b/tests/LondonTravel.Site.Tests/Integration/AlexaTests.cs index d90bc870e..57da7f8a9 100644 --- a/tests/LondonTravel.Site.Tests/Integration/AlexaTests.cs +++ b/tests/LondonTravel.Site.Tests/Integration/AlexaTests.cs @@ -7,7 +7,6 @@ using MartinCostello.LondonTravel.Site.Pages; using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.DependencyInjection; -using xRetry; namespace MartinCostello.LondonTravel.Site.Integration; @@ -27,7 +26,7 @@ public AlexaTests(HttpServerFixture fixture, ITestOutputHelper outputHelper) Fixture.Services!.GetRequiredService().Clear(); } - [RetryTheory] + [Theory] [ClassData(typeof(BrowsersTestData))] public async Task Can_Authorize_Alexa(string browserType, string? browserChannel) { @@ -52,7 +51,7 @@ await WithNavigatorAsync( }); } - [RetryTheory] + [Theory] [ClassData(typeof(BrowsersTestData))] public async Task Can_Get_Preferences_From_Api(string browserType, string? browserChannel) { diff --git a/tests/LondonTravel.Site.Tests/Integration/ApiTests.cs b/tests/LondonTravel.Site.Tests/Integration/ApiTests.cs index af60b4bbb..8fc3aea7b 100644 --- a/tests/LondonTravel.Site.Tests/Integration/ApiTests.cs +++ b/tests/LondonTravel.Site.Tests/Integration/ApiTests.cs @@ -17,7 +17,7 @@ namespace MartinCostello.LondonTravel.Site.Integration; /// /// The fixture to use. /// The to use. -[Collection(TestServerCollection.Name)] +[Collection] public class ApiTests(TestServerFixture fixture, ITestOutputHelper outputHelper) : IntegrationTest(fixture, outputHelper) { private const string Scheme = "bearer"; @@ -38,7 +38,7 @@ public async Task Cannot_Get_Preferences_Unauthenticated(string? value) } // Act - using var response = await client.GetAsync(RequestUri); + using var response = await client.GetAsync(RequestUri, CancellationToken); // Assert response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized); @@ -61,7 +61,7 @@ public async Task Cannot_Get_Preferences_With_Invalid_Token(string value) client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", value); // Act - using var response = await client.GetAsync(RequestUri); + using var response = await client.GetAsync(RequestUri, CancellationToken); // Assert response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized); @@ -85,7 +85,7 @@ public async Task Cannot_Get_Preferences_With_Invalid_Scheme_Value(string value) client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(value, "token"); // Act - using var response = await client.GetAsync(RequestUri); + using var response = await client.GetAsync(RequestUri, CancellationToken); // Assert response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized); @@ -111,7 +111,7 @@ public async Task Cannot_Get_Preferences_With_Invalid_Parameter_Value(string val client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(Scheme, value); // Act - using var response = await client.GetAsync(RequestUri); + using var response = await client.GetAsync(RequestUri, CancellationToken); // Assert response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized); @@ -137,11 +137,11 @@ public async Task Schema_Has_No_Validation_Warnings() using var client = Fixture.CreateClient(); // Act - using var schema = await client.GetStreamAsync("/openapi/api.json"); + using var schema = await client.GetStreamAsync("/openapi/api.json", CancellationToken); // Assert var reader = new OpenApiStreamReader(); - var actual = await reader.ReadAsync(schema); + var actual = await reader.ReadAsync(schema, CancellationToken); actual.OpenApiDiagnostic.Errors.ShouldBeEmpty(); @@ -159,7 +159,7 @@ public async Task Schema_Is_Correct() using var client = Fixture.CreateClient(); // Act - string actual = await client.GetStringAsync("/openapi/api.json"); + string actual = await client.GetStringAsync("/openapi/api.json", CancellationToken); // Assert await VerifyJson(actual, settings); diff --git a/tests/LondonTravel.Site.Tests/Integration/AuthenticationTests.cs b/tests/LondonTravel.Site.Tests/Integration/AuthenticationTests.cs index b69e2099f..b71f6e3e7 100644 --- a/tests/LondonTravel.Site.Tests/Integration/AuthenticationTests.cs +++ b/tests/LondonTravel.Site.Tests/Integration/AuthenticationTests.cs @@ -3,14 +3,13 @@ using MartinCostello.LondonTravel.Site.Pages; using Microsoft.Extensions.DependencyInjection; -using xRetry; namespace MartinCostello.LondonTravel.Site.Integration; /// /// A class containing tests for authentication providers in the website. /// -[Collection(HttpServerCollection.Name)] +[Collection] public sealed class AuthenticationTests : BrowserIntegrationTest { /// @@ -55,7 +54,7 @@ await AtPageAsync( }); } - [RetryTheory] + [Theory] [ClassData(typeof(BrowsersTestData))] public async Task Can_Delete_Account(string browserType, string? browserChannel) { @@ -86,7 +85,7 @@ await page.DeleteAccountAsync() }); } - [RetryTheory] + [Theory] [ClassData(typeof(BrowsersTestData))] public async Task Can_Link_Accounts(string browserType, string? browserChannel) { @@ -121,7 +120,7 @@ await AtPageAsync( page = await accounts[0].RemoveAsync(); // Wait for the UI to update - await Task.Delay(TimeSpan.FromSeconds(1)); + await Task.Delay(TimeSpan.FromSeconds(1), TestContext.Current.CancellationToken); // Assert accounts = await page.LinkedAccountsAsync(); diff --git a/tests/LondonTravel.Site.Tests/Integration/BrowserIntegrationTest.cs b/tests/LondonTravel.Site.Tests/Integration/BrowserIntegrationTest.cs index d700d7c63..33068c8cb 100644 --- a/tests/LondonTravel.Site.Tests/Integration/BrowserIntegrationTest.cs +++ b/tests/LondonTravel.Site.Tests/Integration/BrowserIntegrationTest.cs @@ -9,7 +9,7 @@ namespace MartinCostello.LondonTravel.Site.Integration; /// /// The base class for browser tests. /// -[Collection(HttpServerCollection.Name)] +[Collection] public abstract class BrowserIntegrationTest : BrowserTest { private bool _disposed; diff --git a/tests/LondonTravel.Site.Tests/Integration/IntegrationTest.cs b/tests/LondonTravel.Site.Tests/Integration/IntegrationTest.cs index bc83ba4a9..0ca1a40ef 100644 --- a/tests/LondonTravel.Site.Tests/Integration/IntegrationTest.cs +++ b/tests/LondonTravel.Site.Tests/Integration/IntegrationTest.cs @@ -6,7 +6,7 @@ namespace MartinCostello.LondonTravel.Site.Integration; /// /// The base class for integration tests. /// -[Collection(TestServerCollection.Name)] +[Collection] public abstract class IntegrationTest : IDisposable { private bool _disposed; @@ -30,6 +30,11 @@ protected IntegrationTest(TestServerFixture fixture, ITestOutputHelper outputHel Dispose(false); } + /// + /// Gets the to use. + /// + protected virtual CancellationToken CancellationToken => TestContext.Current.CancellationToken; + /// /// Gets the to use. /// diff --git a/tests/LondonTravel.Site.Tests/Integration/PreferencesTests.cs b/tests/LondonTravel.Site.Tests/Integration/PreferencesTests.cs index 8f2d1d300..811f4500f 100644 --- a/tests/LondonTravel.Site.Tests/Integration/PreferencesTests.cs +++ b/tests/LondonTravel.Site.Tests/Integration/PreferencesTests.cs @@ -22,7 +22,7 @@ public PreferencesTests(HttpServerFixture fixture, ITestOutputHelper outputHelpe Fixture.Services!.GetRequiredService().Clear(); } - [xRetry.RetryTheory] + [Theory] [ClassData(typeof(BrowsersTestData))] public async Task Can_Manage_Preferences(string browserType, string? browserChannel) { @@ -62,7 +62,7 @@ await AtPageAsync( page = await page.UpdatePreferencesAsync(); // Give the UI time to update - await Task.Delay(TimeSpan.FromSeconds(1)); + await Task.Delay(TimeSpan.FromSeconds(1), TestContext.Current.CancellationToken); // Assert lines = await page.LinesAsync(); @@ -87,7 +87,7 @@ await AtPageAsync( page = await page.UpdatePreferencesAsync(); // Give the UI time to update - await Task.Delay(TimeSpan.FromSeconds(1)); + await Task.Delay(TimeSpan.FromSeconds(1), TestContext.Current.CancellationToken); // Assert lines = await page.LinesAsync(); diff --git a/tests/LondonTravel.Site.Tests/Integration/ResourceTests.cs b/tests/LondonTravel.Site.Tests/Integration/ResourceTests.cs index dd86557ec..f45a90a1c 100644 --- a/tests/LondonTravel.Site.Tests/Integration/ResourceTests.cs +++ b/tests/LondonTravel.Site.Tests/Integration/ResourceTests.cs @@ -15,7 +15,7 @@ namespace MartinCostello.LondonTravel.Site.Integration; /// /// The fixture to use. /// The to use. -[Collection(TestServerCollection.Name)] +[Collection] public class ResourceTests(TestServerFixture fixture, ITestOutputHelper outputHelper) : IntegrationTest(fixture, outputHelper) { [Theory] @@ -57,10 +57,10 @@ public async Task Can_Load_Resource(string requestUri, string contentType) using var client = Fixture.CreateClient(); // Act - using var response = await client.GetAsync(requestUri); + using var response = await client.GetAsync(requestUri, CancellationToken); // Assert - response.StatusCode.ShouldBe(HttpStatusCode.OK, $"Failed to get {requestUri}. {await response.Content!.ReadAsStringAsync()}"); + response.StatusCode.ShouldBe(HttpStatusCode.OK, $"Failed to get {requestUri}. {await response.Content!.ReadAsStringAsync(CancellationToken)}"); response.Content.Headers.ContentType?.MediaType.ShouldBe(contentType); response.Content.Headers.ContentLength.ShouldNotBeNull(); response.Content.Headers.ContentLength.ShouldNotBe(0); @@ -76,7 +76,7 @@ public async Task Resource_Is_Redirect(string requestUri, string location) using var client = Fixture.CreateClient(); // Act - using var response = await client.GetAsync(requestUri); + using var response = await client.GetAsync(requestUri, CancellationToken); // Assert response.StatusCode.ShouldBe(HttpStatusCode.Redirect); @@ -93,7 +93,7 @@ public async Task Cannot_Load_Resource_Unauthenticated(string requestUri) using var client = Fixture.CreateClient(); // Act - using var response = await client.GetAsync(requestUri); + using var response = await client.GetAsync(requestUri, CancellationToken); // Assert response.StatusCode.ShouldBe(HttpStatusCode.Redirect); @@ -105,12 +105,12 @@ public async Task Manifest_Is_Valid_Json() { // Arrange using var client = Fixture.CreateClient(); - using var response = await client.GetAsync("/manifest.webmanifest"); + using var response = await client.GetAsync("/manifest.webmanifest", CancellationToken); // Assert response.EnsureSuccessStatusCode(); - string json = await response.Content!.ReadAsStringAsync(); + string json = await response.Content!.ReadAsStringAsync(CancellationToken); var manifest = JsonDocument.Parse(json); manifest.RootElement.GetString("name").ShouldBe("London Travel"); @@ -139,7 +139,7 @@ public async Task Response_Headers_Contains_Expected_Headers() // Act using var client = Fixture.CreateClient(); - var response = await client.GetAsync("/"); + var response = await client.GetAsync("/", CancellationToken); // Assert foreach (string expected in expectedHeaders) @@ -154,7 +154,7 @@ public async Task Response_Headers_Is_Valid_Json(string name) { // Act using var client = Fixture.CreateClient(); - using var response = await client.GetAsync("/"); + using var response = await client.GetAsync("/", CancellationToken); // Assert response.Headers.Contains(name).ShouldBeTrue($"The '{name}' response header was not found."); @@ -182,7 +182,7 @@ public async Task Error_Page_Returns_Correct_Status_Code(string requestUri, Http using var client = Fixture.CreateClient(); // Act - using var response = await client.GetAsync(requestUri); + using var response = await client.GetAsync(requestUri, CancellationToken); // Assert response.StatusCode.ShouldBe(expected); @@ -218,7 +218,7 @@ public async Task Crawler_Spam_Is_Redirected_To_YouTube(string requestUri) using var client = Fixture.CreateClient(); // Act - using (var response = await client.GetAsync(requestUri)) + using (var response = await client.GetAsync(requestUri, CancellationToken)) { // Assert response.StatusCode.ShouldBe(HttpStatusCode.Redirect); @@ -229,7 +229,7 @@ public async Task Crawler_Spam_Is_Redirected_To_YouTube(string requestUri) using (var message = new HttpRequestMessage(HttpMethod.Head, requestUri)) { // Act - using var response = await client.SendAsync(message); + using var response = await client.SendAsync(message, CancellationToken); // Assert response.StatusCode.ShouldBe(HttpStatusCode.Redirect); @@ -240,7 +240,7 @@ public async Task Crawler_Spam_Is_Redirected_To_YouTube(string requestUri) using (var content = new StringContent(string.Empty)) { // Act - using var response = await client.PostAsync(requestUri, content); + using var response = await client.PostAsync(requestUri, content, CancellationToken); // Assert response.StatusCode.ShouldBe(HttpStatusCode.Redirect); diff --git a/tests/LondonTravel.Site.Tests/Integration/SiteMapTests.cs b/tests/LondonTravel.Site.Tests/Integration/SiteMapTests.cs index 9f312a7cb..2bdd192d2 100644 --- a/tests/LondonTravel.Site.Tests/Integration/SiteMapTests.cs +++ b/tests/LondonTravel.Site.Tests/Integration/SiteMapTests.cs @@ -15,7 +15,7 @@ namespace MartinCostello.LondonTravel.Site.Integration; /// /// The fixture to use. /// The to use. -[Collection(TestServerCollection.Name)] +[Collection] public class SiteMapTests(TestServerFixture fixture, ITestOutputHelper outputHelper) : IntegrationTest(fixture, outputHelper) { [Fact] @@ -27,12 +27,12 @@ public async Task Site_Map_Locations_Are_Valid() using (var client = Fixture.CreateClient()) { // Act - using var response = await client.GetAsync("sitemap.xml"); + using var response = await client.GetAsync("sitemap.xml", CancellationToken); response.StatusCode.ShouldBe(HttpStatusCode.OK); response.Content!.Headers.ContentType?.MediaType.ShouldBe(MediaTypeNames.Text.Xml); - string xml = await response.Content.ReadAsStringAsync(); + string xml = await response.Content.ReadAsStringAsync(CancellationToken); xml.ShouldNotBeNullOrWhiteSpace(); locations = GetSitemapLocations(xml); @@ -57,9 +57,9 @@ public async Task Site_Map_Locations_Are_Valid() uri.AbsolutePath.ShouldEndWith("/"); using var client = Fixture.CreateClient(); - using var response = await client.GetAsync(uri.PathAndQuery); + using var response = await client.GetAsync(uri.PathAndQuery, CancellationToken); - response.StatusCode.ShouldBe(HttpStatusCode.OK, $"Failed to get {uri.PathAndQuery}. {await response.Content!.ReadAsStringAsync()}"); + response.StatusCode.ShouldBe(HttpStatusCode.OK, $"Failed to get {uri.PathAndQuery}. {await response.Content!.ReadAsStringAsync(CancellationToken)}"); response.Content.Headers.ContentType?.MediaType.ShouldBe(MediaTypeNames.Text.Html); response.Content.Headers.ContentLength.ShouldNotBeNull(); response.Content.Headers.ContentLength!.Value.ShouldBeGreaterThan(0); diff --git a/tests/LondonTravel.Site.Tests/LondonTravel.Site.Tests.csproj b/tests/LondonTravel.Site.Tests/LondonTravel.Site.Tests.csproj index a6a6000ea..6bea52530 100644 --- a/tests/LondonTravel.Site.Tests/LondonTravel.Site.Tests.csproj +++ b/tests/LondonTravel.Site.Tests/LondonTravel.Site.Tests.csproj @@ -3,6 +3,7 @@ Tests for https://londontravel.martincostello.com/ true $(NoWarn);CA1031;CA1308;CA1707;CA1711;CA1861;CA2000;CA2234 + Exe true MartinCostello.LondonTravel.Site Tests for the London Travel website @@ -20,7 +21,7 @@ - + @@ -28,16 +29,13 @@ - - - + - + - true diff --git a/tests/LondonTravel.Site.Tests/Services/Tfl/TflServiceTests.cs b/tests/LondonTravel.Site.Tests/Services/Tfl/TflServiceTests.cs index b9d3aba65..dc5491d1f 100644 --- a/tests/LondonTravel.Site.Tests/Services/Tfl/TflServiceTests.cs +++ b/tests/LondonTravel.Site.Tests/Services/Tfl/TflServiceTests.cs @@ -34,8 +34,8 @@ public async Task Can_Get_Line_Information_If_Response_Can_Be_Cached() var target = new TflService(httpClient, _cache, _options); // Act - var actual1 = await target.GetLinesAsync(); - var actual2 = await target.GetLinesAsync(); + var actual1 = await target.GetLinesAsync(TestContext.Current.CancellationToken); + var actual2 = await target.GetLinesAsync(TestContext.Current.CancellationToken); // Assert Assert.NotNull(actual1); @@ -67,8 +67,8 @@ public async Task Can_Get_Line_Information_If_Response_Cannot_Be_Cached() var target = new TflService(httpClient, _cache, _options); // Act - var actual1 = await target.GetLinesAsync(); - var actual2 = await target.GetLinesAsync(); + var actual1 = await target.GetLinesAsync(TestContext.Current.CancellationToken); + var actual2 = await target.GetLinesAsync(TestContext.Current.CancellationToken); // Assert Assert.NotNull(actual1); @@ -101,8 +101,8 @@ public async Task Can_Get_Stop_Points_If_Response_Can_Be_Cached() var target = new TflService(httpClient, _cache, _options); // Act - var actual1 = await target.GetStopPointsByLineAsync("victoria"); - var actual2 = await target.GetStopPointsByLineAsync("victoria"); + var actual1 = await target.GetStopPointsByLineAsync("victoria", TestContext.Current.CancellationToken); + var actual2 = await target.GetStopPointsByLineAsync("victoria", TestContext.Current.CancellationToken); // Assert Assert.NotNull(actual1); @@ -136,8 +136,8 @@ public async Task Can_Get_Stop_Points_If_Response_Cannot_Be_Cached() var target = new TflService(httpClient, _cache, _options); // Act - var actual1 = await target.GetStopPointsByLineAsync("victoria"); - var actual2 = await target.GetStopPointsByLineAsync("victoria"); + var actual1 = await target.GetStopPointsByLineAsync("victoria", TestContext.Current.CancellationToken); + var actual2 = await target.GetStopPointsByLineAsync("victoria", TestContext.Current.CancellationToken); // Assert Assert.NotNull(actual1);