@@ -4,28 +4,166 @@ import { MatIconTestingModule } from '@angular/material/icon/testing';
44import { BrowserAnimationsModule } from '@angular/platform-browser/animations' ;
55import { Angulartics2Module } from 'angulartics2' ;
66import { MarkdownService } from 'ngx-markdown' ;
7+ import { of , throwError } from 'rxjs' ;
8+ import { ConnectionsService } from 'src/app/services/connections.service' ;
9+ import { TableStateService } from 'src/app/services/table-state.service' ;
10+ import { TablesService } from 'src/app/services/tables.service' ;
711import { DbTableAiPanelComponent } from './db-table-ai-panel.component' ;
812
913describe ( 'DbTableAiPanelComponent' , ( ) => {
1014 let component : DbTableAiPanelComponent ;
1115 let fixture : ComponentFixture < DbTableAiPanelComponent > ;
16+ let tablesService : TablesService ;
17+ let tableStateService : TableStateService ;
1218
1319 const mockMarkdownService = {
1420 parse : vi . fn ( ) . mockReturnValue ( 'parsed markdown' ) ,
1521 } ;
1622
23+ const mockConnectionsService = {
24+ currentConnectionID : '12345678' ,
25+ } ;
26+
27+ const mockTablesService = {
28+ currentTableName : 'users' ,
29+ createAIthread : vi . fn ( ) ,
30+ requestAImessage : vi . fn ( ) ,
31+ } ;
32+
33+ const mockTableStateService = {
34+ aiPanelCast : of ( false ) ,
35+ handleViewAIpanel : vi . fn ( ) ,
36+ } ;
37+
1738 beforeEach ( async ( ) => {
1839 await TestBed . configureTestingModule ( {
1940 imports : [ Angulartics2Module . forRoot ( ) , DbTableAiPanelComponent , BrowserAnimationsModule , MatIconTestingModule ] ,
20- providers : [ provideHttpClient ( ) , { provide : MarkdownService , useValue : mockMarkdownService } ] ,
41+ providers : [
42+ provideHttpClient ( ) ,
43+ { provide : MarkdownService , useValue : mockMarkdownService } ,
44+ { provide : ConnectionsService , useValue : mockConnectionsService } ,
45+ { provide : TablesService , useValue : mockTablesService } ,
46+ { provide : TableStateService , useValue : mockTableStateService } ,
47+ ] ,
2148 } ) . compileComponents ( ) ;
2249
2350 fixture = TestBed . createComponent ( DbTableAiPanelComponent ) ;
2451 component = fixture . componentInstance ;
52+ tablesService = TestBed . inject ( TablesService ) ;
53+ tableStateService = TestBed . inject ( TableStateService ) ;
2554 fixture . detectChanges ( ) ;
2655 } ) ;
2756
2857 it ( 'should create' , ( ) => {
2958 expect ( component ) . toBeTruthy ( ) ;
3059 } ) ;
60+
61+ it ( 'should initialize with connection ID and table name' , ( ) => {
62+ expect ( component . connectionID ) . toBe ( '12345678' ) ;
63+ expect ( component . tableName ) . toBe ( 'users' ) ;
64+ } ) ;
65+
66+ it ( 'should have default AI request suggestions' , ( ) => {
67+ expect ( component . aiRequestSuggestions . length ) . toBeGreaterThan ( 0 ) ;
68+ expect ( component . aiRequestSuggestions ) . toContain ( 'How many records were created last month?' ) ;
69+ } ) ;
70+
71+ it ( 'should update character count on keydown' , ( ) => {
72+ component . message = 'Hello' ;
73+ const event = new KeyboardEvent ( 'keydown' , { key : 'a' } ) ;
74+ component . onKeydown ( event ) ;
75+ expect ( component . charactrsNumber ) . toBe ( 6 ) ;
76+ } ) ;
77+
78+ it ( 'should create thread on Enter key when no thread exists' , ( ) => {
79+ mockTablesService . createAIthread . mockReturnValue ( of ( { threadId : 'thread-123' , responseMessage : 'AI response' } ) ) ;
80+
81+ component . message = 'Test message' ;
82+ component . threadID = null ;
83+
84+ const event = new KeyboardEvent ( 'keydown' , { key : 'Enter' } ) ;
85+ Object . defineProperty ( event , 'preventDefault' , { value : vi . fn ( ) } ) ;
86+ component . onKeydown ( event ) ;
87+
88+ expect ( mockTablesService . createAIthread ) . toHaveBeenCalledWith ( '12345678' , 'users' , 'Test message' ) ;
89+ } ) ;
90+
91+ it ( 'should send message on Enter key when thread exists' , ( ) => {
92+ mockTablesService . requestAImessage . mockReturnValue ( of ( 'AI response' ) ) ;
93+
94+ component . message = 'Follow up message' ;
95+ component . threadID = 'existing-thread' ;
96+
97+ const event = new KeyboardEvent ( 'keydown' , { key : 'Enter' } ) ;
98+ Object . defineProperty ( event , 'preventDefault' , { value : vi . fn ( ) } ) ;
99+ component . onKeydown ( event ) ;
100+
101+ expect ( mockTablesService . requestAImessage ) . toHaveBeenCalledWith (
102+ '12345678' ,
103+ 'users' ,
104+ 'existing-thread' ,
105+ 'Follow up message' ,
106+ ) ;
107+ } ) ;
108+
109+ it ( 'should add user message to chain when creating thread' , ( ) => {
110+ mockTablesService . createAIthread . mockReturnValue ( of ( { threadId : 'thread-123' , responseMessage : 'AI response' } ) ) ;
111+
112+ component . message = 'User question' ;
113+ component . createThread ( ) ;
114+
115+ expect ( component . messagesChain [ 0 ] ) . toEqual ( {
116+ type : 'user' ,
117+ text : 'User question' ,
118+ } ) ;
119+ } ) ;
120+
121+ it ( 'should add AI response to chain after thread creation' , ( ) => {
122+ mockTablesService . createAIthread . mockReturnValue ( of ( { threadId : 'thread-123' , responseMessage : 'AI response' } ) ) ;
123+
124+ component . message = 'User question' ;
125+ component . createThread ( ) ;
126+
127+ expect ( component . threadID ) . toBe ( 'thread-123' ) ;
128+ expect ( component . messagesChain [ 1 ] ) . toEqual ( {
129+ type : 'ai' ,
130+ text : 'parsed markdown' ,
131+ } ) ;
132+ } ) ;
133+
134+ it ( 'should handle error when creating thread' , ( ) => {
135+ mockTablesService . createAIthread . mockReturnValue ( throwError ( ( ) => 'Error message' ) ) ;
136+
137+ component . message = 'User question' ;
138+ component . createThread ( ) ;
139+
140+ expect ( component . messagesChain [ 1 ] ) . toEqual ( {
141+ type : 'ai-error' ,
142+ text : 'Error message' ,
143+ } ) ;
144+ } ) ;
145+
146+ it ( 'should use suggested message when provided to createThread' , ( ) => {
147+ mockTablesService . createAIthread . mockReturnValue ( of ( { threadId : 'thread-123' , responseMessage : 'AI response' } ) ) ;
148+
149+ component . createThread ( 'Suggested question' ) ;
150+
151+ expect ( component . messagesChain [ 0 ] . text ) . toBe ( 'Suggested question' ) ;
152+ } ) ;
153+
154+ it ( 'should call handleViewAIpanel when closing' , ( ) => {
155+ component . handleClose ( ) ;
156+ expect ( mockTableStateService . handleViewAIpanel ) . toHaveBeenCalled ( ) ;
157+ } ) ;
158+
159+ it ( 'should clear message after sending' , ( ) => {
160+ mockTablesService . requestAImessage . mockReturnValue ( of ( 'AI response' ) ) ;
161+
162+ component . message = 'Test message' ;
163+ component . threadID = 'thread-123' ;
164+ component . sendMessage ( ) ;
165+
166+ expect ( component . message ) . toBe ( '' ) ;
167+ expect ( component . charactrsNumber ) . toBe ( 0 ) ;
168+ } ) ;
31169} ) ;
0 commit comments