Forráskód Böngészése

test: apps.helpers.ts

Nicolas Meienberger 2 éve
szülő
commit
7adc37ab26

+ 111 - 8
packages/system-api/src/modules/apps/__tests__/apps.helpers.test.ts

@@ -1,7 +1,8 @@
 import { faker } from '@faker-js/faker';
 import fs from 'fs-extra';
+import childProcess from 'child_process';
 import { DataSource } from 'typeorm';
-import { getConfig } from '../../../core/config/TipiConfig';
+import logger from '../../../config/logger/logger';
 import { setupConnection, teardownConnection } from '../../../test/connection';
 import App from '../app.entity';
 import { checkAppRequirements, checkEnvFile, generateEnvFile, getAppInfo, getAvailableApps, getEnvMap, getUpdateInfo, runAppScript } from '../apps.helpers';
@@ -107,7 +108,7 @@ describe('checkEnvFile', () => {
   });
 });
 
-describe('runAppScript', () => {
+describe('Test: runAppScript', () => {
   let app1: AppInfo;
 
   beforeEach(async () => {
@@ -124,9 +125,32 @@ describe('runAppScript', () => {
 
     await runAppScript(['install', app1.id]);
   });
+
+  it('Should log the error if the script fails', async () => {
+    const log = jest.spyOn(logger, 'error');
+    const spy = jest.spyOn(childProcess, 'execFile');
+    const randomWord = faker.random.word();
+
+    // @ts-ignore
+    spy.mockImplementation((_path, _args, _, cb) => {
+      // @ts-ignore
+      if (cb) cb(randomWord, null, null);
+    });
+
+    try {
+      await runAppScript(['install', app1.id]);
+      expect(true).toBe(false);
+    } catch (e: any) {
+      expect(e).toBe(randomWord);
+      expect(log).toHaveBeenCalledWith(`Error running app script: ${randomWord}`);
+    }
+
+    log.mockRestore();
+    spy.mockRestore();
+  });
 });
 
-describe('generateEnvFile', () => {
+describe('Test: generateEnvFile', () => {
   let app1: AppInfo;
   let appEntity1: App;
   beforeEach(async () => {
@@ -234,6 +258,18 @@ describe('generateEnvFile', () => {
     expect(envmap.get('APP_EXPOSED')).toBeUndefined();
     expect(envmap.get('APP_DOMAIN')).toBe(`192.168.1.10:${appInfo.port}`);
   });
+
+  it('Should create app folder if it does not exist', async () => {
+    const { appEntity, appInfo, MockFiles } = await createApp({ installed: true });
+    // @ts-ignore
+    fs.__createMockFiles(MockFiles);
+
+    fs.rmSync(`/app/storage/app-data/${appInfo.id}`, { recursive: true });
+
+    generateEnvFile(appEntity);
+
+    expect(fs.existsSync(`/app/storage/app-data/${appInfo.id}`)).toBe(true);
+  });
 });
 
 describe('getAvailableApps', () => {
@@ -251,7 +287,7 @@ describe('getAvailableApps', () => {
   });
 });
 
-describe('getAppInfo', () => {
+describe('Test: getAppInfo', () => {
   let app1: AppInfo;
   beforeEach(async () => {
     const app1create = await createApp({ installed: false });
@@ -267,15 +303,82 @@ describe('getAppInfo', () => {
   });
 
   it('Should take config.json locally if app is installed', async () => {
-    const { appInfo, MockFiles } = await createApp({ installed: true });
+    const { appInfo, MockFiles, appEntity } = await createApp({ installed: true });
     // @ts-ignore
     fs.__createMockFiles(MockFiles);
 
-    fs.writeFileSync(`${getConfig().rootFolder}/repos/repo-id/apps/${app1.id}/config.json`, '{}');
+    const newConfig = {
+      id: faker.random.alphaNumeric(32),
+    };
+
+    fs.writeFileSync(`/app/storage/apps/${appInfo.id}/config.json`, JSON.stringify(newConfig));
+
+    const app = await getAppInfo(appInfo.id, appEntity.status);
+
+    expect(app?.id).toEqual(newConfig.id);
+  });
+
+  it('Should take config.json from repo if app is not installed', async () => {
+    const { appInfo, MockFiles, appEntity } = await createApp({ installed: false });
+    // @ts-ignore
+    fs.__createMockFiles(MockFiles);
 
-    const app = await getAppInfo(appInfo.id);
+    const newConfig = {
+      id: faker.random.alphaNumeric(32),
+      available: true,
+    };
+
+    fs.writeFileSync(`/runtipi/repos/repo-id/apps/${appInfo.id}/config.json`, JSON.stringify(newConfig));
+
+    const app = await getAppInfo(appInfo.id, appEntity.status);
+
+    expect(app?.id).toEqual(newConfig.id);
+  });
+
+  it('Should return null if app is not available', async () => {
+    const { appInfo, MockFiles, appEntity } = await createApp({ installed: false });
+    // @ts-ignore
+    fs.__createMockFiles(MockFiles);
+
+    const newConfig = {
+      id: faker.random.alphaNumeric(32),
+      available: false,
+    };
+
+    fs.writeFileSync(`/runtipi/repos/repo-id/apps/${appInfo.id}/config.json`, JSON.stringify(newConfig));
+
+    const app = await getAppInfo(appInfo.id, appEntity.status);
+
+    expect(app).toBeNull();
+  });
+
+  it('Should throw if something goes wrong', async () => {
+    const log = jest.spyOn(logger, 'error');
+    const spy = jest.spyOn(fs, 'existsSync').mockImplementation(() => {
+      throw new Error('Something went wrong');
+    });
+
+    const { appInfo, MockFiles, appEntity } = await createApp({ installed: false });
+    // @ts-ignore
+    fs.__createMockFiles(MockFiles);
+
+    const newConfig = {
+      id: faker.random.alphaNumeric(32),
+      available: false,
+    };
+
+    fs.writeFileSync(`/runtipi/repos/repo-id/apps/${appInfo.id}/config.json`, JSON.stringify(newConfig));
+
+    try {
+      await getAppInfo(appInfo.id, appEntity.status);
+      expect(true).toBe(false);
+    } catch (e: any) {
+      expect(e.message).toBe(`Error loading app: ${appInfo.id}`);
+      expect(log).toBeCalledWith(`Error loading app: ${appInfo.id}`);
+    }
 
-    expect(app?.id).toEqual(appInfo.id);
+    spy.mockRestore();
+    log.mockRestore();
   });
 
   it('Should return null if app does not exist', async () => {

+ 3 - 3
packages/system-api/src/modules/apps/apps.helpers.ts

@@ -60,7 +60,7 @@ export const runAppScript = async (params: string[]): Promise<void> => {
   return new Promise((resolve, reject) => {
     runScript('/runtipi/scripts/app.sh', [...params], (err: string) => {
       if (err) {
-        logger.error(err);
+        logger.error(`Error running app script: ${err}`);
         reject(err);
       }
 
@@ -160,8 +160,8 @@ export const getAppInfo = (id: string, status?: AppStatusEnum): AppInfo | null =
 
     return null;
   } catch (e) {
-    console.error(e);
-    throw new Error(`Error loading app ${id}`);
+    logger.error(`Error loading app: ${id}`);
+    throw new Error(`Error loading app: ${id}`);
   }
 };