Skip to content

Commit 5bf4943

Browse files
committed
fix(gitlab): address review findings
- update_user now sends admin:false so the Administrator switch can demote (an untouched switch stays undefined and leaves the flag unchanged) - expose the access-level dropdown for Update Invitation - normalize comma-separated invite emails so spaced multi-email input works
1 parent a19b09f commit 5bf4943

4 files changed

Lines changed: 69 additions & 2 deletions

File tree

apps/sim/blocks/blocks/gitlab.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,41 @@ describe('GitLabBlock access operations', () => {
9797
expect(approveParams).toMatchObject({ userId: 7, accessLevel: 30 })
9898
})
9999

100+
it('sends admin:false so update user can demote an administrator', () => {
101+
const demote = block.tools.config.params?.({
102+
accessToken: 'pat',
103+
operation: 'gitlab_update_user',
104+
userId: '9',
105+
userAdminIsAdmin: false,
106+
})
107+
expect(demote?.admin).toBe(false)
108+
109+
// An untouched switch is undefined and must leave the admin flag unchanged.
110+
const untouched = block.tools.config.params?.({
111+
accessToken: 'pat',
112+
operation: 'gitlab_update_user',
113+
userId: '9',
114+
})
115+
expect(untouched?.admin).toBeUndefined()
116+
})
117+
118+
it('exposes the access-level dropdown for update invitation and coerces it', () => {
119+
const accessLevel = block.subBlocks.find((s) => s.id === 'accessLevel')
120+
const condition = accessLevel?.condition
121+
const ops = condition && 'value' in condition ? condition.value : undefined
122+
expect(ops).toContain('gitlab_update_invitation')
123+
124+
const params = block.tools.config.params?.({
125+
accessToken: 'pat',
126+
operation: 'gitlab_update_invitation',
127+
resourceType: 'group',
128+
resourceId: '42',
129+
email: 'a@b.com',
130+
accessLevel: '40',
131+
})
132+
expect(params).toMatchObject({ email: 'a@b.com', accessLevel: 40 })
133+
})
134+
100135
it('throws when required access fields are missing', () => {
101136
expect(() =>
102137
block.tools.config.params?.({

apps/sim/blocks/blocks/gitlab.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1820,7 +1820,10 @@ Return ONLY the commit message - no explanations, no extra text.`,
18201820
email: params.userAdminEmail?.trim() || undefined,
18211821
username: params.userAdminUsername?.trim() || undefined,
18221822
name: params.userAdminName?.trim() || undefined,
1823-
admin: params.userAdminIsAdmin || undefined,
1823+
// Pass the boolean through (not `|| undefined`) so an explicit `false`
1824+
// demotes the user. An untouched switch is `undefined` and is skipped
1825+
// by the tool body, leaving the admin flag unchanged.
1826+
admin: params.userAdminIsAdmin,
18241827
}
18251828

18261829
case 'gitlab_delete_user':

apps/sim/tools/gitlab/access.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,26 @@ describe('gitlab_invite_member', () => {
159159
})
160160
})
161161

162+
describe('gitlab_invite_member email normalization', () => {
163+
it('normalizes a comma-separated list with spaces into GitLab-accepted form', () => {
164+
const body = gitlabInviteMemberTool.request.body?.({
165+
...baseArgs,
166+
email: 'alice@example.com, bob@example.com',
167+
accessLevel: 30,
168+
}) as Record<string, unknown>
169+
expect(body.email).toBe('alice@example.com,bob@example.com')
170+
})
171+
172+
it('passes a single email through unchanged', () => {
173+
const body = gitlabInviteMemberTool.request.body?.({
174+
...baseArgs,
175+
email: 'alice@example.com',
176+
accessLevel: 30,
177+
}) as Record<string, unknown>
178+
expect(body.email).toBe('alice@example.com')
179+
})
180+
})
181+
162182
describe('gitlab user status actions', () => {
163183
it('returns success with no user object when GitLab responds with a bare true', async () => {
164184
const result = await gitlabBlockUserTool.transformResponse!(

apps/sim/tools/gitlab/invite_member.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,17 @@ export const gitlabInviteMemberTool: ToolConfig<
7474
'PRIVATE-TOKEN': params.accessToken,
7575
}),
7676
body: (params) => {
77+
// GitLab accepts a comma-separated list of emails in a single `email`
78+
// field. Normalize surrounding whitespace so "a@b.com, c@d.com" invites
79+
// both addresses rather than sending a malformed second entry.
80+
const email = String(params.email)
81+
.split(',')
82+
.map((address) => address.trim())
83+
.filter(Boolean)
84+
.join(',')
85+
7786
const body: Record<string, unknown> = {
78-
email: params.email,
87+
email,
7988
access_level: params.accessLevel,
8089
}
8190

0 commit comments

Comments
 (0)