Makelore 2.0 initial clean snapshot
This commit is contained in:
201
tests/unit/user-sync-contract.test.ts
Normal file
201
tests/unit/user-sync-contract.test.ts
Normal file
@@ -0,0 +1,201 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import {
|
||||
normalizeUserSyncBootstrap,
|
||||
toServerUserSyncPartner,
|
||||
toServerUserSyncProviderAccount,
|
||||
toUserSyncPartner,
|
||||
toUserSyncPreferences,
|
||||
toUserSyncProviderAccount,
|
||||
} from '../../shared/user-sync';
|
||||
|
||||
describe('user sync contract sanitizers', () => {
|
||||
it('keeps only portable preferences', () => {
|
||||
const result = toUserSyncPreferences({
|
||||
theme: 'dark',
|
||||
language: 'zh-CN',
|
||||
sidebarCollapsed: true,
|
||||
devModeUnlocked: true,
|
||||
launchAtStartup: true,
|
||||
setupComplete: true,
|
||||
activeProjectId: 'prj_1',
|
||||
proxyServer: 'http://proxy.example.com',
|
||||
} as never, 'default-account');
|
||||
|
||||
expect(result).toEqual({
|
||||
theme: 'dark',
|
||||
language: 'zh-CN',
|
||||
sidebarCollapsed: true,
|
||||
devModeUnlocked: true,
|
||||
defaultProviderAccountId: 'default-account',
|
||||
});
|
||||
});
|
||||
|
||||
it('keeps provider metadata but excludes secret and header fields', () => {
|
||||
const result = toUserSyncProviderAccount({
|
||||
id: 'openai-account-1',
|
||||
vendorId: 'openai',
|
||||
label: 'OpenAI',
|
||||
authMode: 'api_key',
|
||||
baseUrl: 'https://api.openai.com/v1',
|
||||
apiProtocol: 'openai-responses',
|
||||
headers: { Authorization: 'Bearer secret' },
|
||||
model: 'gpt-4.1-mini',
|
||||
fallbackModels: ['gpt-4o-mini'],
|
||||
fallbackAccountIds: ['fallback-account'],
|
||||
enabled: true,
|
||||
isDefault: true,
|
||||
apiKey: 'sk-should-not-sync',
|
||||
refreshToken: 'refresh-should-not-sync',
|
||||
metadata: { email: 'user@example.com' },
|
||||
createdAt: '2026-07-04T00:00:00.000Z',
|
||||
updatedAt: '2026-07-04T00:00:00.000Z',
|
||||
} as never);
|
||||
|
||||
expect(result).toEqual({
|
||||
id: 'openai-account-1',
|
||||
vendorId: 'openai',
|
||||
label: 'OpenAI',
|
||||
authMode: 'api_key',
|
||||
baseUrl: 'https://api.openai.com/v1',
|
||||
apiProtocol: 'openai-responses',
|
||||
model: 'gpt-4.1-mini',
|
||||
fallbackModels: ['gpt-4o-mini'],
|
||||
fallbackAccountIds: ['fallback-account'],
|
||||
enabled: true,
|
||||
isDefault: true,
|
||||
metadata: { email: 'user@example.com' },
|
||||
updatedAt: '2026-07-04T00:00:00.000Z',
|
||||
});
|
||||
expect(JSON.stringify(result)).not.toContain('sk-should-not-sync');
|
||||
expect(JSON.stringify(result)).not.toContain('refresh-should-not-sync');
|
||||
expect(JSON.stringify(result)).not.toContain('Authorization');
|
||||
});
|
||||
|
||||
it('keeps global partner metadata but excludes project runtime fields', () => {
|
||||
const result = toUserSyncPartner({
|
||||
id: 'nitu-pm-test',
|
||||
displayName: 'PM',
|
||||
templateRoleId: 'pm',
|
||||
description: 'Reusable partner',
|
||||
prompt: 'Reusable prompt',
|
||||
skillIds: ['pm-project-plan'],
|
||||
filePath: 'D:/repo/.opencode/agent/nitu-pm-test.md',
|
||||
projectRuntimeConfigsByProjectId: { prj_1: { filePath: 'D:/repo/file.md' } },
|
||||
createdAt: '2026-07-04T00:00:00.000Z',
|
||||
updatedAt: '2026-07-04T00:00:00.000Z',
|
||||
} as never);
|
||||
|
||||
expect(result).toEqual({
|
||||
id: 'nitu-pm-test',
|
||||
displayName: 'PM',
|
||||
templateRoleId: 'pm',
|
||||
description: 'Reusable partner',
|
||||
prompt: 'Reusable prompt',
|
||||
skillIds: ['pm-project-plan'],
|
||||
createdAt: '2026-07-04T00:00:00.000Z',
|
||||
updatedAt: '2026-07-04T00:00:00.000Z',
|
||||
});
|
||||
expect(JSON.stringify(result)).not.toContain('filePath');
|
||||
expect(JSON.stringify(result)).not.toContain('projectRuntimeConfigsByProjectId');
|
||||
});
|
||||
|
||||
it('normalizes backend snake_case bootstrap into desktop camelCase records', () => {
|
||||
const result = normalizeUserSyncBootstrap({
|
||||
preferences: {
|
||||
theme: 'dark',
|
||||
language: 'zh-CN',
|
||||
sidebar_collapsed: true,
|
||||
launch_at_startup: true,
|
||||
},
|
||||
provider_accounts: [{
|
||||
id: 'openai-account-1',
|
||||
vendor_id: 'openai',
|
||||
label: 'OpenAI',
|
||||
auth_mode: 'api_key',
|
||||
fallback_models: ['gpt-4o-mini'],
|
||||
fallback_account_ids: ['fallback-account'],
|
||||
api_key: 'sk-should-not-sync',
|
||||
updated_at: '2026-07-04T00:00:00.000Z',
|
||||
}],
|
||||
partners: [{
|
||||
id: 'nitu-pm-test',
|
||||
display_name: 'PM',
|
||||
template_role_id: 'pm',
|
||||
skill_ids: ['pm-project-plan'],
|
||||
file_path: 'D:/repo/.opencode/agent/nitu-pm-test.md',
|
||||
created_at: '2026-07-04T00:00:00.000Z',
|
||||
updated_at: '2026-07-04T00:00:00.000Z',
|
||||
}],
|
||||
usage_aggregates: [],
|
||||
projects: [{ id: 'prj_1' }],
|
||||
});
|
||||
|
||||
expect(result.preferences).toEqual({ theme: 'dark', language: 'zh-CN', sidebarCollapsed: true });
|
||||
expect(result.providerAccounts).toEqual([{
|
||||
id: 'openai-account-1',
|
||||
vendorId: 'openai',
|
||||
label: 'OpenAI',
|
||||
authMode: 'api_key',
|
||||
fallbackModels: ['gpt-4o-mini'],
|
||||
fallbackAccountIds: ['fallback-account'],
|
||||
enabled: true,
|
||||
isDefault: false,
|
||||
metadata: {},
|
||||
updatedAt: '2026-07-04T00:00:00.000Z',
|
||||
}]);
|
||||
expect(result.partners).toEqual([{
|
||||
id: 'nitu-pm-test',
|
||||
displayName: 'PM',
|
||||
templateRoleId: 'pm',
|
||||
skillIds: ['pm-project-plan'],
|
||||
createdAt: '2026-07-04T00:00:00.000Z',
|
||||
updatedAt: '2026-07-04T00:00:00.000Z',
|
||||
}]);
|
||||
expect(JSON.stringify(result)).not.toContain('prj_1');
|
||||
expect(JSON.stringify(result)).not.toContain('sk-should-not-sync');
|
||||
expect(JSON.stringify(result)).not.toContain('file_path');
|
||||
});
|
||||
|
||||
it('converts sanitized desktop records to server snake_case payloads', () => {
|
||||
expect(toServerUserSyncProviderAccount({
|
||||
id: 'openai-account-1',
|
||||
vendorId: 'openai',
|
||||
label: 'OpenAI',
|
||||
authMode: 'api_key',
|
||||
fallbackModels: ['gpt-4o-mini'],
|
||||
fallbackAccountIds: ['fallback-account'],
|
||||
enabled: true,
|
||||
isDefault: true,
|
||||
metadata: {},
|
||||
updatedAt: '2026-07-04T00:00:00.000Z',
|
||||
})).toEqual({
|
||||
id: 'openai-account-1',
|
||||
vendor_id: 'openai',
|
||||
label: 'OpenAI',
|
||||
auth_mode: 'api_key',
|
||||
fallback_models: ['gpt-4o-mini'],
|
||||
fallback_account_ids: ['fallback-account'],
|
||||
enabled: true,
|
||||
is_default: true,
|
||||
metadata: {},
|
||||
updated_at: '2026-07-04T00:00:00.000Z',
|
||||
});
|
||||
|
||||
expect(toServerUserSyncPartner({
|
||||
id: 'nitu-pm-test',
|
||||
displayName: 'PM',
|
||||
templateRoleId: 'pm',
|
||||
skillIds: ['pm-project-plan'],
|
||||
createdAt: '2026-07-04T00:00:00.000Z',
|
||||
updatedAt: '2026-07-04T00:00:00.000Z',
|
||||
})).toEqual({
|
||||
id: 'nitu-pm-test',
|
||||
display_name: 'PM',
|
||||
template_role_id: 'pm',
|
||||
skill_ids: ['pm-project-plan'],
|
||||
created_at: '2026-07-04T00:00:00.000Z',
|
||||
updated_at: '2026-07-04T00:00:00.000Z',
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user