242 lines
7.9 KiB
TypeScript
242 lines
7.9 KiB
TypeScript
import { faker } from '@faker-js/faker';
|
|
import axios from 'axios';
|
|
import fs from 'fs-extra';
|
|
import { DataSource } from 'typeorm';
|
|
import TipiCache from '../../../config/TipiCache';
|
|
import * as TipiConfig from '../../../core/config/TipiConfig';
|
|
import { setConfig } from '../../../core/config/TipiConfig';
|
|
import { setupConnection, teardownConnection } from '../../../test/connection';
|
|
import { gcall } from '../../../test/gcall';
|
|
import { restartMutation, updateMutation } from '../../../test/mutations';
|
|
import { systemInfoQuery, versionQuery } from '../../../test/queries';
|
|
import User from '../../auth/user.entity';
|
|
import { createUser } from '../../auth/__tests__/user.factory';
|
|
import { SystemInfoResponse } from '../system.types';
|
|
import EventDispatcher from '../../../core/config/EventDispatcher';
|
|
|
|
jest.mock('fs-extra');
|
|
jest.mock('axios');
|
|
|
|
beforeEach(async () => {
|
|
jest.resetModules();
|
|
jest.resetAllMocks();
|
|
jest.restoreAllMocks();
|
|
});
|
|
|
|
let db: DataSource | null = null;
|
|
const TEST_SUITE = 'systemresolver';
|
|
beforeAll(async () => {
|
|
db = await setupConnection(TEST_SUITE);
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await db?.destroy();
|
|
await teardownConnection(TEST_SUITE);
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
jest.resetModules();
|
|
jest.resetAllMocks();
|
|
jest.restoreAllMocks();
|
|
await User.clear();
|
|
});
|
|
|
|
describe('Test: systemInfo', () => {
|
|
beforeEach(async () => {});
|
|
|
|
it('Should return correct system info from file', async () => {
|
|
const systemInfo = {
|
|
cpu: { load: 10 },
|
|
memory: { available: 100, total: 1000, used: 900 },
|
|
disk: { available: 100, total: 1000, used: 900 },
|
|
};
|
|
|
|
const MockFiles = {
|
|
'/runtipi/state/system-info.json': JSON.stringify(systemInfo),
|
|
};
|
|
|
|
// @ts-ignore
|
|
fs.__createMockFiles(MockFiles);
|
|
|
|
const { data } = await gcall<{ systemInfo: SystemInfoResponse }>({ source: systemInfoQuery });
|
|
|
|
expect(data?.systemInfo).toBeDefined();
|
|
expect(data?.systemInfo.cpu).toBeDefined();
|
|
expect(data?.systemInfo.cpu.load).toBe(systemInfo.cpu.load);
|
|
expect(data?.systemInfo.memory).toBeDefined();
|
|
expect(data?.systemInfo.memory.available).toBe(systemInfo.memory.available);
|
|
expect(data?.systemInfo.memory.total).toBe(systemInfo.memory.total);
|
|
expect(data?.systemInfo.memory.used).toBe(systemInfo.memory.used);
|
|
expect(data?.systemInfo.disk).toBeDefined();
|
|
expect(data?.systemInfo.disk.available).toBe(systemInfo.disk.available);
|
|
expect(data?.systemInfo.disk.total).toBe(systemInfo.disk.total);
|
|
expect(data?.systemInfo.disk.used).toBe(systemInfo.disk.used);
|
|
});
|
|
|
|
it('Should return 0 for missing values', async () => {
|
|
const systemInfo = {
|
|
cpu: {},
|
|
memory: {},
|
|
disk: {},
|
|
};
|
|
|
|
const MockFiles = {
|
|
'/runtipi/state/system-info.json': JSON.stringify(systemInfo),
|
|
};
|
|
|
|
// @ts-ignore
|
|
fs.__createMockFiles(MockFiles);
|
|
|
|
const { data } = await gcall<{ systemInfo: SystemInfoResponse }>({ source: systemInfoQuery });
|
|
|
|
expect(data?.systemInfo).toBeDefined();
|
|
expect(data?.systemInfo.cpu).toBeDefined();
|
|
expect(data?.systemInfo.cpu.load).toBe(0);
|
|
expect(data?.systemInfo.memory).toBeDefined();
|
|
expect(data?.systemInfo.memory.available).toBe(0);
|
|
expect(data?.systemInfo.memory.total).toBe(0);
|
|
expect(data?.systemInfo.memory.used).toBe(0);
|
|
expect(data?.systemInfo.disk).toBeDefined();
|
|
expect(data?.systemInfo.disk.available).toBe(0);
|
|
expect(data?.systemInfo.disk.total).toBe(0);
|
|
expect(data?.systemInfo.disk.used).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe('Test: getVersion', () => {
|
|
const current = `${faker.random.numeric(1)}.${faker.random.numeric(1)}.${faker.random.numeric()}`;
|
|
const latest = `${faker.random.numeric(1)}.${faker.random.numeric(1)}.${faker.random.numeric()}`;
|
|
beforeEach(async () => {
|
|
jest.spyOn(axios, 'get').mockResolvedValue({
|
|
data: { name: `v${latest}` },
|
|
});
|
|
setConfig('version', current);
|
|
});
|
|
|
|
it('Should return correct version', async () => {
|
|
const { data } = await gcall<{ version: { current: string; latest?: string } }>({
|
|
source: versionQuery,
|
|
});
|
|
|
|
expect(data?.version).toBeDefined();
|
|
expect(data?.version.current).toBeDefined();
|
|
expect(data?.version.latest).toBeDefined();
|
|
expect(data?.version.current).toBe(current);
|
|
expect(data?.version.latest).toBe(latest);
|
|
});
|
|
});
|
|
|
|
describe('Test: restart', () => {
|
|
beforeEach(async () => {
|
|
setConfig('status', 'RUNNING');
|
|
setConfig('version', '1.0.0');
|
|
TipiCache.set('latestVersion', '1.0.1');
|
|
});
|
|
|
|
it('Should return true', async () => {
|
|
// Arrange
|
|
EventDispatcher.prototype.dispatchEventAsync = jest.fn().mockResolvedValueOnce({ success: true });
|
|
|
|
// Act
|
|
const user = await createUser();
|
|
const { data } = await gcall<{ restart: boolean }>({ source: restartMutation, userId: user.id });
|
|
|
|
// Assert
|
|
expect(data?.restart).toBeDefined();
|
|
expect(data?.restart).toBe(true);
|
|
});
|
|
|
|
it("Should return an error if user doesn't exist", async () => {
|
|
// Arrange
|
|
const { data, errors } = await gcall<{ restart: boolean }>({
|
|
source: restartMutation,
|
|
userId: 1,
|
|
});
|
|
|
|
// Assert
|
|
expect(errors?.[0].message).toBe('Access denied! You need to be authorized to perform this action!');
|
|
expect(data?.restart).toBeUndefined();
|
|
});
|
|
|
|
it('Should throw an error if no userId is not provided', async () => {
|
|
// Arrange
|
|
const { data, errors } = await gcall<{ restart: boolean }>({ source: restartMutation });
|
|
|
|
// Assert
|
|
expect(errors?.[0].message).toBe('Access denied! You need to be authorized to perform this action!');
|
|
expect(data?.restart).toBeUndefined();
|
|
});
|
|
|
|
it('Should set app status to restarting', async () => {
|
|
// Arrange
|
|
EventDispatcher.prototype.dispatchEventAsync = jest.fn().mockResolvedValueOnce({ success: true });
|
|
const spy = jest.spyOn(TipiConfig, 'setConfig');
|
|
const user = await createUser();
|
|
|
|
// Act
|
|
await gcall<{ restart: boolean }>({ source: restartMutation, userId: user.id });
|
|
|
|
// Assert
|
|
expect(spy).toHaveBeenCalledTimes(2);
|
|
expect(spy).toHaveBeenNthCalledWith(1, 'status', 'RESTARTING');
|
|
expect(spy).toHaveBeenNthCalledWith(2, 'status', 'RUNNING');
|
|
|
|
spy.mockRestore();
|
|
});
|
|
});
|
|
|
|
describe('Test: update', () => {
|
|
beforeEach(async () => {
|
|
setConfig('status', 'RUNNING');
|
|
setConfig('version', '1.0.0');
|
|
TipiCache.set('latestVersion', '1.0.1');
|
|
});
|
|
|
|
it('Should return true', async () => {
|
|
// Arrange
|
|
EventDispatcher.prototype.dispatchEventAsync = jest.fn().mockResolvedValueOnce({ success: true });
|
|
const user = await createUser();
|
|
|
|
// Act
|
|
const { data } = await gcall<{ update: boolean }>({ source: updateMutation, userId: user.id });
|
|
|
|
// Assert
|
|
expect(data?.update).toBeDefined();
|
|
expect(data?.update).toBe(true);
|
|
});
|
|
|
|
it("Should return an error if user doesn't exist", async () => {
|
|
// Act
|
|
const { data, errors } = await gcall<{ update: boolean }>({ source: updateMutation, userId: 1 });
|
|
|
|
// Assert
|
|
expect(errors?.[0].message).toBe('Access denied! You need to be authorized to perform this action!');
|
|
expect(data?.update).toBeUndefined();
|
|
});
|
|
|
|
it('Should throw an error if no userId is not provided', async () => {
|
|
// Act
|
|
const { data, errors } = await gcall<{ update: boolean }>({ source: updateMutation });
|
|
|
|
// Assert
|
|
expect(errors?.[0].message).toBe('Access denied! You need to be authorized to perform this action!');
|
|
expect(data?.update).toBeUndefined();
|
|
});
|
|
|
|
it('Should set app status to updating', async () => {
|
|
// Arrange
|
|
EventDispatcher.prototype.dispatchEventAsync = jest.fn().mockResolvedValueOnce({ success: true });
|
|
const spy = jest.spyOn(TipiConfig, 'setConfig');
|
|
const user = await createUser();
|
|
|
|
// Act
|
|
await gcall<{ update: boolean }>({ source: updateMutation, userId: user.id });
|
|
|
|
// Assert
|
|
expect(spy).toHaveBeenCalledTimes(2);
|
|
expect(spy).toHaveBeenNthCalledWith(1, 'status', 'UPDATING');
|
|
expect(spy).toHaveBeenNthCalledWith(2, 'status', 'RUNNING');
|
|
|
|
spy.mockRestore();
|
|
});
|
|
});
|