|
@@ -1,131 +1,66 @@
|
|
-import { faker } from '@faker-js/faker';
|
|
|
|
import React from 'react';
|
|
import React from 'react';
|
|
-import { render, screen, waitFor, act, fireEvent, renderHook } from '../../../../../../tests/test-utils';
|
|
|
|
-import { getTRPCMockError } from '../../../../mocks/getTrpcMock';
|
|
|
|
-import { server } from '../../../../mocks/server';
|
|
|
|
-import { useSystemStore } from '../../../../state/systemStore';
|
|
|
|
|
|
+import { server } from '@/client/mocks/server';
|
|
|
|
+import { getTRPCMockError } from '@/client/mocks/getTrpcMock';
|
|
import { useToastStore } from '../../../../state/toastStore';
|
|
import { useToastStore } from '../../../../state/toastStore';
|
|
import { SettingsContainer } from './SettingsContainer';
|
|
import { SettingsContainer } from './SettingsContainer';
|
|
|
|
+import { fireEvent, render, renderHook, screen, waitFor } from '../../../../../../tests/test-utils';
|
|
|
|
|
|
describe('Test: SettingsContainer', () => {
|
|
describe('Test: SettingsContainer', () => {
|
|
- describe('UI', () => {
|
|
|
|
- it('renders without crashing', () => {
|
|
|
|
- const current = faker.system.semver();
|
|
|
|
- render(<SettingsContainer data={{ current }} />);
|
|
|
|
|
|
+ it('should render without error', () => {
|
|
|
|
+ render(<SettingsContainer />);
|
|
|
|
|
|
- expect(screen.getByText('Tipi settings')).toBeInTheDocument();
|
|
|
|
- expect(screen.getByText('Already up to date')).toBeInTheDocument();
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- it('should make update button disable if current version is equal to latest version', () => {
|
|
|
|
- const current = faker.system.semver();
|
|
|
|
- render(<SettingsContainer data={{ current, latest: current }} />);
|
|
|
|
-
|
|
|
|
- expect(screen.getByText('Already up to date')).toBeDisabled();
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- it('should make update button disabled if current version is greater than latest version', () => {
|
|
|
|
- const current = '1.0.0';
|
|
|
|
- const latest = '0.0.1';
|
|
|
|
- render(<SettingsContainer data={{ current, latest }} />);
|
|
|
|
-
|
|
|
|
- expect(screen.getByText('Already up to date')).toBeDisabled();
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- it('should display update button if current version is less than latest version', () => {
|
|
|
|
- const current = '0.0.1';
|
|
|
|
- const latest = '1.0.0';
|
|
|
|
-
|
|
|
|
- render(<SettingsContainer data={{ current, latest }} />);
|
|
|
|
- expect(screen.getByText(`Update to ${latest}`)).toBeInTheDocument();
|
|
|
|
- expect(screen.getByText(`Update to ${latest}`)).not.toBeDisabled();
|
|
|
|
- });
|
|
|
|
|
|
+ expect(screen.getByText('General settings')).toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
|
|
- describe('Restart', () => {
|
|
|
|
- it('should remove token from local storage on success', async () => {
|
|
|
|
- const { result, unmount } = renderHook(() => useSystemStore());
|
|
|
|
- const current = faker.system.semver();
|
|
|
|
- const removeItem = jest.spyOn(localStorage, 'removeItem');
|
|
|
|
|
|
+ it('should show toast if updateSettings mutation fails', async () => {
|
|
|
|
+ // arrange
|
|
|
|
+ const { result } = renderHook(() => useToastStore());
|
|
|
|
+ server.use(getTRPCMockError({ path: ['system', 'updateSettings'], type: 'mutation', status: 500, message: 'Something went wrong' }));
|
|
|
|
+ render(<SettingsContainer />);
|
|
|
|
+ const submitButton = screen.getByRole('button', { name: 'Save' });
|
|
|
|
|
|
- render(<SettingsContainer data={{ current, latest: current }} />);
|
|
|
|
- expect(result.current.pollStatus).toBe(false);
|
|
|
|
-
|
|
|
|
- const restartButton = screen.getByTestId('settings-modal-restart-button');
|
|
|
|
-
|
|
|
|
- act(() => {
|
|
|
|
- fireEvent.click(restartButton);
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- await waitFor(() => {
|
|
|
|
- expect(removeItem).toBeCalledWith('token');
|
|
|
|
- expect(result.current.pollStatus).toBe(true);
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- removeItem.mockRestore();
|
|
|
|
- unmount();
|
|
|
|
|
|
+ await waitFor(() => {
|
|
|
|
+ expect(screen.getByDisplayValue('1.1.1.1')).toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
|
|
- it('should display error toast on error', async () => {
|
|
|
|
- const { result, unmount } = renderHook(() => useToastStore());
|
|
|
|
- const current = faker.system.semver();
|
|
|
|
- const error = faker.lorem.sentence();
|
|
|
|
- server.use(getTRPCMockError({ path: ['system', 'restart'], type: 'mutation', message: error }));
|
|
|
|
- render(<SettingsContainer data={{ current }} />);
|
|
|
|
-
|
|
|
|
- const restartButton = screen.getByTestId('settings-modal-restart-button');
|
|
|
|
- act(() => {
|
|
|
|
- fireEvent.click(restartButton);
|
|
|
|
- });
|
|
|
|
|
|
+ // act
|
|
|
|
+ fireEvent.click(submitButton);
|
|
|
|
|
|
- await waitFor(() => {
|
|
|
|
- expect(result.current.toasts[0].description).toBe(error);
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- unmount();
|
|
|
|
|
|
+ // assert
|
|
|
|
+ await waitFor(() => {
|
|
|
|
+ expect(result.current.toasts).toHaveLength(1);
|
|
|
|
+ expect(result.current.toasts[0].status).toEqual('error');
|
|
|
|
+ expect(result.current.toasts[0].title).toEqual('Error saving settings');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
|
|
- describe('Update', () => {
|
|
|
|
- it('should remove token from local storage on success', async () => {
|
|
|
|
- const { result, unmount } = renderHook(() => useSystemStore());
|
|
|
|
- const current = '0.0.1';
|
|
|
|
- const latest = faker.system.semver();
|
|
|
|
- const removeItem = jest.spyOn(localStorage, 'removeItem');
|
|
|
|
-
|
|
|
|
- render(<SettingsContainer data={{ current, latest }} />);
|
|
|
|
-
|
|
|
|
- const updateButton = screen.getByText('Update');
|
|
|
|
- act(() => {
|
|
|
|
- fireEvent.click(updateButton);
|
|
|
|
- });
|
|
|
|
|
|
+ it('should put zod errors in the fields', async () => {
|
|
|
|
+ // arrange
|
|
|
|
+ server.use(getTRPCMockError({ path: ['system', 'updateSettings'], zodError: { dnsIp: 'invalid ip' }, type: 'mutation', status: 500, message: 'Something went wrong' }));
|
|
|
|
+ render(<SettingsContainer />);
|
|
|
|
+ const submitButton = screen.getByRole('button', { name: 'Save' });
|
|
|
|
|
|
- await waitFor(() => {
|
|
|
|
- expect(removeItem).toBeCalledWith('token');
|
|
|
|
- expect(result.current.pollStatus).toBe(true);
|
|
|
|
- });
|
|
|
|
|
|
+ // act
|
|
|
|
+ fireEvent.click(submitButton);
|
|
|
|
|
|
- unmount();
|
|
|
|
|
|
+ await waitFor(() => {
|
|
|
|
+ expect(screen.getByText('invalid ip')).toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
+ });
|
|
|
|
|
|
- it('should display error toast on error', async () => {
|
|
|
|
- const { result, unmount } = renderHook(() => useToastStore());
|
|
|
|
- const current = '0.0.1';
|
|
|
|
- const latest = faker.system.semver();
|
|
|
|
- const error = faker.lorem.sentence();
|
|
|
|
- server.use(getTRPCMockError({ path: ['system', 'update'], type: 'mutation', message: error }));
|
|
|
|
- render(<SettingsContainer data={{ current, latest }} />);
|
|
|
|
-
|
|
|
|
- const updateButton = screen.getByText('Update');
|
|
|
|
- act(() => {
|
|
|
|
- fireEvent.click(updateButton);
|
|
|
|
- });
|
|
|
|
|
|
+ it('should show toast if updateSettings mutation succeeds', async () => {
|
|
|
|
+ // arrange
|
|
|
|
+ const { result } = renderHook(() => useToastStore());
|
|
|
|
+ render(<SettingsContainer />);
|
|
|
|
+ const submitButton = screen.getByRole('button', { name: 'Save' });
|
|
|
|
|
|
- await waitFor(() => {
|
|
|
|
- expect(result.current.toasts[0].description).toBe(error);
|
|
|
|
- });
|
|
|
|
|
|
+ // act
|
|
|
|
+ fireEvent.click(submitButton);
|
|
|
|
|
|
- unmount();
|
|
|
|
|
|
+ // assert
|
|
|
|
+ await waitFor(() => {
|
|
|
|
+ expect(result.current.toasts).toHaveLength(1);
|
|
|
|
+ expect(result.current.toasts[0].status).toEqual('success');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|