feat: integrate pixel teacher presence and resilient classroom preview
This commit is contained in:
1 parent
12d800ec51
commit
7951cca700
60 files changed
+3313
-180
No files matched your search
@@ -5,6 +5,7 @@ import { Login } from '@/pages/Login';
|
||||
import { dispatchPluginWorkspaceCommand } from '@/pages/Plugins/plugin-workspace-controller';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import { useProviderStore } from '@/stores/providers';
|
||||
import { codingRecoveryAccount } from '@/lib/coding-login-recovery';
|
||||
|
||||
const hostApiFetchMock = vi.hoisted(() => vi.fn());
|
||||
|
||||
@@ -39,7 +40,7 @@ function resetAuthStore() {
|
||||
|
||||
function LocationProbe() {
|
||||
const location = useLocation();
|
||||
return <output data-testid="login-destination">{location.pathname}{location.search}</output>;
|
||||
return <output data-testid="login-destination" data-recovery={JSON.stringify(location.state?.codingRecovery ?? null)}>{location.pathname}{location.search}</output>;
|
||||
}
|
||||
|
||||
function PluginSignInAction() {
|
||||
@@ -244,6 +245,21 @@ describe('Login page', () => {
|
||||
expect(importUserModelConfig).toHaveBeenCalledWith('password-access-token');
|
||||
});
|
||||
|
||||
it.each([true, false])('requires fresh login and only resumes the same account (same=%s)', async (same) => {
|
||||
const user = { username: 'alice', userId: 'a1', tenantId: 't1', deptId: null, authorities: [] };
|
||||
useAuthStore.setState({ user, accessToken: 'stale-token', expiresAt: Date.now() + 3600_000, lastActiveAt: Date.now() });
|
||||
const recovery = { id: 'recovery-1', account: codingRecoveryAccount(user), projectId: 'p1', conversationId: 'c1', work: true };
|
||||
loginWithPassword.mockImplementation(async () => useAuthStore.setState({ accessToken: 'fresh-token', user: same ? user : { ...user, userId: 'a2' } }));
|
||||
renderLogin([{ pathname: '/login', state: { from: '/project-config/plugins', reauthenticate: true, codingRecovery: recovery } }]);
|
||||
expect(screen.queryByTestId('login-destination')).not.toBeInTheDocument();
|
||||
fireEvent.change(screen.getByLabelText('用户名'), { target: { value: 'alice' } });
|
||||
fireEvent.change(screen.getByLabelText('密码'), { target: { value: 'password' } });
|
||||
fireEvent.click(screen.getByRole('checkbox', { name: /我已阅读并同意/ }));
|
||||
fireEvent.click(screen.getByRole('button', { name: '登录' }));
|
||||
const destination = await screen.findByTestId('login-destination');
|
||||
expect(JSON.parse(destination.getAttribute('data-recovery')!)).toEqual(same ? recovery : null);
|
||||
});
|
||||
|
||||
it('returns a signed-out plugin action to the exact canonical workspace query after login', async () => {
|
||||
const canonicalPath = '/project-config/plugins?scope=all&source=official&state=available&q=notes&plugin=official%3Amakelore.notes';
|
||||
loginWithPassword.mockImplementation(async () => {
|
||||
|
||||
Reference in new issue
Block a user