From 84e891bef7b463009e135344fc03b6928902d255 Mon Sep 17 00:00:00 2001 From: Devlin Junker Date: Sat, 16 Sep 2023 15:44:44 -0700 Subject: finish unit tests Signed-off-by: Devlin Junker --- tests/javascript/unit/components/Sidebar.spec.ts | 49 ++++++++++- .../unit/components/SidebarFeedLinkActions.spec.ts | 95 ++++++++++++++++++++++ .../javascript/unit/services/feed.service.spec.ts | 35 ++++++++ .../unit/services/folder.service.spec.ts | 17 +++- 4 files changed, 193 insertions(+), 3 deletions(-) create mode 100644 tests/javascript/unit/components/SidebarFeedLinkActions.spec.ts (limited to 'tests') diff --git a/tests/javascript/unit/components/Sidebar.spec.ts b/tests/javascript/unit/components/Sidebar.spec.ts index 1eee5486a..9b28ab8a0 100644 --- a/tests/javascript/unit/components/Sidebar.spec.ts +++ b/tests/javascript/unit/components/Sidebar.spec.ts @@ -8,6 +8,12 @@ describe('Sidebar.vue', () => { let wrapper: Wrapper + const feeds = [{ + id: 1, title: 'first', + }, { + id: 2, title: 'second', folderId: 123, + }] + beforeAll(() => { const localVue = createLocalVue() wrapper = shallowMount(AppSidebar, { @@ -15,15 +21,22 @@ describe('Sidebar.vue', () => { mocks: { $store: { state: { - feeds: [], + feeds, folders: [], }, + getters: { + feeds, + }, dispatch: jest.fn(), }, }, }) }) + beforeEach(() => { + (wrapper.vm as any).$store.dispatch.mockReset() + }) + it('should initialize without showing AddFeed Component', () => { expect((wrapper.vm as any).$data.showAddFeed).toBeFalsy() }) @@ -51,6 +64,25 @@ describe('Sidebar.vue', () => { (wrapper.vm as any).closeShowAddFeed() expect(wrapper.vm.$data.showAddFeed).toBeFalsy() }) + + it('should call mark feed read for all feeds in state', () => { + window.confirm = jest.fn().mockReturnValue(true); + (wrapper.vm as any).markAllRead() + expect((wrapper.vm as any).$store.dispatch).toHaveBeenCalledTimes(2) + }) + + it('should call mark feed read for all feeds in state with matching folderId', () => { + window.confirm = jest.fn().mockReturnValue(true); + (wrapper.vm as any).markFolderRead({ id: 123 }) + expect((wrapper.vm as any).$store.dispatch).toHaveBeenCalledTimes(1) + }) + + it('should call disptch rename folder with response from user', () => { + const name = 'new name' + window.prompt = jest.fn().mockReturnValue(name); + (wrapper.vm as any).renameFolder({ id: 123 }) + expect((wrapper.vm as any).$store.dispatch).toHaveBeenCalledWith(ACTIONS.FOLDER_SET_NAME, { folder: { id: 123 }, name }) + }) }) describe('SideBarState', () => { @@ -126,6 +158,21 @@ describe('Sidebar.vue', () => { expect(topLevelNav).toEqual([feeds[0], ...folders]) }) + + it('should set pinned feeds at beginning top level nav with feeds and folders', () => { + const feeds: any[] = [{ name: 'feed1', id: 1 }, { name: 'feed2', id: 2, folderId: 123 }, { name: 'feed3', id: 3, pinned: true }] + const folders: any[] = [{ name: 'abc', id: 123 }, { name: 'xyz', id: 234 }] + const topLevelNav = (wrapper.vm.$options.computed?.topLevelNav as any).call({ + $store: { + getters: { + feeds, + folders, + }, + }, + }) + + expect(topLevelNav[0].name).toEqual('feed3') + }) }) // TODO: More Template Testing with https://test-utils.vuejs.org/guide/essentials/a-crash-course.html#adding-a-new-todo diff --git a/tests/javascript/unit/components/SidebarFeedLinkActions.spec.ts b/tests/javascript/unit/components/SidebarFeedLinkActions.spec.ts new file mode 100644 index 000000000..1a4ee6358 --- /dev/null +++ b/tests/javascript/unit/components/SidebarFeedLinkActions.spec.ts @@ -0,0 +1,95 @@ +import { ACTIONS } from '../../../../src/store' +import { Wrapper, shallowMount, createLocalVue } from '@vue/test-utils' + +import SidebarFeedLinkActions from '../../../../src/components/SidebarFeedLinkActions.vue' +import { FEED_UPDATE_MODE, FEED_ORDER } from '../../../../src/dataservices/feed.service' + +describe('SidebarFeedLinkActions.vue', () => { + 'use strict' + + let wrapper: Wrapper + + const feeds = [{ + id: 1, title: 'first', + }, { + id: 2, title: 'second', folderId: 123, + }] + + beforeAll(() => { + const localVue = createLocalVue() + wrapper = shallowMount(SidebarFeedLinkActions, { + localVue, + propsData: { + feedId: 1, + }, + mocks: { + $store: { + state: { + feeds, + folders: [], + }, + getters: { + feeds, + }, + dispatch: jest.fn(), + }, + }, + }) + }) + + beforeEach(() => { + (wrapper.vm as any).$store.dispatch.mockReset() + }) + + describe('User Actions', () => { + it('should dispatch message to store with feed object', () => { + (wrapper.vm as any).markRead() + + expect((wrapper.vm as any).$store.dispatch).toHaveBeenCalledWith(ACTIONS.FEED_MARK_READ, { feed: feeds[0] }) + }) + + it('should dispatch message to store with feed object and pinned', () => { + (wrapper.vm as any).setPinned(true) + + expect((wrapper.vm as any).$store.dispatch).toHaveBeenCalledWith(ACTIONS.FEED_SET_PINNED, { feed: feeds[0], pinned: true }) + }) + + it('should dispatch message to store with feed object and fullTextEnabled', () => { + (wrapper.vm as any).setOrdering(FEED_ORDER.NEWEST) + + expect((wrapper.vm as any).$store.dispatch).toHaveBeenCalledWith(ACTIONS.FEED_SET_ORDERING, { feed: feeds[0], ordering: FEED_ORDER.NEWEST }) + }) + + it('should dispatch message to store with feed object and fullTextEnabled', () => { + (wrapper.vm as any).setFullText(true) + + expect((wrapper.vm as any).$store.dispatch).toHaveBeenCalledWith(ACTIONS.FEED_SET_FULL_TEXT, { feed: feeds[0], fullTextEnabled: true }) + }) + + it('should dispatch message to store with feed object and new updateMode', () => { + (wrapper.vm as any).setUpdateMode(FEED_UPDATE_MODE.IGNORE) + + expect((wrapper.vm as any).$store.dispatch).toHaveBeenCalledWith(ACTIONS.FEED_SET_UPDATE_MODE, { feed: feeds[0], updateMode: FEED_UPDATE_MODE.IGNORE }) + }) + + it('should dispatch message to store with feed object on rename feed', () => { + window.prompt = jest.fn().mockReturnValue('test'); + + (wrapper.vm as any).rename() + + expect((wrapper.vm as any).$store.dispatch).toHaveBeenCalledWith(ACTIONS.FEED_SET_TITLE, { feed: feeds[0], title: 'test' }) + }) + + it('should dispatch message to store with feed object on delete feed', () => { + window.confirm = jest.fn().mockReturnValue(true); + + (wrapper.vm as any).deleteFeed() + + expect((wrapper.vm as any).$store.dispatch).toHaveBeenCalledWith(ACTIONS.FEED_DELETE, { feed: feeds[0] }) + }) + }) + + afterEach(() => { + jest.clearAllMocks() + }) +}) diff --git a/tests/javascript/unit/services/feed.service.spec.ts b/tests/javascript/unit/services/feed.service.spec.ts index 5f0c058cd..a40d296e5 100644 --- a/tests/javascript/unit/services/feed.service.spec.ts +++ b/tests/javascript/unit/services/feed.service.spec.ts @@ -31,4 +31,39 @@ describe('feed.service.ts', () => { expect(args[1].url).toEqual('http://example.com') }) }) + + describe('markRead', () => { + it('should call POST with item id + read in URL and highestItemId param', async () => { + await FeedService.markRead({ feedId: 1, highestItemId: 234 }) + + expect(axios.post).toBeCalled() + const args = (axios.post as any).mock.calls[0] + + expect(args[0]).toContain('1/read') + expect(args[1].highestItemId).toEqual(234) + }) + }) + + describe('updateFeed', () => { + it('should call PATCH with item id in URL and title param', async () => { + await FeedService.updateFeed({ feedId: 1, title: 'abc' }) + + expect(axios.patch).toBeCalled() + const args = (axios.patch as any).mock.calls[0] + + expect(args[0]).toContain('1') + expect(args[1].title).toEqual('abc') + }) + }) + + describe('deleteFeed', () => { + it('should call DELETE with item id in URL ', async () => { + await FeedService.deleteFeed({ feedId: 1 }) + + expect(axios.delete).toBeCalled() + const args = (axios.delete as any).mock.calls[0] + + expect(args[0]).toContain('1') + }) + }) }) diff --git a/tests/javascript/unit/services/folder.service.spec.ts b/tests/javascript/unit/services/folder.service.spec.ts index 6577df2c8..19b601ee4 100644 --- a/tests/javascript/unit/services/folder.service.spec.ts +++ b/tests/javascript/unit/services/folder.service.spec.ts @@ -8,7 +8,8 @@ describe('folder.service.ts', () => { beforeEach(() => { (axios.get as any).mockReset(); - (axios.post as any).mockReset() + (axios.post as any).mockReset(); + (axios.delete as any).mockReset() }) describe('fetchAllFolders', () => { @@ -22,7 +23,7 @@ describe('folder.service.ts', () => { }) describe('createFolder', () => { - it('should call POST with item id in URL and read param', async () => { + it('should call POST with folderName param', async () => { await FolderService.createFolder({ name: 'abc' }) expect(axios.post).toBeCalled() @@ -32,6 +33,18 @@ describe('folder.service.ts', () => { }) }) + describe('renameFolder', () => { + it('should call POST with item id in URL and folderName param', async () => { + await FolderService.renameFolder({ id: 123, name: 'abc' }) + + expect(axios.post).toBeCalled() + const args = (axios.post as any).mock.calls[0] + + expect(args[0]).toContain('123/rename') + expect(args[1].folderName).toEqual('abc') + }) + }) + describe('deleteFolder', () => { it('should call POST with item id in URL and read param', async () => { await FolderService.deleteFolder({ id: 123 }) -- cgit v1.2.3