From c4183b3469f5413e34035d630c5c072d419e032a Mon Sep 17 00:00:00 2001 From: Christian Cueni Date: Tue, 23 Nov 2021 15:06:05 +0100 Subject: [PATCH] Add test --- client/package-lock.json | 6 + client/package.json | 1 + .../tests/unit/class-selection-widget.spec.js | 195 ++++++++++++++++++ 3 files changed, 202 insertions(+) create mode 100644 client/tests/unit/class-selection-widget.spec.js diff --git a/client/package-lock.json b/client/package-lock.json index cf68088b..fef36c7d 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -13280,6 +13280,12 @@ } } }, + "mock-apollo-client": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/mock-apollo-client/-/mock-apollo-client-0.7.0.tgz", + "integrity": "sha512-r0ICU01m007W0MwMej0lzlg1REtepDZ15Fyj8Hz9tiW/1TPb0PyHryGykrg9YhfbB8/+ZF2ovz+88yMF75TDoA==", + "dev": true + }, "moment": { "version": "2.29.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", diff --git a/client/package.json b/client/package.json index 6aa5c78f..213b7f2a 100644 --- a/client/package.json +++ b/client/package.json @@ -128,6 +128,7 @@ "jest-transform-graphql": "^2.1.0", "jest-transform-stub": "^2.0.0", "jest-watch-typeahead": "^0.3.1", + "mock-apollo-client": "^0.7.0", "ts-loader": "^8.3.0", "typescript": "^4.4.3", "vue-jest": "^3.0.4" diff --git a/client/tests/unit/class-selection-widget.spec.js b/client/tests/unit/class-selection-widget.spec.js new file mode 100644 index 00000000..1865f962 --- /dev/null +++ b/client/tests/unit/class-selection-widget.spec.js @@ -0,0 +1,195 @@ +import {createLocalVue, mount} from '@vue/test-utils' +import { createMockClient } from 'mock-apollo-client' + +import SIDEBAR from '@/graphql/gql/local/sidebar.gql'; +import ME_QUERY from '@/graphql/gql/queries/meQuery.gql'; +import UPDATE_USER_SETTING from '@/graphql/gql/mutations/updateUserSetting.gql'; +import MY_SCHOOL_CLASS_QUERY from '@/graphql/gql/queries/mySchoolClass.gql'; +import DELETE_MODULE_NODES from '@/graphql/gql/local/mutations/deleteModuleNodes.gql'; +import MODULE_DETAILS_QUERY from '@/graphql/gql/queries/modules/moduleDetailsQuery.gql'; + +import VueApollo from 'vue-apollo' +import ClassSelectionWidget from '@/components/school-class/ClassSelectionWidget'; + + + +// https://dev.to/n_tepluhina/testing-vue-apollo-2020-edition-2l2p + +const localVue = createLocalVue(); +localVue.use(VueApollo); + +const updateSettingsResponse = { + data: { + updateSetting: { + success: true, + errors:null, + __typename: 'UpdateSettingPayload' + } + } +}; + +const querySidebarResponse = { + data: {} +}; + +const deleteModulesResponse = { + data: {} +}; + +const meQueryResponse = { + data: { + me: { + __typename: "PrivateUserNode", + id: "UHJpdmF0ZVVzZXJOb2RlOjI=", + pk: 2, + username: "ross.geller", + email: "ross.geller@skillbox.example", + firstName: "Ross", + lastName: "Geller", + avatarUrl: "https://ucarecdn.com/fe10f9cc-a509-4170-9396-258abc418247/", + expiryDate: "2021-11-29", + readOnly: false, + lastModule: null, + lastTopic: { + id: "VG9waWNOb2RlOjQ5", + slug: "berufliche-grundbildung", + __typename: "TopicNode" + }, + selectedClass: { + id: "U2Nob29sQ2xhc3NOb2RlOjM=", + readOnly: false, + __typename: "SchoolClassNode" + }, + recentModules: { + edges: [], + __typename: "ModuleNodeConnection" + }, + schoolClasses: { + edges: [ + { + node: { + id: "U2Nob29sQ2xhc3NOb2RlOjE=", + name: "Friends", + __typename: "SchoolClassNode" + }, + __typename: "SchoolClassNodeEdge" + }, + { + node: { + id: "U2Nob29sQ2xhc3NOb2RlOjM=", + name: "ghfgfh", + __typename: "SchoolClassNode" + }, + __typename: "SchoolClassNodeEdge" + } + ], + __typename: "SchoolClassNodeConnection" + }, + team: null, + isTeacher: true, + permissions: [ + "users.can_manage_school_class_content" + ], + onboardingVisited: true + } + } +} + +const mySchoolClassResponse = { + data: {} +}; + +const moduleDetailResponse = { + data: {} +}; + +const slug = '/some/123'; +const schoolClasses = [ + { + id: 'abcd123', + name: 'Hello' + },{ + id: 'xyz098', + name: 'Kitty' + } +]; + +describe('ClassSelectionWidget.vue', () => { + + let mockClient; + let apolloProvider; + let wrapper; + + const requestHandlers = { + updateSettingsHandler: jest.fn().mockResolvedValueOnce(updateSettingsResponse), + querySidebarHandler: jest.fn().mockResolvedValueOnce(querySidebarResponse), + meQueryHandler: jest.fn().mockResolvedValueOnce(meQueryResponse), + deleteModulesHandler: jest.fn().mockResolvedValueOnce(deleteModulesResponse), + mySchoolClassHandler: jest.fn().mockResolvedValueOnce(mySchoolClassResponse), + moduleDetailHandler: jest.fn().mockResolvedValueOnce(moduleDetailResponse), + } + + + const createComponent = () => { + mockClient = createMockClient(); + mockClient.cache.writeQuery = jest.fn(); + + mockClient.setRequestHandler(UPDATE_USER_SETTING, requestHandlers.updateSettingsHandler); + mockClient.setRequestHandler(SIDEBAR, requestHandlers.querySidebarHandler); + mockClient.setRequestHandler(ME_QUERY, requestHandlers.meQueryHandler); + mockClient.setRequestHandler(DELETE_MODULE_NODES, requestHandlers.deleteModulesHandler); + mockClient.setRequestHandler(MY_SCHOOL_CLASS_QUERY, requestHandlers.mySchoolClassHandler); + mockClient.setRequestHandler(MODULE_DETAILS_QUERY, requestHandlers.moduleDetailHandler); + + apolloProvider = new VueApollo({ + defaultClient: mockClient, + }); + + wrapper = mount(ClassSelectionWidget, { + localVue, + apolloProvider, + mocks: { + $route: { + params: { + slug + } + } + } + }); + + wrapper.vm.me.schoolClass = schoolClasses; + + } + + + it('should delete the modules cache and query the current module on a class change', async () => { + + createComponent(); + + wrapper.vm.me.selectedClass = {id: 'abcd123'} + wrapper.vm.updateSelectedClassAndHidePopover(schoolClasses[1]); + + expect(requestHandlers.updateSettingsHandler).toHaveBeenCalledWith({ + input: { + id: schoolClasses[1].id + } + }); + + await wrapper.vm.$nextTick(); + + // modules have been removed from cache + expect(requestHandlers.deleteModulesHandler).toHaveBeenCalled(); + expect(requestHandlers.mySchoolClassHandler).toHaveBeenCalled(); + // current module is being refetched + expect(requestHandlers.moduleDetailHandler).toHaveBeenCalledWith({slug}); + + }); + + afterEach(() => { + wrapper.destroy() + mockClient = null + apolloProvider = null + }) + + +})