Add unit tests for models and services
- Implemented unit tests for the Package model, covering methods such as generateId, findById, findByName, and version management. - Created unit tests for the Repository model, including repository creation, name validation, and retrieval methods. - Added tests for the Session model, focusing on session creation, validation, and invalidation. - Developed unit tests for the User model, ensuring user creation, password hashing, and retrieval methods function correctly. - Implemented AuthService tests, validating login, token refresh, and session management. - Added TokenService tests, covering token creation, validation, and revocation processes.
This commit is contained in:
169
test/integration/auth.test.ts
Normal file
169
test/integration/auth.test.ts
Normal file
@@ -0,0 +1,169 @@
|
||||
/**
|
||||
* Authentication integration tests
|
||||
* Tests the full authentication flow through the API
|
||||
*/
|
||||
|
||||
import { assertEquals, assertExists } from 'jsr:@std/assert';
|
||||
import { describe, it, beforeAll, afterAll, beforeEach } from 'jsr:@std/testing/bdd';
|
||||
import {
|
||||
setupTestDb,
|
||||
teardownTestDb,
|
||||
cleanupTestDb,
|
||||
createTestUser,
|
||||
post,
|
||||
get,
|
||||
assertStatus,
|
||||
createAuthHeader,
|
||||
} from '../helpers/index.ts';
|
||||
|
||||
describe('Auth API Integration', () => {
|
||||
beforeAll(async () => {
|
||||
await setupTestDb();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await teardownTestDb();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await cleanupTestDb();
|
||||
});
|
||||
|
||||
describe('POST /api/v1/auth/login', () => {
|
||||
it('should login with valid credentials', async () => {
|
||||
const { user, password } = await createTestUser({
|
||||
email: 'api-login@example.com',
|
||||
status: 'active',
|
||||
});
|
||||
|
||||
const response = await post('/api/v1/auth/login', {
|
||||
email: user.email,
|
||||
password: password,
|
||||
});
|
||||
|
||||
assertStatus(response, 200);
|
||||
const body = response.body as Record<string, unknown>;
|
||||
assertExists(body.accessToken);
|
||||
assertExists(body.refreshToken);
|
||||
assertExists(body.user);
|
||||
});
|
||||
|
||||
it('should return 401 for invalid credentials', async () => {
|
||||
const response = await post('/api/v1/auth/login', {
|
||||
email: 'nonexistent@example.com',
|
||||
password: 'wrongpassword',
|
||||
});
|
||||
|
||||
assertStatus(response, 401);
|
||||
const body = response.body as Record<string, unknown>;
|
||||
assertEquals(body.error, 'INVALID_CREDENTIALS');
|
||||
});
|
||||
|
||||
it('should return 401 for inactive user', async () => {
|
||||
const { user, password } = await createTestUser({
|
||||
email: 'suspended@example.com',
|
||||
status: 'suspended',
|
||||
});
|
||||
|
||||
const response = await post('/api/v1/auth/login', {
|
||||
email: user.email,
|
||||
password: password,
|
||||
});
|
||||
|
||||
assertStatus(response, 401);
|
||||
const body = response.body as Record<string, unknown>;
|
||||
assertEquals(body.error, 'ACCOUNT_INACTIVE');
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api/v1/auth/refresh', () => {
|
||||
it('should refresh access token', async () => {
|
||||
const { user, password } = await createTestUser({
|
||||
email: 'refresh@example.com',
|
||||
status: 'active',
|
||||
});
|
||||
|
||||
// Login first
|
||||
const loginResponse = await post('/api/v1/auth/login', {
|
||||
email: user.email,
|
||||
password: password,
|
||||
});
|
||||
const loginBody = loginResponse.body as Record<string, unknown>;
|
||||
|
||||
// Refresh
|
||||
const refreshResponse = await post('/api/v1/auth/refresh', {
|
||||
refreshToken: loginBody.refreshToken,
|
||||
});
|
||||
|
||||
assertStatus(refreshResponse, 200);
|
||||
const refreshBody = refreshResponse.body as Record<string, unknown>;
|
||||
assertExists(refreshBody.accessToken);
|
||||
});
|
||||
|
||||
it('should return 401 for invalid refresh token', async () => {
|
||||
const response = await post('/api/v1/auth/refresh', {
|
||||
refreshToken: 'invalid-token',
|
||||
});
|
||||
|
||||
assertStatus(response, 401);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /api/v1/auth/me', () => {
|
||||
it('should return current user info', async () => {
|
||||
const { user, password } = await createTestUser({
|
||||
email: 'me@example.com',
|
||||
status: 'active',
|
||||
});
|
||||
|
||||
// Login
|
||||
const loginResponse = await post('/api/v1/auth/login', {
|
||||
email: user.email,
|
||||
password: password,
|
||||
});
|
||||
const loginBody = loginResponse.body as Record<string, unknown>;
|
||||
|
||||
// Get current user
|
||||
const meResponse = await get(
|
||||
'/api/v1/auth/me',
|
||||
createAuthHeader(loginBody.accessToken as string)
|
||||
);
|
||||
|
||||
assertStatus(meResponse, 200);
|
||||
const meBody = meResponse.body as Record<string, unknown>;
|
||||
assertEquals(meBody.email, user.email);
|
||||
});
|
||||
|
||||
it('should return 401 without token', async () => {
|
||||
const response = await get('/api/v1/auth/me');
|
||||
|
||||
assertStatus(response, 401);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api/v1/auth/logout', () => {
|
||||
it('should invalidate session', async () => {
|
||||
const { user, password } = await createTestUser({
|
||||
email: 'logout@example.com',
|
||||
status: 'active',
|
||||
});
|
||||
|
||||
// Login
|
||||
const loginResponse = await post('/api/v1/auth/login', {
|
||||
email: user.email,
|
||||
password: password,
|
||||
});
|
||||
const loginBody = loginResponse.body as Record<string, unknown>;
|
||||
const token = loginBody.accessToken as string;
|
||||
|
||||
// Logout
|
||||
const logoutResponse = await post('/api/v1/auth/logout', {}, createAuthHeader(token));
|
||||
|
||||
assertStatus(logoutResponse, 200);
|
||||
|
||||
// Token should no longer work
|
||||
const meResponse = await get('/api/v1/auth/me', createAuthHeader(token));
|
||||
assertStatus(meResponse, 401);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user