Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 27 additions & 25 deletions tests/TodoApp.Tests/ApiTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public ApiTests(TodoAppFixture fixture, ITestOutputHelper outputHelper)
Fixture.SetOutputHelper(OutputHelper);
}

public virtual CancellationToken CancellationToken => TestContext.Current.CancellationToken;

private TodoAppFixture Fixture { get; }

private ITestOutputHelper OutputHelper { get; }
Expand All @@ -33,7 +35,7 @@ public async Task Can_Manage_Todo_Items_With_Api()
using var client = Fixture.CreateDefaultClient();

// Act - Get all the items
var items = await client.GetFromJsonAsync<TodoListViewModel>("/api/items");
var items = await client.GetFromJsonAsync<TodoListViewModel>("/api/items", CancellationToken);

// Assert - There should be no items
Assert.NotNull(items);
Expand All @@ -46,20 +48,20 @@ public async Task Can_Manage_Todo_Items_With_Api()
var newItem = new CreateTodoItemModel { Text = text };

// Act - Add a new item
using var createdResponse = await client.PostAsJsonAsync("/api/items", newItem);
using var createdResponse = await client.PostAsJsonAsync("/api/items", newItem, CancellationToken);

// Assert - An item was created
Assert.Equal(HttpStatusCode.Created, createdResponse.StatusCode);
Assert.NotNull(createdResponse.Headers.Location);

using var createdJson = await createdResponse.Content.ReadFromJsonAsync<JsonDocument>();
using var createdJson = await createdResponse.Content.ReadFromJsonAsync<JsonDocument>(CancellationToken);

// Arrange - Get the new item's URL and Id
var itemUri = createdResponse.Headers.Location;
var itemId = createdJson!.RootElement.GetProperty("id").GetString();

// Act - Get the item
var item = await client.GetFromJsonAsync<TodoItemModel>(itemUri);
var item = await client.GetFromJsonAsync<TodoItemModel>(itemUri, CancellationToken);

// Assert - Verify the item was created correctly
Assert.NotNull(item);
Expand All @@ -69,20 +71,20 @@ public async Task Can_Manage_Todo_Items_With_Api()
Assert.Equal(text, item.Text);

// Act - Mark the item as being completed
using var completedResponse = await client.PostAsJsonAsync(itemUri + "/complete", new { });
using var completedResponse = await client.PostAsJsonAsync(itemUri + "/complete", new { }, CancellationToken);

// Assert - The item was completed
Assert.Equal(HttpStatusCode.NoContent, completedResponse.StatusCode);

item = await client.GetFromJsonAsync<TodoItemModel>(itemUri);
item = await client.GetFromJsonAsync<TodoItemModel>(itemUri, CancellationToken);

Assert.NotNull(item);
Assert.Equal(itemId, item.Id);
Assert.Equal(text, item.Text);
Assert.True(item.IsCompleted);

// Act - Get all the items
items = await client.GetFromJsonAsync<TodoListViewModel>("/api/items");
items = await client.GetFromJsonAsync<TodoListViewModel>("/api/items", CancellationToken);

// Assert - The item was completed
Assert.NotNull(items);
Expand All @@ -97,25 +99,25 @@ public async Task Can_Manage_Todo_Items_With_Api()
Assert.NotNull(item.LastUpdated);

// Act - Delete the item
using var deletedResponse = await client.DeleteAsync(itemUri);
using var deletedResponse = await client.DeleteAsync(itemUri, CancellationToken);

// Assert - The item no longer exists
Assert.Equal(HttpStatusCode.NoContent, deletedResponse.StatusCode);

items = await client.GetFromJsonAsync<TodoListViewModel>("/api/items");
items = await client.GetFromJsonAsync<TodoListViewModel>("/api/items", CancellationToken);

Assert.NotNull(items);
Assert.NotNull(items.Items);
Assert.Equal(beforeCount, items.Items.Count);
Assert.DoesNotContain(items.Items, x => x.Id == itemId);

// Act
using var getResponse = await client.GetAsync(itemUri);
using var getResponse = await client.GetAsync(itemUri, CancellationToken);

// Assert
Assert.Equal(HttpStatusCode.NotFound, getResponse.StatusCode);

var problem = await getResponse.Content.ReadFromJsonAsync<ProblemDetails>();
var problem = await getResponse.Content.ReadFromJsonAsync<ProblemDetails>(CancellationToken);

Assert.NotNull(problem);
Assert.Equal(StatusCodes.Status404NotFound, problem.Status);
Expand All @@ -133,12 +135,12 @@ public async Task Cannot_Create_Todo_Item_With_No_Text()
var item = new CreateTodoItemModel { Text = string.Empty };

// Act
var response = await client.PostAsJsonAsync("/api/items", item);
var response = await client.PostAsJsonAsync("/api/items", item, CancellationToken);

// Assert
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);

var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>();
var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>(CancellationToken);

Assert.NotNull(problem);
Assert.Equal(StatusCodes.Status400BadRequest, problem.Status);
Expand All @@ -155,24 +157,24 @@ public async Task Cannot_Complete_Todo_Item_Multiple_Times()
using var client = Fixture.CreateDefaultClient();
var item = new CreateTodoItemModel { Text = "Something" };

using var createdResponse = await client.PostAsJsonAsync("/api/items", item);
using var createdResponse = await client.PostAsJsonAsync("/api/items", item, CancellationToken);

Assert.Equal(HttpStatusCode.Created, createdResponse.StatusCode);
Assert.NotNull(createdResponse.Headers.Location);

var itemUri = createdResponse.Headers.Location;

