From 1add2ffae72291311255d7a47758f3f0bb588076 Mon Sep 17 00:00:00 2001 From: lesion Date: Thu, 27 Oct 2022 15:09:11 +0200 Subject: [PATCH] trim place's name and description + event's title - fix #189 --- components/Event.vue | 4 +- components/WhereInput.vue | 8 ++-- pages/place/_place.vue | 2 +- server/api/controller/event.js | 68 +++++++++++++++++----------------- tests/app.test.js | 28 ++++++++------ 5 files changed, 58 insertions(+), 52 deletions(-) diff --git a/components/Event.vue b/components/Event.vue index 867549db..e6cf69ee 100644 --- a/components/Event.vue +++ b/components/Event.vue @@ -8,12 +8,12 @@ v-card.h-event.event.d-flex(itemscope itemtype="https://schema.org/Event") v-card-text.body.pt-0.pb-0 time.dt-start.subtitle-1(:datetime='event.start_datetime | unixFormat("YYYY-MM-DD HH:mm")' itemprop="startDate" :content="event.start_datetime | unixFormat('YYYY-MM-DDTHH:mm')") {{ event | when }} .d-none.dt-end(itemprop="endDate" :content="event.end_datetime | unixFormat('YYYY-MM-DDTHH:mm')") {{ event.end_datetime | unixFormat('YYYY-MM-DD HH:mm') }} - nuxt-link.place.d-block.p-location.pl-0(text color='primary' :to='`/place/${event.place.name}`' itemprop="location" itemscope itemtype="https://schema.org/Place") {{ event.place.name }} + nuxt-link.place.d-block.p-location.pl-0(text color='primary' :to='`/place/${encodeURIComponent(event.place.name)}`' itemprop="location" itemscope itemtype="https://schema.org/Place") {{ event.place.name }} .d-none(itemprop='address') {{ event.place.address }} v-card-actions.pt-0.actions.justify-space-between .tags - v-chip.ml-1.mt-1(v-for='tag in event.tags.slice(0, 6)' small :to='`/tag/${tag}`' + v-chip.ml-1.mt-1(v-for='tag in event.tags.slice(0, 6)' small :to='`/tag/${encodeURIComponent(tag)}`' :key='tag' outlined color='primary') {{ tag }} diff --git a/components/WhereInput.vue b/components/WhereInput.vue index c4542cff..cc744cdd 100644 --- a/components/WhereInput.vue +++ b/components/WhereInput.vue @@ -10,6 +10,7 @@ v-row hide-no-data @input.native='search' persistent-hint + :value='value' :items="places" item-text='name' @focus='search' @@ -83,13 +84,13 @@ export default { selectPlace (p) { if (!p) { return } if (typeof p === 'object' && !p.create) { - this.place.name = p.name.trim() + this.place.name = p.name this.place.address = p.address this.place.id = p.id this.disableAddress = true } else { // this is a new place - this.place.name = p.name || p - const tmpPlace = this.place.name.trim().toLocaleLowerCase() + this.place.name = (p.name || p).trim() + const tmpPlace = this.place.name.toLocaleLowerCase() // search for a place with the same name const place = this.places.find(p => !p.create && p.name.trim().toLocaleLowerCase() === tmpPlace) if (place) { @@ -99,7 +100,6 @@ export default { this.disableAddress = true } else { delete this.place.id - this.place.name = tmpPlace this.place.address = '' this.disableAddress = false this.$refs.place.blur() diff --git a/pages/place/_place.vue b/pages/place/_place.vue index a1e1f500..43738ab9 100644 --- a/pages/place/_place.vue +++ b/pages/place/_place.vue @@ -33,7 +33,7 @@ export default { asyncData({ $axios, params, error }) { try { const place = params.place - return $axios.$get(`/place/${place}`) + return $axios.$get(`/place/${encodeURIComponent(place)}`) } catch (e) { error({ statusCode: 400, message: 'Error!' }) } diff --git a/server/api/controller/event.js b/server/api/controller/event.js index 8ad33537..063dc6cb 100644 --- a/server/api/controller/event.js +++ b/server/api/controller/event.js @@ -23,6 +23,30 @@ const log = require('../../log') const eventController = { + async _findOrCreatePlace (body) { + if (body.place_id) { + const place = await Place.findByPk(body.place_id) + if (!place) { + throw new Error(`Place not found`) + } + return place + } + + const place_name = body.place_name && body.place_name.trim() + const place_address = body.place_address && body.place_address.trim() + if (!place_address || !place_name) { + throw new Error(`place_id or place_name and place_address are required`) + } + let place = await Place.findOne({ where: Sequelize.where(Sequelize.fn('LOWER', Sequelize.col('name')), Sequelize.Op.eq, place_name.toLocaleLowerCase()) }) + if (!place) { + place = await Place.create({ + name: place_name, + address: place_address + }) + } + return place + }, + async searchMeta(req, res) { const search = req.query.search @@ -389,29 +413,18 @@ const eventController = { // find or create the place let place - if (body.place_id) { - place = await Place.findByPk(body.place_id) + try { + place = await eventController._findOrCreatePlace(body) if (!place) { return res.status(400).send(`Place not found`) } - } else { - if (!body.place_name) { - return res.status(400).send(`Place not found`) - } - place = await Place.findOne({ where: Sequelize.where(Sequelize.fn('LOWER', Sequelize.col('name')), Op.eq, body.place_name.trim().toLocaleLowerCase()) }) - if (!place) { - if (!body.place_address || !body.place_name) { - return res.status(400).send(`place_id or place_name and place_address required`) - } - place = await Place.create({ - name: body.place_name, - address: body.place_address - }) - } + } catch (e) { + return res.status(400).send(e.message) } + const eventDetails = { - title: body.title, + title: body.title.trim(), // sanitize and linkify html description: helpers.sanitizeHTML(linkifyHtml(body.description || '')), multidate: body.multidate, @@ -543,27 +556,14 @@ const eventController = { // find or create the place let place - if (body.place_id) { - place = await Place.findByPk(body.place_id) + try { + place = await eventController._findOrCreatePlace(body) if (!place) { return res.status(400).send(`Place not found`) } - } else { - if (!body.place_name) { - return res.status(400).send(`Place not found`) - } - place = await Place.findOne({ where: Sequelize.where(Sequelize.fn('LOWER', Sequelize.col('name')), Op.eq, body.place_name.trim().toLocaleLowerCase()) }) - if (!place) { - if (!body.place_address || !body.place_name) { - return res.status(400).send(`place_id or place_name and place_address required`) - } - place = await Place.create({ - name: body.place_name, - address: body.place_address - }) - } + } catch (e) { + return res.status(400).send(e.message) } - await event.setPlace(place) // create/assign tags diff --git a/tests/app.test.js b/tests/app.test.js index b4dcfd6c..8c1e8a9f 100644 --- a/tests/app.test.js +++ b/tests/app.test.js @@ -155,7 +155,7 @@ describe('Events', () => { const required_fields = { 'title': {}, 'start_datetime': { title: 'test title' }, - 'place_id or place_name and place_address': { title: 'test title', start_datetime: dayjs().unix() + 1000, place_name: 'test place name' }, + 'place_id or place_name and place_address are': { title: 'test title', start_datetime: dayjs().unix() + 1000, place_name: 'test place name' }, } const promises = Object.keys(required_fields).map(async field => { @@ -200,9 +200,9 @@ describe('Events', () => { }) - test('should trim tags', async () => { + test('should trim tags and title', async () => { const event = { - title: 'test title 4', + title: ' test title 4 ', place_id: places[0], start_datetime: dayjs().unix() + 1000, tags: [' test tag '] @@ -213,6 +213,7 @@ describe('Events', () => { .expect(200) .expect('Content-Type', /json/) + expect(response.body.title).toBe('test title 4') expect(response.body.tags[0]).toBe('test tag') }) }) @@ -300,6 +301,17 @@ describe('Place', () => { expect(response.body.length).toBe(2) }) + test('should trim place\'s name and address', async () => { + const ret = await request(app).post('/api/event') + .send({ title: 'test trimming', place_name: ' test place with white Space ', + place_address: ' address with Space ', start_datetime: dayjs().unix() + 1000 }) + .auth(token.access_token, { type: 'bearer' }) + .expect(200) + + expect(ret.body.place.name).toBe('test place with white Space') + expect(ret.body.place.address).toBe('address with Space') + }) + }) let collections = [] @@ -382,20 +394,14 @@ describe('Collection', () => { }) test('shoud filter for tags', async () => { - let response = await request(app) + await request(app) .post('/api/filter') .send({ collectionId: collections[0], tags: ['test'] }) .auth(token.access_token, { type: 'bearer' }) .expect(200) - // response = await request(app) - // .get(`/api/filter/${response.body.id}`) - // .auth(token.access_token, { type: 'bearer' }) - // .expect(200) - // expect(response.body.length).toBe(1) - - response = await request(app) + const response = await request(app) .get(`/api/collections/test collection`) .expect(200)