Skip to content

Commit badda3f

Browse files
Harminder VirkHarminder Virk
authored andcommitted
feat: flash validation errors summary to errorsBag
1 parent a47763a commit badda3f

File tree

3 files changed

+100
-0
lines changed

3 files changed

+100
-0
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"@adonisjs/assembler": "^7.2.3",
4747
"@adonisjs/core": "^6.3.1",
4848
"@adonisjs/eslint-config": "^1.3.0",
49+
"@adonisjs/i18n": "^2.0.1",
4950
"@adonisjs/prettier-config": "^1.3.0",
5051
"@adonisjs/redis": "^8.0.1",
5152
"@adonisjs/tsconfig": "^1.3.0",

src/session.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* file that was distributed with this source code.
88
*/
99

10+
import type { I18n } from '@adonisjs/i18n'
1011
import lodash from '@poppinss/utils/lodash'
1112
import { cuid } from '@adonisjs/core/helpers'
1213
import type { HttpContext } from '@adonisjs/core/http'
@@ -334,6 +335,26 @@ export class Session {
334335

335336
this.flashExcept(['_csrf', '_method', 'password', 'password_confirmation'])
336337

338+
/**
339+
* Adding the error summary to the "errorsBag" so that
340+
* we display the validation error globally using
341+
* the "@error" tag.
342+
*/
343+
let summary = 'The form could not be saved. Please check the errors below.'
344+
if ('i18n' in this.#ctx) {
345+
summary = (this.#ctx.i18n as I18n).t(
346+
`errors.${error.code}`,
347+
{
348+
count: error.messages.length,
349+
},
350+
summary
351+
)
352+
}
353+
354+
this.flashErrors({
355+
[String(error.code)]: summary,
356+
})
357+
337358
/**
338359
* Adding to inputErrorsBag for "@inputError" tag
339360
* to read validation errors

tests/session.spec.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { SimpleErrorReporter } from '@vinejs/vine'
1717
import { CookieClient } from '@adonisjs/core/http'
1818
import { fieldContext } from '@vinejs/vine/factories'
1919
import { AppFactory } from '@adonisjs/core/factories/app'
20+
import { I18nManagerFactory } from '@adonisjs/i18n/factories'
2021
import { ApplicationService, EventsList } from '@adonisjs/core/types'
2122
import { EncryptionFactory } from '@adonisjs/core/factories/encryption'
2223
import EdgeServiceProvider from '@adonisjs/core/providers/edge_provider'
@@ -973,6 +974,80 @@ test.group('Session | Flash', (group) => {
973974
email: ['Invalid email'],
974975
username: ['Invalid username', 'Username is required'],
975976
},
977+
errorsBag: {
978+
E_VALIDATION_ERROR: 'The form could not be saved. Please check the errors below.',
979+
},
980+
inputErrorsBag: {
981+
email: ['Invalid email'],
982+
username: ['Invalid username', 'Username is required'],
983+
},
984+
},
985+
})
986+
})
987+
988+
test('translate validation error summary', async ({ assert }) => {
989+
const i18nManager = new I18nManagerFactory()
990+
.merge({
991+
config: {
992+
loaders: [
993+
() => {
994+
return {
995+
async load() {
996+
return {
997+
en: {
998+
'errors.E_VALIDATION_ERROR': '{count} errors prohibited form submission',
999+
},
1000+
}
1001+
},
1002+
}
1003+
},
1004+
],
1005+
},
1006+
})
1007+
.create()
1008+
1009+
await i18nManager.loadTranslations()
1010+
1011+
let sessionId: string | undefined
1012+
1013+
const server = httpServer.create(async (req, res) => {
1014+
const request = new RequestFactory().merge({ req, res, encryption }).create()
1015+
const response = new ResponseFactory().merge({ req, res, encryption }).create()
1016+
const ctx = new HttpContextFactory().merge({ request, response }).create()
1017+
ctx.i18n = i18nManager.locale('en')
1018+
1019+
const session = new Session(sessionConfig, cookieDriver, emitter, ctx)
1020+
await session.initiate(false)
1021+
1022+
const errorReporter = new SimpleErrorReporter()
1023+
errorReporter.report('Invalid username', 'alpha', fieldContext.create('username', ''), {})
1024+
errorReporter.report(
1025+
'Username is required',
1026+
'required',
1027+
fieldContext.create('username', ''),
1028+
{}
1029+
)
1030+
errorReporter.report('Invalid email', 'email', fieldContext.create('email', ''), {})
1031+
1032+
session.flashValidationErrors(errorReporter.createError())
1033+
sessionId = session.sessionId
1034+
1035+
await session.commit()
1036+
response.finish()
1037+
})
1038+
1039+
const { headers } = await supertest(server).get('/')
1040+
const cookies = setCookieParser.parse(headers['set-cookie'], { map: true })
1041+
1042+
assert.deepEqual(cookieClient.decrypt(sessionId!, cookies[sessionId!].value), {
1043+
__flash__: {
1044+
errors: {
1045+
email: ['Invalid email'],
1046+
username: ['Invalid username', 'Username is required'],
1047+
},
1048+
errorsBag: {
1049+
E_VALIDATION_ERROR: '3 errors prohibited form submission',
1050+
},
9761051
inputErrorsBag: {
9771052
email: ['Invalid email'],
9781053
username: ['Invalid username', 'Username is required'],
@@ -1021,6 +1096,9 @@ test.group('Session | Flash', (group) => {
10211096
errors: {
10221097
name: ['Invalid name'],
10231098
},
1099+
errorsBag: {
1100+
E_VALIDATION_ERROR: 'The form could not be saved. Please check the errors below.',
1101+
},
10241102
inputErrorsBag: {
10251103
name: ['Invalid name'],
10261104
},

0 commit comments

Comments
 (0)