收口 Makelore 客户端变更
Electron E2E / Electron E2E (macos-latest) (push) Has been cancelled
Electron E2E / Electron E2E (ubuntu-latest) (push) Has been cancelled
Electron E2E / Electron E2E (windows-latest) (push) Has been cancelled

This commit is contained in:
inman committed 2026-08-12 22:43:09 +08:00
1 parent 253bad8b40
commit f4113a872f
232 files changed
+4617 -20121

No files matched your search

+48 -28
View File
@@ -53,7 +53,25 @@ describe('Login page', () => {
</MemoryRouter>,
);
expect(screen.getByRole('button', { name: 'Continue in browser' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: '在浏览器中继续' })).toBeInTheDocument();
});
it('uses Chinese copy and keeps upstream HTML errors concise', () => {
useAuthStore.setState({
error: '<html><head><title>502 Bad Gateway</title></head><body>upstream details</body></html>',
});
render(
<MemoryRouter initialEntries={['/login']}>
<Login />
</MemoryRouter>,
);
expect(screen.getByText('登录 Makelore 账户')).toBeInTheDocument();
expect(screen.getByText('请在浏览器中完成登录,并授权此桌面应用访问。')).toBeInTheDocument();
expect(screen.getByRole('button', { name: '在浏览器中继续' })).toBeInTheDocument();
expect(screen.getByRole('alert')).toHaveTextContent('登录服务暂时不可用,请稍后重试。');
expect(screen.queryByText(/<html>/i)).not.toBeInTheDocument();
});
it('redirects protected app routes to login when setup is complete but the user is signed out', async () => {
@@ -65,7 +83,20 @@ describe('Login page', () => {
</MemoryRouter>,
);
expect(await screen.findByRole('button', { name: 'Continue in browser' })).toBeInTheDocument();
expect(await screen.findByRole('button', { name: '在浏览器中继续' })).toBeInTheDocument();
});
it('opens the module chooser at the default root route', async () => {
vi.stubGlobal('__NIANCODE_RENDERER_ONLY__', true);
render(
<MemoryRouter initialEntries={['/']}>
<App />
</MemoryRouter>,
);
expect(await screen.findByTestId('ai-module-selection-page')).toBeInTheDocument();
expect(screen.getByRole('heading', { name: '今天,想创作什么?' })).toBeInTheDocument();
});
it('redirects an open protected route when the current auth session is invalidated', async () => {
@@ -115,7 +146,7 @@ describe('Login page', () => {
});
});
expect(await screen.findByRole('button', { name: 'Continue in browser' })).toBeInTheDocument();
expect(await screen.findByRole('button', { name: '在浏览器中继续' })).toBeInTheDocument();
});
it('does not record synthetic DOM events as user activity', async () => {
@@ -209,14 +240,14 @@ describe('Login page', () => {
});
const { unmount } = render(
<MemoryRouter initialEntries={['/']}>
<MemoryRouter initialEntries={['/image-canvas']}>
<App />
</MemoryRouter>,
);
expect(await screen.findByText('创建第一个设计项目')).toBeInTheDocument();
expect(screen.queryByText('本地开发')).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: 'Continue in browser' })).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: '在浏览器中继续' })).not.toBeInTheDocument();
unmount();
render(
@@ -224,10 +255,10 @@ describe('Login page', () => {
<App />
</MemoryRouter>,
);
expect(await screen.findByRole('button', { name: 'Continue in browser' })).toBeInTheDocument();
expect(await screen.findByRole('button', { name: '在浏览器中继续' })).toBeInTheDocument();
});
it('opens the project conversation from the default route for an initialized active project', async () => {
it('opens the project conversation from its direct route for an initialized active project', async () => {
vi.stubGlobal('__NIANCODE_RENDERER_ONLY__', true);
const project = {
id: 'project-default-chat',
@@ -252,7 +283,7 @@ describe('Login page', () => {
});
render(
<MemoryRouter initialEntries={['/']}>
<MemoryRouter initialEntries={['/opencode-chat']}>
<App />
</MemoryRouter>,
);
@@ -260,18 +291,8 @@ describe('Login page', () => {
expect(await screen.findByTestId('chat-operation-page')).toBeInTheDocument();
});
it('keeps the default route on project configuration without an active project', async () => {
it('keeps the module chooser at the default route without an active project', async () => {
vi.stubGlobal('__NIANCODE_RENDERER_ONLY__', true);
hostApiFetchMock.mockImplementation(async (path: string) => {
if (path === '/api/opencode/projects') return { projects: [], activeProject: null };
if (path === '/api/opencode/status') return { state: 'stopped', port: 4096 };
if (path === '/api/opencode/config-summary') return { providerIds: [], providerCount: 0, envKeys: [] };
if (path === '/api/provider-accounts') return [];
if (path === '/api/provider-accounts/key-info') return [];
if (path === '/api/provider-vendors') return [];
if (path === '/api/provider-accounts/default') return { accountId: null };
return { success: true };
});
render(
<MemoryRouter initialEntries={['/']}>
@@ -279,12 +300,11 @@ describe('Login page', () => {
</MemoryRouter>,
);
expect(await screen.findByText('一念成光,万物可创。')).toBeInTheDocument();
expect(screen.queryByText('请先新建项目')).not.toBeInTheDocument();
expect(screen.queryByTestId('chat-operation-page')).not.toBeInTheDocument();
expect(await screen.findByTestId('ai-module-selection-page')).toBeInTheDocument();
expect(screen.getByRole('heading', { name: '今天,想创作什么?' })).toBeInTheDocument();
});
it('keeps an uninitialized active project on project configuration', async () => {
it('keeps an uninitialized active project on project configuration from its direct route', async () => {
vi.stubGlobal('__NIANCODE_RENDERER_ONLY__', true);
const project = {
id: 'project-uninitialized',
@@ -309,7 +329,7 @@ describe('Login page', () => {
});
render(
<MemoryRouter initialEntries={['/']}>
<MemoryRouter initialEntries={['/opencode-chat']}>
<App />
</MemoryRouter>,
);
@@ -375,7 +395,7 @@ describe('Login page', () => {
expect(screen.queryByLabelText('Username')).not.toBeInTheDocument();
expect(screen.queryByLabelText('Password')).not.toBeInTheDocument();
expect(screen.queryByLabelText('Captcha')).not.toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: 'Continue in browser' }));
fireEvent.click(screen.getByRole('button', { name: '在浏览器中继续' }));
await screen.findByText('Module Selection');
await waitFor(() => {
@@ -439,7 +459,7 @@ describe('Login page', () => {
</MemoryRouter>,
);
fireEvent.click(screen.getByRole('button', { name: 'Continue in browser' }));
fireEvent.click(screen.getByRole('button', { name: '在浏览器中继续' }));
await waitFor(() => {
expect(hostApiFetchMock).toHaveBeenCalledWith('/api/provider-accounts/import-user-model-config', {
@@ -480,9 +500,9 @@ describe('Login page', () => {
</MemoryRouter>,
);
fireEvent.click(screen.getByRole('button', { name: 'Continue in browser' }));
fireEvent.click(screen.getByRole('button', { name: '在浏览器中继续' }));
expect(await screen.findByText('sync failed')).toBeInTheDocument();
expect(await screen.findByText('登录失败,请稍后重试。')).toBeInTheDocument();
expect(screen.queryByText('Module Selection')).not.toBeInTheDocument();
expect(hostApiFetchMock).toHaveBeenCalledWith('/api/auth/logout', {
method: 'POST',