150 lines
4.3 KiB
TypeScript
150 lines
4.3 KiB
TypeScript
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',
|
|
};
|
|
}
|