214 lines
6.0 KiB
JavaScript
214 lines
6.0 KiB
JavaScript
'use strict';
|
||
|
||
/**
|
||
* Integration tests – job controller (controllers/job.js)
|
||
*
|
||
* The job controller is a factory: require('../../controllers/job')({})
|
||
* Job._id is an auto-increment numeric field.
|
||
* deleteJob wraps transaction errors with try/catch so it works on
|
||
* standalone MongoDB (no replica-set needed).
|
||
*/
|
||
|
||
const { connectDB, disconnectDB, clearCollection } = require('./jest.setup');
|
||
const {
|
||
mockApplicator,
|
||
mockClient,
|
||
mockPilot,
|
||
mockVehicle,
|
||
mockJob,
|
||
mockReq,
|
||
mockRes,
|
||
newId,
|
||
} = require('./mock_data');
|
||
|
||
let Job, Customer, Client, Pilot, Vehicle;
|
||
|
||
beforeAll(async () => {
|
||
await connectDB();
|
||
Customer = require('../../model/customer');
|
||
Client = require('../../model/client');
|
||
Pilot = require('../../model/pilot');
|
||
Vehicle = require('../../model/vehicle');
|
||
Job = require('../../model/job');
|
||
});
|
||
|
||
afterAll(async () => {
|
||
await disconnectDB();
|
||
});
|
||
|
||
// Job controller is a factory
|
||
const jobCtl = require('../../controllers/job')({});
|
||
|
||
describe('job controller – data methods', () => {
|
||
let applicator, client, pilot, vehicle;
|
||
|
||
beforeAll(async () => {
|
||
await clearCollection(Job);
|
||
applicator = await Customer.create(mockApplicator());
|
||
client = await Client.create(mockClient(applicator._id));
|
||
pilot = await Pilot.create(mockPilot(applicator._id));
|
||
vehicle = await Vehicle.create(mockVehicle(applicator._id));
|
||
});
|
||
|
||
afterAll(async () => {
|
||
await clearCollection(Job);
|
||
await Client.deleteMany({ _id: client._id });
|
||
await Pilot.deleteMany({ _id: pilot._id });
|
||
await Vehicle.deleteMany({ _id: vehicle._id });
|
||
await Customer.deleteMany({ _id: applicator._id });
|
||
});
|
||
|
||
const makeReq = (extra = {}) =>
|
||
mockReq({
|
||
uid: applicator._id,
|
||
puid: applicator._id,
|
||
ut: '1',
|
||
userInfo: {
|
||
puid: applicator._id,
|
||
kind: '1',
|
||
premium: 0,
|
||
membership: null,
|
||
markedDelete: false,
|
||
},
|
||
...extra,
|
||
});
|
||
|
||
// -------------------------------------------------------------------------
|
||
describe('createJob_post', () => {
|
||
it('creates a job and returns it', async () => {
|
||
const body = mockJob(applicator._id);
|
||
body.client = client._id;
|
||
body.pilot = pilot._id;
|
||
body.vehicle = vehicle._id;
|
||
|
||
const req = makeReq({ body });
|
||
const res = mockRes();
|
||
|
||
await jobCtl.createJob_post(req, res);
|
||
|
||
expect(res.json).toHaveBeenCalled();
|
||
expect(res._data._id).toBeDefined();
|
||
expect(typeof res._data._id).toBe('number');
|
||
});
|
||
|
||
it('throws when puid is missing', async () => {
|
||
const req = makeReq({ puid: undefined, body: mockJob(applicator._id) });
|
||
const res = mockRes();
|
||
await expect(jobCtl.createJob_post(req, res)).rejects.toThrow();
|
||
});
|
||
});
|
||
|
||
// -------------------------------------------------------------------------
|
||
describe('getJobs_get', () => {
|
||
it('returns jobs for the applicator', async () => {
|
||
const req = makeReq({ query: {} });
|
||
const res = mockRes();
|
||
|
||
await jobCtl.getJobs_get(req, res);
|
||
|
||
expect(res.json).toHaveBeenCalled();
|
||
expect(Array.isArray(res._data)).toBe(true);
|
||
expect(res._data.length).toBeGreaterThan(0);
|
||
});
|
||
|
||
it('returns empty array when puid has no jobs', async () => {
|
||
const unknownId = newId();
|
||
const req = mockReq({
|
||
uid: unknownId,
|
||
puid: unknownId,
|
||
ut: '1',
|
||
userInfo: { puid: unknownId, kind: '1', premium: 0, membership: null, markedDelete: false },
|
||
query: {},
|
||
});
|
||
const res = mockRes();
|
||
|
||
await jobCtl.getJobs_get(req, res);
|
||
|
||
expect(res.json).toHaveBeenCalled();
|
||
expect(res._data.length).toBe(0);
|
||
});
|
||
});
|
||
|
||
// -------------------------------------------------------------------------
|
||
describe('getJob_get', () => {
|
||
let jobId;
|
||
|
||
beforeAll(async () => {
|
||
const body = mockJob(applicator._id);
|
||
body.client = client._id;
|
||
body.pilot = pilot._id;
|
||
body.vehicle = vehicle._id;
|
||
const req = makeReq({ body });
|
||
const res = mockRes();
|
||
await jobCtl.createJob_post(req, res);
|
||
jobId = res._data._id;
|
||
});
|
||
|
||
it('returns a job by numeric id', async () => {
|
||
const req = makeReq({ params: { job_id: String(jobId) } });
|
||
const res = mockRes();
|
||
|
||
await jobCtl.getJob_get(req, res);
|
||
|
||
expect(res.json).toHaveBeenCalled();
|
||
expect(res._data._id).toBe(jobId);
|
||
});
|
||
});
|
||
|
||
// -------------------------------------------------------------------------
|
||
describe('updateJob_put', () => {
|
||
let jobId;
|
||
|
||
beforeAll(async () => {
|
||
const body = mockJob(applicator._id);
|
||
body.client = client._id;
|
||
body.pilot = pilot._id;
|
||
body.vehicle = vehicle._id;
|
||
const req = makeReq({ body });
|
||
const res = mockRes();
|
||
await jobCtl.createJob_post(req, res);
|
||
jobId = res._data._id;
|
||
});
|
||
|
||
it('updates a job field', async () => {
|
||
const req = makeReq({
|
||
params: { job_id: String(jobId) },
|
||
body: { job: { name: 'Updated Job Name' } },
|
||
});
|
||
const res = mockRes();
|
||
|
||
await jobCtl.updateJob_put(req, res);
|
||
|
||
expect(res.json).toHaveBeenCalled();
|
||
expect(res._data.name).toBe('Updated Job Name');
|
||
});
|
||
});
|
||
|
||
// -------------------------------------------------------------------------
|
||
describe('deleteJob', () => {
|
||
let jobId;
|
||
|
||
beforeAll(async () => {
|
||
const body = mockJob(applicator._id);
|
||
body.client = client._id;
|
||
body.pilot = pilot._id;
|
||
body.vehicle = vehicle._id;
|
||
const req = makeReq({ body });
|
||
const res = mockRes();
|
||
await jobCtl.createJob_post(req, res);
|
||
jobId = res._data._id;
|
||
});
|
||
|
||
it('deletes a job (transaction error handled on standalone MongoDB)', async () => {
|
||
const req = makeReq({ params: { id: String(jobId) } });
|
||
const res = mockRes();
|
||
|
||
// deleteJob wraps the transaction with try/catch – it either succeeds
|
||
// fully or returns a soft-success; either way res.json is called.
|
||
await jobCtl.deleteJob(req, res);
|
||
|
||
expect(res.json).toHaveBeenCalled();
|
||
});
|
||
});
|
||
});
|