mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
343535116c
refs https://github.com/TryGhost/Product/issues/3832 --- ### <samp>🤖 Generated by Copilot at adffb67</samp> This file updates the global form select component to use a custom `ReactSelect` component with better performance and style.
217 lines
8.3 KiB
TypeScript
217 lines
8.3 KiB
TypeScript
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/);
|
|
});
|
|
});
|