Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Test action #2

Merged
merged 2 commits into from
Jun 21, 2024
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
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ e2e
fly.toml
Dockerfile*
**/*.md
wwwroot/app.min.css
PointingParty/wwwroot/app.min.css
22 changes: 21 additions & 1 deletion .github/workflows/fly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,31 @@ name: Deploy to fly.io

on:
push:
branches: [ "main" ]
branches: ["main"]
pull_request:
branches: ["main"]

jobs:
unittest:
name: Unit tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 9.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore
- name: Test
run: dotnet test --no-build --verbosity normal

deploy:
name: Deploy
if: github.event_name == 'push'
needs: unittest
runs-on: ubuntu-latest
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
Expand Down
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -482,5 +482,3 @@ $RECYCLE.BIN/

# Vim temporary swap files
*.swp

wwwroot/app.min.css
22 changes: 22 additions & 0 deletions PointingParty.Client.Tests/GameContextTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Logging;

namespace PointingParty.Client.Tests;

public class GameContextTests
{
[Fact]
public void CreateGame_Returns_GameAggregate()
{
var sut = new GameContext(
Substitute.For<ILogger<GameContext>>(),
Substitute.For<NavigationManager>()
);

var agg = sut.CreateGame("Game", "Player");

Assert.Equal(sut.Game, agg);
Assert.Equal("Game", agg.State.GameId);
Assert.Equal("Player", sut.PlayerName);
}
}
12 changes: 6 additions & 6 deletions PointingParty.Client.Tests/GameStateExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public void Calculates_Average()
{
var state = new GameState(
string.Empty,
new Dictionary<string, Vote>()
new Dictionary<string, Vote>
{
{ "a", 1 },
{ "b", 2 }
Expand All @@ -19,7 +19,7 @@ public void Calculates_Average()

Assert.Equal(1.5, state.AverageVote());
}

[Theory]
[InlineData(VoteStatus.Pending)]
[InlineData(VoteStatus.Coffee)]
Expand All @@ -28,7 +28,7 @@ public void Ignores_Non_Voters(VoteStatus vote)
{
var state = new GameState(
string.Empty,
new Dictionary<string, Vote>()
new Dictionary<string, Vote>
{
{ "a", 1 },
{ "b", 2 },
Expand All @@ -47,13 +47,13 @@ public void Returns_Default_When_Nobody_Voted(VoteStatus vote)
{
var state = new GameState(
string.Empty,
new Dictionary<string, Vote>()
new Dictionary<string, Vote>
{
{ "a", vote },
{ "b", vote},
{ "b", vote }
}.ToImmutableDictionary(),
true);

Assert.Equal(default, state.AverageVote());
}
}
Original file line number Diff line number Diff line change
@@ -1,75 +1,73 @@
@using PointingParty.Domain.Events
@inherits TestContext
using AngleSharp.Dom;
using PointingParty.Domain;
using PointingParty.Domain.Events;

@code {
private readonly ITestOutputHelper _testOutputHelper;
private readonly GameAggregate _game;
private readonly IGameContext _gameContext;
namespace PointingParty.Client.Tests;

public class GameUiTests : BunitContext
{
private const string PlayerName = "Player";
private const string GameId = "TestGame";
private readonly GameAggregate _game;
private readonly IGameContext _gameContext;

public GameUiTests(ITestOutputHelper testOutputHelper)
public GameUiTests()
{
_testOutputHelper = testOutputHelper;
_game = new GameAggregate(GameId, PlayerName);
_gameContext = Substitute.For<IGameContext>();
_gameContext.Game = _game;

JSInterop.Mode = JSRuntimeMode.Loose;
}

[Fact]
public void Renders_PlayerName()
{
_gameContext.PlayerName.Returns(PlayerName);
var cut = Render(@<GameUi GameContext="@_gameContext"/>);

var cut = Render<GameUi>(parameters => parameters.Add(p => p.GameContext, _gameContext));
cut.Find("h3").TextContent.MarkupMatches($"Your vote, {PlayerName}:");
}

[Fact]
public void Publishes_PlayerJoined_Event()
{
Render(@<GameUi GameContext="@_gameContext"/>);
Render<GameUi>(parameters => parameters.Add(p => p.GameContext, _gameContext));

Assert.Collection(_game.EventsToPublish, e => Assert.IsType<PlayerJoinedGame>(e));
_gameContext.Received(1).PublishEvents();
}

[Fact]
public void Publishes_Vote_Event()
{
var cut = Render(@<GameUi GameContext="@_gameContext"/>);
var cut = Render<GameUi>(parameters => parameters.Add(p => p.GameContext, _gameContext));

_gameContext.ClearReceivedCalls();
_game.EventsToPublish.Clear();

cut.FindComponent<VoteButton>().Find("button").Click();

Assert.Collection(_game.EventsToPublish, e =>
{
Assert.IsType<VoteCast>(e);
Assert.Equal(((VoteCast)e).Vote, 1);
});

_gameContext.Received(1).PublishEvents();
}

[Fact]
public void Publishes_VotesShown_Event()
{
var cut = Render(@<GameUi GameContext="@_gameContext"/>);
var cut = Render<GameUi>(parameters => parameters.Add(p => p.GameContext, _gameContext));

_gameContext.ClearReceivedCalls();
_game.EventsToPublish.Clear();

cut.FindComponent<FatButton>().Find("button").Click();

Assert.Collection(_game.EventsToPublish, e =>
{
Assert.IsType<VotesShown>(e);
});
Assert.Collection(_game.EventsToPublish, e => { Assert.IsType<VotesShown>(e); });

_gameContext.Received(1).PublishEvents();
}
Expand All @@ -79,15 +77,15 @@ public void Shows_Players_Alphabetized()
{
_game.Handle(new PlayerJoinedGame(GameId, "Player Two"));
_game.Handle(new PlayerJoinedGame(GameId, "Player Three"));

var cut = Render(@<GameUi GameContext="@_gameContext"/>);

var results = cut.FindAll(@"table[data-testid=""results""] tbody tr td:first-child");
var cut = Render<GameUi>(parameters => parameters.Add(p => p.GameContext, _gameContext));

var results = cut.FindAll("""table[data-testid="results"] tbody tr td:first-child""");

Assert.Collection(results,
e => { Assert.Equal(e.GetInnerText(), PlayerName); },
e => { Assert.Equal(e.GetInnerText(), "Player Three"); },
e => { Assert.Equal(e.GetInnerText(), "Player Two"); }
e => { Assert.Equal(PlayerName, e.GetInnerText()); },
e => { Assert.Equal("Player Three", e.GetInnerText()); },
e => { Assert.Equal("Player Two", e.GetInnerText()); }
);
}

Expand All @@ -96,21 +94,21 @@ public void Hides_Votes_By_Default()
{
_game.Handle(new PlayerJoinedGame(GameId, "Player Two"));
_game.Handle(new VoteCast(GameId, "Player Two", 8));
var cut = Render(@<GameUi GameContext="@_gameContext"/>);
var results = cut.Find(@"[data-testid=""vote-for-Player Two""]");
Assert.Equal(results.GetInnerText(), "Voted!");

var cut = Render<GameUi>(parameters => parameters.Add(p => p.GameContext, _gameContext));
var results = cut.Find("""[data-testid="vote-for-Player Two"]""");
Assert.Equal("Voted!", results.GetInnerText());
}

[Fact]
public void Shows_Votes_After_VotesShown_Event()
{
_game.Handle(new PlayerJoinedGame(GameId, "Player Two"));
_game.Handle(new VoteCast(GameId, "Player Two", 8));
_game.Handle(new VotesShown(GameId));

var cut = Render(@<GameUi GameContext="@_gameContext"/>);
var results = cut.Find(@"[data-testid=""vote-for-Player Two""]");
Assert.Equal(results.GetInnerText(), "8");
var cut = Render<GameUi>(parameters => parameters.Add(p => p.GameContext, _gameContext));
var results = cut.Find("""[data-testid="vote-for-Player Two"]""");
Assert.Equal("8", results.GetInnerText());
}
}
}
2 changes: 2 additions & 0 deletions PointingParty.Client.Tests/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
global using Bunit;
global using NSubstitute;
global using Xunit;
78 changes: 78 additions & 0 deletions PointingParty.Client.Tests/Pages/GameTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using Bunit.TestDoubles;
using Microsoft.Extensions.DependencyInjection;
using PointingParty.Client.Pages;
using PointingParty.Domain;

namespace PointingParty.Client.Tests.Pages;

public class GameTests : BunitContext
{
private readonly IGameContext _gameContext;

public GameTests()
{
_gameContext = Substitute.For<IGameContext>();
Services.AddTransient<IGameContext>(_ => _gameContext);
ComponentFactories.AddStub<GameUi>();
}

[Fact]
public void WhenSubmittingForm_CreatesGame()
{
var cut = Render<Game>(parameters =>
parameters.Add(p => p.GameId, "Game"));

var nameInput = cut.Find("""input[placeholder="Player Name"]""");
nameInput.Change("Player");

cut.Find("button").Click();

_gameContext.Received(1).CreateGame("Game", "Player");
_gameContext.Received(1).Initialize(Arg.Any<Action>());
}

[Fact]
public void WithGame_RendersGameUi()
{
_gameContext.Game.Returns(new GameAggregate());

var cut = Render<Game>(parameters =>
parameters.Add(p => p.GameId, "Game"));

Assert.NotNull(cut.FindComponent<Stub<GameUi>>());
}

[Fact]
public void WithGame_RendersTitle()
{
_gameContext.Game.Returns(new GameAggregate());

var cut = Render<Game>(parameters =>
parameters.Add(p => p.GameId, "Game"));

var h2 = cut.Find("h2");

Assert.Equal("Pointing Party: Game", h2.TextContent);
}

[Fact]
public void WithPlayerName_CreatesGame_And_UpdatesUrl()
{
_gameContext.Game.Returns(new GameAggregate());
var navMan = Services.GetRequiredService<BunitNavigationManager>();

navMan.NavigateTo("/Game/Game?PlayerName=Player");

Render<Game>(parameters => { parameters.Add(p => p.GameId, "Game"); });

Assert.Equal("http://localhost/Game/Game", navMan.Uri);

_gameContext.Received(1).CreateGame("Game", "Player");
_gameContext.Received(1).Initialize(Arg.Any<Action>());
}

protected override void Dispose(bool disposing)
{
// Override BunitContext.Dispose to avoid calling sync Dispose on the Services
}
}
16 changes: 12 additions & 4 deletions PointingParty.Client.Tests/PointingParty.Client.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="bunit" Version="2.0.24-preview" />
<PackageReference Include="bunit" Version="2.0.24-preview"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0"/>
<PackageReference Include="NSubstitute" Version="5.1.0" />
<PackageReference Include="xunit" Version="2.8.1" />
<PackageReference Include="NSubstitute" Version="5.1.0"/>
<PackageReference Include="NSubstitute.Analyzers.CSharp" Version="1.0.17">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit" Version="2.8.1"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
Expand All @@ -25,7 +29,11 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\PointingParty.Client\PointingParty.Client.csproj" />
<ProjectReference Include="..\PointingParty.Client\PointingParty.Client.csproj"/>
</ItemGroup>

<ItemGroup>
<AdditionalFiles Include="GameUiTests.cs"/>
</ItemGroup>

</Project>
12 changes: 0 additions & 12 deletions PointingParty.Client.Tests/_Imports.razor

This file was deleted.

Loading
Loading