From 3a9df6dae8b1493cb79ea17a0938ef13e3dfc42f Mon Sep 17 00:00:00 2001 From: Jason Rasmussen Date: Wed, 17 Apr 2024 08:27:04 -0400 Subject: [PATCH] refactor(server): immich-admin list-users (#8862) --- .../specs/immich-admin.e2e-spec.ts | 19 +++++++++++++++++++ e2e/src/utils.ts | 18 ++++++++++-------- e2e/vitest.config.ts | 2 +- server/src/commands/list-users.command.ts | 12 +----------- server/src/services/user.service.ts | 5 +++++ 5 files changed, 36 insertions(+), 20 deletions(-) create mode 100644 e2e/src/immich-admin/specs/immich-admin.e2e-spec.ts diff --git a/e2e/src/immich-admin/specs/immich-admin.e2e-spec.ts b/e2e/src/immich-admin/specs/immich-admin.e2e-spec.ts new file mode 100644 index 0000000000..707093ab25 --- /dev/null +++ b/e2e/src/immich-admin/specs/immich-admin.e2e-spec.ts @@ -0,0 +1,19 @@ +import { immichAdmin, utils } from 'src/utils'; +import { beforeAll, describe, expect, it } from 'vitest'; + +describe(`immich-admin`, () => { + beforeAll(async () => { + await utils.resetDatabase(); + await utils.adminSetup(); + }); + + describe('list-users', () => { + it('should list the admin user', async () => { + const { stdout, stderr, exitCode } = await immichAdmin(['list-users']); + expect(exitCode).toBe(0); + expect(stderr).toBe(''); + expect(stdout).toContain("email: 'admin@immich.cloud'"); + expect(stdout).toContain("name: 'Immich Admin'"); + }); + }); +}); diff --git a/e2e/src/utils.ts b/e2e/src/utils.ts index a46653eb11..617f2d62cc 100644 --- a/e2e/src/utils.ts +++ b/e2e/src/utils.ts @@ -43,7 +43,7 @@ import { loginDto, signupDto } from 'src/fixtures'; import { makeRandomImage } from 'src/generators'; import request from 'supertest'; -type CliResponse = { stdout: string; stderr: string; exitCode: number | null }; +type CommandResponse = { stdout: string; stderr: string; exitCode: number | null }; type EventType = 'assetUpload' | 'assetUpdate' | 'assetDelete' | 'userDelete'; type WaitOptions = { event: EventType; id?: string; total?: number; timeout?: number }; type AdminSetupOptions = { onboarding?: boolean }; @@ -59,13 +59,15 @@ export const testAssetDirInternal = '/data/assets'; export const tempDir = tmpdir(); export const asBearerAuth = (accessToken: string) => ({ Authorization: `Bearer ${accessToken}` }); export const asKeyAuth = (key: string) => ({ 'x-api-key': key }); -export const immichCli = async (args: string[]) => { - let _resolve: (value: CliResponse) => void; - const deferred = new Promise((resolve) => (_resolve = resolve)); - const _args = ['node_modules/.bin/immich', '-d', `/${tempDir}/immich/`, ...args]; - const child = spawn('node', _args, { - stdio: 'pipe', - }); +export const immichCli = (args: string[]) => + executeCommand('node', ['node_modules/.bin/immich', '-d', `/${tempDir}/immich/`, ...args]); +export const immichAdmin = (args: string[]) => + executeCommand('docker', ['exec', '-i', 'immich-e2e-server', '/bin/bash', '-c', `immich-admin ${args.join(' ')}`]); + +const executeCommand = (command: string, args: string[]) => { + let _resolve: (value: CommandResponse) => void; + const deferred = new Promise((resolve) => (_resolve = resolve)); + const child = spawn(command, args, { stdio: 'pipe' }); let stdout = ''; let stderr = ''; diff --git a/e2e/vitest.config.ts b/e2e/vitest.config.ts index 9b9670c042..6b1db353c5 100644 --- a/e2e/vitest.config.ts +++ b/e2e/vitest.config.ts @@ -10,7 +10,7 @@ try { export default defineConfig({ test: { - include: ['src/{api,cli}/specs/*.e2e-spec.ts'], + include: ['src/{api,cli,immich-admin}/specs/*.e2e-spec.ts'], globalSetup, testTimeout: 15_000, poolOptions: { diff --git a/server/src/commands/list-users.command.ts b/server/src/commands/list-users.command.ts index 32bcc35d95..ea3e745463 100644 --- a/server/src/commands/list-users.command.ts +++ b/server/src/commands/list-users.command.ts @@ -1,5 +1,4 @@ import { Command, CommandRunner } from 'nest-commander'; -import { UserEntity } from 'src/entities/user.entity'; import { UserService } from 'src/services/user.service'; @Command({ @@ -13,16 +12,7 @@ export class ListUsersCommand extends CommandRunner { async run(): Promise { try { - const users = await this.userService.getAll( - { - user: { - id: 'cli', - email: 'cli@immich.app', - isAdmin: true, - } as UserEntity, - }, - true, - ); + const users = await this.userService.listUsers(); console.dir(users); } catch (error) { console.error(error); diff --git a/server/src/services/user.service.ts b/server/src/services/user.service.ts index cb9012d641..9d40a14e5a 100644 --- a/server/src/services/user.service.ts +++ b/server/src/services/user.service.ts @@ -37,6 +37,11 @@ export class UserService { this.configCore = SystemConfigCore.create(configRepository, this.logger); } + async listUsers(): Promise { + const users = await this.userRepository.getList({ withDeleted: true }); + return users.map((user) => mapUser(user)); + } + async getAll(auth: AuthDto, isAll: boolean): Promise { const users = await this.userRepository.getList({ withDeleted: !isAll }); return users.map((user) => mapUser(user));