fixing error of unit tests and also update Jenkinsfile

This commit is contained in:
hanzalawebdev 2025-03-24 10:59:54 +05:00
parent a51175c92a
commit 8e6df31dcf
7 changed files with 576 additions and 57 deletions

6
Jenkinsfile vendored
View File

@ -29,7 +29,7 @@ pipeline {
stage('Run Unit Tests') {
steps {
sh 'npm run test -- --coverage --reporters=jest-junit'
sh 'npm test'
}
}
@ -46,12 +46,12 @@ pipeline {
}
success {
echo 'Build completed successfully!'
junit 'reports/junit.xml'
junit '**/reports/junit.xml'
archiveArtifacts artifacts: 'reports/**', fingerprint: true
}
failure {
echo 'Build failed!'
junit 'reports/junit.xml' // Ensures test results are captured even on failure
junit '**/reports/junit.xml'
}
}
}

View File

@ -0,0 +1,404 @@
import { mock } from 'jest-mock-extended';
import { IntegrationService } from '@gitroom/nestjs-libraries/database/prisma/integrations/integration.service';
import { PostsService } from '@gitroom/nestjs-libraries/database/prisma/posts/posts.service';
import { SubscriptionService } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/subscription.service';
import { WebhooksService } from '@gitroom/nestjs-libraries/database/prisma/webhooks/webhooks.service';
import { PermissionsService } from './permissions.service';
import { AuthorizationActions, Sections } from './permissions.service';
import { Period, SubscriptionTier } from '@prisma/client';
// Mock of dependent services
const mockSubscriptionService = mock<SubscriptionService>();
const mockPostsService = mock<PostsService>();
const mockIntegrationService = mock<IntegrationService>();
const mockWebHookService = mock<WebhooksService>();
describe('PermissionsService', () => {
let service: PermissionsService;
// Initial setup before each test
beforeEach(() => {
process.env.STRIPE_PUBLISHABLE_KEY = 'mock_stripe_key';
service = new PermissionsService(
mockSubscriptionService,
mockPostsService,
mockIntegrationService,
mockWebHookService
);
});
// Reusable mocks for `getPackageOptions`
const baseSubscription = {
id: 'mock-id',
organizationId: 'mock-org-id',
subscriptionTier: 'PRO' as SubscriptionTier,
identifier: 'mock-identifier',
cancelAt: new Date(),
period: {} as Period,
totalChannels: 5,
isLifetime: false,
createdAt: new Date(),
updatedAt: new Date(),
deletedAt: null,
disabled: false,
tokenExpiration: new Date(),
profile: 'mock-profile',
postingTimes: '[]',
lastPostedAt: new Date(),
};
const baseOptions = {
channel: 10,
current: 'mock-current',
month_price: 20,
year_price: 200,
posts_per_month: 100,
team_members: true,
community_features: true,
featured_by_gitroom: true,
ai: true,
import_from_channels: true,
image_generator: false,
image_generation_count: 50,
public_api: true,
webhooks: 10,
autoPost: true // Added the missing property
};
const baseIntegration = {
id: 'mock-integration-id',
organizationId: 'mock-org-id',
createdAt: new Date(),
updatedAt: new Date(),
deletedAt: new Date(),
additionalSettings: '{}',
refreshNeeded: false,
refreshToken: 'mock-refresh-token',
name: 'Mock Integration',
internalId: 'mock-internal-id',
picture: 'mock-picture-url',
providerIdentifier: 'mock-provider',
token: 'mock-token',
type: 'social',
inBetweenSteps: false,
disabled: false,
tokenExpiration: new Date(),
profile: 'mock-profile',
postingTimes: '[]',
lastPostedAt: new Date(),
customInstanceDetails: 'mock-details',
customerId: 'mock-customer-id',
rootInternalId: 'mock-root-id',
customer: {
id: 'mock-customer-id',
createdAt: new Date(),
updatedAt: new Date(),
deletedAt: new Date(),
name: 'Mock Customer',
orgId: 'mock-org-id',
},
};
describe('check()', () => {
describe('Verification Bypass (64)', () => {
it('Bypass for Empty List', async () => {
// Setup: STRIPE_PUBLISHABLE_KEY exists and requestedPermission is empty
// Execution: call the check method with an empty list of permissions
const result = await service.check(
'mock-org-id',
new Date(),
'ADMIN',
[] // empty requestedPermission
);
// Verification: not requested, no authorization
expect(result.cannot(AuthorizationActions.Create, Sections.CHANNEL)).toBe(true);
});
it('Bypass for Missing Stripe', async () => {
// Setup: STRIPE_PUBLISHABLE_KEY does not exist
process.env.STRIPE_PUBLISHABLE_KEY = undefined;
// Necessary mock to avoid undefined filter error
jest.spyOn(mockIntegrationService, 'getIntegrationsList').mockResolvedValue([
{ ...baseIntegration, refreshNeeded: false }
]);
// Mock of getPackageOptions (even if not used due to bypass)
jest.spyOn(service, 'getPackageOptions').mockResolvedValue({
subscription: baseSubscription,
options: baseOptions,
});
// List of requested permissions
const requestedPermissions: Array<[AuthorizationActions, Sections]> = [
[AuthorizationActions.Read, Sections.CHANNEL],
[AuthorizationActions.Create, Sections.AI]
];
// Execution: call the check method
const result = await service.check(
'mock-org-id',
new Date(),
'USER',
requestedPermissions
);
// Verification: should allow all requested actions due to the absence of the Stripe key
expect(result.can(AuthorizationActions.Read, Sections.CHANNEL)).toBe(true);
expect(result.can(AuthorizationActions.Create, Sections.AI)).toBe(true);
});
it('No Bypass', async () => {
// List of requested permissions
const requestedPermissions: Array<[AuthorizationActions, Sections]> = [
[AuthorizationActions.Read, Sections.CHANNEL],
[AuthorizationActions.Create, Sections.AI]
];
// Mock of getPackageOptions to force a scenario without permissions
jest.spyOn(service, 'getPackageOptions').mockResolvedValue({
subscription: { ...baseSubscription, totalChannels: 0 },
options: {
...baseOptions,
channel: 0,
ai: false
},
});
// Mock of getIntegrationsList for the channel scenario
jest.spyOn(mockIntegrationService, 'getIntegrationsList').mockResolvedValue([
{ ...baseIntegration, refreshNeeded: false }
]);
// Execution: call the check method
const result = await service.check(
'mock-org-id',
new Date(),
'USER',
requestedPermissions
);
// Verification: should not allow the requested actions as there is no bypass
expect(result.can(AuthorizationActions.Read, Sections.CHANNEL)).toBe(false);
expect(result.can(AuthorizationActions.Create, Sections.AI)).toBe(false);
});
});
describe('Channel Permission (82/87)', () => {
it('All Conditions True', async () => {
// Mock of getPackageOptions to set channel limits
jest.spyOn(service, 'getPackageOptions').mockResolvedValue({
subscription: { ...baseSubscription, totalChannels: 10 },
options: { ...baseOptions, channel: 10 },
});
// Mock of getIntegrationsList to set existing channels
jest.spyOn(mockIntegrationService, 'getIntegrationsList').mockResolvedValue([
{ ...baseIntegration, refreshNeeded: false },
{ ...baseIntegration, refreshNeeded: false },
{ ...baseIntegration, refreshNeeded: false },
]);
// List of requested permissions
const requestedPermissions: Array<[AuthorizationActions, Sections]> = [
[AuthorizationActions.Create, Sections.CHANNEL]
];
// Execution: call the check method
const result = await service.check(
'mock-org-id',
new Date(),
'USER',
requestedPermissions
);
// Verification: should allow the requested action
expect(result.can(AuthorizationActions.Create, Sections.CHANNEL)).toBe(true);
});
it('Channel With Option Limit', async () => {
// Mock of getPackageOptions to set channel limits
jest.spyOn(service, 'getPackageOptions').mockResolvedValue({
subscription: { ...baseSubscription, totalChannels: 3 },
options: { ...baseOptions, channel: 10 },
});
// Mock of getIntegrationsList to set existing channels
jest.spyOn(mockIntegrationService, 'getIntegrationsList').mockResolvedValue([
{ ...baseIntegration, refreshNeeded: false },
{ ...baseIntegration, refreshNeeded: false },
{ ...baseIntegration, refreshNeeded: false },
]);
// List of requested permissions
const requestedPermissions: Array<[AuthorizationActions, Sections]> = [
[AuthorizationActions.Create, Sections.CHANNEL]
];
// Execution: call the check method
const result = await service.check(
'mock-org-id',
new Date(),
'USER',
requestedPermissions
);
// Verification: should allow the requested action
expect(result.can(AuthorizationActions.Create, Sections.CHANNEL)).toBe(true);
});
it('Channel With Subscription Limit', async () => {
// Mock of getPackageOptions to set channel limits
jest.spyOn(service, 'getPackageOptions').mockResolvedValue({
subscription: { ...baseSubscription, totalChannels: 10 },
options: { ...baseOptions, channel: 3 },
});
// Mock of getIntegrationsList to set existing channels
jest.spyOn(mockIntegrationService, 'getIntegrationsList').mockResolvedValue([
{ ...baseIntegration, refreshNeeded: false },
{ ...baseIntegration, refreshNeeded: false },
{ ...baseIntegration, refreshNeeded: false },
]);
// List of requested permissions
const requestedPermissions: Array<[AuthorizationActions, Sections]> = [
[AuthorizationActions.Create, Sections.CHANNEL]
];
// Execution: call the check method
const result = await service.check(
'mock-org-id',
new Date(),
'USER',
requestedPermissions
);
// Verification: should allow the requested action
expect(result.can(AuthorizationActions.Create, Sections.CHANNEL)).toBe(true);
});
it('Channel Without Available Limits', async () => {
// Mock of getPackageOptions to set channel limits
jest.spyOn(service, 'getPackageOptions').mockResolvedValue({
subscription: { ...baseSubscription, totalChannels: 3 },
options: { ...baseOptions, channel: 3 },
});
// Mock of getIntegrationsList to set existing channels
jest.spyOn(mockIntegrationService, 'getIntegrationsList').mockResolvedValue([
{ ...baseIntegration, refreshNeeded: false },
{ ...baseIntegration, refreshNeeded: false },
{ ...baseIntegration, refreshNeeded: false },
]);
// List of requested permissions
const requestedPermissions: Array<[AuthorizationActions, Sections]> = [
[AuthorizationActions.Create, Sections.CHANNEL]
];
// Execution: call the check method
const result = await service.check(
'mock-org-id',
new Date(),
'USER',
requestedPermissions
);
// Verification: should not allow the requested action
expect(result.can(AuthorizationActions.Create, Sections.CHANNEL)).toBe(false);
});
it('Section Different from Channel', async () => {
// Mock of getPackageOptions to set channel limits
jest.spyOn(service, 'getPackageOptions').mockResolvedValue({
subscription: { ...baseSubscription, totalChannels: 10 },
options: { ...baseOptions, channel: 10 },
});
// Mock of getIntegrationsList to set existing channels
jest.spyOn(mockIntegrationService, 'getIntegrationsList').mockResolvedValue([
{ ...baseIntegration, refreshNeeded: false },
{ ...baseIntegration, refreshNeeded: false },
{ ...baseIntegration, refreshNeeded: false },
]);
// List of requested permissions
const requestedPermissions: Array<[AuthorizationActions, Sections]> = [
[AuthorizationActions.Create, Sections.AI] // Requesting permission for AI instead of CHANNEL
];
// Execution: call the check method
const result = await service.check(
'mock-org-id',
new Date(),
'USER',
requestedPermissions
);
// Verification: should not allow the requested action in CHANNEL
expect(result.can(AuthorizationActions.Create, Sections.CHANNEL)).toBe(false);
});
});
describe('Monthly Posts Permission (97/110)', () => {
it('Posts Within Limit', async () => {
// Mock of getPackageOptions to set post limits
jest.spyOn(service, 'getPackageOptions').mockResolvedValue({
subscription: baseSubscription,
options: { ...baseOptions, posts_per_month: 100 },
});
// Mock of getSubscription
jest.spyOn(mockSubscriptionService, 'getSubscription').mockResolvedValue({
...baseSubscription,
createdAt: new Date(),
});
// Mock of countPostsFromDay to return quantity within the limit
jest.spyOn(mockPostsService, 'countPostsFromDay').mockResolvedValue(50);
// List of requested permissions
const requestedPermissions: Array<[AuthorizationActions, Sections]> = [
[AuthorizationActions.Create, Sections.POSTS_PER_MONTH]
];
// Execution: call the check method
const result = await service.check(
'mock-org-id',
new Date(),
'USER',
requestedPermissions
);
// Verification: should allow the requested action
expect(result.can(AuthorizationActions.Create, Sections.POSTS_PER_MONTH)).toBe(true);
});
it('Posts Exceed Limit', async () => {
// Mock of getPackageOptions to set post limits
jest.spyOn(service, 'getPackageOptions').mockResolvedValue({
subscription: baseSubscription,
options: { ...baseOptions, posts_per_month: 100 },
});
// Mock of getSubscription
jest.spyOn(mockSubscriptionService, 'getSubscription').mockResolvedValue({
...baseSubscription,
createdAt: new Date(),
});
// Mock of countPostsFromDay to return quantity above the limit
jest.spyOn(mockPostsService, 'countPostsFromDay').mockResolvedValue(150);
// List of requested permissions
const requestedPermissions: Array<[AuthorizationActions, Sections]> = [
[AuthorizationActions.Create, Sections.POSTS_PER_MONTH]
];
// Execution: call the check method
const result = await service.check(
'mock-org-id',
new Date(),
'USER',
requestedPermissions
);
// Verification: should not allow the requested action
expect(result.can(AuthorizationActions.Create, Sections.POSTS_PER_MONTH)).toBe(false);
});
it('Section Different with Posts Within Limit', async () => {
// Mock of getPackageOptions to set post limits
jest.spyOn(service, 'getPackageOptions').mockResolvedValue({
subscription: baseSubscription,
options: { ...baseOptions, posts_per_month: 100 },
});
// Mock of getSubscription
jest.spyOn(mockSubscriptionService, 'getSubscription').mockResolvedValue({
...baseSubscription,
createdAt: new Date(),
});
// Mock of countPostsFromDay to return quantity within the limit
jest.spyOn(mockPostsService, 'countPostsFromDay').mockResolvedValue(50);
// List of requested permissions
const requestedPermissions: Array<[AuthorizationActions, Sections]> = [
[AuthorizationActions.Create, Sections.AI] // Requesting permission for AI instead of POSTS_PER_MONTH
];
// Execution: call the check method
const result = await service.check(
'mock-org-id',
new Date(),
'USER',
requestedPermissions
);
// Verification: should not allow the requested action in POSTS_PER_MONTH
expect(result.can(AuthorizationActions.Create, Sections.POSTS_PER_MONTH)).toBe(false);
});
});
});
});

