diff --git a/ordinis-app/src/test/java/cloud/nstart/terravault/ordinis/app/e2e/ApprovalWorkflowE2ETest.java b/ordinis-app/src/test/java/cloud/nstart/terravault/ordinis/app/e2e/ApprovalWorkflowE2ETest.java index bd725d1..36fce14 100644 --- a/ordinis-app/src/test/java/cloud/nstart/terravault/ordinis/app/e2e/ApprovalWorkflowE2ETest.java +++ b/ordinis-app/src/test/java/cloud/nstart/terravault/ordinis/app/e2e/ApprovalWorkflowE2ETest.java @@ -69,11 +69,23 @@ class ApprovalWorkflowE2ETest { // === Helpers === - /** Internal-scope JWT для конкретного юзера. */ + /** Internal-scope JWT для maker'а (без workflow ролей). */ private static String tokenFor(String subject) { return JwtTestSupport.signJwt(List.of("ordinis:client:internal"), subject); } + /** + * JWT для reviewer'а — internal scope + Phase 1d {@code ordinis:record:reviewer} + * role. Без этой роли backend гейт ({@code WorkflowRoles.RECORD_REVIEWER}) + * вернёт {@code 403 forbidden_role} до того как тест проверит другие + * invariants (self-approve, missing comment etc). + */ + private static String reviewerTokenFor(String subject) { + return JwtTestSupport.signJwt( + List.of("ordinis:client:internal", "ordinis:record:reviewer"), + subject); + } + private static final String SCHEMA_JSON = """ { "$schema": "http://json-schema.org/draft-07/schema#", @@ -155,7 +167,7 @@ class ApprovalWorkflowE2ETest { @Test void happyFlow_submitApprove_recordLiveAndOutboxEvent() throws Exception { String makerToken = tokenFor("alice-maker"); - String reviewerToken = tokenFor("bob-reviewer"); + String reviewerToken = reviewerTokenFor("bob-reviewer"); String dictName = createDictThenEnableApproval(makerToken, randDictName("appr_h")); String bk = randBk(); @@ -204,7 +216,7 @@ class ApprovalWorkflowE2ETest { @Test void rejectFlow_keepsDraft_noLiveRecord() throws Exception { String makerToken = tokenFor("carol-maker"); - String reviewerToken = tokenFor("dave-reviewer"); + String reviewerToken = reviewerTokenFor("dave-reviewer"); String dictName = createDictThenEnableApproval(makerToken, randDictName("appr_rej")); String bk = randBk(); @@ -235,7 +247,11 @@ class ApprovalWorkflowE2ETest { @Test void selfApproveBlocked_409() throws Exception { - String token = tokenFor("eve-solo"); + // eve-solo даёт BOTH scope И reviewer role — иначе backend ответит + // 403 forbidden_role до того как мы достигнем self-approve check. + // Тест specifically проверяет 409 self_approve_forbidden (maker == reviewer + // даже при наличии role). + String token = reviewerTokenFor("eve-solo"); String dictName = createDictThenEnableApproval(token, randDictName("appr_self")); String bk = randBk(); @@ -336,7 +352,7 @@ class ApprovalWorkflowE2ETest { @Test void withdrawByMaker_keepsDraftStatus() throws Exception { String makerToken = tokenFor("ivan-maker"); - String reviewerToken = tokenFor("julia-reviewer"); + String reviewerToken = reviewerTokenFor("julia-reviewer"); String dictName = createDictThenEnableApproval(makerToken, randDictName("appr_wd")); String bk = randBk(); @@ -364,7 +380,7 @@ class ApprovalWorkflowE2ETest { @Test void rejectWithoutComment_400() throws Exception { String makerToken = tokenFor("kate-maker"); - String reviewerToken = tokenFor("leo-reviewer"); + String reviewerToken = reviewerTokenFor("leo-reviewer"); String dictName = createDictThenEnableApproval(makerToken, randDictName("appr_rc")); String bk = randBk();