import { Component } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { Router, provideRouter } from '@angular/router'; import { of, throwError } from 'rxjs'; import { Mock, vi } from 'vitest'; import { UserList } from '../lists/lists.models'; import { ListsService } from '../lists/lists.service'; import { TemplatesService } from '../templates/templates.service'; import { AssistantChatComponent } from './assistant-chat.component'; import { AssistantService } from './assistant.service'; @Component({ standalone: true, template: '', }) class EmptyRouteComponent {} describe('AssistantChatComponent', () => { let assistantService: { chat: Mock }; let listsService: { getList: Mock }; let templatesService: { getTemplate: Mock }; let router: Router; beforeEach(async () => { assistantService = { chat: vi.fn().mockReturnValue( of({ message: { role: 'assistant', content: 'ok' }, actions: [], }), ), }; listsService = { getList: vi.fn(), }; templatesService = { getTemplate: vi.fn(), }; await TestBed.configureTestingModule({ imports: [AssistantChatComponent], providers: [ provideRouter([ { path: 'lists', component: EmptyRouteComponent }, { path: 'lists/:listId', component: EmptyRouteComponent }, { path: 'templates', component: EmptyRouteComponent }, { path: 'templates/:templateId', component: EmptyRouteComponent }, ]), { provide: AssistantService, useValue: assistantService }, { provide: ListsService, useValue: listsService }, { provide: TemplatesService, useValue: templatesService }, ], }).compileComponents(); router = TestBed.inject(Router); }); it('sends list detail context with the current list', async () => { const list = createList(); listsService.getList.mockReturnValue(of(list)); await router.navigateByUrl('/lists/list-1'); const fixture = TestBed.createComponent(AssistantChatComponent); const component = fixture.componentInstance as unknown as { draft: { set(value: string): void }; send(): void; }; component.draft.set('Was ist hier offen?'); component.send(); expect(listsService.getList).toHaveBeenCalledOnce(); expect(listsService.getList).toHaveBeenCalledWith('list-1'); expect(assistantService.chat).toHaveBeenCalledWith({ messages: [ { role: 'assistant', content: 'Hallo, ich bin dein Listify-Assistent. Was soll ich vorbereiten?', }, { role: 'user', content: 'Was ist hier offen?' }, ], context: { page: 'list_detail', route: '/lists/list-1', list, }, }); }); it('falls back to route context when list context loading fails', async () => { listsService.getList.mockReturnValue( throwError(() => new Error('not found')), ); await router.navigateByUrl('/lists/list-1'); const fixture = TestBed.createComponent(AssistantChatComponent); const component = fixture.componentInstance as unknown as { draft: { set(value: string): void }; send(): void; }; component.draft.set('Was ist hier offen?'); component.send(); expect(assistantService.chat).toHaveBeenCalledWith( expect.objectContaining({ context: { page: 'unknown', route: '/lists/list-1', }, }), ); }); it('sends overview context without loading a list', async () => { await router.navigateByUrl('/lists'); const fixture = TestBed.createComponent(AssistantChatComponent); const component = fixture.componentInstance as unknown as { draft: { set(value: string): void }; send(): void; }; component.draft.set('Welche Listen habe ich?'); component.send(); expect(listsService.getList).not.toHaveBeenCalled(); expect(assistantService.chat).toHaveBeenCalledWith( expect.objectContaining({ context: { page: 'lists_overview', route: '/lists', }, }), ); }); }); function createList(): UserList { return { id: 'list-1', ownerId: 'user-1', accessRole: 'owner', name: 'Einkauf', kind: 'shopping', items: [], collaborators: [], createdAt: '2026-06-12T00:00:00.000Z', updatedAt: '2026-06-12T00:00:00.000Z', }; }