mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
chore: add BillingService.ts test coverage
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -13,7 +13,7 @@ node_modules
|
||||
|
||||
.idea
|
||||
# testing
|
||||
/coverage
|
||||
**/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
7
Common/Utils/Errors.ts
Normal file
7
Common/Utils/Errors.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export default {
|
||||
API: {
|
||||
CLIENT_SECRET_MISSING:
|
||||
'client_secret not returned by payment provider.',
|
||||
INVOICE_NOT_GENERATED: 'Invoice not generated.',
|
||||
},
|
||||
};
|
||||
@@ -15,6 +15,8 @@ import SubscriptionStatus, {
|
||||
import BaseService from './BaseService';
|
||||
import Email from 'Common/Types/Email';
|
||||
import Dictionary from 'Common/Types/Dictionary';
|
||||
import Errors from '../Utils/Errors';
|
||||
import APIErrors from 'Common/Utils/Errors';
|
||||
|
||||
export type SubscriptionItem = Stripe.SubscriptionItem;
|
||||
|
||||
@@ -54,10 +56,9 @@ export class BillingService extends BaseService {
|
||||
}): Promise<string> {
|
||||
if (!this.isBillingEnabled()) {
|
||||
throw new BadDataException(
|
||||
'Billing is not enabled for this server.'
|
||||
Errors.BillingService.BILLING_NOT_ENABLED
|
||||
);
|
||||
}
|
||||
|
||||
const customer: Stripe.Response<Stripe.Customer> =
|
||||
await this.stripe.customers.create({
|
||||
name: data.name,
|
||||
@@ -66,7 +67,6 @@ export class BillingService extends BaseService {
|
||||
id: data.id.toString(),
|
||||
},
|
||||
});
|
||||
|
||||
return customer.id;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ export class BillingService extends BaseService {
|
||||
): Promise<void> {
|
||||
if (!this.isBillingEnabled()) {
|
||||
throw new BadDataException(
|
||||
'Billing is not enabled for this server.'
|
||||
Errors.BillingService.BILLING_NOT_ENABLED
|
||||
);
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ export class BillingService extends BaseService {
|
||||
public async deleteCustomer(id: string): Promise<void> {
|
||||
if (!this.isBillingEnabled()) {
|
||||
throw new BadDataException(
|
||||
'Billing is not enabled for this server.'
|
||||
Errors.BillingService.BILLING_NOT_ENABLED
|
||||
);
|
||||
}
|
||||
|
||||
@@ -191,16 +191,16 @@ export class BillingService extends BaseService {
|
||||
}> {
|
||||
if (!this.isBillingEnabled()) {
|
||||
throw new BadDataException(
|
||||
'Billing is not enabled for this server.'
|
||||
Errors.BillingService.BILLING_NOT_ENABLED
|
||||
);
|
||||
}
|
||||
|
||||
let trialDate: Date | null = null;
|
||||
|
||||
if (typeof data.trial === Typeof.Boolean) {
|
||||
trialDate = OneUptimeDate.getSomeDaysAfter(
|
||||
data.plan.getTrialPeriod()
|
||||
);
|
||||
trialDate = data.trial
|
||||
? OneUptimeDate.getSomeDaysAfter(data.plan.getTrialPeriod())
|
||||
: null;
|
||||
}
|
||||
|
||||
if (data.trial instanceof Date) {
|
||||
@@ -260,7 +260,7 @@ export class BillingService extends BaseService {
|
||||
): Promise<void> {
|
||||
if (!this.isBillingEnabled()) {
|
||||
throw new BadDataException(
|
||||
'Billing is not enabled for this server.'
|
||||
Errors.BillingService.BILLING_NOT_ENABLED
|
||||
);
|
||||
}
|
||||
|
||||
@@ -268,9 +268,10 @@ export class BillingService extends BaseService {
|
||||
await this.stripe.subscriptions.retrieve(subscriptionId);
|
||||
|
||||
if (!subscription) {
|
||||
throw new BadDataException('Subscription not found');
|
||||
throw new BadDataException(
|
||||
Errors.BillingService.SUBSCRIPTION_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
if (subscription.status === 'canceled') {
|
||||
// subscription is canceled.
|
||||
return;
|
||||
@@ -280,7 +281,9 @@ export class BillingService extends BaseService {
|
||||
subscription.items.data[0]?.id;
|
||||
|
||||
if (!subscriptionItemId) {
|
||||
throw new BadDataException('Subscription Item not found');
|
||||
throw new BadDataException(
|
||||
Errors.BillingService.SUBSCRIPTION_ITEM_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
await this.stripe.subscriptionItems.update(subscriptionItemId, {
|
||||
@@ -295,7 +298,7 @@ export class BillingService extends BaseService {
|
||||
): Promise<void> {
|
||||
if (!this.isBillingEnabled()) {
|
||||
throw new BadDataException(
|
||||
'Billing is not enabled for this server.'
|
||||
Errors.BillingService.BILLING_NOT_ENABLED
|
||||
);
|
||||
}
|
||||
|
||||
@@ -305,7 +308,9 @@ export class BillingService extends BaseService {
|
||||
);
|
||||
|
||||
if (!subscription) {
|
||||
throw new BadDataException('Subscription not found');
|
||||
throw new BadDataException(
|
||||
Errors.BillingService.SUBSCRIPTION_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
// check if this pricing exists
|
||||
@@ -324,7 +329,9 @@ export class BillingService extends BaseService {
|
||||
})?.id;
|
||||
|
||||
if (!subscriptionItemId) {
|
||||
throw new BadDataException('Subscription Item not found');
|
||||
throw new BadDataException(
|
||||
Errors.BillingService.SUBSCRIPTION_ITEM_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
// use stripe usage based api to update the quantity.
|
||||
@@ -357,7 +364,7 @@ export class BillingService extends BaseService {
|
||||
public async isPromoCodeValid(promoCode: string): Promise<boolean> {
|
||||
if (!this.isBillingEnabled()) {
|
||||
throw new BadDataException(
|
||||
'Billing is not enabled for this server.'
|
||||
Errors.BillingService.BILLING_NOT_ENABLED
|
||||
);
|
||||
}
|
||||
try {
|
||||
@@ -365,13 +372,16 @@ export class BillingService extends BaseService {
|
||||
await this.stripe.coupons.retrieve(promoCode);
|
||||
|
||||
if (!promoCodeResponse) {
|
||||
throw new BadDataException('Promo code not found');
|
||||
throw new BadDataException(
|
||||
Errors.BillingService.PROMO_CODE_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
return promoCodeResponse.valid;
|
||||
} catch (err) {
|
||||
throw new BadDataException(
|
||||
(err as Error).message || 'Invalid promo code'
|
||||
(err as Error).message ||
|
||||
Errors.BillingService.PROMO_CODE_INVALID
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -383,7 +393,7 @@ export class BillingService extends BaseService {
|
||||
): Promise<void> {
|
||||
if (!this.isBillingEnabled()) {
|
||||
throw new BadDataException(
|
||||
'Billing is not enabled for this server.'
|
||||
Errors.BillingService.BILLING_NOT_ENABLED
|
||||
);
|
||||
}
|
||||
|
||||
@@ -391,7 +401,9 @@ export class BillingService extends BaseService {
|
||||
await this.stripe.subscriptions.retrieve(subscriptionId);
|
||||
|
||||
if (!subscription) {
|
||||
throw new BadDataException('Subscription not found');
|
||||
throw new BadDataException(
|
||||
Errors.BillingService.SUBSCRIPTION_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
if (subscription.status === 'canceled') {
|
||||
@@ -418,7 +430,7 @@ export class BillingService extends BaseService {
|
||||
): Promise<Array<SubscriptionItem>> {
|
||||
if (!this.isBillingEnabled()) {
|
||||
throw new BadDataException(
|
||||
'Billing is not enabled for this server.'
|
||||
Errors.BillingService.BILLING_NOT_ENABLED
|
||||
);
|
||||
}
|
||||
|
||||
@@ -426,7 +438,9 @@ export class BillingService extends BaseService {
|
||||
await this.stripe.subscriptions.retrieve(subscriptionId);
|
||||
|
||||
if (!subscription) {
|
||||
throw new BadDataException('Subscription not found');
|
||||
throw new BadDataException(
|
||||
Errors.BillingService.SUBSCRIPTION_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
return subscription.items.data;
|
||||
@@ -450,10 +464,10 @@ export class BillingService extends BaseService {
|
||||
logger.info(data);
|
||||
|
||||
if (!this.isBillingEnabled()) {
|
||||
logger.info('Billing not enabled');
|
||||
logger.info(Errors.BillingService.BILLING_NOT_ENABLED);
|
||||
|
||||
throw new BadDataException(
|
||||
'Billing is not enabled for this server.'
|
||||
Errors.BillingService.BILLING_NOT_ENABLED
|
||||
);
|
||||
}
|
||||
|
||||
@@ -464,8 +478,10 @@ export class BillingService extends BaseService {
|
||||
logger.info(subscription);
|
||||
|
||||
if (!subscription) {
|
||||
logger.info('Subscription not found');
|
||||
throw new BadDataException('Subscription not found');
|
||||
logger.info(Errors.BillingService.SUBSCRIPTION_NOT_FOUND);
|
||||
throw new BadDataException(
|
||||
Errors.BillingService.SUBSCRIPTION_NOT_FOUND
|
||||
);
|
||||
}
|
||||
|
||||
logger.info('Subscription status');
|
||||
@@ -481,7 +497,7 @@ export class BillingService extends BaseService {
|
||||
logger.info('No payment methods');
|
||||
|
||||
throw new BadDataException(
|
||||
'No payment methods added. Please add your card to this project to change your plan'
|
||||
Errors.BillingService.NO_PAYMENTS_METHODS
|
||||
);
|
||||
}
|
||||
|
||||
@@ -536,7 +552,7 @@ export class BillingService extends BaseService {
|
||||
): Promise<void> {
|
||||
if (!this.isBillingEnabled()) {
|
||||
throw new BadDataException(
|
||||
'Billing is not enabled for this server.'
|
||||
Errors.BillingService.BILLING_NOT_ENABLED
|
||||
);
|
||||
}
|
||||
|
||||
@@ -545,7 +561,7 @@ export class BillingService extends BaseService {
|
||||
|
||||
if (paymentMethods.length === 1) {
|
||||
throw new BadDataException(
|
||||
"There's only one payment method associated with this account. It cannot be deleted. To delete this payment method please add more payment methods to your account."
|
||||
Errors.BillingService.MIN_REQUIRED_PAYMENT_METHOD_NOT_MET
|
||||
);
|
||||
}
|
||||
|
||||
@@ -576,7 +592,7 @@ export class BillingService extends BaseService {
|
||||
): Promise<Array<PaymentMethod>> {
|
||||
if (!this.isBillingEnabled()) {
|
||||
throw new BadDataException(
|
||||
'Billing is not enabled for this server.'
|
||||
Errors.BillingService.BILLING_NOT_ENABLED
|
||||
);
|
||||
}
|
||||
const paymentMethods: Array<PaymentMethod> = [];
|
||||
@@ -671,9 +687,7 @@ export class BillingService extends BaseService {
|
||||
});
|
||||
|
||||
if (!setupIntent.client_secret) {
|
||||
throw new APIException(
|
||||
'client_secret not returned by payment provider.'
|
||||
);
|
||||
throw new APIException(APIErrors.API.CLIENT_SECRET_MISSING);
|
||||
}
|
||||
|
||||
return setupIntent.client_secret;
|
||||
@@ -682,7 +696,7 @@ export class BillingService extends BaseService {
|
||||
public async cancelSubscription(subscriptionId: string): Promise<void> {
|
||||
if (!this.isBillingEnabled()) {
|
||||
throw new BadDataException(
|
||||
'Billing is not enabled for this server.'
|
||||
Errors.BillingService.BILLING_NOT_ENABLED
|
||||
);
|
||||
}
|
||||
try {
|
||||
@@ -706,7 +720,7 @@ export class BillingService extends BaseService {
|
||||
): Promise<Stripe.Subscription> {
|
||||
if (!this.isBillingEnabled()) {
|
||||
throw new BadDataException(
|
||||
'Billing is not enabled for this server.'
|
||||
Errors.BillingService.BILLING_NOT_ENABLED
|
||||
);
|
||||
}
|
||||
|
||||
@@ -748,7 +762,7 @@ export class BillingService extends BaseService {
|
||||
});
|
||||
|
||||
if (!invoice || !invoice.id) {
|
||||
throw new APIException('Invoice not generated.');
|
||||
throw new APIException(APIErrors.API.INVOICE_NOT_GENERATED);
|
||||
}
|
||||
|
||||
await this.stripe.invoiceItems.create({
|
||||
@@ -787,7 +801,7 @@ export class BillingService extends BaseService {
|
||||
|
||||
if (paymentMethods.length === 0) {
|
||||
throw new BadDataException(
|
||||
'Payment Method not added. Please go to Project Settings > Billing and add a payment method.'
|
||||
Errors.BillingService.NO_PAYMENTS_METHODS_2
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
1592
CommonServer/Tests/Services/BillingService.test.ts
Normal file
1592
CommonServer/Tests/Services/BillingService.test.ts
Normal file
File diff suppressed because it is too large
Load Diff
161
CommonServer/Tests/TestingUtils/Services/Helpers.ts
Normal file
161
CommonServer/Tests/TestingUtils/Services/Helpers.ts
Normal file
@@ -0,0 +1,161 @@
|
||||
import { Stripe } from 'stripe';
|
||||
import { faker } from '@faker-js/faker';
|
||||
|
||||
import Email from 'Common/Types/Email';
|
||||
import ObjectID from 'Common/Types/ObjectID';
|
||||
import SubscriptionPlan from 'Common/Types/Billing/SubscriptionPlan';
|
||||
|
||||
import { BillingService } from '../../../Services/BillingService';
|
||||
|
||||
import {
|
||||
CustomerData,
|
||||
Subscription,
|
||||
MeteredSubscription,
|
||||
ChangePlan,
|
||||
CouponData,
|
||||
} from '../../TestingUtils/Services/Types';
|
||||
|
||||
/// @dev consider modifyfing the EnvirontmentConfig to use functions instead of constants so that we can mock them
|
||||
const mockIsBillingEnabled: Function = (value: boolean): BillingService => {
|
||||
jest.resetModules();
|
||||
jest.doMock('../../../EnvironmentConfig', () => {
|
||||
return {
|
||||
IsBillingEnabled: value,
|
||||
};
|
||||
});
|
||||
const { BillingService } = require('../../../Services/BillingService');
|
||||
return new BillingService();
|
||||
};
|
||||
|
||||
const getStripeCustomer: Function = (id?: string): Stripe.Customer => {
|
||||
id = id || faker.datatype.uuid();
|
||||
return {
|
||||
id,
|
||||
object: 'customer',
|
||||
balance: faker.datatype.number(),
|
||||
created: 1,
|
||||
default_source: null,
|
||||
description: null,
|
||||
email: null,
|
||||
invoice_settings: {
|
||||
custom_fields: null,
|
||||
default_payment_method: null,
|
||||
footer: null,
|
||||
rendering_options: null,
|
||||
},
|
||||
livemode: true,
|
||||
metadata: {},
|
||||
shipping: null,
|
||||
};
|
||||
};
|
||||
|
||||
const getStripeSubscription: Function = (): Stripe.Subscription => {
|
||||
return {
|
||||
id: faker.datatype.uuid(),
|
||||
items: {
|
||||
data: [
|
||||
{
|
||||
id: faker.datatype.uuid(),
|
||||
// @ts-ignore
|
||||
price: { id: faker.datatype.uuid() },
|
||||
},
|
||||
],
|
||||
},
|
||||
status: 'active',
|
||||
customer: getStripeCustomer(),
|
||||
};
|
||||
};
|
||||
|
||||
const getSubscriptionPlanData: Function = (): SubscriptionPlan => {
|
||||
return new SubscriptionPlan(
|
||||
faker.datatype.uuid(), // monthlyPlanId
|
||||
faker.datatype.uuid(), // yearlyPlanId
|
||||
faker.commerce.productName(), // name
|
||||
faker.datatype.number(), // monthlySubscriptionAmountInUSD
|
||||
faker.datatype.number({ min: 1, max: 100 }), // yearlySubscriptionAmountInUSD
|
||||
faker.datatype.number({ min: 1, max: 100 }), // order
|
||||
faker.datatype.number({ min: 1, max: 100 }) // trial period days
|
||||
);
|
||||
};
|
||||
|
||||
const getStripeInvoice: Function = (): Stripe.Invoice => {
|
||||
// @ts-ignore
|
||||
return {
|
||||
id: faker.datatype.uuid(),
|
||||
amount_due: faker.datatype.number(),
|
||||
currency: 'usd',
|
||||
customer: faker.datatype.uuid(),
|
||||
subscription: faker.datatype.uuid(),
|
||||
status: 'paid',
|
||||
};
|
||||
};
|
||||
|
||||
const getCustomerData: Function = (id?: ObjectID): CustomerData => {
|
||||
return {
|
||||
id: id || new ObjectID('customer_id'),
|
||||
name: 'John Doe',
|
||||
email: new Email('test@example.com'),
|
||||
};
|
||||
};
|
||||
|
||||
const getSubscriptionData: Function = (id?: ObjectID): Subscription => {
|
||||
return {
|
||||
projectId: id || new ObjectID('project_id'),
|
||||
customerId: 'cust_123',
|
||||
serverMeteredPlans: [],
|
||||
trialDate: new Date(),
|
||||
};
|
||||
};
|
||||
|
||||
const getMeteredSubscription: Function = (
|
||||
subscriptionPlan: SubscriptionPlan,
|
||||
id?: ObjectID
|
||||
): MeteredSubscription => {
|
||||
return {
|
||||
projectId: id || new ObjectID('project_id'),
|
||||
customerId: 'cust_123',
|
||||
serverMeteredPlans: [],
|
||||
plan: subscriptionPlan,
|
||||
quantity: 1,
|
||||
isYearly: false,
|
||||
trial: true,
|
||||
};
|
||||
};
|
||||
|
||||
const getChangePlanData: Function = (
|
||||
subscriptionPlan: SubscriptionPlan,
|
||||
id?: ObjectID
|
||||
): ChangePlan => {
|
||||
return {
|
||||
projectId: id || new ObjectID('project_id'),
|
||||
subscriptionId: 'sub_123',
|
||||
meteredSubscriptionId: 'sub_456',
|
||||
serverMeteredPlans: [],
|
||||
newPlan: subscriptionPlan,
|
||||
quantity: 1,
|
||||
isYearly: false,
|
||||
};
|
||||
};
|
||||
|
||||
const getCouponData: Function = (): CouponData => {
|
||||
return {
|
||||
name: 'TESTCOUPON',
|
||||
metadata: { description: 'Test coupon' },
|
||||
percentOff: 10,
|
||||
durationInMonths: 3,
|
||||
maxRedemptions: 100,
|
||||
};
|
||||
};
|
||||
|
||||
export {
|
||||
mockIsBillingEnabled,
|
||||
getStripeCustomer,
|
||||
getStripeSubscription,
|
||||
getSubscriptionPlanData,
|
||||
getCustomerData,
|
||||
getSubscriptionData,
|
||||
getMeteredSubscription,
|
||||
getChangePlanData,
|
||||
getCouponData,
|
||||
getStripeInvoice,
|
||||
};
|
||||
57
CommonServer/Tests/TestingUtils/Services/Types.ts
Normal file
57
CommonServer/Tests/TestingUtils/Services/Types.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import Email from 'Common/Types/Email';
|
||||
import ObjectID from 'Common/Types/ObjectID';
|
||||
import ServerMeteredPlan from '../../../Types/Billing/MeteredPlan/ServerMeteredPlan';
|
||||
import SubscriptionPlan from 'Common/Types/Billing/SubscriptionPlan';
|
||||
import { PaymentMethod } from '../../../Services/BillingService';
|
||||
import Dictionary from 'Common/Types/Dictionary';
|
||||
|
||||
export type CustomerData = {
|
||||
id: ObjectID;
|
||||
name: string;
|
||||
email: Email;
|
||||
};
|
||||
|
||||
export type CouponData = {
|
||||
name: string;
|
||||
metadata?: Dictionary<string> | undefined;
|
||||
percentOff: number;
|
||||
durationInMonths: number;
|
||||
maxRedemptions: number;
|
||||
};
|
||||
|
||||
export type Subscription = {
|
||||
projectId: ObjectID;
|
||||
customerId: string;
|
||||
serverMeteredPlans: Array<typeof ServerMeteredPlan>;
|
||||
promoCode?: string;
|
||||
defaultPaymentMethodId?: string;
|
||||
trialDate: Date;
|
||||
};
|
||||
|
||||
export type MeteredSubscription = {
|
||||
projectId: ObjectID;
|
||||
customerId: string;
|
||||
serverMeteredPlans: Array<typeof ServerMeteredPlan>;
|
||||
plan: SubscriptionPlan;
|
||||
quantity: number;
|
||||
isYearly: boolean;
|
||||
trial: boolean | Date | undefined;
|
||||
defaultPaymentMethodId?: string | undefined;
|
||||
promoCode?: string | undefined;
|
||||
};
|
||||
|
||||
export type ChangePlan = {
|
||||
projectId: ObjectID;
|
||||
subscriptionId: string;
|
||||
meteredSubscriptionId: string;
|
||||
serverMeteredPlans: Array<typeof ServerMeteredPlan>;
|
||||
newPlan: SubscriptionPlan;
|
||||
quantity: number;
|
||||
isYearly: boolean;
|
||||
endTrialAt?: Date | undefined;
|
||||
};
|
||||
|
||||
export type PaymentMethodsResponse = {
|
||||
data: PaymentMethod[];
|
||||
defaultPaymentMethodId?: string | undefined;
|
||||
};
|
||||
16
CommonServer/Tests/TestingUtils/__mocks__/stripe.mock.ts
Normal file
16
CommonServer/Tests/TestingUtils/__mocks__/stripe.mock.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import * as mock from 'jest-mock-extended';
|
||||
|
||||
let mockStripe: jest.Mocked<Stripe>;
|
||||
|
||||
jest.mock('stripe', () => {
|
||||
mockStripe = mock.mockDeep<Stripe>();
|
||||
return jest.fn(() => {
|
||||
return mockStripe;
|
||||
});
|
||||
});
|
||||
|
||||
// import libraries to mock (we do it here because of hoisting)
|
||||
import Stripe from 'stripe';
|
||||
|
||||
// return the mocked library and the library itself
|
||||
export { mockStripe, Stripe };
|
||||
16
CommonServer/Utils/Errors.ts
Normal file
16
CommonServer/Utils/Errors.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
export default {
|
||||
BillingService: {
|
||||
BILLING_NOT_ENABLED: 'Billing is not enabled for this server.',
|
||||
SUBSCRIPTION_ITEM_NOT_FOUND: 'Subscription item not found.',
|
||||
SUBSCRIPTION_NOT_FOUND: 'Subscription not found.',
|
||||
NO_PAYMENTS_METHODS:
|
||||
'No payment methods added. Please add your card to this project to change your plan',
|
||||
/// @dev consider consolidating the above and below error messages
|
||||
NO_PAYMENTS_METHODS_2:
|
||||
'Payment Method not added. Please go to Project Settings > Billing and add a payment method.',
|
||||
MIN_REQUIRED_PAYMENT_METHOD_NOT_MET:
|
||||
"There's only one payment method associated with this account. It cannot be deleted. To delete this payment method please add more payment methods to your account.",
|
||||
PROMO_CODE_NOT_FOUND: 'Promo code not found',
|
||||
PROMO_CODE_INVALID: 'Invalid promo code',
|
||||
},
|
||||
};
|
||||
@@ -12,8 +12,11 @@
|
||||
".(ts|tsx)": "ts-jest"
|
||||
},
|
||||
"testEnvironment": "node",
|
||||
"collectCoverage": true,
|
||||
"coverageReporters": ["text"],
|
||||
"collectCoverage": false,
|
||||
"transformIgnorePatterns": [
|
||||
"/node_modules/(?!Common).+\\.js$"
|
||||
],
|
||||
"coverageReporters": ["text", "lcov"],
|
||||
"testRegex": "./Tests/(.*).test.ts",
|
||||
"collectCoverageFrom": ["./**/*.(tsx||ts)"],
|
||||
"coverageThreshold": {
|
||||
|
||||
3007
CommonServer/package-lock.json
generated
3007
CommonServer/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,7 @@
|
||||
"scripts": {
|
||||
"compile": "tsc",
|
||||
"test": "jest --detectOpenHandles",
|
||||
"coverage": "jest --detectOpenHandles --coverage",
|
||||
"debug:test": "cd .. && export $(grep -v '^#' config.env | xargs) && cd CommonServer && node --inspect node_modules/.bin/jest --runInBand ./Tests --detectOpenHandles"
|
||||
},
|
||||
"author": "",
|
||||
@@ -59,6 +60,7 @@
|
||||
"@types/jsonwebtoken": "^8.5.9",
|
||||
"@types/node": "^17.0.22",
|
||||
"jest": "^27.5.1",
|
||||
"ts-jest": "^27.1.4"
|
||||
"ts-jest": "^27.1.4",
|
||||
"jest-mock-extended": "^3.0.5"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user