From bee2f2740aede8e1eb24f4f185c4d61fc62147e4 Mon Sep 17 00:00:00 2001 From: Eric Lambrecht Date: Sat, 26 Oct 2019 15:46:48 +0200 Subject: [PATCH] =?UTF-8?q?test:=20=F0=9F=9A=A8=20Added=20tests=20for=20tr?= =?UTF-8?q?ack=20search?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .babelrc | 22 ----- babel.config.js | 22 +++++ jest.config.js | 5 +- package-lock.json | 6 ++ package.json | 2 + src/components/editor/TrackSearch.test.js | 101 ++++++++++++++++++++++ src/utils/testing/createTestRenderer.js | 21 ++++- 7 files changed, 152 insertions(+), 27 deletions(-) delete mode 100644 .babelrc create mode 100644 babel.config.js create mode 100644 src/components/editor/TrackSearch.test.js diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 1eb6c81c..00000000 --- a/.babelrc +++ /dev/null @@ -1,22 +0,0 @@ -{ - "presets": [ - [ - "@babel/env", - { - "targets": { - "browsers": [ - "last 6 chrome versions", - "last 6 firefox versions", - "last 3 safari versions", - "last 3 edge versions" - ] - } - } - ] - ], - "env": { - "test": { - "presets": [["@babel/preset-env", { "targets": { "node": "current" } }]] - } - } -} diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 00000000..96d235da --- /dev/null +++ b/babel.config.js @@ -0,0 +1,22 @@ +module.exports = { + presets: [ + [ + '@babel/env', + { + targets: { + browsers: [ + 'last 6 chrome versions', + 'last 6 firefox versions', + 'last 3 safari versions', + 'last 3 edge versions', + ], + }, + }, + ], + ], + env: { + test: { + presets: [['@babel/preset-env', { targets: { node: 'current' } }]], + }, + }, +} diff --git a/jest.config.js b/jest.config.js index 378ccd4c..12367e7f 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,7 +2,8 @@ module.exports = { verbose: true, moduleFileExtensions: ['js', 'json', 'vue'], transform: { - '.*\\.(vue)$': 'vue-jest', - '^.+\\.js$': '/node_modules/babel-jest', + '^.+\\.js$': 'babel-jest', + '^.+\\.vue$': 'vue-jest', }, + transformIgnorePatterns: ['/node_modules/(?!vue-awesome)'], } diff --git a/package-lock.json b/package-lock.json index 74b757e4..3cf17341 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6545,6 +6545,12 @@ "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", "dev": true }, + "flush-promises": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flush-promises/-/flush-promises-1.0.2.tgz", + "integrity": "sha512-G0sYfLQERwKz4+4iOZYQEZVpOt9zQrlItIxQAAYAWpfby3gbHrx0osCHz5RLl/XoXevXk0xoN4hDFky/VV9TrA==", + "dev": true + }, "flush-write-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", diff --git a/package.json b/package.json index de960e0d..c4c365ad 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "@babel/preset-env": "^7.6.3", "@vue/test-utils": "^1.0.0-beta.29", "babel-core": "^7.0.0-bridge.0", + "babel-jest": "^24.9.0", "babel-loader": "^8.0.6", "clean-webpack-plugin": "^1.0.1", "commitizen": "^4.0.3", @@ -56,6 +57,7 @@ "eslint-plugin-prettier": "^3.1.1", "eslint-plugin-vue": "^5.2.3", "file-loader": "^4.2.0", + "flush-promises": "^1.0.2", "html-loader": "^0.5.5", "jest": "^24.9.0", "markdown-loader": "^5.1.0", diff --git a/src/components/editor/TrackSearch.test.js b/src/components/editor/TrackSearch.test.js new file mode 100644 index 00000000..c86ed811 --- /dev/null +++ b/src/components/editor/TrackSearch.test.js @@ -0,0 +1,101 @@ +import flushPromises from 'flush-promises' +import TrackSearch from './TrackSearch.vue' +import createTestRenderer from '../../utils/testing/createTestRenderer' +import Spotify from '../../utils/Spotify' + +jest.mock('../../utils/Spotify') + +const testTracks = [ + { + name: 'foo', + uri: 'foo-uri', + image: 'foo-image', + artist: 'foo-artist', + duration_ms: 3600, + }, + { + name: 'bar', + uri: 'bar-uri', + image: 'bar-image', + artist: 'bar-artist', + duration_ms: 3600, + }, +] + +describe('TrackSearch', () => { + beforeAll(() => { + Spotify.searchTracks.mockResolvedValue(testTracks) + }) + + const searchForTracks = async wrapper => { + const input = wrapper.find('input') + input.element.value = 'foobar' + input.trigger('input') + await flushPromises() + } + + const shallowMountWithVuex = createTestRenderer(TrackSearch, { + shallow: true, + }) + + it('searches for entered input', () => { + const { wrapper } = shallowMountWithVuex({}) + const input = wrapper.find('input') + input.element.value = 'foobar' + input.trigger('input') + expect(Spotify.searchTracks).toHaveBeenCalledWith('foobar') + }) + + it('shows track items for each found track', async () => { + const { wrapper } = shallowMountWithVuex({}) + + const results = wrapper.find('.results') + expect(results.text()).toContain('No results :(') + + await searchForTracks(wrapper) + + const tracks = wrapper.findAll('search-playlist-item-stub') + expect(tracks).toHaveLength(2) + tracks.wrappers.forEach((track, i) => { + expect(track.props('track').name).toBe(testTracks[i].name) + }) + }) + + it('clicking on a track will add it to the "added" list, clicking again removes it', async () => { + const { wrapper } = shallowMountWithVuex({}) + + await searchForTracks(wrapper) + + const tracks = wrapper.findAll('search-playlist-item-stub') + const clickIndex = 1 + const fooTrack = tracks.at(clickIndex) + fooTrack.trigger('click') + + let addedTracks = wrapper.findAll('.add-list search-playlist-item-stub') + expect(addedTracks).toHaveLength(1) + expect(addedTracks.at(0).props('track').name).toBe( + testTracks[clickIndex].name + ) + + addedTracks.at(0).trigger('click') + addedTracks = wrapper.findAll('.add-list search-playlist-item-stub') + expect(addedTracks).toHaveLength(0) + }) + + it('adding tracks emits their uris in a select event', async () => { + const { wrapper } = shallowMountWithVuex({}) + + await searchForTracks(wrapper) + + const tracks = wrapper.findAll('search-playlist-item-stub') + tracks.wrappers.forEach(track => track.trigger('click')) + + expect(wrapper.emitted().select).toBeTruthy() + expect(wrapper.emitted().select).toHaveLength(2) + + expect(wrapper.emitted().select).toEqual([ + [['foo-uri']], + [['foo-uri', 'bar-uri']], + ]) + }) +}) diff --git a/src/utils/testing/createTestRenderer.js b/src/utils/testing/createTestRenderer.js index 0af4cc45..1d2ce076 100644 --- a/src/utils/testing/createTestRenderer.js +++ b/src/utils/testing/createTestRenderer.js @@ -1,13 +1,27 @@ import { Store } from 'vuex-mock-store' // eslint-disable-line import/no-extraneous-dependencies import merge from 'lodash/fp/merge' -import { shallowMount, mount } from '@vue/test-utils' // eslint-disable-line import/no-extraneous-dependencies +import { shallowMount, mount, createLocalVue } from '@vue/test-utils' // eslint-disable-line import/no-extraneous-dependencies +import Icon from 'vue-awesome/components/Icon' import Button from '../../components/_base/Button' +import TextInput from '../../components/_base/TextInput' // register some important modules that shouldn't be stubbed because of their functionality const specialStubs = { 'b-button': Button, + 'b-text-input': TextInput, + 'b-labeled-element': true, + 'b-list': true, + 'b-list-item': true, + 'b-square-image': true, + 'b-text': true, + 'b-button-group': true, + 'b-paragraph': true, + 'b-headline': true, } +const localVue = createLocalVue() +localVue.component('v-icon', Icon) + const defaultOptions = { props: {}, state: {}, @@ -60,9 +74,10 @@ export const createRenderer = (Component, options = defaultOptions) => { const stubs = merge(specialStubs, customStubsMap) const propsData = merge(defaultProps, customProps) + const testOptions = { mocks, stubs, propsData, localVue } const wrapper = shallow - ? shallowMount(Component, { mocks, stubs, propsData }) - : mount(Component, { mocks, stubs, propsData }) + ? shallowMount(Component, testOptions) + : mount(Component, testOptions) return { wrapper, mockStore } }