@scalekit-sdk/node 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/core.js +2 -2
- package/lib/domain.d.ts +15 -2
- package/lib/domain.js +44 -3
- package/lib/domain.js.map +1 -1
- package/lib/pkg/grpc/scalekit/v1/connections/connections_pb.d.ts +4 -0
- package/lib/pkg/grpc/scalekit/v1/connections/connections_pb.js +1 -0
- package/lib/pkg/grpc/scalekit/v1/connections/connections_pb.js.map +1 -1
- package/lib/pkg/grpc/scalekit/v1/domains/domains_pb.d.ts +9 -5
- package/lib/pkg/grpc/scalekit/v1/domains/domains_pb.js +11 -6
- package/lib/pkg/grpc/scalekit/v1/domains/domains_pb.js.map +1 -1
- package/lib/pkg/grpc/scalekit/v1/errdetails/errdetails_pb.d.ts +6 -2
- package/lib/pkg/grpc/scalekit/v1/errdetails/errdetails_pb.js +8 -3
- package/lib/pkg/grpc/scalekit/v1/errdetails/errdetails_pb.js.map +1 -1
- package/lib/pkg/grpc/scalekit/v1/users/users_pb.d.ts +14 -5
- package/lib/pkg/grpc/scalekit/v1/users/users_pb.js +12 -9
- package/lib/pkg/grpc/scalekit/v1/users/users_pb.js.map +1 -1
- package/package.json +1 -1
- package/src/core.ts +2 -2
- package/src/domain.ts +52 -3
- package/src/pkg/grpc/scalekit/v1/connections/connections_pb.ts +6 -0
- package/src/pkg/grpc/scalekit/v1/domains/domains_pb.ts +12 -6
- package/src/pkg/grpc/scalekit/v1/errdetails/errdetails_pb.ts +9 -3
- package/src/pkg/grpc/scalekit/v1/users/users_pb.ts +20 -7
- package/tests/domain.test.ts +239 -0
- package/tests/utils/test-data.ts +66 -0
package/src/domain.ts
CHANGED
|
@@ -2,7 +2,8 @@ import { PromiseClient } from '@connectrpc/connect';
|
|
|
2
2
|
import GrpcConnect from './connect';
|
|
3
3
|
import CoreClient from './core';
|
|
4
4
|
import { DomainService } from './pkg/grpc/scalekit/v1/domains/domains_connect';
|
|
5
|
-
import { CreateDomainResponse, GetDomainResponse, ListDomainResponse } from './pkg/grpc/scalekit/v1/domains/domains_pb';
|
|
5
|
+
import { CreateDomainResponse, GetDomainResponse, ListDomainResponse, DomainType } from './pkg/grpc/scalekit/v1/domains/domains_pb';
|
|
6
|
+
import { Empty } from '@bufbuild/protobuf';
|
|
6
7
|
|
|
7
8
|
export default class DomainClient {
|
|
8
9
|
private client: PromiseClient<typeof DomainService>;
|
|
@@ -17,9 +18,23 @@ export default class DomainClient {
|
|
|
17
18
|
* Create a domain for an organization with the given name. Optionally, you can provide an external id.
|
|
18
19
|
* @param {string} organizationId The organization id
|
|
19
20
|
* @param {string} name The domain name
|
|
21
|
+
* @param {object} options The options to create a domain
|
|
22
|
+
* @param {DomainType | string} options.domainType The type of domain (ALLOWED_EMAIL_DOMAIN or ORGANIZATION_DOMAIN)
|
|
20
23
|
* @returns {Promise<CreateDomainResponse>} The created domain
|
|
21
24
|
*/
|
|
22
|
-
async createDomain(organizationId: string, name: string): Promise<CreateDomainResponse> {
|
|
25
|
+
async createDomain(organizationId: string, name: string, options?: { domainType?: DomainType | string }): Promise<CreateDomainResponse> {
|
|
26
|
+
let domainTypeValue: DomainType | undefined;
|
|
27
|
+
if (options?.domainType) {
|
|
28
|
+
if (typeof options.domainType === 'string') {
|
|
29
|
+
domainTypeValue = DomainType[options.domainType as keyof typeof DomainType];
|
|
30
|
+
if (domainTypeValue === undefined) {
|
|
31
|
+
throw new Error('Invalid domain type');
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
domainTypeValue = options.domainType;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
23
38
|
return this.coreClient.connectExec(
|
|
24
39
|
this.client.createDomain,
|
|
25
40
|
{
|
|
@@ -28,12 +43,32 @@ export default class DomainClient {
|
|
|
28
43
|
value: organizationId
|
|
29
44
|
},
|
|
30
45
|
domain: {
|
|
31
|
-
domain: name
|
|
46
|
+
domain: name,
|
|
47
|
+
...(domainTypeValue && { domainType: domainTypeValue })
|
|
32
48
|
}
|
|
33
49
|
}
|
|
34
50
|
)
|
|
35
51
|
}
|
|
36
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Get a specific domain by ID for an organization
|
|
55
|
+
* @param organizationId The organization id
|
|
56
|
+
* @param domainId The domain id
|
|
57
|
+
* @returns {Promise<GetDomainResponse>} The domain details
|
|
58
|
+
*/
|
|
59
|
+
async getDomain(organizationId: string, domainId: string): Promise<GetDomainResponse> {
|
|
60
|
+
return this.coreClient.connectExec(
|
|
61
|
+
this.client.getDomain,
|
|
62
|
+
{
|
|
63
|
+
id: domainId,
|
|
64
|
+
identities: {
|
|
65
|
+
case: 'organizationId',
|
|
66
|
+
value: organizationId
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
37
72
|
/**
|
|
38
73
|
* List domains for an organization
|
|
39
74
|
* @param organizationId The organization id
|
|
@@ -50,5 +85,19 @@ export default class DomainClient {
|
|
|
50
85
|
},
|
|
51
86
|
);
|
|
52
87
|
}
|
|
88
|
+
|
|
89
|
+
async deleteDomain(organizationId: string, domainId: string): Promise<Empty> {
|
|
90
|
+
return this.coreClient.connectExec(
|
|
91
|
+
this.client.deleteDomain,
|
|
92
|
+
{
|
|
93
|
+
id: domainId,
|
|
94
|
+
identities: {
|
|
95
|
+
case: 'organizationId',
|
|
96
|
+
value: organizationId
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
53
102
|
}
|
|
54
103
|
|
|
@@ -3314,6 +3314,11 @@ export class ListAppConnectionsRequest extends Message<ListAppConnectionsRequest
|
|
|
3314
3314
|
*/
|
|
3315
3315
|
pageToken = "";
|
|
3316
3316
|
|
|
3317
|
+
/**
|
|
3318
|
+
* @generated from field: optional string provider = 3;
|
|
3319
|
+
*/
|
|
3320
|
+
provider?: string;
|
|
3321
|
+
|
|
3317
3322
|
constructor(data?: PartialMessage<ListAppConnectionsRequest>) {
|
|
3318
3323
|
super();
|
|
3319
3324
|
proto3.util.initPartial(data, this);
|
|
@@ -3324,6 +3329,7 @@ export class ListAppConnectionsRequest extends Message<ListAppConnectionsRequest
|
|
|
3324
3329
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
|
3325
3330
|
{ no: 1, name: "page_size", kind: "scalar", T: 13 /* ScalarType.UINT32 */ },
|
|
3326
3331
|
{ no: 2, name: "page_token", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
3332
|
+
{ no: 3, name: "provider", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
|
|
3327
3333
|
]);
|
|
3328
3334
|
|
|
3329
3335
|
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ListAppConnectionsRequest {
|
|
@@ -29,6 +29,11 @@ export enum VerificationStatus {
|
|
|
29
29
|
* @generated from enum value: FAILED = 3;
|
|
30
30
|
*/
|
|
31
31
|
FAILED = 3,
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @generated from enum value: AUTO_VERIFIED = 4;
|
|
35
|
+
*/
|
|
36
|
+
AUTO_VERIFIED = 4,
|
|
32
37
|
}
|
|
33
38
|
// Retrieve enum metadata with: proto3.getEnumType(VerificationStatus)
|
|
34
39
|
proto3.util.setEnumType(VerificationStatus, "scalekit.v1.domains.VerificationStatus", [
|
|
@@ -36,6 +41,7 @@ proto3.util.setEnumType(VerificationStatus, "scalekit.v1.domains.VerificationSta
|
|
|
36
41
|
{ no: 1, name: "PENDING" },
|
|
37
42
|
{ no: 2, name: "VERIFIED" },
|
|
38
43
|
{ no: 3, name: "FAILED" },
|
|
44
|
+
{ no: 4, name: "AUTO_VERIFIED" },
|
|
39
45
|
]);
|
|
40
46
|
|
|
41
47
|
/**
|
|
@@ -48,20 +54,20 @@ export enum DomainType {
|
|
|
48
54
|
DOMAIN_TYPE_UNSPECIFIED = 0,
|
|
49
55
|
|
|
50
56
|
/**
|
|
51
|
-
* @generated from enum value:
|
|
57
|
+
* @generated from enum value: ALLOWED_EMAIL_DOMAIN = 1;
|
|
52
58
|
*/
|
|
53
|
-
|
|
59
|
+
ALLOWED_EMAIL_DOMAIN = 1,
|
|
54
60
|
|
|
55
61
|
/**
|
|
56
|
-
* @generated from enum value:
|
|
62
|
+
* @generated from enum value: ORGANIZATION_DOMAIN = 2;
|
|
57
63
|
*/
|
|
58
|
-
|
|
64
|
+
ORGANIZATION_DOMAIN = 2,
|
|
59
65
|
}
|
|
60
66
|
// Retrieve enum metadata with: proto3.getEnumType(DomainType)
|
|
61
67
|
proto3.util.setEnumType(DomainType, "scalekit.v1.domains.DomainType", [
|
|
62
68
|
{ no: 0, name: "DOMAIN_TYPE_UNSPECIFIED" },
|
|
63
|
-
{ no: 1, name: "
|
|
64
|
-
{ no: 2, name: "
|
|
69
|
+
{ no: 1, name: "ALLOWED_EMAIL_DOMAIN" },
|
|
70
|
+
{ no: 2, name: "ORGANIZATION_DOMAIN" },
|
|
65
71
|
]);
|
|
66
72
|
|
|
67
73
|
/**
|
|
@@ -475,9 +475,14 @@ export class ToolErrorInfo extends Message<ToolErrorInfo> {
|
|
|
475
475
|
executionId = "";
|
|
476
476
|
|
|
477
477
|
/**
|
|
478
|
-
* @generated from field: string
|
|
478
|
+
* @generated from field: string tool_error_message = 2;
|
|
479
479
|
*/
|
|
480
|
-
|
|
480
|
+
toolErrorMessage = "";
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* @generated from field: string tool_error_code = 3;
|
|
484
|
+
*/
|
|
485
|
+
toolErrorCode = "";
|
|
481
486
|
|
|
482
487
|
constructor(data?: PartialMessage<ToolErrorInfo>) {
|
|
483
488
|
super();
|
|
@@ -488,7 +493,8 @@ export class ToolErrorInfo extends Message<ToolErrorInfo> {
|
|
|
488
493
|
static readonly typeName = "scalekit.v1.errdetails.ToolErrorInfo";
|
|
489
494
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
|
490
495
|
{ no: 1, name: "execution_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
491
|
-
{ no: 2, name: "
|
|
496
|
+
{ no: 2, name: "tool_error_message", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
497
|
+
{ no: 3, name: "tool_error_code", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
492
498
|
]);
|
|
493
499
|
|
|
494
500
|
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ToolErrorInfo {
|
|
@@ -1055,6 +1055,11 @@ export class CreateMembership extends Message<CreateMembership> {
|
|
|
1055
1055
|
*/
|
|
1056
1056
|
metadata: { [key: string]: string } = {};
|
|
1057
1057
|
|
|
1058
|
+
/**
|
|
1059
|
+
* @generated from field: optional string inviter_email = 8;
|
|
1060
|
+
*/
|
|
1061
|
+
inviterEmail?: string;
|
|
1062
|
+
|
|
1058
1063
|
constructor(data?: PartialMessage<CreateMembership>) {
|
|
1059
1064
|
super();
|
|
1060
1065
|
proto3.util.initPartial(data, this);
|
|
@@ -1065,6 +1070,7 @@ export class CreateMembership extends Message<CreateMembership> {
|
|
|
1065
1070
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
|
1066
1071
|
{ no: 4, name: "roles", kind: "message", T: Role, repeated: true },
|
|
1067
1072
|
{ no: 7, name: "metadata", kind: "map", K: 9 /* ScalarType.STRING */, V: {kind: "scalar", T: 9 /* ScalarType.STRING */} },
|
|
1073
|
+
{ no: 8, name: "inviter_email", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
|
|
1068
1074
|
]);
|
|
1069
1075
|
|
|
1070
1076
|
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreateMembership {
|
|
@@ -1453,9 +1459,9 @@ export class Invite extends Message<Invite> {
|
|
|
1453
1459
|
userId = "";
|
|
1454
1460
|
|
|
1455
1461
|
/**
|
|
1456
|
-
* @generated from field: string invited_by = 3;
|
|
1462
|
+
* @generated from field: optional string invited_by = 3;
|
|
1457
1463
|
*/
|
|
1458
|
-
invitedBy
|
|
1464
|
+
invitedBy?: string;
|
|
1459
1465
|
|
|
1460
1466
|
/**
|
|
1461
1467
|
* @generated from field: string status = 4;
|
|
@@ -1492,7 +1498,7 @@ export class Invite extends Message<Invite> {
|
|
|
1492
1498
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
|
1493
1499
|
{ no: 1, name: "organization_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
1494
1500
|
{ no: 2, name: "user_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
1495
|
-
{ no: 3, name: "invited_by", kind: "scalar", T: 9 /* ScalarType.STRING
|
|
1501
|
+
{ no: 3, name: "invited_by", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
|
|
1496
1502
|
{ no: 4, name: "status", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
1497
1503
|
{ no: 5, name: "created_at", kind: "message", T: Timestamp },
|
|
1498
1504
|
{ no: 6, name: "expires_at", kind: "message", T: Timestamp },
|
|
@@ -1731,10 +1737,16 @@ export class AssignUserRolesRequest extends Message<AssignUserRolesRequest> {
|
|
|
1731
1737
|
*/
|
|
1732
1738
|
export class AssignRoleRequest extends Message<AssignRoleRequest> {
|
|
1733
1739
|
/**
|
|
1734
|
-
* @generated from field: string id = 1;
|
|
1740
|
+
* @generated from field: string id = 1 [deprecated = true];
|
|
1741
|
+
* @deprecated
|
|
1735
1742
|
*/
|
|
1736
1743
|
id = "";
|
|
1737
1744
|
|
|
1745
|
+
/**
|
|
1746
|
+
* @generated from field: string role_name = 2;
|
|
1747
|
+
*/
|
|
1748
|
+
roleName = "";
|
|
1749
|
+
|
|
1738
1750
|
constructor(data?: PartialMessage<AssignRoleRequest>) {
|
|
1739
1751
|
super();
|
|
1740
1752
|
proto3.util.initPartial(data, this);
|
|
@@ -1744,6 +1756,7 @@ export class AssignRoleRequest extends Message<AssignRoleRequest> {
|
|
|
1744
1756
|
static readonly typeName = "scalekit.v1.users.AssignRoleRequest";
|
|
1745
1757
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
|
1746
1758
|
{ no: 1, name: "id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
1759
|
+
{ no: 2, name: "role_name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
1747
1760
|
]);
|
|
1748
1761
|
|
|
1749
1762
|
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): AssignRoleRequest {
|
|
@@ -1815,9 +1828,9 @@ export class RemoveUserRoleRequest extends Message<RemoveUserRoleRequest> {
|
|
|
1815
1828
|
userId = "";
|
|
1816
1829
|
|
|
1817
1830
|
/**
|
|
1818
|
-
* @generated from field: string
|
|
1831
|
+
* @generated from field: string role_name = 3;
|
|
1819
1832
|
*/
|
|
1820
|
-
|
|
1833
|
+
roleName = "";
|
|
1821
1834
|
|
|
1822
1835
|
constructor(data?: PartialMessage<RemoveUserRoleRequest>) {
|
|
1823
1836
|
super();
|
|
@@ -1829,7 +1842,7 @@ export class RemoveUserRoleRequest extends Message<RemoveUserRoleRequest> {
|
|
|
1829
1842
|
static readonly fields: FieldList = proto3.util.newFieldList(() => [
|
|
1830
1843
|
{ no: 1, name: "organization_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
1831
1844
|
{ no: 2, name: "user_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
1832
|
-
{ no: 3, name: "
|
|
1845
|
+
{ no: 3, name: "role_name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
1833
1846
|
]);
|
|
1834
1847
|
|
|
1835
1848
|
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): RemoveUserRoleRequest {
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import ScalekitClient from '../src/scalekit';
|
|
2
|
+
import { DomainType } from '../src/pkg/grpc/scalekit/v1/domains/domains_pb';
|
|
3
|
+
import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';
|
|
4
|
+
import { TestDataGenerator, TestOrganizationManager, TestDomainManager } from './utils/test-data';
|
|
5
|
+
|
|
6
|
+
describe('Domains', () => {
|
|
7
|
+
let client: ScalekitClient;
|
|
8
|
+
let testOrg: string;
|
|
9
|
+
|
|
10
|
+
beforeEach(async () => {
|
|
11
|
+
// Use global client
|
|
12
|
+
client = global.client;
|
|
13
|
+
|
|
14
|
+
// Create test organization for each test
|
|
15
|
+
testOrg = await TestOrganizationManager.createTestOrganization(client);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
afterEach(async () => {
|
|
19
|
+
// Clean up test organization
|
|
20
|
+
await TestOrganizationManager.cleanupTestOrganization(client, testOrg);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('createDomain', () => {
|
|
24
|
+
it('should create domain without domainType (backward compatibility)', async () => {
|
|
25
|
+
const domainName = TestDataGenerator.generateUniqueDomainName('backward-compat');
|
|
26
|
+
|
|
27
|
+
const response = await client.domain.createDomain(testOrg, domainName);
|
|
28
|
+
|
|
29
|
+
expect(response).toBeDefined();
|
|
30
|
+
expect(response.domain).toBeDefined();
|
|
31
|
+
expect(response.domain?.domain).toBe(domainName);
|
|
32
|
+
expect(response.domain?.id).toBeDefined();
|
|
33
|
+
expect(response.domain?.organizationId).toBe(testOrg);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should create domain with ALLOWED_EMAIL_DOMAIN type', async () => {
|
|
37
|
+
const domainName = TestDataGenerator.generateUniqueDomainName('allowed-email');
|
|
38
|
+
|
|
39
|
+
const response = await client.domain.createDomain(testOrg, domainName, {
|
|
40
|
+
domainType: DomainType.ALLOWED_EMAIL_DOMAIN
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
expect(response).toBeDefined();
|
|
44
|
+
expect(response.domain).toBeDefined();
|
|
45
|
+
expect(response.domain?.domain).toBe(domainName);
|
|
46
|
+
expect(response.domain?.domainType).toBe(DomainType.ALLOWED_EMAIL_DOMAIN);
|
|
47
|
+
expect(response.domain?.id).toBeDefined();
|
|
48
|
+
expect(response.domain?.organizationId).toBe(testOrg);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should create domain with ORGANIZATION_DOMAIN type', async () => {
|
|
52
|
+
const domainName = TestDataGenerator.generateUniqueDomainName('org-domain');
|
|
53
|
+
|
|
54
|
+
const response = await client.domain.createDomain(testOrg, domainName, {
|
|
55
|
+
domainType: DomainType.ORGANIZATION_DOMAIN
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
expect(response).toBeDefined();
|
|
59
|
+
expect(response.domain).toBeDefined();
|
|
60
|
+
expect(response.domain?.domain).toBe(domainName);
|
|
61
|
+
expect(response.domain?.domainType).toBe(DomainType.ORGANIZATION_DOMAIN);
|
|
62
|
+
expect(response.domain?.id).toBeDefined();
|
|
63
|
+
expect(response.domain?.organizationId).toBe(testOrg);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should create multiple domains of different types', async () => {
|
|
67
|
+
const allowedDomainName = TestDataGenerator.generateUniqueDomainName('allowed');
|
|
68
|
+
const orgDomainName = TestDataGenerator.generateUniqueDomainName('org');
|
|
69
|
+
|
|
70
|
+
// Create allowed email domain
|
|
71
|
+
const allowedResponse = await client.domain.createDomain(testOrg, allowedDomainName, {
|
|
72
|
+
domainType: DomainType.ALLOWED_EMAIL_DOMAIN
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Create organization domain
|
|
76
|
+
const orgResponse = await client.domain.createDomain(testOrg, orgDomainName, {
|
|
77
|
+
domainType: DomainType.ORGANIZATION_DOMAIN
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
expect(allowedResponse.domain?.domainType).toBe(DomainType.ALLOWED_EMAIL_DOMAIN);
|
|
81
|
+
expect(orgResponse.domain?.domainType).toBe(DomainType.ORGANIZATION_DOMAIN);
|
|
82
|
+
expect(allowedResponse.domain?.domain).toBe(allowedDomainName);
|
|
83
|
+
expect(orgResponse.domain?.domain).toBe(orgDomainName);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should create domain using TestDomainManager utility', async () => {
|
|
87
|
+
const { domainId, domainName, domainType, response } = await TestDomainManager.createTestDomain(
|
|
88
|
+
client,
|
|
89
|
+
testOrg,
|
|
90
|
+
'allowed'
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
expect(domainId).toBeDefined();
|
|
94
|
+
expect(domainName).toBeDefined();
|
|
95
|
+
expect(domainType).toBe(DomainType.ALLOWED_EMAIL_DOMAIN);
|
|
96
|
+
expect(response.domain?.domain).toBe(domainName);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe('listDomains', () => {
|
|
101
|
+
it('should list domains for organization', async () => {
|
|
102
|
+
// Create a test domain first
|
|
103
|
+
const { domainName } = await TestDomainManager.createTestDomain(client, testOrg, 'allowed');
|
|
104
|
+
|
|
105
|
+
const response = await client.domain.listDomains(testOrg);
|
|
106
|
+
|
|
107
|
+
expect(response).toBeDefined();
|
|
108
|
+
expect(response.domains).toBeDefined();
|
|
109
|
+
expect(Array.isArray(response.domains)).toBe(true);
|
|
110
|
+
expect(response.domains.length).toBeGreaterThan(0);
|
|
111
|
+
|
|
112
|
+
// Verify basic domain attributes
|
|
113
|
+
const firstDomain = response.domains[0];
|
|
114
|
+
expect(firstDomain.id).toBeDefined();
|
|
115
|
+
expect(firstDomain.domain).toBeDefined();
|
|
116
|
+
expect(firstDomain.organizationId).toBe(testOrg);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('should return empty list when no domains exist', async () => {
|
|
120
|
+
// Use a fresh organization without any domains
|
|
121
|
+
const freshOrg = await TestOrganizationManager.createTestOrganization(client);
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
const response = await client.domain.listDomains(freshOrg);
|
|
125
|
+
|
|
126
|
+
expect(response).toBeDefined();
|
|
127
|
+
expect(response.domains).toBeDefined();
|
|
128
|
+
expect(Array.isArray(response.domains)).toBe(true);
|
|
129
|
+
expect(response.domains.length).toBe(0);
|
|
130
|
+
} finally {
|
|
131
|
+
await TestOrganizationManager.cleanupTestOrganization(client, freshOrg);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('should list domains with different types', async () => {
|
|
136
|
+
// Create domains of different types
|
|
137
|
+
const { domainName: allowedDomainName } = await TestDomainManager.createTestDomain(client, testOrg, 'allowed');
|
|
138
|
+
const { domainName: orgDomainName } = await TestDomainManager.createTestDomain(client, testOrg, 'organization');
|
|
139
|
+
|
|
140
|
+
const response = await client.domain.listDomains(testOrg);
|
|
141
|
+
|
|
142
|
+
expect(response.domains.length).toBeGreaterThanOrEqual(2);
|
|
143
|
+
|
|
144
|
+
const domainNames = response.domains.map(d => d.domain);
|
|
145
|
+
const domainTypes = response.domains.map(d => d.domainType);
|
|
146
|
+
|
|
147
|
+
expect(domainNames).toContain(allowedDomainName);
|
|
148
|
+
expect(domainNames).toContain(orgDomainName);
|
|
149
|
+
expect(domainTypes).toContain(DomainType.ALLOWED_EMAIL_DOMAIN);
|
|
150
|
+
expect(domainTypes).toContain(DomainType.ORGANIZATION_DOMAIN);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
describe('getDomain', () => {
|
|
155
|
+
it('should get domain by ID successfully', async () => {
|
|
156
|
+
// Create a test domain first
|
|
157
|
+
const { domainId, domainName } = await TestDomainManager.createTestDomain(client, testOrg, 'allowed');
|
|
158
|
+
|
|
159
|
+
const response = await client.domain.getDomain(testOrg, domainId);
|
|
160
|
+
|
|
161
|
+
expect(response).toBeDefined();
|
|
162
|
+
expect(response.domain).toBeDefined();
|
|
163
|
+
expect(response.domain?.id).toBe(domainId);
|
|
164
|
+
expect(response.domain?.domain).toBe(domainName);
|
|
165
|
+
expect(response.domain?.organizationId).toBe(testOrg);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('should throw error for non-existent domain', async () => {
|
|
169
|
+
const nonExistentDomainId = 'non-existent-domain-id';
|
|
170
|
+
|
|
171
|
+
await expect(
|
|
172
|
+
client.domain.getDomain(testOrg, nonExistentDomainId)
|
|
173
|
+
).rejects.toThrow();
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('should throw error for invalid organization ID', async () => {
|
|
177
|
+
// Create a test domain first
|
|
178
|
+
const { domainId } = await TestDomainManager.createTestDomain(client, testOrg, 'allowed');
|
|
179
|
+
const invalidOrgId = 'invalid-org-id';
|
|
180
|
+
|
|
181
|
+
await expect(
|
|
182
|
+
client.domain.getDomain(invalidOrgId, domainId)
|
|
183
|
+
).rejects.toThrow();
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
describe('deleteDomain', () => {
|
|
188
|
+
it('should delete domain successfully', async () => {
|
|
189
|
+
// Create a test domain for deletion
|
|
190
|
+
const { domainId, domainName } = await TestDomainManager.createTestDomain(client, testOrg, 'allowed');
|
|
191
|
+
|
|
192
|
+
// Verify domain exists before deletion
|
|
193
|
+
const getResponse = await client.domain.getDomain(testOrg, domainId);
|
|
194
|
+
expect(getResponse.domain?.id).toBe(domainId);
|
|
195
|
+
|
|
196
|
+
// Delete the domain
|
|
197
|
+
const deleteResponse = await client.domain.deleteDomain(testOrg, domainId);
|
|
198
|
+
expect(deleteResponse).toBeDefined();
|
|
199
|
+
|
|
200
|
+
// Verify domain is deleted by trying to get it
|
|
201
|
+
await expect(
|
|
202
|
+
client.domain.getDomain(testOrg, domainId)
|
|
203
|
+
).rejects.toThrow();
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it('should throw error when deleting non-existent domain', async () => {
|
|
207
|
+
const nonExistentDomainId = 'non-existent-domain-id';
|
|
208
|
+
|
|
209
|
+
await expect(
|
|
210
|
+
client.domain.deleteDomain(testOrg, nonExistentDomainId)
|
|
211
|
+
).rejects.toThrow();
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
describe('error handling', () => {
|
|
218
|
+
it('should handle invalid organization ID', async () => {
|
|
219
|
+
const invalidOrgId = 'invalid-org-id';
|
|
220
|
+
const domainName = TestDataGenerator.generateUniqueDomainName('error-test');
|
|
221
|
+
|
|
222
|
+
await expect(
|
|
223
|
+
client.domain.createDomain(invalidOrgId, domainName)
|
|
224
|
+
).rejects.toThrow();
|
|
225
|
+
|
|
226
|
+
await expect(
|
|
227
|
+
client.domain.listDomains(invalidOrgId)
|
|
228
|
+
).rejects.toThrow();
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('should handle invalid domain name format', async () => {
|
|
232
|
+
const invalidDomainName = 'invalid-domain-name';
|
|
233
|
+
|
|
234
|
+
await expect(
|
|
235
|
+
client.domain.createDomain(testOrg, invalidDomainName)
|
|
236
|
+
).rejects.toThrow();
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
});
|
package/tests/utils/test-data.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CreateUserRequest, UpdateUserRequest } from '../../src/types/user';
|
|
2
2
|
import { TemplateType } from '../../src/pkg/grpc/scalekit/v1/auth/passwordless_pb';
|
|
3
|
+
import { DomainType } from '../../src/pkg/grpc/scalekit/v1/domains/domains_pb';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Test data generation utilities to reduce redundancy across test files
|
|
@@ -165,6 +166,28 @@ export class TestDataGenerator {
|
|
|
165
166
|
return { linkToken: 'mock-link-token' };
|
|
166
167
|
}
|
|
167
168
|
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Generate test domain data
|
|
172
|
+
*/
|
|
173
|
+
static generateDomainData(domainType?: 'allowed' | 'organization') {
|
|
174
|
+
const uniqueId = this.generateUniqueId();
|
|
175
|
+
const baseDomain = `test-domain-${uniqueId}.com`;
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
domain: baseDomain,
|
|
179
|
+
domainType: domainType === 'allowed' ? 'ALLOWED_EMAIL_DOMAIN' :
|
|
180
|
+
domainType === 'organization' ? 'ORGANIZATION_DOMAIN' : undefined
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Generate unique domain name for testing
|
|
186
|
+
*/
|
|
187
|
+
static generateUniqueDomainName(prefix: string = 'test'): string {
|
|
188
|
+
const uniqueId = this.generateUniqueId();
|
|
189
|
+
return `${prefix}-${uniqueId}.com`;
|
|
190
|
+
}
|
|
168
191
|
}
|
|
169
192
|
|
|
170
193
|
/**
|
|
@@ -245,4 +268,47 @@ export class TestUserManager {
|
|
|
245
268
|
}
|
|
246
269
|
}
|
|
247
270
|
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Test domain management utilities
|
|
275
|
+
*/
|
|
276
|
+
export class TestDomainManager {
|
|
277
|
+
/**
|
|
278
|
+
* Create a test domain and return domain data
|
|
279
|
+
*/
|
|
280
|
+
static async createTestDomain(client: any, testOrg: string, domainType?: 'allowed' | 'organization') {
|
|
281
|
+
const domainName = TestDataGenerator.generateUniqueDomainName();
|
|
282
|
+
const options = domainType ? {
|
|
283
|
+
domainType: domainType === 'allowed' ? DomainType.ALLOWED_EMAIL_DOMAIN : DomainType.ORGANIZATION_DOMAIN
|
|
284
|
+
} : undefined;
|
|
285
|
+
|
|
286
|
+
const response = await client.domain.createDomain(testOrg, domainName, options);
|
|
287
|
+
const createdDomainId = response.domain?.id;
|
|
288
|
+
|
|
289
|
+
if (!createdDomainId) {
|
|
290
|
+
throw new Error('Failed to create test domain');
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return {
|
|
294
|
+
domainId: createdDomainId,
|
|
295
|
+
domainName,
|
|
296
|
+
domainType: response.domain?.domainType,
|
|
297
|
+
response
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Clean up a test domain (if domain deletion is supported)
|
|
303
|
+
*/
|
|
304
|
+
static async cleanupTestDomain(client: any, testOrg: string, domainId: string): Promise<void> {
|
|
305
|
+
if (domainId) {
|
|
306
|
+
try {
|
|
307
|
+
// Note: Domain deletion may not be implemented yet
|
|
308
|
+
// await client.domain.deleteDomain(testOrg, domainId);
|
|
309
|
+
} catch (error) {
|
|
310
|
+
// Domain may already be deleted or deletion not supported
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
248
314
|
}
|