View File

@ -2,4 +2,4 @@ import { getJestProjects } from '@nx/jest';
export default {
projects: getJestProjects(),
};
};

View File

@ -1,6 +1,30 @@
import { Redis } from 'ioredis';
export const ioRedis = new Redis(process.env.REDIS_URL!, {
maxRetriesPerRequest: null,
connectTimeout: 10000
});
// Create a mock Redis implementation for testing environments
class MockRedis {
private data: Map<string, any> = new Map();
async get(key: string) {
return this.data.get(key);
}
async set(key: string, value: any) {
this.data.set(key, value);
return 'OK';
}
async del(key: string) {
this.data.delete(key);
return 1;
}
// Add other Redis methods as needed for your tests
}
// Use real Redis if REDIS_URL is defined, otherwise use MockRedis
export const ioRedis = process.env.REDIS_URL
? new Redis(process.env.REDIS_URL, {
maxRetriesPerRequest: null,
connectTimeout: 10000
})
: (new MockRedis() as unknown as Redis); // Type cast to Redis to maintain interface compatibility

140
package-lock.json generated
View File

@ -48,7 +48,7 @@
"@nx/webpack": "19.7.2",
"@nx/workspace": "19.7.2",
"@postiz/wallets": "^0.0.1",
"@prisma/client": "^6.4.1",
"@prisma/client": "^6.5.0",
"@solana/wallet-adapter-react": "^0.15.35",
"@solana/wallet-adapter-react-ui": "^0.9.35",
"@swc/helpers": "0.5.13",
@ -199,10 +199,11 @@
"jest-environment-jsdom": "29.7.0",
"jest-environment-node": "^29.4.1",
"jest-junit": "^16.0.0",
"jest-mock-extended": "^4.0.0-beta1",
"jsdom": "~22.1.0",
"postcss": "8.4.38",
"prettier": "^2.6.2",
"prisma": "^5.8.1",
"prisma": "^6.5.0",
"react-refresh": "^0.10.0",
"sass": "1.62.1",
"ts-jest": "^29.1.0",
@ -10846,9 +10847,9 @@
}
},
"node_modules/@prisma/client": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.4.1.tgz",
"integrity": "sha512-A7Mwx44+GVZVexT5e2GF/WcKkEkNNKbgr059xpr5mn+oUm2ZW1svhe+0TRNBwCdzhfIZ+q23jEgsNPvKD9u+6g==",
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.5.0.tgz",
"integrity": "sha512-M6w1Ql/BeiGoZmhMdAZUXHu5sz5HubyVcKukbLs3l0ELcQb8hTUJxtGEChhv4SVJ0QJlwtLnwOLgIRQhpsm9dw==",
"hasInstallScript": true,
"license": "Apache-2.0",
"engines": {
@ -10867,49 +10868,65 @@
}
}
},
"node_modules/@prisma/config": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.5.0.tgz",
"integrity": "sha512-sOH/2Go9Zer67DNFLZk6pYOHj+rumSb0VILgltkoxOjYnlLqUpHPAN826vnx8HigqnOCxj9LRhT6U7uLiIIWgw==",
"devOptional": true,
"license": "Apache-2.0",
"dependencies": {
"esbuild": ">=0.12 <1",
"esbuild-register": "3.6.0"
}
},
"node_modules/@prisma/debug": {
"version": "5.22.0",
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.22.0.tgz",
"integrity": "sha512-AUt44v3YJeggO2ZU5BkXI7M4hu9BF2zzH2iF2V5pyXT/lRTyWiElZ7It+bRH1EshoMRxHgpYg4VB6rCM+mG5jQ==",
"devOptional": true
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.5.0.tgz",
"integrity": "sha512-fc/nusYBlJMzDmDepdUtH9aBsJrda2JNErP9AzuHbgUEQY0/9zQYZdNlXmKoIWENtio+qarPNe/+DQtrX5kMcQ==",
"devOptional": true,
"license": "Apache-2.0"
},
"node_modules/@prisma/engines": {
"version": "5.22.0",
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.22.0.tgz",
"integrity": "sha512-UNjfslWhAt06kVL3CjkuYpHAWSO6L4kDCVPegV6itt7nD1kSJavd3vhgAEhjglLJJKEdJ7oIqDJ+yHk6qO8gPA==",
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.5.0.tgz",
"integrity": "sha512-FVPQYHgOllJklN9DUyujXvh3hFJCY0NX86sDmBErLvoZjy2OXGiZ5FNf3J/C4/RZZmCypZBYpBKEhx7b7rEsdw==",
"devOptional": true,
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
"@prisma/debug": "5.22.0",
"@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2",
"@prisma/fetch-engine": "5.22.0",
"@prisma/get-platform": "5.22.0"
"@prisma/debug": "6.5.0",
"@prisma/engines-version": "6.5.0-73.173f8d54f8d52e692c7e27e72a88314ec7aeff60",
"@prisma/fetch-engine": "6.5.0",
"@prisma/get-platform": "6.5.0"
}
},
"node_modules/@prisma/engines-version": {
"version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2",
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2.tgz",
"integrity": "sha512-2PTmxFR2yHW/eB3uqWtcgRcgAbG1rwG9ZriSvQw+nnb7c4uCr3RAcGMb6/zfE88SKlC1Nj2ziUvc96Z379mHgQ==",
"devOptional": true
"version": "6.5.0-73.173f8d54f8d52e692c7e27e72a88314ec7aeff60",
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.5.0-73.173f8d54f8d52e692c7e27e72a88314ec7aeff60.tgz",
"integrity": "sha512-iK3EmiVGFDCmXjSpdsKGNqy9hOdLnvYBrJB61far/oP03hlIxrb04OWmDjNTwtmZ3UZdA5MCvI+f+3k2jPTflQ==",
"devOptional": true,
"license": "Apache-2.0"
},
"node_modules/@prisma/fetch-engine": {
"version": "5.22.0",
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.22.0.tgz",
"integrity": "sha512-bkrD/Mc2fSvkQBV5EpoFcZ87AvOgDxbG99488a5cexp5Ccny+UM6MAe/UFkUC0wLYD9+9befNOqGiIJhhq+HbA==",
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.5.0.tgz",
"integrity": "sha512-3LhYA+FXP6pqY8FLHCjewyE8pGXXJ7BxZw2rhPq+CZAhvflVzq4K8Qly3OrmOkn6wGlz79nyLQdknyCG2HBTuA==",
"devOptional": true,
"license": "Apache-2.0",
"dependencies": {
"@prisma/debug": "5.22.0",
"@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2",
"@prisma/get-platform": "5.22.0"
"@prisma/debug": "6.5.0",
"@prisma/engines-version": "6.5.0-73.173f8d54f8d52e692c7e27e72a88314ec7aeff60",
"@prisma/get-platform": "6.5.0"
}
},
"node_modules/@prisma/get-platform": {
"version": "5.22.0",
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.22.0.tgz",
"integrity": "sha512-pHhpQdr1UPFpt+zFfnPazhulaZYCUqeIcPpJViYoq9R+D/yw4fjE+CtnsnKzPYm0ddUbeXUzjGVGIRVgPDCk4Q==",
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.5.0.tgz",
"integrity": "sha512-xYcvyJwNMg2eDptBYFqFLUCfgi+wZLcj6HDMsj0Qw0irvauG4IKmkbywnqwok0B+k+W+p+jThM2DKTSmoPCkzw==",
"devOptional": true,
"license": "Apache-2.0",
"dependencies": {
"@prisma/debug": "5.22.0"
"@prisma/debug": "6.5.0"
}
},
"node_modules/@project-serum/sol-wallet-adapter": {
@ -24177,6 +24194,19 @@
"@esbuild/win32-x64": "0.21.5"
}
},
"node_modules/esbuild-register": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz",
"integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"debug": "^4.3.4"
},
"peerDependencies": {
"esbuild": ">=0.12 <1"
}
},
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@ -30314,6 +30344,21 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-mock-extended": {
"version": "4.0.0-beta1",
"resolved": "https://registry.npmjs.org/jest-mock-extended/-/jest-mock-extended-4.0.0-beta1.tgz",
"integrity": "sha512-MYcI0wQu3ceNhqKoqAJOdEfsVMamAFqDTjoLN5Y45PAG3iIm4WGnhOu0wpMjlWCexVPO71PMoNir9QrGXrnIlw==",
"dev": true,
"license": "MIT",
"dependencies": {
"ts-essentials": "^10.0.2"
},
"peerDependencies": {
"@jest/globals": "^28.0.0 || ^29.0.0",
"jest": "^24.0.0 || ^25.0.0 || ^26.0.0 || ^27.0.0 || ^28.0.0 || ^29.0.0",
"typescript": "^3.0.0 || ^4.0.0 || ^5.0.0"
}
},
"node_modules/jest-pnp-resolver": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
@ -39383,22 +39428,32 @@
"dev": true
},
"node_modules/prisma": {
"version": "5.22.0",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-5.22.0.tgz",
"integrity": "sha512-vtpjW3XuYCSnMsNVBjLMNkTj6OZbudcPPTPYHqX0CJfpcdWciI1dM8uHETwmDxxiqEwCIE6WvXucWUetJgfu/A==",
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-6.5.0.tgz",
"integrity": "sha512-yUGXmWqv5F4PByMSNbYFxke/WbnyTLjnJ5bKr8fLkcnY7U5rU9rUTh/+Fja+gOrRxEgtCbCtca94IeITj4j/pg==",
"devOptional": true,
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
"@prisma/engines": "5.22.0"
"@prisma/config": "6.5.0",
"@prisma/engines": "6.5.0"
},
"bin": {
"prisma": "build/index.js"
},
"engines": {
"node": ">=16.13"
"node": ">=18.18"
},
"optionalDependencies": {
"fsevents": "2.3.3"
},
"peerDependencies": {
"typescript": ">=5.1.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/prismjs": {
@ -45315,6 +45370,21 @@
"node": ">=6.10"
}
},
"node_modules/ts-essentials": {
"version": "10.0.4",
"resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-10.0.4.tgz",
"integrity": "sha512-lwYdz28+S4nicm+jFi6V58LaAIpxzhg9rLdgNC1VsdP/xiFBseGhF1M/shwCk6zMmwahBZdXcl34LVHrEang3A==",
"dev": true,
"license": "MIT",
"peerDependencies": {
"typescript": ">=4.5.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/ts-interface-checker": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",

View File

@ -30,12 +30,7 @@
"docker-build": "./var/docker/docker-build.sh",
"docker-create": "./var/docker/docker-create.sh",
"postinstall": "npm run update-plugins && npm run prisma-generate",
"test": "npx nx run-many --target=test --projects=frontend,backend,workers,cron,commands --parallel=5",
"test:frontend": "npx nx run frontend:test",
"test:backend": "npx nx run backend:test",
"test:workers": "npx nx run workers:test",
"test:cron": "npx nx run cron:test",
"test:commands": "npx nx run commands:test"
"test": "jest --coverage --detectOpenHandles --reporters=default --reporters=jest-junit"
},
"private": true,
"dependencies": {
@ -77,7 +72,7 @@
"@nx/webpack": "19.7.2",
"@nx/workspace": "19.7.2",
"@postiz/wallets": "^0.0.1",
"@prisma/client": "^6.4.1",
"@prisma/client": "^6.5.0",
"@solana/wallet-adapter-react": "^0.15.35",
"@solana/wallet-adapter-react-ui": "^0.9.35",
"@swc/helpers": "0.5.13",
@ -228,10 +223,11 @@
"jest-environment-jsdom": "29.7.0",
"jest-environment-node": "^29.4.1",
"jest-junit": "^16.0.0",
"jest-mock-extended": "^4.0.0-beta1",
"jsdom": "~22.1.0",
"postcss": "8.4.38",
"prettier": "^2.6.2",
"prisma": "^5.8.1",
"prisma": "^6.5.0",
"react-refresh": "^0.10.0",
"sass": "1.62.1",
"ts-jest": "^29.1.0",
@ -243,10 +239,8 @@
"volta": {
"node": "20.17.0"
},
"jest": {
"reporters": [
"default",
["jest-junit", { "outputDirectory": "reports", "outputName": "junit.xml" }]
]
}
"jest-junit": {
"outputDirectory": "./reports",
"outputName": "junit.xml"
}
}

27
reports/junit.xml Normal file
View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="jest tests" tests="11" failures="0" errors="0" time="31.615">
<testsuite name="PermissionsService" errors="0" failures="0" skipped="0" timestamp="2025-03-24T05:53:33" time="31.496" tests="11">
<testcase classname="PermissionsService check() Verification Bypass (64) Bypass for Empty List" name="PermissionsService check() Verification Bypass (64) Bypass for Empty List" time="0.01">
</testcase>
<testcase classname="PermissionsService check() Verification Bypass (64) Bypass for Missing Stripe" name="PermissionsService check() Verification Bypass (64) Bypass for Missing Stripe" time="0.003">
</testcase>
<testcase classname="PermissionsService check() Verification Bypass (64) No Bypass" name="PermissionsService check() Verification Bypass (64) No Bypass" time="0.002">
</testcase>
<testcase classname="PermissionsService check() Channel Permission (82/87) All Conditions True" name="PermissionsService check() Channel Permission (82/87) All Conditions True" time="0.003">
</testcase>
<testcase classname="PermissionsService check() Channel Permission (82/87) Channel With Option Limit" name="PermissionsService check() Channel Permission (82/87) Channel With Option Limit" time="0.003">
</testcase>
<testcase classname="PermissionsService check() Channel Permission (82/87) Channel With Subscription Limit" name="PermissionsService check() Channel Permission (82/87) Channel With Subscription Limit" time="0.002">
</testcase>
<testcase classname="PermissionsService check() Channel Permission (82/87) Channel Without Available Limits" name="PermissionsService check() Channel Permission (82/87) Channel Without Available Limits" time="0.003">
</testcase>
<testcase classname="PermissionsService check() Channel Permission (82/87) Section Different from Channel" name="PermissionsService check() Channel Permission (82/87) Section Different from Channel" time="0.003">
</testcase>
<testcase classname="PermissionsService check() Monthly Posts Permission (97/110) Posts Within Limit" name="PermissionsService check() Monthly Posts Permission (97/110) Posts Within Limit" time="0.008">
</testcase>
<testcase classname="PermissionsService check() Monthly Posts Permission (97/110) Posts Exceed Limit" name="PermissionsService check() Monthly Posts Permission (97/110) Posts Exceed Limit" time="0.003">
</testcase>
<testcase classname="PermissionsService check() Monthly Posts Permission (97/110) Section Different with Posts Within Limit" name="PermissionsService check() Monthly Posts Permission (97/110) Section Different with Posts Within Limit" time="0.003">
</testcase>
</testsuite>
</testsuites>