diff --git a/static/app/components/pipeline/integrationGitLab/index.spec.tsx b/static/app/components/pipeline/integrationGitLab/index.spec.tsx
index eba31c40a2d1..229b1b9d9d54 100644
--- a/static/app/components/pipeline/integrationGitLab/index.spec.tsx
+++ b/static/app/components/pipeline/integrationGitLab/index.spec.tsx
@@ -96,6 +96,10 @@ describe('InstallationConfigStep', () => {
'my-app-id'
);
await userEvent.type(screen.getByLabelText('GitLab Application Secret'), 'my-secret');
+ await userEvent.type(
+ screen.getByRole('textbox', {name: 'GitLab Group Path'}),
+ 'my-group'
+ );
await userEvent.click(screen.getByRole('button', {name: 'Continue'}));
@@ -103,14 +107,38 @@ describe('InstallationConfigStep', () => {
expect(advance).toHaveBeenCalledWith({
url: undefined,
verify_ssl: undefined,
- group: '',
- include_subgroups: undefined,
+ group: 'my-group',
+ include_subgroups: false,
client_id: 'my-app-id',
client_secret: 'my-secret',
});
});
});
+ it('requires a group path before submitting', async () => {
+ const advance = jest.fn();
+ render(
+
+ );
+
+ await userEvent.click(screen.getByRole('button', {name: 'Next'}));
+ await userEvent.click(screen.getByRole('button', {name: 'Next'}));
+
+ await userEvent.type(
+ screen.getByRole('textbox', {name: 'GitLab Application ID'}),
+ 'my-app-id'
+ );
+ await userEvent.type(screen.getByLabelText('GitLab Application Secret'), 'my-secret');
+ await userEvent.type(screen.getByRole('textbox', {name: 'GitLab Group Path'}), ' ');
+
+ await userEvent.click(screen.getByRole('button', {name: 'Continue'}));
+
+ expect(await screen.findByText('Group path is required')).toBeInTheDocument();
+ expect(advance).not.toHaveBeenCalled();
+ });
+
it('submits with group and include_subgroups when group is set', async () => {
const advance = jest.fn();
render(
@@ -191,6 +219,10 @@ describe('InstallationConfigStep', () => {
'my-app-id'
);
await userEvent.type(screen.getByLabelText('GitLab Application Secret'), 'my-secret');
+ await userEvent.type(
+ screen.getByRole('textbox', {name: 'GitLab Group Path'}),
+ 'my-group'
+ );
await userEvent.click(screen.getByRole('checkbox', {name: 'Self-Hosted Instance'}));
@@ -232,6 +264,10 @@ describe('InstallationConfigStep', () => {
'id'
);
await userEvent.type(screen.getByLabelText('GitLab Application Secret'), 'secret');
+ await userEvent.type(
+ screen.getByRole('textbox', {name: 'GitLab Group Path'}),
+ 'my-group'
+ );
await userEvent.click(screen.getByRole('checkbox', {name: 'Self-Hosted Instance'}));
diff --git a/static/app/components/pipeline/integrationGitLab/index.tsx b/static/app/components/pipeline/integrationGitLab/index.tsx
index 33010b90dab9..0c6647917ce5 100644
--- a/static/app/components/pipeline/integrationGitLab/index.tsx
+++ b/static/app/components/pipeline/integrationGitLab/index.tsx
@@ -23,7 +23,7 @@ const installationConfigSchema = z
.object({
selfHosted: z.boolean(),
url: z.string(),
- group: z.string(),
+ group: z.string().trim().min(1, t('Group path is required')),
includeSubgroups: z.boolean(),
verifySsl: z.boolean(),
clientId: z.string().min(1, t('Application ID is required')),
@@ -78,7 +78,7 @@ function InstallationConfigStep({
url: value.selfHosted ? value.url.replace(/\/+$/, '') : undefined,
verify_ssl: value.selfHosted ? value.verifySsl : undefined,
group: value.group,
- include_subgroups: value.group ? value.includeSubgroups : undefined,
+ include_subgroups: value.includeSubgroups,
client_id: value.clientId,
client_secret: value.clientSecret,
});
@@ -122,8 +122,9 @@ function InstallationConfigStep({