@@ -3,31 +3,35 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
33import { MatIconTestingModule } from '@angular/material/icon/testing' ;
44import { BrowserAnimationsModule } from '@angular/platform-browser/animations' ;
55import { Angulartics2Module } from 'angulartics2' ;
6- import { MarkdownService } from 'ngx-markdown ' ;
7- import { of , throwError } from 'rxjs ' ;
6+ import { of } from 'rxjs ' ;
7+ import { AiService } from 'src/app/services/ai.service ' ;
88import { ConnectionsService } from 'src/app/services/connections.service' ;
99import { TableStateService } from 'src/app/services/table-state.service' ;
1010import { TablesService } from 'src/app/services/tables.service' ;
1111import { DbTableAiPanelComponent } from './db-table-ai-panel.component' ;
1212
13+ async function * mockStream ( ...chunks : string [ ] ) : AsyncGenerator < string > {
14+ for ( const chunk of chunks ) {
15+ yield chunk ;
16+ }
17+ }
18+
1319describe ( 'DbTableAiPanelComponent' , ( ) => {
1420 let component : DbTableAiPanelComponent ;
1521 let fixture : ComponentFixture < DbTableAiPanelComponent > ;
16- let tablesService : TablesService ;
1722 let tableStateService : TableStateService ;
1823
19- const mockMarkdownService = {
20- parse : vi . fn ( ) . mockReturnValue ( 'parsed markdown' ) ,
21- } ;
22-
2324 const mockConnectionsService = {
2425 currentConnectionID : '12345678' ,
2526 } ;
2627
2728 const mockTablesService = {
2829 currentTableName : 'users' ,
29- createAIthread : vi . fn ( ) ,
30- requestAImessage : vi . fn ( ) ,
30+ } ;
31+
32+ const mockAiService : Partial < AiService > = {
33+ createThread : vi . fn ( ) ,
34+ sendMessage : vi . fn ( ) ,
3135 } ;
3236
3337 const mockTableStateService = {
@@ -41,16 +45,15 @@ describe('DbTableAiPanelComponent', () => {
4145 imports : [ Angulartics2Module . forRoot ( ) , DbTableAiPanelComponent , BrowserAnimationsModule , MatIconTestingModule ] ,
4246 providers : [
4347 provideHttpClient ( ) ,
44- { provide : MarkdownService , useValue : mockMarkdownService } ,
4548 { provide : ConnectionsService , useValue : mockConnectionsService } ,
4649 { provide : TablesService , useValue : mockTablesService } ,
50+ { provide : AiService , useValue : mockAiService } ,
4751 { provide : TableStateService , useValue : mockTableStateService } ,
4852 ] ,
4953 } ) . compileComponents ( ) ;
5054
5155 fixture = TestBed . createComponent ( DbTableAiPanelComponent ) ;
5256 component = fixture . componentInstance ;
53- tablesService = TestBed . inject ( TablesService ) ;
5457 tableStateService = TestBed . inject ( TableStateService ) ;
5558 fixture . detectChanges ( ) ;
5659 } ) ;
@@ -77,7 +80,10 @@ describe('DbTableAiPanelComponent', () => {
7780 } ) ;
7881
7982 it ( 'should create thread on Enter key when no thread exists' , ( ) => {
80- mockTablesService . createAIthread . mockReturnValue ( of ( { threadId : 'thread-123' , responseMessage : 'AI response' } ) ) ;
83+ ( mockAiService . createThread as ReturnType < typeof vi . fn > ) . mockResolvedValue ( {
84+ threadId : 'thread-123' ,
85+ stream : mockStream ( 'AI response' ) ,
86+ } ) ;
8187
8288 component . message = 'Test message' ;
8389 component . threadID = null ;
@@ -86,11 +92,16 @@ describe('DbTableAiPanelComponent', () => {
8692 Object . defineProperty ( event , 'preventDefault' , { value : vi . fn ( ) } ) ;
8793 component . onKeydown ( event ) ;
8894
89- expect ( mockTablesService . createAIthread ) . toHaveBeenCalledWith ( '12345678' , 'users' , 'Test message' ) ;
95+ expect ( mockAiService . createThread ) . toHaveBeenCalledWith (
96+ '12345678' ,
97+ 'users' ,
98+ 'Test message' ,
99+ expect . any ( AbortSignal ) ,
100+ ) ;
90101 } ) ;
91102
92103 it ( 'should send message on Enter key when thread exists' , ( ) => {
93- mockTablesService . requestAImessage . mockReturnValue ( of ( 'AI response' ) ) ;
104+ ( mockAiService . sendMessage as ReturnType < typeof vi . fn > ) . mockResolvedValue ( mockStream ( 'AI response' ) ) ;
94105
95106 component . message = 'Follow up message' ;
96107 component . threadID = 'existing-thread' ;
@@ -99,55 +110,65 @@ describe('DbTableAiPanelComponent', () => {
99110 Object . defineProperty ( event , 'preventDefault' , { value : vi . fn ( ) } ) ;
100111 component . onKeydown ( event ) ;
101112
102- expect ( mockTablesService . requestAImessage ) . toHaveBeenCalledWith (
113+ expect ( mockAiService . sendMessage ) . toHaveBeenCalledWith (
103114 '12345678' ,
104115 'users' ,
105116 'existing-thread' ,
106117 'Follow up message' ,
118+ expect . any ( AbortSignal ) ,
107119 ) ;
108120 } ) ;
109121
110- it ( 'should add user message to chain when creating thread' , ( ) => {
111- mockTablesService . createAIthread . mockReturnValue ( of ( { threadId : 'thread-123' , responseMessage : 'AI response' } ) ) ;
122+ it ( 'should add user message to chain when creating thread' , async ( ) => {
123+ ( mockAiService . createThread as ReturnType < typeof vi . fn > ) . mockResolvedValue ( {
124+ threadId : 'thread-123' ,
125+ stream : mockStream ( 'AI response' ) ,
126+ } ) ;
112127
113128 component . message = 'User question' ;
114- component . createThread ( ) ;
129+ await component . createThread ( ) ;
115130
116131 expect ( component . messagesChain [ 0 ] ) . toEqual ( {
117132 type : 'user' ,
118133 text : 'User question' ,
119134 } ) ;
120135 } ) ;
121136
122- it ( 'should add AI response to chain after thread creation' , ( ) => {
123- mockTablesService . createAIthread . mockReturnValue ( of ( { threadId : 'thread-123' , responseMessage : 'AI response' } ) ) ;
137+ it ( 'should add AI response to chain after thread creation' , async ( ) => {
138+ ( mockAiService . createThread as ReturnType < typeof vi . fn > ) . mockResolvedValue ( {
139+ threadId : 'thread-123' ,
140+ stream : mockStream ( 'AI response' ) ,
141+ } ) ;
124142
125143 component . message = 'User question' ;
126- component . createThread ( ) ;
144+ await component . createThread ( ) ;
127145
128146 expect ( component . threadID ) . toBe ( 'thread-123' ) ;
129147 expect ( component . messagesChain [ 1 ] ) . toEqual ( {
130148 type : 'ai' ,
131- text : 'parsed markdown ' ,
149+ text : 'AI response ' ,
132150 } ) ;
133151 } ) ;
134152
135- it ( 'should handle error when creating thread' , ( ) => {
136- mockTablesService . createAIthread . mockReturnValue ( throwError ( ( ) => 'Error message' ) ) ;
153+ it ( 'should handle error when creating thread' , async ( ) => {
154+ ( mockAiService . createThread as ReturnType < typeof vi . fn > ) . mockRejectedValue ( 'Error message' ) ;
137155
138156 component . message = 'User question' ;
139- component . createThread ( ) ;
157+ await component . createThread ( ) ;
140158
141159 expect ( component . messagesChain [ 1 ] ) . toEqual ( {
142160 type : 'ai-error' ,
143161 text : 'Error message' ,
144162 } ) ;
145163 } ) ;
146164
147- it ( 'should use suggested message when provided to createThread' , ( ) => {
148- mockTablesService . createAIthread . mockReturnValue ( of ( { threadId : 'thread-123' , responseMessage : 'AI response' } ) ) ;
165+ it ( 'should use suggested message when provided to createThread' , async ( ) => {
166+ ( mockAiService . createThread as ReturnType < typeof vi . fn > ) . mockResolvedValue ( {
167+ threadId : 'thread-123' ,
168+ stream : mockStream ( 'AI response' ) ,
169+ } ) ;
149170
150- component . createThread ( 'Suggested question' ) ;
171+ await component . createThread ( 'Suggested question' ) ;
151172
152173 expect ( component . messagesChain [ 0 ] . text ) . toBe ( 'Suggested question' ) ;
153174 } ) ;
@@ -157,12 +178,12 @@ describe('DbTableAiPanelComponent', () => {
157178 expect ( mockTableStateService . handleViewAIpanel ) . toHaveBeenCalled ( ) ;
158179 } ) ;
159180
160- it ( 'should clear message after sending' , ( ) => {
161- mockTablesService . requestAImessage . mockReturnValue ( of ( 'AI response' ) ) ;
181+ it ( 'should clear message after sending' , async ( ) => {
182+ ( mockAiService . sendMessage as ReturnType < typeof vi . fn > ) . mockResolvedValue ( mockStream ( 'AI response' ) ) ;
162183
163184 component . message = 'Test message' ;
164185 component . threadID = 'thread-123' ;
165- component . sendMessage ( ) ;
186+ await component . sendMessage ( ) ;
166187
167188 expect ( component . message ) . toBe ( '' ) ;
168189 expect ( component . charactrsNumber ) . toBe ( 0 ) ;
0 commit comments