89 lines
2.9 KiB
TypeScript
89 lines
2.9 KiB
TypeScript
import { ForbiddenException } from '@nestjs/common';
|
|
import { ApiKey } from '@domain/entities/api-key.entity';
|
|
import { Subscription } from '@domain/entities/subscription.entity';
|
|
import { SubscriptionPlan } from '@domain/value-objects/subscription-plan.vo';
|
|
import {
|
|
SubscriptionStatus,
|
|
SubscriptionStatusType,
|
|
} from '@domain/value-objects/subscription-status.vo';
|
|
import { ApiKeyRepository } from '@domain/ports/out/api-key.repository';
|
|
import { UserRepository } from '@domain/ports/out/user.repository';
|
|
import { SubscriptionRepository } from '@domain/ports/out/subscription.repository';
|
|
import { ApiKeysService } from './api-keys.service';
|
|
|
|
describe('API key current entitlement', () => {
|
|
const setup = () => {
|
|
let subscription = Subscription.create({
|
|
id: 'sub',
|
|
organizationId: 'org',
|
|
plan: SubscriptionPlan.gold(),
|
|
});
|
|
const key = ApiKey.create({
|
|
id: 'key',
|
|
userId: 'user',
|
|
organizationId: 'org',
|
|
name: 'test',
|
|
keyHash: 'hash',
|
|
keyPrefix: 'xped_live_test',
|
|
});
|
|
const keys = {
|
|
findByKeyHash: jest.fn().mockResolvedValue(key),
|
|
save: jest.fn().mockImplementation(async value => value),
|
|
};
|
|
const users = {
|
|
findById: jest
|
|
.fn()
|
|
.mockResolvedValue({ id: 'user', organizationId: 'org', isActive: true, role: 'MANAGER' }),
|
|
};
|
|
const subscriptions = {
|
|
findByOrganizationId: jest.fn().mockImplementation(async () => subscription),
|
|
};
|
|
return {
|
|
service: new ApiKeysService(
|
|
keys as unknown as ApiKeyRepository,
|
|
users as unknown as UserRepository,
|
|
subscriptions as unknown as SubscriptionRepository
|
|
),
|
|
keys,
|
|
setStatus: (status: SubscriptionStatusType) => {
|
|
subscription = subscription.updateStatus(SubscriptionStatus.create(status));
|
|
},
|
|
};
|
|
};
|
|
|
|
it.each<SubscriptionStatusType>([
|
|
'UNPAID',
|
|
'PAUSED',
|
|
'INCOMPLETE',
|
|
'INCOMPLETE_EXPIRED',
|
|
'CANCELED',
|
|
])('%s invalidates an existing key and forbids creation', async status => {
|
|
const { service, keys, setStatus } = setup();
|
|
await expect(service.validateAndGetUser('xped_live_test')).resolves.toMatchObject({
|
|
plan: 'GOLD',
|
|
});
|
|
keys.save.mockClear();
|
|
setStatus(status);
|
|
await expect(service.validateAndGetUser('xped_live_test')).resolves.toBeNull();
|
|
await expect(service.generateApiKey('user', 'org', { name: 'new' })).rejects.toBeInstanceOf(
|
|
ForbiddenException
|
|
);
|
|
expect(keys.save).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it.each<SubscriptionStatusType>(['ACTIVE', 'TRIALING', 'PAST_DUE'])(
|
|
'%s permits keys',
|
|
async status => {
|
|
const { service, setStatus } = setup();
|
|
setStatus(status);
|
|
await expect(service.validateAndGetUser('xped_live_test')).resolves.toMatchObject({
|
|
plan: 'GOLD',
|
|
});
|
|
await expect(service.generateApiKey('user', 'org', { name: 'new' })).resolves.toMatchObject({
|
|
name: 'new',
|
|
isActive: true,
|
|
});
|
|
}
|
|
);
|
|
});
|