Advanced
Testing with Japa
Authenticate functional HTTP tests effortlessly using the simpleAuthApiClient Japa plugin.
@eienjs/adonisjs-simple-auth provides an official plugin for @japa/api-client that adds a .withApiKey() macro to ApiRequest. When called on a test request, it automatically reads apiKeyHeader and apiKeyValue from your config/simpleauth.ts file and attaches the header to the outgoing request.
Registering the Plugin
Open tests/bootstrap.ts and register simpleAuthApiClient(app) in your plugins array right after apiClient():
tests/bootstrap.ts
import type { Config } from '@japa/runner/types';
import app from '@adonisjs/core/services/app';
import { simpleAuthApiClient } from '@eienjs/adonisjs-simple-auth/plugins/api_client';
import { apiClient } from '@japa/api-client';
import { assert } from '@japa/assert';
import { pluginAdonisJS } from '@japa/plugin-adonisjs';
export const plugins: Config['plugins'] = [
assert(),
apiClient(),
pluginAdonisJS(app),
simpleAuthApiClient(app),
];
@japa/api-client (^3.2.1) must be installed in your project and config/simpleauth.ts must export a configuration created with defineConfig.Writing Authenticated Tests
Once the plugin is registered, chain .withApiKey() onto any client request in your functional tests:
tests/functional/users.spec.ts
import { test } from '@japa/runner';
test.group('Users API', () => {
test('returns 401 when API key header is not provided', async ({ client }) => {
const response = await client.get('/api/v1/users');
response.assertStatus(401);
response.assertBodyContains({
errors: [{ message: 'Unauthorized access' }],
});
});
test('returns users list when authenticated with withApiKey()', async ({ client }) => {
const response = await client.get('/api/v1/users').withApiKey();
response.assertStatus(200);
});
});
How .withApiKey() Works
- Resolves your
config/simpleauth.tsconfiguration via AdonisJSconfigProvider. - Registers the
withApiKey()macro onApiRequestand augments@japa/api-clientTypeScript types automatically. - Registers an
ApiClient.setuphook that inspects whether.withApiKey()was called on the current request, and if so, setsrequest.header(config.apiKeyHeader, config.apiKeyValue.release()).
Because the hook is scoped per request via a symbol flag, requests that do not call
.withApiKey() remain unauthenticated, making it easy to test both authorized and unauthorized scenarios in the same test group.