test(scim): add 7 tests for stats, pause, resume, delete endpoints
- routes.test.ts: add mock functions for deleteConnector, getConnectorStats - 7 new tests: stats endpoint, pause active, pause rejects non-active, resume paused, resume rejects non-paused, delete paused, delete rejects active - Total: 11 SCIM tests (was 4)
This commit is contained in:
parent
28b6668fb1
commit
9e510f7b49
@ -6,12 +6,14 @@ const repoMock = {
|
|||||||
createConnector: vi.fn(),
|
createConnector: vi.fn(),
|
||||||
getConnector: vi.fn(),
|
getConnector: vi.fn(),
|
||||||
updateConnector: vi.fn(),
|
updateConnector: vi.fn(),
|
||||||
|
deleteConnector: vi.fn(),
|
||||||
upsertUserSync: vi.fn(),
|
upsertUserSync: vi.fn(),
|
||||||
listUserSync: vi.fn(),
|
listUserSync: vi.fn(),
|
||||||
upsertGroupSync: vi.fn(),
|
upsertGroupSync: vi.fn(),
|
||||||
listGroupSync: vi.fn(),
|
listGroupSync: vi.fn(),
|
||||||
createEvent: vi.fn(),
|
createEvent: vi.fn(),
|
||||||
listEvents: vi.fn(),
|
listEvents: vi.fn(),
|
||||||
|
getConnectorStats: vi.fn(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const orgRepoMock = {
|
const orgRepoMock = {
|
||||||
@ -116,4 +118,99 @@ describe('scimRoutes', () => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('GET /scim/connectors/:orgId/:id/stats returns connector stats', async () => {
|
||||||
|
repoMock.getConnector.mockResolvedValue({ id: 'scim_1', orgId: 'org_1' });
|
||||||
|
repoMock.getConnectorStats.mockResolvedValue({
|
||||||
|
connectorId: 'scim_1',
|
||||||
|
userCount: 10,
|
||||||
|
groupCount: 3,
|
||||||
|
eventCount: 25,
|
||||||
|
provisionedUsers: 8,
|
||||||
|
failedUsers: 2,
|
||||||
|
provisionedGroups: 3,
|
||||||
|
failedGroups: 0,
|
||||||
|
lastEventAt: '2026-03-20T00:00:00.000Z',
|
||||||
|
});
|
||||||
|
|
||||||
|
const app = await buildApp({ sub: 'admin_1', productId: 'lysnrai', role: 'admin' });
|
||||||
|
const res = await app.inject({ method: 'GET', url: '/api/scim/connectors/org_1/scim_1/stats' });
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
expect(res.json().userCount).toBe(10);
|
||||||
|
expect(res.json().failedUsers).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('POST /scim/connectors/:orgId/:id/pause pauses an active connector', async () => {
|
||||||
|
repoMock.getConnector.mockResolvedValue({ id: 'scim_1', status: 'active' });
|
||||||
|
repoMock.updateConnector.mockResolvedValue({ id: 'scim_1', status: 'paused' });
|
||||||
|
|
||||||
|
const app = await buildApp({ sub: 'admin_1', productId: 'lysnrai', role: 'admin' });
|
||||||
|
const res = await app.inject({
|
||||||
|
method: 'POST',
|
||||||
|
url: '/api/scim/connectors/org_1/scim_1/pause',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
expect(repoMock.updateConnector).toHaveBeenCalledWith('scim_1', 'org_1', { status: 'paused' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('POST /scim/connectors/:orgId/:id/pause rejects non-active connector', async () => {
|
||||||
|
repoMock.getConnector.mockResolvedValue({ id: 'scim_1', status: 'paused' });
|
||||||
|
|
||||||
|
const app = await buildApp({ sub: 'admin_1', productId: 'lysnrai', role: 'admin' });
|
||||||
|
const res = await app.inject({
|
||||||
|
method: 'POST',
|
||||||
|
url: '/api/scim/connectors/org_1/scim_1/pause',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(400);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('POST /scim/connectors/:orgId/:id/resume resumes a paused connector', async () => {
|
||||||
|
repoMock.getConnector.mockResolvedValue({ id: 'scim_1', status: 'paused' });
|
||||||
|
repoMock.updateConnector.mockResolvedValue({ id: 'scim_1', status: 'active' });
|
||||||
|
|
||||||
|
const app = await buildApp({ sub: 'admin_1', productId: 'lysnrai', role: 'admin' });
|
||||||
|
const res = await app.inject({
|
||||||
|
method: 'POST',
|
||||||
|
url: '/api/scim/connectors/org_1/scim_1/resume',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
expect(repoMock.updateConnector).toHaveBeenCalledWith('scim_1', 'org_1', { status: 'active' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('POST /scim/connectors/:orgId/:id/resume rejects non-paused connector', async () => {
|
||||||
|
repoMock.getConnector.mockResolvedValue({ id: 'scim_1', status: 'active' });
|
||||||
|
|
||||||
|
const app = await buildApp({ sub: 'admin_1', productId: 'lysnrai', role: 'admin' });
|
||||||
|
const res = await app.inject({
|
||||||
|
method: 'POST',
|
||||||
|
url: '/api/scim/connectors/org_1/scim_1/resume',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(400);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('DELETE /scim/connectors/:orgId/:id deletes a paused connector', async () => {
|
||||||
|
repoMock.getConnector.mockResolvedValue({ id: 'scim_1', status: 'paused' });
|
||||||
|
repoMock.deleteConnector.mockResolvedValue(undefined);
|
||||||
|
|
||||||
|
const app = await buildApp({ sub: 'admin_1', productId: 'lysnrai', role: 'admin' });
|
||||||
|
const res = await app.inject({ method: 'DELETE', url: '/api/scim/connectors/org_1/scim_1' });
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
expect(res.json()).toEqual({ deleted: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('DELETE /scim/connectors/:orgId/:id rejects active connector', async () => {
|
||||||
|
repoMock.getConnector.mockResolvedValue({ id: 'scim_1', status: 'active' });
|
||||||
|
|
||||||
|
const app = await buildApp({ sub: 'admin_1', productId: 'lysnrai', role: 'admin' });
|
||||||
|
const res = await app.inject({ method: 'DELETE', url: '/api/scim/connectors/org_1/scim_1' });
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(400);
|
||||||
|
expect(repoMock.deleteConnector).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user