forked from xiongyuxing/tiku-backend.net
feat: add tenant admin engagement endpoints
This commit is contained in:
@@ -7,6 +7,7 @@ using Tiku.Api.Contracts;
|
||||
using Tiku.Domain.Catalog;
|
||||
using Tiku.Domain.Common;
|
||||
using Tiku.Domain.Identity;
|
||||
using Tiku.Domain.Learning;
|
||||
using Tiku.Domain.Operations;
|
||||
using Tiku.Domain.Tenancy;
|
||||
using Tiku.Infrastructure.Auth;
|
||||
@@ -299,6 +300,90 @@ public sealed class TenantAdminDirectEndpointTests
|
||||
Assert.NotEmpty(auditJson.RootElement.GetProperty("items").EnumerateArray());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Tenant_admin_can_manage_badges_notifications_and_feedbacks()
|
||||
{
|
||||
await using var factory = new ApiTestFactory();
|
||||
var seed = await SeedAdminAsync(factory);
|
||||
var studentId = Guid.NewGuid();
|
||||
var feedbackId = Guid.NewGuid();
|
||||
await factory.SeedAsync(
|
||||
new User { Id = studentId, Phone = "13900000005", Name = "反馈学生" },
|
||||
new TenantMembership { TenantId = seed.TenantId, UserId = studentId, Role = TenantRole.Student, Status = MembershipStatus.Active },
|
||||
new StudentProfile { TenantId = seed.TenantId, UserId = studentId },
|
||||
new Report
|
||||
{
|
||||
Id = feedbackId,
|
||||
TenantId = seed.TenantId,
|
||||
UserId = studentId,
|
||||
Type = ReportType.Suggestion,
|
||||
Title = "希望增加解析",
|
||||
Description = "视频解析再详细一点",
|
||||
Status = ReportStatus.Pending
|
||||
});
|
||||
using var client = factory.CreateClient();
|
||||
await LoginAsync(client, seed);
|
||||
|
||||
var badgeResponse = await client.PutAsJsonAsync(
|
||||
"/api/tenant-admin/badges",
|
||||
new UpsertTenantAdminBadgeDto
|
||||
{
|
||||
Name = "反馈达人",
|
||||
Category = "feedback",
|
||||
UnlockType = "manual",
|
||||
Order = 1
|
||||
});
|
||||
var badgeJson = await ReadJsonAsync(badgeResponse);
|
||||
var badgeId = badgeJson.RootElement.GetProperty("item").GetProperty("id").GetGuid();
|
||||
|
||||
var grantResponse = await client.PostAsJsonAsync(
|
||||
"/api/tenant-admin/badge-grants",
|
||||
new GrantTenantAdminBadgeDto
|
||||
{
|
||||
UserId = studentId,
|
||||
BadgeId = badgeId,
|
||||
Note = "感谢反馈"
|
||||
});
|
||||
var notificationResponse = await client.PutAsJsonAsync(
|
||||
"/api/tenant-admin/notifications",
|
||||
new UpsertTenantAdminNotificationDto
|
||||
{
|
||||
UserId = studentId,
|
||||
NotificationType = "admin_message",
|
||||
Severity = "info",
|
||||
Title = "学习提醒",
|
||||
Message = "记得复习错题",
|
||||
DedupeKey = "daily-review"
|
||||
});
|
||||
var notificationsListResponse = await client.GetAsync($"/api/tenant-admin/notifications?userId={studentId}");
|
||||
var feedbackUpdateResponse = await client.PostAsJsonAsync(
|
||||
"/api/tenant-admin/feedbacks/status",
|
||||
new UpdateTenantAdminFeedbackDto
|
||||
{
|
||||
FeedbackId = feedbackId,
|
||||
Status = "resolved",
|
||||
Priority = "high",
|
||||
Resolution = "已安排补充解析",
|
||||
Note = "后台处理完成"
|
||||
});
|
||||
var feedbackListResponse = await client.GetAsync("/api/tenant-admin/feedbacks?status=resolved");
|
||||
var notificationsJson = await ReadJsonAsync(notificationsListResponse);
|
||||
var feedbackJson = await ReadJsonAsync(feedbackListResponse);
|
||||
|
||||
Assert.Equal(HttpStatusCode.OK, badgeResponse.StatusCode);
|
||||
Assert.Equal(HttpStatusCode.OK, grantResponse.StatusCode);
|
||||
Assert.Equal(HttpStatusCode.OK, notificationResponse.StatusCode);
|
||||
Assert.Equal(HttpStatusCode.OK, feedbackUpdateResponse.StatusCode);
|
||||
Assert.True(notificationsJson.RootElement.GetProperty("items").GetArrayLength() >= 2);
|
||||
Assert.Single(feedbackJson.RootElement.GetProperty("items").EnumerateArray());
|
||||
|
||||
using var scope = factory.Services.CreateScope();
|
||||
var dbContext = scope.ServiceProvider.GetRequiredService<TikuDbContext>();
|
||||
Assert.True(await dbContext.UserBadges.AnyAsync(item => item.TenantId == seed.TenantId && item.UserId == studentId && item.BadgeId == badgeId));
|
||||
Assert.True(await dbContext.UserNotifications.AnyAsync(item => item.TenantId == seed.TenantId && item.UserId == studentId && item.NotificationType == "badge_granted"));
|
||||
Assert.True(await dbContext.ReportStatusEvents.AnyAsync(item => item.TenantId == seed.TenantId && item.ReportId == feedbackId && item.ToStatus == ReportStatus.Resolved));
|
||||
}
|
||||
|
||||
private static async Task<(Guid TenantId, Guid UserId, string Phone)> SeedAdminAsync(
|
||||
ApiTestFactory factory,
|
||||
TenantRole role = TenantRole.TenantAdmin)
|
||||
|
||||
Reference in New Issue
Block a user