Restore Agent workspace and add platform pixel avatars
This commit is contained in:
1 parent
7a7d1f7fd8
commit
c14d996c05
22 files changed
+1387
-462
No files matched your search
@@ -45,6 +45,42 @@ beforeEach(() => { vi.clearAllMocks(); journalRecords.clear(); clearWorksSquareS
|
||||
afterEach(() => { instances.splice(0).forEach((module) => module.dispose()); clearWorksSquareSession(); vi.useRealTimers(); });
|
||||
|
||||
describe('Main cloud Agents boundary', () => {
|
||||
it.each(Array.from({ length: 16 }, (_, index) => `avatar-${String(index + 1).padStart(2, '0')}`))('uploads the bundled platform portrait %s through scoped Main transport without a dialog', async id => {
|
||||
const icon = '/api/storage/public/images/creator/preset.png';
|
||||
const transport = vi.fn().mockResolvedValueOnce(session()).mockResolvedValueOnce(json({ icon, private: 'hidden' }));
|
||||
expect(await moduleFor(transport).useAvatarPreset({ id })).toEqual({ icon, icon_url: 'https://agents.example.test' + icon });
|
||||
expect(desktop.pick).not.toHaveBeenCalled();
|
||||
expect(transport.mock.calls[1][0]).toBe('https://agents.example.test/api/makelore/avatars');
|
||||
expect(transport.mock.calls[1][1].headers).toEqual({ Authorization: 'Bearer yuxi-secret' });
|
||||
const file = (transport.mock.calls[1][1].body as FormData).get('file') as File;
|
||||
expect(file.name).toBe(`${id}.png`);
|
||||
expect(file.type).toBe('image/png');
|
||||
const bytes = Buffer.from(await file.arrayBuffer());
|
||||
expect(bytes.subarray(0, 8)).toEqual(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]));
|
||||
expect(bytes.length).toBeGreaterThan(100000);
|
||||
});
|
||||
|
||||
it.each(['avatar-00', 'avatar-17', '../../private/avatar.png', 'file:///tmp/avatar.png', 'data:image/png;base64,a', undefined])('rejects a non-allowlisted preset %s before transport', async id => {
|
||||
const transport = vi.fn();
|
||||
await expect(moduleFor(transport).useAvatarPreset({ id })).rejects.toMatchObject({ status: 422, code: 'invalid_input' });
|
||||
expect(desktop.pick).not.toHaveBeenCalled();
|
||||
expect(transport).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('requires a logged-in account for platform avatars and drops upload results after an account switch', async () => {
|
||||
const transport = vi.fn();
|
||||
const module = moduleFor(transport);
|
||||
clearWorksSquareSession();
|
||||
await expect(module.useAvatarPreset({ id: 'avatar-01' })).rejects.toMatchObject({ code: 'session_expired' });
|
||||
expect(transport).not.toHaveBeenCalled();
|
||||
login();
|
||||
transport.mockResolvedValueOnce(session()).mockImplementationOnce(async () => {
|
||||
login('b'.repeat(64));
|
||||
return json({ icon: '/api/storage/public/images/other/preset.png' });
|
||||
});
|
||||
await expect(module.useAvatarPreset({ id: 'avatar-01' })).rejects.toMatchObject({ code: 'account_changed' });
|
||||
});
|
||||
|
||||
it('uploads avatar bytes through Main and resolves Yuxi public URLs without exposing credentials', async () => {
|
||||
const directory = await mkdtemp(join(tmpdir(), 'makelore-avatar-'));
|
||||
try {
|
||||
@@ -106,8 +142,7 @@ describe('Main cloud Agents boundary', () => {
|
||||
expect(await module.execute({ operation: 'version', input: { slug: draft.slug, version: '1' } })).toMatchObject(avatar);
|
||||
});
|
||||
|
||||
it.each(['file:///private/avatar.png', 'javascript:alert(1)', 'https://secret@images.example.test/avatar.png'])
|
||||
('falls back for an unusable legacy avatar URL %s', async icon => {
|
||||
it.each(['file:///private/avatar.png', 'javascript:alert(1)', 'https://secret@images.example.test/avatar.png'])('falls back for an unusable legacy avatar URL %s', async icon => {
|
||||
const transport = vi.fn().mockResolvedValueOnce(session()).mockResolvedValueOnce(json({ ...draft, icon }));
|
||||
expect(await moduleFor(transport).get(draft.slug)).toMatchObject({ icon, icon_url: null });
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user