using System.Text.Json;
using Yavsc.Blogspot;
using Yavsc.Models.Blog;
namespace Yavsc.Blogs.Tests;
///
/// Wire-shape tests pinning that
/// is carried on the JSON the blog API list endpoint emits.
///
/// The blog API host (Yavsc.Blogs/Program.cs) serialises
/// with System.Text.Json (the .AddControllers() default — no
/// AddNewtonsoftJson), and BlogApiController.GetBlogspot
/// returns IEnumerable<IBlogPost>. System.Text.Json emits
/// only the members of the declared type, so a property that
/// exists solely on the concrete BlogPost entity is dropped from
/// the payload. IsPublished used to be one such property: it was
/// on BlogPost and BlogPostDto but not on
/// , so the list response omitted it and PostIt
/// read IsPublished == false for every post — including
/// published ones.
///
/// These tests reproduce that serialisation path directly
/// (declared type IEnumerable<IBlogPost> through
/// ) and assert
/// isPublished survives the round trip. They live in
/// Yavsc.Blogs.Tests — the assembly that owns the blog API
/// contract — so a regression at the wire boundary is caught here,
/// where it manifested in production (PostIt showing a published
/// post's status as false).
///
public sealed class IBlogPostWireShapeTests
{
private static readonly JsonSerializerOptions WebDefaults
= new(JsonSerializerDefaults.Web);
[Fact]
public void IsPublished_is_emitted_when_list_is_serialised_as_IEnumerable_IBlogPost()
{
var post = new BlogPost
{
Id = 13,
Title = "Published",
AuthorId = "alice",
Article = "x",
};
post.IsPublished = true;
// Declared type mirrors GetBlogspot's return: IEnumerable.
IEnumerable list = new List { post };
// Serialize with the DECLARED type, the way ASP.NET Core's
// SystemTextJsonOutputFormatter hands context.ObjectType (the
// action return type) to JsonSerializer.Serialize.
var json = JsonSerializer.Serialize(list, typeof(IEnumerable),
WebDefaults);
using var doc = JsonDocument.Parse(json);
var element = doc.RootElement[0];
// Web defaults use camelCase, so the property is "isPublished".
Assert.True(element.TryGetProperty("isPublished", out var isPublished),
$"isPublished was dropped from the list payload. JSON: {json}");
Assert.True(isPublished.GetBoolean());
}
[Fact]
public void IsPublished_round_trips_through_BlogPostDto_on_the_client()
{
// The shape the client (PostIt) receives and deserialises with
// PropertyNameCaseInsensitive = true (cf. YavscApiClient).
var json = """
[{
"id": 13,
"title": "Published",
"article": "x",
"authorId": "alice",
"isPublished": true
}]
""";
var posts = JsonSerializer.Deserialize>(json,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true })!;
var post = Assert.Single(posts);
Assert.True(post.IsPublished);
}
}