Merge branch 'master' of http://82.157.175.59:3000/GenarrativeAI/Genarrative
This commit is contained in:
@@ -1821,9 +1821,164 @@ test('runtime persistence is isolated by user', async () => {
|
||||
},
|
||||
);
|
||||
const userBLibraryPayload = (await userBLibrary.json()) as {
|
||||
profiles: unknown[];
|
||||
entries: unknown[];
|
||||
};
|
||||
assert.deepEqual(userBLibraryPayload.profiles, []);
|
||||
assert.deepEqual(userBLibraryPayload.entries, []);
|
||||
});
|
||||
});
|
||||
|
||||
test('custom worlds stay private until published and then appear in the public gallery', async () => {
|
||||
await withTestServer('custom-world-gallery', async ({ baseUrl }) => {
|
||||
const owner = await authEntry(baseUrl, 'gallery_owner', 'secret123');
|
||||
const viewer = await authEntry(baseUrl, 'gallery_viewer', 'secret123');
|
||||
|
||||
const upsertResponse = await httpRequest(
|
||||
`${baseUrl}/api/runtime/custom-world-library/world-a`,
|
||||
withBearer(owner.token, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({
|
||||
profile: {
|
||||
id: 'world-a',
|
||||
name: '裂桥前线',
|
||||
subtitle: '边境上空的断层回响',
|
||||
summary: '围绕裂桥哨线与失序潮汐展开的前线世界。',
|
||||
tone: '压迫、冷峻、持续失衡',
|
||||
playerGoal: '在裂桥崩塌前守住归路',
|
||||
majorFactions: ['裂桥守军'],
|
||||
coreConflicts: ['断层外压正在逼近城线'],
|
||||
playableNpcs: [
|
||||
{
|
||||
id: 'role-1',
|
||||
name: '沈昼',
|
||||
},
|
||||
],
|
||||
storyNpcs: [],
|
||||
landmarks: [
|
||||
{
|
||||
id: 'landmark-1',
|
||||
name: '裂桥前哨',
|
||||
description: '裂谷边缘的前线哨卡。',
|
||||
dangerLevel: '高',
|
||||
sceneNpcIds: [],
|
||||
connections: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
}),
|
||||
);
|
||||
const upsertPayload = (await upsertResponse.json()) as {
|
||||
entry: {
|
||||
visibility: 'draft' | 'published';
|
||||
authorDisplayName: string;
|
||||
};
|
||||
entries: unknown[];
|
||||
};
|
||||
|
||||
assert.equal(upsertResponse.status, 200);
|
||||
assert.equal(upsertPayload.entry.visibility, 'draft');
|
||||
assert.equal(upsertPayload.entry.authorDisplayName, 'gallery_owner');
|
||||
|
||||
const galleryBeforePublish = await httpRequest(
|
||||
`${baseUrl}/api/runtime/custom-world-gallery`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${viewer.token}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
const galleryBeforePayload = (await galleryBeforePublish.json()) as {
|
||||
entries: unknown[];
|
||||
};
|
||||
assert.deepEqual(galleryBeforePayload.entries, []);
|
||||
|
||||
const publishResponse = await httpRequest(
|
||||
`${baseUrl}/api/runtime/custom-world-library/world-a/publish`,
|
||||
withBearer(owner.token, {
|
||||
method: 'POST',
|
||||
}),
|
||||
);
|
||||
const publishPayload = (await publishResponse.json()) as {
|
||||
entry: {
|
||||
visibility: 'draft' | 'published';
|
||||
publishedAt: string | null;
|
||||
};
|
||||
};
|
||||
|
||||
assert.equal(publishResponse.status, 200);
|
||||
assert.equal(publishPayload.entry.visibility, 'published');
|
||||
assert.ok(publishPayload.entry.publishedAt);
|
||||
|
||||
const galleryAfterPublish = await httpRequest(
|
||||
`${baseUrl}/api/runtime/custom-world-gallery`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${viewer.token}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
const galleryAfterPayload = (await galleryAfterPublish.json()) as {
|
||||
entries: Array<{
|
||||
ownerUserId: string;
|
||||
profileId: string;
|
||||
worldName: string;
|
||||
authorDisplayName: string;
|
||||
}>;
|
||||
};
|
||||
|
||||
assert.equal(galleryAfterPublish.status, 200);
|
||||
assert.equal(galleryAfterPayload.entries.length, 1);
|
||||
assert.equal(galleryAfterPayload.entries[0]?.worldName, '裂桥前线');
|
||||
assert.equal(galleryAfterPayload.entries[0]?.authorDisplayName, 'gallery_owner');
|
||||
|
||||
const galleryDetail = await httpRequest(
|
||||
`${baseUrl}/api/runtime/custom-world-gallery/${encodeURIComponent(galleryAfterPayload.entries[0]?.ownerUserId || '')}/${encodeURIComponent(galleryAfterPayload.entries[0]?.profileId || '')}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${viewer.token}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
const galleryDetailPayload = (await galleryDetail.json()) as {
|
||||
entry: {
|
||||
worldName: string;
|
||||
profile: {
|
||||
name: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
assert.equal(galleryDetail.status, 200);
|
||||
assert.equal(galleryDetailPayload.entry.worldName, '裂桥前线');
|
||||
assert.equal(galleryDetailPayload.entry.profile.name, '裂桥前线');
|
||||
|
||||
const unpublishResponse = await httpRequest(
|
||||
`${baseUrl}/api/runtime/custom-world-library/world-a/unpublish`,
|
||||
withBearer(owner.token, {
|
||||
method: 'POST',
|
||||
}),
|
||||
);
|
||||
const unpublishPayload = (await unpublishResponse.json()) as {
|
||||
entry: {
|
||||
visibility: 'draft' | 'published';
|
||||
};
|
||||
};
|
||||
|
||||
assert.equal(unpublishResponse.status, 200);
|
||||
assert.equal(unpublishPayload.entry.visibility, 'draft');
|
||||
|
||||
const galleryAfterUnpublish = await httpRequest(
|
||||
`${baseUrl}/api/runtime/custom-world-gallery`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${viewer.token}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
const galleryAfterUnpublishPayload = (await galleryAfterUnpublish.json()) as {
|
||||
entries: unknown[];
|
||||
};
|
||||
assert.deepEqual(galleryAfterUnpublishPayload.entries, []);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user