Skip to content

Commit

Permalink
Release 9.2.5 (#218)
Browse files Browse the repository at this point in the history
* bump v9.2.5

* Fix "*.validate.customMessage" translations (#217)

* chore(browserslist): run `npx browserslist@latest --update-db`

* fix(i18n): patch Component properties with 'validate.customMessage' getterr

* fix(i18n): surface key.errorLabel strings from the API

* fix(i18n): rework error message translations

rename patch function, move tests from patch.js to translation.js, and translate key.errorLabel in built-in messages

* fix(i18n): fall back errorLabel to placeholder, label, key

* fix(i18n): add zh "required" translation

Co-authored-by: Nicole Lee <nlsfds@users.noreply.github.com>

* chore: delete unused translations.json

* chore(npm): delete unused "update-translations" npm script

* chore(optimize): remove .class-debug styles

* chore: delete _debug.scss

* chore(tests): add tests for mergeObjects(), Chinese "required" translation

* feat(i18n): add "Get started" translations

* chore(tests): add more translation smoke tests

* chore(tests): fix up some more i18n tests

* fix(i18n): refactor translation resolution

Co-authored-by: Nicole Lee <nlsfds@users.noreply.github.com>

Co-authored-by: shawnbot <shawnbot@users.noreply.github.com>
Co-authored-by: Nicole Lee <nlsfds@users.noreply.github.com>
  • Loading branch information
3 people authored Mar 10, 2022
1 parent 4bc80fc commit 91d6208
Show file tree
Hide file tree
Showing 13 changed files with 269 additions and 229 deletions.
36 changes: 31 additions & 5 deletions __tests__/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,13 @@ describe('form localization', () => {
{
type: 'textfield',
key: 'name',
label: 'Name',
input: true
label: 'Name'
}
]
}, {
language: 'zh',
i18n: {
'zh-hant': {
zh: {
Name: 'boaty mcboatface'
}
}
Expand All @@ -91,13 +90,18 @@ describe('form localization', () => {
})

it('fetches translations from the URL if provided a string', async () => {
loadTranslations.mockImplementationOnce(() => ({
loadTranslations.mockResolvedValueOnce({
es: {
hello: 'hola'
}
}))
})
const form = await createForm({}, { i18n: mockUrl, language: 'es' })
expect(loadTranslations).toHaveBeenCalledWith(mockUrl)
expect(form.i18next.getDataByLanguage('es')?.translation).toEqual(
expect.objectContaining({
hello: 'hola'
})
)
expect(form.t('hello')).toEqual('hola')
destroyForm(form)
})
Expand Down Expand Up @@ -392,6 +396,28 @@ describe('i18n extraction', () => {
})
})

describe('errorLabel', () => {
it('gets the errorLabel', () => {
const strings = getStrings({
components: [
{
key: 'a',
errorLabel: 'A is required!'
},
{
key: 'b',
errorLabel: 'B must match the pattern'
}
]
})

expect(strings).toHaveLength(2)
expect(strings[0].key).toBe('a.errorLabel')
expect(strings[0].value).toBe('A is required!')
expect(strings[1].key).toBe('b.errorLabel')
expect(strings[1].value).toBe('B must match the pattern')
})
})
describe('errors map', () => {
it('gets a string for each non-empty key/value in component.errors', () => {
const strings = getStrings({
Expand Down
110 changes: 110 additions & 0 deletions __tests__/translation.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,39 @@ import { createForm, destroyForm } from '../lib/test-helpers'
import '../dist/formio-sfds.standalone.js'

describe('generic string translations', () => {
describe('translation string management', () => {
it('gets default translations without an "i18n" option', async () => {
const form = await createForm()
expect(form.options.i18n?.resources).toEqual(
expect.objectContaining({
en: expect.any(Object),
es: expect.any(Object),
tl: expect.any(Object),
zh: expect.any(Object)
})
)
})

it('can override translations', async () => {
const form = await createForm({
components: []
}, {
language: 'es',
i18n: {
es: {
hello: 'hola'
}
}
})
expect(form.t('hello')).toEqual('hola')
expect(form.t('Get started')).toEqual('Comenzar')
})
})

describe('translates validation error types', () => {
it('without custom translations', async () => {
const form = await createForm()
expect(form.i18next.getDataByLanguage('es')?.translation?.required).toBe('{{field}} es requerido')
expect(form.t('required', { field: 'foo' })).toEqual('foo is required')
await (form.language = 'es')
expect(form.t('required', { field: 'foo' })).toEqual('foo es requerido')
Expand Down Expand Up @@ -116,4 +146,84 @@ describe('field translations', () => {

destroyForm(form)
})

describe('finds the "key.validate.customMessage" translations', () => {
it('works', async () => {
const form = await createForm({
components: [
{
key: 'name',
type: 'textfield',
validate: {
required: true,
customMessage: 'English error message'
}
}
]
}, {
language: 'es',
i18n: {
es: {
'name.validate.customMessage': 'Spanish error message'
}
}
})
const errors = await form.submit().catch(errors => errors)
expect(errors).toHaveLength(1)
expect(errors[0].message).toBe('Spanish error message')
destroyForm(form)
})
})

it('translates the field label in default error messages', async () => {
const form = await createForm({
components: [
{
key: 'age',
type: 'textfield',
label: 'Age',
validate: {
required: true
}
}
]
}, {
language: 'es',
i18n: {
es: {
'age.label': 'Edad'
}
}
})
const errors = await form.submit().catch(errors => errors)
expect(errors).toHaveLength(1)
expect(errors[0].message).toBe('Edad es requerido')
destroyForm(form)
})

it('translates Chinese required errors', async () => {
const form = await createForm({
components: [
{
key: 'name',
label: 'Name',
validate: {
required: true
}
}
]
}, {
language: 'zh',
i18n: {
zh: {
'name.label': '全名'
}
}
})

const errors = await form.submit().catch(errors => errors)
expect(errors).toHaveLength(1)
expect(errors[0].message).toBe('全名 必填')
destroyForm(form)
})
})
48 changes: 48 additions & 0 deletions __tests__/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/* eslint-env jest */
import { mergeObjects } from '../src/utils'

describe('mergeObjects()', () => {
it('merges deeply', () => {
expect(mergeObjects({
one: 1,
two: {
three: 3
}
}, {
four: 4,
two: {
five: 5
}
})).toEqual({
one: 1,
two: {
three: 3,
five: 5
},
four: 4
})
})

it('preserves keys in the original object', () => {
expect(mergeObjects({
i18n: {
zh: {
original: 'original'
}
}
}, {
i18n: {
zh: {
other: 'other'
}
}
})).toEqual({
i18n: {
zh: {
original: 'original',
other: 'other'
}
}
})
})
})
1 change: 1 addition & 0 deletions lib/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ function getStrings (form) {
}
}),
fieldGetter('validate.customMessage'),
fieldGetter('errorLabel'),
fieldGetter('errors', (errors, component, path) => {
const strings = []
for (const [type, value] of Object.entries(errors)) {
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "formio-sfds",
"version": "9.2.4",
"version": "9.2.5",
"description": "The Form.io theme for sf.gov",
"module": "src/index.js",
"browser": "dist/formio-sfds.standalone.js",
Expand All @@ -16,7 +16,6 @@
"lint-js": "eslint src __tests__ lib api '*.js'",
"start": "node server.js",
"test": "jest",
"update-translations": "script/get-translations > src/i18n/translations.json",
"snaps": "npm run build-js && npm test -- -u",
"watch": "run-s build-css watch-all",
"watch-all": "run-p watch-css watch-js watch-views",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"february": "Febrero",
"File Name": "Nombre del archivo",
"File name": "Nombre del archivo",
"Get started": "Comenzar",
"january": "Enero",
"july": "Julio",
"june": "Junio",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/tl.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"Drop files to attach, or": "I-drop ang mga file para i-attach, o",
"File Name": "Pangalan ng File",
"File name": "Pangalan ng File",
"Get started": "Magsimula",
"next": "Susunod",
"Size": "Laki",
"Submit": "I-padala dito."
Expand Down
Loading

0 comments on commit 91d6208

Please sign in to comment.