121 lines
4.3 KiB
C#
121 lines
4.3 KiB
C#
using Elternbeirat.PocketBase;
|
|
|
|
namespace Elternbeirat.Web.Tests;
|
|
|
|
/// <summary>
|
|
/// Tests the <see cref="PocketBaseClient"/> against a throwaway PocketBase container
|
|
/// with a known seed (see <see cref="PocketBaseFixture"/>). Because the data is fixed,
|
|
/// the tests assert on exact values, and they need no network to the live instance.
|
|
/// </summary>
|
|
[Collection(PocketBaseTestGroup.Name)]
|
|
public sealed class PocketBaseClientTests(PocketBaseFixture pocketBase)
|
|
{
|
|
[Fact]
|
|
public async Task Events_load_sorted_by_start()
|
|
{
|
|
var client = pocketBase.CreateClient();
|
|
|
|
var events = await client.GetEventsAsync();
|
|
|
|
// Two seeded events, earliest start first.
|
|
events.Select(@event => @event.Title).ShouldBe(["Elternbeiratssitzung", "Herbstbasar"]);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Event_utc_is_converted_to_berlin_wall_clock()
|
|
{
|
|
var client = pocketBase.CreateClient();
|
|
|
|
var events = await client.GetEventsAsync();
|
|
|
|
// The meeting is seeded as 17:30Z. October is summer time (UTC+2), so the
|
|
// converter turns it into 19:30 Berlin wall-clock -- the time an editor
|
|
// entered in the admin form.
|
|
var meeting = events.FirstOrDefault(e =>
|
|
e.Title.Contains("Elternbeiratssitzung", StringComparison.Ordinal));
|
|
meeting.ShouldNotBeNull();
|
|
meeting.Start.Hour.ShouldBe(19);
|
|
meeting.Start.Minute.ShouldBe(30);
|
|
meeting.Start.Kind.ShouldBe(DateTimeKind.Unspecified);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Event_without_end_maps_to_null()
|
|
{
|
|
var client = pocketBase.CreateClient();
|
|
|
|
var events = await client.GetEventsAsync();
|
|
|
|
var meeting = events.Single(@event => @event.Title == "Elternbeiratssitzung");
|
|
var basar = events.Single(@event => @event.Title == "Herbstbasar");
|
|
meeting.End.ShouldBeNull(); // no end seeded
|
|
basar.End.ShouldNotBeNull(); // end seeded
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Posts_load_newest_first()
|
|
{
|
|
var client = pocketBase.CreateClient();
|
|
|
|
var posts = await client.GetPostsAsync();
|
|
|
|
// Sorted by -date: March before January.
|
|
posts.Select(post => post.Title).ShouldBe(["Neuer Vorstand", "Neue Sporthalle"]);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Post_date_is_the_berlin_calendar_day()
|
|
{
|
|
var client = pocketBase.CreateClient();
|
|
|
|
var posts = await client.GetPostsAsync();
|
|
|
|
// The post is seeded as 2026-03-01 23:30Z, which is 2 March 00:30 in Berlin.
|
|
// The date is the Berlin day the editor picked (2 March), not the raw UTC
|
|
// day (1 March) -- the time zone is applied before the day is taken.
|
|
var post = posts.Single(p => p.Title == "Neuer Vorstand");
|
|
post.Date.ShouldBe(new DateOnly(2026, 3, 2));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Pages_exclude_non_public_records()
|
|
{
|
|
var client = pocketBase.CreateClient();
|
|
|
|
var pages = await client.GetPagesAsync();
|
|
|
|
// The draft (public=false) must be filtered out, the public ones present.
|
|
pages.ShouldNotContain(page => page.Slug == "draft");
|
|
pages.ShouldContain(page => page.Slug == "home");
|
|
pages.ShouldContain(page => page.Slug == "contact");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Page_embed_is_read_as_list()
|
|
{
|
|
var client = pocketBase.CreateClient();
|
|
|
|
var pages = await client.GetPagesAsync();
|
|
|
|
var home = pages.Single(p => p.Slug == "home");
|
|
home.Embed.ShouldBe(["posts", "events"], ignoreOrder: true);
|
|
// Home sits in the header like every other page (location is required); it
|
|
// is the single source of the home nav link.
|
|
home.Location.ShouldBe("header");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Faqs_load_from_instance()
|
|
{
|
|
var client = pocketBase.CreateClient();
|
|
|
|
var faqs = await client.GetFaqsAsync();
|
|
|
|
// The topic relation is expanded, so each entry carries its topic. The two
|
|
// seeded topics are ordered (Mensa order 1 before Schließfächer order 2), and
|
|
// GetFaqsAsync sorts by topic.order, so the groups come back in that order.
|
|
faqs.Select(faq => faq.Topic?.Title).ShouldBe(["Mensa und Mittagessen", "Schließfächer"]);
|
|
faqs.ShouldAllBe(faq => !string.IsNullOrWhiteSpace(faq.Question));
|
|
}
|
|
}
|