From 1f4d9779f68e188f378a9aba4aea6facf7497203 Mon Sep 17 00:00:00 2001 From: Jack Palmer Date: Mon, 2 Jun 2025 11:30:48 +0100 Subject: [PATCH] chore: Add tests Signed-off-by: Jack Palmer --- .../src/__testUtils__/handlers.ts | 63 ++++- .../src/__testUtils__/mocks.ts | 252 +++++++++++++++++- .../GitlabOrgDiscoveryEntityProvider.test.ts | 4 +- 3 files changed, 315 insertions(+), 4 deletions(-) diff --git a/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts b/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts index 77efa87878..3616ed1f47 100644 --- a/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts +++ b/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts @@ -30,6 +30,10 @@ import { some_endpoint, unhealthy_endpoint, userID, + all_saas_group_with_subgroups_members, + all_saas_subgroup_1_members, + all_saas_subgroup_2_members, + group_with_subgroups_response, } from './mocks'; const httpHandlers = [ @@ -71,6 +75,13 @@ const httpHandlers = [ return res(ctx.set('x-next-page', ''), ctx.json(all_groups_response)); }), + rest.get(`${apiBaseUrl}/groups/group-with-subgroup`, (_, res, ctx) => { + return res( + ctx.set('x-next-page', ''), + ctx.json(group_with_subgroups_response), + ); + }), + rest.get(`${apiBaseUrl}/groups/42`, (_, res, ctx) => { return res(ctx.status(500), ctx.json({ error: 'Internal Server Error' })); }), @@ -97,6 +108,16 @@ const httpHandlers = [ return res(ctx.json(all_saas_users_response)); }), + // Subgroup 1 members id=6 + rest.get(`${apiBaseUrlSaas}/groups/6/members/all`, (_req, res, ctx) => { + return res(ctx.json(all_saas_subgroup_1_members)); + }), + + // Subgroup 2 members id=7 + rest.get(`${apiBaseUrlSaas}/groups/7/members/all`, (_req, res, ctx) => { + return res(ctx.json(all_saas_subgroup_2_members)); + }), + /** * Users REST endpoint mocks */ @@ -616,7 +637,47 @@ const graphqlHandlers = [ graphql .link(saasGraphQlBaseUrl) - .query('listDescendantGroups', async (_, res, ctx) => { + .query('listDescendantGroups', async (req, res, ctx) => { + const { group } = req.variables; + + if (group === 'group1') { + return res( + ctx.data({ + group: { + descendantGroups: { + nodes: req.variables.endCursor + ? [ + { + id: 'gid://gitlab/Group/6', + name: 'subgroup1', + description: 'description1', + fullPath: 'path/subgroup1', + parent: { + id: '1', + }, + }, + ] + : [ + { + id: 'gid://gitlab/Group/7', + name: 'subgroup2', + description: 'description2', + fullPath: 'path/subgroup2', + parent: { + id: '1', + }, + }, + ], + pageInfo: { + endCursor: req.variables.endCursor ? 'end' : 'next', + hasNextPage: !req.variables.endCursor, + }, + }, + }, + }), + ); + } + return res( ctx.data({ group: { diff --git a/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts b/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts index 43187031a2..2e74be66cc 100644 --- a/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts +++ b/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts @@ -796,6 +796,30 @@ export const config_org_group_restrictUsers_true_selfHosted = { }, }, }; + +export const config_org_group_with_subgroups_sass = { + integrations: { + gitlab: [ + { + host: 'gitlab.com', + apiBaseUrl: 'https://gitlab.com/api/v4', + token: '1234', + }, + ], + }, + catalog: { + providers: { + gitlab: { + 'test-id': { + host: 'gitlab.com', + group: 'group1', + orgEnabled: true, + skipForkedRepos: true, + }, + }, + }, + }, +}; /** * GitLab API responses */ @@ -1021,6 +1045,71 @@ export const all_saas_users_response: MockObject[] = [ created_at: '2023-07-19T08:58:34.984Z', expires_at: null, id: 36, + username: 'testusernoseat1', + name: 'Test User No Seat 1', + state: 'active', + avatar_url: 'https://secure.gravatar.com/', + web_url: 'https://gitlab.com/testusernoseat1', + email: 'testusernoseat1@example.com', + group_saml_identity: { + provider: 'group_saml', + extern_uid: '60', + saml_provider_id: 1, + }, + is_using_seat: false, + membership_state: 'active', + }, +]; + +// Only test user 1 +export const all_saas_group_with_subgroups_members: MockObject[] = [ + { + access_level: 30, + created_at: '2023-07-17T08:58:34.984Z', + expires_at: null, + id: 12, + username: 'testuser1', + name: 'Test User 1', + state: 'active', + avatar_url: 'https://secure.gravatar.com/', + web_url: 'https://gitlab.com/testuser1', + email: 'testuser1@example.com', + group_saml_identity: { + provider: 'group_saml', + extern_uid: '50', + saml_provider_id: 1, + }, + is_using_seat: true, + membership_state: 'active', + }, +]; + +// Only test user 1 +export const all_saas_subgroup_1_members: MockObject[] = [ + { + access_level: 30, + created_at: '2023-07-17T08:58:34.984Z', + expires_at: null, + id: 12, + username: 'testuser1', + name: 'Test User 1', + state: 'active', + avatar_url: 'https://secure.gravatar.com/', + web_url: 'https://gitlab.com/testuser1', + email: 'testuser1@example.com', + group_saml_identity: { + provider: 'group_saml', + extern_uid: '51', + saml_provider_id: 1, + }, + is_using_seat: true, + membership_state: 'active', + }, + { + access_level: 30, + created_at: '2023-07-17T08:58:34.984Z', + expires_at: null, + id: 33, username: 'testuser3', name: 'Test User 3', state: 'active', @@ -1032,7 +1121,49 @@ export const all_saas_users_response: MockObject[] = [ extern_uid: '53', saml_provider_id: 1, }, - is_using_seat: false, + is_using_seat: true, + membership_state: 'active', + }, +]; + +// Only test user 2 +export const all_saas_subgroup_2_members: MockObject[] = [ + { + access_level: 30, + created_at: '2023-07-19T08:58:34.984Z', + expires_at: null, + id: 34, + username: 'testuser2', + name: 'Test User 2', + state: 'active', + avatar_url: 'https://secure.gravatar.com/', + web_url: 'https://gitlab.com/testuser2', + email: 'testuser2@example.com', + group_saml_identity: { + provider: 'group_saml', + extern_uid: '52', + saml_provider_id: 1, + }, + is_using_seat: true, + membership_state: 'active', + }, + { + access_level: 30, + created_at: '2023-07-17T08:58:34.984Z', + expires_at: null, + id: 44, + username: 'testuser4', + name: 'Test User 4', + state: 'active', + avatar_url: 'https://secure.gravatar.com/', + web_url: 'https://gitlab.com/testuser4', + email: 'testuser4@example.com', + group_saml_identity: { + provider: 'group_saml', + extern_uid: '54', + saml_provider_id: 1, + }, + is_using_seat: true, membership_state: 'active', }, ]; @@ -1074,6 +1205,21 @@ export const all_groups_response: GitLabGroup[] = [ description: '', full_path: 'group1/subgroup1', }, + { + id: 7, + name: 'subgroup2', + description: '', + full_path: 'group1/subgroup2', + }, +]; + +export const group_with_subgroups_response: GitLabGroup[] = [ + { + id: 1, + name: 'group1', + description: 'description1', + full_path: 'group1', + }, ]; export const group_with_parent: MockObject[] = [ @@ -2183,6 +2329,58 @@ export const expected_full_org_scan_entities_saas: MockObject[] = [ }, locationKey: 'GitlabOrgDiscoveryEntityProvider:test-id', }, + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://gitlab.com/testuser4', + 'backstage.io/managed-by-origin-location': + 'url:https://gitlab.com/testuser4', + 'gitlab.com/user-login': 'https://gitlab.com/testuser4', + 'gitlab.com/saml-external-uid': '54', + }, + name: 'testuser4', + }, + spec: { + memberOf: [], + profile: { + displayName: 'Test User 4', + email: 'testuser4@example.com', + picture: 'https://secure.gravatar.com/', + }, + }, + }, + locationKey: 'GitlabOrgDiscoveryEntityProvider:test-id', + }, + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://gitlab.com/testuser3', + 'backstage.io/managed-by-origin-location': + 'url:https://gitlab.com/testuser3', + 'gitlab.com/user-login': 'https://gitlab.com/testuser3', + 'gitlab.com/saml-external-uid': '53', + }, + name: 'testuser3', + }, + spec: { + memberOf: [], + profile: { + displayName: 'Test User 3', + email: 'testuser3@example.com', + picture: 'https://secure.gravatar.com/', + }, + }, + }, + locationKey: 'GitlabOrgDiscoveryEntityProvider:test-id', + }, ]; export const expected_full_org_scan_entities_includeUsersWithoutSeat_saas: MockObject[] = @@ -2239,6 +2437,58 @@ export const expected_full_org_scan_entities_includeUsersWithoutSeat_saas: MockO }, locationKey: 'GitlabOrgDiscoveryEntityProvider:test-id', }, + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://gitlab.com/testusernoseat1', + 'backstage.io/managed-by-origin-location': + 'url:https://gitlab.com/testusernoseat1', + 'gitlab.com/user-login': 'https://gitlab.com/testusernoseat1', + 'gitlab.com/saml-external-uid': '60', + }, + name: 'testusernoseat1', + }, + spec: { + memberOf: [], + profile: { + displayName: 'Test User No Seat 1', + email: 'testusernoseat1@example.com', + picture: 'https://secure.gravatar.com/', + }, + }, + }, + locationKey: 'GitlabOrgDiscoveryEntityProvider:test-id', + }, + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://gitlab.com/testuser4', + 'backstage.io/managed-by-origin-location': + 'url:https://gitlab.com/testuser4', + 'gitlab.com/user-login': 'https://gitlab.com/testuser4', + 'gitlab.com/saml-external-uid': '54', + }, + name: 'testuser4', + }, + spec: { + memberOf: [], + profile: { + displayName: 'Test User 4', + email: 'testuser4@example.com', + picture: 'https://secure.gravatar.com/', + }, + }, + }, + locationKey: 'GitlabOrgDiscoveryEntityProvider:test-id', + }, { entity: { apiVersion: 'backstage.io/v1alpha1', diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts index 5f62cedb71..047488166a 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts @@ -303,7 +303,7 @@ describe('GitlabOrgDiscoveryEntityProvider - refresh', () => { }); }); - // This should return all members of the SaaS Root group (group1) -> expected_full_org_scan_entities_saas + // This should return all members of the SaaS Root group (group1) and any subgroups -> expected_full_org_scan_entities_saas it('SaaS: should get all saas root group users when restrictUsersToGroup is not set', async () => { const config = new ConfigReader(mock.config_org_group_saas); const schedule = new PersistingTaskRunner(); @@ -334,7 +334,7 @@ describe('GitlabOrgDiscoveryEntityProvider - refresh', () => { }); }); - // This should return all members of the SaaS Root group (group1) -> expected_full_org_scan_entities_saas + // This should return all members of the SaaS Root group (group1) and any subgroups -> expected_full_org_scan_entities_saas it('SaaS: should get all saas root group users when restrictUsersToGroup is false', async () => { const config = new ConfigReader( mock.config_org_group_restrictUsers_false_saas,