xpeditis2.0/apps/backend/src/application/api-keys/api-keys-entitlement.security.spec.ts

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,
});
}
);
});