test: add coverage for new features
This commit is contained in:
parent
25ad967ccb
commit
70b6c20b29
10 changed files with 81 additions and 12 deletions
2
.github/workflows/e2e.yml
vendored
2
.github/workflows/e2e.yml
vendored
|
@ -104,7 +104,7 @@ jobs:
|
|||
cd runtipi
|
||||
echo 'Checking out branch ${{ github.head_ref }}'
|
||||
git checkout ${{ github.head_ref }}
|
||||
sudo ./scripts/start-e2e.sh latest
|
||||
sudo ./scripts/start-e2e.sh e2e
|
||||
echo 'App deployed'
|
||||
host: ${{ steps.get-droplet-ip.outputs.droplet_ip }}
|
||||
user: root
|
||||
|
|
|
@ -30,8 +30,8 @@ test('user can install and uninstall app', async ({ page, context }) => {
|
|||
await expect(page.getByText('Running')).toBeVisible({ timeout: 60000 });
|
||||
await expect(page.getByText('App installed successfully')).toBeVisible();
|
||||
|
||||
await page.getByTestId('app-details').getByRole('button', { name: 'Open' }).click();
|
||||
const [newPage] = await Promise.all([context.waitForEvent('page'), await page.getByRole('menuitem', { name: 'localhost:8000' }).click()]);
|
||||
await page.getByTestId('app-details').getByRole('button', { name: 'Open' }).press('ArrowDown');
|
||||
const [newPage] = await Promise.all([context.waitForEvent('page'), await page.getByRole('menuitem', { name: `${process.env.SERVER_IP}:8000` }).click()]);
|
||||
|
||||
await newPage.waitForLoadState();
|
||||
await expect(newPage.getByText('Hello World')).toBeVisible();
|
||||
|
|
|
@ -114,9 +114,11 @@ function generateTLSCert() {
|
|||
|
||||
if ! openssl req -x509 -newkey rsa:4096 -keyout traefik/tls/key.pem -out traefik/tls/cert.pem -days 365 -subj "/O=runtipi.io/OU=IT/CN=*.${domain}/emailAddress=webmaster@${domain}" -addext "subjectAltName = DNS:*.${domain},DNS:${domain}" -nodes; then
|
||||
echo "Failed to generate TLS certificate"
|
||||
fi
|
||||
else
|
||||
echo "TLS certificate generated"
|
||||
# Create a file to indicate that the certificate has been generated for this domain
|
||||
touch "traefik/tls/$domain.txt"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ env_variables_json=$(cat <<EOF
|
|||
"local_domain": "tipi.lan",
|
||||
"repo_id": "$("${ROOT_FOLDER}"/scripts/git.sh get_hash "${apps_repository}")",
|
||||
"apps_repository": "${apps_repository}",
|
||||
"domain": "tipi.lan",
|
||||
"domain": "example.com",
|
||||
"storage_path": "${ROOT_FOLDER}",
|
||||
"demo_mode": false,
|
||||
}
|
||||
|
|
|
@ -253,7 +253,8 @@
|
|||
"submit": "Save",
|
||||
"user-settings-title": "User settings",
|
||||
"language": "Language",
|
||||
"help-translate": "Help translate Tipi"
|
||||
"help-translate": "Help translate Tipi",
|
||||
"download-certificate": "Download certificate"
|
||||
},
|
||||
"security": {
|
||||
"tab-title": "Security",
|
||||
|
|
|
@ -29,7 +29,7 @@ export const handlers = [
|
|||
getTRPCMock({
|
||||
path: ['system', 'getSettings'],
|
||||
type: 'query',
|
||||
response: { internalIp: 'localhost', dnsIp: '1.1.1.1', appsRepoUrl: 'https://test.com/test', domain: 'tipi.localhost' },
|
||||
response: { internalIp: 'localhost', dnsIp: '1.1.1.1', appsRepoUrl: 'https://test.com/test', domain: 'tipi.localhost', localDomain: 'tipi.lan' },
|
||||
}),
|
||||
getTRPCMock({
|
||||
path: ['system', 'updateSettings'],
|
||||
|
|
|
@ -124,6 +124,54 @@ describe('Test: AppDetailsContainer', () => {
|
|||
});
|
||||
spy.mockRestore();
|
||||
});
|
||||
|
||||
it('should open with domain when domain is clicked', async () => {
|
||||
// Arrange
|
||||
const app = createAppEntity({ overrides: { domain: 'test.com', exposed: true } });
|
||||
const spy = jest.spyOn(window, 'open').mockImplementation(() => null);
|
||||
render(<AppDetailsContainer app={app} />);
|
||||
|
||||
// Act
|
||||
const openButton = screen.getByRole('button', { name: 'Open' });
|
||||
userEvent.type(openButton, '{arrowdown}');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(/test.com/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const openButtonItem = screen.getByText(/test.com/);
|
||||
userEvent.click(openButtonItem);
|
||||
|
||||
// Assert
|
||||
await waitFor(() => {
|
||||
expect(spy).toHaveBeenCalledWith(`https://test.com`, '_blank', 'noreferrer');
|
||||
});
|
||||
spy.mockRestore();
|
||||
});
|
||||
|
||||
it('should open with local domain when local domain is clicked', async () => {
|
||||
// Arrange
|
||||
const app = createAppEntity({});
|
||||
const spy = jest.spyOn(window, 'open').mockImplementation(() => null);
|
||||
render(<AppDetailsContainer app={app} />);
|
||||
|
||||
// Act
|
||||
const openButton = screen.getByRole('button', { name: 'Open' });
|
||||
userEvent.type(openButton, '{arrowdown}');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(/.tipi.lan/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const openButtonItem = screen.getByText(/.tipi.lan/);
|
||||
userEvent.click(openButtonItem);
|
||||
|
||||
// Assert
|
||||
await waitFor(() => {
|
||||
expect(spy).toHaveBeenCalledWith(`https://${app.id}.tipi.lan`, '_blank', 'noreferrer');
|
||||
});
|
||||
spy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Test: Install app', () => {
|
||||
|
|
|
@ -39,6 +39,7 @@ describe('Test: SettingsForm', () => {
|
|||
internalIp: 'invalid internal ip',
|
||||
appsRepoUrl: 'invalid url',
|
||||
storagePath: 'invalid path',
|
||||
localDomain: 'invalid local domain',
|
||||
};
|
||||
render(<SettingsForm onSubmit={jest.fn()} submitErrors={submitErrors} />);
|
||||
|
||||
|
@ -50,6 +51,7 @@ describe('Test: SettingsForm', () => {
|
|||
expect(screen.getByText(submitErrors.internalIp)).toBeInTheDocument();
|
||||
expect(screen.getByText(submitErrors.appsRepoUrl)).toBeInTheDocument();
|
||||
expect(screen.getByText(submitErrors.storagePath)).toBeInTheDocument();
|
||||
expect(screen.getByText(submitErrors.localDomain)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should correctly validate the form', async () => {
|
||||
|
@ -60,19 +62,21 @@ describe('Test: SettingsForm', () => {
|
|||
const domainInput = screen.getByRole('textbox', { name: 'domain' });
|
||||
const internalIpInput = screen.getByRole('textbox', { name: 'internalIp' });
|
||||
const appsRepoUrlInput = screen.getByRole('textbox', { name: 'appsRepoUrl' });
|
||||
const localDomainInput = screen.getByRole('textbox', { name: 'localDomain' });
|
||||
|
||||
// act
|
||||
fireEvent.change(dnsIpInput, { target: { value: 'invalid ip' } });
|
||||
fireEvent.change(domainInput, { target: { value: 'invalid domain' } });
|
||||
fireEvent.change(internalIpInput, { target: { value: 'invalid internal ip' } });
|
||||
fireEvent.change(appsRepoUrlInput, { target: { value: 'invalid url' } });
|
||||
fireEvent.change(localDomainInput, { target: { value: 'invalid local domain' } });
|
||||
fireEvent.click(submitButton);
|
||||
|
||||
// assert
|
||||
await waitFor(() => {
|
||||
expect(screen.getAllByText('Invalid IP address')).toHaveLength(2);
|
||||
});
|
||||
expect(screen.getByText('Invalid domain')).toBeInTheDocument();
|
||||
expect(screen.getAllByText('Invalid domain')).toHaveLength(2);
|
||||
expect(screen.getByText('Invalid URL')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
@ -90,4 +94,19 @@ describe('Test: SettingsForm', () => {
|
|||
expect(onSubmit).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('should download the certificate when the download button is clicked', async () => {
|
||||
// arrange
|
||||
const spy = jest.spyOn(window, 'open').mockImplementation();
|
||||
render(<SettingsForm onSubmit={jest.fn} />);
|
||||
const downloadButton = screen.getByRole('button', { name: 'Download certificate' });
|
||||
|
||||
// act
|
||||
fireEvent.click(downloadButton);
|
||||
|
||||
// assert
|
||||
await waitFor(() => {
|
||||
expect(spy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -183,9 +183,8 @@ export const SettingsForm = (props: IProps) => {
|
|||
error={errors.localDomain?.message}
|
||||
placeholder="tipi.lan"
|
||||
/>
|
||||
|
||||
<Button className="mt-2" onClick={downloadCertificate}>
|
||||
Download certificate
|
||||
{t('download-certificate')}
|
||||
</Button>
|
||||
</div>
|
||||
<Button loading={loading} type="submit" className="btn-success">
|
||||
|
|
|
@ -65,7 +65,7 @@ nextApp.prepare().then(async () => {
|
|||
EventDispatcher.clear();
|
||||
|
||||
// Run database migrations
|
||||
if (getConfig().NODE_ENV === 'development') {
|
||||
if (getConfig().NODE_ENV !== 'development') {
|
||||
await runPostgresMigrations();
|
||||
}
|
||||
setConfig('status', 'RUNNING');
|
||||
|
|
Loading…
Reference in a new issue