From 47324d49054bf97d69e81d9da36fecffa9105274 Mon Sep 17 00:00:00 2001 From: ogerly Date: Wed, 17 Jul 2019 09:57:08 +0200 Subject: [PATCH 1/4] example II - lint ok, test local ok --- webapp/graphql/PostQuery.js | 4 ++-- webapp/locales/de.json | 6 +++++ webapp/locales/en.json | 6 +++++ webapp/pages/index.vue | 47 +++++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/webapp/graphql/PostQuery.js b/webapp/graphql/PostQuery.js index cac80d9b1..1daedf5e1 100644 --- a/webapp/graphql/PostQuery.js +++ b/webapp/graphql/PostQuery.js @@ -79,8 +79,8 @@ export default i18n => { export const filterPosts = i18n => { const lang = i18n.locale().toUpperCase() return gql(` - query Post($filter: _PostFilter, $first: Int, $offset: Int) { - Post(filter: $filter, first: $first, offset: $offset) { + query Post($filter: _PostFilter, $first: Int, $offset: Int, $orderBy: [_PostOrdering]) { + Post(filter: $filter, first: $first, offset: $offset, orderBy: $orderBy) { id title contentExcerpt diff --git a/webapp/locales/de.json b/webapp/locales/de.json index 467a9a2ee..617741170 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -23,6 +23,12 @@ "bank": "Bankverbindung", "germany": "Deutschland" }, + "sorting": { + "newest": "Neuste", + "oldest": "Älteste", + "poular": "Beliebt", + "commented": "meist Kommentiert" + }, "login": { "copy": "Wenn Du bereits ein Konto bei Human Connection hast, melde Dich bitte hier an.", "login": "Einloggen", diff --git a/webapp/locales/en.json b/webapp/locales/en.json index edd2c6dc6..13d9f2ed6 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -23,6 +23,12 @@ "bank": "bank account", "germany": "Germany" }, + "sorting": { + "newest": "Newest", + "oldest": "Oldest", + "poular": "Popular", + "commented": "most Commented" + }, "login": { "copy": "If you already have a human-connection account, login here.", "login": "Login", diff --git a/webapp/pages/index.vue b/webapp/pages/index.vue index 0930d9a71..d2ad96113 100644 --- a/webapp/pages/index.vue +++ b/webapp/pages/index.vue @@ -9,6 +9,17 @@ @clearSearch="clearSearch" /> + +
+ +
+
Date: Mon, 22 Jul 2019 05:52:01 -0300 Subject: [PATCH 2/4] Remove extra parantheses --- webapp/graphql/PostQuery.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/graphql/PostQuery.js b/webapp/graphql/PostQuery.js index 61c3a97bc..eec2b25d8 100644 --- a/webapp/graphql/PostQuery.js +++ b/webapp/graphql/PostQuery.js @@ -78,7 +78,7 @@ export default i18n => { export const filterPosts = i18n => { const lang = i18n.locale().toUpperCase() - return gql(` + return gql` query Post($filter: _PostFilter, $first: Int, $offset: Int, $orderBy: [_PostOrdering]) { Post(filter: $filter, first: $first, offset: $offset, orderBy: $orderBy) { id From c8a67926270417953afbbcaea9e377611599ce8a Mon Sep 17 00:00:00 2001 From: Matt Rider Date: Mon, 22 Jul 2019 06:50:58 -0300 Subject: [PATCH 3/4] Add parent class for css selector on cypress/component --- cypress/integration/common/search.js | 97 ++++++++++++++-------------- webapp/pages/index.vue | 9 ++- 2 files changed, 55 insertions(+), 51 deletions(-) diff --git a/cypress/integration/common/search.js b/cypress/integration/common/search.js index 1c1981581..5a3819a9d 100644 --- a/cypress/integration/common/search.js +++ b/cypress/integration/common/search.js @@ -1,73 +1,70 @@ -import { When, Then } from 'cypress-cucumber-preprocessor/steps' -When('I search for {string}', value => { - cy.get('#nav-search') +import { When, Then } from "cypress-cucumber-preprocessor/steps"; +When("I search for {string}", value => { + cy.get("#nav-search") .focus() - .type(value) -}) + .type(value); +}); -Then('I should have one post in the select dropdown', () => { - cy.get('.ds-select-dropdown').should($li => { - expect($li).to.have.length(1) - }) -}) +Then("I should have one post in the select dropdown", () => { + cy.get(".input .ds-select-dropdown").should($li => { + expect($li).to.have.length(1); + }); +}); -Then('I should see the following posts in the select dropdown:', table => { +Then("I should see the following posts in the select dropdown:", table => { table.hashes().forEach(({ title }) => { - cy.get('.ds-select-dropdown').should('contain', title) - }) -}) + cy.get(".ds-select-dropdown").should("contain", title); + }); +}); -When('I type {string} and press Enter', value => { - cy.get('#nav-search') +When("I type {string} and press Enter", value => { + cy.get("#nav-search") .focus() .type(value) - .type('{enter}', { force: true }) -}) + .type("{enter}", { force: true }); +}); -When('I type {string} and press escape', value => { - cy.get('#nav-search') +When("I type {string} and press escape", value => { + cy.get("#nav-search") .focus() .type(value) - .type('{esc}') -}) + .type("{esc}"); +}); -Then('the search field should clear', () => { - cy.get('#nav-search').should('have.text', '') -}) +Then("the search field should clear", () => { + cy.get("#nav-search").should("have.text", ""); +}); -When('I select an entry', () => { - cy.get('.ds-select-dropdown ul li') +When("I select an entry", () => { + cy.get(".input .ds-select-dropdown ul li") .first() - .trigger('click') -}) + .trigger("click"); +}); Then("I should be on the post's page", () => { - cy.location('pathname').should( - 'contain', - '/post/' - ) - cy.location('pathname').should( - 'eq', - '/post/p1/101-essays-that-will-change-the-way-you-think' - ) -}) + cy.location("pathname").should("contain", "/post/"); + cy.location("pathname").should( + "eq", + "/post/p1/101-essays-that-will-change-the-way-you-think" + ); +}); Then( - 'I should see posts with the searched-for term in the select dropdown', + "I should see posts with the searched-for term in the select dropdown", () => { - cy.get('.ds-select-dropdown').should( - 'contain', - '101 Essays that will change the way you think' - ) + cy.get(".ds-select-dropdown").should( + "contain", + "101 Essays that will change the way you think" + ); } -) +); Then( - 'I should not see posts without the searched-for term in the select dropdown', + "I should not see posts without the searched-for term in the select dropdown", () => { - cy.get('.ds-select-dropdown').should( - 'not.contain', - 'No searched for content' - ) + cy.get(".ds-select-dropdown").should( + "not.contain", + "No searched for content" + ); } -) +); diff --git a/webapp/pages/index.vue b/webapp/pages/index.vue index d2ad96113..78c28e656 100644 --- a/webapp/pages/index.vue +++ b/webapp/pages/index.vue @@ -10,7 +10,7 @@ /> -
+
From 88a14ebd4f44b852194e2da21f325ccda369f894 Mon Sep 17 00:00:00 2001 From: Matt Rider Date: Tue, 23 Jul 2019 10:55:07 -0300 Subject: [PATCH 4/4] Add tests, fix typo --- webapp/locales/de.json | 2 +- webapp/locales/en.json | 2 +- webapp/pages/index.spec.js | 140 +++++++++++++++++++++++++++++++++++++ webapp/pages/index.vue | 4 +- 4 files changed, 144 insertions(+), 4 deletions(-) create mode 100644 webapp/pages/index.spec.js diff --git a/webapp/locales/de.json b/webapp/locales/de.json index 617741170..5a628a579 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -26,7 +26,7 @@ "sorting": { "newest": "Neuste", "oldest": "Älteste", - "poular": "Beliebt", + "popular": "Beliebt", "commented": "meist Kommentiert" }, "login": { diff --git a/webapp/locales/en.json b/webapp/locales/en.json index 16791e21d..1db0125b3 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -26,7 +26,7 @@ "sorting": { "newest": "Newest", "oldest": "Oldest", - "poular": "Popular", + "popular": "Popular", "commented": "most Commented" }, "login": { diff --git a/webapp/pages/index.spec.js b/webapp/pages/index.spec.js new file mode 100644 index 000000000..8cdf626ab --- /dev/null +++ b/webapp/pages/index.spec.js @@ -0,0 +1,140 @@ +import { config, shallowMount, mount, createLocalVue } from '@vue/test-utils' +import PostIndex from './index.vue' +import Vuex from 'vuex' +import Styleguide from '@human-connection/styleguide' +import Filters from '~/plugins/vue-filters' +import VTooltip from 'v-tooltip' +import FilterMenu from '~/components/FilterMenu/FilterMenu' + +const localVue = createLocalVue() + +localVue.use(Vuex) +localVue.use(Styleguide) +localVue.use(Filters) +localVue.use(VTooltip) + +config.stubs['no-ssr'] = '' +config.stubs['router-link'] = '' +config.stubs['nuxt-link'] = '' + +describe('PostIndex', () => { + let wrapper + let Wrapper + let store + let mocks + + beforeEach(() => { + store = new Vuex.Store({ + getters: { + 'posts/posts': () => { + return [ + { + id: 'p23', + name: 'It is a post', + author: { + id: 'u1', + }, + }, + ] + }, + 'auth/user': () => { + return { id: 'u23' } + }, + }, + }) + mocks = { + $t: key => key, + $filters: { + truncate: a => a, + removeLinks: jest.fn(), + }, + // If you are mocking router, than don't use VueRouter with localVue: https://vue-test-utils.vuejs.org/guides/using-with-vue-router.html + $router: { + history: { + push: jest.fn(), + }, + push: jest.fn(), + }, + $toast: { + success: jest.fn(), + error: jest.fn(), + }, + $apollo: { + mutate: jest.fn().mockResolvedValue(), + queries: { + Post: { + refetch: jest.fn(), + fetchMore: jest.fn().mockResolvedValue([ + { + id: 'p23', + name: 'It is a post', + author: { + id: 'u1', + }, + }, + ]), + }, + }, + }, + $route: { + query: {}, + }, + } + }) + + describe('shallowMount', () => { + Wrapper = () => { + return shallowMount(PostIndex, { + store, + mocks, + localVue, + }) + } + + beforeEach(() => { + wrapper = Wrapper() + }) + + it('refetches Posts when changeFilterBubble is emitted', () => { + wrapper.find(FilterMenu).vm.$emit('changeFilterBubble') + expect(mocks.$apollo.queries.Post.refetch).toHaveBeenCalledTimes(1) + }) + + it('clears the search when the filter menu emits clearSearch', () => { + wrapper.find(FilterMenu).vm.$emit('clearSearch') + expect(wrapper.vm.hashtag).toBeNull() + }) + + it('calls the changeFilterBubble if there are hasthags in the route query', () => { + mocks.$route.query.hashtag = { id: 'hashtag' } + wrapper = Wrapper() + expect(mocks.$apollo.queries.Post.refetch).toHaveBeenCalledTimes(1) + }) + + describe('mount', () => { + beforeEach(() => { + wrapper = mount(PostIndex, { + store, + mocks, + localVue, + }) + }) + + it('sets the post in the store when there are posts', () => { + wrapper + .findAll('li') + .at(0) + .trigger('click') + expect(wrapper.vm.sorting).toEqual('createdAt_desc') + }) + + it('loads more posts when a user clicks on the load more button', () => { + wrapper + .findAll('button') + .at(2) + .trigger('click') + expect(mocks.$apollo.queries.Post.fetchMore).toHaveBeenCalledTimes(1) + }) + }) + }) +}) diff --git a/webapp/pages/index.vue b/webapp/pages/index.vue index 78c28e656..8a7276269 100644 --- a/webapp/pages/index.vue +++ b/webapp/pages/index.vue @@ -82,7 +82,7 @@ export default { order: 'createdAt_asc', }, { - label: this.$t('sorting.poular'), + label: this.$t('sorting.popular'), value: 'Popular', icons: 'fire', order: 'shoutedCount_desc', @@ -130,7 +130,7 @@ export default { } } this.filter = filter - this.$apollo.queries.Post.refresh() + this.$apollo.queries.Post.refetch() }, toggleOnlySorting(x) { this.sortingIcon = x.icons