diff options
author | Devlin Junker <devlin.junker@gmail.com> | 2023-08-26 22:31:24 -0700 |
---|---|---|
committer | Benjamin Brahmer <info@b-brahmer.de> | 2023-08-28 07:03:07 +0200 |
commit | 83f99debaa1a6bfde88b62e43e6a0852ce928063 (patch) | |
tree | 40b7fa5d8ef9d67071d79885fbf34a7c2697a992 | |
parent | bb154d0a49d30932bb8b2aedfbcbf34f3aeee46c (diff) |
basic unit tests
Signed-off-by: Devlin Junker <devlin.junker@gmail.com>
13 files changed, 147 insertions, 34 deletions
diff --git a/src/components/FeedItemDisplayList.vue b/src/components/FeedItemDisplayList.vue index 11be6266a..f7ba8d3ab 100644 --- a/src/components/FeedItemDisplayList.vue +++ b/src/components/FeedItemDisplayList.vue @@ -5,7 +5,7 @@ <template #icon> <FilterIcon /> </template> - <NcActionButton v-if="config.unreadFilter" @click="toggleFilter(unreadFilter)"> + <NcActionButton v-if="cfg.unreadFilter" @click="toggleFilter(unreadFilter)"> <template #default> {{ t("news", "Unread") }} </template> @@ -14,7 +14,7 @@ <EyeCheckIcon v-if="filter === unreadFilter" /> </template> </NcActionButton> - <NcActionButton v-if="config.starFilter" @click="toggleFilter(starFilter)"> + <NcActionButton v-if="cfg.starFilter" @click="toggleFilter(starFilter)"> <template #default> {{ t("news", "Starred") }} </template> @@ -45,6 +45,7 @@ <script lang="ts"> import Vue from 'vue' +import _ from 'lodash' import FilterIcon from 'vue-material-design-icons/Filter.vue' import StarIcon from 'vue-material-design-icons/Star.vue' @@ -61,6 +62,11 @@ import FeedItemDisplay from './FeedItemDisplay.vue' import { FeedItem } from '../types/FeedItem' +const DEFAULT_DISPLAY_LIST_CONFIG = { + starFilter: true, + unreadFilter: true, +} + export default Vue.extend({ components: { VirtualScroll, @@ -86,10 +92,7 @@ export default Vue.extend({ config: { type: Object, default: () => { - return { - unreadFilter: true, - starFilter: true, - } + return DEFAULT_DISPLAY_LIST_CONFIG }, }, }, @@ -118,6 +121,9 @@ export default Vue.extend({ reachedEnd(): boolean { return this.mounted && this.$store.state.items.allItemsLoaded[this.fetchKey] === true }, + cfg() { + return _.defaults({ ...this.config }, DEFAULT_DISPLAY_LIST_CONFIG) + }, }, mounted() { this.mounted = true diff --git a/src/components/Sidebar.vue b/src/components/Sidebar.vue index 9a3f97bfb..eedead3b0 100644 --- a/src/components/Sidebar.vue +++ b/src/components/Sidebar.vue @@ -149,6 +149,8 @@ import NcAppNavigationNewItem from '@nextcloud/vue/dist/Components/NcAppNavigati import NcCounterBubble from '@nextcloud/vue/dist/Components/NcCounterBubble.js' import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js' +import RssIcon from 'vue-material-design-icons/Rss.vue' + import { ROUTES } from '../routes' import { ACTIONS, AppState } from '../store' @@ -179,6 +181,7 @@ export default Vue.extend({ NcCounterBubble, NcActionButton, AddFeed, + RssIcon, }, data: () => { return { diff --git a/src/components/Explore.vue b/src/components/routes/Explore.vue index 067dd61b3..5edca3dfe 100644 --- a/src/components/Explore.vue +++ b/src/components/routes/Explore.vue @@ -38,10 +38,10 @@ import NcButton from '@nextcloud/vue/dist/Components/NcButton.js' import axios from '@nextcloud/axios' import * as router from '@nextcloud/router' -import AddFeed from './AddFeed.vue' +import AddFeed from '../AddFeed.vue' -import { ExploreSite } from '../types/ExploreSite' -import { Feed } from '../types/Feed' +import { ExploreSite } from '../../types/ExploreSite' +import { Feed } from '../../types/Feed' const ExploreComponent = Vue.extend({ components: { diff --git a/src/components/Feed.vue b/src/components/routes/Feed.vue index 33c5ed6dd..6f8f9c922 100644 --- a/src/components/Feed.vue +++ b/src/components/routes/Feed.vue @@ -17,11 +17,11 @@ import { mapState } from 'vuex' import NcCounterBubble from '@nextcloud/vue/dist/Components/NcCounterBubble.js' -import FeedItemDisplayList from './FeedItemDisplayList.vue' +import FeedItemDisplayList from '../FeedItemDisplayList.vue' -import { FeedItem } from '../types/FeedItem' -import { ACTIONS, MUTATIONS } from '../store' -import { Feed } from '../types/Feed' +import { FeedItem } from '../../types/FeedItem' +import { ACTIONS, MUTATIONS } from '../../store' +import { Feed } from '../../types/Feed' export default Vue.extend({ components: { @@ -52,7 +52,6 @@ export default Vue.extend({ this.$store.commit(MUTATIONS.SET_SELECTED_ITEM, { id: undefined }) this.fetchMore() this.$watch(() => this.$route.params, this.fetchMore) - }, methods: { async fetchMore() { diff --git a/src/components/Starred.vue b/src/components/routes/Starred.vue index 3d5845484..d3df5a89f 100644 --- a/src/components/Starred.vue +++ b/src/components/routes/Starred.vue @@ -9,7 +9,7 @@ <FeedItemDisplayList :items="starred" :fetch-key="'starred'" - :config="{ unreadFilter: true }" + :config="{ starFilter: false }" @load-more="fetchMore()" /> </div> </template> @@ -20,10 +20,10 @@ import { mapState } from 'vuex' import NcCounterBubble from '@nextcloud/vue/dist/Components/NcCounterBubble.js' -import FeedItemDisplayList from './FeedItemDisplayList.vue' +import FeedItemDisplayList from '../FeedItemDisplayList.vue' -import { FeedItem } from '../types/FeedItem' -import { ACTIONS, MUTATIONS } from '../store' +import { FeedItem } from '../../types/FeedItem' +import { ACTIONS, MUTATIONS } from '../../store' export default Vue.extend({ components: { diff --git a/src/components/Unread.vue b/src/components/routes/Unread.vue index d012ca43b..230a8ea04 100644 --- a/src/components/Unread.vue +++ b/src/components/routes/Unread.vue @@ -10,7 +10,7 @@ <FeedItemDisplayList v-if="unread()" :items="unread()" :fetch-key="'unread'" - :config="{ starFilter: true }" + :config="{ unreadFilter: false }" @load-more="fetchMore()" /> </div> </template> @@ -21,10 +21,10 @@ import { mapState } from 'vuex' import NcCounterBubble from '@nextcloud/vue/dist/Components/NcCounterBubble.js' -import FeedItemDisplayList from './FeedItemDisplayList.vue' +import FeedItemDisplayList from '../FeedItemDisplayList.vue' -import { FeedItem } from '../types/FeedItem' -import { ACTIONS, MUTATIONS } from '../store' +import { FeedItem } from '../../types/FeedItem' +import { ACTIONS, MUTATIONS } from '../../store' type UnreadItemState = { // need cache so we aren't always removing items when they get read diff --git a/src/routes/index.ts b/src/routes/index.ts index 0a67042b7..fb0f7742a 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -1,15 +1,15 @@ import VueRouter from 'vue-router' -import ExplorePanel from '../components/Explore.vue' -import StarredPanel from '../components/Starred.vue' -import UnreadPanel from '../components/Unread.vue' -import FeedPanel from '../components/Feed.vue' +import ExplorePanel from '../components/routes/Explore.vue' +import StarredPanel from '../components/routes/Starred.vue' +import UnreadPanel from '../components/routes/Unread.vue' +import FeedPanel from '../components/routes/Feed.vue' export const ROUTES = { EXPLORE: 'explore', STARRED: 'starred', UNREAD: 'unread', - FEED: 'feeed', + FEED: 'feed', } const getInitialRoute = function() { diff --git a/tests/javascript/unit/components/Explore.spec.ts b/tests/javascript/unit/components/routes/Explore.spec.ts index b2ab052d5..04c7d6508 100644 --- a/tests/javascript/unit/components/Explore.spec.ts +++ b/tests/javascript/unit/components/routes/Explore.spec.ts @@ -3,7 +3,7 @@ import { shallowMount, createLocalVue } from '@vue/test-utils' import * as router from '@nextcloud/router' -import Explore from '../../../../src/components/Explore.vue' +import Explore from '../../../../../src/components/routes/Explore.vue' jest.mock('@nextcloud/axios') diff --git a/tests/javascript/unit/components/routes/Feed.spec.ts b/tests/javascript/unit/components/routes/Feed.spec.ts new file mode 100644 index 000000000..4e0e69f2b --- /dev/null +++ b/tests/javascript/unit/components/routes/Feed.spec.ts @@ -0,0 +1,75 @@ +import Vuex, { Store } from 'vuex' +import { shallowMount, createLocalVue, Wrapper } from '@vue/test-utils' + +import Feed from '../../../../../src/components/routes/Feed.vue' +import FeedItemDisplayList from '../../../../../src/components/FeedItemDisplayList.vue' + +jest.mock('@nextcloud/axios') + +describe('Feed.vue', () => { + 'use strict' + const localVue = createLocalVue() + localVue.use(Vuex) + let wrapper: Wrapper<Feed> + + const mockFeed = { + id: 123, + title: 'feed name', + unreadCount: 2, + } + + let store: Store<any> + beforeAll(() => { + store = new Vuex.Store({ + state: { + items: { + fetchingItems: { + 'feed-123': false, + }, + allItems: [{ + feedId: 123, + title: 'feed item', + }, { + feedId: 123, + title: 'feed item 2', + }], + }, + }, + actions: { + }, + getters: { + feeds: () => [mockFeed], + }, + }) + + store.dispatch = jest.fn() + store.commit = jest.fn() + + wrapper = shallowMount(Feed, { + propsData: { + feedId: '123', + }, + mocks: { + $route: { + params: {}, + }, + }, + localVue, + store, + }) + }) + + it('should display feed title and unread count', () => { + expect(wrapper.find('.header').text()).toContain(mockFeed.title) + expect(wrapper.find('.header').text()).toContain(mockFeed.unreadCount.toString()) + }) + + it('should get starred items from state', () => { + expect((wrapper.findComponent(FeedItemDisplayList)).props().items.length).toEqual(2) + }) + + it('should dispatch FETCH_FEED_ITEMS action if not fetchingItems.starred', () => { + (wrapper.vm as any).fetchMore() + expect(store.dispatch).toBeCalled() + }) +}) diff --git a/tests/javascript/unit/components/Starred.spec.ts b/tests/javascript/unit/components/routes/Starred.spec.ts index 4f09f4e3c..44c9acd75 100644 --- a/tests/javascript/unit/components/Starred.spec.ts +++ b/tests/javascript/unit/components/routes/Starred.spec.ts @@ -1,8 +1,8 @@ import Vuex, { Store } from 'vuex' import { shallowMount, createLocalVue, Wrapper } from '@vue/test-utils' -import Starred from '../../../../src/components/Starred.vue' -import FeedItemDisplayList from '../../../../src/components/FeedItemDisplayList.vue' +import Starred from '../../../../../src/components/routes/Starred.vue' +import FeedItemDisplayList from '../../../../../src/components/FeedItemDisplayList.vue' jest.mock('@nextcloud/axios') diff --git a/tests/javascript/unit/components/Unread.spec.ts b/tests/javascript/unit/components/routes/Unread.spec.ts index 6de4d8565..149fc015f 100644 --- a/tests/javascript/unit/components/Unread.spec.ts +++ b/tests/javascript/unit/components/routes/Unread.spec.ts @@ -1,8 +1,8 @@ import Vuex, { Store } from 'vuex' import { shallowMount, createLocalVue, Wrapper } from '@vue/test-utils' -import Unread from '../../../../src/components/Unread.vue' -import FeedItemDisplayList from '../../../../src/components/FeedItemDisplayList.vue' +import Unread from '../../../../../src/components/routes/Unread.vue' +import FeedItemDisplayList from '../../../../../src/components/FeedItemDisplayList.vue' jest.mock('@nextcloud/axios') diff --git a/tests/javascript/unit/services/item.service.spec.ts b/tests/javascript/unit/services/item.service.spec.ts index 29de8f1a3..005248709 100644 --- a/tests/javascript/unit/services/item.service.spec.ts +++ b/tests/javascript/unit/services/item.service.spec.ts @@ -12,7 +12,7 @@ describe('item.service.ts', () => { }) describe('fetchStarred', () => { - it('should call GET with offset set to start param', async () => { + it('should call GET with offset set to start param and STARRED item type', async () => { (axios as any).get.mockResolvedValue({ data: { feeds: [] } }) await ItemService.fetchStarred(0) @@ -26,7 +26,7 @@ describe('item.service.ts', () => { }) describe('fetchUnread', () => { - it('should call GET with offset set to start param', async () => { + it('should call GET with offset set to start param and UNREAD item type', async () => { (axios as any).get.mockResolvedValue({ data: { feeds: [] } }) await ItemService.fetchUnread(2) @@ -39,6 +39,21 @@ describe('item.service.ts', () => { }) }) + describe('fetchFeedItems', () => { + it('should call GET with offset set to start param, UNREAD item type, and id set to feedId', async () => { + (axios as any).get.mockResolvedValue({ data: { feeds: [] } }) + + await ItemService.fetchFeedItems(123, 0) + + expect(axios.get).toBeCalled() + const queryParams = (axios.get as any).mock.calls[0][1].params + + expect(queryParams.id).toEqual(123) + expect(queryParams.offset).toEqual(0) + expect(queryParams.type).toEqual(ITEM_TYPES.ALL) + }) + }) + describe('markRead', () => { it('should call POST with item id in URL and read param', async () => { await ItemService.markRead({ id: 123 } as any, true) diff --git a/tests/javascript/unit/store/item.spec.ts b/tests/javascript/unit/store/item.spec.ts index c393a03f4..84869c4d8 100644 --- a/tests/javascript/unit/store/item.spec.ts +++ b/tests/javascript/unit/store/item.spec.ts @@ -37,6 +37,21 @@ describe('item.ts', () => { }) }) + describe('FETCH_FEED_ITEMS', () => { + it('should call ItemService and commit items to state', async () => { + const mockItems = [{ id: 123, title: 'feed item' }] + const fetchMock = jest.fn() + fetchMock.mockResolvedValue({ data: { items: mockItems } }) + ItemService.debounceFetchFeedItems = fetchMock as any + const commit = jest.fn() + + await (actions[FEED_ITEM_ACTION_TYPES.FETCH_FEED_ITEMS] as any)({ commit }, { feedId: 123 }) + + expect(fetchMock).toBeCalled() + expect(commit).toBeCalledWith(FEED_ITEM_MUTATION_TYPES.SET_ITEMS, mockItems) + }) + }) + it('MARK_READ should call GET and commit returned feeds to state', async () => { const item = { id: 1 } const commit = jest.fn() |