changes requested by reviews

This commit is contained in:
Moriz Wahl 2020-01-10 09:23:56 +01:00
parent 3f37b007d7
commit 8c7079cf81
12 changed files with 52 additions and 49 deletions

View File

@ -162,10 +162,10 @@ type Query {
blockedUsers: [User] blockedUsers: [User]
isLoggedIn: Boolean! isLoggedIn: Boolean!
currentUser: User currentUser: User
findUsers(query: String!,limit: Int = 10, filter: _UserFilter): [User]! findUsers(query: String!,limit: Int = 10, filter: _UserFilter): [User]!
@cypher( @cypher(
statement: """ statement: """
CALL db.index.fulltext.queryNodes('user_fulltext_search', $query) CALL db.index.fulltext.queryNodes('user_fulltext_search', $query)
YIELD node as post, score YIELD node as post, score
MATCH (user) MATCH (user)
@ -192,8 +192,7 @@ type Mutation {
termsAndConditionsAgreedAt: String termsAndConditionsAgreedAt: String
allowEmbedIframes: Boolean allowEmbedIframes: Boolean
showShoutsPublicly: Boolean showShoutsPublicly: Boolean
locale: String
locale: String
): User ): User
DeleteUser(id: ID!, resource: [Deletable]): User DeleteUser(id: ID!, resource: [Deletable]): User

View File

@ -1,6 +1,6 @@
import { When, Then } from "cypress-cucumber-preprocessor/steps"; import { When, Then } from "cypress-cucumber-preprocessor/steps";
When("I search for {string}", value => { When("I search for {string}", value => {
cy.get("#search-resources") cy.get("[data-test=search-field]")
.focus() .focus()
.type(value); .type(value);
}); });
@ -16,7 +16,7 @@ Then("the search has no results", () => {
expect($li).to.have.length(1); expect($li).to.have.length(1);
}); });
cy.get(".ds-select-dropdown").should("contain", 'Nothing found'); cy.get(".ds-select-dropdown").should("contain", 'Nothing found');
cy.get("#search-resources") cy.get("[data-test=search-field]")
.focus() .focus()
.type("{esc}"); .type("{esc}");
}); });
@ -35,21 +35,21 @@ Then("I should see the following users in the select dropdown:", table => {
}); });
When("I type {string} and press Enter", value => { When("I type {string} and press Enter", value => {
cy.get("#search-resources") cy.get("[data-test=search-field]")
.focus() .focus()
.type(value) .type(value)
.type("{enter}", { force: true }); .type("{enter}", { force: true });
}); });
When("I type {string} and press escape", value => { When("I type {string} and press escape", value => {
cy.get("#search-resources") cy.get("[data-test=search-field]")
.focus() .focus()
.type(value) .type(value)
.type("{esc}"); .type("{esc}");
}); });
Then("the search field should clear", () => { Then("the search field should clear", () => {
cy.get("#search-resources").should("have.text", ""); cy.get("[data-test=search-field]").should("have.text", "");
}); });
When("I select a post entry", () => { When("I select a post entry", () => {
@ -94,4 +94,4 @@ Then("I select a user entry", () => {
Then("I should be on the user's profile", () => { Then("I should be on the user's profile", () => {
cy.location("pathname").should("eq", "/profile/user-for-search/search-for-me") cy.location("pathname").should("eq", "/profile/user-for-search/search-for-me")
}) })

View File

@ -1,15 +1,15 @@
import { config, mount } from '@vue/test-utils' import { config, mount } from '@vue/test-utils'
import Vuex from 'vuex' import Vuex from 'vuex'
import SearchResources from './SearchResources.vue' import SearchField from './SearchField.vue'
import SearchableInput from '~/components/generic/SearchableInput/SearchableInput' import SearchableInput from '~/components/generic/SearchableInput/SearchableInput'
import { results as searchResults } from './SearchResources.story' import { results as searchResults } from './SearchField.story'
const localVue = global.localVue const localVue = global.localVue
localVue.filter('truncate', () => 'truncated string') localVue.filter('truncate', () => 'truncated string')
localVue.filter('dateTime', () => Date.now) localVue.filter('dateTime', () => Date.now)
config.stubs['nuxt-link'] = '<span><slot /></span>' config.stubs['nuxt-link'] = '<span><slot /></span>'
describe('SearchResources.vue', () => { describe('SearchField.vue', () => {
let mocks, wrapper, getters let mocks, wrapper, getters
beforeEach(() => { beforeEach(() => {
mocks = { mocks = {
@ -26,7 +26,7 @@ describe('SearchResources.vue', () => {
const store = new Vuex.Store({ const store = new Vuex.Store({
getters, getters,
}) })
return mount(SearchResources, { mocks, localVue, store }) return mount(SearchField, { mocks, localVue, store })
} }
describe('mount', () => { describe('mount', () => {

View File

@ -1,6 +1,6 @@
import { storiesOf } from '@storybook/vue' import { storiesOf } from '@storybook/vue'
import { withA11y } from '@storybook/addon-a11y' import { withA11y } from '@storybook/addon-a11y'
import SearchResources from './SearchResources.vue' import SearchField from './SearchField.vue'
import helpers from '~/storybook/helpers' import helpers from '~/storybook/helpers'
helpers.init() helpers.init()
@ -100,19 +100,18 @@ export const results = [
}, },
] ]
storiesOf('Search Input', module) storiesOf('Search Field', module)
.addDecorator(withA11y) .addDecorator(withA11y)
.addDecorator(helpers.layout) .addDecorator(helpers.layout)
.add('test', () => ({ .add('test', () => ({
components: { SearchResources }, components: { SearchField },
store: helpers.store, store: helpers.store,
data: () => ({ data: () => ({
results: results, results: results,
}), }),
template: ` template: `
<search-input <search-field
:results="results" :searchResults="results"
:width="{ base: '100%', xs: '100%', md: '50%', xl: '33%' }"
/> />
`, `,
})) }))

View File

@ -1,7 +1,6 @@
<template> <template>
<searchable-input <searchable-input
data-test="search-resources" data-test="search-field"
id="search-resources"
:loading="pending" :loading="pending"
:options="searchResults" :options="searchResults"
@query="query" @query="query"
@ -14,6 +13,7 @@ import { findResourcesQuery } from '~/graphql/Search.js'
import SearchableInput from '~/components/generic/SearchableInput/SearchableInput.vue' import SearchableInput from '~/components/generic/SearchableInput/SearchableInput.vue'
export default { export default {
name: 'SearchField',
components: { components: {
SearchableInput, SearchableInput,
}, },

View File

@ -13,3 +13,14 @@ export default {
}, },
} }
</script> </script>
<style lang="scss">
.search-heading {
display: flex;
flex-wrap: wrap;
font-weight: bold;
cursor: default;
background-color: white;
margin: -8px;
padding: 8px;
}
</style>

View File

@ -28,10 +28,11 @@ describe('SearchPost.vue', () => {
return shallowMount(SearchPost, { mocks, localVue, propsData }) return shallowMount(SearchPost, { mocks, localVue, propsData })
} }
describe('mount', () => { describe('shallowMount', () => {
it('renders post title', () => { it('renders post title', () => {
expect(wrapper.find('.search-option-label').text()).toMatch('Post Title') expect(wrapper.find('.search-option-label').text()).toMatch('Post Title')
}) })
it('renders post commentsCount', () => { it('renders post commentsCount', () => {
expect( expect(
wrapper wrapper
@ -41,6 +42,7 @@ describe('SearchPost.vue', () => {
.exists(), .exists(),
).toBe(true) ).toBe(true)
}) })
it('renders post shoutedCount', () => { it('renders post shoutedCount', () => {
expect( expect(
wrapper wrapper
@ -50,9 +52,11 @@ describe('SearchPost.vue', () => {
.exists(), .exists(),
).toBe(true) ).toBe(true)
}) })
it('renders post author', () => { it('renders post author', () => {
expect(wrapper.find('.search-post-author').text()).toContain('Post Author') expect(wrapper.find('.search-post-author').text()).toContain('Post Author')
}) })
it('renders post createdAt', () => { it('renders post createdAt', () => {
expect(wrapper.find('.search-post-author').text()).toContain('23.08.2019') expect(wrapper.find('.search-post-author').text()).toContain('23.08.2019')
}) })

View File

@ -2,7 +2,7 @@ import { config, mount } from '@vue/test-utils'
import Vuex from 'vuex' import Vuex from 'vuex'
import Vue from 'vue' import Vue from 'vue'
import SearchableInput from './SearchableInput' import SearchableInput from './SearchableInput'
import { results } from '~/components/features/SearchResources/SearchResources.story' import { results } from '~/components/features/SearchField/SearchField.story'
const localVue = global.localVue const localVue = global.localVue

View File

@ -39,13 +39,13 @@
</span> </span>
<span <span
v-if="option.__typename === 'User'" v-if="option.__typename === 'User'"
:class="{ 'extra-space': isFirstOfType(option), 'flex-span': true }" :class="{ 'option-with-heading': isFirstOfType(option), 'flex-span': true }"
> >
<hc-user :user="option" :showPopover="false" /> <hc-user :user="option" :showPopover="false" />
</span> </span>
<span <span
v-if="option.__typename === 'Post'" v-if="option.__typename === 'Post'"
:class="{ 'extra-space': isFirstOfType(option), 'flex-span': true }" :class="{ 'option-with-heading': isFirstOfType(option), 'flex-span': true }"
> >
<search-post :option="option" /> <search-post :option="option" />
</span> </span>
@ -62,6 +62,7 @@ import SearchPost from '~/components/generic/SearchPost/SearchPost.vue'
import HcUser from '~/components/User/User.vue' import HcUser from '~/components/User/User.vue'
export default { export default {
name: 'SearchableInput',
components: { components: {
SearchHeading, SearchHeading,
SearchPost, SearchPost,
@ -169,25 +170,16 @@ export default {
}, },
} }
</script> </script>
<style lang="scss" `> <style lang="scss">
.searchable-input { .searchable-input {
display: flex; display: flex;
align-self: center; align-self: center;
width: 100%; width: 100%;
position: relative; position: relative;
$padding-left: $space-x-small; $padding-left: $space-x-small;
.search-heading { .option-with-heading {
display: flex; margin-top: $space-x-small;
flex-wrap: wrap; padding-top: $space-xx-small;
font-weight: bold;
cursor: default;
background-color: white;
margin: -8px;
padding: 8px;
}
.extra-space {
margin-top: 8px;
padding-top: 4px;
} }
.flex-span { .flex-span {
display: flex; display: flex;

View File

@ -19,10 +19,10 @@
<ds-flex-item <ds-flex-item
:width="{ base: '85%', sm: '85%', md: '50%', lg: '50%' }" :width="{ base: '85%', sm: '85%', md: '50%', lg: '50%' }"
:class="{ 'hide-mobile-menu': !toggleMobileMenu }" :class="{ 'hide-mobile-menu': !toggleMobileMenu }"
id="nav-search-box"
v-if="isLoggedIn"
> >
<div id="nav-search-box" v-if="isLoggedIn"> <search-field />
<search-resources />
</div>
</ds-flex-item> </ds-flex-item>
<ds-flex-item <ds-flex-item
v-if="isLoggedIn" v-if="isLoggedIn"
@ -84,7 +84,7 @@
<script> <script>
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch' import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
import SearchResources from '~/components/features/SearchResources/SearchResources.vue' import SearchField from '~/components/features/SearchField/SearchField.vue'
import Modal from '~/components/Modal' import Modal from '~/components/Modal'
import NotificationMenu from '~/components/NotificationMenu/NotificationMenu' import NotificationMenu from '~/components/NotificationMenu/NotificationMenu'
import seo from '~/mixins/seo' import seo from '~/mixins/seo'
@ -96,7 +96,7 @@ import AvatarMenu from '~/components/AvatarMenu/AvatarMenu'
export default { export default {
components: { components: {
LocaleSwitch, LocaleSwitch,
SearchResources, SearchField,
Modal, Modal,
NotificationMenu, NotificationMenu,
AvatarMenu, AvatarMenu,

View File

@ -518,8 +518,7 @@
"failed": "Nichts gefunden", "failed": "Nichts gefunden",
"heading": { "heading": {
"Post": "Beiträge", "Post": "Beiträge",
"User": "Benutzer", "User": "Benutzer"
"Tag": "Hashtags"
} }
}, },
"components": { "components": {

View File

@ -202,8 +202,7 @@
"failed": "Nothing found", "failed": "Nothing found",
"heading": { "heading": {
"Post": "Posts", "Post": "Posts",
"User": "Users", "User": "Users"
"Tag": "Hashtags"
} }
}, },
"settings": { "settings": {