Skip to content

Commit eec026a

Browse files
ref(plugins): migrate plugin config to BackendJsonSubmitForm
Replace the legacy PluginSettings class component and GenericField rendering with BackendJsonSubmitForm for plugin configuration forms. The plugin config now fetches field definitions via useApiQuery and maps backend field types to the new form adapter, eliminating the dependency on the client-side plugin module system for settings. Refs DE-1054 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent bcca7b6 commit eec026a

File tree

2 files changed

+286
-41
lines changed

2 files changed

+286
-41
lines changed

static/app/components/pluginConfig.spec.tsx

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import {WebhookPluginConfigFixture} from 'sentry-fixture/integrationListDirector
33
import {initializeOrg} from 'sentry-test/initializeOrg';
44
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
55

6-
import {plugins} from 'sentry/plugins';
7-
86
import {PluginConfig} from './pluginConfig';
97

108
describe('PluginConfig', () => {
@@ -16,19 +14,31 @@ describe('PluginConfig', () => {
1614
MockApiClient.addMockResponse({
1715
url: `/projects/${organization.slug}/${project.slug}/plugins/${webhookPlugin.id}/`,
1816
method: 'GET',
19-
body: webhookPlugin,
17+
body: {
18+
...webhookPlugin,
19+
config: [
20+
{
21+
name: 'urls',
22+
label: 'Callback URLs',
23+
type: 'textarea',
24+
placeholder: 'https://sentry.io/callback/url',
25+
required: false,
26+
help: 'Enter callback URLs, separated by newlines.',
27+
value: 'https://example.com/hook',
28+
defaultValue: '',
29+
},
30+
],
31+
},
2032
});
2133
const testWebhookMock = MockApiClient.addMockResponse({
2234
url: `/projects/${organization.slug}/${project.slug}/plugins/${webhookPlugin.id}/`,
2335
method: 'POST',
2436
body: {detail: 'No errors returned'},
2537
});
2638

27-
expect(plugins.isLoaded(webhookPlugin)).toBe(false);
2839
render(<PluginConfig plugin={webhookPlugin} project={project} />);
29-
expect(plugins.isLoaded(webhookPlugin)).toBe(true);
3040

31-
await userEvent.click(screen.getByRole('button', {name: 'Test Plugin'}));
41+
await userEvent.click(await screen.findByRole('button', {name: 'Test Plugin'}));
3242

3343
expect(await screen.findByText('"No errors returned"')).toBeInTheDocument();
3444
expect(testWebhookMock).toHaveBeenCalledWith(
@@ -39,4 +49,53 @@ describe('PluginConfig', () => {
3949
})
4050
);
4151
});
52+
53+
it('renders config fields from backend', async () => {
54+
const webhookPlugin = WebhookPluginConfigFixture({enabled: true});
55+
56+
MockApiClient.addMockResponse({
57+
url: `/projects/${organization.slug}/${project.slug}/plugins/${webhookPlugin.id}/`,
58+
method: 'GET',
59+
body: {
60+
...webhookPlugin,
61+
config: [
62+
{
63+
name: 'urls',
64+
label: 'Callback URLs',
65+
type: 'textarea',
66+
placeholder: 'https://sentry.io/callback/url',
67+
required: false,
68+
help: 'Enter callback URLs, separated by newlines.',
69+
value: '',
70+
defaultValue: '',
71+
},
72+
],
73+
},
74+
});
75+
76+
render(<PluginConfig plugin={webhookPlugin} project={project} />);
77+
78+
expect(await screen.findByText('Callback URLs')).toBeInTheDocument();
79+
});
80+
81+
it('renders auth error state', async () => {
82+
const webhookPlugin = WebhookPluginConfigFixture({enabled: true});
83+
84+
MockApiClient.addMockResponse({
85+
url: `/projects/${organization.slug}/${project.slug}/plugins/${webhookPlugin.id}/`,
86+
method: 'GET',
87+
body: {
88+
...webhookPlugin,
89+
config_error: 'You need to associate an identity',
90+
auth_url: '/auth/associate/webhooks/',
91+
},
92+
});
93+
94+
render(<PluginConfig plugin={webhookPlugin} project={project} />);
95+
96+
expect(
97+
await screen.findByText('You need to associate an identity')
98+
).toBeInTheDocument();
99+
expect(screen.getByRole('button', {name: 'Associate Identity'})).toBeInTheDocument();
100+
});
42101
});

0 commit comments

Comments
 (0)