Skip to content

Commit

Permalink
test(keycloak): add tests (#437)
Browse files Browse the repository at this point in the history
* test: add keycloak tests

Signed-off-by: Paul Schultz <[email protected]>

* remove mocking in config.test.ts

Signed-off-by: Paul Schultz <[email protected]>

* wip tests

Signed-off-by: Paul Schultz <[email protected]>

* finish keycloak tests

Signed-off-by: Paul Schultz <[email protected]>

* fix codesmells

Signed-off-by: Paul Schultz <[email protected]>

* resolve pr comments

Signed-off-by: Paul Schultz <[email protected]>

---------

Signed-off-by: Paul Schultz <[email protected]>
  • Loading branch information
schultzp2020 authored Jun 12, 2023
1 parent e9d7ed5 commit 1872d7c
Show file tree
Hide file tree
Showing 7 changed files with 470 additions and 1 deletion.
93 changes: 93 additions & 0 deletions plugins/keycloak-backend/__fixtures__/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
export const groups = [
{
id: '9cf51b5d-e066-4ed8-940c-dc6da77f81a5',
name: 'biggroup',
path: '/biggroup',
subGroups: [
{
id: 'eefa5b46-0509-41d8-b8b3-7ddae9c83632',
name: 'subgroup',
path: '/biggroup/subgroup',
subGroups: [],
},
],
},
{
id: '557501bd-8188-41c0-a2d5-43ff3d5b0258',
name: 'emptygroup',
path: '/emptygroup',
subGroups: [],
},
{
id: 'bb10231b-2939-4b1a-b8bb-9249ed7b76f7',
name: 'testgroup',
path: '/testgroup',
subGroups: [],
},
];

export const users = [
{
id: '59efec15-a00b-4700-8833-5f4cdecc1132',
createdTimestamp: 1686170983010,
username: 'jamesdoe',
enabled: true,
totp: false,
emailVerified: false,
firstName: '',
lastName: '',
email: '[email protected]',
disableableCredentialTypes: [],
requiredActions: [],
notBefore: 0,
access: {
manageGroupMembership: false,
view: true,
mapRoles: false,
impersonate: false,
manage: false,
},
},
{
id: 'c982b51a-abf6-4f68-bfdf-a1c6257214fc',
createdTimestamp: 1686170953553,
username: 'joedoe',
enabled: true,
totp: false,
emailVerified: false,
firstName: '',
lastName: '',
disableableCredentialTypes: [],
requiredActions: [],
notBefore: 0,
access: {
manageGroupMembership: false,
view: true,
mapRoles: false,
impersonate: false,
manage: false,
},
},
{
id: '2bf97dbd-fd6a-47ae-986b-2632fa95e03f',
createdTimestamp: 1686170890908,
username: 'johndoe',
enabled: true,
totp: false,
emailVerified: false,
firstName: 'John',
lastName: 'Doe',
disableableCredentialTypes: [],
requiredActions: [],
notBefore: 0,
access: {
manageGroupMembership: false,
view: true,
mapRoles: false,
impersonate: false,
manage: false,
},
},
];

export const groupMembers = [[], [], [], ['jamesdoe', 'joedoe', 'johndoe']];
44 changes: 44 additions & 0 deletions plugins/keycloak-backend/__fixtures__/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { EntityProviderConnection } from '@backstage/plugin-catalog-backend';

import { groupMembers, groups, users } from './data';

export const BASIC_VALID_CONFIG = {
catalog: {
providers: {
keycloakOrg: {
default: {
baseUrl: 'http://localhost:8080/auth',
},
},
},
},
} as const;

export class KeycloakAdminClientMock {
public constructor() {
return;
}

users = {
find: jest.fn().mockResolvedValue(users),
count: jest.fn().mockResolvedValue(users.length),
};

groups = {
find: jest.fn().mockResolvedValue(groups),
count: jest.fn().mockResolvedValue(groups.length),
listMembers: jest
.fn()
.mockResolvedValueOnce(groupMembers[0])
.mockResolvedValueOnce(groupMembers[1])
.mockResolvedValueOnce(groupMembers[2])
.mockResolvedValueOnce(groupMembers[3]),
};

auth = jest.fn().mockResolvedValue({});
}

export const connection = {
applyMutation: jest.fn(),
refresh: jest.fn(),
} as unknown as EntityProviderConnection;
1 change: 1 addition & 0 deletions plugins/keycloak-backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@types/lodash": "4.14.195",
"@types/supertest": "2.0.12",
"@types/uuid": "9.0.1",
"deepmerge": "^4.3.1",
"msw": "1.2.1",
"supertest": "6.3.3"
},
Expand Down
169 changes: 169 additions & 0 deletions plugins/keycloak-backend/src/lib/config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import { ConfigReader } from '@backstage/config';

