mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 21:00:31 +00:00
feat(nestjs): migrate to NestJS
This commit is contained in:
59
packages/server/test/auth.e2e-spec.ts
Normal file
59
packages/server/test/auth.e2e-spec.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import * as request from 'supertest';
|
||||
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app } from './init-app-test';
|
||||
|
||||
describe('Authentication (e2e)', () => {
|
||||
beforeAll(async () => {});
|
||||
|
||||
it('should signup success', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/auth/signup')
|
||||
.send({
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
email: faker.internet.email(),
|
||||
password: '123123123',
|
||||
})
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('should signin success', () => {
|
||||
const signupBody = {
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
email: faker.internet.email(),
|
||||
password: '123123123',
|
||||
};
|
||||
const response = request(app.getHttpServer())
|
||||
.post('/auth/signup')
|
||||
.send(signupBody);
|
||||
|
||||
request(app.getHttpServer())
|
||||
.post('/auth/signin')
|
||||
.send({
|
||||
email: signupBody.email,
|
||||
password: signupBody.password,
|
||||
})
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('should send reset password success', () => {
|
||||
const signupBody = {
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
email: faker.internet.email(),
|
||||
password: '123123123',
|
||||
};
|
||||
const signupResponse = request(app.getHttpServer())
|
||||
.post('/auth/signup')
|
||||
.send(signupBody);
|
||||
|
||||
request(app.getHttpServer())
|
||||
.post('/auth/send_reset_password')
|
||||
.send({
|
||||
email: signupBody.email,
|
||||
})
|
||||
.expect(201);
|
||||
});
|
||||
});
|
||||
97
packages/server/test/bank-rules.e2e-spec.ts
Normal file
97
packages/server/test/bank-rules.e2e-spec.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
const requestBankRule = () => ({
|
||||
name: faker.company.name(),
|
||||
order: 1,
|
||||
applyIfAccountId: 1001,
|
||||
applyIfTransactionType: 'deposit',
|
||||
conditions: [
|
||||
{
|
||||
field: 'description',
|
||||
comparator: 'contains',
|
||||
value: faker.finance.transactionDescription(),
|
||||
},
|
||||
],
|
||||
assignCategory: 'Deposit',
|
||||
assignAccountId: 1002,
|
||||
assignPayee: faker.company.name(),
|
||||
assignMemo: faker.lorem.sentence(),
|
||||
});
|
||||
|
||||
describe('Bank Rules (e2e)', () => {
|
||||
it('/banking/rules (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/banking/rules')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestBankRule())
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/banking/rules/:id (PUT)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/banking/rules')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestBankRule());
|
||||
|
||||
const ruleId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/banking/rules/${ruleId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestBankRule())
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/banking/rules/:id (DELETE)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/banking/rules')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestBankRule());
|
||||
|
||||
const ruleId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/banking/rules/${ruleId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/banking/rules/:id (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/banking/rules')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestBankRule());
|
||||
|
||||
const ruleId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/banking/rules/${ruleId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/banking/rules (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/banking/rules')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestBankRule());
|
||||
|
||||
const ruleId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/banking/rules/${ruleId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
66
packages/server/test/banking-transactions.e2e-spec.ts
Normal file
66
packages/server/test/banking-transactions.e2e-spec.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
const createOwnerContributionTransaction = () => ({
|
||||
date: '2024-01-01',
|
||||
transactionNumber: faker.string.alphanumeric(10),
|
||||
referenceNo: faker.string.alphanumeric(8),
|
||||
transactionType: 'owner_contribution',
|
||||
description: faker.lorem.sentence(),
|
||||
amount: faker.number.float({ min: 100, max: 10000, precision: 2 }),
|
||||
// exchangeRate: 1,
|
||||
// currencyCode: 'USD',
|
||||
creditAccountId: 1014,
|
||||
cashflowAccountId: 1000,
|
||||
publish: true,
|
||||
branchId: 1,
|
||||
// plaidTransactionId: faker.string.uuid()
|
||||
});
|
||||
|
||||
describe('Banking Transactions (e2e)', () => {
|
||||
it('/banking/transactions (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/banking/transactions')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(createOwnerContributionTransaction())
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/banking/transactions/:id (GET)', async () => {
|
||||
const transaction = createOwnerContributionTransaction();
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/banking/transactions')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(transaction)
|
||||
.expect(201);
|
||||
|
||||
const transactionId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/banking/transactions/${transactionId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/banking/transactions/:id (DELETE)', async () => {
|
||||
const transaction = createOwnerContributionTransaction();
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/banking/transactions')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(transaction)
|
||||
.expect(201);
|
||||
|
||||
const transactionId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/banking/transactions/${transactionId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
77
packages/server/test/branches.e2e-spec.ts
Normal file
77
packages/server/test/branches.e2e-spec.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
describe('Branches (e2e)', () => {
|
||||
it('/branches (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/branches')
|
||||
.set('organization-id', orgainzationId)
|
||||
.send({
|
||||
name: faker.commerce.productName(),
|
||||
code: faker.string.alpha(4),
|
||||
})
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/branches/:id (DELETE)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/branches')
|
||||
.set('organization-id', orgainzationId)
|
||||
.send({
|
||||
name: faker.commerce.productName(),
|
||||
code: faker.string.alpha(4),
|
||||
});
|
||||
const branchId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/branches/${branchId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/branches/:id (PUT)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/branches')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
name: faker.commerce.productName(),
|
||||
code: faker.string.alpha(4),
|
||||
});
|
||||
const branchId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/branches/${branchId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/branches/:id (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/branches')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
name: faker.commerce.productName(),
|
||||
code: faker.string.alpha(4),
|
||||
});
|
||||
const branchId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/branches/${branchId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/branches (GET)', async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/branches')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
107
packages/server/test/credit-notes.e2e-spec.ts
Normal file
107
packages/server/test/credit-notes.e2e-spec.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
import * as request from 'supertest';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
import { faker } from '@faker-js/faker';
|
||||
|
||||
let customerId;
|
||||
let itemId;
|
||||
|
||||
const requestCreditNote = () => ({
|
||||
customerId: customerId,
|
||||
creditNoteDate: '2020-02-02',
|
||||
branchId: 1,
|
||||
warehouseId: 1,
|
||||
entries: [
|
||||
{
|
||||
index: 1,
|
||||
itemId: itemId,
|
||||
quantity: 1,
|
||||
rate: 1000,
|
||||
description: "It's description here.",
|
||||
},
|
||||
],
|
||||
discount: '100',
|
||||
discountType: 'amount',
|
||||
});
|
||||
|
||||
describe('Credit Notes (e2e)', () => {
|
||||
beforeAll(async () => {
|
||||
const customer = await request(app.getHttpServer())
|
||||
.post('/customers')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({ displayName: 'Test Customer' });
|
||||
|
||||
customerId = customer.body.id;
|
||||
|
||||
const item = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
name: faker.commerce.productName(),
|
||||
sellable: true,
|
||||
purchasable: true,
|
||||
sellAccountId: 1026,
|
||||
costAccountId: 1019,
|
||||
costPrice: 100,
|
||||
sellPrice: 100,
|
||||
});
|
||||
itemId = parseInt(item.text, 10);
|
||||
});
|
||||
|
||||
it('/credit-notes (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/credit-notes')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestCreditNote())
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/credit-notes/:id (DELETE)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/credit-notes')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestCreditNote());
|
||||
const creditNoteId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/credit-notes/${creditNoteId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/credit-notes/:id (PUT)', async () => {
|
||||
const creditNote = requestCreditNote();
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/credit-notes')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(creditNote);
|
||||
const creditNoteId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/credit-notes/${creditNoteId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(creditNote)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/credit-notes/:id/open (POST)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/credit-notes')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestCreditNote());
|
||||
const creditNoteId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/credit-notes/${creditNoteId}/open`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
89
packages/server/test/customers.e2e-spec.ts
Normal file
89
packages/server/test/customers.e2e-spec.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
describe('Customers (e2e)', () => {
|
||||
it('/customers (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/customers')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
customerType: 'business',
|
||||
displayName: faker.commerce.productName(),
|
||||
email: faker.internet.email(),
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
})
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/customers/:id (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/customers')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
customerType: 'business',
|
||||
displayName: faker.commerce.productName(),
|
||||
email: faker.internet.email(),
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
});
|
||||
const customerId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/customers/${customerId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/customers/:id (DELETE)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/customers')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
customerType: 'business',
|
||||
displayName: faker.commerce.productName(),
|
||||
email: faker.internet.email(),
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
});
|
||||
const customerId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/customers/${customerId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/customers/:id (PUT)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/customers')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
customerType: 'business',
|
||||
displayName: faker.commerce.productName(),
|
||||
email: faker.internet.email(),
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
});
|
||||
const customerId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/customers/${customerId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
displayName: faker.commerce.productName(),
|
||||
email: faker.internet.email(),
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
})
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
80
packages/server/test/expenses.e2e-spec.ts
Normal file
80
packages/server/test/expenses.e2e-spec.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
const makeExpenseRequest = () => ({
|
||||
exchangeRate: 1,
|
||||
description: faker.lorem.sentence(),
|
||||
paymentAccountId: 1000,
|
||||
referenceNo: faker.string.alphanumeric(10),
|
||||
publish: true,
|
||||
paymentDate: faker.date.recent(),
|
||||
categories: [
|
||||
{
|
||||
expenseAccountId: 1021,
|
||||
amount: faker.number.float({ min: 10, max: 1000, precision: 0.01 }),
|
||||
description: faker.lorem.sentence(),
|
||||
},
|
||||
],
|
||||
branchId: 1,
|
||||
});
|
||||
|
||||
describe('Expenses (e2e)', () => {
|
||||
it('/expenses (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/expenses')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeExpenseRequest())
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/expenses/:id (PUT)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/expenses')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeExpenseRequest());
|
||||
|
||||
const expenseId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/expenses/${expenseId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeExpenseRequest())
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/expenses/:id (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/expenses')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeExpenseRequest());
|
||||
|
||||
const expenseId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/expenses/${expenseId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/expenses/:id (DELETE)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/expenses')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeExpenseRequest());
|
||||
|
||||
const expenseId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/expenses/${expenseId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
40
packages/server/test/init-app-test.ts
Normal file
40
packages/server/test/init-app-test.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import * as request from 'supertest';
|
||||
import { INestApplication, Logger } from '@nestjs/common';
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { AppModule } from '../src/modules/App/App.module';
|
||||
|
||||
let app: INestApplication;
|
||||
|
||||
const email = 'ahmed@sa1234dsad.com';
|
||||
const password = '123123123';
|
||||
|
||||
let orgainzationId = 'hpgpqfqom8zic574';
|
||||
let authenticationToken = '';
|
||||
let AuthorizationHeader = '';
|
||||
|
||||
beforeAll(async () => {
|
||||
const moduleFixture: TestingModule = await Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
}).compile();
|
||||
|
||||
app = moduleFixture.createNestApplication();
|
||||
await app.init();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
// jest.retryTimes(3, { logErrorsBeforeRetry: true });
|
||||
|
||||
beforeAll(async () => {
|
||||
const signinResponse = await request(app.getHttpServer())
|
||||
.post('/auth/signin')
|
||||
.send({ email, password })
|
||||
.expect(201);
|
||||
|
||||
authenticationToken = signinResponse.body.access_token;
|
||||
AuthorizationHeader = `Bearer ${authenticationToken}`;
|
||||
})
|
||||
|
||||
export { app, orgainzationId, authenticationToken, AuthorizationHeader };
|
||||
124
packages/server/test/inventory-adjustment.e2e-spec.ts
Normal file
124
packages/server/test/inventory-adjustment.e2e-spec.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
export const createInventoryAdjustment = ({ itemId }) => ({
|
||||
date: '2020-01-01',
|
||||
type: 'increment',
|
||||
adjustmentAccountId: 1001,
|
||||
reason: faker.lorem.sentence(),
|
||||
description: faker.lorem.paragraph(),
|
||||
referenceNo: faker.string.alphanumeric(10),
|
||||
itemId,
|
||||
quantity: faker.number.int({ min: 1, max: 100 }),
|
||||
cost: faker.number.float({ min: 1, max: 1000 }),
|
||||
publish: true,
|
||||
|
||||
warehouseId: 1,
|
||||
branchId: 1,
|
||||
});
|
||||
|
||||
const makeItemRequest = () => ({
|
||||
name: faker.commerce.productName(),
|
||||
type: 'inventory',
|
||||
inventory_account_id: 1007,
|
||||
});
|
||||
|
||||
describe('Inventory Adjustments (e2e)', () => {
|
||||
it('/inventory-adjustments/quick (POST)', async () => {
|
||||
const itemResponse = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeItemRequest())
|
||||
.expect(201);
|
||||
|
||||
const itemId = itemResponse.text;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.post('/inventory-adjustments/quick')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(createInventoryAdjustment({ itemId }))
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/inventory-adjustments/:id (DELETE)', async () => {
|
||||
const itemResponse = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeItemRequest())
|
||||
.expect(201);
|
||||
|
||||
const itemId = itemResponse.text;
|
||||
|
||||
const inventoryAdjustmentResponse = await request(app.getHttpServer())
|
||||
.post('/inventory-adjustments/quick')
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.send(createInventoryAdjustment({ itemId }))
|
||||
.expect(201);
|
||||
|
||||
const inventoryAdjustmentId = inventoryAdjustmentResponse.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/inventory-adjustments/${inventoryAdjustmentId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/inventory-adjustments/:id (GET)', async () => {
|
||||
const itemResponse = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeItemRequest())
|
||||
.expect(201);
|
||||
|
||||
const itemId = itemResponse.text;
|
||||
const inventoryAdjustmentResponse = await request(app.getHttpServer())
|
||||
.post('/inventory-adjustments/quick')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(createInventoryAdjustment({ itemId }))
|
||||
.expect(201);
|
||||
|
||||
const inventoryAdjustmentId = inventoryAdjustmentResponse.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/inventory-adjustments/${inventoryAdjustmentId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/inventory-adjustments/:id/publish (POST)', async () => {
|
||||
const itemResponse = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeItemRequest())
|
||||
.expect(201);
|
||||
|
||||
const itemId = itemResponse.text;
|
||||
const inventoryAdjustmentResponse = await request(app.getHttpServer())
|
||||
.post('/inventory-adjustments/quick')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
...createInventoryAdjustment({ itemId }),
|
||||
publish: false,
|
||||
})
|
||||
.expect(201);
|
||||
|
||||
const inventoryAdjustmentId = inventoryAdjustmentResponse.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/inventory-adjustments/${inventoryAdjustmentId}/publish`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
53
packages/server/test/item-categories.e2e-spec.ts
Normal file
53
packages/server/test/item-categories.e2e-spec.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
describe('Item Categories(e2e)', () => {
|
||||
it('/item-categories (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/item-categories')
|
||||
.set('organization-id', orgainzationId)
|
||||
.send({
|
||||
name: faker.person.fullName(),
|
||||
description: faker.lorem.sentence(),
|
||||
})
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/item-categories/:id (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/item-categories')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
name: faker.person.fullName(),
|
||||
description: faker.lorem.sentence(),
|
||||
});
|
||||
const itemCategoryId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/item-categories/${itemCategoryId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/item-categories/:id (DELETE)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/item-categories')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
name: faker.person.fullName(),
|
||||
description: faker.lorem.sentence(),
|
||||
});
|
||||
|
||||
const itemCategoryId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/item-categories/${itemCategoryId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
148
packages/server/test/items.e2e-spec.ts
Normal file
148
packages/server/test/items.e2e-spec.ts
Normal file
@@ -0,0 +1,148 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import {
|
||||
app,
|
||||
authenticationToken,
|
||||
AuthorizationHeader,
|
||||
orgainzationId,
|
||||
} from './init-app-test';
|
||||
|
||||
const makeItemRequest = () => ({
|
||||
name: faker.commerce.productName(),
|
||||
type: 'service',
|
||||
});
|
||||
|
||||
describe('Items (e2e)', () => {
|
||||
it('/items (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', `Bearer ${authenticationToken}`)
|
||||
.send(makeItemRequest())
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/items/:id (PUT)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeItemRequest());
|
||||
const itemId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/items/${itemId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeItemRequest());
|
||||
});
|
||||
|
||||
it('/items/:id/inactivate (PATCH)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeItemRequest());
|
||||
const itemId = response.text;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.patch(`/items/${itemId}/inactivate`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/items/:id/activate (PATCH)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeItemRequest());
|
||||
const itemId = response.text;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.patch(`/items/${itemId}/activate`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/items/:id (DELETE)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeItemRequest());
|
||||
const itemId = response.text;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/items/${itemId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/items/:id/invoices (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeItemRequest());
|
||||
|
||||
const itemId = response.text;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/items/${itemId}/invoices`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/items/:id/bills (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeItemRequest());
|
||||
|
||||
const itemId = response.text;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/items/${itemId}/bills`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/items/:id/estimates (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeItemRequest());
|
||||
|
||||
const itemId = response.text;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/items/${itemId}/estimates`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/items/:id/receipts (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeItemRequest());
|
||||
|
||||
const itemId = response.text;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/items/${itemId}/receipts`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
14
packages/server/test/jest-e2e.json
Normal file
14
packages/server/test/jest-e2e.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"moduleFileExtensions": ["js", "json", "ts"],
|
||||
"rootDir": ".",
|
||||
"testEnvironment": "node",
|
||||
"testRegex": ".e2e-spec.ts$",
|
||||
"transform": {
|
||||
"^.+\\.(t|j)s$": "ts-jest"
|
||||
},
|
||||
"moduleNameMapper": {
|
||||
"^@/(.*)$": "<rootDir>/../src/$1"
|
||||
},
|
||||
"maxWorkers": 1,
|
||||
"maxConcurrency": 1
|
||||
}
|
||||
104
packages/server/test/manual-journal.e2e-spec.ts
Normal file
104
packages/server/test/manual-journal.e2e-spec.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
const makeManualJournalRequest = () => ({
|
||||
date: '2022-06-01',
|
||||
reference: faker.string.uuid(),
|
||||
journalNumber: faker.string.uuid(),
|
||||
publish: false,
|
||||
entries: [
|
||||
{
|
||||
index: 1,
|
||||
credit: 1000,
|
||||
debit: 0,
|
||||
accountId: 1003,
|
||||
},
|
||||
{
|
||||
index: 2,
|
||||
credit: 0,
|
||||
debit: 1000,
|
||||
accountId: 1004,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
describe.only('Manual Journals (e2e)', () => {
|
||||
it('/manual-journals (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/manual-journals')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeManualJournalRequest())
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/manual-journals/:id (DELETE)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/manual-journals')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeManualJournalRequest());
|
||||
|
||||
const journalId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/manual-journals/${journalId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send()
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/manual-journals/:id (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/manual-journals')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeManualJournalRequest());
|
||||
|
||||
const journalId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/manual-journals/${journalId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send()
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/manual-journals/:id (PUT)', async () => {
|
||||
const manualJournal = makeManualJournalRequest();
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/manual-journals')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(manualJournal);
|
||||
|
||||
const journalId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/manual-journals/${journalId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(manualJournal)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/manual-journals/:id/publish (PUT)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/manual-journals')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeManualJournalRequest());
|
||||
|
||||
const journalId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/manual-journals/${journalId}/publish`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send()
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
74
packages/server/test/organization.e2e-spec.ts
Normal file
74
packages/server/test/organization.e2e-spec.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app } from './init-app-test';
|
||||
|
||||
let signinResponse = null;
|
||||
let signupResponse = null;
|
||||
|
||||
describe('Organization (e2e)', () => {
|
||||
beforeAll(async () => {
|
||||
const signupBody = {
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
email: faker.internet.email(),
|
||||
password: '123123123',
|
||||
};
|
||||
signupResponse = await request(app.getHttpServer())
|
||||
.post('/auth/signup')
|
||||
.send(signupBody);
|
||||
|
||||
signinResponse = await request(app.getHttpServer())
|
||||
.post('/auth/signin')
|
||||
.send({
|
||||
email: signupBody.email,
|
||||
password: signupBody.password,
|
||||
});
|
||||
});
|
||||
|
||||
it('/organization (POST)', async () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/organization/build')
|
||||
.set('Accept', 'application/json')
|
||||
.set('Content-Type', 'application/json')
|
||||
.set('Authorization', `Bearer ${signinResponse.body.access_token}`)
|
||||
.set('organization-id', signupResponse.body.organization_id)
|
||||
.send({
|
||||
name: 'BIGCAPITAL, INC',
|
||||
baseCurrency: 'USD',
|
||||
location: 'US',
|
||||
language: 'en',
|
||||
fiscalYear: 'march',
|
||||
timezone: 'US/Central',
|
||||
})
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/organization (GET)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/organization/current')
|
||||
.set('Accept', 'application/json')
|
||||
.set('Content-Type', 'application/json')
|
||||
.set('Authorization', `Bearer ${signinResponse.body.access_token}`)
|
||||
.set('organization-id', signupResponse.body.organization_id)
|
||||
.send()
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/organization (PUT)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.put('/organization')
|
||||
.set('Accept', 'application/json')
|
||||
.set('Content-Type', 'application/json')
|
||||
.set('Authorization', `Bearer ${signinResponse.body.access_token}`)
|
||||
.set('organization-id', signupResponse.body.organization_id)
|
||||
.send({
|
||||
name: 'BIGCAPITAL, INC',
|
||||
baseCurrency: 'USD',
|
||||
location: 'US',
|
||||
language: 'en',
|
||||
fiscalYear: 'march',
|
||||
timezone: 'US/Central',
|
||||
})
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
178
packages/server/test/payment-received.e2e-spec.ts
Normal file
178
packages/server/test/payment-received.e2e-spec.ts
Normal file
@@ -0,0 +1,178 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
let invoice;
|
||||
let customerId;
|
||||
let itemId;
|
||||
|
||||
const requestPaymentReceivedBody = (invoiceId: number) => ({
|
||||
customerId: customerId,
|
||||
paymentDate: '2023-01-01',
|
||||
exchangeRate: 1,
|
||||
referenceNo: faker.string.uuid(),
|
||||
depositAccountId: 1000,
|
||||
paymentReceiveNo: faker.string.uuid(),
|
||||
statement: 'Payment received for invoice',
|
||||
entries: [{ index: 1, invoiceId, paymentAmount: 1 }],
|
||||
branchId: 1,
|
||||
});
|
||||
|
||||
const requestSaleInvoiceBody = () => ({
|
||||
customerId: customerId,
|
||||
invoiceDate: '2023-01-01',
|
||||
dueDate: '2023-02-01',
|
||||
invoiceNo: faker.string.uuid(),
|
||||
referenceNo: 'REF-000201',
|
||||
delivered: true,
|
||||
discountType: 'percentage',
|
||||
discount: 10,
|
||||
branchId: 1,
|
||||
warehouseId: 1,
|
||||
entries: [
|
||||
{
|
||||
index: 1,
|
||||
itemId: itemId,
|
||||
quantity: 100,
|
||||
rate: 1000,
|
||||
description: 'Item description...',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
describe('Payment Received (e2e)', () => {
|
||||
beforeAll(async () => {
|
||||
const customer = await request(app.getHttpServer())
|
||||
.post('/customers')
|
||||
.set('organization-id', orgainzationId)
|
||||
.send({ displayName: 'Test Customer' });
|
||||
|
||||
customerId = customer.body.id;
|
||||
|
||||
const item = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
name: faker.commerce.productName(),
|
||||
sellable: true,
|
||||
purchasable: true,
|
||||
sellAccountId: 1026,
|
||||
costAccountId: 1019,
|
||||
costPrice: 100,
|
||||
sellPrice: 100,
|
||||
});
|
||||
itemId = parseInt(item.text, 10);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-invoices')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestSaleInvoiceBody());
|
||||
|
||||
invoice = response.body;
|
||||
});
|
||||
|
||||
it('/payments-received (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/payments-received')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestPaymentReceivedBody(invoice.id))
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/payments-received/:id (DELETE)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/payments-received')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestPaymentReceivedBody(invoice.id));
|
||||
|
||||
const paymentReceivedId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/payments-received/${paymentReceivedId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/payments-received/:id (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/payments-received')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestPaymentReceivedBody(invoice.id));
|
||||
|
||||
const paymentReceivedId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/payments-received/${paymentReceivedId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/payments-received/:id/invoices (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/payments-received')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestPaymentReceivedBody(invoice.id));
|
||||
|
||||
const paymentReceivedId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/payments-received/${paymentReceivedId}/invoices`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/payments-received/state (GET)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/payments-received/state')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/payments-received/:id/mail (POST)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/payments-received')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestPaymentReceivedBody(invoice.id));
|
||||
|
||||
const paymentReceivedId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.post(`/payments-received/${paymentReceivedId}/mail`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
subject: 'Email subject from here',
|
||||
to: 'a.bouhuolia@gmail.com',
|
||||
body: 'asfdasdf',
|
||||
})
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/payments-received/:id/mail (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/payments-received')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestPaymentReceivedBody(invoice.id));
|
||||
|
||||
const paymentReceivedId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/payments-received/${paymentReceivedId}/mail`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
74
packages/server/test/pdf-templates.e2e-spec.ts
Normal file
74
packages/server/test/pdf-templates.e2e-spec.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import * as request from 'supertest';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
describe('Pdf Templates (e2e)', () => {
|
||||
it('/pdf-templates (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/pdf-templates')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
template_name: 'Standard',
|
||||
resource: 'SaleInvoice',
|
||||
attributes: {},
|
||||
})
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/pdf-templates (DELETE)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/pdf-templates')
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.send({
|
||||
template_name: 'Standard',
|
||||
resource: 'SaleInvoice',
|
||||
attributes: {},
|
||||
});
|
||||
const pdfTemplateId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/pdf-templates/${pdfTemplateId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/pdf-templates/:id (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/pdf-templates')
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.send({
|
||||
template_name: 'Standard',
|
||||
resource: 'SaleInvoice',
|
||||
attributes: {},
|
||||
});
|
||||
const pdfTemplateId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/pdf-templates/${pdfTemplateId}`)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/pdf-templates/:id/assign-default (POST)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/pdf-templates')
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.send({
|
||||
template_name: 'Standard',
|
||||
resource: 'SaleInvoice',
|
||||
attributes: {},
|
||||
});
|
||||
const pdfTemplateId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/pdf-templates/${pdfTemplateId}/assign-default`)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
176
packages/server/test/sale-estimates.e2e-spec.ts
Normal file
176
packages/server/test/sale-estimates.e2e-spec.ts
Normal file
@@ -0,0 +1,176 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
let customerId;
|
||||
let itemId;
|
||||
|
||||
const makeEstimateRequest = ({ ...props } = {}) => ({
|
||||
customerId: customerId,
|
||||
estimateDate: '2022-02-02',
|
||||
expirationDate: '2020-03-02',
|
||||
delivered: false,
|
||||
estimateNumber: faker.string.uuid(),
|
||||
discount: 100,
|
||||
discountType: 'amount',
|
||||
entries: [
|
||||
{
|
||||
index: 1,
|
||||
itemId: itemId,
|
||||
quantity: 3,
|
||||
rate: 1000,
|
||||
description: "It's description here.",
|
||||
},
|
||||
],
|
||||
...props,
|
||||
});
|
||||
|
||||
describe('Sale Estimates (e2e)', () => {
|
||||
beforeAll(async () => {
|
||||
const customer = await request(app.getHttpServer())
|
||||
.post('/customers')
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.send({ displayName: 'Test Customer' });
|
||||
|
||||
customerId = customer.body.id;
|
||||
|
||||
const item = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.send({
|
||||
name: faker.commerce.productName(),
|
||||
type: 'inventory',
|
||||
sellable: true,
|
||||
purchasable: true,
|
||||
sellAccountId: 1026,
|
||||
costAccountId: 1019,
|
||||
costPrice: 100,
|
||||
sellPrice: 100,
|
||||
});
|
||||
itemId = parseInt(item.text, 10);
|
||||
});
|
||||
|
||||
it('/sale-estimates (POST)', async () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/sale-estimates')
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.send(makeEstimateRequest())
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/sale-estimates (DELETE)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-estimates')
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.send(makeEstimateRequest());
|
||||
|
||||
const estimateId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/sale-estimates/${estimateId}`)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-estimates/state (GET)', async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/sale-estimates/state')
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-estimates/:id (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-estimates')
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.send(makeEstimateRequest());
|
||||
|
||||
const estimateId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/sale-estimates/${estimateId}`)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-estimates/:id/approve (PUT)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-estimates')
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.send({ ...makeEstimateRequest(), delivered: true });
|
||||
|
||||
const estimateId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/sale-estimates/${estimateId}/approve`)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-estimates/:id/reject (PUT)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-estimates')
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.send({ ...makeEstimateRequest(), delivered: true });
|
||||
|
||||
const estimateId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/sale-estimates/${estimateId}/reject`)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-estimates (GET)', async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/sale-estimates')
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-estimates/:id/mail (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-estimates')
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.send(makeEstimateRequest());
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/sale-estimates/${response.body.id}/mail`)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-estimates/:id/mail (POST)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-estimates')
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.set('organization-id', orgainzationId)
|
||||
.send(makeEstimateRequest());
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.post(`/sale-estimates/${response.body.id}/mail`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
subject: 'Email subject from here',
|
||||
to: 'a.bouhuolia@gmail.com',
|
||||
body: 'asfdasdf',
|
||||
attachInvoice: false,
|
||||
})
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
243
packages/server/test/sale-invoices.e2e-spec.ts
Normal file
243
packages/server/test/sale-invoices.e2e-spec.ts
Normal file
@@ -0,0 +1,243 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
let customerId;
|
||||
let itemId;
|
||||
|
||||
const requestSaleInvoiceBody = () => ({
|
||||
customerId: customerId,
|
||||
invoiceDate: '2023-01-01',
|
||||
dueDate: '2023-02-01',
|
||||
invoiceNo: faker.string.uuid(),
|
||||
referenceNo: 'REF-000201',
|
||||
delivered: true,
|
||||
discountType: 'percentage',
|
||||
discount: 10,
|
||||
branchId: 1,
|
||||
warehouseId: 1,
|
||||
entries: [
|
||||
{
|
||||
index: 1,
|
||||
itemId: itemId,
|
||||
quantity: 2,
|
||||
rate: 1000,
|
||||
description: 'Item description...',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
describe('Sale Invoices (e2e)', () => {
|
||||
beforeAll(async () => {
|
||||
const customer = await request(app.getHttpServer())
|
||||
.post('/customers')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({ displayName: 'Test Customer' });
|
||||
|
||||
customerId = customer.body.id;
|
||||
|
||||
const item = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
name: faker.commerce.productName(),
|
||||
sellable: true,
|
||||
purchasable: true,
|
||||
sellAccountId: 1026,
|
||||
costAccountId: 1019,
|
||||
costPrice: 100,
|
||||
sellPrice: 100,
|
||||
});
|
||||
itemId = parseInt(item.text, 10);
|
||||
});
|
||||
|
||||
it('/sale-invoices (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/sale-invoices')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestSaleInvoiceBody())
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/sale-invoices/:id (DELETE)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-invoices')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestSaleInvoiceBody());
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/sale-invoices/${response.body.id}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-invoices/:id (PUT)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-invoices')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestSaleInvoiceBody());
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/sale-invoices/${response.body.id}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestSaleInvoiceBody())
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-invoices (GET)', async () => {
|
||||
await request(app.getHttpServer())
|
||||
.post('/sale-invoices')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestSaleInvoiceBody());
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get('/sale-invoices')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-invoices/:id (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-invoices')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestSaleInvoiceBody());
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/sale-invoices/${response.body.id}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-invoices/:id/state (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-invoices')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestSaleInvoiceBody());
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/sale-invoices/${response.body.id}/state`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-invoices/:id/payments (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-invoices')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestSaleInvoiceBody());
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/sale-invoices/${response.body.id}/payments`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-invoices/:id/writeoff (POST)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-invoices')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestSaleInvoiceBody());
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.post(`/sale-invoices/${response.body.id}/writeoff`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
expenseAccountId: 1024,
|
||||
date: '2023-01-01',
|
||||
reason: 'Write off reason',
|
||||
})
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-invoices/:id/cancel-writeoff (POST)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-invoices')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestSaleInvoiceBody());
|
||||
|
||||
await request(app.getHttpServer())
|
||||
.post(`/sale-invoices/${response.body.id}/writeoff`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
expenseAccountId: 1024,
|
||||
date: '2023-01-01',
|
||||
reason: 'Write off reason',
|
||||
});
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.post(`/sale-invoices/${response.body.id}/cancel-writeoff`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-invoices/:id/deliver (PUT)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-invoices')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
...requestSaleInvoiceBody(),
|
||||
delivered: false,
|
||||
});
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.post(`/sale-invoices/${response.body.id}/deliver`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-invoices/:id/mail-state (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-invoices')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestSaleInvoiceBody());
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/sale-invoices/${response.body.id}/mail-state`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-invoices/:id/mail (POST)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-invoices')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestSaleInvoiceBody());
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/sale-invoices/${response.body.id}/mail`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
subject: 'Email subject from here',
|
||||
to: 'a.bouhuolia@gmail.com',
|
||||
body: 'asfdasdf',
|
||||
attachInvoice: false,
|
||||
})
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
136
packages/server/test/sale-receipts.e2e-spec.ts
Normal file
136
packages/server/test/sale-receipts.e2e-spec.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
let customerId;
|
||||
let itemId;
|
||||
|
||||
const makeReceiptRequest = () => ({
|
||||
customerId: customerId,
|
||||
depositAccountId: 1000,
|
||||
receiptDate: '2022-02-02',
|
||||
referenceNo: '123',
|
||||
receiptNumber: faker.string.uuid(),
|
||||
branchId: 1,
|
||||
warehouseId: 1,
|
||||
discount: 100,
|
||||
discountType: 'amount',
|
||||
entries: [
|
||||
{
|
||||
index: 1,
|
||||
itemId: itemId,
|
||||
quantity: 1,
|
||||
rate: 2000,
|
||||
description: 'asdfsadf',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
describe('Sale Receipts (e2e)', () => {
|
||||
beforeAll(async () => {
|
||||
const customer = await request(app.getHttpServer())
|
||||
.post('/customers')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({ displayName: 'Test Customer' });
|
||||
|
||||
customerId = customer.body.id;
|
||||
|
||||
const item = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
name: faker.commerce.productName(),
|
||||
sellable: true,
|
||||
purchasable: true,
|
||||
sellAccountId: 1026,
|
||||
costAccountId: 1019,
|
||||
costPrice: 100,
|
||||
sellPrice: 100,
|
||||
});
|
||||
itemId = parseInt(item.text, 10);
|
||||
});
|
||||
|
||||
it('/sale-reeipts (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/sale-receipts')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeReceiptRequest())
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/sale-receipts/:id (DELETE)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-receipts')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeReceiptRequest());
|
||||
|
||||
const receiptId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/sale-receipts/${receiptId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.send();
|
||||
});
|
||||
|
||||
it('/sale-receipts/:id (PUT)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-receipts')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeReceiptRequest());
|
||||
|
||||
const receiptId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/sale-receipts/${receiptId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
...makeReceiptRequest(),
|
||||
referenceNo: '321',
|
||||
})
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-receipts (GET)', async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/sale-receipts')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-receipts/:id (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-receipts')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeReceiptRequest());
|
||||
|
||||
const receiptId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/sale-receipts/${receiptId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/sale-receipts/:id/mail (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/sale-receipts')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeReceiptRequest());
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/sale-receipts/${response.body.id}/mail`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
36
packages/server/test/settings.e2e-spec.ts
Normal file
36
packages/server/test/settings.e2e-spec.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import * as request from 'supertest';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
const makeSettingsRequest = () => ({
|
||||
options: [
|
||||
{
|
||||
group: 'credit_note',
|
||||
key: 'customer_notes',
|
||||
value: 'Customer Notes...',
|
||||
},
|
||||
{
|
||||
group: 'credit_note',
|
||||
key: 'terms_conditions',
|
||||
value: 'Terms & Conditions...',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
describe('Settings (e2e)', () => {
|
||||
it('/settings (PUT)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.put('/settings')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(makeSettingsRequest())
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/settings (GET)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/settings')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
39
packages/server/test/tax-rates.e2e-spec.ts
Normal file
39
packages/server/test/tax-rates.e2e-spec.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
describe('Item Categories(e2e)', () => {
|
||||
it('/tax-rates (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/tax-rates')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
name: faker.person.fullName(),
|
||||
rate: 2,
|
||||
code: faker.string.uuid(),
|
||||
active: 1,
|
||||
})
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/tax-rates/:id (DELETE)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/tax-rates')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
name: faker.person.fullName(),
|
||||
rate: 2,
|
||||
code: faker.string.uuid(),
|
||||
active: 1,
|
||||
});
|
||||
const taxRateId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/tax-rates/${taxRateId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
113
packages/server/test/transactions-locking.e2e-spec.ts
Normal file
113
packages/server/test/transactions-locking.e2e-spec.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import * as request from 'supertest';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
describe.only('Transactions Locking (e2e)', () => {
|
||||
it('/transactions-locking/lock (PUT)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.put('/transactions-locking/lock')
|
||||
.set('organization-id', orgainzationId)
|
||||
.send({
|
||||
module: 'all',
|
||||
lock_to_date: '2025-01-01',
|
||||
reason: 'test',
|
||||
})
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/transactions-locking/cancel-lock (PUT)', async () => {
|
||||
await request(app.getHttpServer())
|
||||
.put('/transactions-locking/lock')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
module: 'all',
|
||||
lock_to_date: '2025-01-01',
|
||||
reason: 'test',
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put('/transactions-locking/cancel-lock')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/transactions-locking/unlock-partial (PUT)', async () => {
|
||||
await request(app.getHttpServer())
|
||||
.put('/transactions-locking/lock')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
module: 'all',
|
||||
lock_to_date: '2025-01-01',
|
||||
reason: 'test',
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put('/transactions-locking/cancel-lock')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
module: 'all',
|
||||
unlockFromDate: '2025-01-01',
|
||||
unlockToDate: '2025-12-31',
|
||||
reason: 'test partial unlock',
|
||||
})
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/transactions-locking/cancel-unlock-partial (PUT)', async () => {
|
||||
await request(app.getHttpServer())
|
||||
.put('/transactions-locking/lock')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
module: 'all',
|
||||
lock_to_date: '2025-01-01',
|
||||
reason: 'test',
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
await request(app.getHttpServer())
|
||||
.put('/transactions-locking/unlock-partial')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
module: 'all',
|
||||
unlockFromDate: '2025-01-01',
|
||||
unlockToDate: '2025-12-31',
|
||||
reason: 'test partial unlock',
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put('/transactions-locking/cancel-unlock-partial')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
module: 'all',
|
||||
unlockFromDate: '2025-01-01',
|
||||
unlockToDate: '2025-12-31',
|
||||
reason: 'test partial unlock',
|
||||
})
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/transactions-locking (GET)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/transactions-locking')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/transactions-locking/:module (GET)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/transactions-locking/all')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
108
packages/server/test/vendor-credits.e2e-spec.ts
Normal file
108
packages/server/test/vendor-credits.e2e-spec.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
let vendorId;
|
||||
let itemId;
|
||||
|
||||
const requestVendorCredit = () => ({
|
||||
vendorId: vendorId,
|
||||
exchangeRate: 1,
|
||||
vendorCreditNumber: faker.string.uuid(),
|
||||
vendorCreditDate: '2025-01-01',
|
||||
entries: [
|
||||
{
|
||||
index: 1,
|
||||
item_id: itemId,
|
||||
quantity: 1,
|
||||
rate: 1000,
|
||||
description: "It's description here.",
|
||||
},
|
||||
],
|
||||
branchId: 1,
|
||||
warehouseId: 1,
|
||||
});
|
||||
|
||||
describe('Vendor Credits (e2e)', () => {
|
||||
beforeAll(async () => {
|
||||
const vendor = await request(app.getHttpServer())
|
||||
.post('/vendors')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({ displayName: 'Test Customer' });
|
||||
|
||||
vendorId = vendor.body.id;
|
||||
|
||||
const item = await request(app.getHttpServer())
|
||||
.post('/items')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
name: faker.commerce.productName(),
|
||||
sellable: true,
|
||||
purchasable: true,
|
||||
sellAccountId: 1026,
|
||||
costAccountId: 1019,
|
||||
costPrice: 100,
|
||||
sellPrice: 100,
|
||||
});
|
||||
itemId = parseInt(item.text, 10);
|
||||
});
|
||||
|
||||
it('/vendor-credits (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/vendor-credits')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestVendorCredit())
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/vendor-credits/:id (DELETE)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/vendor-credits')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestVendorCredit());
|
||||
|
||||
const vendorCreditId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/vendor-credits/${vendorCreditId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/vendor-credits/:id/open (POST)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/vendor-credits')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestVendorCredit());
|
||||
|
||||
const vendorCreditId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/vendor-credits/${vendorCreditId}/open`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/vendor-credits/:id (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/vendor-credits')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send(requestVendorCredit());
|
||||
|
||||
const vendorCreditId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/vendor-credits/${vendorCreditId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
81
packages/server/test/vendors.e2e-spec.ts
Normal file
81
packages/server/test/vendors.e2e-spec.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
describe.only('Vendors (e2e)', () => {
|
||||
it('/vendors (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/vendors')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
displayName: faker.commerce.productName(),
|
||||
email: faker.internet.email(),
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
})
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/vendors/:id (PUT)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/vendors')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
displayName: faker.commerce.productName(),
|
||||
email: faker.internet.email(),
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
});
|
||||
const vendorId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/vendors/${vendorId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
displayName: faker.commerce.productName(),
|
||||
email: faker.internet.email(),
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
})
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/vendors/:id (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/vendors')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
displayName: faker.commerce.productName(),
|
||||
email: faker.internet.email(),
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
});
|
||||
const vendorId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/vendors/${vendorId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/vendors/:id (DELETE)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/vendors')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
displayName: faker.commerce.productName(),
|
||||
});
|
||||
const vendorId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/vendors/${vendorId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
76
packages/server/test/warehouses.e2e-spec.ts
Normal file
76
packages/server/test/warehouses.e2e-spec.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import * as request from 'supertest';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { app, AuthorizationHeader, orgainzationId } from './init-app-test';
|
||||
|
||||
describe('Warehouses (e2e)', () => {
|
||||
it('/warehouses (POST)', () => {
|
||||
return request(app.getHttpServer())
|
||||
.post('/warehouses')
|
||||
.set('organization-id', orgainzationId)
|
||||
.send({
|
||||
name: faker.commerce.productName(),
|
||||
code: faker.string.alpha(4),
|
||||
})
|
||||
.expect(201);
|
||||
});
|
||||
|
||||
it('/warehouses/:id (DELETE)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/warehouses')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
name: faker.commerce.productName(),
|
||||
code: faker.string.alpha(4),
|
||||
});
|
||||
const warehouseId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.delete(`/warehouses/${warehouseId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/warehouses/:id (PUT)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/warehouses')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
name: faker.commerce.productName(),
|
||||
code: faker.string.alpha(4),
|
||||
});
|
||||
const warehouseId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.put(`/warehouses/${warehouseId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/warehouses/:id (GET)', async () => {
|
||||
const response = await request(app.getHttpServer())
|
||||
.post('/warehouses')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.send({
|
||||
name: faker.commerce.productName(),
|
||||
code: faker.string.alpha(4),
|
||||
});
|
||||
const warehouseId = response.body.id;
|
||||
|
||||
return request(app.getHttpServer())
|
||||
.get(`/warehouses/${warehouseId}`)
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('/warehouses (GET)', async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/warehouses')
|
||||
.set('organization-id', orgainzationId)
|
||||
.set('Authorization', AuthorizationHeader)
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user