|
| 1 | +/* eslint-disable max-lines */ |
| 2 | +// TODO: @darcy reorg to break this file into smaller files |
1 | 3 | import assert from 'node:assert';
|
2 | 4 |
|
3 | 5 | import { generateStandardId } from '@logto/shared';
|
4 | 6 | import { isKeyInObject, pick } from '@silverhand/essentials';
|
5 | 7 | import { HTTPError } from 'ky';
|
6 | 8 |
|
| 9 | +import { createResource } from '#src/api/index.js'; |
| 10 | +import { createScope } from '#src/api/scope.js'; |
7 | 11 | import { OrganizationRoleApiTest, OrganizationScopeApiTest } from '#src/helpers/organization.js';
|
8 | 12 | import { ScopeApiTest } from '#src/helpers/resource.js';
|
| 13 | +import { generateScopeName } from '#src/utils.js'; |
9 | 14 |
|
10 | 15 | const randomId = () => generateStandardId(4);
|
11 | 16 |
|
@@ -179,6 +184,85 @@ describe('organization role APIs', () => {
|
179 | 184 | const response = await roleApi.delete('0').catch((error: unknown) => error);
|
180 | 185 | expect(response instanceof HTTPError && response.response.status).toBe(404);
|
181 | 186 | });
|
| 187 | + |
| 188 | + it('should fail when creating a role with invalid organization scope IDs', async () => { |
| 189 | + const invalidScopeId = generateStandardId(); |
| 190 | + const response = await roleApi |
| 191 | + .create({ |
| 192 | + name: 'test' + randomId(), |
| 193 | + organizationScopeIds: [invalidScopeId], |
| 194 | + }) |
| 195 | + .catch((error: unknown) => error); |
| 196 | + |
| 197 | + assert(response instanceof HTTPError); |
| 198 | + const body: unknown = await response.response.json(); |
| 199 | + expect(response.response.status).toBe(422); |
| 200 | + expect(body).toMatchObject( |
| 201 | + expect.objectContaining({ |
| 202 | + code: 'organization.roles.invalid_scope_ids', |
| 203 | + }) |
| 204 | + ); |
| 205 | + |
| 206 | + const roles = await roleApi.getList(); |
| 207 | + expect(roles).toHaveLength(0); |
| 208 | + }); |
| 209 | + |
| 210 | + it('should fail when creating a role with invalid resource scope IDs', async () => { |
| 211 | + const invalidScopeId = generateStandardId(); |
| 212 | + const response = await roleApi |
| 213 | + .create({ |
| 214 | + name: 'test' + randomId(), |
| 215 | + resourceScopeIds: [invalidScopeId], |
| 216 | + }) |
| 217 | + .catch((error: unknown) => error); |
| 218 | + |
| 219 | + assert(response instanceof HTTPError); |
| 220 | + const body: unknown = await response.response.json(); |
| 221 | + expect(response.response.status).toBe(422); |
| 222 | + expect(body).toMatchObject( |
| 223 | + expect.objectContaining({ |
| 224 | + code: 'organization.roles.invalid_resource_scope_ids', |
| 225 | + }) |
| 226 | + ); |
| 227 | + |
| 228 | + const roles = await roleApi.getList(); |
| 229 | + expect(roles).toHaveLength(0); |
| 230 | + }); |
| 231 | + |
| 232 | + it('should successfully create a role with scope IDs are provided', async () => { |
| 233 | + const resource = await createResource(); |
| 234 | + const scopeName = generateScopeName(); |
| 235 | + const createdScope = await createScope(resource.id, scopeName); |
| 236 | + |
| 237 | + const [scope1, scope2] = await Promise.all([ |
| 238 | + scopeApi.create({ name: 'test' + randomId() }), |
| 239 | + scopeApi.create({ name: 'test' + randomId() }), |
| 240 | + ]); |
| 241 | + const createdRole = await roleApi.create({ |
| 242 | + name: 'test' + randomId(), |
| 243 | + organizationScopeIds: [scope1.id, scope2.id], |
| 244 | + resourceScopeIds: [createdScope.id], |
| 245 | + }); |
| 246 | + |
| 247 | + expect(createdRole).toHaveProperty('id'); |
| 248 | + expect(createdRole).toHaveProperty('name'); |
| 249 | + |
| 250 | + const scopes = await roleApi.getScopes(createdRole.id); |
| 251 | + expect(scopes).toContainEqual( |
| 252 | + expect.objectContaining({ |
| 253 | + name: scope1.name, |
| 254 | + }) |
| 255 | + ); |
| 256 | + expect(scopes).toContainEqual( |
| 257 | + expect.objectContaining({ |
| 258 | + name: scope2.name, |
| 259 | + }) |
| 260 | + ); |
| 261 | + |
| 262 | + const { resourceScopes } = await roleApi.get(createdRole.id); |
| 263 | + expect(resourceScopes.length).toBe(1); |
| 264 | + expect(resourceScopes[0]).toHaveProperty('name', scopeName); |
| 265 | + }); |
182 | 266 | });
|
183 | 267 |
|
184 | 268 | describe('organization role - scope relations', () => {
|
@@ -397,3 +481,4 @@ describe('organization role APIs', () => {
|
397 | 481 | });
|
398 | 482 | });
|
399 | 483 | });
|
| 484 | +/* eslint-enable max-lines */ |
0 commit comments