From 1fa400f7d9c09d59f39866f20292013ef18abf3d Mon Sep 17 00:00:00 2001 From: Oksana Volodkevych Date: Fri, 11 Apr 2025 17:02:04 +0200 Subject: [PATCH 1/3] fix: replaced icon for history and added tests --- .../src/client/features/history.test.ts | 157 ++++++++++++++++++ chat-client/src/client/mynahUi.test.ts | 27 +++ chat-client/src/client/mynahUi.ts | 2 +- 3 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 chat-client/src/client/features/history.test.ts diff --git a/chat-client/src/client/features/history.test.ts b/chat-client/src/client/features/history.test.ts new file mode 100644 index 0000000000..28d8c30afb --- /dev/null +++ b/chat-client/src/client/features/history.test.ts @@ -0,0 +1,157 @@ +import { DetailedList, MynahUI } from '@aws/mynah-ui' +import { Messager } from '../messager' +import sinon = require('sinon') +import { ChatHistoryList } from './history' +import { ListConversationsResult } from '@aws/language-server-runtimes-types' +import * as assert from 'assert' +import { DetailedListSheetProps } from '@aws/mynah-ui/dist/components/detailed-list/detailed-list-sheet' + +describe('history', () => { + let mynahUi: MynahUI + let messager: Messager + let openDetailedListStub: sinon.SinonStub + let chatHistoryList: ChatHistoryList + + beforeEach(() => { + mynahUi = { + openDetailedList: sinon.stub(), + } as unknown as MynahUI + openDetailedListStub = mynahUi.openDetailedList as sinon.SinonStub + + messager = { + onListConversations: sinon.stub(), + onConversationClick: sinon.stub(), + } as unknown as Messager + + chatHistoryList = new ChatHistoryList(mynahUi, messager) + }) + + afterEach(() => { + sinon.restore() + }) + + it('show opens detailed list if called the first time', () => { + const mockParams: ListConversationsResult = { + header: { title: 'test title' }, + list: [ + { + groupName: 'group', + icon: 'not_existing', + items: [ + { + id: 'i1', + icon: 'chat', + description: 'desc', + actions: [ + { + id: 'a1', + text: 'delete', + icon: 'trash', + }, + ], + }, + ], + }, + ], + filterOptions: [ + { + id: '1', + type: 'textinput', + icon: 'search', + }, + ], + } + + chatHistoryList.show(mockParams) + + sinon.assert.calledOnce(openDetailedListStub) + const arg = openDetailedListStub.getCall(0).args[0] as DetailedListSheetProps + assert.equal(arg.tabId, '') + assert.equal(arg.detailedList.header, mockParams.header) + assert.deepEqual(arg.detailedList.filterOptions, [ + { + ...mockParams.filterOptions?.[0], + autoFocus: true, + }, + ]) + assert.deepEqual(arg.detailedList.list, [ + { + groupName: mockParams.list?.[0].groupName, + icon: undefined, + children: mockParams.list?.[0].items, + }, + ]) + }) + it('show updates detailed list if called the second time', () => { + const mockParams: ListConversationsResult = { + header: { title: 'test title' }, + list: [ + { + groupName: 'group', + items: [ + { + id: 'i1', + }, + ], + }, + ], + } + + const updateStub = sinon.stub() + openDetailedListStub.returns({ + update: updateStub, + close: sinon.stub(), + changeTarget: sinon.stub(), + getTargetElementId: sinon.stub(), + }) + + // First call to show + chatHistoryList.show(mockParams) + + // Second call to show + const updatedMockParams: ListConversationsResult = { + list: [ + { + groupName: 'group', + items: [ + { + id: 'i2', + }, + ], + }, + ], + } + chatHistoryList.show(updatedMockParams) + + sinon.assert.calledOnce(openDetailedListStub) + sinon.assert.calledOnce(updateStub) + const updateArg = updateStub.getCall(0).args[0] as DetailedList + assert.equal(updateArg.list?.[0].children?.[0].id, updatedMockParams.list[0].items?.[0].id) + }) + it('show opens detailed list if called after close', () => { + const mockParams: ListConversationsResult = { + header: { title: 'test title' }, + list: [ + { + groupName: 'group', + items: [ + { + id: 'i1', + }, + ], + }, + ], + } + + // First call to show + chatHistoryList.show(mockParams) + + // Close the list + chatHistoryList.close() + + // Call show again + chatHistoryList.show(mockParams) + + sinon.assert.calledTwice(openDetailedListStub) + }) +}) diff --git a/chat-client/src/client/mynahUi.test.ts b/chat-client/src/client/mynahUi.test.ts index bfebabf77e..f2e39efb7d 100644 --- a/chat-client/src/client/mynahUi.test.ts +++ b/chat-client/src/client/mynahUi.test.ts @@ -243,6 +243,33 @@ describe('MynahUI', () => { }) }) }) + + describe('conversationClicked result', () => { + it('should list conversarions if successfully deleted conversation', () => { + const listConversationsSpy = sinon.spy(messager, 'onListConversations') + + // Simulate a successful conversation deletion + inboundChatApi.conversationClicked({ + success: true, + action: 'delete', + id: 'test-conversation-id', + }) + + sinon.assert.calledOnce(listConversationsSpy) + }) + it('should not list conversarions if conversartion click processing failed', () => { + const listConversationsSpy = sinon.spy(messager, 'onListConversations') + + // Simulate a successful conversation deletion + inboundChatApi.conversationClicked({ + success: false, + action: 'delete', + id: 'test-conversation-id', + }) + + sinon.assert.neverCalledWith(listConversationsSpy) + }) + }) }) describe('withAdapter', () => { diff --git a/chat-client/src/client/mynahUi.ts b/chat-client/src/client/mynahUi.ts index c93d69966d..686f21fa70 100644 --- a/chat-client/src/client/mynahUi.ts +++ b/chat-client/src/client/mynahUi.ts @@ -360,7 +360,7 @@ export const createMynahUi = ( tabBarButtons: [ { id: ChatHistory.TabBarButtonId, - icon: MynahIcons.COMMENT, + icon: MynahIcons.HISTORY, description: 'View chat history', }, ], From f32fb791b31756ca8689f9a4e830c475bc872170 Mon Sep 17 00:00:00 2001 From: Oksana Volodkevych Date: Fri, 11 Apr 2025 17:10:52 +0200 Subject: [PATCH 2/3] chore: updated version ov mynah-ui and removed unneeded tabId setting to empty --- chat-client/package.json | 2 +- chat-client/src/client/features/history.test.ts | 1 - chat-client/src/client/features/history.ts | 1 - chat-client/src/client/mynahUi.test.ts | 2 +- package-lock.json | 8 ++++---- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/chat-client/package.json b/chat-client/package.json index 488cce0319..8db6d1eedc 100644 --- a/chat-client/package.json +++ b/chat-client/package.json @@ -23,7 +23,7 @@ "dependencies": { "@aws/chat-client-ui-types": "^0.1.13", "@aws/language-server-runtimes-types": "^0.1.11", - "@aws/mynah-ui": "^4.28.0" + "@aws/mynah-ui": "^4.30.1" }, "devDependencies": { "@types/jsdom": "^21.1.6", diff --git a/chat-client/src/client/features/history.test.ts b/chat-client/src/client/features/history.test.ts index 28d8c30afb..44cd9d6974 100644 --- a/chat-client/src/client/features/history.test.ts +++ b/chat-client/src/client/features/history.test.ts @@ -66,7 +66,6 @@ describe('history', () => { sinon.assert.calledOnce(openDetailedListStub) const arg = openDetailedListStub.getCall(0).args[0] as DetailedListSheetProps - assert.equal(arg.tabId, '') assert.equal(arg.detailedList.header, mockParams.header) assert.deepEqual(arg.detailedList.filterOptions, [ { diff --git a/chat-client/src/client/features/history.ts b/chat-client/src/client/features/history.ts index ac586c0ad1..b4e0055016 100644 --- a/chat-client/src/client/features/history.ts +++ b/chat-client/src/client/features/history.ts @@ -41,7 +41,6 @@ export class ChatHistoryList { this.historyDetailedList.update(detailedList) } else { this.historyDetailedList = this.mynahUi.openDetailedList({ - tabId: '', // TODO: remove after MynahUI is changed to remove the property detailedList: detailedList, events: { onFilterValueChange: this.onFilterValueChange, diff --git a/chat-client/src/client/mynahUi.test.ts b/chat-client/src/client/mynahUi.test.ts index f2e39efb7d..6a77b10bba 100644 --- a/chat-client/src/client/mynahUi.test.ts +++ b/chat-client/src/client/mynahUi.test.ts @@ -257,7 +257,7 @@ describe('MynahUI', () => { sinon.assert.calledOnce(listConversationsSpy) }) - it('should not list conversarions if conversartion click processing failed', () => { + it('should not list conversarions if conversartion click processing failed', () => { const listConversationsSpy = sinon.spy(messager, 'onListConversations') // Simulate a successful conversation deletion diff --git a/package-lock.json b/package-lock.json index db6b6eac61..e3ec31b7db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -246,7 +246,7 @@ "dependencies": { "@aws/chat-client-ui-types": "^0.1.13", "@aws/language-server-runtimes-types": "^0.1.11", - "@aws/mynah-ui": "^4.28.0" + "@aws/mynah-ui": "^4.30.1" }, "devDependencies": { "@types/jsdom": "^21.1.6", @@ -7544,9 +7544,9 @@ "link": true }, "node_modules/@aws/mynah-ui": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/@aws/mynah-ui/-/mynah-ui-4.29.0.tgz", - "integrity": "sha512-+oEUULPEYLTBU0HdJlmTl++mpkr02qj/j0gyHugoMLrZH9UIDTnedbi1cNolpmvGOYOhVi6hYPC7lWT/yhgYZw==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@aws/mynah-ui/-/mynah-ui-4.30.1.tgz", + "integrity": "sha512-ZBtvmHYjlJXzIUCeDmNu1cFfJyO86S/+UCuM/LFbAV5mf4Qm1o8i0Gmpw/4ngKx3ZXdFGnVT1Iq2bCGSYhuoSw==", "hasInstallScript": true, "license": "Apache License 2.0", "dependencies": { From 4ef9561cc07e859094650da5a568d301160f4195 Mon Sep 17 00:00:00 2001 From: Oksana Volodkevych Date: Fri, 11 Apr 2025 17:12:43 +0200 Subject: [PATCH 3/3] chore: updated comments --- chat-client/src/client/mynahUi.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chat-client/src/client/mynahUi.test.ts b/chat-client/src/client/mynahUi.test.ts index 6a77b10bba..bd7ca2134d 100644 --- a/chat-client/src/client/mynahUi.test.ts +++ b/chat-client/src/client/mynahUi.test.ts @@ -248,7 +248,7 @@ describe('MynahUI', () => { it('should list conversarions if successfully deleted conversation', () => { const listConversationsSpy = sinon.spy(messager, 'onListConversations') - // Simulate a successful conversation deletion + // Successful conversation deletion inboundChatApi.conversationClicked({ success: true, action: 'delete', @@ -260,7 +260,7 @@ describe('MynahUI', () => { it('should not list conversarions if conversartion click processing failed', () => { const listConversationsSpy = sinon.spy(messager, 'onListConversations') - // Simulate a successful conversation deletion + // Unsuccessful conversation deletion inboundChatApi.conversationClicked({ success: false, action: 'delete',