import deepmerge from 'deepmerge';

import { BASIC_VALID_CONFIG } from '../../__fixtures__/helpers';
import { readProviderConfigs } from './config';

describe('readProviderConfigs', () => {
it('should return an empty array if no providers are configured', () => {
const config = new ConfigReader({});

const result = readProviderConfigs(config);

expect(result).toEqual([]);
});

it('should return an array of provider configs', () => {
const config = new ConfigReader(BASIC_VALID_CONFIG);

const result = readProviderConfigs(config);

expect(result).toEqual([
{
id: 'default',
baseUrl: 'http://localhost:8080/auth',
loginRealm: 'master',
realm: 'master',
username: undefined,
password: undefined,
clientId: undefined,
clientSecret: undefined,
schedule: undefined,
userQuerySize: undefined,
groupQuerySize: undefined,
},
]);
});

it('should return an array of provider configs with optional values', () => {
const config = new ConfigReader(
deepmerge(BASIC_VALID_CONFIG, {
catalog: {
providers: {
keycloakOrg: {
default: {
realm: 'myrealm',
loginRealm: 'myloginrealm',
username: 'myusername',
password: 'mypassword',
clientId: 'myclientid',
clientSecret: 'myclientsecret',
userQuerySize: 100,
groupQuerySize: 200,
schedule: {
frequency: { hours: 1 },
timeout: { minutes: 50 },
initialDelay: { seconds: 15 },
},
},
},
},
},
}),
);

const result = readProviderConfigs(config);

expect(result).toEqual([
{
id: 'default',
baseUrl: 'http://localhost:8080/auth',
loginRealm: 'myloginrealm',
realm: 'myrealm',
username: 'myusername',
password: 'mypassword',
clientId: 'myclientid',
clientSecret: 'myclientsecret',
userQuerySize: 100,
groupQuerySize: 200,
schedule: {
scope: undefined,
frequency: { hours: 1 },
timeout: { minutes: 50 },
initialDelay: { seconds: 15 },
},
},
]);
});

it('should throw an error if clientId is provided without clientSecret', () => {
const config = new ConfigReader(
deepmerge(BASIC_VALID_CONFIG, {
catalog: {
providers: {
keycloakOrg: {
default: {
clientId: 'myclientid',
},
},
},
},
}),
);

expect(() => readProviderConfigs(config)).toThrow(
`clientSecret must be provided when clientId is defined.`,
);
});

it('should throw an error if clientSecret is provided without clientId', () => {
const config = new ConfigReader(
deepmerge(BASIC_VALID_CONFIG, {
catalog: {
providers: {
keycloakOrg: {
default: {
clientSecret: 'myclientsecret',
},
},
},
},
}),
);

expect(() => readProviderConfigs(config)).toThrow(
`clientId must be provided when clientSecret is defined.`,
);
});

it('should throw an error if username is provided without password', () => {
const config = new ConfigReader(
deepmerge(BASIC_VALID_CONFIG, {
catalog: {
providers: {
keycloakOrg: {
default: {
username: 'myusername',
},
},
},
},
}),
);

expect(() => readProviderConfigs(config)).toThrow(
`password must be provided when username is defined.`,
);
});

it('should throw an error if password is provided without username', () => {
const config = new ConfigReader(
deepmerge(BASIC_VALID_CONFIG, {
catalog: {
providers: {
keycloakOrg: {
default: {
password: 'mypassword',
},
},
},
},
}),
);

expect(() => readProviderConfigs(config)).toThrow(
`username must be provided when password is defined.`,
);
});
});
21 changes: 21 additions & 0 deletions plugins/keycloak-backend/src/lib/read.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import KcAdminClient from '@keycloak/keycloak-admin-client';

import { KeycloakAdminClientMock } from '../../__fixtures__/helpers';
import { KeycloakProviderConfig } from './config';
import { readKeycloakRealm } from './read';

const config: KeycloakProviderConfig = {
realm: 'myrealm',
id: 'mock_id',
baseUrl: 'http://mock-url',
};

describe('readKeycloakRealm', () => {
it('should return the correct number of users and groups', async () => {
const client = new KeycloakAdminClientMock() as unknown as KcAdminClient;
const { users, groups } = await readKeycloakRealm(client, config);

expect(users).toHaveLength(3);
expect(groups).toHaveLength(4);
});
});
Loading

0 comments on commit 1872d7c

Please sign in to comment.