mirror of
https://github.com/immich-app/immich
synced 2026-08-15 13:03:57 +00:00
refactor(server): migrate e2e auth/validation tests to controller specs (#30715)
Co-authored-by: Claude (thor) <claude@thor.local>
This commit is contained in:
parent
ee525f159b
commit
1b8cbaab97
36 changed files with 125 additions and 1108 deletions
|
|
@ -1,6 +1,5 @@
|
||||||
import { LoginResponseDto, createPartner } from '@immich/sdk';
|
import { LoginResponseDto, createPartner } from '@immich/sdk';
|
||||||
import { createUserDto } from 'src/fixtures';
|
import { createUserDto } from 'src/fixtures';
|
||||||
import { errorDto } from 'src/responses';
|
|
||||||
import { app, asBearerAuth, utils } from 'src/utils';
|
import { app, asBearerAuth, utils } from 'src/utils';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
import { beforeAll, describe, expect, it } from 'vitest';
|
import { beforeAll, describe, expect, it } from 'vitest';
|
||||||
|
|
@ -29,13 +28,6 @@ describe('/partners', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /partners', () => {
|
describe('GET /partners', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).get('/partners');
|
|
||||||
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get all partners shared by user', async () => {
|
it('should get all partners shared by user', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.get('/partners')
|
.get('/partners')
|
||||||
|
|
@ -58,13 +50,6 @@ describe('/partners', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /partners/:id', () => {
|
describe('POST /partners/:id', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).post(`/partners/${user3.userId}`);
|
|
||||||
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should share with new partner', async () => {
|
it('should share with new partner', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.post(`/partners/${user3.userId}`)
|
.post(`/partners/${user3.userId}`)
|
||||||
|
|
@ -85,13 +70,6 @@ describe('/partners', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /partners/:id', () => {
|
describe('PUT /partners/:id', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).put(`/partners/${user2.userId}`);
|
|
||||||
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update partner', async () => {
|
it('should update partner', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.put(`/partners/${user2.userId}`)
|
.put(`/partners/${user2.userId}`)
|
||||||
|
|
@ -104,13 +82,6 @@ describe('/partners', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /partners/:id', () => {
|
describe('DELETE /partners/:id', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).delete(`/partners/${user3.userId}`);
|
|
||||||
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should delete partner', async () => {
|
it('should delete partner', async () => {
|
||||||
const { status } = await request(app)
|
const { status } = await request(app)
|
||||||
.delete(`/partners/${user3.userId}`)
|
.delete(`/partners/${user3.userId}`)
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,6 @@ describe('/server', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /server/about', () => {
|
describe('GET /server/about', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).get('/server/about');
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return about information', async () => {
|
it('should return about information', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.get('/server/about')
|
.get('/server/about')
|
||||||
|
|
@ -56,12 +50,6 @@ describe('/server', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /server/storage', () => {
|
describe('GET /server/storage', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).get('/server/storage');
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return the disk information', async () => {
|
it('should return the disk information', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.get('/server/storage')
|
.get('/server/storage')
|
||||||
|
|
@ -149,12 +137,6 @@ describe('/server', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /server/statistics', () => {
|
describe('GET /server/statistics', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).get('/server/statistics');
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should only work for admins', async () => {
|
it('should only work for admins', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.get('/server/statistics')
|
.get('/server/statistics')
|
||||||
|
|
@ -213,12 +195,6 @@ describe('/server', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /server/license', () => {
|
describe('GET /server/license', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).get('/server/license');
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should only work for admins', async () => {
|
it('should only work for admins', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.get('/server/license')
|
.get('/server/license')
|
||||||
|
|
@ -241,12 +217,6 @@ describe('/server', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /server/license', () => {
|
describe('DELETE /server/license', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).delete('/server/license');
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should only work for admins', async () => {
|
it('should only work for admins', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.delete('/server/license')
|
.delete('/server/license')
|
||||||
|
|
@ -266,12 +236,6 @@ describe('/server', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /server/license', () => {
|
describe('PUT /server/license', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).put('/server/license');
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should only work for admins', async () => {
|
it('should only work for admins', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.put('/server/license')
|
.put('/server/license')
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,6 @@ describe('/sessions', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /sessions', () => {
|
describe('GET /sessions', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).get('/sessions');
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get a list of authorized devices', async () => {
|
it('should get a list of authorized devices', async () => {
|
||||||
const { status, body } = await request(app).get('/sessions').set('Authorization', `Bearer ${admin.accessToken}`);
|
const { status, body } = await request(app).get('/sessions').set('Authorization', `Bearer ${admin.accessToken}`);
|
||||||
expect(status).toBe(200);
|
expect(status).toBe(200);
|
||||||
|
|
@ -29,12 +23,6 @@ describe('/sessions', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /sessions', () => {
|
describe('DELETE /sessions', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).delete(`/sessions`);
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should logout all devices (except the current one)', async () => {
|
it('should logout all devices (except the current one)', async () => {
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < 5; i++) {
|
||||||
await login({ loginCredentialDto: loginDto.admin });
|
await login({ loginCredentialDto: loginDto.admin });
|
||||||
|
|
|
||||||
|
|
@ -137,13 +137,6 @@ describe('/shared-links', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /shared-links', () => {
|
describe('GET /shared-links', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).get('/shared-links');
|
|
||||||
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get all shared links created by user', async () => {
|
it('should get all shared links created by user', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.get('/shared-links')
|
.get('/shared-links')
|
||||||
|
|
@ -200,12 +193,6 @@ describe('/shared-links', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /shared-links/me', () => {
|
describe('GET /shared-links/me', () => {
|
||||||
it('should not require admin authentication', async () => {
|
|
||||||
const { status } = await request(app).get('/shared-links/me').set('Authorization', `Bearer ${admin.accessToken}`);
|
|
||||||
|
|
||||||
expect(status).toBe(403);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get data for correct shared link', async () => {
|
it('should get data for correct shared link', async () => {
|
||||||
const { status, body } = await request(app).get('/shared-links/me').query({ key: linkWithAlbum.key });
|
const { status, body } = await request(app).get('/shared-links/me').query({ key: linkWithAlbum.key });
|
||||||
|
|
||||||
|
|
@ -293,13 +280,6 @@ describe('/shared-links', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /shared-links/:id', () => {
|
describe('GET /shared-links/:id', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).get(`/shared-links/${linkWithAlbum.id}`);
|
|
||||||
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get shared link by id', async () => {
|
it('should get shared link by id', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.get(`/shared-links/${linkWithAlbum.id}`)
|
.get(`/shared-links/${linkWithAlbum.id}`)
|
||||||
|
|
@ -326,26 +306,6 @@ describe('/shared-links', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /shared-links', () => {
|
describe('POST /shared-links', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app)
|
|
||||||
.post('/shared-links')
|
|
||||||
.send({ type: SharedLinkType.Album, albumId: uuidDto.notFound });
|
|
||||||
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a type and the correspondent asset/album id', async () => {
|
|
||||||
const { status, body } = await request(app)
|
|
||||||
.post('/shared-links')
|
|
||||||
.set('Authorization', `Bearer ${user1.accessToken}`);
|
|
||||||
|
|
||||||
expect(status).toBe(400);
|
|
||||||
expect(body).toEqual(
|
|
||||||
errorDto.validationError([{ path: [], message: 'Invalid input: expected object, received undefined' }]),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require an asset/album id', async () => {
|
it('should require an asset/album id', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.post('/shared-links')
|
.post('/shared-links')
|
||||||
|
|
@ -383,15 +343,6 @@ describe('/shared-links', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PATCH /shared-links/:id', () => {
|
describe('PATCH /shared-links/:id', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app)
|
|
||||||
.patch(`/shared-links/${linkWithAlbum.id}`)
|
|
||||||
.send({ description: 'foo' });
|
|
||||||
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should fail if invalid link', async () => {
|
it('should fail if invalid link', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.patch(`/shared-links/${uuidDto.notFound}`)
|
.patch(`/shared-links/${uuidDto.notFound}`)
|
||||||
|
|
@ -474,13 +425,6 @@ describe('/shared-links', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /shared-links/:id', () => {
|
describe('DELETE /shared-links/:id', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).delete(`/shared-links/${linkWithAlbum.id}`);
|
|
||||||
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should fail if invalid link', async () => {
|
it('should fail if invalid link', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.delete(`/shared-links/${uuidDto.notFound}`)
|
.delete(`/shared-links/${uuidDto.notFound}`)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { AssetMediaResponseDto, LoginResponseDto, searchStacks } from '@immich/sdk';
|
import { AssetMediaResponseDto, LoginResponseDto, searchStacks } from '@immich/sdk';
|
||||||
import { createUserDto, uuidDto } from 'src/fixtures';
|
import { createUserDto } from 'src/fixtures';
|
||||||
import { errorDto } from 'src/responses';
|
import { errorDto } from 'src/responses';
|
||||||
import { app, asBearerAuth, utils } from 'src/utils';
|
import { app, asBearerAuth, utils } from 'src/utils';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
|
|
@ -25,42 +25,6 @@ describe('/stacks', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /stacks', () => {
|
describe('POST /stacks', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app)
|
|
||||||
.post('/stacks')
|
|
||||||
.send({ assetIds: [asset.id] });
|
|
||||||
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require at least two assets', async () => {
|
|
||||||
const { status, body } = await request(app)
|
|
||||||
.post('/stacks')
|
|
||||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
|
||||||
.send({ assetIds: [asset.id] });
|
|
||||||
|
|
||||||
expect(status).toBe(400);
|
|
||||||
expect(body).toEqual(
|
|
||||||
errorDto.validationError([{ path: ['assetIds'], message: 'Too small: expected array to have >=2 items' }]),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid id', async () => {
|
|
||||||
const { status, body } = await request(app)
|
|
||||||
.post('/stacks')
|
|
||||||
.set('Authorization', `Bearer ${user1.accessToken}`)
|
|
||||||
.send({ assetIds: [uuidDto.invalid, uuidDto.invalid] });
|
|
||||||
|
|
||||||
expect(status).toBe(400);
|
|
||||||
expect(body).toEqual(
|
|
||||||
errorDto.validationError([
|
|
||||||
{ path: ['assetIds', 0], message: 'Invalid UUID' },
|
|
||||||
{ path: ['assetIds', 1], message: 'Invalid UUID' },
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require access', async () => {
|
it('should require access', async () => {
|
||||||
const user2Asset = await utils.createAsset(user2.accessToken);
|
const user2Asset = await utils.createAsset(user2.accessToken);
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,6 @@ describe('/server-info', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /system-metadata/admin-onboarding', () => {
|
describe('POST /system-metadata/admin-onboarding', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).post('/system-metadata/admin-onboarding').send({ isOnboarded: true });
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should only work for admins', async () => {
|
it('should only work for admins', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.post('/system-metadata/admin-onboarding')
|
.post('/system-metadata/admin-onboarding')
|
||||||
|
|
@ -47,12 +41,6 @@ describe('/server-info', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /system-metadata/reverse-geocoding-state', () => {
|
describe('GET /system-metadata/reverse-geocoding-state', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).get('/system-metadata/reverse-geocoding-state');
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should only work for admins', async () => {
|
it('should only work for admins', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.get('/system-metadata/reverse-geocoding-state')
|
.get('/system-metadata/reverse-geocoding-state')
|
||||||
|
|
|
||||||
|
|
@ -41,12 +41,6 @@ describe('/tags', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /tags', () => {
|
describe('POST /tags', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).post('/tags').send({ name: 'TagA' });
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require authorization (api key)', async () => {
|
it('should require authorization (api key)', async () => {
|
||||||
const { secret } = await utils.createApiKey(user.accessToken, [Permission.AssetRead]);
|
const { secret } = await utils.createApiKey(user.accessToken, [Permission.AssetRead]);
|
||||||
const { status, body } = await request(app).post('/tags').set('x-api-key', secret).send({ name: 'TagA' });
|
const { status, body } = await request(app).post('/tags').set('x-api-key', secret).send({ name: 'TagA' });
|
||||||
|
|
@ -117,12 +111,6 @@ describe('/tags', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /tags', () => {
|
describe('GET /tags', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).get('/tags');
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require authorization (api key)', async () => {
|
it('should require authorization (api key)', async () => {
|
||||||
const { secret } = await utils.createApiKey(user.accessToken, [Permission.AssetRead]);
|
const { secret } = await utils.createApiKey(user.accessToken, [Permission.AssetRead]);
|
||||||
const { status, body } = await request(app).get('/tags').set('x-api-key', secret);
|
const { status, body } = await request(app).get('/tags').set('x-api-key', secret);
|
||||||
|
|
@ -169,12 +157,6 @@ describe('/tags', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /tags', () => {
|
describe('PUT /tags', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).put(`/tags`).send({ name: 'TagA/TagB' });
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require authorization (api key)', async () => {
|
it('should require authorization (api key)', async () => {
|
||||||
const { secret } = await utils.createApiKey(user.accessToken, [Permission.AssetRead]);
|
const { secret } = await utils.createApiKey(user.accessToken, [Permission.AssetRead]);
|
||||||
const { status, body } = await request(app).put('/tags').set('x-api-key', secret).send({ name: 'TagA' });
|
const { status, body } = await request(app).put('/tags').set('x-api-key', secret).send({ name: 'TagA' });
|
||||||
|
|
@ -213,12 +195,6 @@ describe('/tags', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /tags/assets', () => {
|
describe('PUT /tags/assets', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).put(`/tags/assets`).send({ tagIds: [], assetIds: [] });
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require authorization (api key)', async () => {
|
it('should require authorization (api key)', async () => {
|
||||||
const { secret } = await utils.createApiKey(user.accessToken, [Permission.AssetRead]);
|
const { secret } = await utils.createApiKey(user.accessToken, [Permission.AssetRead]);
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
|
|
@ -279,12 +255,6 @@ describe('/tags', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /tags/:id', () => {
|
describe('GET /tags/:id', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).get(`/tags/${uuidDto.notFound}`);
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require authorization', async () => {
|
it('should require authorization', async () => {
|
||||||
const tag = await create(user.accessToken, { name: 'TagA' });
|
const tag = await create(user.accessToken, { name: 'TagA' });
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
|
|
@ -304,14 +274,6 @@ describe('/tags', () => {
|
||||||
expect(body).toEqual(errorDto.missingPermission('tag.read'));
|
expect(body).toEqual(errorDto.missingPermission('tag.read'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should require a valid uuid', async () => {
|
|
||||||
const { status, body } = await request(app)
|
|
||||||
.get(`/tags/${uuidDto.invalid}`)
|
|
||||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
|
||||||
expect(status).toBe(400);
|
|
||||||
expect(body).toEqual(errorDto.validationError([{ path: ['id'], message: 'Invalid UUID' }]));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get tag details', async () => {
|
it('should get tag details', async () => {
|
||||||
const tag = await create(user.accessToken, { name: 'TagA' });
|
const tag = await create(user.accessToken, { name: 'TagA' });
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
|
|
@ -349,13 +311,6 @@ describe('/tags', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /tags/:id', () => {
|
describe('PUT /tags/:id', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const tag = await create(user.accessToken, { name: 'TagA' });
|
|
||||||
const { status, body } = await request(app).put(`/tags/${tag.id}`).send({ color: '#000000' });
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require authorization', async () => {
|
it('should require authorization', async () => {
|
||||||
const tag = await create(admin.accessToken, { name: 'tagA' });
|
const tag = await create(admin.accessToken, { name: 'tagA' });
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
|
|
@ -399,12 +354,6 @@ describe('/tags', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /tags/:id', () => {
|
describe('DELETE /tags/:id', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).delete(`/tags/${uuidDto.notFound}`);
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require authorization', async () => {
|
it('should require authorization', async () => {
|
||||||
const tag = await create(user.accessToken, { name: 'TagA' });
|
const tag = await create(user.accessToken, { name: 'TagA' });
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
|
|
@ -422,14 +371,6 @@ describe('/tags', () => {
|
||||||
expect(body).toEqual(errorDto.missingPermission('tag.delete'));
|
expect(body).toEqual(errorDto.missingPermission('tag.delete'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should require a valid uuid', async () => {
|
|
||||||
const { status, body } = await request(app)
|
|
||||||
.delete(`/tags/${uuidDto.invalid}`)
|
|
||||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
|
||||||
expect(status).toBe(400);
|
|
||||||
expect(body).toEqual(errorDto.validationError([{ path: ['id'], message: 'Invalid UUID' }]));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should delete a tag', async () => {
|
it('should delete a tag', async () => {
|
||||||
const tag = await create(user.accessToken, { name: 'TagA' });
|
const tag = await create(user.accessToken, { name: 'TagA' });
|
||||||
const { status } = await request(app)
|
const { status } = await request(app)
|
||||||
|
|
@ -463,15 +404,6 @@ describe('/tags', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /tags/:id/assets', () => {
|
describe('PUT /tags/:id/assets', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const tagA = await create(user.accessToken, { name: 'TagA' });
|
|
||||||
const { status, body } = await request(app)
|
|
||||||
.put(`/tags/${tagA.id}/assets`)
|
|
||||||
.send({ ids: [userAsset.id] });
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require authorization', async () => {
|
it('should require authorization', async () => {
|
||||||
const tag = await create(user.accessToken, { name: 'TagA' });
|
const tag = await create(user.accessToken, { name: 'TagA' });
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
|
|
@ -531,16 +463,6 @@ describe('/tags', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /tags/:id/assets', () => {
|
describe('DELETE /tags/:id/assets', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const tagA = await create(admin.accessToken, { name: 'TagA' });
|
|
||||||
const { status, body } = await request(app)
|
|
||||||
.delete(`/tags/${tagA}/assets`)
|
|
||||||
.send({ ids: [userAsset.id] });
|
|
||||||
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require authorization', async () => {
|
it('should require authorization', async () => {
|
||||||
const tagA = await create(user.accessToken, { name: 'TagA' });
|
const tagA = await create(user.accessToken, { name: 'TagA' });
|
||||||
await tagAssets(
|
await tagAssets(
|
||||||
|
|
|
||||||
|
|
@ -46,12 +46,6 @@ describe('/admin/users', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /admin/users', () => {
|
describe('GET /admin/users', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).get(`/admin/users`);
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require authorization', async () => {
|
it('should require authorization', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.get(`/admin/users`)
|
.get(`/admin/users`)
|
||||||
|
|
@ -94,12 +88,6 @@ describe('/admin/users', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /admin/users', () => {
|
describe('POST /admin/users', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).post(`/admin/users`).send(createUserDto.user1);
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require authorization', async () => {
|
it('should require authorization', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.post(`/admin/users`)
|
.post(`/admin/users`)
|
||||||
|
|
@ -109,23 +97,6 @@ describe('/admin/users', () => {
|
||||||
expect(body).toEqual(errorDto.forbidden);
|
expect(body).toEqual(errorDto.forbidden);
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const [key, message] of [
|
|
||||||
['password', 'Invalid input: expected string, received null'],
|
|
||||||
['email', 'Invalid input: expected email, received object'],
|
|
||||||
['name', 'Invalid input: expected string, received null'],
|
|
||||||
['shouldChangePassword', 'Invalid input: expected boolean, received null'],
|
|
||||||
['notify', 'Invalid input: expected boolean, received null'],
|
|
||||||
] as const) {
|
|
||||||
it(`should not allow null ${key}`, async () => {
|
|
||||||
const { status, body } = await request(app)
|
|
||||||
.post(`/admin/users`)
|
|
||||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
|
||||||
.send({ ...createUserDto.user1, [key]: null });
|
|
||||||
expect(status).toBe(400);
|
|
||||||
expect(body).toEqual(errorDto.validationError([{ path: [key], message }]));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
it('should accept `isAdmin`', async () => {
|
it('should accept `isAdmin`', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.post(`/admin/users`)
|
.post(`/admin/users`)
|
||||||
|
|
@ -146,12 +117,6 @@ describe('/admin/users', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /admin/users/:id', () => {
|
describe('PUT /admin/users/:id', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).put(`/admin/users/${uuidDto.notFound}`);
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require authorization', async () => {
|
it('should require authorization', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.put(`/admin/users/${uuidDto.notFound}`)
|
.put(`/admin/users/${uuidDto.notFound}`)
|
||||||
|
|
@ -160,22 +125,6 @@ describe('/admin/users', () => {
|
||||||
expect(body).toEqual(errorDto.forbidden);
|
expect(body).toEqual(errorDto.forbidden);
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const [key, message] of [
|
|
||||||
['password', 'Invalid input: expected string, received null'],
|
|
||||||
['email', 'Invalid input: expected email, received object'],
|
|
||||||
['name', 'Invalid input: expected string, received null'],
|
|
||||||
['shouldChangePassword', 'Invalid input: expected boolean, received null'],
|
|
||||||
] as const) {
|
|
||||||
it(`should not allow null ${key}`, async () => {
|
|
||||||
const { status, body } = await request(app)
|
|
||||||
.put(`/admin/users/${uuidDto.notFound}`)
|
|
||||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
|
||||||
.send({ [key]: null });
|
|
||||||
expect(status).toBe(400);
|
|
||||||
expect(body).toEqual(errorDto.validationError([{ path: [key], message }]));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
it('should allow a non-admin to become an admin', async () => {
|
it('should allow a non-admin to become an admin', async () => {
|
||||||
const user = await utils.userSetup(admin.accessToken, createUserDto.create('admin2'));
|
const user = await utils.userSetup(admin.accessToken, createUserDto.create('admin2'));
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
|
|
@ -245,12 +194,6 @@ describe('/admin/users', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /admin/users/:id/preferences', () => {
|
describe('PUT /admin/users/:id/preferences', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).put(`/admin/users/${userToDelete.userId}/preferences`);
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update memories enabled', async () => {
|
it('should update memories enabled', async () => {
|
||||||
const before = await getUserPreferencesAdmin({ id: admin.userId }, { headers: asBearerAuth(admin.accessToken) });
|
const before = await getUserPreferencesAdmin({ id: admin.userId }, { headers: asBearerAuth(admin.accessToken) });
|
||||||
expect(before).toMatchObject({ memories: { enabled: true } });
|
expect(before).toMatchObject({ memories: { enabled: true } });
|
||||||
|
|
@ -282,12 +225,6 @@ describe('/admin/users', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /admin/users/:id', () => {
|
describe('DELETE /admin/users/:id', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).delete(`/admin/users/${userToDelete.userId}`);
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require authorization', async () => {
|
it('should require authorization', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.delete(`/admin/users/${userToDelete.userId}`)
|
.delete(`/admin/users/${userToDelete.userId}`)
|
||||||
|
|
@ -360,12 +297,6 @@ describe('/admin/users', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /admin/users/:id/calendar-heatmap', () => {
|
describe('GET /admin/users/:id/calendar-heatmap', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).get(`/admin/users/${nonAdmin.userId}/calendar-heatmap`);
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require admin permissions', async () => {
|
it('should require admin permissions', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.get(`/admin/users/${nonAdmin.userId}/calendar-heatmap`)
|
.get(`/admin/users/${nonAdmin.userId}/calendar-heatmap`)
|
||||||
|
|
@ -385,12 +316,6 @@ describe('/admin/users', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /admin/users/:id/restore', () => {
|
describe('POST /admin/users/:id/restore', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status, body } = await request(app).post(`/admin/users/${userToDelete.userId}/restore`);
|
|
||||||
expect(status).toBe(401);
|
|
||||||
expect(body).toEqual(errorDto.unauthorized);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require authorization', async () => {
|
it('should require authorization', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.post(`/admin/users/${userToDelete.userId}/restore`)
|
.post(`/admin/users/${userToDelete.userId}/restore`)
|
||||||
|
|
|
||||||
|
|
@ -171,20 +171,6 @@ describe('/users', () => {
|
||||||
expect(after).toMatchObject({ memories: { enabled: false } });
|
expect(after).toMatchObject({ memories: { enabled: false } });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should require an integer for download archive size', async () => {
|
|
||||||
const { status, body } = await request(app)
|
|
||||||
.put(`/users/me/preferences`)
|
|
||||||
.send({ download: { archiveSize: 1_234_567.89 } })
|
|
||||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
|
||||||
|
|
||||||
expect(status).toBe(400);
|
|
||||||
expect(body).toEqual(
|
|
||||||
errorDto.validationError([
|
|
||||||
{ path: ['download', 'archiveSize'], message: 'Invalid input: expected int, received number' },
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update download archive size', async () => {
|
it('should update download archive size', async () => {
|
||||||
const before = await getMyPreferences({ headers: asBearerAuth(admin.accessToken) });
|
const before = await getMyPreferences({ headers: asBearerAuth(admin.accessToken) });
|
||||||
expect(before).toMatchObject({ download: { archiveSize: 4 * 2 ** 30 } });
|
expect(before).toMatchObject({ download: { archiveSize: 4 * 2 ** 30 } });
|
||||||
|
|
@ -201,20 +187,6 @@ describe('/users', () => {
|
||||||
expect(after).toMatchObject({ download: { archiveSize: 1_234_567 } });
|
expect(after).toMatchObject({ download: { archiveSize: 1_234_567 } });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should require a boolean for download include embedded videos', async () => {
|
|
||||||
const { status, body } = await request(app)
|
|
||||||
.put(`/users/me/preferences`)
|
|
||||||
.send({ download: { includeEmbeddedVideos: 1_234_567.89 } })
|
|
||||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
|
||||||
|
|
||||||
expect(status).toBe(400);
|
|
||||||
expect(body).toEqual(
|
|
||||||
errorDto.validationError([
|
|
||||||
{ path: ['download', 'includeEmbeddedVideos'], message: 'Invalid input: expected boolean, received number' },
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update download include embedded videos', async () => {
|
it('should update download include embedded videos', async () => {
|
||||||
const before = await getMyPreferences({ headers: asBearerAuth(admin.accessToken) });
|
const before = await getMyPreferences({ headers: asBearerAuth(admin.accessToken) });
|
||||||
expect(before).toMatchObject({ download: { includeEmbeddedVideos: false } });
|
expect(before).toMatchObject({ download: { includeEmbeddedVideos: false } });
|
||||||
|
|
@ -318,11 +290,6 @@ describe('/users', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /users/me/license', () => {
|
describe('DELETE /users/me/license', () => {
|
||||||
it('should require authentication', async () => {
|
|
||||||
const { status } = await request(app).put(`/users/me/license`);
|
|
||||||
expect(status).toEqual(401);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should delete the user license', async () => {
|
it('should delete the user license', async () => {
|
||||||
const { status } = await request(app)
|
const { status } = await request(app)
|
||||||
.delete(`/users/me/license`)
|
.delete(`/users/me/license`)
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,6 @@ describe(ActivityController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /activities', () => {
|
describe('GET /activities', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/activities');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require an albumId', async () => {
|
it('should require an albumId', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).get('/activities');
|
const { status, body } = await request(ctx.getHttpServer()).get('/activities');
|
||||||
expect(status).toEqual(400);
|
expect(status).toEqual(400);
|
||||||
|
|
@ -50,11 +45,6 @@ describe(ActivityController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /activities', () => {
|
describe('POST /activities', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/activities');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require an albumId', async () => {
|
it('should require an albumId', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.post('/activities')
|
.post('/activities')
|
||||||
|
|
@ -77,11 +67,6 @@ describe(ActivityController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /activities/:id', () => {
|
describe('DELETE /activities/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).delete(`/activities/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid uuid', async () => {
|
it('should require a valid uuid', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).delete(`/activities/123`);
|
const { status, body } = await request(ctx.getHttpServer()).delete(`/activities/123`);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,6 @@ describe(AlbumController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /albums', () => {
|
describe('GET /albums', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/albums');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should reject an invalid shared param', async () => {
|
it('should reject an invalid shared param', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).get('/albums?isShared=invalid');
|
const { status, body } = await request(ctx.getHttpServer()).get('/albums?isShared=invalid');
|
||||||
expect(status).toEqual(400);
|
expect(status).toEqual(400);
|
||||||
|
|
@ -40,60 +35,4 @@ describe(AlbumController.name, () => {
|
||||||
expect(body).toEqual(factory.responses.validationError([{ path: ['assetId'], message: 'Invalid UUID' }]));
|
expect(body).toEqual(factory.responses.validationError([{ path: ['assetId'], message: 'Invalid UUID' }]));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /albums/:id', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/albums/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('GET /albums/statistics', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/albums/statistics');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('POST /albums', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/albums').send({ albumName: 'New album' });
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('PUT /albums/:id/assets', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put(`/albums/${factory.uuid()}/assets`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('PUT /albums/assets', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put(`/albums/assets`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('PATCH /albums/:id', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).patch(`/albums/${factory.uuid()}`).send({ albumName: 'New album name' });
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('DELETE /albums/:id/assets', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).delete(`/albums/${factory.uuid()}/assets`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('PUT :id/users', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put(`/albums/${factory.uuid()}/users`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -19,33 +19,7 @@ describe(ApiKeyController.name, () => {
|
||||||
ctx.reset();
|
ctx.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /api-keys', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/api-keys').send({ name: 'API Key' });
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('GET /api-keys', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/api-keys');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('GET /api-keys/me', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/api-keys/me`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('GET /api-keys/:id', () => {
|
describe('GET /api-keys/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/api-keys/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid uuid', async () => {
|
it('should require a valid uuid', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).get(`/api-keys/123`);
|
const { status, body } = await request(ctx.getHttpServer()).get(`/api-keys/123`);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
@ -54,11 +28,6 @@ describe(ApiKeyController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /api-keys/:id', () => {
|
describe('PUT /api-keys/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put(`/api-keys/${factory.uuid()}`).send({ name: 'new name' });
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid uuid', async () => {
|
it('should require a valid uuid', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.put(`/api-keys/123`)
|
.put(`/api-keys/123`)
|
||||||
|
|
@ -76,11 +45,6 @@ describe(ApiKeyController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /api-keys/:id', () => {
|
describe('DELETE /api-keys/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).delete(`/api-keys/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid uuid', async () => {
|
it('should require a valid uuid', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).delete(`/api-keys/123`);
|
const { status, body } = await request(ctx.getHttpServer()).delete(`/api-keys/123`);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
|
||||||
|
|
@ -44,11 +44,6 @@ describe(AssetMediaController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /assets', () => {
|
describe('POST /assets', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post(`/assets`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should accept metadata', async () => {
|
it('should accept metadata', async () => {
|
||||||
const mobileMetadata = { key: AssetMetadataKey.MobileApp, value: { iCloudId: '123' } };
|
const mobileMetadata = { key: AssetMetadataKey.MobileApp, value: { iCloudId: '123' } };
|
||||||
const { status } = await request(ctx.getHttpServer())
|
const { status } = await request(ctx.getHttpServer())
|
||||||
|
|
@ -171,20 +166,9 @@ describe(AssetMediaController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO figure out how to deal with `sendFile`
|
// TODO figure out how to deal with `sendFile`
|
||||||
describe.skip('GET /assets/:id/original', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/assets/${factory.uuid()}/original`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO figure out how to deal with `sendFile`
|
// TODO figure out how to deal with `sendFile`
|
||||||
describe('GET /assets/:id/thumbnail', () => {
|
describe('GET /assets/:id/thumbnail', () => {
|
||||||
it.skip('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/assets/${factory.uuid()}/thumbnail`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should redirect if size=original is requested', async () => {
|
it('should redirect if size=original is requested', async () => {
|
||||||
const { status } = await request(ctx.getHttpServer()).get(`/assets/${factory.uuid()}/thumbnail?size=original`);
|
const { status } = await request(ctx.getHttpServer()).get(`/assets/${factory.uuid()}/thumbnail?size=original`);
|
||||||
expect(status).toBe(302);
|
expect(status).toBe(302);
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,6 @@ describe(AssetController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /assets', () => {
|
describe('PUT /assets', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put(`/assets`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid uuid', async () => {
|
it('should require a valid uuid', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.put(`/assets`)
|
.put(`/assets`)
|
||||||
|
|
@ -59,13 +54,6 @@ describe(AssetController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /assets', () => {
|
describe('DELETE /assets', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer())
|
|
||||||
.delete(`/assets`)
|
|
||||||
.send({ ids: [factory.uuid()] });
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid uuid', async () => {
|
it('should require a valid uuid', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.delete(`/assets`)
|
.delete(`/assets`)
|
||||||
|
|
@ -77,11 +65,6 @@ describe(AssetController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /assets/:id', () => {
|
describe('GET /assets/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/assets/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid id', async () => {
|
it('should require a valid id', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).get(`/assets/123`);
|
const { status, body } = await request(ctx.getHttpServer()).get(`/assets/123`);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
@ -90,11 +73,6 @@ describe(AssetController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /assets/copy', () => {
|
describe('PUT /assets/copy', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/assets/copy`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require target and source id', async () => {
|
it('should require target and source id', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).put('/assets/copy').send({});
|
const { status, body } = await request(ctx.getHttpServer()).put('/assets/copy').send({});
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
@ -115,11 +93,6 @@ describe(AssetController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /assets/metadata', () => {
|
describe('PUT /assets/metadata', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put(`/assets/metadata`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid assetId', async () => {
|
it('should require a valid assetId', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.put('/assets/metadata')
|
.put('/assets/metadata')
|
||||||
|
|
@ -151,11 +124,6 @@ describe(AssetController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /assets/metadata', () => {
|
describe('DELETE /assets/metadata', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).delete(`/assets/metadata`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid assetId', async () => {
|
it('should require a valid assetId', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.delete('/assets/metadata')
|
.delete('/assets/metadata')
|
||||||
|
|
@ -187,11 +155,6 @@ describe(AssetController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /assets/:id', () => {
|
describe('PUT /assets/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/assets/123`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid id', async () => {
|
it('should require a valid id', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).put(`/assets/123`);
|
const { status, body } = await request(ctx.getHttpServer()).put(`/assets/123`);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
@ -267,26 +230,7 @@ describe(AssetController.name, () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /assets/statistics', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/assets/statistics`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('GET /assets/:id/metadata', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/assets/${factory.uuid()}/metadata`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('PUT /assets/:id/metadata', () => {
|
describe('PUT /assets/:id/metadata', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put(`/assets/${factory.uuid()}/metadata`).send({ items: [] });
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid id', async () => {
|
it('should require a valid id', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).put(`/assets/123/metadata`).send({ items: [] });
|
const { status, body } = await request(ctx.getHttpServer()).put(`/assets/123/metadata`).send({ items: [] });
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
@ -353,11 +297,6 @@ describe(AssetController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /assets/:id/metadata/:key', () => {
|
describe('GET /assets/:id/metadata/:key', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/assets/${factory.uuid()}/metadata/mobile-app`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid id', async () => {
|
it('should require a valid id', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).get(`/assets/123/metadata/mobile-app`);
|
const { status, body } = await request(ctx.getHttpServer()).get(`/assets/123/metadata/mobile-app`);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
@ -366,11 +305,6 @@ describe(AssetController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /assets/:id/edits', () => {
|
describe('PUT /assets/:id/edits', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put(`/assets/${factory.uuid()}/edits`).send({ edits: [] });
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should accept valid edits and pass to service correctly', async () => {
|
it('should accept valid edits and pass to service correctly', async () => {
|
||||||
const edits = [
|
const edits = [
|
||||||
{
|
{
|
||||||
|
|
@ -456,11 +390,6 @@ describe(AssetController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /assets/:id/metadata/:key', () => {
|
describe('DELETE /assets/:id/metadata/:key', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).delete(`/assets/${factory.uuid()}/metadata/mobile-app`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid id', async () => {
|
it('should require a valid id', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).delete(`/assets/123/metadata/mobile-app`);
|
const { status, body } = await request(ctx.getHttpServer()).delete(`/assets/123/metadata/mobile-app`);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
|
||||||
|
|
@ -199,28 +199,7 @@ describe(AuthController.name, () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /auth/logout', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/auth/logout');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('POST /auth/change-password', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer())
|
|
||||||
.post('/auth/change-password')
|
|
||||||
.send({ password: 'password', newPassword: 'Password1234', invalidateSessions: false });
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('POST /auth/pin-code', () => {
|
describe('POST /auth/pin-code', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/auth/pin-code').send({ pinCode: '123456' });
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should reject 5 digits', async () => {
|
it('should reject 5 digits', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).post('/auth/pin-code').send({ pinCode: '12345' });
|
const { status, body } = await request(ctx.getHttpServer()).post('/auth/pin-code').send({ pinCode: '12345' });
|
||||||
expect(status).toEqual(400);
|
expect(status).toEqual(400);
|
||||||
|
|
@ -251,25 +230,4 @@ describe(AuthController.name, () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /auth/pin-code', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put('/auth/pin-code').send({ pinCode: '123456', newPinCode: '654321' });
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('DELETE /auth/pin-code', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).delete('/auth/pin-code').send({ pinCode: '123456' });
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('GET /auth/status', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/auth/status');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,6 @@ describe(DatabaseBackupController.name, () => {
|
||||||
ctx.reset();
|
ctx.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /admin/database-backups', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/admin/database-backups').send();
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('POST /admin/database-backups/start-restore', () => {
|
describe('POST /admin/database-backups/start-restore', () => {
|
||||||
it('should not be an authenticated route', async () => {
|
it('should not be an authenticated route', async () => {
|
||||||
maintenanceService.startRestoreFlow.mockResolvedValue({ jwt: 'jwt' });
|
maintenanceService.startRestoreFlow.mockResolvedValue({ jwt: 'jwt' });
|
||||||
|
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
import { Readable } from 'node:stream';
|
|
||||||
import { DownloadController } from 'src/controllers/download.controller';
|
|
||||||
import { DownloadService } from 'src/services/download.service';
|
|
||||||
import request from 'supertest';
|
|
||||||
import { factory } from 'test/small.factory';
|
|
||||||
import { ControllerContext, controllerSetup, mockBaseService } from 'test/utils';
|
|
||||||
|
|
||||||
describe(DownloadController.name, () => {
|
|
||||||
let ctx: ControllerContext;
|
|
||||||
const service = mockBaseService(DownloadService);
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
|
||||||
ctx = await controllerSetup(DownloadController, [{ provide: DownloadService, useValue: service }]);
|
|
||||||
return () => ctx.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
service.resetAllMocks();
|
|
||||||
ctx.reset();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('POST /download/info', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer())
|
|
||||||
.post('/download/info')
|
|
||||||
.send({ assetIds: [factory.uuid()] });
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('POST /download/archive', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
const stream = new Readable({
|
|
||||||
read() {
|
|
||||||
// eslint-disable-next-line unicorn/no-this-outside-of-class
|
|
||||||
this.push('test');
|
|
||||||
// eslint-disable-next-line unicorn/no-this-outside-of-class
|
|
||||||
this.push(null);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
service.downloadArchive.mockResolvedValue({ stream });
|
|
||||||
await request(ctx.getHttpServer())
|
|
||||||
.post('/download/archive')
|
|
||||||
.send({ assetIds: [factory.uuid()] });
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -18,26 +18,7 @@ describe(DuplicateController.name, () => {
|
||||||
ctx.reset();
|
ctx.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /duplicates', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/duplicates');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('DELETE /duplicates', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).delete('/duplicates');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('DELETE /duplicates/:id', () => {
|
describe('DELETE /duplicates/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).delete(`/duplicates/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid uuid', async () => {
|
it('should require a valid uuid', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).delete(`/duplicates/123`);
|
const { status, body } = await request(ctx.getHttpServer()).delete(`/duplicates/123`);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,6 @@ describe(MaintenanceController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /admin/maintenance', () => {
|
describe('POST /admin/maintenance', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/admin/maintenance').send();
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a backup file when action is restore', async () => {
|
it('should require a backup file when action is restore', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).post('/admin/maintenance').send({
|
const { status, body } = await request(ctx.getHttpServer()).post('/admin/maintenance').send({
|
||||||
action: MaintenanceAction.RestoreDatabase,
|
action: MaintenanceAction.RestoreDatabase,
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,6 @@ describe(MemoryController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /memories', () => {
|
describe('GET /memories', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/memories');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not require any parameters', async () => {
|
it('should not require any parameters', async () => {
|
||||||
await request(ctx.getHttpServer()).get('/memories').query({});
|
await request(ctx.getHttpServer()).get('/memories').query({});
|
||||||
expect(service.search).toHaveBeenCalled();
|
expect(service.search).toHaveBeenCalled();
|
||||||
|
|
@ -32,11 +27,6 @@ describe(MemoryController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /memories', () => {
|
describe('POST /memories', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/memories');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should validate data when type is on this day', async () => {
|
it('should validate data when type is on this day', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.post('/memories')
|
.post('/memories')
|
||||||
|
|
@ -69,19 +59,7 @@ describe(MemoryController.name, () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /memories/statistics', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/memories/statistics');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('GET /memories/:id', () => {
|
describe('GET /memories/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/memories/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid id', async () => {
|
it('should require a valid id', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).get(`/memories/invalid`);
|
const { status, body } = await request(ctx.getHttpServer()).get(`/memories/invalid`);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
@ -90,11 +68,6 @@ describe(MemoryController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /memories/:id', () => {
|
describe('PUT /memories/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put(`/memories/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid id', async () => {
|
it('should require a valid id', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).put(`/memories/invalid`);
|
const { status, body } = await request(ctx.getHttpServer()).put(`/memories/invalid`);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
@ -114,19 +87,7 @@ describe(MemoryController.name, () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /memories/:id', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).delete(`/memories/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('PUT /memories/:id/assets', () => {
|
describe('PUT /memories/:id/assets', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put(`/memories/${factory.uuid()}/assets`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid id', async () => {
|
it('should require a valid id', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).put(`/memories/invalid/assets`).send({ ids: [] });
|
const { status, body } = await request(ctx.getHttpServer()).put(`/memories/invalid/assets`).send({ ids: [] });
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
@ -143,11 +104,6 @@ describe(MemoryController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /memories/:id/assets', () => {
|
describe('DELETE /memories/:id/assets', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).delete(`/memories/${factory.uuid()}/assets`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid id', async () => {
|
it('should require a valid id', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).delete(`/memories/invalid/assets`);
|
const { status, body } = await request(ctx.getHttpServer()).delete(`/memories/invalid/assets`);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,6 @@ describe(NotificationAdminController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /admin/notifications', () => {
|
describe('POST /admin/notifications', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/admin/notifications');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should accept a null readAt', async () => {
|
it('should accept a null readAt', async () => {
|
||||||
await request(ctx.getHttpServer())
|
await request(ctx.getHttpServer())
|
||||||
.post(`/admin/notifications`)
|
.post(`/admin/notifications`)
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,6 @@ describe(NotificationController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /notifications', () => {
|
describe('GET /notifications', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/notifications');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should reject an invalid notification level`, async () => {
|
it(`should reject an invalid notification level`, async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.get(`/notifications`)
|
.get(`/notifications`)
|
||||||
|
|
@ -40,11 +35,6 @@ describe(NotificationController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /notifications', () => {
|
describe('PUT /notifications', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put('/notifications');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('ids', () => {
|
describe('ids', () => {
|
||||||
it('should require a list', async () => {
|
it('should require a list', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).put(`/notifications`).send({ ids: true });
|
const { status, body } = await request(ctx.getHttpServer()).put(`/notifications`).send({ ids: true });
|
||||||
|
|
@ -75,11 +65,6 @@ describe(NotificationController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /notifications/:id', () => {
|
describe('GET /notifications/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/notifications/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid uuid', async () => {
|
it('should require a valid uuid', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).get(`/notifications/123`);
|
const { status, body } = await request(ctx.getHttpServer()).get(`/notifications/123`);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
@ -88,11 +73,6 @@ describe(NotificationController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /notifications/:id', () => {
|
describe('PUT /notifications/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put(`/notifications/${factory.uuid()}`).send({ readAt: factory.date() });
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should accept a null readAt', async () => {
|
it('should accept a null readAt', async () => {
|
||||||
const id = factory.uuid();
|
const id = factory.uuid();
|
||||||
await request(ctx.getHttpServer()).put(`/notifications/${id}`).send({ readAt: null });
|
await request(ctx.getHttpServer()).put(`/notifications/${id}`).send({ readAt: null });
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
import { PartnerService } from 'src/services/partner.service';
|
import { PartnerService } from 'src/services/partner.service';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
import { errorDto } from 'test/medium/responses';
|
import { errorDto } from 'test/medium/responses';
|
||||||
import { factory } from 'test/small.factory';
|
|
||||||
import { automock, ControllerContext, controllerSetup, mockBaseService } from 'test/utils';
|
import { automock, ControllerContext, controllerSetup, mockBaseService } from 'test/utils';
|
||||||
|
|
||||||
describe(PartnerController.name, () => {
|
describe(PartnerController.name, () => {
|
||||||
|
|
@ -24,11 +23,6 @@ describe(PartnerController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /partners', () => {
|
describe('GET /partners', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/partners');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should require a direction`, async () => {
|
it(`should require a direction`, async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).get(`/partners`).set('Authorization', `Bearer token`);
|
const { status, body } = await request(ctx.getHttpServer()).get(`/partners`).set('Authorization', `Bearer token`);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
@ -54,11 +48,6 @@ describe(PartnerController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /partners', () => {
|
describe('POST /partners', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/partners');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should require sharedWithId to be a uuid`, async () => {
|
it(`should require sharedWithId to be a uuid`, async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.post(`/partners`)
|
.post(`/partners`)
|
||||||
|
|
@ -70,11 +59,6 @@ describe(PartnerController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /partners/:id', () => {
|
describe('PUT /partners/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put(`/partners/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should require id to be a uuid`, async () => {
|
it(`should require id to be a uuid`, async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.put(`/partners/invalid`)
|
.put(`/partners/invalid`)
|
||||||
|
|
@ -86,11 +70,6 @@ describe(PartnerController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /partners/:id', () => {
|
describe('DELETE /partners/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).delete(`/partners/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should require id to be a uuid`, async () => {
|
it(`should require id to be a uuid`, async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.delete(`/partners/invalid`)
|
.delete(`/partners/invalid`)
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,6 @@ describe(PersonController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /people', () => {
|
describe('GET /people', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/people');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should require closestPersonId to be a uuid`, async () => {
|
it(`should require closestPersonId to be a uuid`, async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.get(`/people`)
|
.get(`/people`)
|
||||||
|
|
@ -48,19 +43,7 @@ describe(PersonController.name, () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /people', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/people');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('DELETE /people', () => {
|
describe('DELETE /people', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).delete('/people');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require uuids in the body', async () => {
|
it('should require uuids in the body', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.delete('/people')
|
.delete('/people')
|
||||||
|
|
@ -78,19 +61,7 @@ describe(PersonController.name, () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /people/:id', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/people/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('PUT /people/:id', () => {
|
describe('PUT /people/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/people/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid uuid', async () => {
|
it('should require a valid uuid', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).put(`/people/123`);
|
const { status, body } = await request(ctx.getHttpServer()).put(`/people/123`);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
@ -177,11 +148,6 @@ describe(PersonController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /people/:id', () => {
|
describe('DELETE /people/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).delete(`/people/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid uuid', async () => {
|
it('should require a valid uuid', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).delete(`/people/invalid`);
|
const { status, body } = await request(ctx.getHttpServer()).delete(`/people/invalid`);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
@ -194,18 +160,4 @@ describe(PersonController.name, () => {
|
||||||
expect(service.delete).toHaveBeenCalled();
|
expect(service.delete).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /people/:id/merge', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post(`/people/${factory.uuid()}/merge`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('GET /people/:id/statistics', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/people/${factory.uuid()}/statistics`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
import { PluginService } from 'src/services/plugin.service';
|
import { PluginService } from 'src/services/plugin.service';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
import { errorDto } from 'test/medium/responses';
|
import { errorDto } from 'test/medium/responses';
|
||||||
import { factory } from 'test/small.factory';
|
|
||||||
import { automock, ControllerContext, controllerSetup, mockBaseService } from 'test/utils';
|
import { automock, ControllerContext, controllerSetup, mockBaseService } from 'test/utils';
|
||||||
|
|
||||||
describe(PluginController.name, () => {
|
describe(PluginController.name, () => {
|
||||||
|
|
@ -24,11 +23,6 @@ describe(PluginController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /plugins', () => {
|
describe('GET /plugins', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/plugins');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should require id to be a uuid`, async () => {
|
it(`should require id to be a uuid`, async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.get(`/plugins`)
|
.get(`/plugins`)
|
||||||
|
|
@ -40,11 +34,6 @@ describe(PluginController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /plugins/:id', () => {
|
describe('GET /plugins/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/plugins/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should require id to be a uuid`, async () => {
|
it(`should require id to be a uuid`, async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.get(`/plugins/invalid`)
|
.get(`/plugins/invalid`)
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,6 @@ describe(SearchController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /search/metadata', () => {
|
describe('POST /search/metadata', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/search/metadata');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should reject page as a string', async () => {
|
it('should reject page as a string', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).post('/search/metadata').send({ page: 'abc' });
|
const { status, body } = await request(ctx.getHttpServer()).post('/search/metadata').send({ page: 'abc' });
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
@ -121,11 +116,6 @@ describe(SearchController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /search/random', () => {
|
describe('POST /search/random', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/search/random');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should reject if withStacked is not a boolean', async () => {
|
it('should reject if withStacked is not a boolean', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.post('/search/random')
|
.post('/search/random')
|
||||||
|
|
@ -151,26 +141,7 @@ describe(SearchController.name, () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /search/smart', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/search/smart');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('GET /search/explore', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/search/explore');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('POST /search/person', () => {
|
describe('POST /search/person', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/search/person');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a name', async () => {
|
it('should require a name', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).get('/search/person').send({});
|
const { status, body } = await request(ctx.getHttpServer()).get('/search/person').send({});
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
@ -181,11 +152,6 @@ describe(SearchController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /search/places', () => {
|
describe('GET /search/places', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/search/places');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a name', async () => {
|
it('should require a name', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).get('/search/places').send({});
|
const { status, body } = await request(ctx.getHttpServer()).get('/search/places').send({});
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
@ -195,19 +161,7 @@ describe(SearchController.name, () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /search/cities', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/search/cities');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('GET /search/suggestions', () => {
|
describe('GET /search/suggestions', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/search/suggestions');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a type', async () => {
|
it('should require a type', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).get('/search/suggestions').send({});
|
const { status, body } = await request(ctx.getHttpServer()).get('/search/suggestions').send({});
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
import { ServerController } from 'src/controllers/server.controller';
|
|
||||||
import { ServerService } from 'src/services/server.service';
|
|
||||||
import { SystemMetadataService } from 'src/services/system-metadata.service';
|
|
||||||
import { VersionService } from 'src/services/version.service';
|
|
||||||
import request from 'supertest';
|
|
||||||
import { ControllerContext, controllerSetup, mockBaseService } from 'test/utils';
|
|
||||||
|
|
||||||
describe(ServerController.name, () => {
|
|
||||||
let ctx: ControllerContext;
|
|
||||||
const serverService = mockBaseService(ServerService);
|
|
||||||
const systemMetadataService = mockBaseService(SystemMetadataService);
|
|
||||||
const versionService = mockBaseService(VersionService);
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
|
||||||
ctx = await controllerSetup(ServerController, [
|
|
||||||
{ provide: ServerService, useValue: serverService },
|
|
||||||
{ provide: SystemMetadataService, useValue: systemMetadataService },
|
|
||||||
{ provide: VersionService, useValue: versionService },
|
|
||||||
]);
|
|
||||||
return () => ctx.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
serverService.resetAllMocks();
|
|
||||||
versionService.resetAllMocks();
|
|
||||||
ctx.reset();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('GET /server/license', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/server/license');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { SharedLinkController } from 'src/controllers/shared-link.controller';
|
||||||
import { Permission, SharedLinkType } from 'src/enum';
|
import { Permission, SharedLinkType } from 'src/enum';
|
||||||
import { SharedLinkService } from 'src/services/shared-link.service';
|
import { SharedLinkService } from 'src/services/shared-link.service';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
|
import { errorDto } from 'test/medium/responses';
|
||||||
import { factory } from 'test/small.factory';
|
import { factory } from 'test/small.factory';
|
||||||
import { ControllerContext, controllerSetup, mockBaseService } from 'test/utils';
|
import { ControllerContext, controllerSetup, mockBaseService } from 'test/utils';
|
||||||
|
|
||||||
|
|
@ -19,10 +20,24 @@ describe(SharedLinkController.name, () => {
|
||||||
ctx.reset();
|
ctx.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('GET /shared-links/me', () => {
|
||||||
|
it('should be a shared link route', async () => {
|
||||||
|
await request(ctx.getHttpServer()).get('/shared-links/me');
|
||||||
|
expect(ctx.authenticate).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({ metadata: expect.objectContaining({ sharedLinkRoute: true }) }),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('POST /shared-links', () => {
|
describe('POST /shared-links', () => {
|
||||||
it('should be an authenticated route', async () => {
|
it('should require a type and the correspondent asset/album id', async () => {
|
||||||
await request(ctx.getHttpServer()).post('/shared-links');
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
.post('/shared-links')
|
||||||
|
.set('Authorization', `Bearer token`);
|
||||||
|
expect(status).toBe(400);
|
||||||
|
expect(body).toEqual(
|
||||||
|
errorDto.validationError([{ path: [], message: 'Invalid input: expected object, received undefined' }]),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow an null expiresAt', async () => {
|
it('should allow an null expiresAt', async () => {
|
||||||
|
|
|
||||||
46
server/src/controllers/stack.controller.spec.ts
Normal file
46
server/src/controllers/stack.controller.spec.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
import { StackController } from 'src/controllers/stack.controller';
|
||||||
|
import { StackService } from 'src/services/stack.service';
|
||||||
|
import request from 'supertest';
|
||||||
|
import { errorDto } from 'test/medium/responses';
|
||||||
|
import { factory } from 'test/small.factory';
|
||||||
|
import { ControllerContext, controllerSetup, mockBaseService } from 'test/utils';
|
||||||
|
|
||||||
|
describe(StackController.name, () => {
|
||||||
|
let ctx: ControllerContext;
|
||||||
|
const service = mockBaseService(StackService);
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
ctx = await controllerSetup(StackController, [{ provide: StackService, useValue: service }]);
|
||||||
|
return () => ctx.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
service.resetAllMocks();
|
||||||
|
ctx.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('POST /stacks', () => {
|
||||||
|
it('should require at least two assets', async () => {
|
||||||
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
|
.post('/stacks')
|
||||||
|
.send({ assetIds: [factory.uuid()] });
|
||||||
|
expect(status).toBe(400);
|
||||||
|
expect(body).toEqual(
|
||||||
|
errorDto.validationError([{ path: ['assetIds'], message: 'Too small: expected array to have >=2 items' }]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should require a valid id', async () => {
|
||||||
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
|
.post('/stacks')
|
||||||
|
.send({ assetIds: ['invalid', 'invalid'] });
|
||||||
|
expect(status).toBe(400);
|
||||||
|
expect(body).toEqual(
|
||||||
|
errorDto.validationError([
|
||||||
|
{ path: ['assetIds', 0], message: 'Invalid UUID' },
|
||||||
|
{ path: ['assetIds', 1], message: 'Invalid UUID' },
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -25,11 +25,6 @@ describe(SyncController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /sync/stream', () => {
|
describe('POST /sync/stream', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/sync/stream');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require sync request type enums', async () => {
|
it('should require sync request type enums', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.post('/sync/stream')
|
.post('/sync/stream')
|
||||||
|
|
@ -44,19 +39,7 @@ describe(SyncController.name, () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /sync/ack', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/sync/ack');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('POST /sync/ack', () => {
|
describe('POST /sync/ack', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/sync/ack');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not allow more than 1,000 entries', async () => {
|
it('should not allow more than 1,000 entries', async () => {
|
||||||
const acks = Array.from({ length: 1001 }, (_, i) => `ack-${i}`);
|
const acks = Array.from({ length: 1001 }, (_, i) => `ack-${i}`);
|
||||||
const { status, body } = await request(ctx.getHttpServer()).post('/sync/ack').send({ acks });
|
const { status, body } = await request(ctx.getHttpServer()).post('/sync/ack').send({ acks });
|
||||||
|
|
@ -69,11 +52,6 @@ describe(SyncController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /sync/ack', () => {
|
describe('DELETE /sync/ack', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).delete('/sync/ack');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require sync response type enums', async () => {
|
it('should require sync response type enums', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.delete('/sync/ack')
|
.delete('/sync/ack')
|
||||||
|
|
|
||||||
|
|
@ -40,26 +40,7 @@ describe(SystemConfigController.name, () => {
|
||||||
ctx.reset();
|
ctx.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /system-config', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/system-config');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('GET /system-config/defaults', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/system-config/defaults');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('PUT /system-config', () => {
|
describe('PUT /system-config', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put('/system-config');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('nightlyTasks', () => {
|
describe('nightlyTasks', () => {
|
||||||
it('should validate nightly jobs start time', async () => {
|
it('should validate nightly jobs start time', async () => {
|
||||||
const config = validConfig();
|
const config = validConfig();
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import { TagController } from 'src/controllers/tag.controller';
|
||||||
import { TagService } from 'src/services/tag.service';
|
import { TagService } from 'src/services/tag.service';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
import { errorDto } from 'test/medium/responses';
|
import { errorDto } from 'test/medium/responses';
|
||||||
import { factory } from 'test/small.factory';
|
|
||||||
import { ControllerContext, controllerSetup, mockBaseService } from 'test/utils';
|
import { ControllerContext, controllerSetup, mockBaseService } from 'test/utils';
|
||||||
|
|
||||||
describe(TagController.name, () => {
|
describe(TagController.name, () => {
|
||||||
|
|
@ -19,38 +18,14 @@ describe(TagController.name, () => {
|
||||||
ctx.reset();
|
ctx.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /tags', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/tags');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('POST /tags', () => {
|
describe('POST /tags', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/tags');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should a null parentId', async () => {
|
it('should a null parentId', async () => {
|
||||||
await request(ctx.getHttpServer()).post(`/tags`).send({ name: 'tag', parentId: null });
|
await request(ctx.getHttpServer()).post(`/tags`).send({ name: 'tag', parentId: null });
|
||||||
expect(service.create).toHaveBeenCalledWith(undefined, expect.objectContaining({ parentId: null }));
|
expect(service.create).toHaveBeenCalledWith(undefined, expect.objectContaining({ parentId: null }));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /tags', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put('/tags');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('GET /tags/:id', () => {
|
describe('GET /tags/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/tags/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should require a valid uuid', async () => {
|
it('should require a valid uuid', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).get(`/tags/123`);
|
const { status, body } = await request(ctx.getHttpServer()).get(`/tags/123`);
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
|
|
@ -58,10 +33,11 @@ describe(TagController.name, () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /tags/:id', () => {
|
describe('DELETE /tags/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
it('should require a valid uuid', async () => {
|
||||||
await request(ctx.getHttpServer()).put(`/tags/${factory.uuid()}`);
|
const { status, body } = await request(ctx.getHttpServer()).delete(`/tags/123`);
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
expect(status).toBe(400);
|
||||||
|
expect(body).toEqual(errorDto.validationError([{ path: ['id'], message: 'Invalid UUID' }]));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,6 @@ describe(TimelineController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /timeline/buckets', () => {
|
describe('GET /timeline/buckets', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/timeline/buckets');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse bbox query string into an object', async () => {
|
it('should parse bbox query string into an object', async () => {
|
||||||
const { status } = await request(ctx.getHttpServer())
|
const { status } = await request(ctx.getHttpServer())
|
||||||
.get('/timeline/buckets')
|
.get('/timeline/buckets')
|
||||||
|
|
@ -58,11 +53,6 @@ describe(TimelineController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /timeline/bucket', () => {
|
describe('GET /timeline/bucket', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/timeline/bucket?timeBucket=1900-01-01');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO enable date string validation while still accepting 5 digit years
|
// TODO enable date string validation while still accepting 5 digit years
|
||||||
it.fails('should fail if time bucket is invalid', async () => {
|
it.fails('should fail if time bucket is invalid', async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer()).get('/timeline/bucket').query({ timeBucket: 'foo' });
|
const { status, body } = await request(ctx.getHttpServer()).get('/timeline/bucket').query({ timeBucket: 'foo' });
|
||||||
|
|
|
||||||
|
|
@ -24,26 +24,7 @@ describe(UserAdminController.name, () => {
|
||||||
ctx.reset();
|
ctx.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /admin/users', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/admin/users');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('PUT /admin/users/:id', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put(`/admin/users/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('POST /admin/users', () => {
|
describe('POST /admin/users', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/admin/users');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should allow a null pinCode', async () => {
|
it('should allow a null pinCode', async () => {
|
||||||
await request(ctx.getHttpServer()).post(`/admin/users`).send({
|
await request(ctx.getHttpServer()).post(`/admin/users`).send({
|
||||||
name: 'Test user',
|
name: 'Test user',
|
||||||
|
|
@ -64,25 +45,22 @@ describe(UserAdminController.name, () => {
|
||||||
expect(service.create).toHaveBeenCalledWith(expect.objectContaining({ avatarColor: null }));
|
expect(service.create).toHaveBeenCalledWith(expect.objectContaining({ avatarColor: null }));
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should `, async () => {
|
for (const [key, message] of [
|
||||||
const dto: UserAdminCreateDto = {
|
['password', 'Invalid input: expected string, received null'],
|
||||||
email: 'user@immich.app',
|
['email', 'Invalid input: expected email, received object'],
|
||||||
password: 'test',
|
['name', 'Invalid input: expected string, received null'],
|
||||||
name: 'Test User',
|
['shouldChangePassword', 'Invalid input: expected boolean, received null'],
|
||||||
quotaSizeInBytes: 1.2,
|
['notify', 'Invalid input: expected boolean, received null'],
|
||||||
};
|
] as const) {
|
||||||
|
it(`should not allow null ${key}`, async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.post(`/admin/users`)
|
.post(`/admin/users`)
|
||||||
.set('Authorization', `Bearer token`)
|
.set('Authorization', `Bearer token`)
|
||||||
.send(dto);
|
.send({ email: 'user@immich.app', password: 'test', name: 'Test User', [key]: null });
|
||||||
expect(status).toBe(400);
|
expect(status).toBe(400);
|
||||||
expect(body).toEqual(
|
expect(body).toEqual(errorDto.validationError([{ path: [key], message }]));
|
||||||
errorDto.validationError([
|
});
|
||||||
{ path: ['quotaSizeInBytes'], message: 'Invalid input: expected int, received number' },
|
}
|
||||||
]),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should not allow decimal quota`, async () => {
|
it(`should not allow decimal quota`, async () => {
|
||||||
const dto: UserAdminCreateDto = {
|
const dto: UserAdminCreateDto = {
|
||||||
|
|
@ -105,19 +83,7 @@ describe(UserAdminController.name, () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /admin/users/:id', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/admin/users/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('PUT /admin/users/:id', () => {
|
describe('PUT /admin/users/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put(`/admin/users/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should not allow decimal quota`, async () => {
|
it(`should not allow decimal quota`, async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.put(`/admin/users/${factory.uuid()}`)
|
.put(`/admin/users/${factory.uuid()}`)
|
||||||
|
|
@ -142,5 +108,21 @@ describe(UserAdminController.name, () => {
|
||||||
await request(ctx.getHttpServer()).put(`/admin/users/${id}`).send({ avatarColor: null });
|
await request(ctx.getHttpServer()).put(`/admin/users/${id}`).send({ avatarColor: null });
|
||||||
expect(service.update).toHaveBeenCalledWith(undefined, id, expect.objectContaining({ avatarColor: null }));
|
expect(service.update).toHaveBeenCalledWith(undefined, id, expect.objectContaining({ avatarColor: null }));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (const [key, message] of [
|
||||||
|
['password', 'Invalid input: expected string, received null'],
|
||||||
|
['email', 'Invalid input: expected email, received object'],
|
||||||
|
['name', 'Invalid input: expected string, received null'],
|
||||||
|
['shouldChangePassword', 'Invalid input: expected boolean, received null'],
|
||||||
|
] as const) {
|
||||||
|
it(`should not allow null ${key}`, async () => {
|
||||||
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
|
.put(`/admin/users/${factory.uuid()}`)
|
||||||
|
.set('Authorization', `Bearer token`)
|
||||||
|
.send({ [key]: null });
|
||||||
|
expect(status).toBe(400);
|
||||||
|
expect(body).toEqual(errorDto.validationError([{ path: [key], message }]));
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
import { UserService } from 'src/services/user.service';
|
import { UserService } from 'src/services/user.service';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
import { errorDto } from 'test/medium/responses';
|
import { errorDto } from 'test/medium/responses';
|
||||||
import { factory } from 'test/small.factory';
|
|
||||||
import { automock, ControllerContext, controllerSetup, mockBaseService } from 'test/utils';
|
import { automock, ControllerContext, controllerSetup, mockBaseService } from 'test/utils';
|
||||||
|
|
||||||
describe(UserController.name, () => {
|
describe(UserController.name, () => {
|
||||||
|
|
@ -23,26 +22,7 @@ describe(UserController.name, () => {
|
||||||
ctx.reset();
|
ctx.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /users', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/users');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('GET /users/me', () => {
|
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/users/me');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('PUT /users/me', () => {
|
describe('PUT /users/me', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).put('/users/me');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const [key, message] of [
|
for (const [key, message] of [
|
||||||
['email', 'Invalid input: expected email, received object'],
|
['email', 'Invalid input: expected email, received object'],
|
||||||
['name', 'Invalid input: expected string, received null'],
|
['name', 'Invalid input: expected string, received null'],
|
||||||
|
|
@ -66,24 +46,31 @@ describe(UserController.name, () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /users/:id', () => {
|
describe('PUT /users/me/preferences', () => {
|
||||||
it('should be an authenticated route', async () => {
|
it('should require an integer for download archive size', async () => {
|
||||||
await request(ctx.getHttpServer()).get(`/users/${factory.uuid()}`);
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
.put(`/users/me/preferences`)
|
||||||
|
.set('Authorization', `Bearer token`)
|
||||||
|
.send({ download: { archiveSize: 1_234_567.89 } });
|
||||||
|
expect(status).toBe(400);
|
||||||
|
expect(body).toEqual(
|
||||||
|
errorDto.validationError([
|
||||||
|
{ path: ['download', 'archiveSize'], message: 'Invalid input: expected int, received number' },
|
||||||
|
]),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe('PUT /users/me/license', () => {
|
it('should require a boolean for download include embedded videos', async () => {
|
||||||
it('should be an authenticated route', async () => {
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
await request(ctx.getHttpServer()).put('/users/me/license');
|
.put(`/users/me/preferences`)
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
.set('Authorization', `Bearer token`)
|
||||||
});
|
.send({ download: { includeEmbeddedVideos: 1_234_567.89 } });
|
||||||
});
|
expect(status).toBe(400);
|
||||||
|
expect(body).toEqual(
|
||||||
describe('DELETE /users/me/license', () => {
|
errorDto.validationError([
|
||||||
it('should be an authenticated route', async () => {
|
{ path: ['download', 'includeEmbeddedVideos'], message: 'Invalid input: expected boolean, received number' },
|
||||||
await request(ctx.getHttpServer()).delete('/users/me/license');
|
]),
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
import { WorkflowService } from 'src/services/workflow.service';
|
import { WorkflowService } from 'src/services/workflow.service';
|
||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
import { errorDto } from 'test/medium/responses';
|
import { errorDto } from 'test/medium/responses';
|
||||||
import { factory } from 'test/small.factory';
|
|
||||||
import { automock, ControllerContext, controllerSetup, mockBaseService } from 'test/utils';
|
import { automock, ControllerContext, controllerSetup, mockBaseService } from 'test/utils';
|
||||||
|
|
||||||
describe(WorkflowController.name, () => {
|
describe(WorkflowController.name, () => {
|
||||||
|
|
@ -25,11 +24,6 @@ describe(WorkflowController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /workflows', () => {
|
describe('POST /workflows', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).post('/workflows').send({});
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should require a valid trigger`, async () => {
|
it(`should require a valid trigger`, async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.post(`/workflows`)
|
.post(`/workflows`)
|
||||||
|
|
@ -65,11 +59,6 @@ describe(WorkflowController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /workflows', () => {
|
describe('GET /workflows', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get('/workflows');
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should require id to be a uuid`, async () => {
|
it(`should require id to be a uuid`, async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.get(`/workflows`)
|
.get(`/workflows`)
|
||||||
|
|
@ -81,11 +70,6 @@ describe(WorkflowController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /workflows/:id', () => {
|
describe('GET /workflows/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).get(`/workflows/${factory.uuid()}`);
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should require id to be a uuid`, async () => {
|
it(`should require id to be a uuid`, async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.get(`/workflows/invalid`)
|
.get(`/workflows/invalid`)
|
||||||
|
|
@ -96,11 +80,6 @@ describe(WorkflowController.name, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PATCH /workflows/:id', () => {
|
describe('PATCH /workflows/:id', () => {
|
||||||
it('should be an authenticated route', async () => {
|
|
||||||
await request(ctx.getHttpServer()).patch(`/workflows/${factory.uuid()}`).send({});
|
|
||||||
expect(ctx.authenticate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should require id to be a uuid`, async () => {
|
it(`should require id to be a uuid`, async () => {
|
||||||
const { status, body } = await request(ctx.getHttpServer())
|
const { status, body } = await request(ctx.getHttpServer())
|
||||||
.patch(`/workflows/invalid`)
|
.patch(`/workflows/invalid`)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue