feat: expand EasyCode software factory workflows
This commit is contained in:
248
RuoYi-Vue/ruoyi-ui/test/pluginRegistryView.test.mjs
Normal file
248
RuoYi-Vue/ruoyi-ui/test/pluginRegistryView.test.mjs
Normal file
@@ -0,0 +1,248 @@
|
||||
import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { dirname, resolve } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
||||
const read = path => readFileSync(resolve(root, path), 'utf8')
|
||||
|
||||
test('plugin registry api exposes status and immutable publication operations', () => {
|
||||
const api = read('src/api/generator/plugin.js')
|
||||
for (const name of [
|
||||
'getPluginRegistryStatus',
|
||||
'probePluginSqlTarget',
|
||||
'getPluginDeliveryVerification',
|
||||
'createPluginDeliveryRehearsal',
|
||||
'listPluginDeliveryRehearsals',
|
||||
'getPluginDeliveryRehearsal',
|
||||
'startPluginDeliveryRehearsal',
|
||||
'listPluginDeliveryRehearsalAttempts',
|
||||
'getPluginDeliveryRehearsalAttempt',
|
||||
'abortPluginDeliveryRehearsalAttempt',
|
||||
'reconcilePluginDeliveryRehearsalAttempt',
|
||||
'comparePluginDeliveryRehearsalAttempts',
|
||||
'getPluginDeliveryReleaseGate',
|
||||
'getPluginRegistryReadiness',
|
||||
'bootstrapPluginRegistry',
|
||||
'listPlugins',
|
||||
'getPlugin',
|
||||
'addPlugin',
|
||||
'updatePlugin',
|
||||
'createPluginVersion',
|
||||
'publishPluginVersion',
|
||||
'rollbackPluginVersion',
|
||||
'preflightPluginTransition',
|
||||
'executePluginTransition',
|
||||
'retryPluginTransition',
|
||||
'compensatePluginTransition',
|
||||
'requestPluginTransitionApproval',
|
||||
'listPluginTransitionApprovals',
|
||||
'approvePluginTransitionApproval',
|
||||
'revokePluginTransitionApproval',
|
||||
'getPluginTransitionExecutions',
|
||||
'reconcilePluginTransitionExecution'
|
||||
]) {
|
||||
assert.equal(api.includes(`export function ${name}`), true, `${name} should be exported`)
|
||||
}
|
||||
assert.match(api, /plugin\/registry-status/)
|
||||
assert.match(api, /plugin\/sql-target\/probe/)
|
||||
assert.match(api, /plugin\/delivery-verification/)
|
||||
assert.match(api, /plugin\/delivery-rehearsals/)
|
||||
assert.match(api, /delivery-rehearsals\/\$\{rehearsalId\}/)
|
||||
assert.match(api, /delivery-rehearsals\/\$\{rehearsalId\}\/attempts/)
|
||||
assert.match(api, /attempts\/\$\{attemptId\}\/abort/)
|
||||
assert.match(api, /attempts\/\$\{attemptId\}\/reconcile/)
|
||||
assert.match(api, /attempt-comparison/)
|
||||
assert.match(api, /release-gate/)
|
||||
assert.match(api, /baselineAttemptId, candidateAttemptId/)
|
||||
assert.match(api, /sql-target\/probe', method: 'post'/)
|
||||
assert.match(api, /plugin\/readiness/)
|
||||
assert.match(api, /plugin\/bootstrap/)
|
||||
assert.match(api, /versions\/\$\{pluginVersionId\}\/publish/)
|
||||
assert.match(api, /versions\/\$\{pluginVersionId\}\/rollback/)
|
||||
assert.match(api, /transitions\/\$\{transitionId\}\/preflight/)
|
||||
assert.match(api, /params: \{ executionMode \}/)
|
||||
assert.match(api, /transitions\/\$\{transitionId\}\/execute/)
|
||||
assert.match(api, /transitions\/\$\{transitionId\}\/retry/)
|
||||
assert.match(api, /transitions\/\$\{transitionId\}\/compensate/)
|
||||
assert.match(api, /executePluginTransition\(pluginId, transitionId, data\)/)
|
||||
assert.match(api, /retryPluginTransition\(pluginId, transitionId, data\)/)
|
||||
assert.match(api, /compensatePluginTransition\(pluginId, transitionId, data\)/)
|
||||
assert.match(api, /transitions\/\$\{transitionId\}\/approvals`/)
|
||||
assert.match(api, /approvals\/\$\{approvalId\}\/approve/)
|
||||
assert.match(api, /approvals\/\$\{approvalId\}\/revoke/)
|
||||
assert.match(api, /executions\/\$\{executionId\}\/reconcile/)
|
||||
})
|
||||
|
||||
test('plugin registry view manages installed definitions and release lifecycle', () => {
|
||||
const view = read('src/views/generator/plugin/index.vue')
|
||||
assert.match(view, /name: 'PluginRegistry'/)
|
||||
assert.match(view, /registryStatus\.databaseEnabled/)
|
||||
assert.match(view, /registryReadiness\.readyReleaseCount/)
|
||||
assert.match(view, /bootstrapPluginRegistry/)
|
||||
assert.match(view, /readinessStateLabel/)
|
||||
assert.match(view, /contributionReversible/)
|
||||
assert.match(view, /IRREVERSIBLE_CONTRIBUTION/)
|
||||
assert.match(view, /installedManifests/)
|
||||
assert.match(view, /createPluginVersion/)
|
||||
assert.match(view, /publishPluginVersion/)
|
||||
assert.match(view, /rollbackPluginVersion/)
|
||||
assert.match(view, /detail\.transitions/)
|
||||
assert.match(view, /transitionOperationLabel/)
|
||||
assert.match(view, /inspectTransitionPlan/)
|
||||
assert.match(view, /transitionFingerprint/)
|
||||
assert.match(view, /latestExecutionStatus/)
|
||||
assert.match(view, /runTransition/)
|
||||
assert.match(view, /openExecutionHistory/)
|
||||
assert.match(view, /executionDialogOpen/)
|
||||
assert.match(view, /reconcilePluginTransitionExecution/)
|
||||
assert.match(view, /reconcileExecution/)
|
||||
assert.match(view, /outbox\.status/)
|
||||
assert.match(view, /deliveryCount/)
|
||||
assert.match(view, /leaseUntil/)
|
||||
assert.match(view, /QUEUED/)
|
||||
assert.match(view, /PROCESSING/)
|
||||
assert.match(view, /DELIVERED/)
|
||||
assert.match(view, /已入队/)
|
||||
assert.match(view, /dry-run:v1/)
|
||||
assert.match(view, /sql-jdbc:v1/)
|
||||
assert.match(view, /permission-jdbc:v1/)
|
||||
assert.match(view, /menu-jdbc:v1/)
|
||||
assert.match(view, /executorCode/)
|
||||
assert.match(view, /routed:v1/)
|
||||
assert.match(view, /executionEnvironmentCode/)
|
||||
assert.match(view, /routingFingerprint/)
|
||||
assert.match(view, /approvalRequiredForNonDryRun/)
|
||||
assert.match(view, /approvalSeparationEnabled/)
|
||||
assert.match(view, /approvalRequestTtlMinutes/)
|
||||
assert.match(view, /approvalValidityMinutes/)
|
||||
assert.match(view, /realExecutorConfigured/)
|
||||
assert.match(view, /executorRoutes/)
|
||||
assert.match(view, /expectedTransitionFingerprint/)
|
||||
assert.match(view, /expectedRoutingFingerprint/)
|
||||
assert.match(view, /environmentCode/)
|
||||
assert.match(view, /approvalId/)
|
||||
assert.match(view, /requestPluginTransitionApproval/)
|
||||
assert.match(view, /listPluginTransitionApprovals/)
|
||||
assert.match(view, /approvePluginTransitionApproval/)
|
||||
assert.match(view, /revokePluginTransitionApproval/)
|
||||
assert.match(view, /preflightPluginTransition/)
|
||||
assert.match(view, /approvalPreflight/)
|
||||
assert.match(view, /executableApprovals/)
|
||||
assert.match(view, /preflightStateLabel/)
|
||||
assert.match(view, /approvalPreflight\.routes/)
|
||||
assert.match(view, /requestReason/)
|
||||
assert.match(view, /requesterRoles/)
|
||||
assert.match(view, /approverRoles/)
|
||||
assert.match(view, /approvalReason/)
|
||||
assert.match(view, /\$prompt/)
|
||||
assert.match(view, /approvedBy/)
|
||||
assert.match(view, /approvedAt/)
|
||||
assert.match(view, /step\.row\.executorCode/)
|
||||
assert.match(view, /sqlTargetReady/)
|
||||
assert.match(view, /sqlTargetEnvironmentCode/)
|
||||
assert.match(view, /sqlTargetCatalog/)
|
||||
assert.match(view, /probePluginSqlTarget/)
|
||||
assert.match(view, /sqlTargetProbeLoading/)
|
||||
assert.match(view, /sqlTargetProbe/)
|
||||
assert.match(view, /probeSqlTarget/)
|
||||
assert.match(view, /NOT_CHECKED/)
|
||||
assert.match(view, /LEDGER_UNAVAILABLE/)
|
||||
assert.match(view, /PERMISSION_LEDGER_UNAVAILABLE/)
|
||||
assert.match(view, /permissionLedgerRequired/)
|
||||
assert.match(view, /permissionLedgerReady/)
|
||||
assert.match(view, /MENU_LEDGER_UNAVAILABLE/)
|
||||
assert.match(view, /menuLedgerRequired/)
|
||||
assert.match(view, /menuLedgerReady/)
|
||||
assert.match(view, /INVALID_CONFIGURATION/)
|
||||
assert.doesNotMatch(view, /registryStatus\.jdbcUrl/)
|
||||
assert.doesNotMatch(view, /registryStatus\.username/)
|
||||
assert.doesNotMatch(view, /registryStatus\.password/)
|
||||
assert.match(view, /class="manifest-view"/)
|
||||
assert.match(view, /generator:plugin:publish/)
|
||||
assert.match(view, /generator:plugin:rollback/)
|
||||
assert.match(view, /Conflicting|Manifest/)
|
||||
assert.doesNotMatch(view, /<textarea/)
|
||||
|
||||
const runStart = view.indexOf(' runTransition(row, action)')
|
||||
const runEnd = view.indexOf(' availableTransitionAction(row)', runStart)
|
||||
const runTransition = view.slice(runStart, runEnd)
|
||||
assert.match(runTransition, /approvalId/)
|
||||
assert.match(runTransition, /preflightPluginTransition/)
|
||||
assert.match(runTransition, /preflight\.approvalRequired/)
|
||||
assert.doesNotMatch(runTransition, /approvalReason/)
|
||||
assert.doesNotMatch(runTransition, /registryStatus\.realExecutorConfigured/)
|
||||
})
|
||||
|
||||
test('delivery verification view exposes the routed target snapshot', () => {
|
||||
const view = read('src/views/generator/delivery/index.vue')
|
||||
assert.match(view, /name: 'DeliveryVerification'/)
|
||||
assert.match(view, /getPluginDeliveryVerification/)
|
||||
assert.match(view, /executionEnvironmentCode/)
|
||||
assert.match(view, /routingFingerprint/)
|
||||
assert.match(view, /executorRoutes/)
|
||||
assert.match(view, /approvalRequiredForNonDryRun/)
|
||||
assert.match(view, /approvalSeparationEnabled/)
|
||||
assert.match(view, /approvalValidityMinutes/)
|
||||
assert.match(view, /approvalRequestTtlMinutes/)
|
||||
assert.match(view, /status\.checks/)
|
||||
assert.match(view, /databaseRegistryEnabled/)
|
||||
assert.match(view, /acceptanceCheckLabel/)
|
||||
assert.match(view, /部署验收/)
|
||||
assert.match(view, /permissionLedgerReady/)
|
||||
assert.match(view, /menuLedgerReady/)
|
||||
assert.match(view, /MENU_LEDGER_UNAVAILABLE/)
|
||||
assert.match(view, /createPluginDeliveryRehearsal/)
|
||||
assert.match(view, /listPluginDeliveryRehearsals/)
|
||||
assert.match(view, /getPluginDeliveryRehearsal/)
|
||||
assert.match(view, /rehearsalRuns/)
|
||||
assert.match(view, /selectedRehearsal/)
|
||||
assert.match(view, /acceptanceFingerprint/)
|
||||
assert.match(view, /scenarioFingerprint/)
|
||||
assert.match(view, /acceptanceSnapshot/)
|
||||
assert.match(view, /requiredEvidence/)
|
||||
assert.match(view, /PLAN_ONLY/)
|
||||
assert.match(view, /创建验收快照/)
|
||||
assert.match(view, /部署演练报告/)
|
||||
assert.match(view, /startPluginDeliveryRehearsal/)
|
||||
assert.match(view, /listPluginDeliveryRehearsalAttempts/)
|
||||
assert.match(view, /getPluginDeliveryRehearsalAttempt/)
|
||||
assert.match(view, /abortPluginDeliveryRehearsalAttempt/)
|
||||
assert.match(view, /reconcilePluginDeliveryRehearsalAttempt/)
|
||||
assert.match(view, /comparePluginDeliveryRehearsalAttempts/)
|
||||
assert.match(view, /getPluginDeliveryReleaseGate/)
|
||||
assert.match(view, /rehearsalAttempts/)
|
||||
assert.match(view, /selectedAttempt/)
|
||||
assert.match(view, /LOCAL_H2/)
|
||||
assert.match(view, /sandboxFingerprint/)
|
||||
assert.match(view, /evidenceFingerprint/)
|
||||
assert.match(view, /outbox\.status/)
|
||||
assert.match(view, /deliveryCount/)
|
||||
assert.match(view, /lastHeartbeatAt/)
|
||||
assert.match(view, /leaseUntil/)
|
||||
assert.match(view, /beginAttemptPolling/)
|
||||
assert.match(view, /releaseGate\.checks/)
|
||||
assert.match(view, /baselineSemanticFingerprint/)
|
||||
assert.match(view, /candidateSemanticFingerprint/)
|
||||
assert.match(view, /发布门禁/)
|
||||
assert.match(view, /语义对比/)
|
||||
assert.match(view, /持久队列/)
|
||||
assert.match(view, /formatEvidence/)
|
||||
assert.match(view, /启动本地 H2 演练/)
|
||||
assert.match(view, /本地 H2 演练证据/)
|
||||
assert.doesNotMatch(view, /executePluginTransition/)
|
||||
assert.doesNotMatch(view, /jdbc:h2/)
|
||||
assert.doesNotMatch(view, /leaseToken/)
|
||||
assert.doesNotMatch(view, /jdbcUrl/)
|
||||
assert.doesNotMatch(view, /username/)
|
||||
assert.doesNotMatch(view, /password/)
|
||||
})
|
||||
|
||||
test('plugin registry menu publishes every controller permission', () => {
|
||||
const sql = read('../sql/plugin_registry_menu.sql')
|
||||
for (const permission of ['list', 'query', 'add', 'edit', 'version', 'publish', 'rollback', 'bootstrap', 'execute', 'approve']) {
|
||||
assert.match(sql, new RegExp(`generator:plugin:${permission}`))
|
||||
}
|
||||
assert.match(sql, /generator\/plugin\/index/)
|
||||
})
|
||||
Reference in New Issue
Block a user