11import { ComponentFixture , TestBed , waitForAsync } from '@angular/core/testing'
2- import { IgxChatComponent } from './chat.component'
2+ import { IgxChatComponent , IgxChatMessageContextDirective , NgChatTemplates } from './chat.component'
33import { Component , signal , TemplateRef , viewChild } from '@angular/core' ;
4- import type { IgcChatMessage } from 'igniteui-webcomponents' ;
4+ import type { IgcChatComponent , IgcChatMessage , IgcTextareaComponent } from 'igniteui-webcomponents' ;
55
66describe ( 'Chat wrapper' , ( ) => {
7- function getShadowRoot ( element : HTMLElement ) {
8- return element . shadowRoot ;
9- }
107
118 let chatComponent : IgxChatComponent ;
12- let chatElement : HTMLElement ;
9+ let chatElement : IgcChatComponent ;
1310 let fixture : ComponentFixture < IgxChatComponent > ;
1411
1512 beforeEach ( waitForAsync ( ( ) => {
@@ -21,7 +18,7 @@ describe('Chat wrapper', () => {
2118 beforeEach ( ( ) => {
2219 fixture = TestBed . createComponent ( IgxChatComponent ) ;
2320 chatComponent = fixture . componentInstance ;
24- chatElement = ( fixture . nativeElement as HTMLElement ) . querySelector ( 'igc-chat' ) ;
21+ chatElement = getChatElement ( fixture ) ;
2522 fixture . detectChanges ( ) ;
2623 } )
2724
@@ -43,9 +40,10 @@ describe('Chat wrapper', () => {
4340 fixture . detectChanges ( ) ;
4441 await fixture . whenStable ( ) ;
4542
46- const messageElement = getShadowRoot ( chatElement ) . querySelector < HTMLElement > ( 'igc-chat-message' ) ;
43+
44+ const messageElement = getChatMessages ( chatElement ) [ 0 ] ;
4745 expect ( messageElement ) . toBeDefined ( ) ;
48- expect ( getShadowRoot ( messageElement ) . textContent . trim ( ) ) . toEqual ( chatComponent . messages ( ) [ 0 ] . text ) ;
46+ expect ( getChatMessageDOM ( messageElement ) . textContent . trim ( ) ) . toEqual ( chatComponent . messages ( ) [ 0 ] . text ) ;
4947 } ) ;
5048
5149 it ( 'correct bindings for draft message' , async ( ) => {
@@ -54,29 +52,25 @@ describe('Chat wrapper', () => {
5452 fixture . detectChanges ( ) ;
5553 await fixture . whenStable ( ) ;
5654
57- const textarea = getShadowRoot ( getShadowRoot ( chatElement ) . querySelector ( 'igc-chat-input' ) ) . querySelector ( 'igc-textarea' ) ;
55+ const textarea = getChatInput ( chatElement ) ;
5856 expect ( textarea . value ) . toEqual ( chatComponent . draftMessage ( ) . text ) ;
5957 } ) ;
6058} ) ;
6159
6260describe ( 'Chat templates' , ( ) => {
63- function getShadowRoot ( element : HTMLElement ) {
64- return element . shadowRoot ;
65- }
66-
6761 let fixture : ComponentFixture < ChatTemplatesBed > ;
68- let chatElement : HTMLElement ;
62+ let chatElement : IgcChatComponent ;
6963
7064 beforeEach ( waitForAsync ( ( ) => {
7165 TestBed . configureTestingModule ( {
72- imports : [ IgxChatComponent , ChatTemplatesBed ]
66+ imports : [ IgxChatComponent , IgxChatMessageContextDirective , ChatTemplatesBed ]
7367 } ) . compileComponents ( ) ;
7468 } ) ) ;
7569
7670 beforeEach ( ( ) => {
7771 fixture = TestBed . createComponent ( ChatTemplatesBed ) ;
7872 fixture . detectChanges ( ) ;
79- chatElement = ( fixture . nativeElement as HTMLElement ) . querySelector ( 'igc-chat' ) ;
73+ chatElement = getChatElement ( fixture ) ;
8074 } ) ;
8175
8276 it ( 'has correct initially bound template' , async ( ) => {
@@ -87,20 +81,49 @@ describe('Chat templates', () => {
8781 // This is so we don't explicitly invoke `viewRef.detectChanges()` inside the returned closure
8882 // from the wrapper's `_createTemplateRenderer` call.
8983 fixture . detectChanges ( ) ;
90- expect ( getShadowRoot ( getShadowRoot ( chatElement ) . querySelector ( 'igc-chat-message' ) ) . textContent . trim ( ) )
84+ expect ( getChatMessageDOM ( getChatMessages ( chatElement ) [ 0 ] ) . textContent . trim ( ) )
85+ . toEqual ( `Your message: ${ fixture . componentInstance . messages ( ) [ 0 ] . text } ` ) ;
86+ } ) ;
87+ } ) ;
88+
89+ describe ( 'Chat dynamic templates binding' , ( ) => {
90+ let fixture : ComponentFixture < ChatDynamicTemplatesBed > ;
91+ let chatElement : IgcChatComponent ;
92+
93+ beforeEach ( waitForAsync ( ( ) => {
94+ TestBed . configureTestingModule ( {
95+ imports : [ IgxChatComponent , IgxChatMessageContextDirective , ChatDynamicTemplatesBed ]
96+ } ) . compileComponents ( ) ;
97+ } ) ) ;
98+
99+ beforeEach ( ( ) => {
100+ fixture = TestBed . createComponent ( ChatDynamicTemplatesBed ) ;
101+ fixture . detectChanges ( ) ;
102+ chatElement = getChatElement ( fixture ) ;
103+ } ) ;
104+
105+ it ( 'supports late binding' , async ( ) => {
106+ fixture . componentInstance . bindTemplates ( ) ;
107+ fixture . detectChanges ( ) ;
108+
109+ await fixture . whenStable ( ) ;
110+ fixture . detectChanges ( ) ;
111+
112+ expect ( getChatMessageDOM ( getChatMessages ( chatElement ) [ 0 ] ) . textContent . trim ( ) )
91113 . toEqual ( `Your message: ${ fixture . componentInstance . messages ( ) [ 0 ] . text } ` ) ;
92114 } ) ;
115+
93116} ) ;
94117
95118
96119@Component ( {
97120 template : `
98121 <igx-chat [messages]="messages()" [templates]="{messageContent: messageTemplate()}"/>
99- <ng-template #message let-message>
122+ <ng-template igxChatMessageContext #message let-message>
100123 <h3>Your message: {{ message.text }}</h3>
101124 </ng-template>
102125 ` ,
103- imports : [ IgxChatComponent ]
126+ imports : [ IgxChatComponent , IgxChatMessageContextDirective ]
104127} )
105128class ChatTemplatesBed {
106129 public messages = signal < IgcChatMessage [ ] > ( [ {
@@ -110,3 +133,45 @@ class ChatTemplatesBed {
110133 } ] ) ;
111134 public messageTemplate = viewChild . required < TemplateRef < any > > ( 'message' ) ;
112135}
136+
137+ @Component ( {
138+ template : `
139+ <igx-chat [messages]="messages()" [templates]="templates()" />
140+ <ng-template igxChatMessageContext #message let-message>
141+ <h3>Your message: {{ message.text }}</h3>
142+ </ng-template>
143+ ` ,
144+ imports : [ IgxChatComponent , IgxChatMessageContextDirective ]
145+ } )
146+ class ChatDynamicTemplatesBed {
147+ public templates = signal < NgChatTemplates | null > ( null ) ;
148+ public messages = signal < IgcChatMessage [ ] > ( [ {
149+ id : '1' ,
150+ sender : 'user' ,
151+ text : 'Hello world'
152+ } ] ) ;
153+ public messageTemplate = viewChild . required < TemplateRef < any > > ( 'message' ) ;
154+
155+ public bindTemplates ( ) : void {
156+ this . templates . set ( {
157+ messageContent : this . messageTemplate ( )
158+ } ) ;
159+ }
160+ }
161+
162+ function getChatElement < T > ( fixture : ComponentFixture < T > ) : IgcChatComponent {
163+ const nativeElement = fixture . nativeElement as HTMLElement ;
164+ return nativeElement . querySelector ( 'igc-chat' ) ;
165+ }
166+
167+ function getChatInput ( chat : IgcChatComponent ) : IgcTextareaComponent {
168+ return chat . renderRoot . querySelector ( 'igc-chat-input' ) . shadowRoot . querySelector ( 'igc-textarea' ) ;
169+ }
170+
171+ function getChatMessages ( chat : IgcChatComponent ) : HTMLElement [ ] {
172+ return Array . from ( chat . renderRoot . querySelectorAll ( 'igc-chat-message' ) ) ;
173+ }
174+
175+ function getChatMessageDOM ( message : HTMLElement ) {
176+ return message . shadowRoot ;
177+ }
0 commit comments