using var completedResponse = await client.PostAsJsonAsync(itemUri + "/complete", new { });
using var completedResponse = await client.PostAsJsonAsync(itemUri + "/complete", new { }, CancellationToken);

Assert.Equal(HttpStatusCode.NoContent, completedResponse.StatusCode);

// Act
using var response = await client.PostAsJsonAsync(itemUri + "/complete", new { });
using var response = await client.PostAsJsonAsync(itemUri + "/complete", new { }, CancellationToken);

// Assert
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);

var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>();
var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>(CancellationToken);

Assert.NotNull(problem);
Assert.Equal(StatusCodes.Status400BadRequest, problem.Status);
Expand All @@ -189,24 +191,24 @@ public async Task Cannot_Complete_Deleted_Todo_Item()
using var client = Fixture.CreateDefaultClient();
var item = new CreateTodoItemModel { Text = "Something" };

using var createdResponse = await client.PostAsJsonAsync("/api/items", item);
using var createdResponse = await client.PostAsJsonAsync("/api/items", item, CancellationToken);

Assert.Equal(HttpStatusCode.Created, createdResponse.StatusCode);
Assert.NotNull(createdResponse.Headers.Location);

var itemUri = createdResponse.Headers.Location;

using var deletedResponse = await client.DeleteAsync(itemUri);
using var deletedResponse = await client.DeleteAsync(itemUri, CancellationToken);

Assert.Equal(HttpStatusCode.NoContent, deletedResponse.StatusCode);

// Act
using var response = await client.PostAsJsonAsync(itemUri + "/complete", new { });
using var response = await client.PostAsJsonAsync(itemUri + "/complete", new { }, CancellationToken);

// Assert
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);

var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>();
var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>(CancellationToken);

Assert.NotNull(problem);
Assert.Equal(StatusCodes.Status404NotFound, problem.Status);
Expand All @@ -223,24 +225,24 @@ public async Task Cannot_Delete_Todo_Item_Multiple_Times()
using var client = Fixture.CreateDefaultClient();
var item = new CreateTodoItemModel { Text = "Something" };

using var createdResponse = await client.PostAsJsonAsync("/api/items", item);
using var createdResponse = await client.PostAsJsonAsync("/api/items", item, CancellationToken);

Assert.Equal(HttpStatusCode.Created, createdResponse.StatusCode);
Assert.NotNull(createdResponse.Headers.Location);

var itemUri = createdResponse.Headers.Location;

using var deletedResponse = await client.DeleteAsync(itemUri);
using var deletedResponse = await client.DeleteAsync(itemUri, CancellationToken);

Assert.Equal(HttpStatusCode.NoContent, deletedResponse.StatusCode);

// Act
using var response = await client.DeleteAsync(itemUri);
using var response = await client.DeleteAsync(itemUri, CancellationToken);

// Assert
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);

var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>();
var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>(CancellationToken);

Assert.NotNull(problem);
Assert.Equal(StatusCodes.Status404NotFound, problem.Status);
Expand Down
6 changes: 3 additions & 3 deletions tests/TodoApp.Tests/OpenApiTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public async Task Schema_Is_Correct(string schemaUrl)
using var client = Fixture.CreateDefaultClient();

// Act
var actual = await client.GetStringAsync(schemaUrl);
var actual = await client.GetStringAsync(schemaUrl, TestContext.Current.CancellationToken);

// Assert
var settings = new VerifySettings();
Expand All @@ -60,11 +60,11 @@ public async Task Schema_Has_No_Validation_Warnings(string schemaUrl)
using var client = Fixture.CreateDefaultClient();

// Act
using var schema = await client.GetStreamAsync(schemaUrl);
using var schema = await client.GetStreamAsync(schemaUrl, TestContext.Current.CancellationToken);

// Assert
var reader = new OpenApiStreamReader();
var actual = await reader.ReadAsync(schema);
var actual = await reader.ReadAsync(schema, TestContext.Current.CancellationToken);

Assert.Empty(actual.OpenApiDiagnostic.Errors);

Expand Down
8 changes: 4 additions & 4 deletions tests/TodoApp.Tests/TodoApp.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@
<PropertyGroup>
<IsPackable>false</IsPackable>
<NoWarn>$(NoWarn);CA1861</NoWarn>
<OutputType>Exe</OutputType>
<RootNamespace>TodoApp</RootNamespace>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="GitHubActionsTestLogger" Version="2.4.1" />
<PackageReference Include="MartinCostello.Logging.XUnit" Version="0.4.0" />
<PackageReference Include="MartinCostello.Logging.XUnit.v3" Version="0.5.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="Microsoft.OpenApi.Readers" Version="1.6.22" />
<PackageReference Include="Microsoft.Playwright" Version="1.49.0" />
<PackageReference Include="Verify.Xunit" Version="28.6.1" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="Verify.XunitV3" Version="28.6.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.0" />
<PackageReference Include="xunit.v3" Version="1.0.0" />
</ItemGroup>
<ItemGroup>
<Content Include="xunit.runner.json;xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
Expand All @@ -26,6 +27,5 @@
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
<Using Include="Xunit.Abstractions" />
</ItemGroup>
</Project>
12 changes: 8 additions & 4 deletions tests/TodoApp.Tests/UITests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ await browser.WithPageAsync(async page =>
await items[0].DeleteAsync();
await items[1].CompleteAsync();

await Task.Delay(TimeSpan.FromSeconds(0.5));
await Task.Delay(TimeSpan.FromSeconds(0.5), TestContext.Current.CancellationToken);

// Assert
items = await app.GetItemsAsync();
Expand All @@ -107,13 +107,17 @@ await browser.WithPageAsync(async page =>
});
}

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;
}

private static void InstallPlaywright()
{
Expand Down
Loading