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

v3.28.0 #596

Merged
merged 31 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c53ec34
Resolves #522
sei-bstein Jan 6, 2025
edbc0c2
WIP export
sei-bstein Jan 7, 2025
fa9343e
Merge branch 'next' into feature/export
sei-bstein Jan 7, 2025
52e2879
Fix an issue that caused the game name to be null in ticket markdown …
sei-bstein Jan 7, 2025
5a4d568
Fixed an issue where challenges from games with no end date wouldn't …
sei-bstein Jan 7, 2025
2c75ab1
Merge branch 'next' into feature/export
sei-bstein Jan 7, 2025
9d81b6e
Add cancellation tokens to report endpoints, fix denorm bug for new s…
sei-bstein Jan 8, 2025
b3f4346
Cleanup
sei-bstein Jan 8, 2025
cc5e44b
Minor cleanup
sei-bstein Jan 9, 2025
a01c4d3
Merge branch 'next' into feature/export
sei-bstein Jan 9, 2025
b48c607
WIP import/export
sei-bstein Jan 9, 2025
2a0d112
Merge branch 'next' into feature/export
sei-bstein Jan 10, 2025
058dc86
Fix flailing test and more defense for session time stuff
sei-bstein Jan 11, 2025
900672a
Merge branch 'next' into feature/export
sei-bstein Jan 11, 2025
25b5532
WIP import/export
sei-bstein Jan 11, 2025
420f89f
MVP import/export endpoints
sei-bstein Jan 14, 2025
64ab1cb
Fix 'top performance' for #594
sei-bstein Jan 14, 2025
5b5a600
Add 'completed teams' to game center for #594
sei-bstein Jan 14, 2025
d804268
Remove old cert stuff. Rename RequirePermissions to Require. Fix tests
sei-bstein Jan 14, 2025
396fc6b
Remove version endpoint since we no longer support it anyway.
sei-bstein Jan 14, 2025
0064bd6
Resolve #572
sei-bstein Jan 14, 2025
3ceba4e
Fixed autotagging bug and minor cleanup
sei-bstein Jan 15, 2025
0b5625a
Fix autotagging bugs, add observe to practice tab, fix import/export …
sei-bstein Jan 15, 2025
0f3ea4f
Fix bug that prevented feedback from loading for support personnel
sei-bstein Jan 15, 2025
9848b05
Fix enrollment report unstarted teams calc. Fix challenge launch fail…
sei-bstein Jan 15, 2025
d75c517
Align calculation of 'team has started' logic
sei-bstein Jan 15, 2025
d1a1cd3
Minor cleanup
sei-bstein Jan 15, 2025
dee881d
Add export download endpoint
sei-bstein Jan 16, 2025
3ab0967
Add missing export field
sei-bstein Jan 16, 2025
9672319
Add missing field
sei-bstein Jan 16, 2025
72dd922
Hide test in dev
sei-bstein Jan 16, 2025
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,7 @@ Thumbs.db
# git-kept
src/Gameboard.Api/wwwroot/temp/*
!.gitkeep

# stuff that gameboard makes as part of being itself
src/Gameboard.Api/wwwroot/export/*
src/Gameboard.Api/wwwroot/import/*
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
namespace Gameboard.Api.Tests.Integration;

public class CertificatesControllerTests_GetCertificatesTests(GameboardTestContext testContext) : IClassFixture<GameboardTestContext>
{
private readonly GameboardTestContext _testContext = testContext;

// [Theory, GbIntegrationAutoData]
// public async Task GetCertificates_WhenScoreConstrained_ReturnsExpectedCount
// (
// int score,
// string scoringUserId,
// string scoringPlayerId,
// string nonScoringUserId,
// string nonScoringPlayerId,
// IFixture fixture
// )
// {
// // given
// var now = DateTimeOffset.UtcNow;

// await _testContext.WithDataState(state =>
// {
// state.Add<Data.Game>(fixture, g =>
// {
// g.GameEnd = now - TimeSpan.FromDays(1);
// g.CertificateTemplateLegacy = "This is a template with a {{player_count}}.";
// g.Players =
// [
// // i almost broke my brain trying to get GbIntegrationAutoData to work with
// // inline autodata, so I'm just doing two checks here
// state.Build<Data.Player>(fixture, p =>
// {
// p.Id = scoringPlayerId;
// p.User = state.Build<Data.User>(fixture, u => u.Id = scoringUserId);
// p.UserId = scoringUserId;
// p.SessionEnd = now - TimeSpan.FromDays(-2);
// p.TeamId = "teamId";
// p.Score = score;
// }),
// state.Build<Data.Player>(fixture, p =>
// {
// p.Id = nonScoringPlayerId;
// p.User = state.Build<Data.User>(fixture, u => u.Id = nonScoringUserId);
// p.UserId = nonScoringUserId;
// p.SessionEnd = now - TimeSpan.FromDays(-2);
// p.TeamId = "teamId";
// p.Score = score;
// })
// ];
// });
// });

// var httpClient = _testContext.CreateHttpClientWithActingUser(u => u.Id = scoringUserId);

// // when
// var certs = await httpClient
// .GetAsync("/api/certificates")
// .DeserializeResponseAs<IEnumerable<PlayerCertificate>>();

// // then
// certs?.Count().ShouldBe(1);
// certs?.First().Player.Id.ShouldBe(scoringPlayerId);
// }

// [Theory, GbIntegrationAutoData]
// public async Task GetCertificates_WithTeamsAndNonScorers_ReturnsExpected(string teamId, string userId, IFixture fixture)
// {
// // given
// var now = DateTimeOffset.UtcNow;
// var recentDate = DateTime.UtcNow.AddDays(-1);

// await _testContext.WithDataState(state =>
// {
// state.Add<Data.Game>(fixture, g =>
// {
// g.CertificateTemplateLegacy = "This is a template with a {{player_count}} and a {{team_count}}.";
// g.GameEnd = now - TimeSpan.FromDays(1);
// g.Players = new List<Data.Player>
// {
// // three players with nonzero score (2 on the same team)
// state.Build<Data.Player>(fixture, p =>
// {
// p.SessionEnd = recentDate;
// p.Score = 20;
// p.User = state.Build<Data.User>(fixture, u => u.Id = userId);
// }),
// state.Build<Data.Player>(fixture, p =>
// {
// p.SessionEnd = recentDate;
// p.Score = 30;
// p.TeamId = teamId;
// }),
// state.Build<Data.Player>(fixture, p =>
// {
// p.SessionEnd = recentDate;
// p.Score = 30;
// p.TeamId = teamId;
// }),
// // one player with zero score
// state.Build<Data.Player>(fixture, p =>
// {
// p.SessionEnd = recentDate;
// p.Score = 0;
// }),
// };
// });
// });

// var httpClient = _testContext.CreateHttpClientWithActingUser(u => u.Id = userId);

// // when
// var certsResponse = await httpClient
// .GetAsync("/api/certificates")
// .DeserializeResponseAs<IEnumerable<PlayerCertificate>>();

// // then
// var certs = certsResponse.ToArray();
// certs.ShouldNotBeNull();
// certs.Count().ShouldBe(1);
// certs.First().Html.ShouldBe("This is a template with a 3 and a 2.");
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,120 +50,4 @@ await _testContext
// assert
updatedPlayer?.NameStatus.ShouldBe(AppConstants.NameStatusNotUnique);
}

[Theory, GbIntegrationAutoData]
public async Task GetCertificates_WhenScoreConstrained_ReturnsExpectedCount
(
int score,
string scoringUserId,
string scoringPlayerId,
string nonScoringUserId,
string nonScoringPlayerId,
IFixture fixture
)
{
// given
var now = DateTimeOffset.UtcNow;

await _testContext.WithDataState(state =>
{
state.Add<Data.Game>(fixture, g =>
{
g.GameEnd = now - TimeSpan.FromDays(1);
g.CertificateTemplateLegacy = "This is a template with a {{player_count}}.";
g.Players =
[
// i almost broke my brain trying to get GbIntegrationAutoData to work with
// inline autodata, so I'm just doing two checks here
state.Build<Data.Player>(fixture, p =>
{
p.Id = scoringPlayerId;
p.User = state.Build<Data.User>(fixture, u => u.Id = scoringUserId);
p.UserId = scoringUserId;
p.SessionEnd = now - TimeSpan.FromDays(-2);
p.TeamId = "teamId";
p.Score = score;
}),
state.Build<Data.Player>(fixture, p =>
{
p.Id = nonScoringPlayerId;
p.User = state.Build<Data.User>(fixture, u => u.Id = nonScoringUserId);
p.UserId = nonScoringUserId;
p.SessionEnd = now - TimeSpan.FromDays(-2);
p.TeamId = "teamId";
p.Score = score;
})
];
});
});

var httpClient = _testContext.CreateHttpClientWithActingUser(u => u.Id = scoringUserId);

// when
var certs = await httpClient
.GetAsync("/api/certificates")
.DeserializeResponseAs<IEnumerable<PlayerCertificate>>();

// then
certs?.Count().ShouldBe(1);
certs?.First().Player.Id.ShouldBe(scoringPlayerId);
}

[Theory, GbIntegrationAutoData]
public async Task GetCertificates_WithTeamsAndNonScorers_ReturnsExpected(string teamId, string userId, IFixture fixture)
{
// given
var now = DateTimeOffset.UtcNow;
var recentDate = DateTime.UtcNow.AddDays(-1);

await _testContext.WithDataState(state =>
{
state.Add<Data.Game>(fixture, g =>
{
g.CertificateTemplateLegacy = "This is a template with a {{player_count}} and a {{team_count}}.";
g.GameEnd = now - TimeSpan.FromDays(1);
g.Players = new List<Data.Player>
{
// three players with nonzero score (2 on the same team)
state.Build<Data.Player>(fixture, p =>
{
p.SessionEnd = recentDate;
p.Score = 20;
p.User = state.Build<Data.User>(fixture, u => u.Id = userId);
}),
state.Build<Data.Player>(fixture, p =>
{
p.SessionEnd = recentDate;
p.Score = 30;
p.TeamId = teamId;
}),
state.Build<Data.Player>(fixture, p =>
{
p.SessionEnd = recentDate;
p.Score = 30;
p.TeamId = teamId;
}),
// one player with zero score
state.Build<Data.Player>(fixture, p =>
{
p.SessionEnd = recentDate;
p.Score = 0;
}),
};
});
});

var httpClient = _testContext.CreateHttpClientWithActingUser(u => u.Id = userId);

// when
var certsResponse = await httpClient
.GetAsync("/api/certificates")
.DeserializeResponseAs<IEnumerable<PlayerCertificate>>();

// then
var certs = certsResponse.ToArray();
certs.ShouldNotBeNull();
certs.Count().ShouldBe(1);
certs.First().Html.ShouldBe("This is a template with a 3 and a 2.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,50 +8,50 @@ public class SupportControllerTests(GameboardTestContext testContext) : IClassFi
{
private readonly GameboardTestContext _testContext = testContext;

[Theory, GbIntegrationAutoData]
public async Task Ticket_WhenCreatedWithAutoTagTrigger_AutoTags
(
IFixture fixture,
string gameId,
string tag,
string sponsorId,
string userId
)
{
// given an autotag which triggers on sponsor and a player with that sponsor
await _testContext.WithDataState(state =>
{
state.Add<Data.Game>(fixture, g =>
{
g.Id = gameId;
g.Players = new Data.Player
{
Id = fixture.Create<string>(),
Sponsor = state.Build<Data.Sponsor>(fixture, s => s.Id = sponsorId),
User = new Data.User { Id = userId, SponsorId = sponsorId }
}.ToCollection();
});
// [Theory, GbIntegrationAutoData]
// public async Task Ticket_WhenCreatedWithAutoTagTrigger_AutoTags
// (
// IFixture fixture,
// string gameId,
// string tag,
// string sponsorId,
// string userId
// )
// {
// // given an autotag which triggers on sponsor and a player with that sponsor
// await _testContext.WithDataState(state =>
// {
// state.Add<Data.Game>(fixture, g =>
// {
// g.Id = gameId;
// g.Players = new Data.Player
// {
// Id = fixture.Create<string>(),
// Sponsor = state.Build<Data.Sponsor>(fixture, s => s.Id = sponsorId),
// User = new Data.User { Id = userId, SponsorId = sponsorId }
// }.ToCollection();
// });

state.Add<SupportSettingsAutoTag>(fixture, t =>
{
t.ConditionType = SupportSettingsAutoTagConditionType.SponsorId;
t.ConditionValue = sponsorId;
t.IsEnabled = true;
t.Tag = tag;
});
});
// state.Add<SupportSettingsAutoTag>(fixture, t =>
// {
// t.ConditionType = SupportSettingsAutoTagConditionType.SponsorId;
// t.ConditionValue = sponsorId;
// t.IsEnabled = true;
// t.Tag = tag;
// });
// });

// var result = await _testContext
// .CreateHttpClientWithAuthRole(UserRoleKey.Support)
// .PostAsync("api/ticket", new NewTicket
// {
// AssigneeId = userId,
// Description = fixture.Create<string>(),
// Summary = fixture.Create<string>(),
// RequesterId = userId,
// // var result = await _testContext
// // .CreateHttpClientWithAuthRole(UserRoleKey.Support)
// // .PostAsync("api/ticket", new NewTicket
// // {
// // AssigneeId = userId,
// // Description = fixture.Create<string>(),
// // Summary = fixture.Create<string>(),
// // RequesterId = userId,

// }
// .ToJsonBody())
// .DeserializeResponseAs<Ticket>();
}
// // }
// // .ToJsonBody())
// // .DeserializeResponseAs<Ticket>();
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,8 @@ private void RegisterDefaultEntityModels(IFixture fixture)
fixture.Register(() => new PracticeModeSettings
{
Id = fixture.Create<string>(),
CertificateHtmlTemplate = null,
DefaultPracticeSessionLengthMinutes = 60,
IntroTextMarkdown = null,
SuggestedSearches = ""
SuggestedSearches = string.Empty
});

fixture.Register<Data.Sponsor>(() => new()
Expand Down
Loading