mirror of
https://github.com/iflytek/skillhub.git
synced 2026-10-09 03:17:52 +00:00
test(e2e): harden namespace selection for publish flows
This commit is contained in:
parent
a6a3bdc5f3
commit
ccf7e3840d
2 changed files with 84 additions and 13 deletions
|
|
@ -10,6 +10,11 @@ export interface SeededNamespace {
|
|||
id: number
|
||||
slug: string
|
||||
displayName: string
|
||||
status?: string
|
||||
type?: string
|
||||
currentUserRole?: string
|
||||
canUnfreeze?: boolean
|
||||
canRestore?: boolean
|
||||
}
|
||||
|
||||
export interface SeededSkill {
|
||||
|
|
@ -234,6 +239,34 @@ export class E2eTestDataBuilder {
|
|||
)
|
||||
}
|
||||
|
||||
private isTeamNamespace(namespace: SeededNamespace): boolean {
|
||||
return namespace.type === 'TEAM' || namespace.slug !== 'global'
|
||||
}
|
||||
|
||||
private isActiveNamespace(namespace: SeededNamespace): boolean {
|
||||
return namespace.status === 'ACTIVE'
|
||||
}
|
||||
|
||||
private async activateNamespace(namespace: SeededNamespace): Promise<SeededNamespace | null> {
|
||||
if (!this.isTeamNamespace(namespace)) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (namespace.status === 'FROZEN' && namespace.canUnfreeze) {
|
||||
return parseEnvelope<SeededNamespace>(
|
||||
await this.request.post(`/api/web/namespaces/${encodeURIComponent(namespace.slug)}/unfreeze`),
|
||||
)
|
||||
}
|
||||
|
||||
if (namespace.status === 'ARCHIVED' && namespace.canRestore) {
|
||||
return parseEnvelope<SeededNamespace>(
|
||||
await this.request.post(`/api/web/namespaces/${encodeURIComponent(namespace.slug)}/restore`),
|
||||
)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
async ensureWritableNamespace(): Promise<SeededNamespace> {
|
||||
if (this.ensuredNamespace) {
|
||||
return this.ensuredNamespace
|
||||
|
|
@ -251,16 +284,38 @@ export class E2eTestDataBuilder {
|
|||
}
|
||||
|
||||
const namespaces = await this.listMyNamespaces()
|
||||
const writable = namespaces.find((item) => item.slug !== 'global') ?? namespaces[0]
|
||||
if (!writable) {
|
||||
throw new Error('No namespace available for e2e data seeding')
|
||||
const activeTeam = namespaces.find((item) => this.isTeamNamespace(item) && this.isActiveNamespace(item))
|
||||
if (activeTeam) {
|
||||
this.ensuredNamespace = activeTeam
|
||||
return activeTeam
|
||||
}
|
||||
this.ensuredNamespace = writable
|
||||
return writable
|
||||
|
||||
const activeFallback = namespaces.find((item) => this.isActiveNamespace(item))
|
||||
if (activeFallback) {
|
||||
this.ensuredNamespace = activeFallback
|
||||
return activeFallback
|
||||
}
|
||||
|
||||
const activatable = namespaces.find((item) =>
|
||||
this.isTeamNamespace(item)
|
||||
&& ((item.status === 'FROZEN' && item.canUnfreeze) || (item.status === 'ARCHIVED' && item.canRestore)),
|
||||
)
|
||||
if (activatable) {
|
||||
const activated = await this.activateNamespace(activatable)
|
||||
if (activated) {
|
||||
this.ensuredNamespace = activated
|
||||
return activated
|
||||
}
|
||||
}
|
||||
|
||||
const summary = namespaces
|
||||
.map((item) => `${item.slug}:${item.status ?? 'UNKNOWN'}`)
|
||||
.join(', ')
|
||||
throw new Error(`No active writable namespace available for e2e data seeding [${summary}]`)
|
||||
}
|
||||
|
||||
async ensureReviewableNamespace(): Promise<SeededNamespace> {
|
||||
if (this.ensuredNamespace && this.ensuredNamespace.slug !== 'global') {
|
||||
if (this.ensuredNamespace && this.isTeamNamespace(this.ensuredNamespace) && this.isActiveNamespace(this.ensuredNamespace)) {
|
||||
return this.ensuredNamespace
|
||||
}
|
||||
|
||||
|
|
@ -276,13 +331,28 @@ export class E2eTestDataBuilder {
|
|||
}
|
||||
|
||||
const namespaces = await this.listMyNamespaces()
|
||||
const reviewableNamespace = namespaces.find((item) => item.slug !== 'global')
|
||||
if (!reviewableNamespace) {
|
||||
throw new Error('No TEAM namespace available for review E2E data seeding')
|
||||
const activeTeam = namespaces.find((item) => this.isTeamNamespace(item) && this.isActiveNamespace(item))
|
||||
if (activeTeam) {
|
||||
this.ensuredNamespace = activeTeam
|
||||
return activeTeam
|
||||
}
|
||||
|
||||
this.ensuredNamespace = reviewableNamespace
|
||||
return reviewableNamespace
|
||||
const activatable = namespaces.find((item) =>
|
||||
this.isTeamNamespace(item)
|
||||
&& ((item.status === 'FROZEN' && item.canUnfreeze) || (item.status === 'ARCHIVED' && item.canRestore)),
|
||||
)
|
||||
if (activatable) {
|
||||
const activated = await this.activateNamespace(activatable)
|
||||
if (activated) {
|
||||
this.ensuredNamespace = activated
|
||||
return activated
|
||||
}
|
||||
}
|
||||
|
||||
const summary = namespaces
|
||||
.map((item) => `${item.slug}:${item.status ?? 'UNKNOWN'}`)
|
||||
.join(', ')
|
||||
throw new Error(`No TEAM namespace available for review E2E data seeding [${summary}]`)
|
||||
}
|
||||
|
||||
private async getMySkillInNamespace(namespaceSlug: string): Promise<SeededSkill | null> {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { E2eTestDataBuilder } from './helpers/test-data-builder'
|
|||
|
||||
interface PublishEnvelope {
|
||||
code: number
|
||||
msg?: string
|
||||
data: {
|
||||
namespace: string
|
||||
slug: string
|
||||
|
|
@ -51,14 +52,14 @@ test.describe('Publish Flow UI (Real API)', () => {
|
|||
const publishResponsePromise = page.waitForResponse(
|
||||
(response) =>
|
||||
response.request().method() === 'POST'
|
||||
&& response.url().includes(`/api/web/skills/${encodeURIComponent(namespace.slug)}/publish`)
|
||||
&& response.status() === 200,
|
||||
&& response.url().includes(`/api/web/skills/${encodeURIComponent(namespace.slug)}/publish`),
|
||||
{ timeout: 90_000 },
|
||||
)
|
||||
await confirmButton.click()
|
||||
const publishResponse = await publishResponsePromise
|
||||
const publishBody = await publishResponse.json() as PublishEnvelope
|
||||
|
||||
expect(publishResponse.status(), `publish failed: ${publishBody.msg ?? 'unknown error'}`).toBe(200)
|
||||
expect(publishBody.code).toBe(0)
|
||||
expect(publishBody.data.namespace).toBe(namespace.slug)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue