forked from xiongyuxing/tiku-backend.net
123 lines
5.6 KiB
C#
123 lines
5.6 KiB
C#
using System.Net;
|
|
using System.Text.Json;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Tiku.Domain.Catalog;
|
|
using Tiku.Domain.Common;
|
|
using Tiku.Domain.Tenancy;
|
|
using Tiku.Infrastructure.Persistence;
|
|
|
|
namespace Tiku.IntegrationTests.Api;
|
|
|
|
public sealed class ScorelineEndpointTests
|
|
{
|
|
[Fact]
|
|
public async Task Public_scoreline_records_support_dynamic_filters()
|
|
{
|
|
await using var factory = new ApiTestFactory();
|
|
var tenantId = Guid.NewGuid();
|
|
var regionId = Guid.NewGuid();
|
|
var schoolId = Guid.NewGuid();
|
|
var majorId = Guid.NewGuid();
|
|
var tenantCode = tenantId.ToString("N");
|
|
await factory.SeedAsync(
|
|
new Tenant
|
|
{
|
|
Id = tenantId,
|
|
Slug = tenantCode,
|
|
Name = "Test Tenant",
|
|
Status = TenantStatus.Active,
|
|
Metadata = JsonDefaults.Object()
|
|
},
|
|
new Region { Id = regionId, TenantId = tenantId, Name = "四川" },
|
|
new School { Id = schoolId, TenantId = tenantId, RegionId = regionId, Name = "美术学院" },
|
|
new Major { Id = majorId, TenantId = tenantId, RegionId = regionId, SchoolId = schoolId, Name = "视觉传达" },
|
|
new ScorelineField
|
|
{
|
|
TenantId = tenantId,
|
|
RegionId = regionId,
|
|
FieldKey = "cultureScore",
|
|
FieldName = "文化分",
|
|
FieldType = "number",
|
|
IsFilter = true,
|
|
IsTrend = true
|
|
},
|
|
new ScorelineRecord
|
|
{
|
|
TenantId = tenantId,
|
|
RegionId = regionId,
|
|
SchoolId = schoolId,
|
|
MajorId = majorId,
|
|
Year = 2026,
|
|
SchoolName = "美术学院",
|
|
MajorName = "视觉传达",
|
|
FieldValues = JsonSerializer.SerializeToElement(new { cultureScore = 420, scoreType = "统考" })
|
|
},
|
|
new ScorelineRecord
|
|
{
|
|
TenantId = tenantId,
|
|
RegionId = regionId,
|
|
SchoolId = schoolId,
|
|
MajorId = majorId,
|
|
Year = 2025,
|
|
SchoolName = "美术学院",
|
|
MajorName = "视觉传达",
|
|
FieldValues = JsonSerializer.SerializeToElement(new { cultureScore = 360, scoreType = "统考" })
|
|
});
|
|
using var client = factory.CreateClient();
|
|
|
|
using var response = await client.GetAsync(
|
|
$"/api/scoreline/records?tenantCode={tenantCode}®ionId={regionId}&min.cultureScore=400");
|
|
var json = await ReadJsonAsync(response);
|
|
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
Assert.Equal(1, json.RootElement.GetProperty("total").GetInt32());
|
|
var item = json.RootElement.GetProperty("items").EnumerateArray().Single();
|
|
Assert.Equal(2026, item.GetProperty("year").GetInt32());
|
|
Assert.Equal(420, item.GetProperty("fieldValues").GetProperty("cultureScore").GetInt32());
|
|
|
|
using var firstCursorResponse = await client.GetAsync(
|
|
$"/api/scoreline/records/cursor?tenantCode={tenantCode}®ionId={regionId}&pageSize=1");
|
|
var firstCursorJson = await ReadJsonAsync(firstCursorResponse);
|
|
Assert.Equal(HttpStatusCode.OK, firstCursorResponse.StatusCode);
|
|
Assert.True(firstCursorJson.RootElement.GetProperty("hasMore").GetBoolean());
|
|
var firstCursorItem = firstCursorJson.RootElement.GetProperty("items").EnumerateArray().Single();
|
|
var firstCursorId = firstCursorItem.GetProperty("id").GetGuid();
|
|
var nextCursor = firstCursorJson.RootElement.GetProperty("nextCursor").GetString();
|
|
Assert.False(string.IsNullOrWhiteSpace(nextCursor));
|
|
|
|
using var secondCursorResponse = await client.GetAsync(
|
|
$"/api/scoreline/records/cursor?tenantCode={tenantCode}®ionId={regionId}&pageSize=1&cursor={Uri.EscapeDataString(nextCursor!)}");
|
|
var secondCursorJson = await ReadJsonAsync(secondCursorResponse);
|
|
Assert.Equal(HttpStatusCode.OK, secondCursorResponse.StatusCode);
|
|
Assert.False(secondCursorJson.RootElement.GetProperty("hasMore").GetBoolean());
|
|
var secondCursorItem = secondCursorJson.RootElement.GetProperty("items").EnumerateArray().Single();
|
|
Assert.NotEqual(firstCursorId, secondCursorItem.GetProperty("id").GetGuid());
|
|
Assert.Equal(2025, secondCursorItem.GetProperty("year").GetInt32());
|
|
|
|
using var invalidCursorResponse = await client.GetAsync(
|
|
$"/api/scoreline/records/cursor?tenantCode={tenantCode}®ionId={regionId}&cursor=not-a-cursor");
|
|
var invalidCursorJson = await ReadJsonAsync(invalidCursorResponse);
|
|
Assert.Equal(HttpStatusCode.BadRequest, invalidCursorResponse.StatusCode);
|
|
Assert.Equal("scoreline_cursor_invalid", invalidCursorJson.RootElement.GetProperty("code").GetString());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Public_scoreline_without_tenant_returns_not_found()
|
|
{
|
|
await using var factory = new ApiTestFactory();
|
|
using var client = factory.CreateClient();
|
|
|
|
using var response = await client.GetAsync("/api/scoreline/fields");
|
|
var json = await ReadJsonAsync(response);
|
|
|
|
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
|
Assert.Equal("tenant_not_found", json.RootElement.GetProperty("code").GetString());
|
|
}
|
|
|
|
private static async Task<JsonDocument> ReadJsonAsync(HttpResponseMessage response)
|
|
{
|
|
var stream = await response.Content.ReadAsStreamAsync();
|
|
return await JsonDocument.ParseAsync(stream);
|
|
}
|
|
}
|