@dalmore/api-contracts 1.0.3 → 1.0.6
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/README.md +34 -60
- package/index.mjs +1001 -18638
- package/package.json +5 -53
- package/src/common/types/address.spec.ts +203 -0
- package/src/common/types/batch-jobs.types.ts +1 -0
- package/src/common/types/common.types.spec.ts +336 -0
- package/src/common/types/files.types.spec.ts +154 -0
- package/src/common/types/issuer-payment-method.types.spec.ts +612 -0
- package/src/common/types/offering.types.spec.ts +91 -0
- package/src/common/types/phone.spec.ts +76 -0
- package/src/common/types/queue.types.ts +1 -0
- package/src/common/types/reminder-config.types.ts +40 -0
- package/src/common/types/site-link.types.spec.ts +134 -0
- package/src/common/types/trade.types.ts +2 -4
- package/clients/index.mjs +0 -10970
- package/compliance/index.mjs +0 -20016
- package/compliance-apikey/index.mjs +0 -9795
- package/helpers/index.mjs +0 -146
- package/investors/index.mjs +0 -12844
- package/issuers/index.mjs +0 -16168
- package/secondaries/index.mjs +0 -10282
- package/src/common/helpers/index.ts +0 -205
- package/src/contracts/compliance/account-contacts/index.ts +0 -82
- package/src/contracts/compliance/account-managers/index.ts +0 -142
- package/src/contracts/compliance/accounts/index.ts +0 -187
- package/src/contracts/compliance/activities/index.ts +0 -55
- package/src/contracts/compliance/aic/index.ts +0 -60
- package/src/contracts/compliance/api-keys/index.ts +0 -91
- package/src/contracts/compliance/assets/index.ts +0 -122
- package/src/contracts/compliance/auth/index.ts +0 -134
- package/src/contracts/compliance/batch-jobs/index.ts +0 -62
- package/src/contracts/compliance/bonus-tiers/index.ts +0 -55
- package/src/contracts/compliance/checklist/index.ts +0 -87
- package/src/contracts/compliance/checklist-items/index.ts +0 -86
- package/src/contracts/compliance/covered-persons/index.ts +0 -97
- package/src/contracts/compliance/dashboard/index.ts +0 -111
- package/src/contracts/compliance/data-records/index.ts +0 -116
- package/src/contracts/compliance/data-rooms/index.ts +0 -113
- package/src/contracts/compliance/default-theme-configs/index.ts +0 -95
- package/src/contracts/compliance/disbursement/index.ts +0 -165
- package/src/contracts/compliance/disbursement-approval-users/index.ts +0 -84
- package/src/contracts/compliance/disbursement-transactions/index.ts +0 -37
- package/src/contracts/compliance/domain-filters/index.ts +0 -117
- package/src/contracts/compliance/email-themes/index.ts +0 -284
- package/src/contracts/compliance/escrow-accounts/index.ts +0 -85
- package/src/contracts/compliance/exchange-api-keys/index.ts +0 -129
- package/src/contracts/compliance/exchange-imports/index.ts +0 -137
- package/src/contracts/compliance/files/index.ts +0 -267
- package/src/contracts/compliance/files-public/index.ts +0 -188
- package/src/contracts/compliance/health/index.ts +0 -26
- package/src/contracts/compliance/index.ts +0 -147
- package/src/contracts/compliance/individuals/index.ts +0 -57
- package/src/contracts/compliance/investor-accounts/index.ts +0 -141
- package/src/contracts/compliance/invites/index.ts +0 -137
- package/src/contracts/compliance/issuer-bank-accounts/index.ts +0 -81
- package/src/contracts/compliance/issuer-payment-methods/index.ts +0 -81
- package/src/contracts/compliance/issuers/index.ts +0 -97
- package/src/contracts/compliance/job-items/index.ts +0 -58
- package/src/contracts/compliance/jobs/index.ts +0 -59
- package/src/contracts/compliance/kyb/index.ts +0 -54
- package/src/contracts/compliance/kyc/index.ts +0 -77
- package/src/contracts/compliance/legal-entities/index.ts +0 -57
- package/src/contracts/compliance/login-histories/index.ts +0 -37
- package/src/contracts/compliance/notes/index.ts +0 -69
- package/src/contracts/compliance/notion-databases/index.ts +0 -107
- package/src/contracts/compliance/notion-pages/index.ts +0 -105
- package/src/contracts/compliance/offering-reports/index.ts +0 -149
- package/src/contracts/compliance/offerings/index.ts +0 -233
- package/src/contracts/compliance/pages/index.ts +0 -178
- package/src/contracts/compliance/payment-methods/index.ts +0 -57
- package/src/contracts/compliance/rejection-reasons/index.ts +0 -32
- package/src/contracts/compliance/review/index.ts +0 -169
- package/src/contracts/compliance/roles/index.ts +0 -34
- package/src/contracts/compliance/secondary-customers/index.ts +0 -77
- package/src/contracts/compliance/secondary-orders/index.ts +0 -60
- package/src/contracts/compliance/secondary-trades/index.ts +0 -100
- package/src/contracts/compliance/secure-requests/index.ts +0 -54
- package/src/contracts/compliance/signer/index.ts +0 -369
- package/src/contracts/compliance/site-links/index.ts +0 -128
- package/src/contracts/compliance/site-settings/index.ts +0 -669
- package/src/contracts/compliance/sites/index.ts +0 -56
- package/src/contracts/compliance/state-machine/index.ts +0 -94
- package/src/contracts/compliance/tasks/index.ts +0 -91
- package/src/contracts/compliance/third-parties/index.ts +0 -52
- package/src/contracts/compliance/trade-line-items/index.ts +0 -59
- package/src/contracts/compliance/trades/index.ts +0 -230
- package/src/contracts/compliance/transactions/index.ts +0 -161
- package/src/contracts/compliance/user-manuals/index.ts +0 -271
- package/src/contracts/compliance/user-settings/index.ts +0 -189
- package/src/contracts/compliance/users/index.ts +0 -200
- package/src/contracts/compliance/webhooks/index.ts +0 -41
- package/src/contracts/compliance-apikey/accounts/index.ts +0 -58
- package/src/contracts/compliance-apikey/index.ts +0 -14
- package/src/contracts/index.ts +0 -6
- package/src/contracts/investors/account-contacts/index.ts +0 -58
- package/src/contracts/investors/aic/index.ts +0 -59
- package/src/contracts/investors/assets/index.ts +0 -61
- package/src/contracts/investors/auth/index.ts +0 -116
- package/src/contracts/investors/bonus-tiers/index.ts +0 -37
- package/src/contracts/investors/cart/index.ts +0 -75
- package/src/contracts/investors/contact-us/index.ts +0 -48
- package/src/contracts/investors/data-records/index.ts +0 -113
- package/src/contracts/investors/data-rooms/index.ts +0 -96
- package/src/contracts/investors/files/index.ts +0 -167
- package/src/contracts/investors/files-public/index.ts +0 -185
- package/src/contracts/investors/index.ts +0 -72
- package/src/contracts/investors/individuals/index.ts +0 -99
- package/src/contracts/investors/investor-accounts/index.ts +0 -110
- package/src/contracts/investors/issuer-payment-methods/index.ts +0 -36
- package/src/contracts/investors/issuers/index.ts +0 -30
- package/src/contracts/investors/legal-entities/index.ts +0 -93
- package/src/contracts/investors/notes/index.ts +0 -69
- package/src/contracts/investors/offerings/index.ts +0 -93
- package/src/contracts/investors/pages/index.ts +0 -88
- package/src/contracts/investors/payment-methods/index.ts +0 -149
- package/src/contracts/investors/portfolios/index.ts +0 -53
- package/src/contracts/investors/sites/index.ts +0 -96
- package/src/contracts/investors/tasks/index.ts +0 -111
- package/src/contracts/investors/trade-line-items/index.ts +0 -75
- package/src/contracts/investors/trades/index.ts +0 -114
- package/src/contracts/investors/transactions/index.ts +0 -37
- package/src/contracts/investors/trusted-contacts/index.ts +0 -93
- package/src/contracts/investors/user-manuals/index.ts +0 -62
- package/src/contracts/investors/user-settings/index.ts +0 -170
- package/src/contracts/investors/users/index.ts +0 -45
- package/src/contracts/investors/webhooks/index.ts +0 -30
- package/src/contracts/issuers/account-contacts/index.ts +0 -76
- package/src/contracts/issuers/account-integrations/index.ts +0 -97
- package/src/contracts/issuers/accounts/index.ts +0 -97
- package/src/contracts/issuers/activities/index.ts +0 -54
- package/src/contracts/issuers/aic/index.ts +0 -39
- package/src/contracts/issuers/api-key-logs/index.ts +0 -53
- package/src/contracts/issuers/api-keys/index.ts +0 -93
- package/src/contracts/issuers/assets/index.ts +0 -122
- package/src/contracts/issuers/auth/index.ts +0 -152
- package/src/contracts/issuers/bonus-tiers/index.ts +0 -55
- package/src/contracts/issuers/contact-us/index.ts +0 -48
- package/src/contracts/issuers/covered-persons/index.ts +0 -136
- package/src/contracts/issuers/dashboard/index.ts +0 -72
- package/src/contracts/issuers/data-records/index.ts +0 -257
- package/src/contracts/issuers/data-rooms/index.ts +0 -134
- package/src/contracts/issuers/disbursement-approval-users/index.ts +0 -82
- package/src/contracts/issuers/disbursement-transactions/index.ts +0 -53
- package/src/contracts/issuers/disbursements/index.ts +0 -153
- package/src/contracts/issuers/email-themes/index.ts +0 -242
- package/src/contracts/issuers/escrow-accounts/index.ts +0 -81
- package/src/contracts/issuers/exchange-api-keys/index.ts +0 -144
- package/src/contracts/issuers/files/index.ts +0 -166
- package/src/contracts/issuers/files-public/index.ts +0 -166
- package/src/contracts/issuers/health/index.ts +0 -24
- package/src/contracts/issuers/index.ts +0 -112
- package/src/contracts/issuers/investor-accounts/index.ts +0 -148
- package/src/contracts/issuers/invites/index.ts +0 -129
- package/src/contracts/issuers/issuer/index.ts +0 -94
- package/src/contracts/issuers/issuer-bank-accounts/index.ts +0 -81
- package/src/contracts/issuers/issuer-payment-methods/index.ts +0 -136
- package/src/contracts/issuers/kyc/index.ts +0 -38
- package/src/contracts/issuers/login-histories/index.ts +0 -51
- package/src/contracts/issuers/notes/index.ts +0 -69
- package/src/contracts/issuers/offerings/index.ts +0 -206
- package/src/contracts/issuers/pages/index.ts +0 -138
- package/src/contracts/issuers/payment-methods/index.ts +0 -61
- package/src/contracts/issuers/portfolios/index.ts +0 -36
- package/src/contracts/issuers/rejection-reasons/index.ts +0 -32
- package/src/contracts/issuers/review/index.ts +0 -63
- package/src/contracts/issuers/secondary-customers/index.ts +0 -55
- package/src/contracts/issuers/secondary-orders/index.ts +0 -57
- package/src/contracts/issuers/secondary-trades/index.ts +0 -57
- package/src/contracts/issuers/secure-requests/index.ts +0 -34
- package/src/contracts/issuers/site-links/index.ts +0 -116
- package/src/contracts/issuers/site-settings/index.ts +0 -585
- package/src/contracts/issuers/sites/index.ts +0 -32
- package/src/contracts/issuers/tasks/index.ts +0 -111
- package/src/contracts/issuers/trades/index.ts +0 -132
- package/src/contracts/issuers/transactions/index.ts +0 -158
- package/src/contracts/issuers/user-manuals/index.ts +0 -62
- package/src/contracts/issuers/user-settings/index.ts +0 -170
- package/src/contracts/issuers/users/index.ts +0 -126
- package/src/contracts/secondaries/accounts/index.ts +0 -58
- package/src/contracts/secondaries/index.ts +0 -23
- package/src/contracts/secondaries/secondary-customers/index.ts +0 -55
- package/src/contracts/secondaries/secondary-issuers/index.ts +0 -94
- package/src/contracts/secondaries/secondary-orders/index.ts +0 -56
- package/src/contracts/secondaries/secondary-securities/index.ts +0 -95
- package/src/contracts/secondaries/secondary-trades/index.ts +0 -56
- package/types/index.mjs +0 -10320
|
@@ -0,0 +1,612 @@
|
|
|
1
|
+
import { PaymentMethodType } from './payment-methods.types';
|
|
2
|
+
import {
|
|
3
|
+
PatchIssuerPaymentMethodZod,
|
|
4
|
+
PaymentMethodConfig,
|
|
5
|
+
createDefaultIssuerPaymentMethods,
|
|
6
|
+
stripeConfigSchema,
|
|
7
|
+
wireConfigSchema,
|
|
8
|
+
checkConfigSchema,
|
|
9
|
+
retirementConfigSchema,
|
|
10
|
+
} from './issuer-payment-method.types';
|
|
11
|
+
import { StateCode } from './states.types';
|
|
12
|
+
import { CountryCode } from './countries.types';
|
|
13
|
+
import { typeid } from 'typeid-js';
|
|
14
|
+
import {
|
|
15
|
+
getRandomName,
|
|
16
|
+
getRandomCompanyName,
|
|
17
|
+
getRandomAddress,
|
|
18
|
+
getRandomCity,
|
|
19
|
+
getRandomState,
|
|
20
|
+
getRandomZip,
|
|
21
|
+
getRandomNumber,
|
|
22
|
+
getRandomStripeAccountId,
|
|
23
|
+
} from '../../tests/factory/random.factory';
|
|
24
|
+
|
|
25
|
+
describe('PatchIssuerPaymentMethodZod Schema', () => {
|
|
26
|
+
it('should validate CREDIT_CARD payment method', () => {
|
|
27
|
+
const input = {
|
|
28
|
+
paymentMethodType: PaymentMethodType.CREDIT_CARD,
|
|
29
|
+
config: {
|
|
30
|
+
stripeAccountId: getRandomStripeAccountId(),
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const result = PatchIssuerPaymentMethodZod.safeParse(input);
|
|
35
|
+
expect(result.success).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should validate WIRE payment method', () => {
|
|
39
|
+
const input = {
|
|
40
|
+
paymentMethodType: PaymentMethodType.WIRE,
|
|
41
|
+
config: {
|
|
42
|
+
usAccountHolderName: getRandomName(),
|
|
43
|
+
usBankName: `${getRandomName()} Bank`,
|
|
44
|
+
usRoutingNumber: getRandomNumber(100000000, 999999999, 0)
|
|
45
|
+
.toString()
|
|
46
|
+
.padStart(9, '0'),
|
|
47
|
+
usAccountNumber: getRandomNumber(
|
|
48
|
+
10000000,
|
|
49
|
+
Number.MAX_SAFE_INTEGER,
|
|
50
|
+
0,
|
|
51
|
+
).toString(),
|
|
52
|
+
reference: null,
|
|
53
|
+
swiftId: null,
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const result = PatchIssuerPaymentMethodZod.safeParse(input);
|
|
58
|
+
expect(result.success).toBe(true);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should validate CHECK payment method', () => {
|
|
62
|
+
const input = {
|
|
63
|
+
paymentMethodType: PaymentMethodType.CHECK,
|
|
64
|
+
config: {
|
|
65
|
+
companyName: getRandomCompanyName(),
|
|
66
|
+
address: getRandomAddress(),
|
|
67
|
+
address2: `Suite ${getRandomNumber(1, 999, 0)}`,
|
|
68
|
+
city: getRandomCity(),
|
|
69
|
+
state: StateCode[getRandomState() as keyof typeof StateCode],
|
|
70
|
+
zip: getRandomZip(),
|
|
71
|
+
country: CountryCode['US'],
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const result = PatchIssuerPaymentMethodZod.safeParse(input);
|
|
76
|
+
expect(result.success).toBe(true);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('should reject mismatched payment method type and config', () => {
|
|
80
|
+
const input = {
|
|
81
|
+
paymentMethodType: PaymentMethodType.CREDIT_CARD,
|
|
82
|
+
config: {
|
|
83
|
+
usAccountHolderName: getRandomName(),
|
|
84
|
+
usBankName: `${getRandomName()} Bank`,
|
|
85
|
+
usRoutingNumber: getRandomNumber(100000000, 999999999, 0)
|
|
86
|
+
.toString()
|
|
87
|
+
.padStart(9, '0'),
|
|
88
|
+
usAccountNumber: getRandomNumber(
|
|
89
|
+
10000000,
|
|
90
|
+
Number.MAX_SAFE_INTEGER,
|
|
91
|
+
0,
|
|
92
|
+
).toString(),
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const result = PatchIssuerPaymentMethodZod.safeParse(input);
|
|
97
|
+
expect(result.success).toBe(false);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should reject invalid Stripe account id', () => {
|
|
101
|
+
const input = {
|
|
102
|
+
paymentMethodType: PaymentMethodType.CREDIT_CARD,
|
|
103
|
+
config: {
|
|
104
|
+
stripeAccountId: 123,
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const result = PatchIssuerPaymentMethodZod.safeParse(input);
|
|
109
|
+
expect(result.success).toBe(false);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('should reject missing required fields', () => {
|
|
113
|
+
const input = {
|
|
114
|
+
paymentMethodType: PaymentMethodType.WIRE,
|
|
115
|
+
config: {
|
|
116
|
+
usAccountHolderName: getRandomName(),
|
|
117
|
+
// missing other required fields
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const result = PatchIssuerPaymentMethodZod.safeParse(input);
|
|
122
|
+
expect(result.success).toBe(false);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe('Issuer Payment Method Schema Consistency', () => {
|
|
127
|
+
describe('PatchIssuerPaymentMethodZod and PaymentMethodConfig consistency', () => {
|
|
128
|
+
it('should use the same stripeConfigSchema for CREDIT_CARD in both schemas', () => {
|
|
129
|
+
const stripeAccountId = getRandomStripeAccountId();
|
|
130
|
+
const patchInput = {
|
|
131
|
+
paymentMethodType: PaymentMethodType.CREDIT_CARD,
|
|
132
|
+
config: {
|
|
133
|
+
stripeAccountId,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const configInput = {
|
|
138
|
+
paymentMethodType: PaymentMethodType.CREDIT_CARD,
|
|
139
|
+
config: {
|
|
140
|
+
stripeAccountId,
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const patchResult = PatchIssuerPaymentMethodZod.safeParse(patchInput);
|
|
145
|
+
const configResult = PaymentMethodConfig.safeParse(configInput);
|
|
146
|
+
|
|
147
|
+
expect(patchResult.success).toBe(true);
|
|
148
|
+
expect(configResult.success).toBe(true);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('should use the same stripeConfigSchema for ACH in both schemas', () => {
|
|
152
|
+
const stripeAccountId = getRandomStripeAccountId();
|
|
153
|
+
const patchInput = {
|
|
154
|
+
paymentMethodType: PaymentMethodType.ACH,
|
|
155
|
+
config: {
|
|
156
|
+
stripeAccountId,
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const configInput = {
|
|
161
|
+
paymentMethodType: PaymentMethodType.ACH,
|
|
162
|
+
config: {
|
|
163
|
+
stripeAccountId,
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const patchResult = PatchIssuerPaymentMethodZod.safeParse(patchInput);
|
|
168
|
+
const configResult = PaymentMethodConfig.safeParse(configInput);
|
|
169
|
+
|
|
170
|
+
expect(patchResult.success).toBe(true);
|
|
171
|
+
expect(configResult.success).toBe(true);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('should use the same wireConfigSchema for WIRE in both schemas', () => {
|
|
175
|
+
// Generate a valid swiftId (8-11 characters)
|
|
176
|
+
const bankCode = getRandomName()
|
|
177
|
+
.substring(0, 4)
|
|
178
|
+
.toUpperCase()
|
|
179
|
+
.padEnd(4, 'A');
|
|
180
|
+
const swiftId = `${bankCode}US33XXX`.substring(0, 11); // Ensure 8-11 chars
|
|
181
|
+
|
|
182
|
+
const wireConfig = {
|
|
183
|
+
usAccountHolderName: getRandomName(),
|
|
184
|
+
usBankName: `${getRandomName()} Bank`,
|
|
185
|
+
usRoutingNumber: getRandomNumber(100000000, 999999999, 0)
|
|
186
|
+
.toString()
|
|
187
|
+
.padStart(9, '0'),
|
|
188
|
+
usAccountNumber: getRandomNumber(
|
|
189
|
+
10000000,
|
|
190
|
+
Number.MAX_SAFE_INTEGER,
|
|
191
|
+
0,
|
|
192
|
+
).toString(),
|
|
193
|
+
reference: `REF${getRandomNumber(100, 999, 0)}`,
|
|
194
|
+
swiftId:
|
|
195
|
+
swiftId.length >= 8 ? swiftId : `${bankCode}US33XXX`.substring(0, 11),
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const patchInput = {
|
|
199
|
+
paymentMethodType: PaymentMethodType.WIRE,
|
|
200
|
+
config: wireConfig,
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const configInput = {
|
|
204
|
+
paymentMethodType: PaymentMethodType.WIRE,
|
|
205
|
+
config: wireConfig,
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
const patchResult = PatchIssuerPaymentMethodZod.safeParse(patchInput);
|
|
209
|
+
const configResult = PaymentMethodConfig.safeParse(configInput);
|
|
210
|
+
|
|
211
|
+
expect(patchResult.success).toBe(true);
|
|
212
|
+
expect(configResult.success).toBe(true);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it('should use the same checkConfigSchema for CHECK in both schemas', () => {
|
|
216
|
+
const checkConfig = {
|
|
217
|
+
companyName: getRandomCompanyName(),
|
|
218
|
+
address: getRandomAddress(),
|
|
219
|
+
address2: `Suite ${getRandomNumber(1, 999, 0)}`,
|
|
220
|
+
city: getRandomCity(),
|
|
221
|
+
state: StateCode[getRandomState() as keyof typeof StateCode],
|
|
222
|
+
zip: getRandomZip(),
|
|
223
|
+
country: CountryCode['US'],
|
|
224
|
+
reference: `REF${getRandomNumber(100, 999, 0)}`,
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const patchInput = {
|
|
228
|
+
paymentMethodType: PaymentMethodType.CHECK,
|
|
229
|
+
config: checkConfig,
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const configInput = {
|
|
233
|
+
paymentMethodType: PaymentMethodType.CHECK,
|
|
234
|
+
config: checkConfig,
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
const patchResult = PatchIssuerPaymentMethodZod.safeParse(patchInput);
|
|
238
|
+
const configResult = PaymentMethodConfig.safeParse(configInput);
|
|
239
|
+
|
|
240
|
+
expect(patchResult.success).toBe(true);
|
|
241
|
+
expect(configResult.success).toBe(true);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it('should use the same retirementConfigSchema for RETIREMENT in both schemas', () => {
|
|
245
|
+
const retirementConfig = {
|
|
246
|
+
custodianInstruction: `Custodian instruction for ${getRandomCompanyName()}`,
|
|
247
|
+
custodianDocument: null,
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const patchInput = {
|
|
251
|
+
paymentMethodType: PaymentMethodType.RETIREMENT,
|
|
252
|
+
config: retirementConfig,
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
const configInput = {
|
|
256
|
+
paymentMethodType: PaymentMethodType.RETIREMENT,
|
|
257
|
+
config: retirementConfig,
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
const patchResult = PatchIssuerPaymentMethodZod.safeParse(patchInput);
|
|
261
|
+
const configResult = PaymentMethodConfig.safeParse(configInput);
|
|
262
|
+
|
|
263
|
+
expect(patchResult.success).toBe(true);
|
|
264
|
+
expect(configResult.success).toBe(true);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
it('should reject the same invalid configs in both schemas', () => {
|
|
268
|
+
const invalidWireConfig = {
|
|
269
|
+
usAccountHolderName: getRandomName(),
|
|
270
|
+
// Missing required fields
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
const patchInput = {
|
|
274
|
+
paymentMethodType: PaymentMethodType.WIRE,
|
|
275
|
+
config: invalidWireConfig,
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
const configInput = {
|
|
279
|
+
paymentMethodType: PaymentMethodType.WIRE,
|
|
280
|
+
config: invalidWireConfig,
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
const patchResult = PatchIssuerPaymentMethodZod.safeParse(patchInput);
|
|
284
|
+
const configResult = PaymentMethodConfig.safeParse(configInput);
|
|
285
|
+
|
|
286
|
+
expect(patchResult.success).toBe(false);
|
|
287
|
+
expect(configResult.success).toBe(false);
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
describe('Payment method type coverage', () => {
|
|
292
|
+
it('should cover all payment method types in PatchIssuerPaymentMethodZod', () => {
|
|
293
|
+
const paymentMethodTypes = Object.values(PaymentMethodType);
|
|
294
|
+
const coveredTypes = new Set<string>();
|
|
295
|
+
|
|
296
|
+
// Test each payment method type
|
|
297
|
+
paymentMethodTypes.forEach((type) => {
|
|
298
|
+
let config: any;
|
|
299
|
+
switch (type) {
|
|
300
|
+
case PaymentMethodType.CREDIT_CARD:
|
|
301
|
+
case PaymentMethodType.ACH:
|
|
302
|
+
case PaymentMethodType.BANK_ACCOUNT:
|
|
303
|
+
config = { stripeAccountId: getRandomStripeAccountId() };
|
|
304
|
+
break;
|
|
305
|
+
case PaymentMethodType.WIRE:
|
|
306
|
+
config = {
|
|
307
|
+
usAccountHolderName: getRandomName(),
|
|
308
|
+
usBankName: `${getRandomName()} Bank`,
|
|
309
|
+
usRoutingNumber: getRandomNumber(100000000, 999999999, 0)
|
|
310
|
+
.toString()
|
|
311
|
+
.padStart(9, '0'),
|
|
312
|
+
usAccountNumber: getRandomNumber(
|
|
313
|
+
10000000,
|
|
314
|
+
Number.MAX_SAFE_INTEGER,
|
|
315
|
+
0,
|
|
316
|
+
).toString(),
|
|
317
|
+
};
|
|
318
|
+
break;
|
|
319
|
+
case PaymentMethodType.CHECK:
|
|
320
|
+
config = {
|
|
321
|
+
companyName: getRandomCompanyName(),
|
|
322
|
+
address: getRandomAddress(),
|
|
323
|
+
city: getRandomCity(),
|
|
324
|
+
state: StateCode[getRandomState() as keyof typeof StateCode],
|
|
325
|
+
zip: getRandomZip(),
|
|
326
|
+
country: CountryCode['US'],
|
|
327
|
+
};
|
|
328
|
+
break;
|
|
329
|
+
case PaymentMethodType.RETIREMENT:
|
|
330
|
+
config = {
|
|
331
|
+
custodianInstruction: `Custodian instruction for ${getRandomCompanyName()}`,
|
|
332
|
+
};
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const result = PatchIssuerPaymentMethodZod.safeParse({
|
|
337
|
+
paymentMethodType: type,
|
|
338
|
+
config,
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
if (result.success) {
|
|
342
|
+
coveredTypes.add(type);
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
// BANK_ACCOUNT is in PatchIssuerPaymentMethodZod but not in PaymentMethodConfig
|
|
347
|
+
// This is expected behavior, so we check that all types that should be covered are covered
|
|
348
|
+
expect(coveredTypes.has(PaymentMethodType.CREDIT_CARD)).toBe(true);
|
|
349
|
+
expect(coveredTypes.has(PaymentMethodType.ACH)).toBe(true);
|
|
350
|
+
expect(coveredTypes.has(PaymentMethodType.BANK_ACCOUNT)).toBe(true);
|
|
351
|
+
expect(coveredTypes.has(PaymentMethodType.WIRE)).toBe(true);
|
|
352
|
+
expect(coveredTypes.has(PaymentMethodType.CHECK)).toBe(true);
|
|
353
|
+
expect(coveredTypes.has(PaymentMethodType.RETIREMENT)).toBe(true);
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
it('should cover all payment method types in PaymentMethodConfig', () => {
|
|
357
|
+
const paymentMethodTypes = Object.values(PaymentMethodType);
|
|
358
|
+
const coveredTypes = new Set<string>();
|
|
359
|
+
|
|
360
|
+
// Test each payment method type
|
|
361
|
+
paymentMethodTypes.forEach((type) => {
|
|
362
|
+
let config: any;
|
|
363
|
+
switch (type) {
|
|
364
|
+
case PaymentMethodType.CREDIT_CARD:
|
|
365
|
+
case PaymentMethodType.ACH:
|
|
366
|
+
config = { stripeAccountId: getRandomStripeAccountId() };
|
|
367
|
+
break;
|
|
368
|
+
case PaymentMethodType.WIRE:
|
|
369
|
+
config = {
|
|
370
|
+
usAccountHolderName: getRandomName(),
|
|
371
|
+
usBankName: `${getRandomName()} Bank`,
|
|
372
|
+
usRoutingNumber: getRandomNumber(100000000, 999999999, 0)
|
|
373
|
+
.toString()
|
|
374
|
+
.padStart(9, '0'),
|
|
375
|
+
usAccountNumber: getRandomNumber(
|
|
376
|
+
10000000,
|
|
377
|
+
Number.MAX_SAFE_INTEGER,
|
|
378
|
+
0,
|
|
379
|
+
).toString(),
|
|
380
|
+
};
|
|
381
|
+
break;
|
|
382
|
+
case PaymentMethodType.CHECK:
|
|
383
|
+
config = {
|
|
384
|
+
companyName: getRandomCompanyName(),
|
|
385
|
+
address: getRandomAddress(),
|
|
386
|
+
city: getRandomCity(),
|
|
387
|
+
state: StateCode[getRandomState() as keyof typeof StateCode],
|
|
388
|
+
zip: getRandomZip(),
|
|
389
|
+
country: CountryCode['US'],
|
|
390
|
+
};
|
|
391
|
+
break;
|
|
392
|
+
case PaymentMethodType.RETIREMENT:
|
|
393
|
+
config = {
|
|
394
|
+
custodianInstruction: `Custodian instruction for ${getRandomCompanyName()}`,
|
|
395
|
+
};
|
|
396
|
+
break;
|
|
397
|
+
case PaymentMethodType.BANK_ACCOUNT:
|
|
398
|
+
// BANK_ACCOUNT is not in PaymentMethodConfig, skip it
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
const result = PaymentMethodConfig.safeParse({
|
|
403
|
+
paymentMethodType: type,
|
|
404
|
+
config,
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
if (result.success) {
|
|
408
|
+
coveredTypes.add(type);
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
// PaymentMethodConfig doesn't include BANK_ACCOUNT, which is expected
|
|
413
|
+
expect(coveredTypes.has(PaymentMethodType.CREDIT_CARD)).toBe(true);
|
|
414
|
+
expect(coveredTypes.has(PaymentMethodType.ACH)).toBe(true);
|
|
415
|
+
expect(coveredTypes.has(PaymentMethodType.WIRE)).toBe(true);
|
|
416
|
+
expect(coveredTypes.has(PaymentMethodType.CHECK)).toBe(true);
|
|
417
|
+
expect(coveredTypes.has(PaymentMethodType.RETIREMENT)).toBe(true);
|
|
418
|
+
});
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
describe('createDefaultIssuerPaymentMethods schema consistency', () => {
|
|
422
|
+
it('should create payment methods with valid configs that match their schemas', () => {
|
|
423
|
+
const issuerId = typeid('issuer').toString();
|
|
424
|
+
const defaultMethods = createDefaultIssuerPaymentMethods(issuerId);
|
|
425
|
+
|
|
426
|
+
defaultMethods.forEach((method) => {
|
|
427
|
+
let configSchema: any;
|
|
428
|
+
switch (method.paymentMethodType) {
|
|
429
|
+
case PaymentMethodType.CREDIT_CARD:
|
|
430
|
+
case PaymentMethodType.ACH:
|
|
431
|
+
case PaymentMethodType.BANK_ACCOUNT:
|
|
432
|
+
configSchema = stripeConfigSchema;
|
|
433
|
+
break;
|
|
434
|
+
case PaymentMethodType.WIRE:
|
|
435
|
+
configSchema = wireConfigSchema;
|
|
436
|
+
break;
|
|
437
|
+
case PaymentMethodType.CHECK:
|
|
438
|
+
configSchema = checkConfigSchema;
|
|
439
|
+
break;
|
|
440
|
+
case PaymentMethodType.RETIREMENT:
|
|
441
|
+
configSchema = retirementConfigSchema;
|
|
442
|
+
break;
|
|
443
|
+
default:
|
|
444
|
+
throw new Error(
|
|
445
|
+
`Unknown payment method type: ${method.paymentMethodType}`,
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Parse the config string back to object
|
|
450
|
+
const configObj =
|
|
451
|
+
typeof method.config === 'string'
|
|
452
|
+
? JSON.parse(method.config)
|
|
453
|
+
: method.config;
|
|
454
|
+
|
|
455
|
+
// Validate the config against its schema
|
|
456
|
+
const result = configSchema.safeParse(configObj);
|
|
457
|
+
expect(result.success).toBe(true);
|
|
458
|
+
});
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
it('should create all expected payment method types', () => {
|
|
462
|
+
const issuerId = typeid('issuer').toString();
|
|
463
|
+
const defaultMethods = createDefaultIssuerPaymentMethods(issuerId);
|
|
464
|
+
|
|
465
|
+
const createdTypes = defaultMethods.map((m) => m.paymentMethodType);
|
|
466
|
+
const expectedTypes = [
|
|
467
|
+
PaymentMethodType.CREDIT_CARD,
|
|
468
|
+
PaymentMethodType.ACH,
|
|
469
|
+
PaymentMethodType.BANK_ACCOUNT,
|
|
470
|
+
PaymentMethodType.WIRE,
|
|
471
|
+
PaymentMethodType.CHECK,
|
|
472
|
+
PaymentMethodType.RETIREMENT,
|
|
473
|
+
];
|
|
474
|
+
|
|
475
|
+
expectedTypes.forEach((expectedType) => {
|
|
476
|
+
expect(createdTypes).toContain(expectedType);
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
expect(defaultMethods.length).toBe(expectedTypes.length);
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
it('should create payment methods that can be validated by PatchIssuerPaymentMethodZod', () => {
|
|
483
|
+
const issuerId = typeid('issuer').toString();
|
|
484
|
+
const defaultMethods = createDefaultIssuerPaymentMethods(issuerId);
|
|
485
|
+
|
|
486
|
+
defaultMethods.forEach((method) => {
|
|
487
|
+
const configObj =
|
|
488
|
+
typeof method.config === 'string'
|
|
489
|
+
? JSON.parse(method.config)
|
|
490
|
+
: method.config;
|
|
491
|
+
|
|
492
|
+
const input = {
|
|
493
|
+
paymentMethodType: method.paymentMethodType,
|
|
494
|
+
config: configObj,
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
const result = PatchIssuerPaymentMethodZod.safeParse(input);
|
|
498
|
+
|
|
499
|
+
// BANK_ACCOUNT might not be in PaymentMethodConfig but should be in PatchIssuerPaymentMethodZod
|
|
500
|
+
expect(result.success).toBe(true);
|
|
501
|
+
});
|
|
502
|
+
});
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
describe('Config schema field consistency', () => {
|
|
506
|
+
it('should have consistent field definitions in wireConfigSchema', () => {
|
|
507
|
+
// Generate a valid swiftId (8-11 characters, alphanumeric)
|
|
508
|
+
// SWIFT IDs are typically 8 or 11 characters: 4 letters (bank code) + 2 letters (country) + 2 chars (location) + optional 3 chars (branch)
|
|
509
|
+
const bankCode = getRandomName()
|
|
510
|
+
.substring(0, 4)
|
|
511
|
+
.toUpperCase()
|
|
512
|
+
.padEnd(4, 'A');
|
|
513
|
+
const countryCode = 'US';
|
|
514
|
+
const locationCode = '33';
|
|
515
|
+
const branchCode = 'XXX'; // Optional 3-character branch code
|
|
516
|
+
const swiftId =
|
|
517
|
+
`${bankCode}${countryCode}${locationCode}${branchCode}`.substring(
|
|
518
|
+
0,
|
|
519
|
+
11,
|
|
520
|
+
); // Ensure max 11 chars
|
|
521
|
+
|
|
522
|
+
const validConfig = {
|
|
523
|
+
usAccountHolderName: getRandomName(),
|
|
524
|
+
usBankName: `${getRandomName()} Bank`,
|
|
525
|
+
usRoutingNumber: getRandomNumber(100000000, 999999999, 0)
|
|
526
|
+
.toString()
|
|
527
|
+
.padStart(9, '0'),
|
|
528
|
+
usAccountNumber: getRandomNumber(
|
|
529
|
+
10000000,
|
|
530
|
+
Number.MAX_SAFE_INTEGER,
|
|
531
|
+
0,
|
|
532
|
+
).toString(),
|
|
533
|
+
reference: `REF${getRandomNumber(100, 999, 0)}`,
|
|
534
|
+
swiftId:
|
|
535
|
+
swiftId.length >= 8
|
|
536
|
+
? swiftId
|
|
537
|
+
: `${bankCode}${countryCode}${locationCode}XXX`.substring(0, 11),
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
const result = wireConfigSchema.safeParse(validConfig);
|
|
541
|
+
expect(result.success).toBe(true);
|
|
542
|
+
|
|
543
|
+
// Verify all expected fields are present
|
|
544
|
+
if (result.success) {
|
|
545
|
+
expect(result.data).toHaveProperty('usAccountHolderName');
|
|
546
|
+
expect(result.data).toHaveProperty('usBankName');
|
|
547
|
+
expect(result.data).toHaveProperty('usRoutingNumber');
|
|
548
|
+
expect(result.data).toHaveProperty('usAccountNumber');
|
|
549
|
+
expect(result.data).toHaveProperty('reference');
|
|
550
|
+
expect(result.data).toHaveProperty('swiftId');
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
it('should have consistent field definitions in checkConfigSchema', () => {
|
|
555
|
+
const validConfig = {
|
|
556
|
+
companyName: getRandomCompanyName(),
|
|
557
|
+
address: getRandomAddress(),
|
|
558
|
+
address2: `Suite ${getRandomNumber(1, 999, 0)}`,
|
|
559
|
+
city: getRandomCity(),
|
|
560
|
+
state: StateCode[getRandomState() as keyof typeof StateCode],
|
|
561
|
+
zip: getRandomZip(),
|
|
562
|
+
country: CountryCode['US'],
|
|
563
|
+
reference: `REF${getRandomNumber(100, 999, 0)}`,
|
|
564
|
+
};
|
|
565
|
+
|
|
566
|
+
const result = checkConfigSchema.safeParse(validConfig);
|
|
567
|
+
expect(result.success).toBe(true);
|
|
568
|
+
|
|
569
|
+
// Verify all expected fields are present
|
|
570
|
+
if (result.success) {
|
|
571
|
+
expect(result.data).toHaveProperty('companyName');
|
|
572
|
+
expect(result.data).toHaveProperty('address');
|
|
573
|
+
expect(result.data).toHaveProperty('address2');
|
|
574
|
+
expect(result.data).toHaveProperty('city');
|
|
575
|
+
expect(result.data).toHaveProperty('state');
|
|
576
|
+
expect(result.data).toHaveProperty('zip');
|
|
577
|
+
expect(result.data).toHaveProperty('country');
|
|
578
|
+
expect(result.data).toHaveProperty('reference');
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
it('should have consistent field definitions in retirementConfigSchema', () => {
|
|
583
|
+
const validConfig = {
|
|
584
|
+
custodianInstruction: `Custodian instruction for ${getRandomCompanyName()}`,
|
|
585
|
+
custodianDocument: null,
|
|
586
|
+
};
|
|
587
|
+
|
|
588
|
+
const result = retirementConfigSchema.safeParse(validConfig);
|
|
589
|
+
expect(result.success).toBe(true);
|
|
590
|
+
|
|
591
|
+
// Verify all expected fields are present
|
|
592
|
+
if (result.success) {
|
|
593
|
+
expect(result.data).toHaveProperty('custodianInstruction');
|
|
594
|
+
expect(result.data).toHaveProperty('custodianDocument');
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
it('should have consistent field definitions in stripeConfigSchema', () => {
|
|
599
|
+
const validConfig = {
|
|
600
|
+
stripeAccountId: getRandomStripeAccountId(),
|
|
601
|
+
};
|
|
602
|
+
|
|
603
|
+
const result = stripeConfigSchema.safeParse(validConfig);
|
|
604
|
+
expect(result.success).toBe(true);
|
|
605
|
+
|
|
606
|
+
// Verify all expected fields are present
|
|
607
|
+
if (result.success) {
|
|
608
|
+
expect(result.data).toHaveProperty('stripeAccountId');
|
|
609
|
+
}
|
|
610
|
+
});
|
|
611
|
+
});
|
|
612
|
+
});
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { OfferingSettings, OfferingFeeType } from './offering.types';
|
|
3
|
+
|
|
4
|
+
describe('OfferingSettings Schema', () => {
|
|
5
|
+
it('should pass with all null or undefined values', () => {
|
|
6
|
+
const data = {
|
|
7
|
+
settingsBrokerageFeeValue: null,
|
|
8
|
+
settingsBrokerageFeeType: null,
|
|
9
|
+
settingsCardFeeValue: null,
|
|
10
|
+
settingsCardFeeType: null,
|
|
11
|
+
settingsDisbursementFeeValue: null,
|
|
12
|
+
settingsDisbursementFeeType: null,
|
|
13
|
+
settingsRefundPoolFeeValue: null,
|
|
14
|
+
settingsRefundPoolFeeType: null,
|
|
15
|
+
serviceCharges: null,
|
|
16
|
+
serviceChargesType: null,
|
|
17
|
+
};
|
|
18
|
+
expect(() => OfferingSettings.parse(data)).not.toThrow();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should pass with valid non-null pair values', () => {
|
|
22
|
+
const data = {
|
|
23
|
+
settingsBrokerageFeeValue: 50,
|
|
24
|
+
settingsBrokerageFeeType: OfferingFeeType.PERCENTAGE,
|
|
25
|
+
settingsCardFeeValue: 25,
|
|
26
|
+
settingsCardFeeType: OfferingFeeType.PERCENTAGE,
|
|
27
|
+
settingsDisbursementFeeValue: 30,
|
|
28
|
+
settingsDisbursementFeeType: OfferingFeeType.PERCENTAGE,
|
|
29
|
+
settingsRefundPoolFeeValue: 40,
|
|
30
|
+
settingsRefundPoolFeeType: OfferingFeeType.PERCENTAGE,
|
|
31
|
+
};
|
|
32
|
+
expect(() => OfferingSettings.parse(data)).not.toThrow();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should fail if one of a pair is null and the other is not', () => {
|
|
36
|
+
const data = {
|
|
37
|
+
settingsBrokerageFeeValue: 10,
|
|
38
|
+
settingsBrokerageFeeType: null,
|
|
39
|
+
settingsCardFeeValue: null,
|
|
40
|
+
settingsCardFeeType: OfferingFeeType.PERCENTAGE,
|
|
41
|
+
settingsDisbursementFeeValue: 15,
|
|
42
|
+
settingsDisbursementFeeType: null,
|
|
43
|
+
settingsRefundPoolFeeValue: null,
|
|
44
|
+
settingsRefundPoolFeeType: OfferingFeeType.PERCENTAGE,
|
|
45
|
+
};
|
|
46
|
+
expect(() => OfferingSettings.parse(data)).toThrow(
|
|
47
|
+
'settingsBrokerageFeeType and settingsBrokerageFeeValue must both be either null or not-null',
|
|
48
|
+
);
|
|
49
|
+
expect(() => OfferingSettings.parse(data)).toThrow(
|
|
50
|
+
'settingsCardFeeType and settingsCardFeeValue must both be either null or not-null',
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should fail if percentage fee values exceed 100', () => {
|
|
55
|
+
const data = {
|
|
56
|
+
settingsBrokerageFeeValue: 101,
|
|
57
|
+
settingsBrokerageFeeType: OfferingFeeType.PERCENTAGE,
|
|
58
|
+
settingsCardFeeValue: 50,
|
|
59
|
+
settingsCardFeeType: OfferingFeeType.PERCENTAGE,
|
|
60
|
+
settingsDisbursementFeeValue: 200,
|
|
61
|
+
settingsDisbursementFeeType: OfferingFeeType.PERCENTAGE,
|
|
62
|
+
settingsRefundPoolFeeValue: 150,
|
|
63
|
+
settingsRefundPoolFeeType: OfferingFeeType.PERCENTAGE,
|
|
64
|
+
};
|
|
65
|
+
expect(() => OfferingSettings.parse(data)).toThrow(
|
|
66
|
+
'settingsBrokerageFeeValue must be less than or equal to 100',
|
|
67
|
+
);
|
|
68
|
+
expect(() => OfferingSettings.parse(data)).toThrow(
|
|
69
|
+
'settingsDisbursementFeeValue must be less than 100',
|
|
70
|
+
);
|
|
71
|
+
expect(() => OfferingSettings.parse(data)).toThrow(
|
|
72
|
+
'settingsRefundPoolFeeValue must be less than or equal to 100',
|
|
73
|
+
);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should fail if required values are missing', () => {
|
|
77
|
+
const data = {
|
|
78
|
+
settingsBrokerageFeeValue: undefined,
|
|
79
|
+
settingsBrokerageFeeType: OfferingFeeType.PERCENTAGE,
|
|
80
|
+
};
|
|
81
|
+
expect(() => OfferingSettings.parse(data)).toThrow(z.ZodError);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should fail if invalid types are provided', () => {
|
|
85
|
+
const data = {
|
|
86
|
+
settingsBrokerageFeeValue: 'invalid', // should be a number
|
|
87
|
+
settingsBrokerageFeeType: OfferingFeeType.PERCENTAGE,
|
|
88
|
+
};
|
|
89
|
+
expect(() => OfferingSettings.parse(data)).toThrow(z.ZodError);
|
|
90
|
+
});
|
|
91
|
+
});
|