test(p1r): 固化 Account 真实 API 覆盖门禁
This commit is contained in:
parent
c4a8f4ea5d
commit
0dcaa9f581
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,11 @@
|
||||
# P1R API Coverage Report
|
||||
|
||||
- Generated at: `2026-05-25T18:47:44+00:00`
|
||||
- Generated at: `2026-05-25T01:55:37+00:00`
|
||||
- Total operations: `233`
|
||||
- Needs verification: `67`
|
||||
- Incomplete: `166`
|
||||
- Needs verification: `100`
|
||||
- Incomplete: `133`
|
||||
- Catch-all: `0`
|
||||
- Generic persistence: `164`
|
||||
- Generic persistence: `131`
|
||||
- SSE placeholder: `2`
|
||||
- Missing: `0`
|
||||
|
||||
@ -13,39 +13,39 @@
|
||||
|
||||
| Domain | Side | Method | Path | Operation | Implementation | Completion | Target Stage |
|
||||
|--------|------|--------|------|-----------|----------------|------------|--------------|
|
||||
| account | admin | POST | `/admin-api/muse/account/call-attribution-jobs` | `adminCreateCallAttributionJob` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/call-attribution-jobs/{jobId}` | `adminGetCallAttributionJob` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/integration-calls/by-correlation/{correlationId}` | `adminGetIntegrationCallByCorrelation` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/new-api-bindings` | `adminListNewApiBindings` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/purchase-records` | `adminListPurchaseRecords` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/usage-records` | `adminListUsageRecords` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/users` | `adminListAccountUsers` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/users/{userId}/balance-snapshots` | `adminGetBalanceSnapshots` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/users/{userId}/entitlements` | `adminGetUserEntitlements` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | admin | POST | `/admin-api/muse/account/users/{userId}/new-api-binding` | `adminCreateNewApiBinding` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/users/{userId}/quota-adjustments` | `adminListQuotaAdjustments` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | admin | POST | `/admin-api/muse/account/users/{userId}/quota-adjustments` | `adminCreateQuotaAdjustment` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | admin | POST | `/admin-api/muse/account/users/{userId}/quota-requests` | `adminCreateQuotaRequest` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/balance-snapshots` | `getAppBalanceSnapshots` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/downloads/{credentialId}` | `appDownloadExport` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/entitlements` | `getAppEntitlements` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | POST | `/app-api/muse/account/export-tasks` | `appCreateExportTask` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/export-tasks/{taskId}` | `appGetExportTask` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/integration-calls/by-correlation/{correlationId}` | `appGetIntegrationCallByCorrelation` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/licenses` | `appListLicenses` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/new-api-binding` | `getAppNewApiBinding` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | POST | `/app-api/muse/account/new-api-binding/recheck` | `appRecheckNewApiBinding` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/publish-records` | `appListPublishRecords` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/purchases` | `appListPurchases` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | POST | `/app-api/muse/account/quota-requests` | `appCreateQuotaRequest` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/quota-requests/{requestId}` | `appGetQuotaRequest` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/security-events` | `appListSecurityEvents` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/security-events/{eventId}` | `appGetSecurityEvent` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | POST | `/app-api/muse/account/security-events/{eventId}/acknowledge` | `appAcknowledgeSecurityEvent` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/usage` | `getAppUsage` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/me` | `getCurrentUser` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/profile` | `getProfile` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | app | PATCH | `/app-api/muse/profile` | `updateProfile` | generic_persistence | incomplete | P1R-3 Account Real API |
|
||||
| account | admin | POST | `/admin-api/muse/account/call-attribution-jobs` | `adminCreateCallAttributionJob` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/call-attribution-jobs/{jobId}` | `adminGetCallAttributionJob` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/integration-calls/by-correlation/{correlationId}` | `adminGetIntegrationCallByCorrelation` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/new-api-bindings` | `adminListNewApiBindings` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/purchase-records` | `adminListPurchaseRecords` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/usage-records` | `adminListUsageRecords` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/users` | `adminListAccountUsers` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/users/{userId}/balance-snapshots` | `adminGetBalanceSnapshots` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/users/{userId}/entitlements` | `adminGetUserEntitlements` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | admin | POST | `/admin-api/muse/account/users/{userId}/new-api-binding` | `adminCreateNewApiBinding` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | admin | GET | `/admin-api/muse/account/users/{userId}/quota-adjustments` | `adminListQuotaAdjustments` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | admin | POST | `/admin-api/muse/account/users/{userId}/quota-adjustments` | `adminCreateQuotaAdjustment` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | admin | POST | `/admin-api/muse/account/users/{userId}/quota-requests` | `adminCreateQuotaRequest` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/balance-snapshots` | `getAppBalanceSnapshots` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/downloads/{credentialId}` | `appDownloadExport` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/entitlements` | `getAppEntitlements` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | POST | `/app-api/muse/account/export-tasks` | `appCreateExportTask` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/export-tasks/{taskId}` | `appGetExportTask` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/integration-calls/by-correlation/{correlationId}` | `appGetIntegrationCallByCorrelation` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/licenses` | `appListLicenses` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/new-api-binding` | `getAppNewApiBinding` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | POST | `/app-api/muse/account/new-api-binding/recheck` | `appRecheckNewApiBinding` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/publish-records` | `appListPublishRecords` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/purchases` | `appListPurchases` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | POST | `/app-api/muse/account/quota-requests` | `appCreateQuotaRequest` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/quota-requests/{requestId}` | `appGetQuotaRequest` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/security-events` | `appListSecurityEvents` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/security-events/{eventId}` | `appGetSecurityEvent` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | POST | `/app-api/muse/account/security-events/{eventId}/acknowledge` | `appAcknowledgeSecurityEvent` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/account/usage` | `getAppUsage` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/me` | `getCurrentUser` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | GET | `/app-api/muse/profile` | `getProfile` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| account | app | PATCH | `/app-api/muse/profile` | `updateProfile` | dedicated | needs_verification | P1R-3 Account Real API |
|
||||
| ai | admin | GET | `/admin-api/muse/ai/agents` | `adminListAgents` | generic_persistence | incomplete | P1R-4 AI Real API |
|
||||
| ai | admin | POST | `/admin-api/muse/ai/agents` | `adminCreateAgent` | generic_persistence | incomplete | P1R-4 AI Real API |
|
||||
| ai | admin | POST | `/admin-api/muse/ai/agents/{agentId}/versions` | `adminCreateAgentVersion` | generic_persistence | incomplete | P1R-4 AI Real API |
|
||||
@ -249,39 +249,6 @@
|
||||
|
||||
## Incomplete Or Blocked
|
||||
|
||||
- `adminCreateCallAttributionJob` `POST /admin-api/muse/account/call-attribution-jobs`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `adminGetCallAttributionJob` `GET /admin-api/muse/account/call-attribution-jobs/{jobId}`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `adminGetIntegrationCallByCorrelation` `GET /admin-api/muse/account/integration-calls/by-correlation/{correlationId}`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `adminListNewApiBindings` `GET /admin-api/muse/account/new-api-bindings`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `adminListPurchaseRecords` `GET /admin-api/muse/account/purchase-records`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `adminListUsageRecords` `GET /admin-api/muse/account/usage-records`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `adminListAccountUsers` `GET /admin-api/muse/account/users`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `adminGetBalanceSnapshots` `GET /admin-api/muse/account/users/{userId}/balance-snapshots`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `adminGetUserEntitlements` `GET /admin-api/muse/account/users/{userId}/entitlements`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `adminCreateNewApiBinding` `POST /admin-api/muse/account/users/{userId}/new-api-binding`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `adminListQuotaAdjustments` `GET /admin-api/muse/account/users/{userId}/quota-adjustments`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `adminCreateQuotaAdjustment` `POST /admin-api/muse/account/users/{userId}/quota-adjustments`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `adminCreateQuotaRequest` `POST /admin-api/muse/account/users/{userId}/quota-requests`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `getAppBalanceSnapshots` `GET /app-api/muse/account/balance-snapshots`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `appDownloadExport` `GET /app-api/muse/account/downloads/{credentialId}`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `getAppEntitlements` `GET /app-api/muse/account/entitlements`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `appCreateExportTask` `POST /app-api/muse/account/export-tasks`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `appGetExportTask` `GET /app-api/muse/account/export-tasks/{taskId}`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `appGetIntegrationCallByCorrelation` `GET /app-api/muse/account/integration-calls/by-correlation/{correlationId}`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `appListLicenses` `GET /app-api/muse/account/licenses`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `getAppNewApiBinding` `GET /app-api/muse/account/new-api-binding`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `appRecheckNewApiBinding` `POST /app-api/muse/account/new-api-binding/recheck`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `appListPublishRecords` `GET /app-api/muse/account/publish-records`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `appListPurchases` `GET /app-api/muse/account/purchases`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `appCreateQuotaRequest` `POST /app-api/muse/account/quota-requests`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `appGetQuotaRequest` `GET /app-api/muse/account/quota-requests/{requestId}`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `appListSecurityEvents` `GET /app-api/muse/account/security-events`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `appGetSecurityEvent` `GET /app-api/muse/account/security-events/{eventId}`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `appAcknowledgeSecurityEvent` `POST /app-api/muse/account/security-events/{eventId}/acknowledge`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `getAppUsage` `GET /app-api/muse/account/usage`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `getCurrentUser` `GET /app-api/muse/me`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `getProfile` `GET /app-api/muse/profile`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `updateProfile` `PATCH /app-api/muse/profile`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `adminListAgents` `GET /admin-api/muse/ai/agents`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `adminCreateAgent` `POST /admin-api/muse/ai/agents`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
- `adminCreateAgentVersion` `POST /admin-api/muse/ai/agents/{agentId}/versions`: generic_persistence - Handled by MuseContractPersistenceService generic persistence, which is not P1R completion.
|
||||
|
||||
@ -0,0 +1,193 @@
|
||||
package cn.iocoder.muse.server.framework.api;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
|
||||
/**
|
||||
* P1R-3 Account 真实 API 阶段覆盖报告门禁。
|
||||
*
|
||||
* <p>这个 gate 只证明 P1R-3 coverage 已收口到 dedicated / needs_verification,
|
||||
* 不证明 Account 业务 runtime 已经 completed。后续如果要推进 completed,必须先补充真实运行态验收证据。</p>
|
||||
*/
|
||||
class P1rAccountRealApiGateTest {
|
||||
|
||||
/** P1R-3 Account 合同固定 operation 数量。 */
|
||||
private static final int EXPECTED_ACCOUNT_OPERATION_COUNT = 33;
|
||||
|
||||
/** Account 阶段不能继续使用的非真实实现状态。 */
|
||||
private static final Set<String> NON_REAL_IMPLEMENTATION_STATUSES = Set.of(
|
||||
"generic_persistence",
|
||||
"catch_all",
|
||||
"sse_placeholder",
|
||||
"missing"
|
||||
);
|
||||
|
||||
/** P1R-3 阶段不允许使用的完成状态。 */
|
||||
private static final Set<String> DISALLOWED_COMPLETION_STATUSES = Set.of(
|
||||
"blocked",
|
||||
"completed"
|
||||
);
|
||||
|
||||
/** P1R-3 计划第 1 节冻结的 Account operation、方法和路径清单。 */
|
||||
private static final Map<String, String> P1R3_ACCOUNT_OPERATION_SIGNATURES = Map.ofEntries(
|
||||
entry("adminListAccountUsers", "GET /admin-api/muse/account/users"),
|
||||
entry("adminGetUserEntitlements", "GET /admin-api/muse/account/users/{userId}/entitlements"),
|
||||
entry("adminCreateQuotaAdjustment", "POST /admin-api/muse/account/users/{userId}/quota-adjustments"),
|
||||
entry("adminListQuotaAdjustments", "GET /admin-api/muse/account/users/{userId}/quota-adjustments"),
|
||||
entry("adminListNewApiBindings", "GET /admin-api/muse/account/new-api-bindings"),
|
||||
entry("adminCreateNewApiBinding", "POST /admin-api/muse/account/users/{userId}/new-api-binding"),
|
||||
entry("adminCreateQuotaRequest", "POST /admin-api/muse/account/users/{userId}/quota-requests"),
|
||||
entry("adminGetBalanceSnapshots", "GET /admin-api/muse/account/users/{userId}/balance-snapshots"),
|
||||
entry("adminCreateCallAttributionJob", "POST /admin-api/muse/account/call-attribution-jobs"),
|
||||
entry("adminGetCallAttributionJob", "GET /admin-api/muse/account/call-attribution-jobs/{jobId}"),
|
||||
entry("adminGetIntegrationCallByCorrelation", "GET /admin-api/muse/account/integration-calls/by-correlation/{correlationId}"),
|
||||
entry("adminListUsageRecords", "GET /admin-api/muse/account/usage-records"),
|
||||
entry("adminListPurchaseRecords", "GET /admin-api/muse/account/purchase-records"),
|
||||
entry("getCurrentUser", "GET /app-api/muse/me"),
|
||||
entry("getProfile", "GET /app-api/muse/profile"),
|
||||
entry("updateProfile", "PATCH /app-api/muse/profile"),
|
||||
entry("getAppEntitlements", "GET /app-api/muse/account/entitlements"),
|
||||
entry("getAppUsage", "GET /app-api/muse/account/usage"),
|
||||
entry("getAppNewApiBinding", "GET /app-api/muse/account/new-api-binding"),
|
||||
entry("appRecheckNewApiBinding", "POST /app-api/muse/account/new-api-binding/recheck"),
|
||||
entry("getAppBalanceSnapshots", "GET /app-api/muse/account/balance-snapshots"),
|
||||
entry("appCreateQuotaRequest", "POST /app-api/muse/account/quota-requests"),
|
||||
entry("appGetQuotaRequest", "GET /app-api/muse/account/quota-requests/{requestId}"),
|
||||
entry("appGetIntegrationCallByCorrelation", "GET /app-api/muse/account/integration-calls/by-correlation/{correlationId}"),
|
||||
entry("appListPurchases", "GET /app-api/muse/account/purchases"),
|
||||
entry("appListLicenses", "GET /app-api/muse/account/licenses"),
|
||||
entry("appListPublishRecords", "GET /app-api/muse/account/publish-records"),
|
||||
entry("appListSecurityEvents", "GET /app-api/muse/account/security-events"),
|
||||
entry("appGetSecurityEvent", "GET /app-api/muse/account/security-events/{eventId}"),
|
||||
entry("appAcknowledgeSecurityEvent", "POST /app-api/muse/account/security-events/{eventId}/acknowledge"),
|
||||
entry("appCreateExportTask", "POST /app-api/muse/account/export-tasks"),
|
||||
entry("appGetExportTask", "GET /app-api/muse/account/export-tasks/{taskId}"),
|
||||
entry("appDownloadExport", "GET /app-api/muse/account/downloads/{credentialId}")
|
||||
);
|
||||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
/**
|
||||
* 验证 Account operation 数量、operationId、方法和路径与 P1R-3 计划第 1 节一致。
|
||||
*
|
||||
* @throws IOException 读取覆盖报告失败时抛出
|
||||
*/
|
||||
@Test
|
||||
void should_keep_account_operation_inventory_complete() throws IOException {
|
||||
JsonNode accountOperations = readAccountOperations();
|
||||
Map<String, String> actualSignatures = toOperationSignatures(accountOperations);
|
||||
|
||||
assertEquals(EXPECTED_ACCOUNT_OPERATION_COUNT, accountOperations.size(),
|
||||
"Account operation 数量必须保持 33");
|
||||
assertEquals(EXPECTED_ACCOUNT_OPERATION_COUNT, actualSignatures.size(),
|
||||
"Account operationId 不能重复");
|
||||
assertEquals(P1R3_ACCOUNT_OPERATION_SIGNATURES, actualSignatures,
|
||||
"Account operation 清单必须与 P1R-3 计划第 1 节一致");
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证 Account operation 不再落回通用持久化、catch-all、SSE 占位或缺入口。
|
||||
*
|
||||
* @throws IOException 读取覆盖报告失败时抛出
|
||||
*/
|
||||
@Test
|
||||
void should_not_allow_account_operations_to_use_non_real_entrypoints() throws IOException {
|
||||
JsonNode accountOperations = readAccountOperations();
|
||||
|
||||
for (JsonNode operation : accountOperations) {
|
||||
String operationId = operation.path("operationId").asText("<missing-operationId>");
|
||||
String implementationStatus = operation.path("implementationStatus").asText();
|
||||
assertFalse(NON_REAL_IMPLEMENTATION_STATUSES.contains(implementationStatus),
|
||||
operationId + " 不能使用非真实 Account 实现入口: " + implementationStatus);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证 Account operation 不能在 P1R-3 阶段提前宣称 completed 或退回 blocked。
|
||||
*
|
||||
* @throws IOException 读取覆盖报告失败时抛出
|
||||
*/
|
||||
@Test
|
||||
void should_not_mark_account_operations_as_blocked_or_completed() throws IOException {
|
||||
JsonNode accountOperations = readAccountOperations();
|
||||
|
||||
for (JsonNode operation : accountOperations) {
|
||||
String operationId = operation.path("operationId").asText("<missing-operationId>");
|
||||
String completionStatus = operation.path("completionStatus").asText();
|
||||
assertFalse(DISALLOWED_COMPLETION_STATUSES.contains(completionStatus),
|
||||
operationId + " 在 P1R-3 不能标记为 blocked 或 completed,当前为: " + completionStatus);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证当前 P1R-3 收口口径:Account 全部进入 dedicated,但仍保持 needs_verification。
|
||||
*
|
||||
* @throws IOException 读取覆盖报告失败时抛出
|
||||
*/
|
||||
@Test
|
||||
void should_keep_current_account_operations_dedicated_and_needs_verification() throws IOException {
|
||||
JsonNode accountOperations = readAccountOperations();
|
||||
|
||||
for (JsonNode operation : accountOperations) {
|
||||
String operationId = operation.path("operationId").asText("<missing-operationId>");
|
||||
assertEquals("dedicated", operation.path("implementationStatus").asText(),
|
||||
operationId + " 当前 P1R-3 目标必须是 dedicated");
|
||||
assertEquals("needs_verification", operation.path("completionStatus").asText(),
|
||||
operationId + " 当前 P1R-3 目标必须是 needs_verification,不能提前宣称 completed");
|
||||
}
|
||||
}
|
||||
|
||||
private JsonNode readAccountOperations() throws IOException {
|
||||
JsonNode operations = objectMapper.readTree(findReportPath().toFile()).path("operations");
|
||||
return filterAccountOperations(operations);
|
||||
}
|
||||
|
||||
private JsonNode filterAccountOperations(JsonNode operations) {
|
||||
ArrayNode accountOperations = objectMapper.createArrayNode();
|
||||
for (JsonNode operation : operations) {
|
||||
if ("P1R-3 Account Real API".equals(operation.path("targetStage").asText())
|
||||
|| "account".equals(operation.path("domain").asText())) {
|
||||
accountOperations.add(operation);
|
||||
}
|
||||
}
|
||||
return accountOperations;
|
||||
}
|
||||
|
||||
private static Map<String, String> toOperationSignatures(JsonNode operations) {
|
||||
Map<String, String> operationSignatures = new LinkedHashMap<>();
|
||||
for (JsonNode operation : operations) {
|
||||
String operationId = operation.path("operationId").asText("<missing-operationId>");
|
||||
String signature = operation.path("method").asText() + " " + operation.path("path").asText();
|
||||
operationSignatures.put(operationId, signature);
|
||||
}
|
||||
return operationSignatures;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从当前 Maven 执行目录逐级向上查找仓库根目录,避免 surefire 在不同模块目录执行时路径失效。
|
||||
*/
|
||||
private static Path findReportPath() {
|
||||
Path current = Path.of("").toAbsolutePath();
|
||||
for (Path candidate = current; candidate != null; candidate = candidate.getParent()) {
|
||||
Path reportPath = candidate.resolve("docs/superpowers/reports/p1r-api-coverage.json");
|
||||
if (Files.exists(reportPath)) {
|
||||
return reportPath;
|
||||
}
|
||||
}
|
||||
return current.resolve("docs/superpowers/reports/p1r-api-coverage.json");
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user