Merge pull request #2699 from langbot-app/test/quality-account-ui-oracles-20261017

test(web): replace account and privacy source checks with browser behavior
This commit is contained in:
huanghuoguoguo
2026-10-17 20:35:41 +08:00
committed by GitHub
9 changed files with 503 additions and 242 deletions
@@ -1,19 +0,0 @@
import assert from 'node:assert/strict';
import fs from 'node:fs';
import test from 'node:test';
const source = fs.readFileSync(
new URL('../../src/app/login/page.tsx', import.meta.url),
'utf8',
);
test('normal Cloud login uses the standard Space OAuth callback path', () => {
assert.doesNotMatch(source, /cloudEntry/);
assert.match(source, /getSpaceAuthorizeUrl\(redirectUri\)/);
});
test('invitation login uses the same OAuth callback before accepting the invitation', () => {
assert.doesNotMatch(source, /cloudEntry/);
assert.match(source, /const invitationToken = getPendingInvitationToken\(\)/);
assert.match(source, /acceptWorkspaceInvitation\(invitationToken\)/);
});
@@ -10,45 +10,6 @@ const root = path.resolve(
);
const read = (file) => fs.readFileSync(path.join(root, file), 'utf8');
test('invited local registration returns to login instead of authenticating', () => {
const source = read('src/app/invitations/accept/page.tsx');
assert.doesNotMatch(
source,
/beginAuthenticatedSession\([\s\S]{0,120}response\.token/,
);
assert.match(source, /navigate\('\/login\?invitation=1'/);
});
test('authenticated invitation page offers logout while retaining invitation', () => {
const source = read('src/app/invitations/accept/page.tsx');
assert.match(source, /workspace\.logoutAndReturn/);
assert.match(source, /setPendingInvitationToken\(token\)/);
});
test('Space OAuth callback distinguishes unknown and unbound accounts by stable codes', () => {
const source = read('src/app/auth/space/callback/page.tsx');
assert.match(source, /space_account_not_registered/);
assert.match(source, /space_account_binding_required/);
});
test('models panel derives LangBot Models billing state from workspace owner', () => {
const source = read('src/app/home/components/models-dialog/ModelsPanel.tsx');
assert.match(source, /getWorkspaceSpaceBilling/);
assert.doesNotMatch(source, /getSpaceCredits\(\)/);
assert.match(source, /membership\.role === 'owner'/);
});
test('provider card represents owner and member owner-bound states explicitly', () => {
const source = read(
'src/app/home/components/models-dialog/components/ProviderCard.tsx',
);
assert.match(source, /isWorkspaceOwner/);
assert.match(source, /ownerSpaceBound/);
assert.match(source, /models\.ownerMustBindSpace/);
assert.match(source, /models\.usesOwnerSpaceBilling/);
assert.match(source, /isWorkspaceOwner && \(\s*<Button/);
});
test('workspace member controls never offer ownership transfer', () => {
const source = read(
'src/app/home/components/workspace-settings/WorkspaceSettingsPanel.tsx',
@@ -1,123 +0,0 @@
import assert from 'node:assert/strict';
import fs from 'node:fs';
import path from 'node:path';
import test from 'node:test';
import { fileURLToPath } from 'node:url';
const currentDirectory = path.dirname(fileURLToPath(import.meta.url));
const webRoot = path.resolve(currentDirectory, '../..');
function readSource(relativePath) {
return fs.readFileSync(path.join(webRoot, relativePath), 'utf8');
}
const homeSidebarSource = readSource(
'src/app/home/components/home-sidebar/HomeSidebar.tsx',
);
const botFormSource = readSource(
'src/app/home/bots/components/bot-form/BotForm.tsx',
);
const dynamicFormSource = readSource(
'src/app/home/components/dynamic-form/DynamicFormComponent.tsx',
);
const kbFormSource = readSource(
'src/app/home/knowledge/components/kb-form/KBForm.tsx',
);
const settingsDialogSource = readSource(
'src/app/home/components/settings-dialog/SettingsDialog.tsx',
);
const pluginPageSource = readSource('src/app/home/plugin-pages/page.tsx');
const authenticatedPluginResourceSource = readSource(
'src/hooks/useAuthenticatedPluginResource.ts',
);
test('keeps bot forms spaced with responsive setup and detail columns', () => {
const fieldset = botFormSource.match(
/<fieldset\s[\s\S]*?disabled=\{isLoading\}/,
)?.[0];
assert.ok(fieldset, 'the form must retain its loading-disabled fieldset');
assert.match(
fieldset,
/initBotId\s*\?\s*'grid gap-4 lg:h-full lg:min-h-0 lg:grid-cols-\[minmax\(0,2fr\)_minmax\(0,3fr\)\] lg:grid-rows-\[minmax\(0,1fr\)\]'\s*:\s*'grid items-start gap-6 lg:grid-cols-\[minmax\(16rem,0\.7fr\)_minmax\(0,2fr\)\]'/,
);
assert.match(kbFormSource, /<form[\s\S]*?className="space-y-6"/);
});
test('hides the manifest connection switch behind the dedicated selector', () => {
assert.match(
botFormSource,
/webhookField\?\.show_if\?\.field\s*\?\s*\[webhookField\.show_if\.field\]/,
);
assert.match(
botFormSource,
/hiddenItemNames=\{connectionModeControllerNames\}/,
);
assert.match(
dynamicFormSource,
/if \(hiddenItemNames\?\.includes\(config\.name\)\) return null/,
);
assert.doesNotMatch(
dynamicFormSource.match(
/const editableItems = useMemo\([\s\S]*?\n \);/,
)?.[0] ?? '',
/hiddenItemNames/,
);
});
test('does not expose storage analysis in Cloud settings or via a deep link', () => {
assert.match(
homeSidebarSource,
/canViewStorageAnalysis\s*&&\s*\(\s*<DropdownMenuItem[\s\S]*?openSettings\('storageAnalysis'\)/,
);
assert.match(
settingsDialogSource,
/const canViewStorageAnalysis\s*=\s*currentWorkspace\?\.workspace\.source\s*!==\s*'cloud_projection'\s*&&\s*canViewAudit/,
);
assert.match(
settingsDialogSource,
/item\.id === 'storageAnalysis'[\s\S]*?return canViewStorageAnalysis/,
);
assert.match(
settingsDialogSource,
/section === 'storageAnalysis' && !canViewStorageAnalysis/,
);
assert.match(
settingsDialogSource,
/section === 'storageAnalysis' &&\s*canViewStorageAnalysis &&\s*\(\s*<StorageAnalysisPanel/,
);
});
test('renders storage analysis with the storage icon in the user menu', () => {
assert.match(
homeSidebarSource,
/canViewStorageAnalysis\s*&&\s*\(\s*<DropdownMenuItem[\s\S]*?<HardDrive\s*\/>[\s\S]*?\{t\('storageAnalysis\.title'\)\}/,
);
});
test('loads plugin pages through the authenticated Workspace-scoped asset route', () => {
assert.match(pluginPageSource, /useAuthenticatedPluginAsset/);
assert.match(
pluginPageSource,
/useAuthenticatedPluginAsset\(\s*author,\s*pluginName,\s*pagePath,?\s*\)/,
);
assert.match(pluginPageSource, /src=\{assetUrl\}/);
assert.doesNotMatch(pluginPageSource, /getPluginAssetURL\(/);
assert.match(pluginPageSource, /plugins\.loadFailed/);
assert.match(pluginPageSource, /loadedAssetUrl !== assetUrl/);
});
test('revokes and reloads authenticated plugin resources when the Workspace changes', () => {
assert.match(authenticatedPluginResourceSource, /useCurrentWorkspace/);
assert.match(
authenticatedPluginResourceSource,
/const workspaceUuid = currentWorkspace\?\.workspace\.uuid;/,
);
assert.match(
authenticatedPluginResourceSource,
/\[author, name, filepath, resourceKey\]/,
);
assert.match(
authenticatedPluginResourceSource,
/resource\.key === resourceKey \? resource\.url : ''/,
);
});