Files
tkmind_go/ui/h5/mindspace.test.mjs
john 4e21ca937a
Deploy Documentation / deploy (push) Has been cancelled
Canary / Prepare Version (push) Has been cancelled
Canary / build-cli (push) Has been cancelled
Canary / Upload Install Script (push) Has been cancelled
Canary / bundle-desktop (push) Has been cancelled
Canary / bundle-desktop-intel (push) Has been cancelled
Canary / bundle-desktop-linux (push) Has been cancelled
Canary / bundle-desktop-windows (push) Has been cancelled
Canary / bundle-desktop-windows-cuda (push) Has been cancelled
Canary / Release (push) Has been cancelled
Unused Dependencies / machete (push) Has been cancelled
CI / changes (push) Has been cancelled
CI / Check Rust Code Format (push) Has been cancelled
CI / Build and Test Rust Project (push) Has been cancelled
CI / Build Rust Project on Windows (push) Has been cancelled
CI / Check MSRV (push) Has been cancelled
CI / Lint Rust Code (push) Has been cancelled
CI / Check Generated Schemas are Up-to-Date (push) Has been cancelled
CI / Test and Lint Electron Desktop App (push) Has been cancelled
CI / H5 Plaza Tests and Build (push) Has been cancelled
Live Provider Tests / check-fork (push) Has been cancelled
Live Provider Tests / changes (push) Has been cancelled
Live Provider Tests / Build Binary (push) Has been cancelled
Live Provider Tests / Smoke Tests (push) Has been cancelled
Live Provider Tests / Smoke Tests (Code Execution) (push) Has been cancelled
Live Provider Tests / Compaction Tests (push) Has been cancelled
Live Provider Tests / goose server HTTP integration tests (push) Has been cancelled
Publish Ask AI Bot Docker Image / docker (push) Has been cancelled
Publish Docker Image / docker (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
Add TKMind platform extensions, H5/MindSpace stack, and deployment tooling.
Fork goose with custom MCP widgets, platform extensions (aider, git, web, search),
MindSpace H5 backend/frontend, Plaza/Ops UIs, and deploy scripts for tkmind.cn.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-14 21:30:20 +08:00

122 lines
3.5 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import {
createMindSpaceService,
DEFAULT_SPACE_QUOTA_BYTES,
ensureDefaultSpaces,
initializeDefaultSpace,
SYSTEM_CATEGORIES,
} from './mindspace.mjs';
test('initializeDefaultSpace creates one space and all system categories', async () => {
const queries = [];
let id = 0;
const db = {
async query(sql, params) {
queries.push({ sql, params });
if (sql.includes('SELECT id FROM h5_user_spaces')) {
return [[{ id: 'space-1' }]];
}
return [[]];
},
};
const spaceId = await initializeDefaultSpace(db, 'user-1', {
now: 123,
idFactory: () => `id-${++id}`,
});
assert.equal(spaceId, 'space-1');
assert.equal(queries.length, SYSTEM_CATEGORIES.length + 2);
assert.equal(queries[0].params[3], DEFAULT_SPACE_QUOTA_BYTES);
assert.deepEqual(
queries
.filter(({ sql }) => sql.includes('INSERT INTO h5_space_categories'))
.map(({ params }) => params[3]),
['oa', 'private', 'public', 'draft', 'archive'],
);
});
test('ensureDefaultSpaces backfills only users without a space', async () => {
let selectedMissingUsers = false;
const createdFor = [];
const pool = {
async query(sql, params) {
if (sql.includes('LEFT JOIN h5_user_spaces')) {
selectedMissingUsers = true;
return [[{ id: 'user-a' }, { id: 'user-b' }]];
}
if (sql.includes('INSERT INTO h5_user_spaces')) {
createdFor.push(params[1]);
return [[]];
}
if (sql.includes('SELECT id FROM h5_user_spaces')) {
return [[{ id: `space-${params[0]}` }]];
}
return [[]];
},
};
const count = await ensureDefaultSpaces(pool, {
idFactory: () => 'generated-id',
});
assert.equal(selectedMissingUsers, true);
assert.equal(count, 2);
assert.deepEqual(createdFor, ['user-a', 'user-b']);
});
test('getSpace scopes space and categories to the authenticated user', async () => {
const calls = [];
const pool = {
async query(sql, params) {
calls.push({ sql, params });
if (sql.includes('FROM h5_user_spaces')) {
return [[{
id: 'space-1',
user_id: 'user-1',
space_name: '我的空间',
quota_bytes: 5 * 1024 * 1024,
used_bytes: 1024,
reserved_bytes: 2048,
status: 'active',
created_at: 10,
updated_at: 20,
}]];
}
return [[{
id: 'category-1',
category_code: 'private',
category_name: '私人区',
visibility_policy: 'private',
ai_access_policy: 'explicit_asset_grant',
publish_policy: 'desensitized_copy_only',
is_system: 1,
sort_order: 20,
item_count: 0,
}]];
},
};
const service = createMindSpaceService(pool);
const space = await service.getSpace('user-1');
assert.equal(space.userId, 'user-1');
assert.equal(space.quota.availableBytes, 5 * 1024 * 1024 - 3072);
assert.equal(space.categories[0].code, 'private');
assert.deepEqual(calls[0].params, ['user-1']);
assert.deepEqual(calls[1].params, ['user-1', 'space-1']);
});
test('getSpace returns null when the user has no space', async () => {
const service = createMindSpaceService({
async query() {
return [[]];
},
});
assert.equal(await service.getSpace('missing-user'), null);
assert.equal(await service.getQuota('missing-user'), null);
assert.equal(await service.listCategories('missing-user'), null);
});