123 lines
5.6 KiB
C#
123 lines
5.6 KiB
C#
using System.Net;
|
|
using System.Net.Http.Json;
|
|
|
|
namespace HSchool.AppHost.Tests;
|
|
|
|
[Collection(AppHostCollection.Name)]
|
|
public class NoticeImageApiTests(AppHostFixture fixture)
|
|
{
|
|
private static readonly DateTime Start = new(2012, 4, 3, 6, 0, 0, DateTimeKind.Utc);
|
|
|
|
[Fact]
|
|
public async Task OwnerGenerate_MatchesCardOutcome_GuestIs403()
|
|
{
|
|
using var owner = await SchoolApiTests.CreateIsolatedClientAsync(fixture.App, "NoticeImageOwner");
|
|
await SchoolApiTests.WipeAllSavesAsync(owner);
|
|
var school = await SchoolApiTests.CreateAsync(owner, "Кнопка хозяина", Start);
|
|
var personId = await FirstPersonIdAsync(owner, school.Id);
|
|
var posted = await PostNoticeAsync(owner, school.Id, "GenerationFailed", personId, "full");
|
|
|
|
using var card = await owner.PostAsync(
|
|
$"/api/schools/{school.Id}/people/{Uri.EscapeDataString(personId)}/portrait?kind=full",
|
|
content: null,
|
|
TestContext.Current.CancellationToken);
|
|
using var fromNotice = await owner.PostAsync(
|
|
$"/api/schools/{school.Id}/notices/{posted.Id}/generate",
|
|
content: null,
|
|
TestContext.Current.CancellationToken);
|
|
|
|
Assert.Equal(card.StatusCode, fromNotice.StatusCode);
|
|
Assert.Equal(await SchoolApiTests.ProblemCodeAsync(card), await SchoolApiTests.ProblemCodeAsync(fromNotice));
|
|
|
|
var paused = (await SchoolApiTests.GetSchoolsAsync(owner)).Schools.Single(item => item.Id == school.Id);
|
|
Assert.False(paused.Running);
|
|
|
|
using var guest = await SchoolApiTests.CreateIsolatedClientAsync(fixture.App, "NoticeImageGuest");
|
|
using var forbidden = await guest.PostAsync(
|
|
$"/api/schools/{school.Id}/notices/{posted.Id}/generate",
|
|
content: null,
|
|
TestContext.Current.CancellationToken);
|
|
Assert.Equal(HttpStatusCode.Forbidden, forbidden.StatusCode);
|
|
Assert.Equal("not-owner", await SchoolApiTests.ProblemCodeAsync(forbidden));
|
|
|
|
var stillPaused = (await SchoolApiTests.GetSchoolsAsync(owner)).Schools.Single(item => item.Id == school.Id);
|
|
Assert.False(stillPaused.Running);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GenerateWithoutPerson_DoesNotCallSwarm()
|
|
{
|
|
using var client = fixture.App.CreateHttpClient("server");
|
|
await SchoolApiTests.ResetAsync(client);
|
|
var school = await SchoolApiTests.CreateAsync(client, "Без человека", Start);
|
|
var posted = await PostNoticeAsync(client, school.Id, "GenerationFailed");
|
|
|
|
using var response = await client.PostAsync(
|
|
$"/api/schools/{school.Id}/notices/{posted.Id}/generate",
|
|
content: null,
|
|
TestContext.Current.CancellationToken);
|
|
|
|
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
|
var code = await SchoolApiTests.ProblemCodeAsync(response);
|
|
Assert.Equal("notice-cannot-generate", code);
|
|
Assert.NotEqual("swarmui-not-configured", code);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task NoticePersonPrompt_ContainsThePersonNotAnEmptyCorridor()
|
|
{
|
|
using var client = fixture.App.CreateHttpClient("server");
|
|
await SchoolApiTests.ResetAsync(client);
|
|
var school = await SchoolApiTests.CreateAsync(client, "Сцена с человеком", Start);
|
|
var personId = await FirstPersonIdAsync(client, school.Id);
|
|
await PostNoticeAsync(client, school.Id, "GenerationFailed", personId, "full");
|
|
|
|
using var response = await client.GetAsync(
|
|
$"/api/schools/{school.Id}/people/{Uri.EscapeDataString(personId)}/portrait/prompt?kind=full",
|
|
TestContext.Current.CancellationToken);
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
var payload = await response.Content.ReadFromJsonAsync<PortraitPromptPayload>(TestContext.Current.CancellationToken);
|
|
Assert.NotNull(payload);
|
|
Assert.Contains("years old", payload!.Positive, StringComparison.OrdinalIgnoreCase);
|
|
Assert.Contains("wearing", payload.Positive, StringComparison.OrdinalIgnoreCase);
|
|
Assert.DoesNotMatch(@"\bage \d+", payload.Positive);
|
|
Assert.DoesNotContain("empty corridor", payload.Positive, StringComparison.OrdinalIgnoreCase);
|
|
Assert.False(string.IsNullOrWhiteSpace(payload.Negative));
|
|
}
|
|
|
|
private static async Task<string> FirstPersonIdAsync(HttpClient client, int schoolId)
|
|
{
|
|
var page = await client.GetFromJsonAsync<PeopleListResponse>(
|
|
$"/api/schools/{schoolId}/people?pageSize=1",
|
|
TestContext.Current.CancellationToken);
|
|
Assert.NotNull(page);
|
|
Assert.NotEmpty(page!.People);
|
|
return page.People[0].Id;
|
|
}
|
|
|
|
private static async Task<DevNoticeResponse> PostNoticeAsync(
|
|
HttpClient client,
|
|
int schoolId,
|
|
string defName,
|
|
string? person = null,
|
|
string? kind = null)
|
|
{
|
|
using var response = await client.PostAsJsonAsync(
|
|
$"/api/dev/schools/{schoolId}/notices",
|
|
new { defName, person, kind },
|
|
TestContext.Current.CancellationToken);
|
|
response.EnsureSuccessStatusCode();
|
|
var body = await response.Content.ReadFromJsonAsync<DevNoticeResponse>(TestContext.Current.CancellationToken);
|
|
Assert.NotNull(body);
|
|
return body;
|
|
}
|
|
|
|
private sealed record PeopleListResponse(int Total, IReadOnlyList<PersonListItem> People);
|
|
|
|
private sealed record PersonListItem(string Id);
|
|
|
|
private sealed record DevNoticeResponse(uint Id, string DefName, bool Pause);
|
|
|
|
private sealed record PortraitPromptPayload(string Kind, string Positive, string Negative);
|
|
}
|