mirror of
https://github.com/immich-app/immich.git
synced 2026-05-23 07:22:31 -04:00
Merge branch 'main' of https://github.com/immich-app/immich into feat/offline-files-job
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
import { LoginResponseDto } from '@immich/sdk';
|
||||
import { LoginResponseDto, getConfig } from '@immich/sdk';
|
||||
import { createUserDto } from 'src/fixtures';
|
||||
import { errorDto } from 'src/responses';
|
||||
import { app, utils } from 'src/utils';
|
||||
import { app, asBearerAuth, utils } from 'src/utils';
|
||||
import request from 'supertest';
|
||||
import { beforeAll, describe, expect, it } from 'vitest';
|
||||
|
||||
const getSystemConfig = (accessToken: string) => getConfig({ headers: asBearerAuth(accessToken) });
|
||||
|
||||
describe('/system-config', () => {
|
||||
let admin: LoginResponseDto;
|
||||
let nonAdmin: LoginResponseDto;
|
||||
@@ -60,4 +62,25 @@ describe('/system-config', () => {
|
||||
expect(body).toEqual(expect.objectContaining({ id: 'immich-map-dark' }));
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /system-config', () => {
|
||||
it('should require authentication', async () => {
|
||||
const { status, body } = await request(app).put('/system-config');
|
||||
expect(status).toBe(401);
|
||||
expect(body).toEqual(errorDto.unauthorized);
|
||||
});
|
||||
|
||||
it('should reject an invalid config entry', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.put('/system-config')
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||
.send({
|
||||
...(await getSystemConfig(admin.accessToken)),
|
||||
storageTemplate: { enabled: true, hashVerificationEnabled: true, template: '{{foo}}' },
|
||||
});
|
||||
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest(expect.stringContaining('Invalid storage template')));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,25 +2,25 @@ import { stat } from 'node:fs/promises';
|
||||
import { app, immichCli, utils } from 'src/utils';
|
||||
import { beforeEach, describe, expect, it } from 'vitest';
|
||||
|
||||
describe(`immich login-key`, () => {
|
||||
describe(`immich login`, () => {
|
||||
beforeEach(async () => {
|
||||
await utils.resetDatabase();
|
||||
});
|
||||
|
||||
it('should require a url', async () => {
|
||||
const { stderr, exitCode } = await immichCli(['login-key']);
|
||||
const { stderr, exitCode } = await immichCli(['login']);
|
||||
expect(stderr).toBe("error: missing required argument 'url'");
|
||||
expect(exitCode).toBe(1);
|
||||
});
|
||||
|
||||
it('should require a key', async () => {
|
||||
const { stderr, exitCode } = await immichCli(['login-key', app]);
|
||||
const { stderr, exitCode } = await immichCli(['login', app]);
|
||||
expect(stderr).toBe("error: missing required argument 'key'");
|
||||
expect(exitCode).toBe(1);
|
||||
});
|
||||
|
||||
it('should require a valid key', async () => {
|
||||
const { stderr, exitCode } = await immichCli(['login-key', app, 'immich-is-so-cool']);
|
||||
const { stderr, exitCode } = await immichCli(['login', app, 'immich-is-so-cool']);
|
||||
expect(stderr).toContain('Failed to connect to server');
|
||||
expect(stderr).toContain('Invalid API key');
|
||||
expect(stderr).toContain('401');
|
||||
@@ -30,7 +30,7 @@ describe(`immich login-key`, () => {
|
||||
it('should login and save auth.yml with 600', async () => {
|
||||
const admin = await utils.adminSetup();
|
||||
const key = await utils.createApiKey(admin.accessToken);
|
||||
const { stdout, stderr, exitCode } = await immichCli(['login-key', app, `${key.secret}`]);
|
||||
const { stdout, stderr, exitCode } = await immichCli(['login', app, `${key.secret}`]);
|
||||
expect(stdout.split('\n')).toEqual([
|
||||
'Logging in to http://127.0.0.1:2283/api',
|
||||
'Logged in as admin@immich.cloud',
|
||||
@@ -47,7 +47,7 @@ describe(`immich login-key`, () => {
|
||||
it('should login without /api in the url', async () => {
|
||||
const admin = await utils.adminSetup();
|
||||
const key = await utils.createApiKey(admin.accessToken);
|
||||
const { stdout, stderr, exitCode } = await immichCli(['login-key', app.replaceAll('/api', ''), `${key.secret}`]);
|
||||
const { stdout, stderr, exitCode } = await immichCli(['login', app.replaceAll('/api', ''), `${key.secret}`]);
|
||||
expect(stdout.split('\n')).toEqual([
|
||||
'Logging in to http://127.0.0.1:2283',
|
||||
'Discovered API at http://127.0.0.1:2283/api',
|
||||
|
||||
@@ -4,7 +4,8 @@ import { beforeAll, describe, expect, it } from 'vitest';
|
||||
describe(`immich server-info`, () => {
|
||||
beforeAll(async () => {
|
||||
await utils.resetDatabase();
|
||||
await utils.cliLogin();
|
||||
const admin = await utils.adminSetup();
|
||||
await utils.cliLogin(admin.accessToken);
|
||||
});
|
||||
|
||||
it('should return the server info', async () => {
|
||||
|
||||
@@ -1,20 +1,69 @@
|
||||
import { getAllAlbums, getAllAssets } from '@immich/sdk';
|
||||
import { LoginResponseDto, getAllAlbums, getAllAssets } from '@immich/sdk';
|
||||
import { mkdir, readdir, rm, symlink } from 'node:fs/promises';
|
||||
import { asKeyAuth, immichCli, testAssetDir, utils } from 'src/utils';
|
||||
import { beforeAll, beforeEach, describe, expect, it } from 'vitest';
|
||||
|
||||
describe(`immich upload`, () => {
|
||||
let admin: LoginResponseDto;
|
||||
let key: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
await utils.resetDatabase();
|
||||
key = await utils.cliLogin();
|
||||
|
||||
admin = await utils.adminSetup();
|
||||
key = await utils.cliLogin(admin.accessToken);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await utils.resetDatabase(['assets', 'albums']);
|
||||
});
|
||||
|
||||
describe(`immich upload /path/to/file.jpg`, () => {
|
||||
it('should upload a single file', async () => {
|
||||
const { stderr, stdout, exitCode } = await immichCli(['upload', `${testAssetDir}/albums/nature/silver_fir.jpg`]);
|
||||
expect(stderr).toBe('');
|
||||
expect(stdout.split('\n')).toEqual(
|
||||
expect.arrayContaining([expect.stringContaining('Successfully uploaded 1 asset')]),
|
||||
);
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should skip a duplicate file', async () => {
|
||||
const first = await immichCli(['upload', `${testAssetDir}/albums/nature/silver_fir.jpg`]);
|
||||
expect(first.stderr).toBe('');
|
||||
expect(first.stdout.split('\n')).toEqual(
|
||||
expect.arrayContaining([expect.stringContaining('Successfully uploaded 1 asset')]),
|
||||
);
|
||||
expect(first.exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(1);
|
||||
|
||||
const second = await immichCli(['upload', `${testAssetDir}/albums/nature/silver_fir.jpg`]);
|
||||
expect(second.stderr).toBe('');
|
||||
expect(second.stdout.split('\n')).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.stringContaining('Found 0 new files and 1 duplicate'),
|
||||
expect.stringContaining('All assets were already uploaded, nothing to do'),
|
||||
]),
|
||||
);
|
||||
expect(first.exitCode).toBe(0);
|
||||
});
|
||||
|
||||
it('should skip files that do not exist', async () => {
|
||||
const { stderr, stdout, exitCode } = await immichCli(['upload', `/path/to/file`]);
|
||||
expect(stderr).toBe('');
|
||||
expect(stdout.split('\n')).toEqual(expect.arrayContaining([expect.stringContaining('No files found, exiting')]));
|
||||
expect(exitCode).toBe(0);
|
||||
|
||||
const assets = await getAllAssets({}, { headers: asKeyAuth(key) });
|
||||
expect(assets.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('immich upload --recursive', () => {
|
||||
it('should upload a folder recursively', async () => {
|
||||
const { stderr, stdout, exitCode } = await immichCli(['upload', `${testAssetDir}/albums/nature/`, '--recursive']);
|
||||
|
||||
+3
-4
@@ -404,10 +404,9 @@ export const utils = {
|
||||
},
|
||||
]),
|
||||
|
||||
cliLogin: async () => {
|
||||
const admin = await utils.adminSetup();
|
||||
const key = await utils.createApiKey(admin.accessToken);
|
||||
await immichCli(['login-key', app, `${key.secret}`]);
|
||||
cliLogin: async (accessToken: string) => {
|
||||
const key = await utils.createApiKey(accessToken);
|
||||
await immichCli(['login', app, `${key.secret}`]);
|
||||
return key.secret;
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user