Merge branch 'main' of https://git.nianxx.cn/wangxuming/makelore
Electron E2E / Electron E2E (macos-latest) (push) Canceled after 0s
Electron E2E / Electron E2E (ubuntu-latest) (push) Canceled after 0s
Electron E2E / Electron E2E (windows-latest) (push) Canceled after 0s

This commit is contained in:
brother7 committed 2026-10-09 16:11:55 +08:00
commit 87d3f03d75
9 files changed
+259 -34

No files matched your search

+48 -2
View File
@@ -21,11 +21,11 @@ const definition: TeacherDefinition = {
function checkInTopic(projectId = 'project', id = 'check-1'): TeacherTopic {
return { schemaVersion: 1, revision: 2, id: 'topic-' + projectId, role: 'teacher', accountId: 'kid', projectId, sourceConversationId: 'project', version: 1, definition, createdAt: 'now', updatedAt: 'now', requests: [{ id, intent: 'check-in', text: '', references: [], createdAt: 'now', sourceCursor: { workerGeneration: 1, seq: 1 }, sourceCapturedAt: 'now', includedSourceMessageIds: [], omittedMessages: 0, status: 'completed', response: '你刚才想加排行榜,我们一起想想比什么更有意思?' }] };
}
function Harness({ projectId = 'project', sourceId = 'source', busy = false, archived = false }: { projectId?: string; sourceId?: string; busy?: boolean; archived?: boolean }) {
function Harness({ projectId = 'project', sourceId = 'source', busy = false, archived = false, showWelcomes = true }: { projectId?: string; sourceId?: string; busy?: boolean; archived?: boolean; showWelcomes?: boolean }) {
const [open, setOpen] = useState(false);
const [teacherComposing, setTeacherComposing] = useState(false);
const companion = useTeacherCompanion({ projectId, sourceId, sourceBusy: busy, sourceArchived: archived, teacherOpen: open, teacherComposing });
return <><TeacherCompanion companion={companion} open={open} onOpen={(id) => { if (id) companion.selectAgent(id); setOpen(true); }}
return <><TeacherCompanion companion={companion} open={open} showWelcomes={showWelcomes} onOpen={(id) => { if (id) companion.selectAgent(id); setOpen(true); }}
onToggle={(id) => {
if (open && (!id || id === companion.selectedAgent?.teacher_id)) setOpen(false);
else { if (id) companion.selectAgent(id); setOpen(true); }
@@ -75,6 +75,26 @@ describe('grouped teacher introductions', () => {
}));
}
it('temporarily hides introductions without consuming them and keeps counting completed operation rounds', async () => {
api.catalog.mockResolvedValue({ items: agents });
const view = await mount();
await operation('one');
await operation('two');
const saved = { ...localStorage };
await act(async () => view.rerender(<Harness showWelcomes={false} />));
expect(screen.queryByTestId('teacher-welcomes')).not.toBeInTheDocument();
expect(screen.getByRole('button', { name: '与方法老师聊天' })).toBeVisible();
expect({ ...localStorage }).toEqual(saved);
await act(async () => view.rerender(<Harness />));
expect(screen.getByTestId('teacher-welcomes').querySelectorAll('.teacher-welcome-card')).toHaveLength(3);
await act(async () => view.rerender(<Harness showWelcomes={false} />));
await operation('three');
await act(async () => view.rerender(<Harness />));
expect(screen.queryByTestId('teacher-welcomes')).not.toBeInTheDocument();
expect(api.sendConversation).not.toHaveBeenCalled();
expect(api.checkIn).not.toHaveBeenCalled();
});
it('leaves introductions until the third completed operation round and preserves hover and unread receipts', async () => {
api.catalog.mockResolvedValue({ items: agents });
localStorage.setItem('makelore-teacher-presence:kid:seen', JSON.stringify(['keep-seen']));
@@ -715,6 +735,32 @@ describe('teacher presence and periodic guidance', () => {
expect(screen.queryByTestId('teacher-invitation')).not.toBeInTheDocument();
});
it('temporarily hides the legacy welcome without marking it dismissed', async () => {
api.config.mockResolvedValue({ enabled: true, definition: { ...definition, welcome_message: '欢迎一起创作' } });
const view = await mount();
expect(screen.getByTestId('teacher-invitation')).toHaveTextContent('欢迎一起创作');
const saved = { ...localStorage };
await act(async () => view.rerender(<Harness showWelcomes={false} />));
expect(screen.queryByTestId('teacher-presence')).not.toBeInTheDocument();
expect({ ...localStorage }).toEqual(saved);
await act(async () => view.rerender(<Harness />));
expect(screen.getByTestId('teacher-invitation')).toHaveTextContent('欢迎一起创作');
});
it('keeps real unread replies visible while welcomes are temporarily hidden', async () => {
api.config.mockResolvedValue({ enabled: true, definition: { ...definition, welcome_message: '欢迎一起创作' } });
api.list.mockResolvedValue({ items: [{ id: 'topic-project' }], lastSelectedTopicId: 'topic-project' });
api.read.mockResolvedValue(checkInTopic());
const view = await mount();
const saved = { ...localStorage };
await act(async () => view.rerender(<Harness showWelcomes={false} />));
expect(screen.getByTestId('teacher-invitation')).toHaveAttribute('data-bubble-kind', 'check-in');
expect(screen.getByTestId('teacher-invitation')).toHaveTextContent('排行榜');
expect(view.container.querySelector('.teacher-companion-unread')).toBeInTheDocument();
expect({ ...localStorage }).toEqual(saved);
expect(api.seenConversation).not.toHaveBeenCalled();
});
it('gives a real unread reply priority over the greeting and does not show the greeting after acknowledgment', async () => {
api.config.mockResolvedValue({ enabled: true, definition: { ...definition, welcome_message: '欢迎一起创作' } });
api.list.mockResolvedValue({ items: [{ id: 'topic-project' }], lastSelectedTopicId: 'topic-project' });