Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions app/api/auth.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import express from 'express';
import request from 'supertest';
import * as auth from './auth';
import * as store from '../store';

Check warning on line 4 in app/api/auth.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'store' is defined but never used

Check warning on line 4 in app/api/auth.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'store' is defined but never used
import * as registry from '../registry';

Check warning on line 5 in app/api/auth.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'registry' is defined but never used

Check warning on line 5 in app/api/auth.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'registry' is defined but never used

jest.mock('../store', () => ({
getConfiguration: jest.fn(() => ({
path: '/tmp',
file: 'test.db',
})),
}));

jest.mock('../registry', () => ({
getState: jest.fn(() => ({
authentication: {
mockAuth: {
getId: () => 'mockAuth',
getStrategy: () => ({ name: 'mockStrategy' }),
getStrategyDescription: () => ({
type: 'mock',
name: 'Mock Auth',
logoutUrl: 'http://logout',
}),
},
},
})),
}));

jest.mock('getmac', () => jest.fn(() => '00:00:00:00:00:00'));
jest.mock('uuid', () => ({
v5: jest.fn(() => '12345678-1234-5678-1234-567812345678'),
}));

jest.mock('../configuration', () => ({
getVersion: jest.fn(() => '1.0.0'),
getLogLevel: jest.fn(() => 'info'),
}));

describe('API Auth', () => {
let app: express.Express;

beforeEach(() => {
jest.clearAllMocks();
app = express();
app.use(express.json());

// Mock passport authentication middleware so it passes
const passport = require('passport');
jest.spyOn(passport, 'authenticate').mockImplementation(
() => (req: any, res: any, next: any) => {
req.user = { username: 'testuser' };
req.isAuthenticated = () => true;
next();
},
);
jest.spyOn(passport, 'initialize').mockImplementation(
() => (req: any, res: any, next: any) => {
req.logout = jest.fn((cb: any) => {
if (typeof cb === 'function') cb(null);
});
req.isAuthenticated = () => true;
req.user = { username: 'testuser' };
next();
},
);
jest.spyOn(passport, 'session').mockImplementation(
() => (req: any, res: any, next: any) => next(),
);

auth.init(app);
});

test('GET /auth/strategies should return unique strategies', async () => {
const res = await request(app).get('/auth/strategies');
expect(res.status).toBe(200);
expect(res.body).toEqual([
{ type: 'mock', name: 'Mock Auth', logoutUrl: 'http://logout' },
]);
});

test('POST /auth/login should return user', async () => {
const res = await request(app).post('/auth/login');
expect(res.status).toBe(200);
expect(res.body).toEqual({ username: 'testuser' });
});

test('GET /auth/user should return current user', async () => {
const res = await request(app).get('/auth/user');
expect(res.status).toBe(200);
expect(res.body).toEqual({ username: 'testuser' });
});

test('POST /auth/logout should clear session', async () => {
// We override the passport mock to mock req.logout
const tempApp = express();
tempApp.use(express.json());
auth.init(tempApp);
tempApp.use((err: any, req: any, res: any, next: any) => {

Check warning on line 99 in app/api/auth.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'next' is defined but never used

Check warning on line 99 in app/api/auth.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'next' is defined but never used
console.error(err);
res.status(500).json({ error: err.message });
});

const res = await request(tempApp).post('/auth/logout');
expect(res.status).toBe(200);
expect(res.body).toHaveProperty('logoutUrl');
});

test('requireAuthentication middleware should proceed if authenticated', () => {
const req = { isAuthenticated: () => true } as any;
const res = {} as any;
const next = jest.fn();
auth.requireAuthentication(req, res, next);
expect(next).toHaveBeenCalled();
});

test('requireAuthentication middleware should call passport if not authenticated', () => {
const req = { isAuthenticated: () => false } as any;
const res = {} as any;
const next = jest.fn();

auth.requireAuthentication(req, res, next);
// Since we mocked passport.authenticate to call next() and set user
expect(req.user).toEqual({ username: 'testuser' });
expect(next).toHaveBeenCalled();
});

test('getAllIds should return registered strategy ids', () => {
const ids = auth.getAllIds();
expect(ids).toContain('mockAuth');
});
});
56 changes: 56 additions & 0 deletions app/api/authentication.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import express from 'express';
import request from 'supertest';
import * as authApi from './authentication';
import * as registry from '../registry';

Check warning on line 4 in app/api/authentication.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'registry' is defined but never used

Check warning on line 4 in app/api/authentication.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'registry' is defined but never used

jest.mock('../registry', () => ({
getState: jest.fn(() => ({
authentication: {
'mock.test': {
type: 'mock',
name: 'test',
maskConfiguration: () => ({ mockConfig: true }),
},
},
})),
}));

describe('API Authentication', () => {
let app: express.Express;

beforeEach(() => {
jest.clearAllMocks();
app = express();
app.use(express.json());
app.use(authApi.init());
});

test('should get all authentications', async () => {
const res = await request(app).get('/');
expect(res.status).toBe(200);
expect(res.body).toEqual([
{
id: 'mock.test',
type: 'mock',
name: 'test',
configuration: { mockConfig: true },
},
]);
});

test('should get authentication by type and name', async () => {
const res = await request(app).get('/mock/test');
expect(res.status).toBe(200);
expect(res.body).toEqual({
id: 'mock.test',
type: 'mock',
name: 'test',
configuration: { mockConfig: true },
});
});

test('should return 404 for unknown authentication', async () => {
const res = await request(app).get('/mock/unknown');
expect(res.status).toBe(404);
});
});
Loading
Loading