Bladeren bron

refactor: remove the ability to update tipi through the ui

Nicolas Meienberger 1 jaar geleden
bovenliggende
commit
e9da22f686

+ 2 - 21
src/client/components/hoc/StatusProvider/StatusProvider.test.tsx

@@ -52,29 +52,10 @@ describe('Test: StatusProvider', () => {
     unmount();
   });
 
-  it('should render StatusScreen when system is UPDATING', async () => {
-    const { result, unmount } = renderHook(() => useSystemStore());
-    act(() => {
-      result.current.setStatus('UPDATING');
-    });
-
-    render(
-      <StatusProvider>
-        <div>system running</div>
-      </StatusProvider>,
-    );
-
-    await waitFor(() => {
-      expect(screen.getByText('Your system is updating...')).toBeInTheDocument();
-    });
-
-    unmount();
-  });
-
   it('should reload the page when system is RUNNING after being something else than RUNNING', async () => {
     const { result, unmount } = renderHook(() => useSystemStore());
     act(() => {
-      result.current.setStatus('UPDATING');
+      result.current.setStatus('RESTARTING');
     });
 
     render(
@@ -84,7 +65,7 @@ describe('Test: StatusProvider', () => {
     );
 
     await waitFor(() => {
-      expect(screen.getByText('Your system is updating...')).toBeInTheDocument();
+      expect(screen.getByText('Your system is restarting...')).toBeInTheDocument();
     });
 
     act(() => {

+ 0 - 7
src/client/components/hoc/StatusProvider/StatusProvider.tsx

@@ -23,9 +23,6 @@ export const StatusProvider: React.FC<IProps> = ({ children }) => {
     if (status === 'RESTARTING') {
       s.current = 'RESTARTING';
     }
-    if (status === 'UPDATING') {
-      s.current = 'UPDATING';
-    }
   }, [status, s, setPollStatus]);
 
   if (s.current === 'LOADING') {
@@ -36,9 +33,5 @@ export const StatusProvider: React.FC<IProps> = ({ children }) => {
     return <StatusScreen title="Your system is restarting..." subtitle="Please do not refresh this page" />;
   }
 
-  if (s.current === 'UPDATING') {
-    return <StatusScreen title="Your system is updating..." subtitle="Please do not refresh this page" />;
-  }
-
   return children;
 };

+ 1 - 2
src/client/messages/en.json

@@ -33,7 +33,7 @@
       "domain-already-in-use": "Domain {domain} is already in use by app {id}",
       "could-not-get-latest-version": "Could not get latest version",
       "current-version-is-latest": "Current version is already up to date",
-      "major-version-update": "The major version has changed. Please update manually (instructions on GitHub)",
+      "major-version-update": "The major version has changed. Please update manually (instructions in release notes)",
       "demo-mode-limit": "Only 6 apps can be installed in the demo mode. Please uninstall an other app to install a new one."
     },
     "success": {}
@@ -229,7 +229,6 @@
       "maintenance-title": "Maintenance",
       "maintenance-subtitle": "Common actions to perform on your instance",
       "restart": "Restart",
-      "update": "Update to {version}",
       "already-latest": "Already up to date"
     },
     "settings": {

+ 0 - 6
src/client/mocks/handlers.ts

@@ -9,12 +9,6 @@ export const handlers = [
     type: 'query',
     response: { current: '1.0.0', latest: '1.0.0', body: 'hello' },
   }),
-  getTRPCMock({
-    path: ['system', 'update'],
-    type: 'mutation',
-    response: true,
-    delay: 100,
-  }),
   getTRPCMock({
     path: ['system', 'restart'],
     type: 'mutation',

+ 0 - 28
src/client/modules/Settings/components/UpdateModal/UpdateModal.tsx

@@ -1,28 +0,0 @@
-import React from 'react';
-import { Button } from '../../../../components/ui/Button';
-import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader } from '../../../../components/ui/Dialog';
-
-interface IProps {
-  isOpen: boolean;
-  onClose: () => void;
-  onConfirm: () => void;
-  loading: boolean;
-}
-
-export const UpdateModal: React.FC<IProps> = ({ isOpen, onClose, onConfirm, loading }) => (
-  <Dialog open={isOpen} onOpenChange={onClose}>
-    <DialogContent size="sm">
-      <DialogHeader>
-        <h5 className="modal-title">Update Tipi</h5>
-      </DialogHeader>
-      <DialogDescription>
-        <div className="text-muted">Would you like to update Tipi to the latest version?</div>
-      </DialogDescription>
-      <DialogFooter>
-        <Button onClick={onConfirm} className="btn-success" loading={loading}>
-          Update
-        </Button>
-      </DialogFooter>
-    </DialogContent>
-  </Dialog>
-);

+ 0 - 1
src/client/modules/Settings/components/UpdateModal/index.ts

@@ -1 +0,0 @@
-export { UpdateModal } from './UpdateModal';

+ 0 - 52
src/client/modules/Settings/containers/GeneralActions/GeneralActions.test.tsx

@@ -14,58 +14,6 @@ describe('Test: GeneralActions', () => {
     expect(screen.getByText('Actions')).toBeInTheDocument();
   });
 
-  it('should show toast if update mutation fails', async () => {
-    // arrange
-    server.use(getTRPCMock({ path: ['system', 'getVersion'], response: { current: '1.0.0', latest: '2.0.0', body: '' } }));
-    server.use(getTRPCMockError({ path: ['system', 'update'], type: 'mutation', status: 500, message: 'Something went wrong' }));
-    render(<GeneralActions />);
-    await waitFor(() => {
-      expect(screen.getByText('Update to 2.0.0')).toBeInTheDocument();
-    });
-    const updateButton = screen.getByRole('button', { name: /Update/i });
-    fireEvent.click(updateButton);
-
-    // act
-    const updateButtonModal = screen.getByRole('button', { name: /Update/i });
-    fireEvent.click(updateButtonModal);
-
-    // assert
-    await waitFor(() => {
-      expect(screen.getByText(/Something went wrong/)).toBeInTheDocument();
-    });
-  });
-
-  it('should set poll status to true if update mutation succeeds', async () => {
-    // arrange
-    server.use(getTRPCMock({ path: ['system', 'getVersion'], response: { current: '1.0.0', latest: '2.0.0', body: '' } }));
-    server.use(getTRPCMock({ path: ['system', 'update'], type: 'mutation', response: true }));
-    const { result } = renderHook(() => useSystemStore());
-    result.current.setStatus('RUNNING');
-
-    render(
-      <StatusProvider>
-        <GeneralActions />
-      </StatusProvider>,
-    );
-    await waitFor(() => {
-      expect(screen.getByText('Update to 2.0.0')).toBeInTheDocument();
-    });
-    const updateButton = screen.getByRole('button', { name: /Update/i });
-    fireEvent.click(updateButton);
-
-    // act
-    const updateButtonModal = screen.getByRole('button', { name: /Update/i });
-    fireEvent.click(updateButtonModal);
-
-    result.current.setStatus('UPDATING');
-
-    // assert
-    await waitFor(() => {
-      expect(screen.getByText('Your system is updating...')).toBeInTheDocument();
-    });
-    expect(result.current.pollStatus).toBe(true);
-  });
-
   it('should show toast if restart mutation fails', async () => {
     // arrange
     server.use(getTRPCMockError({ path: ['system', 'restart'], type: 'mutation', status: 500, message: 'Something went badly' }));

+ 0 - 20
src/client/modules/Settings/containers/GeneralActions/GeneralActions.tsx

@@ -8,7 +8,6 @@ import { MessageKey } from '@/server/utils/errors';
 import { Button } from '../../../../components/ui/Button';
 import { useDisclosure } from '../../../../hooks/useDisclosure';
 import { RestartModal } from '../../components/RestartModal';
-import { UpdateModal } from '../../components/UpdateModal/UpdateModal';
 import { trpc } from '../../../../utils/trpc';
 import { useSystemStore } from '../../../../state/systemStore';
 
@@ -19,25 +18,10 @@ export const GeneralActions = () => {
   const [loading, setLoading] = React.useState(false);
   const { setPollStatus } = useSystemStore();
   const restartDisclosure = useDisclosure();
-  const updateDisclosure = useDisclosure();
 
   const defaultVersion = '0.0.0';
   const isLatest = semver.gte(versionQuery.data?.current || defaultVersion, versionQuery.data?.latest || defaultVersion);
 
-  const update = trpc.system.update.useMutation({
-    onMutate: () => {
-      setLoading(true);
-    },
-    onSuccess: async () => {
-      setPollStatus(true);
-    },
-    onError: (e) => {
-      updateDisclosure.close();
-      setLoading(false);
-      toast.error(t(e.data?.tError.message as MessageKey, { ...e.data?.tError?.variables }));
-    },
-  });
-
   const restart = trpc.system.restart.useMutation({
     onMutate: () => {
       setLoading(true);
@@ -71,9 +55,6 @@ export const GeneralActions = () => {
             </div>
           </div>
         )}
-        <Button onClick={updateDisclosure.open} className="mt-3 mr-2 btn-success">
-          {t('settings.actions.update', { version: versionQuery.data?.latest })}
-        </Button>
       </div>
     );
   };
@@ -92,7 +73,6 @@ export const GeneralActions = () => {
         </div>
       </div>
       <RestartModal isOpen={restartDisclosure.isOpen} onClose={restartDisclosure.close} onConfirm={() => restart.mutate()} loading={loading} />
-      <UpdateModal isOpen={updateDisclosure.isOpen} onClose={updateDisclosure.close} onConfirm={() => update.mutate()} loading={loading} />
     </>
   );
 };

+ 0 - 1
src/client/state/systemStore.ts

@@ -3,7 +3,6 @@ import { create } from 'zustand';
 const SYSTEM_STATUS = {
   RUNNING: 'RUNNING',
   RESTARTING: 'RESTARTING',
-  UPDATING: 'UPDATING',
   LOADING: 'LOADING',
 } as const;
 export type SystemStatus = (typeof SYSTEM_STATUS)[keyof typeof SYSTEM_STATUS];

+ 0 - 1
src/server/routers/system/system.router.ts

@@ -12,7 +12,6 @@ export const systemRouter = router({
   systemInfo: protectedProcedure.query(SystemServiceClass.systemInfo),
   getVersion: publicProcedure.query(SystemService.getVersion),
   restart: protectedProcedure.mutation(SystemService.restart),
-  update: protectedProcedure.mutation(SystemService.update),
   updateSettings: protectedProcedure.input(settingsSchema).mutation(({ input }) => TipiConfig.setSettings(input)),
   getSettings: protectedProcedure.query(TipiConfig.getSettings),
 });

+ 0 - 56
src/server/services/system/system.service.test.ts

@@ -160,59 +160,3 @@ describe('Test: restart', () => {
     await expect(SystemService.restart()).rejects.toThrow('server-messages.errors.not-allowed-in-demo');
   });
 });
-
-describe('Test: update', () => {
-  it('Should return true', async () => {
-    // Arrange
-    EventDispatcher.dispatchEventAsync = jest.fn().mockResolvedValueOnce({ success: true });
-    setConfig('version', '0.0.1');
-    await cache.set('latestVersion', '0.0.2');
-
-    // Act
-    const update = await SystemService.update();
-
-    // Assert
-    expect(update).toBeTruthy();
-  });
-
-  it('Should throw an error if latest version is not set', async () => {
-    // Arrange
-    await cache.del('latestVersion');
-    server.use(
-      rest.get('https://api.github.com/repos/meienberger/runtipi/releases/latest', (_, res, ctx) => {
-        return res(ctx.json({ name: null }));
-      }),
-    );
-    setConfig('version', '0.0.1');
-
-    // Act & Assert
-    await expect(SystemService.update()).rejects.toThrow('server-messages.errors.could-not-get-latest-version');
-  });
-
-  it('Should throw if current version is higher than latest', async () => {
-    // Arrange
-    setConfig('version', '0.0.2');
-    await cache.set('latestVersion', '0.0.1');
-
-    // Act & Assert
-    await expect(SystemService.update()).rejects.toThrow('server-messages.errors.current-version-is-latest');
-  });
-
-  it('Should throw if current version is equal to latest', async () => {
-    // Arrange
-    setConfig('version', '0.0.1');
-    await cache.set('latestVersion', '0.0.1');
-
-    // Act & Assert
-    await expect(SystemService.update()).rejects.toThrow('server-messages.errors.current-version-is-latest');
-  });
-
-  it('Should throw an error if there is a major version difference', async () => {
-    // Arrange
-    setConfig('version', '0.0.1');
-    await cache.set('latestVersion', '1.0.0');
-
-    // Act & Assert
-    await expect(SystemService.update()).rejects.toThrow('server-messages.errors.major-version-update');
-  });
-});

+ 0 - 31
src/server/services/system/system.service.ts

@@ -1,4 +1,3 @@
-import semver from 'semver';
 import { z } from 'zod';
 import axios from 'redaxios';
 import { TranslatedError } from '@/server/utils/errors';
@@ -84,36 +83,6 @@ export class SystemServiceClass {
     return info.data;
   };
 
-  public update = async (): Promise<boolean> => {
-    const { current, latest } = await this.getVersion();
-
-    if (TipiConfig.getConfig().NODE_ENV === 'development') {
-      throw new TranslatedError('server-messages.errors.not-allowed-in-dev');
-    }
-
-    if (!latest) {
-      throw new TranslatedError('server-messages.errors.could-not-get-latest-version');
-    }
-
-    if (semver.gt(current, latest)) {
-      throw new TranslatedError('server-messages.errors.current-version-is-latest');
-    }
-
-    if (semver.eq(current, latest)) {
-      throw new TranslatedError('server-messages.errors.current-version-is-latest');
-    }
-
-    if (semver.major(current) !== semver.major(latest)) {
-      throw new TranslatedError('server-messages.errors.major-version-update');
-    }
-
-    TipiConfig.setConfig('status', 'UPDATING');
-
-    this.dispatcher.dispatchEvent({ type: 'system', command: 'update', version: latest });
-
-    return true;
-  };
-
   public restart = async (): Promise<boolean> => {
     if (TipiConfig.getConfig().NODE_ENV === 'development') {
       throw new TranslatedError('server-messages.errors.not-allowed-in-dev');