Skip to content

Commit

Permalink
Add and refactor Financial Report controllers and tests: Business Log…
Browse files Browse the repository at this point in the history
…ic, Authorization, and CRUD operations
  • Loading branch information
urbantech committed Nov 6, 2024
1 parent 24009b5 commit 49c2965
Show file tree
Hide file tree
Showing 8 changed files with 910 additions and 269 deletions.
80 changes: 45 additions & 35 deletions __tests__/financialReportAuth.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// __tests__/FinancialReportAuth.test.js
// __tests__/financialReportAuth.test.js
const {
checkUserPermissions,
validateApiKey,
authorizeReportAccess
} = require('../controllers/financialReportingController');
} = require('../controllers/financialReportAuthController');
const FinancialReport = require('../models/financialReport');
const httpMocks = require('node-mocks-http');
const jwt = require('jsonwebtoken');

jest.mock('jsonwebtoken');
jest.mock('../models/financialReport');

describe('Financial Report Authorization', () => {
let req, res, next;
Expand Down Expand Up @@ -46,50 +46,25 @@ const {
})
);
});

it('should handle role-based access control', async () => {
req.user = {
role: 'financial_analyst',
permissions: ['create:reports', 'read:reports', 'update:reports']
};
req.method = 'DELETE';

await checkUserPermissions(req, res, next);
expect(next).toHaveBeenCalledWith(
expect.objectContaining({
message: 'Insufficient permissions',
statusCode: 403
})
);
});
});

describe('API Key Validation', () => {
it('should validate valid API key', async () => {
const apiKey = 'valid-api-key-123';
req.headers = { 'x-api-key': apiKey };

jwt.verify.mockImplementation(() => ({
permissions: ['create:reports', 'read:reports']
}));
req.headers = { 'x-api-key': 'valid-api-key-123' };

await validateApiKey(req, res, next);
expect(next).toHaveBeenCalled();
expect(next).not.toHaveBeenCalledWith(expect.any(Error));
expect(req.apiPermissions).toContain('read:reports');
});

it('should reject invalid API key', async () => {
const apiKey = 'invalid-api-key';
req.headers = { 'x-api-key': apiKey };

jwt.verify.mockImplementation(() => {
throw new Error('Invalid token');
});
it('should reject missing API key', async () => {
req.headers = {};

await validateApiKey(req, res, next);
expect(next).toHaveBeenCalledWith(
expect.objectContaining({
message: 'Invalid API key',
message: 'API key is required',
statusCode: 401
})
);
Expand All @@ -106,4 +81,39 @@ const {
};

const mockReport = {
ReportID: reportI
ReportID: reportId,
userId: 'user-123'
};

FinancialReport.findOne = jest.fn().mockResolvedValue(mockReport);

await authorizeReportAccess(req, res, next);
expect(next).toHaveBeenCalled();
expect(next).not.toHaveBeenCalledWith(expect.any(Error));
});

it('should deny access to other users reports', async () => {
const reportId = 'test-report-123';
req.params = { id: reportId };
req.user = {
id: 'different-user',
role: 'user'
};

const mockReport = {
ReportID: reportId,
userId: 'user-123'
};

FinancialReport.findOne = jest.fn().mockResolvedValue(mockReport);

await authorizeReportAccess(req, res, next);
expect(next).toHaveBeenCalledWith(
expect.objectContaining({
message: 'Unauthorized access to report',
statusCode: 403
})
);
});
});
});
29 changes: 11 additions & 18 deletions __tests__/financialReportCRUD.test.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
// __tests__/FinancialReportCRUD.test.js
// __tests__/financialReportCRUD.test.js
const {
createFinancialReport,
createFinancialReport,
getFinancialReport,
listFinancialReports,
updateFinancialReport,
deleteFinancialReport,
listFinancialReports
} = require('../controllers/financialReportingController');
deleteFinancialReport
} = require('../controllers/financialReportCrudController');
const FinancialReport = require('../models/financialReport');
const httpMocks = require('node-mocks-http');
const mongoose = require('mongoose');

jest.mock('../models/financialReport');

Expand Down Expand Up @@ -114,26 +113,20 @@ const {

it('should handle update validation errors', async () => {
const reportId = 'test-id-123';
const invalidData = {
const invalidData = {
...sampleReport,
Type: 'InvalidType'
TotalRevenue: '-1000000.00' // Invalid negative value
};

req.params = { id: reportId };
req.body = invalidData;

const validationError = new mongoose.Error.ValidationError();
validationError.errors.Type = new mongoose.Error.ValidatorError({
message: 'Invalid report type',
path: 'Type'
});

FinancialReport.findOneAndUpdate = jest.fn()
.mockRejectedValue(validationError);

await updateFinancialReport(req, res, next);

expect(next).toHaveBeenCalledWith(validationError);
expect(res.statusCode).toBe(400);
expect(JSON.parse(res._getData())).toEqual({
error: 'Financial values cannot be negative'
});
});
});

Expand Down
25 changes: 6 additions & 19 deletions __tests__/financialReportLogic.test.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
// __tests__/FinancialReportBusinessLogic.test.js
// __tests__/financialReportLogic.test.js
const {
validateFinancialReport,
calculateFinancialMetrics,
validateReportingPeriod
} = require('../controllers/financialReportingController');
const httpMocks = require('node-mocks-http');
validateReportingPeriod,
validateFinancialReport
} = require('../controllers/financialReportBusinessController');

describe('Financial Report Business Logic', () => {
let req, res, next;

beforeEach(() => {
req = httpMocks.createRequest();
res = httpMocks.createResponse();
next = jest.fn();
jest.clearAllMocks();
});

describe('Financial Calculations', () => {
it('should correctly calculate net income', () => {
const reportData = {
Expand Down Expand Up @@ -58,7 +48,6 @@ const {
it('should validate annual report period', () => {
const reportData = {
Type: 'Annual',
Timestamp: new Date('2024-12-31'),
Data: {
revenue: { q1: 250000, q2: 250000, q3: 250000, q4: 250000 },
expenses: { q1: 150000, q2: 150000, q3: 150000, q4: 150000 }
Expand All @@ -72,7 +61,6 @@ const {
it('should validate quarterly report period', () => {
const reportData = {
Type: 'Quarterly',
Timestamp: new Date('2024-03-31'),
Data: {
revenue: { q1: 250000 },
expenses: { q1: 150000 }
Expand All @@ -86,7 +74,6 @@ const {
it('should reject invalid period data', () => {
const reportData = {
Type: 'Annual',
Timestamp: new Date('2024-12-31'),
Data: {
revenue: { q1: 250000 }, // Missing quarters
expenses: { q1: 150000 }
Expand All @@ -111,7 +98,7 @@ const {
TotalRevenue: '1000000.00',
TotalExpenses: '600000.00',
NetIncome: '400000.00',
Timestamp: new Date()
Timestamp: new Date().toISOString()
};

const result = validateFinancialReport(reportData);
Expand All @@ -129,7 +116,7 @@ const {
TotalRevenue: '1000000.00',
TotalExpenses: '600000.00',
NetIncome: '400000.00',
Timestamp: new Date()
Timestamp: new Date().toISOString()
};

const result = validateFinancialReport(reportData);
Expand Down
Loading

0 comments on commit 49c2965

Please sign in to comment.