0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-20 22:42:53 -05:00
ghost/apps/admin-x-settings/test/e2e/advanced/integrations/custom.test.ts

218 lines
8.3 KiB
TypeScript
Raw Normal View History

import {Integration, IntegrationsResponseType} from '../../../../src/api/integrations';
import {Webhook, WebhooksResponseType} from '../../../../src/api/webhooks';
import {chooseOptionInSelect, globalDataRequests, limitRequests, mockApi, responseFixtures} from '../../../utils/e2e';
import {expect, test} from '@playwright/test';
test.describe('Custom integrations', async () => {
test('Supports creating an integration and adding webhooks', async ({page}) => {
const integration = {
id: 'custom-id',
type: 'custom',
slug: 'my-integration',
name: 'My integration',
icon_image: null,
description: null,
created_at: '2023-01-01T00:00:00.000Z',
updated_at: '2023-01-01T00:00:00.000Z',
api_keys: [{
id: 'admin-key-id',
type: 'admin',
secret: 'admin-api-secret',
role_id: 'role-id',
integration_id: 'my-integration',
user_id: 'user-id',
last_seen_at: null,
last_seen_version: null,
created_at: '2023-01-01T00:00:00.000Z',
updated_at: '2023-01-01T00:00:00.000Z'
}, {
id: 'content-key-id',
type: 'content',
secret: 'content-api-secret',
role_id: 'role-id',
integration_id: 'my-integration',
user_id: 'user-id',
last_seen_at: null,
last_seen_version: null,
created_at: '2023-01-01T00:00:00.000Z',
updated_at: '2023-01-01T00:00:00.000Z'
}]
} satisfies Integration;
const webhook = {
id: 'webhook-id',
event: 'post.created',
target_url: 'https://example.com',
name: 'My webhook',
secret: null,
api_version: 'v3',
integration_id: integration.id,
last_triggered_at: null,
last_triggered_status: null,
last_triggered_error: null,
created_at: '2023-01-01T00:00:00.000Z',
updated_at: '2023-01-01T00:00:00.000Z'
} satisfies Webhook;
await mockApi({
page,
requests: {
...globalDataRequests,
browseIntegrations: {
method: 'GET',
path: '/integrations/?include=api_keys%2Cwebhooks',
response: {integrations: []} satisfies IntegrationsResponseType
},
addIntegration: {
method: 'POST',
path: '/integrations/?include=api_keys%2Cwebhooks',
response: {integrations: [integration]} satisfies IntegrationsResponseType
},
editIntegration: {
method: 'PUT',
path: `/integrations/${integration.id}/?include=api_keys%2Cwebhooks`,
response: {integrations: [{
...integration,
description: 'Test description'
}]} satisfies IntegrationsResponseType
},
deleteIntegration: {
method: 'DELETE',
path: `/integrations/${integration.id}/`,
response: null
},
createWebhook: {
method: 'POST',
path: '/webhooks/',
response: {webhooks: [webhook]} satisfies WebhooksResponseType
},
editWebhook: {
method: 'PUT',
path: `/webhooks/${webhook.id}/`,
response: {webhooks: [{
...webhook,
name: 'Updated webhook'
}]} satisfies WebhooksResponseType
},
deleteWebhook: {
method: 'DELETE',
path: `/webhooks/${webhook.id}/`,
response: null
},
refreshAPIKey: {
method: 'POST',
path: /\/api_key\/.+\/refresh/,
response: ({
integrations: [{
...integration,
api_keys: [{
...integration.api_keys[0],
secret: 'new-api-key'
}]
}]
} satisfies IntegrationsResponseType)
}
}
});
await page.goto('/');
const integrationsSection = page.getByTestId('integrations');
await integrationsSection.getByRole('button', {name: 'Add custom integration'}).click();
const createModal = page.getByTestId('add-integration-modal');
createModal.getByLabel('Name').fill('My integration');
createModal.getByRole('button', {name: 'Add'}).click();
const modal = page.getByTestId('custom-integration-modal');
// Regenerate API key
await expect(modal).toHaveText(/admin-api-secret/);
await modal.getByText('admin-api-secret').hover();
await modal.getByRole('button', {name: 'Regenerate'}).click();
await page.getByTestId('confirmation-modal').getByRole('button', {name: 'Regenerate Admin API Key'}).click();
await expect(modal).toHaveText(/Admin API Key was successfully regenerated/);
await expect(modal).toHaveText(/new-api-key/);
// Create webhook
await modal.getByRole('button', {name: 'Add webhook'}).click();
const webhookModal = page.getByTestId('webhook-modal');
await webhookModal.getByLabel('Name').fill('My webhook');
await webhookModal.getByLabel('Target URL').fill('https://example.com');
await chooseOptionInSelect(webhookModal.getByLabel('Event'), 'Post created');
await webhookModal.getByRole('button', {name: 'Add'}).click();
await expect(modal).toHaveText(/My webhook/);
// Edit webhook
await modal.getByText('My webhook').click();
await webhookModal.getByLabel('Name').fill('Updated webhook');
await webhookModal.getByRole('button', {name: 'Update'}).click();
await expect(modal).toHaveText(/Updated webhook/);
// Delete webhook
await modal.getByText('Updated webhook').hover();
await modal.getByRole('button', {name: 'Delete'}).click();
await page.getByTestId('confirmation-modal').getByRole('button', {name: 'Delete webhook'}).click();
await expect(modal).not.toHaveText(/Updated webhook/);
// Edit integration
await modal.getByLabel('Description').fill('Test description');
await modal.getByRole('button', {name: 'Save & close'}).click();
await expect(integrationsSection).toHaveText(/Test description/);
// Delete integration
await integrationsSection.getByText('My integration').hover();
await integrationsSection.getByRole('button', {name: 'Delete'}).click();
await page.getByTestId('confirmation-modal').getByRole('button', {name: 'Delete integration'}).click();
await expect(integrationsSection).not.toHaveText(/My integration/);
});
test('Limits creating custom integrations', async ({page}) => {
await mockApi({page, requests: {
...globalDataRequests,
...limitRequests,
browseConfig: {
...globalDataRequests.browseConfig,
response: {
config: {
...responseFixtures.config.config,
hostSettings: {
limits: {
customIntegrations: {
disabled: true
}
}
}
}
}
}
}});
await page.goto('/');
const integrationsSection = page.getByTestId('integrations');
await integrationsSection.getByRole('button', {name: 'Add custom integration'}).click();
await expect(page.getByTestId('limit-modal')).toHaveText(/Your plan does not support custom integrations/);
});
});