test(tooling): add vitest baseline policy and order tests

This commit is contained in:
zetaloop
2026-02-22 14:51:21 +08:00
parent 6517018a9c
commit f8c4c87c61
5 changed files with 976 additions and 4 deletions
+123
View File
@@ -0,0 +1,123 @@
import { describe, expect, it } from "vitest"
import { evaluateOrderTransition } from "@/lib/domain/order-machine"
import type { Actor } from "@/lib/policy/actor"
import type { UserRole } from "@/lib/types"
function actor(role: UserRole, userId = "u1"): Actor {
return { role, userId }
}
describe("evaluateOrderTransition", () => {
it("allows valid transition for pay", () => {
const result = evaluateOrderTransition({
actor: actor("consumer"),
order: { status: "pending_payment" },
action: "PAY",
})
expect(result.decision.ok).toBe(true)
expect(result.nextStatus).toBe("pending_accept")
expect(result.sideEffects).toContainEqual({
type: "SCHEDULE_TIMEOUT",
status: "pending_accept",
})
})
it("denies invalid status transition", () => {
const result = evaluateOrderTransition({
actor: actor("consumer"),
order: { status: "completed" },
action: "PAY",
})
expect(result.decision).toMatchObject({
ok: false,
reasonCode: "INVALID_STATUS",
})
expect(result.nextStatus).toBeUndefined()
})
it("denies role forbidden actions", () => {
const result = evaluateOrderTransition({
actor: actor("consumer"),
order: { status: "pending_accept" },
action: "ACCEPT",
})
expect(result.decision).toMatchObject({
ok: false,
reasonCode: "ROLE_FORBIDDEN",
})
})
it("allows accept for player", () => {
const result = evaluateOrderTransition({
actor: actor("player"),
order: { status: "pending_accept" },
action: "ACCEPT",
})
expect(result.decision.ok).toBe(true)
expect(result.nextStatus).toBe("in_progress")
})
it("allows close confirmation to pending_review", () => {
const result = evaluateOrderTransition({
actor: actor("consumer"),
order: { status: "pending_close" },
action: "CONFIRM_CLOSE",
})
expect(result.decision.ok).toBe(true)
expect(result.nextStatus).toBe("pending_review")
expect(result.sideEffects).toContainEqual({
type: "SCHEDULE_TIMEOUT",
status: "pending_review",
})
})
it("allows auto timeout actions without actor", () => {
const result = evaluateOrderTransition({
order: { status: "pending_close" },
action: "AUTO_TIMEOUT_PENDING_CLOSE",
})
expect(result.decision.ok).toBe(true)
expect(result.nextStatus).toBe("pending_review")
})
it("adds payout side effect when entering completed", () => {
const result = evaluateOrderTransition({
order: { status: "pending_review" },
action: "AUTO_TIMEOUT_PENDING_REVIEW",
})
expect(result.decision.ok).toBe(true)
expect(result.nextStatus).toBe("completed")
expect(result.sideEffects).toContainEqual({ type: "PAYOUT_INCOME" })
})
it("supports resolving dispute by owner", () => {
const result = evaluateOrderTransition({
actor: actor("owner"),
order: { status: "disputed" },
action: "RESOLVE_DISPUTE",
})
expect(result.decision.ok).toBe(true)
expect(result.nextStatus).toBe("pending_review")
})
it("rejects dispute resolution by non-owner", () => {
const result = evaluateOrderTransition({
actor: actor("player"),
order: { status: "disputed" },
action: "RESOLVE_DISPUTE",
})
expect(result.decision).toMatchObject({
ok: false,
reasonCode: "ROLE_FORBIDDEN",
})
})
})
+31
View File
@@ -0,0 +1,31 @@
import { describe, expect, it } from "vitest"
import { allow, deny, requireAuth } from "@/lib/policy/assert"
describe("policy decision helpers", () => {
it("returns ok for allow", () => {
expect(allow()).toEqual({ ok: true })
})
it("returns reason code for deny", () => {
expect(deny("ROLE_FORBIDDEN", "forbidden")).toEqual({
ok: false,
reasonCode: "ROLE_FORBIDDEN",
message: "forbidden",
})
})
it("requires auth actor", () => {
expect(requireAuth(undefined)).toEqual({
ok: false,
reasonCode: "AUTH_REQUIRED",
message: "请先登录",
})
expect(
requireAuth({
userId: "u1",
role: "consumer",
}),
).toEqual({ ok: true })
})
})