mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2026-03-01 12:44:28 +00:00
fix(webapp): fix lang query location (#9337)
This commit is contained in:
parent
4b0470310e
commit
d543c192a8
@ -40,6 +40,7 @@ export const getContext =
|
||||
req,
|
||||
cypherParams: {
|
||||
currentUserId: user ? user.id : null,
|
||||
languageDefault: config.LANGUAGE_DEFAULT.toUpperCase(),
|
||||
},
|
||||
config,
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ export default {
|
||||
nameNL: { type: 'string' },
|
||||
namePL: { type: 'string' },
|
||||
nameRU: { type: 'string' },
|
||||
nameSQ: { type: 'string' },
|
||||
isIn: {
|
||||
type: 'relationship',
|
||||
relationship: 'IS_IN',
|
||||
|
||||
@ -14,6 +14,7 @@ export interface LocationDbProperties {
|
||||
namePL: string
|
||||
namePT: string
|
||||
nameRU: string
|
||||
nameSQ: string
|
||||
type: string
|
||||
}
|
||||
|
||||
|
||||
@ -42,8 +42,6 @@ mutation CreateGroup(
|
||||
location {
|
||||
id
|
||||
name
|
||||
nameDE
|
||||
nameEN
|
||||
}
|
||||
myRole
|
||||
}
|
||||
|
||||
@ -25,8 +25,6 @@ query Group($isMember: Boolean, $id: ID, $slug: String) {
|
||||
location {
|
||||
id
|
||||
name
|
||||
nameDE
|
||||
nameEN
|
||||
}
|
||||
myRole
|
||||
inviteCodes {
|
||||
|
||||
@ -43,8 +43,6 @@ mutation UpdateGroup(
|
||||
location {
|
||||
id
|
||||
name
|
||||
nameDE
|
||||
nameEN
|
||||
}
|
||||
myRole
|
||||
}
|
||||
|
||||
@ -37,9 +37,6 @@ mutation UpdateUser(
|
||||
location {
|
||||
id
|
||||
name
|
||||
nameDE
|
||||
nameEN
|
||||
nameRU
|
||||
}
|
||||
emailNotificationSettings {
|
||||
type
|
||||
|
||||
@ -302,8 +302,6 @@ describe('in mode', () => {
|
||||
locationName: 'Hamburg, Germany',
|
||||
location: expect.objectContaining({
|
||||
name: 'Hamburg',
|
||||
nameDE: 'Hamburg',
|
||||
nameEN: 'Hamburg',
|
||||
}),
|
||||
},
|
||||
},
|
||||
@ -551,8 +549,6 @@ describe('in mode', () => {
|
||||
locationName: 'Hamburg, Germany',
|
||||
location: expect.objectContaining({
|
||||
name: 'Hamburg',
|
||||
nameDE: 'Hamburg',
|
||||
nameEN: 'Hamburg',
|
||||
}),
|
||||
myRole: 'owner',
|
||||
}),
|
||||
@ -2895,8 +2891,6 @@ describe('in mode', () => {
|
||||
locationName: 'Berlin, Germany',
|
||||
location: expect.objectContaining({
|
||||
name: 'Berlin',
|
||||
nameDE: 'Berlin',
|
||||
nameEN: 'Berlin',
|
||||
}),
|
||||
myRole: 'owner',
|
||||
},
|
||||
@ -2947,8 +2941,6 @@ describe('in mode', () => {
|
||||
locationName: 'Paris, France',
|
||||
location: expect.objectContaining({
|
||||
name: 'Paris',
|
||||
nameDE: 'Paris',
|
||||
nameEN: 'Paris',
|
||||
}),
|
||||
myRole: 'owner',
|
||||
},
|
||||
@ -2975,8 +2967,6 @@ describe('in mode', () => {
|
||||
locationName: 'Hamburg, Germany',
|
||||
location: expect.objectContaining({
|
||||
name: 'Hamburg',
|
||||
nameDE: 'Hamburg',
|
||||
nameEN: 'Hamburg',
|
||||
}),
|
||||
myRole: 'owner',
|
||||
},
|
||||
|
||||
@ -1,17 +1,29 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
import { parse } from 'graphql'
|
||||
|
||||
import Factory, { cleanDatabase } from '@db/factories'
|
||||
import UpdateUser from '@graphql/queries/users/UpdateUser.gql'
|
||||
import User from '@graphql/queries/users/User.gql'
|
||||
import { createApolloTestSetup } from '@root/test/helpers'
|
||||
|
||||
import type { ApolloTestSetup } from '@root/test/helpers'
|
||||
import type { Context } from '@src/context'
|
||||
|
||||
const UserLocationName = parse(`
|
||||
query User($id: ID, $lang: String) {
|
||||
User(id: $id) {
|
||||
id
|
||||
location {
|
||||
id
|
||||
name(lang: $lang)
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
let authenticatedUser: Context['user']
|
||||
const context = () => ({ authenticatedUser })
|
||||
let mutate: ApolloTestSetup['mutate']
|
||||
let query: ApolloTestSetup['query']
|
||||
let database: ApolloTestSetup['database']
|
||||
let server: ApolloTestSetup['server']
|
||||
@ -19,7 +31,6 @@ let server: ApolloTestSetup['server']
|
||||
beforeAll(async () => {
|
||||
await cleanDatabase()
|
||||
const apolloSetup = await createApolloTestSetup({ context })
|
||||
mutate = apolloSetup.mutate
|
||||
query = apolloSetup.query
|
||||
database = apolloSetup.database
|
||||
server = apolloSetup.server
|
||||
@ -39,41 +50,84 @@ afterEach(async () => {
|
||||
|
||||
describe('resolvers', () => {
|
||||
describe('Location', () => {
|
||||
describe('custom mutation, not handled by neo4j-graphql-js', () => {
|
||||
let variables
|
||||
|
||||
describe('name(lang)', () => {
|
||||
beforeEach(async () => {
|
||||
variables = {
|
||||
id: 'u47',
|
||||
name: 'John Doughnut',
|
||||
}
|
||||
const Paris = await Factory.build('location', {
|
||||
id: 'region.9397217726497330',
|
||||
name: 'Paris',
|
||||
const Hamburg = await Factory.build('location', {
|
||||
id: 'region.5127278006398860',
|
||||
name: 'Hamburg',
|
||||
type: 'region',
|
||||
lng: 2.35183,
|
||||
lat: 48.85658,
|
||||
nameEN: 'Paris',
|
||||
lng: 10.0,
|
||||
lat: 53.55,
|
||||
nameEN: 'Hamburg',
|
||||
nameDE: 'Hamburg',
|
||||
nameIT: 'Amburgo',
|
||||
nameRU: 'Гамбург',
|
||||
nameFR: 'Hambourg',
|
||||
nameES: 'Hamburgo',
|
||||
})
|
||||
|
||||
const user = await Factory.build('user', {
|
||||
id: 'u47',
|
||||
name: 'John Doe',
|
||||
})
|
||||
await user.relateTo(Paris, 'isIn')
|
||||
await user.relateTo(Hamburg, 'isIn')
|
||||
authenticatedUser = await user.toJson()
|
||||
})
|
||||
|
||||
it('returns `null` if location translation is not available', async () => {
|
||||
await expect(mutate({ mutation: UpdateUser, variables })).resolves.toMatchObject({
|
||||
it('returns the name in the requested language', async () => {
|
||||
await expect(
|
||||
query({ query: UserLocationName, variables: { id: 'u47', lang: 'RU' } }),
|
||||
).resolves.toMatchObject({
|
||||
data: {
|
||||
UpdateUser: {
|
||||
name: 'John Doughnut',
|
||||
location: {
|
||||
nameRU: null,
|
||||
nameEN: 'Paris',
|
||||
User: [
|
||||
expect.objectContaining({
|
||||
location: expect.objectContaining({ name: 'Гамбург' }),
|
||||
}),
|
||||
],
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
|
||||
it('returns a different name for a different language', async () => {
|
||||
await expect(
|
||||
query({ query: UserLocationName, variables: { id: 'u47', lang: 'IT' } }),
|
||||
).resolves.toMatchObject({
|
||||
data: {
|
||||
User: [
|
||||
expect.objectContaining({
|
||||
location: expect.objectContaining({ name: 'Amburgo' }),
|
||||
}),
|
||||
],
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
|
||||
it('returns the default name when no lang is provided', async () => {
|
||||
await expect(
|
||||
query({ query: UserLocationName, variables: { id: 'u47' } }),
|
||||
).resolves.toMatchObject({
|
||||
data: {
|
||||
User: [
|
||||
expect.objectContaining({
|
||||
location: expect.objectContaining({ name: 'Hamburg' }),
|
||||
}),
|
||||
],
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
|
||||
it('falls back to default when the requested translation does not exist', async () => {
|
||||
await expect(
|
||||
query({ query: UserLocationName, variables: { id: 'u47', lang: 'ZZ' } }),
|
||||
).resolves.toMatchObject({
|
||||
data: {
|
||||
User: [
|
||||
expect.objectContaining({
|
||||
location: expect.objectContaining({ name: 'Hamburg' }),
|
||||
}),
|
||||
],
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
|
||||
@ -5,26 +5,12 @@
|
||||
/* eslint-disable @typescript-eslint/return-await */
|
||||
import { UserInputError } from '@graphql/errors'
|
||||
|
||||
import Resolver from './helpers/Resolver'
|
||||
import { queryLocations } from './users/location'
|
||||
|
||||
import type { Context } from '@src/context'
|
||||
|
||||
export default {
|
||||
Location: {
|
||||
...Resolver('Location', {
|
||||
undefinedToNull: [
|
||||
'nameEN',
|
||||
'nameDE',
|
||||
'nameFR',
|
||||
'nameNL',
|
||||
'nameIT',
|
||||
'nameES',
|
||||
'namePT',
|
||||
'namePL',
|
||||
'nameRU',
|
||||
],
|
||||
}),
|
||||
distanceToMe: async (parent, _params, context: Context, _resolveInfo) => {
|
||||
if (!parent.id) {
|
||||
throw new Error('Can not identify selected Location!')
|
||||
|
||||
@ -245,8 +245,6 @@ describe('UpdateUser', () => {
|
||||
locationName: 'Hamburg, New Jersey, United States',
|
||||
location: expect.objectContaining({
|
||||
name: 'Hamburg',
|
||||
nameDE: 'Hamburg',
|
||||
nameEN: 'Hamburg',
|
||||
}),
|
||||
},
|
||||
},
|
||||
|
||||
@ -34,6 +34,7 @@ const newlyCreatedNodesWithLocales = [
|
||||
nameRU: 'Вельцхайм',
|
||||
nameNL: 'Welzheim',
|
||||
namePL: 'Welzheim',
|
||||
nameSQ: 'Welzheim',
|
||||
lng: 9.634301,
|
||||
lat: 48.874393,
|
||||
},
|
||||
@ -50,6 +51,7 @@ const newlyCreatedNodesWithLocales = [
|
||||
namePL: 'Badenia-Wirtembergia',
|
||||
namePT: 'Baden-Württemberg',
|
||||
nameRU: 'Баден-Вюртемберг',
|
||||
nameSQ: 'Baden-Vyrtemberg',
|
||||
},
|
||||
country: {
|
||||
id: expect.stringContaining('country'),
|
||||
@ -64,6 +66,7 @@ const newlyCreatedNodesWithLocales = [
|
||||
namePL: 'Niemcy',
|
||||
namePT: 'Alemanha',
|
||||
nameRU: 'Германия',
|
||||
nameSQ: 'Gjermania',
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
@ -13,7 +13,7 @@ import { UserInputError } from '@graphql/errors'
|
||||
|
||||
import type { Context } from '@src/context'
|
||||
|
||||
const locales = ['en', 'de', 'fr', 'nl', 'it', 'es', 'pt', 'pl', 'ru']
|
||||
const locales = ['en', 'de', 'fr', 'nl', 'it', 'es', 'pt', 'pl', 'ru', 'sq']
|
||||
|
||||
const REQUEST_TIMEOUT = 3000
|
||||
|
||||
@ -29,6 +29,7 @@ const createLocation = async (session, mapboxData) => {
|
||||
namePT: mapboxData.text_pt,
|
||||
namePL: mapboxData.text_pl,
|
||||
nameRU: mapboxData.text_ru,
|
||||
nameSQ: mapboxData.text_sq,
|
||||
type: mapboxData.id.split('.')[0].toLowerCase(),
|
||||
address: mapboxData.address,
|
||||
lng: mapboxData.center?.length ? mapboxData.center[0] : null,
|
||||
@ -47,6 +48,7 @@ const createLocation = async (session, mapboxData) => {
|
||||
'l.namePT = $namePT, ' +
|
||||
'l.namePL = $namePL, ' +
|
||||
'l.nameRU = $nameRU, ' +
|
||||
'l.nameSQ = $nameSQ, ' +
|
||||
'l.type = $type'
|
||||
|
||||
if (data.lat && data.lng) {
|
||||
|
||||
@ -1,15 +1,17 @@
|
||||
type Location {
|
||||
id: ID!
|
||||
name: String!
|
||||
nameEN: String
|
||||
nameDE: String
|
||||
nameFR: String
|
||||
nameNL: String
|
||||
nameIT: String
|
||||
nameES: String
|
||||
namePT: String
|
||||
namePL: String
|
||||
nameRU: String
|
||||
name(lang: String = ""): String!
|
||||
@cypher(
|
||||
statement: """
|
||||
RETURN COALESCE(
|
||||
CASE WHEN $lang <> '' THEN this['name' + toUpper($lang)] END,
|
||||
this['name' + $cypherParams.languageDefault],
|
||||
this.name,
|
||||
this.nameEN,
|
||||
this.id
|
||||
)
|
||||
"""
|
||||
)
|
||||
type: String!
|
||||
lat: Float
|
||||
lng: Float
|
||||
|
||||
@ -59,6 +59,7 @@ describe('LocationSelect', () => {
|
||||
place: 'nowhere',
|
||||
lang: 'en',
|
||||
},
|
||||
fetchPolicy: 'network-only',
|
||||
})
|
||||
})
|
||||
|
||||
@ -69,8 +70,8 @@ describe('LocationSelect', () => {
|
||||
|
||||
it('emits an empty string', () => {
|
||||
expect(wrapper.emitted().input).toBeTruthy()
|
||||
expect(wrapper.emitted().input.length).toBe(1)
|
||||
expect(wrapper.emitted().input[0]).toEqual([''])
|
||||
const lastEmit = wrapper.emitted().input[wrapper.emitted().input.length - 1]
|
||||
expect(lastEmit).toEqual([''])
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@ -40,6 +40,7 @@ export default {
|
||||
components: { OsButton, OsIcon },
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Object],
|
||||
required: true,
|
||||
},
|
||||
canBeCleared: {
|
||||
@ -55,10 +56,7 @@ export default {
|
||||
},
|
||||
async created() {
|
||||
this.icons = iconRegistry
|
||||
const result = await this.requestGeoData(this.locationName)
|
||||
this.$nextTick(() => {
|
||||
this.currentValue = result || this.locationName
|
||||
})
|
||||
await this.resolveLocalizedLocation()
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -74,6 +72,9 @@ export default {
|
||||
locationNameLabelAddOnOldName() {
|
||||
return this.locationName !== '' && this.showPreviousLocation ? ' — ' + this.locationName : ''
|
||||
},
|
||||
currentLocale() {
|
||||
return this.$store && this.$store.state.i18n && this.$store.state.i18n.locale
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
currentValue() {
|
||||
@ -81,10 +82,19 @@ export default {
|
||||
this.$emit('input', this.currentValue)
|
||||
}
|
||||
},
|
||||
value() {
|
||||
if (this.value !== this.currentValue) {
|
||||
this.currentValue = this.value
|
||||
value(newVal, oldVal) {
|
||||
if (newVal !== this.currentValue) {
|
||||
this.currentValue = newVal
|
||||
}
|
||||
// resolve when value is set after initial mount (e.g. settings page)
|
||||
const newName = typeof newVal === 'object' ? newVal.value : newVal
|
||||
const oldName = typeof oldVal === 'object' ? oldVal.value : oldVal
|
||||
if (newName && newName !== oldName) {
|
||||
this.resolveLocalizedLocation()
|
||||
}
|
||||
},
|
||||
currentLocale() {
|
||||
this.resolveLocalizedLocation()
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
@ -124,7 +134,11 @@ export default {
|
||||
|
||||
const {
|
||||
data: { queryLocations: result },
|
||||
} = await this.$apollo.query({ query: queryLocations(), variables: { place, lang } })
|
||||
} = await this.$apollo.query({
|
||||
query: queryLocations(),
|
||||
variables: { place, lang },
|
||||
fetchPolicy: 'network-only',
|
||||
})
|
||||
|
||||
this.cities = this.processLocationsResult(result)
|
||||
this.loadingGeo = false
|
||||
@ -136,6 +150,13 @@ export default {
|
||||
this.loadingGeo = false
|
||||
}
|
||||
},
|
||||
async resolveLocalizedLocation() {
|
||||
if (!this.locationName) return
|
||||
const result = await this.requestGeoData(this.locationName)
|
||||
this.$nextTick(() => {
|
||||
this.currentValue = result || (this.cities.length ? this.cities[0] : this.locationName)
|
||||
})
|
||||
},
|
||||
clearLocationName() {
|
||||
this.currentValue = ''
|
||||
},
|
||||
|
||||
@ -5,7 +5,7 @@ export const location = (type, lang) => gql`
|
||||
locationName
|
||||
location {
|
||||
id
|
||||
name: name${lang}
|
||||
name(lang: "${lang}")
|
||||
lng
|
||||
lat
|
||||
distanceToMe
|
||||
|
||||
@ -149,8 +149,6 @@ describe('GroupProfileSlug', () => {
|
||||
locationName: 'France',
|
||||
location: {
|
||||
name: 'Paris',
|
||||
nameDE: 'Paris',
|
||||
nameEN: 'Paris',
|
||||
},
|
||||
isMutedByMe: true,
|
||||
membersCount: 0,
|
||||
@ -193,8 +191,6 @@ describe('GroupProfileSlug', () => {
|
||||
locationName: 'Hamburg, Germany',
|
||||
location: {
|
||||
name: 'Hamburg',
|
||||
nameDE: 'Hamburg',
|
||||
nameEN: 'Hamburg',
|
||||
},
|
||||
isMutedByMe: false,
|
||||
membersCount: 0,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user