Introduces accounts (ASP.NET Identity + cookie auth), four global roles (Admin/Writer/Editor/Reviewer), per-novel ownership and grants via ProjectMember, and a service-API-key principal for the MCP server and background import jobs. Enforcement lives in the application services (not endpoint filters) so the embedded agent and MCP tools, which call the same services directly, can't bypass it. Web client gets a login page, session-aware routing, and a People section for managing per-novel access. Also includes prior in-flight changes from this branch (CLAUDE.md compliance pass, dev-deploy docker-compose setup) that were uncommitted when this feature work started.
90 lines
4.3 KiB
C#
90 lines
4.3 KiB
C#
using Novelly.Api.Beats;
|
|
using Novelly.Api.Chapters;
|
|
using Novelly.Api.Characters;
|
|
using Novelly.Api.Genres;
|
|
using Novelly.Api.Projects;
|
|
using Novelly.Api.Questions;
|
|
using Novelly.Api.Tags;
|
|
using Novelly.Api.Users;
|
|
|
|
namespace Novelly.Api.Tests;
|
|
|
|
public abstract class ServiceTestFixture
|
|
{
|
|
protected TestDatabase Db { get; private set; } = null!;
|
|
protected TestUserContext UserContext { get; private set; } = null!;
|
|
protected ProjectAccessService Access { get; private set; } = null!;
|
|
protected TagService Tags { get; private set; } = null!;
|
|
protected ProjectService Projects { get; private set; } = null!;
|
|
protected CharacterService Characters { get; private set; } = null!;
|
|
protected ChapterService Chapters { get; private set; } = null!;
|
|
protected BeatService Beats { get; private set; } = null!;
|
|
protected CharacterArcService Arcs { get; private set; } = null!;
|
|
protected OpenQuestionService Questions { get; private set; } = null!;
|
|
protected GenreService Genres { get; private set; } = null!;
|
|
|
|
protected CapturingLogger<ProjectService> ProjectLogs { get; private set; } = null!;
|
|
protected CapturingLogger<CharacterService> CharacterLogs { get; private set; } = null!;
|
|
protected CapturingLogger<ChapterService> ChapterLogs { get; private set; } = null!;
|
|
protected CapturingLogger<BeatService> BeatLogs { get; private set; } = null!;
|
|
protected CapturingLogger<TagService> TagLogs { get; private set; } = null!;
|
|
protected CapturingLogger<CharacterArcService> ArcLogs { get; private set; } = null!;
|
|
protected CapturingLogger<OpenQuestionService> QuestionLogs { get; private set; } = null!;
|
|
protected CapturingLogger<GenreService> GenreLogs { get; private set; } = null!;
|
|
|
|
[SetUp]
|
|
public void SetUpFixture()
|
|
{
|
|
Db = new TestDatabase();
|
|
UserContext = new TestUserContext();
|
|
Access = new ProjectAccessService(Db.Context, UserContext, new CapturingLogger<ProjectAccessService>());
|
|
|
|
Db.Context.Users.Add(new NovellyUser
|
|
{
|
|
Id = UserContext.UserId!.Value,
|
|
UserName = "admin@novelly.test",
|
|
Email = "admin@novelly.test",
|
|
DisplayName = "Test Admin",
|
|
GlobalRole = GlobalRole.Admin
|
|
});
|
|
Db.Context.SaveChanges();
|
|
|
|
TagLogs = new CapturingLogger<TagService>();
|
|
ProjectLogs = new CapturingLogger<ProjectService>();
|
|
CharacterLogs = new CapturingLogger<CharacterService>();
|
|
ChapterLogs = new CapturingLogger<ChapterService>();
|
|
BeatLogs = new CapturingLogger<BeatService>();
|
|
ArcLogs = new CapturingLogger<CharacterArcService>();
|
|
QuestionLogs = new CapturingLogger<OpenQuestionService>();
|
|
GenreLogs = new CapturingLogger<GenreService>();
|
|
|
|
Tags = new TagService(Db.Context, Access, TagLogs, new CreateTagRequestValidator(), new UpdateTagRequestValidator());
|
|
Projects = new ProjectService(
|
|
Db.Context, Access, UserContext, ProjectLogs, new CreateProjectRequestValidator(), new UpdateProjectRequestValidator());
|
|
Characters = new CharacterService(
|
|
Db.Context, Access, Tags, CharacterLogs,
|
|
new CreateCharacterRequestValidator(), new UpdateCharacterRequestValidator(), new CreateRelationshipRequestValidator());
|
|
Chapters = new ChapterService(Db.Context, Access, Tags, ChapterLogs, new CreateChapterRequestValidator(), new UpdateChapterRequestValidator());
|
|
Beats = new BeatService(
|
|
Db.Context, Access, Tags, BeatLogs,
|
|
new CreateBeatRequestValidator(), new UpdateBeatRequestValidator(), new ReorderBeatsRequestValidator(),
|
|
new AssignCharacterToBeatsRequestValidator());
|
|
Arcs = new CharacterArcService(
|
|
Db.Context, Access, ArcLogs,
|
|
new CreateArcStageRequestValidator(), new UpdateArcStageRequestValidator(), new ReorderArcStagesRequestValidator());
|
|
Questions = new OpenQuestionService(
|
|
Db.Context, Access, QuestionLogs,
|
|
new CreateOpenQuestionRequestValidator(), new UpdateOpenQuestionRequestValidator(), new ResolveOpenQuestionRequestValidator());
|
|
Genres = new GenreService(Db.Context, GenreLogs);
|
|
|
|
OnSetUp();
|
|
}
|
|
|
|
protected virtual void OnSetUp()
|
|
{
|
|
}
|
|
|
|
[TearDown]
|
|
public void TearDownFixture() => Db.Dispose();
|
|
}
|