mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
Merge remote-tracking branch 'origin/2119_Create_Post_consistent_form_input_validation' into 2119_Create_Post_consistent_form_input_validation-improvements
This commit is contained in:
commit
4108bb7d71
@ -22,37 +22,36 @@ config.stubs['v-popover'] = '<span><slot /></span>'
|
||||
|
||||
const categories = [
|
||||
{
|
||||
"id": "cat3",
|
||||
"slug": "health-wellbeing",
|
||||
"icon": "medkit"
|
||||
id: 'cat3',
|
||||
slug: 'health-wellbeing',
|
||||
icon: 'medkit',
|
||||
},
|
||||
{
|
||||
"id": "cat12",
|
||||
"slug": "it-internet-data-privacy",
|
||||
"icon": "mouse-pointer"
|
||||
id: 'cat12',
|
||||
slug: 'it-internet-data-privacy',
|
||||
icon: 'mouse-pointer',
|
||||
},
|
||||
{
|
||||
"id": "cat9",
|
||||
"slug": "democracy-politics",
|
||||
"icon": "university"
|
||||
id: 'cat9',
|
||||
slug: 'democracy-politics',
|
||||
icon: 'university',
|
||||
},
|
||||
{
|
||||
"id": "cat15",
|
||||
"slug": "consumption-sustainability",
|
||||
"icon": "shopping-cart"
|
||||
id: 'cat15',
|
||||
slug: 'consumption-sustainability',
|
||||
icon: 'shopping-cart',
|
||||
},
|
||||
{
|
||||
"id": "cat4",
|
||||
"slug": "environment-nature",
|
||||
"icon": "tree"
|
||||
}
|
||||
id: 'cat4',
|
||||
slug: 'environment-nature',
|
||||
icon: 'tree',
|
||||
},
|
||||
]
|
||||
|
||||
describe('ContributionForm.vue', () => {
|
||||
let wrapper
|
||||
let postTitleInput
|
||||
let expectedParams
|
||||
let deutschOption
|
||||
let cancelBtn
|
||||
let mocks
|
||||
let propsData
|
||||
@ -137,21 +136,13 @@ describe('ContributionForm.vue', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper()
|
||||
wrapper.setData({
|
||||
form: {
|
||||
languageOptions: [
|
||||
{
|
||||
label: 'Deutsch',
|
||||
value: 'de',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
describe('CreatePost', () => {
|
||||
describe('language placeholder', () => {
|
||||
it("displays the name that corresponds with the user's location code", () => {
|
||||
it.skip("displays the name that corresponds with the user's location code", () => {
|
||||
// Well not anymore right? We want the user to save the language
|
||||
// excplicitly. I'll keep this test if we change our minds
|
||||
expect(wrapper.find('.ds-select-placeholder').text()).toEqual('English')
|
||||
})
|
||||
})
|
||||
@ -242,8 +233,16 @@ describe('ContributionForm.vue', () => {
|
||||
postTitleInput = wrapper.find('.ds-input')
|
||||
postTitleInput.setValue(postTitle)
|
||||
await wrapper.vm.updateEditorContent(postContent)
|
||||
wrapper.find(CategoriesSelect).setData({categories})
|
||||
await wrapper.find(CategoriesSelect).findAll('button').at(1).trigger('click')
|
||||
wrapper.find(CategoriesSelect).setData({ categories })
|
||||
wrapper
|
||||
.findAll('li')
|
||||
.at(1)
|
||||
.trigger('click') // language
|
||||
await wrapper
|
||||
.find(CategoriesSelect)
|
||||
.findAll('button')
|
||||
.at(1)
|
||||
.trigger('click')
|
||||
})
|
||||
|
||||
it('creates a post with valid title, content, and at least one category', async () => {
|
||||
@ -251,15 +250,12 @@ describe('ContributionForm.vue', () => {
|
||||
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams))
|
||||
})
|
||||
|
||||
it("sends a fallback language based on a user's locale", () => {
|
||||
wrapper.find('form').trigger('submit')
|
||||
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams))
|
||||
})
|
||||
|
||||
it('supports changing the language', async () => {
|
||||
expectedParams.variables.language = 'de'
|
||||
deutschOption = wrapper.findAll('li').at(0)
|
||||
deutschOption.trigger('click')
|
||||
wrapper
|
||||
.findAll('li')
|
||||
.at(0)
|
||||
.trigger('click') // choose German as language
|
||||
wrapper.find('form').trigger('submit')
|
||||
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams))
|
||||
})
|
||||
@ -303,8 +299,16 @@ describe('ContributionForm.vue', () => {
|
||||
postTitleInput.setValue(postTitle)
|
||||
await wrapper.vm.updateEditorContent(postContent)
|
||||
categoryIds = ['cat12']
|
||||
wrapper.find(CategoriesSelect).setData({categories})
|
||||
await wrapper.find(CategoriesSelect).findAll('button').at(1).trigger('click')
|
||||
wrapper.find(CategoriesSelect).setData({ categories })
|
||||
wrapper
|
||||
.findAll('li')
|
||||
.at(1)
|
||||
.trigger('click') // language
|
||||
await wrapper
|
||||
.find(CategoriesSelect)
|
||||
.findAll('button')
|
||||
.at(1)
|
||||
.trigger('click')
|
||||
})
|
||||
|
||||
it('shows an error toaster when apollo mutation rejects', async () => {
|
||||
@ -385,6 +389,10 @@ describe('ContributionForm.vue', () => {
|
||||
postTitleInput = wrapper.find('.ds-input')
|
||||
postTitleInput.setValue(postTitle)
|
||||
wrapper.vm.updateEditorContent(postContent)
|
||||
wrapper
|
||||
.findAll('li')
|
||||
.at(0)
|
||||
.trigger('click') // language
|
||||
await wrapper.find('form').trigger('submit')
|
||||
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams))
|
||||
})
|
||||
@ -394,10 +402,26 @@ describe('ContributionForm.vue', () => {
|
||||
postTitleInput = wrapper.find('.ds-input')
|
||||
postTitleInput.setValue(postTitle)
|
||||
wrapper.vm.updateEditorContent(postContent)
|
||||
wrapper.find(CategoriesSelect).setData({categories})
|
||||
await wrapper.find(CategoriesSelect).findAll('button').at(0).trigger('click')
|
||||
await wrapper.find(CategoriesSelect).findAll('button').at(3).trigger('click')
|
||||
await wrapper.find(CategoriesSelect).findAll('button').at(4).trigger('click')
|
||||
wrapper
|
||||
.findAll('li')
|
||||
.at(0)
|
||||
.trigger('click') // language
|
||||
wrapper.find(CategoriesSelect).setData({ categories })
|
||||
await wrapper
|
||||
.find(CategoriesSelect)
|
||||
.findAll('button')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
await wrapper
|
||||
.find(CategoriesSelect)
|
||||
.findAll('button')
|
||||
.at(3)
|
||||
.trigger('click')
|
||||
await wrapper
|
||||
.find(CategoriesSelect)
|
||||
.findAll('button')
|
||||
.at(4)
|
||||
.trigger('click')
|
||||
await wrapper.find('form').trigger('submit')
|
||||
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams))
|
||||
})
|
||||
|
||||
@ -50,23 +50,27 @@
|
||||
<ds-text align="right">
|
||||
<ds-chip v-if="errors && errors.categoryIds" color="danger" size="base">
|
||||
{{ form.categoryIds.length }} / 3
|
||||
<ds-icon name="warning"></ds-icon>
|
||||
<ds-icon name="warning" class="colorRed"></ds-icon>
|
||||
</ds-chip>
|
||||
<ds-chip v-else size="base">{{ form.categoryIds.length }} / 3</ds-chip>
|
||||
</ds-text>
|
||||
<ds-flex class="contribution-form-footer">
|
||||
<ds-flex-item :width="{ base: '10%', sm: '10%', md: '10%', lg: '15%' }" />
|
||||
<ds-flex-item :width="{ base: '80%', sm: '30%', md: '30%', lg: '20%' }">
|
||||
<ds-flex-item>
|
||||
<ds-space margin-bottom="small" />
|
||||
<ds-select
|
||||
model="language"
|
||||
:options="form.languageOptions"
|
||||
:options="languageOptions"
|
||||
icon="globe"
|
||||
:placeholder="locale"
|
||||
:placeholder="$t('contribution.languageSelectText')"
|
||||
:label="$t('contribution.languageSelectLabel')"
|
||||
/>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
<ds-text align="right">
|
||||
<ds-chip v-if="errors && errors.language" size="base" color="danger">
|
||||
<ds-icon name="warning"></ds-icon>
|
||||
</ds-chip>
|
||||
</ds-text>
|
||||
<ds-space />
|
||||
<div slot="footer" style="text-align: right">
|
||||
<ds-button
|
||||
@ -77,13 +81,7 @@
|
||||
>
|
||||
{{ $t('actions.cancel') }}
|
||||
</ds-button>
|
||||
<ds-button
|
||||
type="submit"
|
||||
icon="check"
|
||||
:loading="loading"
|
||||
:disabled="errors"
|
||||
primary
|
||||
>
|
||||
<ds-button type="submit" icon="check" :loading="loading" :disabled="errors" primary>
|
||||
{{ $t('actions.save') }}
|
||||
</ds-button>
|
||||
</div>
|
||||
@ -115,16 +113,35 @@ export default {
|
||||
contribution: { type: Object, default: () => {} },
|
||||
},
|
||||
data() {
|
||||
const languageOptions = orderBy(locales, 'name').map(locale => {
|
||||
return { label: locale.name, value: locale.code }
|
||||
})
|
||||
|
||||
const formDefaults = {
|
||||
title: '',
|
||||
content: '',
|
||||
teaserImage: null,
|
||||
image: null,
|
||||
language: null,
|
||||
categoryIds: [],
|
||||
}
|
||||
let id = null
|
||||
let slug = null
|
||||
const form = { ...formDefaults }
|
||||
if (this.contribution && this.contribution.id) {
|
||||
id = this.contribution.id
|
||||
slug = this.contribution.slug
|
||||
form.title = this.contribution.title
|
||||
form.content = this.contribution.content
|
||||
form.image = this.contribution.image
|
||||
form.language =
|
||||
this.contribution && this.contribution.language
|
||||
? languageOptions.find(o => this.contribution.language === o.value)
|
||||
: null
|
||||
form.categoryIds = this.categoryIds(this.contribution.categories)
|
||||
}
|
||||
return {
|
||||
form: {
|
||||
title: '',
|
||||
content: '',
|
||||
categoryIds: [],
|
||||
teaserImage: null,
|
||||
image: null,
|
||||
language: null,
|
||||
languageOptions: [],
|
||||
},
|
||||
form,
|
||||
formSchema: {
|
||||
title: { required: true, min: 3, max: 100 },
|
||||
content: {
|
||||
@ -139,66 +156,41 @@ export default {
|
||||
required: true,
|
||||
validator: (rule, value) => {
|
||||
const errors = []
|
||||
if (!(value && 1 <= value.length && value.length <= 3)) {
|
||||
if (!(value && value.length >= 1 && value.length <= 3)) {
|
||||
errors.push(new Error(this.$t('common.validations.categories')))
|
||||
}
|
||||
return errors
|
||||
},
|
||||
},
|
||||
language: { required: true },
|
||||
},
|
||||
id: null,
|
||||
languageOptions,
|
||||
id,
|
||||
slug,
|
||||
loading: false,
|
||||
slug: null,
|
||||
users: [],
|
||||
contentMin: 3,
|
||||
hashtags: [],
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
contribution: {
|
||||
immediate: true,
|
||||
handler: function(contribution) {
|
||||
if (!contribution || !contribution.id) {
|
||||
return
|
||||
}
|
||||
this.id = contribution.id
|
||||
this.slug = contribution.slug
|
||||
this.form.title = contribution.title
|
||||
this.form.content = contribution.content
|
||||
this.form.image = contribution.image
|
||||
this.form.categoryIds = this.categoryIds(contribution.categories)
|
||||
},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
contentLength() {
|
||||
return this.$filters.removeHtml(this.form.content).length
|
||||
},
|
||||
locale() {
|
||||
const locale =
|
||||
this.contribution && this.contribution.language
|
||||
? locales.find(loc => this.contribution.language === loc.code)
|
||||
: locales.find(loc => this.$i18n.locale() === loc.code)
|
||||
return locale.name
|
||||
},
|
||||
...mapGetters({
|
||||
currentUser: 'auth/user',
|
||||
}),
|
||||
},
|
||||
mounted() {
|
||||
this.availableLocales()
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
const { title, content, image, teaserImage, categoryIds } = this.form
|
||||
let language
|
||||
if (this.form.language) {
|
||||
language = this.form.language.value
|
||||
} else if (this.contribution && this.contribution.language) {
|
||||
language = this.contribution.language
|
||||
} else {
|
||||
language = this.$i18n.locale()
|
||||
}
|
||||
const {
|
||||
language: { value: language },
|
||||
title,
|
||||
content,
|
||||
image,
|
||||
teaserImage,
|
||||
categoryIds,
|
||||
} = this.form
|
||||
this.loading = true
|
||||
this.$apollo
|
||||
.mutate({
|
||||
@ -231,11 +223,6 @@ export default {
|
||||
updateEditorContent(value) {
|
||||
this.$refs.contributionForm.update('content', value)
|
||||
},
|
||||
availableLocales() {
|
||||
orderBy(locales, 'name').map(locale => {
|
||||
this.form.languageOptions.push({ label: locale.name, value: locale.code })
|
||||
})
|
||||
},
|
||||
addTeaserImage(file) {
|
||||
this.form.teaserImage = file
|
||||
},
|
||||
@ -295,4 +282,14 @@ export default {
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
.checkicon {
|
||||
cursor: default;
|
||||
top: -18px;
|
||||
}
|
||||
.checkicon_cat {
|
||||
top: -58px;
|
||||
}
|
||||
.colorRed {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -45,6 +45,7 @@ export const postFragment = lang => gql`
|
||||
deleted
|
||||
slug
|
||||
image
|
||||
language
|
||||
author {
|
||||
...user
|
||||
}
|
||||
|
||||
@ -580,7 +580,8 @@
|
||||
"filterFollow": "Beiträge filtern von Usern denen ich folge",
|
||||
"filterALL": "Alle Beiträge anzeigen",
|
||||
"success": "Gespeichert!",
|
||||
"languageSelectLabel": "Sprache",
|
||||
"languageSelectLabel": "Sprache deines Beitrags",
|
||||
"languageSelectText": "Sprache wählen",
|
||||
"categories": {
|
||||
"infoSelectedNoOfMaxCategories": "{chosen} von {max} Kategorien ausgewählt"
|
||||
},
|
||||
|
||||
@ -581,7 +581,8 @@
|
||||
"filterFollow": "Filter contributions from users I follow",
|
||||
"filterALL": "View all contributions",
|
||||
"success": "Saved!",
|
||||
"languageSelectLabel": "Language",
|
||||
"languageSelectLabel": "Language of your contribution",
|
||||
"languageSelectText": "Select Language",
|
||||
"categories": {
|
||||
"infoSelectedNoOfMaxCategories": "{chosen} of {max} categories selected"
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user