Skip to content

Commit e8e8e11

Browse files
committed
test: add tests for intended URL storage on unauthorized redirect
Verify that the session guard's error handler stores the intended URL for GET navigational requests (including Inertia), skips storage for AJAX and non-GET requests, skips when no route is matched, and forwards query strings to the login redirect.
1 parent aaf8a06 commit e8e8e11

File tree

1 file changed

+113
-1
lines changed

1 file changed

+113
-1
lines changed

tests/auth/e_unauthorized_access.spec.ts

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99

1010
import { test } from '@japa/runner'
1111
import { I18nManagerFactory } from '@adonisjs/i18n/factories'
12-
import { HttpContextFactory } from '@adonisjs/core/factories/http'
12+
import { EncryptionFactory } from '@adonisjs/core/factories/encryption'
1313
import { SessionMiddlewareFactory } from '@adonisjs/session/factories'
14+
import { HttpContextFactory, RequestFactory, ResponseFactory } from '@adonisjs/core/factories/http'
15+
16+
const encryption = new EncryptionFactory().create()
1417

1518
import { E_UNAUTHORIZED_ACCESS } from '../../src/errors.ts'
1619

@@ -54,6 +57,115 @@ test.group('Errors | E_UNAUTHORIZED_ACCESS | session', () => {
5457
assert.equal(ctx.response.getHeader('location'), '/login')
5558
})
5659

60+
test('store intended URL in session for GET navigational requests', async ({ assert }) => {
61+
const sessionMiddleware = await new SessionMiddlewareFactory().create()
62+
const error = new E_UNAUTHORIZED_ACCESS('Unauthorized access', {
63+
guardDriverName: 'session',
64+
redirectTo: '/login',
65+
})
66+
67+
const request = new RequestFactory()
68+
.merge({ encryption, url: '/billing?plan=pro', method: 'GET' })
69+
.create()
70+
const response = new ResponseFactory().merge({ encryption }).create()
71+
response.request.url = request.url(true)
72+
const ctx = new HttpContextFactory().merge({ request, response }).create()
73+
ctx.route = { pattern: '/billing', handler: {} } as any
74+
75+
await sessionMiddleware.handle(ctx, async () => {
76+
return error.handle(error, ctx)
77+
})
78+
79+
assert.equal(ctx.session.get('redirect.intendedUrl'), '/billing?plan=pro')
80+
assert.equal(ctx.response.getHeader('location'), '/login?plan=pro')
81+
})
82+
83+
test('store intended URL for Inertia requests', async ({ assert }) => {
84+
const sessionMiddleware = await new SessionMiddlewareFactory().create()
85+
const error = new E_UNAUTHORIZED_ACCESS('Unauthorized access', {
86+
guardDriverName: 'session',
87+
redirectTo: '/login',
88+
})
89+
90+
const request = new RequestFactory()
91+
.merge({ encryption, url: '/billing', method: 'GET' })
92+
.create()
93+
request.request.headers['x-inertia'] = 'true'
94+
const response = new ResponseFactory().merge({ encryption }).create()
95+
response.request.url = request.url(true)
96+
const ctx = new HttpContextFactory().merge({ request, response }).create()
97+
ctx.route = { pattern: '/billing', handler: {} } as any
98+
99+
await sessionMiddleware.handle(ctx, async () => {
100+
return error.handle(error, ctx)
101+
})
102+
103+
assert.equal(ctx.session.get('redirect.intendedUrl'), '/billing')
104+
})
105+
106+
test('do not store intended URL for AJAX requests', async ({ assert }) => {
107+
const sessionMiddleware = await new SessionMiddlewareFactory().create()
108+
const error = new E_UNAUTHORIZED_ACCESS('Unauthorized access', {
109+
guardDriverName: 'session',
110+
redirectTo: '/login',
111+
})
112+
113+
const request = new RequestFactory()
114+
.merge({ encryption, url: '/billing', method: 'GET' })
115+
.create()
116+
request.request.headers['x-requested-with'] = 'XMLHttpRequest'
117+
const response = new ResponseFactory().merge({ encryption }).create()
118+
const ctx = new HttpContextFactory().merge({ request, response }).create()
119+
ctx.route = { pattern: '/billing', handler: {} } as any
120+
121+
await sessionMiddleware.handle(ctx, async () => {
122+
return error.handle(error, ctx)
123+
})
124+
125+
assert.isNull(ctx.session.get('redirect.intendedUrl', null))
126+
})
127+
128+
test('do not store intended URL for non-GET requests', async ({ assert }) => {
129+
const sessionMiddleware = await new SessionMiddlewareFactory().create()
130+
const error = new E_UNAUTHORIZED_ACCESS('Unauthorized access', {
131+
guardDriverName: 'session',
132+
redirectTo: '/login',
133+
})
134+
135+
const request = new RequestFactory()
136+
.merge({ encryption, url: '/billing', method: 'POST' })
137+
.create()
138+
const response = new ResponseFactory().merge({ encryption }).create()
139+
const ctx = new HttpContextFactory().merge({ request, response }).create()
140+
ctx.route = { pattern: '/billing', handler: {} } as any
141+
142+
await sessionMiddleware.handle(ctx, async () => {
143+
return error.handle(error, ctx)
144+
})
145+
146+
assert.isNull(ctx.session.get('redirect.intendedUrl', null))
147+
})
148+
149+
test('do not store intended URL when no route is matched', async ({ assert }) => {
150+
const sessionMiddleware = await new SessionMiddlewareFactory().create()
151+
const error = new E_UNAUTHORIZED_ACCESS('Unauthorized access', {
152+
guardDriverName: 'session',
153+
redirectTo: '/login',
154+
})
155+
156+
const request = new RequestFactory()
157+
.merge({ encryption, url: '/not-found', method: 'GET' })
158+
.create()
159+
const response = new ResponseFactory().merge({ encryption }).create()
160+
const ctx = new HttpContextFactory().merge({ request, response }).create()
161+
162+
await sessionMiddleware.handle(ctx, async () => {
163+
return error.handle(error, ctx)
164+
})
165+
166+
assert.isNull(ctx.session.get('redirect.intendedUrl', null))
167+
})
168+
57169
test('respond with json', async ({ assert }) => {
58170
const error = new E_UNAUTHORIZED_ACCESS('Unauthorized access', {
59171
guardDriverName: 'session',

0 commit comments

Comments
 (0)