@lilaquadrat/studio 13.0.1 → 14.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/helpers.d.ts +3 -2
- package/lib/helpers.js +3 -2
- package/lib/helpers.js.map +1 -1
- package/lib/models.d.ts +6 -4
- package/lib/models.js +5 -2
- package/lib/models.js.map +1 -1
- package/lib/services.d.ts +7 -1
- package/lib/services.js +6 -1
- package/lib/services.js.map +1 -1
- package/lib/src/Immutable.class.d.ts +0 -1
- package/lib/src/Immutable.class.js.map +1 -1
- package/lib/src/aggegations/genericData.aggregation.js +1 -1
- package/lib/src/aggegations/genericData.aggregation.js.map +1 -1
- package/lib/src/classes/paymentProviders/PaymentProviderFactory.class.d.ts +1 -1
- package/lib/src/classes/paymentProviders/StripePaymentProvider.class.d.ts +1 -1
- package/lib/src/helpers/createError.d.ts +1 -1
- package/lib/src/helpers/escapeRegExp.d.ts +2 -0
- package/lib/src/helpers/escapeRegExp.js +5 -0
- package/lib/src/helpers/escapeRegExp.js.map +1 -0
- package/lib/src/helpers/permissionScopes.d.ts +6 -0
- package/lib/src/helpers/permissionScopes.js +289 -0
- package/lib/src/helpers/permissionScopes.js.map +1 -0
- package/lib/src/helpers/shiftPlanAllocation.d.ts +2 -38
- package/lib/src/helpers/shiftPlanAllocation.js.map +1 -1
- package/lib/src/helpers/shiftPlanCoverage.d.ts +0 -1
- package/lib/src/helpers/shiftPlanningSchemas.d.ts +6 -0
- package/lib/src/helpers/shiftPlanningSchemas.js +1 -0
- package/lib/src/helpers/shiftPlanningSchemas.js.map +1 -1
- package/lib/src/helpers/structureMatch.d.ts +1 -5
- package/lib/src/helpers/structureMatch.js.map +1 -1
- package/lib/src/helpers/verifyToken.d.ts +1 -8
- package/lib/src/helpers/verifyToken.js.map +1 -1
- package/lib/src/models/access.model.d.ts +1 -12
- package/lib/src/models/access.model.js.map +1 -1
- package/lib/src/models/cart.model.js +36 -1
- package/lib/src/models/cart.model.js.map +1 -1
- package/lib/src/models/editor.model.js +2 -0
- package/lib/src/models/editor.model.js.map +1 -1
- package/lib/src/models/environment.model.d.ts +4 -0
- package/lib/src/models/environment.model.js +47 -0
- package/lib/src/models/environment.model.js.map +1 -0
- package/lib/src/models/id.model.d.ts +2 -12
- package/lib/src/models/id.model.js.map +1 -1
- package/lib/src/models/migration.model.d.ts +22 -0
- package/lib/src/models/migration.model.js +51 -0
- package/lib/src/models/migration.model.js.map +1 -0
- package/lib/src/models/participant.model.d.ts +1 -1
- package/lib/src/models/participant.model.js +1 -1
- package/lib/src/models/participant.model.js.map +1 -1
- package/lib/src/models/permissions.model.d.ts +1 -6
- package/lib/src/models/permissions.model.js +0 -275
- package/lib/src/models/permissions.model.js.map +1 -1
- package/lib/src/models/project.model.js +142 -35
- package/lib/src/models/project.model.js.map +1 -1
- package/lib/src/models/publish.model.js +1 -0
- package/lib/src/models/publish.model.js.map +1 -1
- package/lib/src/models/shift.model.js +1 -1
- package/lib/src/models/shift.model.js.map +1 -1
- package/lib/src/models/timeTrackingProject.model.d.ts +4 -0
- package/lib/src/models/timeTrackingProject.model.js +57 -0
- package/lib/src/models/timeTrackingProject.model.js.map +1 -0
- package/lib/src/models/timeTrackingProjectAllocation.model.d.ts +4 -0
- package/lib/src/models/timeTrackingProjectAllocation.model.js +38 -0
- package/lib/src/models/timeTrackingProjectAllocation.model.js.map +1 -0
- package/lib/src/models/tracker.model.js +18 -2
- package/lib/src/models/tracker.model.js.map +1 -1
- package/lib/src/services/access.service.js.map +1 -1
- package/lib/src/services/cart.service.d.ts +7 -1
- package/lib/src/services/cart.service.js +29 -3
- package/lib/src/services/cart.service.js.map +1 -1
- package/lib/src/services/environments.service.d.ts +15 -0
- package/lib/src/services/environments.service.js +20 -0
- package/lib/src/services/environments.service.js.map +1 -0
- package/lib/src/services/history.service.d.ts +1 -2
- package/lib/src/services/history.service.js.map +1 -1
- package/lib/src/services/historySeen.service.d.ts +1 -8
- package/lib/src/services/historySeen.service.js.map +1 -1
- package/lib/src/services/id.service.d.ts +1 -1
- package/lib/src/services/listParticipants.service.d.ts +3 -4
- package/lib/src/services/listParticipants.service.js +4 -4
- package/lib/src/services/listParticipants.service.js.map +1 -1
- package/lib/src/services/lists.service.js +33 -0
- package/lib/src/services/lists.service.js.map +1 -1
- package/lib/src/services/migrations.service.d.ts +60 -0
- package/lib/src/services/migrations.service.js +221 -0
- package/lib/src/services/migrations.service.js.map +1 -0
- package/lib/src/services/participants.service.d.ts +1 -1
- package/lib/src/services/permissions.service.d.ts +1 -1
- package/lib/src/services/permissions.service.js +2 -1
- package/lib/src/services/permissions.service.js.map +1 -1
- package/lib/src/services/shiftPlans.service.d.ts +1 -1
- package/lib/src/services/shiftPlans.service.js +10 -4
- package/lib/src/services/shiftPlans.service.js.map +1 -1
- package/lib/src/services/shifts.service.d.ts +4 -1
- package/lib/src/services/shifts.service.js +25 -6
- package/lib/src/services/shifts.service.js.map +1 -1
- package/lib/src/services/timeTrackingProjectAllocations.service.d.ts +20 -0
- package/lib/src/services/timeTrackingProjectAllocations.service.js +85 -0
- package/lib/src/services/timeTrackingProjectAllocations.service.js.map +1 -0
- package/lib/src/services/timeTrackingProjects.service.d.ts +18 -0
- package/lib/src/services/timeTrackingProjects.service.js +78 -0
- package/lib/src/services/timeTrackingProjects.service.js.map +1 -0
- package/lib/src/services/tracker.service.d.ts +153 -0
- package/lib/src/services/tracker.service.js +741 -0
- package/lib/src/services/tracker.service.js.map +1 -0
- package/lib/tests/cartModel.spec.d.ts +1 -0
- package/lib/tests/cartModel.spec.js +13 -0
- package/lib/tests/cartModel.spec.js.map +1 -0
- package/lib/tests/getUnsetObject.spec.js +3 -0
- package/lib/tests/getUnsetObject.spec.js.map +1 -1
- package/lib/tests/listParticipantsServiceJoin.spec.js +48 -0
- package/lib/tests/listParticipantsServiceJoin.spec.js.map +1 -1
- package/lib/tests/listsSingle.spec.d.ts +1 -0
- package/lib/tests/listsSingle.spec.js +56 -0
- package/lib/tests/listsSingle.spec.js.map +1 -0
- package/lib/tests/migrationModel.spec.d.ts +1 -0
- package/lib/tests/migrationModel.spec.js +38 -0
- package/lib/tests/migrationModel.spec.js.map +1 -0
- package/lib/tests/migrationsService.spec.d.ts +1 -0
- package/lib/tests/migrationsService.spec.js +163 -0
- package/lib/tests/migrationsService.spec.js.map +1 -0
- package/lib/tests/permissionsModel.spec.js +1 -1
- package/lib/tests/shiftPlanCoverage.spec.js.map +1 -1
- package/lib/tests/shiftPlanning.spec.js +63 -11
- package/lib/tests/shiftPlanning.spec.js.map +1 -1
- package/lib/tests/shiftPlansList.spec.js +1 -1
- package/lib/tests/shiftPlansList.spec.js.map +1 -1
- package/lib/tests/timeTrackingProjectAllocationModel.spec.d.ts +1 -0
- package/lib/tests/timeTrackingProjectAllocationModel.spec.js +54 -0
- package/lib/tests/timeTrackingProjectAllocationModel.spec.js.map +1 -0
- package/lib/tests/timeTrackingProjectAllocationsService.spec.d.ts +1 -0
- package/lib/tests/timeTrackingProjectAllocationsService.spec.js +153 -0
- package/lib/tests/timeTrackingProjectAllocationsService.spec.js.map +1 -0
- package/lib/tests/timeTrackingProjectModel.spec.d.ts +1 -0
- package/lib/tests/timeTrackingProjectModel.spec.js +151 -0
- package/lib/tests/timeTrackingProjectModel.spec.js.map +1 -0
- package/lib/tests/timeTrackingProjectsService.spec.d.ts +1 -0
- package/lib/tests/timeTrackingProjectsService.spec.js +256 -0
- package/lib/tests/timeTrackingProjectsService.spec.js.map +1 -0
- package/lib/tests/trackerAllUsers.spec.d.ts +1 -0
- package/lib/tests/trackerAllUsers.spec.js +46 -0
- package/lib/tests/trackerAllUsers.spec.js.map +1 -0
- package/lib/tests/trackerAllocationUsage.spec.d.ts +1 -0
- package/lib/tests/trackerAllocationUsage.spec.js +36 -0
- package/lib/tests/trackerAllocationUsage.spec.js.map +1 -0
- package/lib/tests/trackerBookings.spec.d.ts +1 -0
- package/lib/tests/trackerBookings.spec.js +67 -0
- package/lib/tests/trackerBookings.spec.js.map +1 -0
- package/lib/tests/trackerCategories.spec.d.ts +1 -0
- package/lib/tests/trackerCategories.spec.js +40 -0
- package/lib/tests/trackerCategories.spec.js.map +1 -0
- package/lib/tests/trackerDailyLimit.spec.d.ts +1 -0
- package/lib/tests/trackerDailyLimit.spec.js +84 -0
- package/lib/tests/trackerDailyLimit.spec.js.map +1 -0
- package/lib/tests/trackerModel.spec.d.ts +1 -0
- package/lib/tests/trackerModel.spec.js +73 -0
- package/lib/tests/trackerModel.spec.js.map +1 -0
- package/lib/tests/trackerResolveUser.spec.d.ts +1 -0
- package/lib/tests/trackerResolveUser.spec.js +26 -0
- package/lib/tests/trackerResolveUser.spec.js.map +1 -0
- package/lib/tests/trackerShiftAssignment.spec.d.ts +1 -0
- package/lib/tests/trackerShiftAssignment.spec.js +125 -0
- package/lib/tests/trackerShiftAssignment.spec.js.map +1 -0
- package/lib/tests/trackerShiftBookings.spec.d.ts +1 -0
- package/lib/tests/trackerShiftBookings.spec.js +58 -0
- package/lib/tests/trackerShiftBookings.spec.js.map +1 -0
- package/lib/tests/trackerShiftPlans.spec.d.ts +1 -0
- package/lib/tests/trackerShiftPlans.spec.js +251 -0
- package/lib/tests/trackerShiftPlans.spec.js.map +1 -0
- package/lib/tests/trackerWholePlanStatistics.spec.d.ts +1 -0
- package/lib/tests/trackerWholePlanStatistics.spec.js +41 -0
- package/lib/tests/trackerWholePlanStatistics.spec.js.map +1 -0
- package/package.json +2 -2
- package/lib/src/interfaces/ListPlanningParticipant.d.ts +0 -17
- package/lib/src/interfaces/ListPlanningParticipant.js +0 -2
- package/lib/src/interfaces/ListPlanningParticipant.js.map +0 -1
- package/lib/src/interfaces/Participant.d.ts +0 -62
- package/lib/src/interfaces/Participant.js +0 -4
- package/lib/src/interfaces/Participant.js.map +0 -1
- package/lib/src/interfaces/PaymentProviderBase.d.ts +0 -14
- package/lib/src/interfaces/PaymentProviderBase.js +0 -2
- package/lib/src/interfaces/PaymentProviderBase.js.map +0 -1
- package/lib/src/interfaces/PlanCoveragePreparation.d.ts +0 -17
- package/lib/src/interfaces/PlanCoveragePreparation.js +0 -2
- package/lib/src/interfaces/PlanCoveragePreparation.js.map +0 -1
- package/lib/src/interfaces/PlanningParticipantsResult.d.ts +0 -12
- package/lib/src/interfaces/PlanningParticipantsResult.js +0 -2
- package/lib/src/interfaces/PlanningParticipantsResult.js.map +0 -1
- package/lib/src/interfaces/ShiftAutofillResult.d.ts +0 -6
- package/lib/src/interfaces/ShiftAutofillResult.js +0 -2
- package/lib/src/interfaces/ShiftAutofillResult.js.map +0 -1
- package/lib/src/interfaces/ShiftReportContextOptions.d.ts +0 -9
- package/lib/src/interfaces/ShiftReportContextOptions.js +0 -2
- package/lib/src/interfaces/ShiftReportContextOptions.js.map +0 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { describe, expect, it } from '@jest/globals';
|
|
2
|
+
import Models from '../src/classes/models.class';
|
|
3
|
+
import TimeTrackingProjectAllocationModel from '../src/models/timeTrackingProjectAllocation.model';
|
|
4
|
+
const models = new Models();
|
|
5
|
+
models.register('timeTrackingProjectAllocation', TimeTrackingProjectAllocationModel);
|
|
6
|
+
const validAllocation = {
|
|
7
|
+
company: 'lilaquadrat',
|
|
8
|
+
project: 'studio',
|
|
9
|
+
timeTrackingProject: 'team-website',
|
|
10
|
+
category: 'design',
|
|
11
|
+
user: 'user-1',
|
|
12
|
+
hours: 40,
|
|
13
|
+
};
|
|
14
|
+
describe('TimeTrackingProjectAllocationModel', () => {
|
|
15
|
+
it('accepts a complete allocation', () => {
|
|
16
|
+
expect(TimeTrackingProjectAllocationModel.validate(validAllocation, 'create')).toBe(true);
|
|
17
|
+
});
|
|
18
|
+
it('requires tenant, project, category and user', () => {
|
|
19
|
+
expect(TimeTrackingProjectAllocationModel.validate({ ...validAllocation, company: undefined }, 'create')).toBe(false);
|
|
20
|
+
expect(TimeTrackingProjectAllocationModel.validate({ ...validAllocation, project: undefined }, 'create')).toBe(false);
|
|
21
|
+
expect(TimeTrackingProjectAllocationModel.validate({ ...validAllocation, timeTrackingProject: undefined }, 'create')).toBe(false);
|
|
22
|
+
expect(TimeTrackingProjectAllocationModel.validate({ ...validAllocation, category: undefined }, 'create')).toBe(false);
|
|
23
|
+
expect(TimeTrackingProjectAllocationModel.validate({ ...validAllocation, user: undefined }, 'create')).toBe(false);
|
|
24
|
+
});
|
|
25
|
+
it('accepts an allocation without hours', () => {
|
|
26
|
+
expect(TimeTrackingProjectAllocationModel.validate({ ...validAllocation, hours: undefined }, 'create')).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
it('rejects zero or negative hours', () => {
|
|
29
|
+
expect(TimeTrackingProjectAllocationModel.validate({ ...validAllocation, hours: 0 }, 'create')).toBe(false);
|
|
30
|
+
expect(TimeTrackingProjectAllocationModel.validate({ ...validAllocation, hours: -1 }, 'create')).toBe(false);
|
|
31
|
+
expect(TimeTrackingProjectAllocationModel.validate({ ...validAllocation, hours: null }, 'create')).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
it('rejects unknown properties', () => {
|
|
34
|
+
expect(TimeTrackingProjectAllocationModel.validate({ ...validAllocation, extra: true }, 'create')).toBe(false);
|
|
35
|
+
});
|
|
36
|
+
it('allows only the hours to change', () => {
|
|
37
|
+
expect(TimeTrackingProjectAllocationModel.validate({ hours: 20 }, 'change')).toBe(true);
|
|
38
|
+
expect(TimeTrackingProjectAllocationModel.validate({ hours: null }, 'change')).toBe(true);
|
|
39
|
+
expect(TimeTrackingProjectAllocationModel.validate({ hours: 20, user: 'other' }, 'change')).toBe(false);
|
|
40
|
+
});
|
|
41
|
+
it('marks the identity fields as immutable', () => {
|
|
42
|
+
expect(TimeTrackingProjectAllocationModel.immutable).toContain('timeTrackingProject');
|
|
43
|
+
expect(TimeTrackingProjectAllocationModel.immutable).toContain('category');
|
|
44
|
+
expect(TimeTrackingProjectAllocationModel.immutable).toContain('user');
|
|
45
|
+
});
|
|
46
|
+
it('defines one allocation per person and category', () => {
|
|
47
|
+
expect(TimeTrackingProjectAllocationModel.indexes).toContainEqual(expect.objectContaining({
|
|
48
|
+
key: { company: 1, project: 1, timeTrackingProject: 1, category: 1, user: 1 },
|
|
49
|
+
unique: true,
|
|
50
|
+
name: 'company_project_project_category_user-v1',
|
|
51
|
+
}));
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
//# sourceMappingURL=timeTrackingProjectAllocationModel.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeTrackingProjectAllocationModel.spec.js","sourceRoot":"","sources":["../../tests/timeTrackingProjectAllocationModel.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, jest } from '@jest/globals';
|
|
2
|
+
import { ObjectId } from 'mongodb';
|
|
3
|
+
import TimeTrackingProjectModel from '../src/models/timeTrackingProject.model';
|
|
4
|
+
import TimeTrackingProjectAllocationModel from '../src/models/timeTrackingProjectAllocation.model';
|
|
5
|
+
import TimeTrackingProjectAllocationsService from '../src/services/timeTrackingProjectAllocations.service';
|
|
6
|
+
const options = {
|
|
7
|
+
user: 'user',
|
|
8
|
+
app: 'app',
|
|
9
|
+
company: 'company',
|
|
10
|
+
project: 'project',
|
|
11
|
+
};
|
|
12
|
+
const project = {
|
|
13
|
+
id: 'team-website',
|
|
14
|
+
modes: 'fromTo',
|
|
15
|
+
categories: [{ id: 'design', name: 'Design', maximumHours: 100, costsPerHour: 80 }],
|
|
16
|
+
};
|
|
17
|
+
const input = {
|
|
18
|
+
timeTrackingProject: 'team-website',
|
|
19
|
+
category: 'design',
|
|
20
|
+
user: 'user-1',
|
|
21
|
+
hours: 40,
|
|
22
|
+
};
|
|
23
|
+
const inputWithoutHours = {
|
|
24
|
+
timeTrackingProject: 'team-website',
|
|
25
|
+
category: 'design',
|
|
26
|
+
user: 'user-1',
|
|
27
|
+
};
|
|
28
|
+
function mockProject(found = project) {
|
|
29
|
+
jest.spyOn(TimeTrackingProjectModel, 'db', 'get').mockReturnValue({ findOne: jest.fn().mockResolvedValue(found) });
|
|
30
|
+
}
|
|
31
|
+
function mockAllocations(hours) {
|
|
32
|
+
const toArray = jest.fn().mockResolvedValue(hours.map((value) => ({ hours: value })));
|
|
33
|
+
const find = jest.fn().mockReturnValue({ toArray });
|
|
34
|
+
jest.spyOn(TimeTrackingProjectAllocationModel, 'db', 'get').mockReturnValue({ find });
|
|
35
|
+
return { find, toArray };
|
|
36
|
+
}
|
|
37
|
+
describe('TimeTrackingProjectAllocationsService', () => {
|
|
38
|
+
afterEach(() => {
|
|
39
|
+
jest.restoreAllMocks();
|
|
40
|
+
});
|
|
41
|
+
it('lists a project allocations, optionally filtered by category', async () => {
|
|
42
|
+
const toArray = jest.fn().mockResolvedValue([]);
|
|
43
|
+
const sort = jest.fn().mockReturnValue({ toArray });
|
|
44
|
+
const find = jest.fn().mockReturnValue({ sort });
|
|
45
|
+
jest.spyOn(TimeTrackingProjectAllocationModel, 'db', 'get').mockReturnValue({ find });
|
|
46
|
+
await TimeTrackingProjectAllocationsService.listTimeTrackingProjectAllocations('team-website', 'design', options);
|
|
47
|
+
expect(find).toHaveBeenCalledWith({ company: 'company', project: 'project', timeTrackingProject: 'team-website', category: 'design' }, { projection: { history: 0 } });
|
|
48
|
+
expect(sort).toHaveBeenCalledWith({ user: 1 });
|
|
49
|
+
});
|
|
50
|
+
it('creates an allocation owned by the tenant when the category budget allows it', async () => {
|
|
51
|
+
mockProject();
|
|
52
|
+
mockAllocations([40]);
|
|
53
|
+
const create = jest.spyOn(TimeTrackingProjectAllocationsService, 'create').mockResolvedValue({ _id: new ObjectId() });
|
|
54
|
+
jest.spyOn(TimeTrackingProjectAllocationsService, 'singleTimeTrackingProjectAllocation').mockResolvedValue({ _id: new ObjectId() });
|
|
55
|
+
await TimeTrackingProjectAllocationsService.createTimeTrackingProjectAllocation(input, options);
|
|
56
|
+
expect(create).toHaveBeenCalledWith({ ...input, company: 'company', project: 'project' }, 'user', 'app');
|
|
57
|
+
});
|
|
58
|
+
it('creates an allocation when the category has no maximum', async () => {
|
|
59
|
+
mockProject({ id: 'team-website', categories: [{ id: 'design', name: 'Design' }] });
|
|
60
|
+
mockAllocations([500]);
|
|
61
|
+
const create = jest.spyOn(TimeTrackingProjectAllocationsService, 'create').mockResolvedValue({ _id: new ObjectId() });
|
|
62
|
+
jest.spyOn(TimeTrackingProjectAllocationsService, 'singleTimeTrackingProjectAllocation').mockResolvedValue({ _id: new ObjectId() });
|
|
63
|
+
await TimeTrackingProjectAllocationsService.createTimeTrackingProjectAllocation(input, options);
|
|
64
|
+
expect(create).toHaveBeenCalled();
|
|
65
|
+
});
|
|
66
|
+
it('creates an allocation without hours', async () => {
|
|
67
|
+
mockProject();
|
|
68
|
+
mockAllocations([40]);
|
|
69
|
+
const create = jest.spyOn(TimeTrackingProjectAllocationsService, 'create').mockResolvedValue({ _id: new ObjectId() });
|
|
70
|
+
jest.spyOn(TimeTrackingProjectAllocationsService, 'singleTimeTrackingProjectAllocation').mockResolvedValue({ _id: new ObjectId() });
|
|
71
|
+
await TimeTrackingProjectAllocationsService.createTimeTrackingProjectAllocation(inputWithoutHours, options);
|
|
72
|
+
expect(create).toHaveBeenCalledWith({ ...inputWithoutHours, company: 'company', project: 'project' }, 'user', 'app');
|
|
73
|
+
});
|
|
74
|
+
it('counts existing allocations without hours as zero in the category budget', async () => {
|
|
75
|
+
mockProject();
|
|
76
|
+
mockAllocations([undefined, 80, undefined]);
|
|
77
|
+
await expect(TimeTrackingProjectAllocationsService.createTimeTrackingProjectAllocation(input, options))
|
|
78
|
+
.rejects.toThrow('TIME_TRACKING_ALLOCATION_HOURS_EXCEEDED');
|
|
79
|
+
});
|
|
80
|
+
it('does not count a new allocation without hours against the category budget', async () => {
|
|
81
|
+
mockProject({ id: 'team-website', categories: [{ id: 'design', name: 'Design', maximumHours: 40 }] });
|
|
82
|
+
mockAllocations([40]);
|
|
83
|
+
jest.spyOn(TimeTrackingProjectAllocationsService, 'create').mockResolvedValue({ _id: new ObjectId() });
|
|
84
|
+
jest.spyOn(TimeTrackingProjectAllocationsService, 'singleTimeTrackingProjectAllocation').mockResolvedValue({ _id: new ObjectId() });
|
|
85
|
+
await TimeTrackingProjectAllocationsService.createTimeTrackingProjectAllocation(inputWithoutHours, options);
|
|
86
|
+
expect(TimeTrackingProjectAllocationsService.create).toHaveBeenCalled();
|
|
87
|
+
});
|
|
88
|
+
it('rejects an allocation for a missing project', async () => {
|
|
89
|
+
mockProject(null);
|
|
90
|
+
await expect(TimeTrackingProjectAllocationsService.createTimeTrackingProjectAllocation(input, options))
|
|
91
|
+
.rejects.toThrow('TIME_TRACKING_PROJECT_NOT_FOUND');
|
|
92
|
+
});
|
|
93
|
+
it('rejects an allocation for a missing category', async () => {
|
|
94
|
+
mockProject({ id: 'team-website', categories: [] });
|
|
95
|
+
await expect(TimeTrackingProjectAllocationsService.createTimeTrackingProjectAllocation(input, options))
|
|
96
|
+
.rejects.toThrow('TIME_TRACKING_CATEGORY_NOT_FOUND');
|
|
97
|
+
});
|
|
98
|
+
it('rejects an allocation for a shift-based plan without categories', async () => {
|
|
99
|
+
mockProject({ id: 'team-website', modes: 'shifts', shiftPlan: '507f1f77bcf86cd799439011' });
|
|
100
|
+
await expect(TimeTrackingProjectAllocationsService.createTimeTrackingProjectAllocation(input, options))
|
|
101
|
+
.rejects.toThrow('TIME_TRACKING_CATEGORY_NOT_FOUND');
|
|
102
|
+
});
|
|
103
|
+
it('rejects an allocation that would exceed the category budget', async () => {
|
|
104
|
+
mockProject();
|
|
105
|
+
mockAllocations([80]);
|
|
106
|
+
await expect(TimeTrackingProjectAllocationsService.createTimeTrackingProjectAllocation(input, options))
|
|
107
|
+
.rejects.toThrow('TIME_TRACKING_ALLOCATION_HOURS_EXCEEDED');
|
|
108
|
+
});
|
|
109
|
+
it('changes an allocation while excluding its own hours from the budget', async () => {
|
|
110
|
+
const _id = new ObjectId();
|
|
111
|
+
jest.spyOn(TimeTrackingProjectAllocationsService, 'singleTimeTrackingProjectAllocation').mockResolvedValue({ _id, timeTrackingProject: 'team-website', category: 'design' });
|
|
112
|
+
mockProject();
|
|
113
|
+
mockAllocations([]);
|
|
114
|
+
const immutable = jest.spyOn(TimeTrackingProjectAllocationsService, 'immutable').mockResolvedValue({});
|
|
115
|
+
await TimeTrackingProjectAllocationsService.changeTimeTrackingProjectAllocation(_id, { hours: 30 }, options);
|
|
116
|
+
expect(immutable).toHaveBeenCalledWith({ _id, company: 'company', project: 'project' }, { hours: 30 }, 'user', 'change', 'app');
|
|
117
|
+
});
|
|
118
|
+
it('clears the hour limit when changing an allocation to null', async () => {
|
|
119
|
+
const _id = new ObjectId();
|
|
120
|
+
jest.spyOn(TimeTrackingProjectAllocationsService, 'singleTimeTrackingProjectAllocation').mockResolvedValue({ _id, timeTrackingProject: 'team-website', category: 'design' });
|
|
121
|
+
mockProject({ id: 'team-website', categories: [{ id: 'design', name: 'Design', maximumHours: 40 }] });
|
|
122
|
+
mockAllocations([40]);
|
|
123
|
+
const immutable = jest.spyOn(TimeTrackingProjectAllocationsService, 'immutable').mockResolvedValue({});
|
|
124
|
+
await TimeTrackingProjectAllocationsService.changeTimeTrackingProjectAllocation(_id, { hours: null }, options);
|
|
125
|
+
expect(immutable).toHaveBeenCalledWith({ _id, company: 'company', project: 'project' }, { hours: null }, 'user', 'change', 'app', undefined, undefined, undefined, { unset: ['hours'] });
|
|
126
|
+
});
|
|
127
|
+
it('rejects changing a missing allocation', async () => {
|
|
128
|
+
jest.spyOn(TimeTrackingProjectAllocationsService, 'singleTimeTrackingProjectAllocation').mockResolvedValue(null);
|
|
129
|
+
await expect(TimeTrackingProjectAllocationsService.changeTimeTrackingProjectAllocation(new ObjectId(), { hours: 30 }, options))
|
|
130
|
+
.rejects.toThrow('TIME_TRACKING_ALLOCATION_NOT_FOUND');
|
|
131
|
+
});
|
|
132
|
+
it('rejects a change that would exceed the category budget', async () => {
|
|
133
|
+
const _id = new ObjectId();
|
|
134
|
+
jest.spyOn(TimeTrackingProjectAllocationsService, 'singleTimeTrackingProjectAllocation').mockResolvedValue({ _id, timeTrackingProject: 'team-website', category: 'design' });
|
|
135
|
+
mockProject();
|
|
136
|
+
mockAllocations([90]);
|
|
137
|
+
await expect(TimeTrackingProjectAllocationsService.changeTimeTrackingProjectAllocation(_id, { hours: 30 }, options))
|
|
138
|
+
.rejects.toThrow('TIME_TRACKING_ALLOCATION_HOURS_EXCEEDED');
|
|
139
|
+
});
|
|
140
|
+
it('removes an allocation', async () => {
|
|
141
|
+
const _id = new ObjectId();
|
|
142
|
+
jest.spyOn(TimeTrackingProjectAllocationsService, 'singleTimeTrackingProjectAllocation').mockResolvedValue({ _id });
|
|
143
|
+
const remove = jest.spyOn(TimeTrackingProjectAllocationsService, 'delete').mockResolvedValue({ acknowledged: true, deletedCount: 1 });
|
|
144
|
+
await TimeTrackingProjectAllocationsService.removeTimeTrackingProjectAllocation(_id, options);
|
|
145
|
+
expect(remove).toHaveBeenCalledWith(_id, 'user', 'app');
|
|
146
|
+
});
|
|
147
|
+
it('rejects removing a missing allocation', async () => {
|
|
148
|
+
jest.spyOn(TimeTrackingProjectAllocationsService, 'singleTimeTrackingProjectAllocation').mockResolvedValue(null);
|
|
149
|
+
await expect(TimeTrackingProjectAllocationsService.removeTimeTrackingProjectAllocation(new ObjectId(), options))
|
|
150
|
+
.rejects.toThrow('TIME_TRACKING_ALLOCATION_NOT_FOUND');
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
//# sourceMappingURL=timeTrackingProjectAllocationsService.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeTrackingProjectAllocationsService.spec.js","sourceRoot":"","sources":["../../tests/timeTrackingProjectAllocationsService.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { describe, expect, it } from '@jest/globals';
|
|
2
|
+
import Models from '../src/classes/models.class';
|
|
3
|
+
import TimeTrackingProjectModel from '../src/models/timeTrackingProject.model';
|
|
4
|
+
const models = new Models();
|
|
5
|
+
models.register('timeTrackingProject', TimeTrackingProjectModel);
|
|
6
|
+
const validProject = {
|
|
7
|
+
id: 'team-website',
|
|
8
|
+
company: 'lilaquadrat',
|
|
9
|
+
project: 'studio',
|
|
10
|
+
name: 'Website',
|
|
11
|
+
description: 'Redesign of the public site',
|
|
12
|
+
maximumHours: 120,
|
|
13
|
+
modes: 'fromTo',
|
|
14
|
+
categories: [{ id: 'design', name: 'Design', maximumHours: 40, costsPerHour: 80 }],
|
|
15
|
+
};
|
|
16
|
+
const validChange = {
|
|
17
|
+
name: 'Website',
|
|
18
|
+
description: 'Updated',
|
|
19
|
+
maximumHours: 80,
|
|
20
|
+
modes: 'fromTo',
|
|
21
|
+
categories: [{ id: 'design', name: 'Design', maximumHours: 30, costsPerHour: 90 }],
|
|
22
|
+
};
|
|
23
|
+
describe('TimeTrackingProjectModel', () => {
|
|
24
|
+
it('accepts a complete time tracking project', () => {
|
|
25
|
+
expect(TimeTrackingProjectModel.validate(validProject, 'create')).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
it('requires id, company, project and name', () => {
|
|
28
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, id: undefined }, 'create')).toBe(false);
|
|
29
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, company: undefined }, 'create')).toBe(false);
|
|
30
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, project: undefined }, 'create')).toBe(false);
|
|
31
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, name: undefined }, 'create')).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
it('allows a project without categories for a shift-based plan', () => {
|
|
34
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, modes: 'shifts', shiftPlan: '507f1f77bcf86cd799439011', categories: undefined }, 'create')).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
it('requires a mode', () => {
|
|
37
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, modes: undefined }, 'create')).toBe(false);
|
|
38
|
+
});
|
|
39
|
+
it('rejects an unknown mode', () => {
|
|
40
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, modes: 'weekly' }, 'create')).toBe(false);
|
|
41
|
+
});
|
|
42
|
+
it('accepts every supported mode', () => {
|
|
43
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, modes: 'hours' }, 'create')).toBe(true);
|
|
44
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, modes: 'fromTo' }, 'create')).toBe(true);
|
|
45
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, modes: 'multiDay' }, 'create')).toBe(true);
|
|
46
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, modes: 'shifts' }, 'create')).toBe(true);
|
|
47
|
+
});
|
|
48
|
+
it('allows a project without a description', () => {
|
|
49
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, description: undefined }, 'create')).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
it('allows a project without a maximum hours budget', () => {
|
|
52
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, maximumHours: undefined }, 'create')).toBe(true);
|
|
53
|
+
});
|
|
54
|
+
it('accepts a maximum hours per day', () => {
|
|
55
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, maximumHoursPerDay: 8 }, 'create')).toBe(true);
|
|
56
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, maximumHoursPerDay: 24 }, 'create')).toBe(true);
|
|
57
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, maximumHoursPerDay: undefined }, 'create')).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
it('rejects an invalid maximum hours per day', () => {
|
|
60
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, maximumHoursPerDay: 0 }, 'create')).toBe(false);
|
|
61
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, maximumHoursPerDay: 25 }, 'create')).toBe(false);
|
|
62
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, maximumHoursPerDay: 'eight' }, 'create')).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
it('accepts a maximum hours per day on change', () => {
|
|
65
|
+
expect(TimeTrackingProjectModel.validate({ ...validChange, maximumHoursPerDay: 6 }, 'change')).toBe(true);
|
|
66
|
+
});
|
|
67
|
+
it('allows an empty category list', () => {
|
|
68
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, categories: [] }, 'create')).toBe(true);
|
|
69
|
+
});
|
|
70
|
+
it('validates the shape of every category', () => {
|
|
71
|
+
const withCategory = (category) => TimeTrackingProjectModel.validate({ ...validProject, categories: [category] }, 'create');
|
|
72
|
+
expect(withCategory({ name: 'Design', maximumHours: 40, costsPerHour: 80 })).toBe(false);
|
|
73
|
+
expect(withCategory({ id: 'design', maximumHours: 40, costsPerHour: 80 })).toBe(false);
|
|
74
|
+
expect(withCategory({ id: 'design', name: 'Design', maximumHours: 0, costsPerHour: 80 })).toBe(false);
|
|
75
|
+
expect(withCategory({ id: 'design', name: 'Design', maximumHours: 40, costsPerHour: -1 })).toBe(false);
|
|
76
|
+
expect(withCategory({ id: 'design', name: 'Design', maximumHours: 40, costsPerHour: 80, extra: true })).toBe(false);
|
|
77
|
+
});
|
|
78
|
+
it('allows a category without hours and hourly cost', () => {
|
|
79
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, categories: [{ id: 'design', name: 'Design' }] }, 'create')).toBe(true);
|
|
80
|
+
});
|
|
81
|
+
it('allows a category with only a maximum or only an hourly cost', () => {
|
|
82
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, categories: [{ id: 'design', name: 'Design', maximumHours: 40 }] }, 'create')).toBe(true);
|
|
83
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, categories: [{ id: 'design', name: 'Design', costsPerHour: 80 }] }, 'create')).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
it('accepts a category with a zero hourly cost', () => {
|
|
86
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, categories: [{ id: 'design', name: 'Design', maximumHours: 40, costsPerHour: 0 }] }, 'create')).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
it('rejects a negative category hourly cost', () => {
|
|
89
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, categories: [{ id: 'design', name: 'Design', maximumHours: 40, costsPerHour: -1 }] }, 'create')).toBe(false);
|
|
90
|
+
});
|
|
91
|
+
it('rejects a maximum of zero or less', () => {
|
|
92
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, maximumHours: 0 }, 'create')).toBe(false);
|
|
93
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, maximumHours: -1 }, 'create')).toBe(false);
|
|
94
|
+
});
|
|
95
|
+
it('rejects an id outside the slug pattern', () => {
|
|
96
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, id: 'Team Website' }, 'create')).toBe(false);
|
|
97
|
+
});
|
|
98
|
+
it('accepts a shift plan for a shifts project', () => {
|
|
99
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, modes: 'shifts', shiftPlan: '507f1f77bcf86cd799439011' }, 'create')).toBe(true);
|
|
100
|
+
});
|
|
101
|
+
it('allows a shifts project without a shift plan', () => {
|
|
102
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, modes: 'shifts', shiftPlan: undefined }, 'create')).toBe(true);
|
|
103
|
+
});
|
|
104
|
+
it('rejects a shift plan that is not a 24 character hex id', () => {
|
|
105
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, modes: 'shifts', shiftPlan: 'plan-1' }, 'create')).toBe(false);
|
|
106
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, modes: 'shifts', shiftPlan: '507F1F77BCF86CD799439011' }, 'create')).toBe(false);
|
|
107
|
+
});
|
|
108
|
+
it('accepts a shift plan on change', () => {
|
|
109
|
+
expect(TimeTrackingProjectModel.validate({ ...validChange, modes: 'shifts', shiftPlan: '507f1f77bcf86cd799439011' }, 'change')).toBe(true);
|
|
110
|
+
});
|
|
111
|
+
it('rejects unknown properties', () => {
|
|
112
|
+
expect(TimeTrackingProjectModel.validate({ ...validProject, extra: true }, 'create')).toBe(false);
|
|
113
|
+
});
|
|
114
|
+
it('allows name, description, maximumHours and categories to change', () => {
|
|
115
|
+
expect(TimeTrackingProjectModel.validate(validChange, 'change')).toBe(true);
|
|
116
|
+
});
|
|
117
|
+
it('ignores the mode on change', () => {
|
|
118
|
+
expect(TimeTrackingProjectModel.validate({ ...validChange, modes: undefined }, 'change')).toBe(true);
|
|
119
|
+
});
|
|
120
|
+
it('requires only the name on change', () => {
|
|
121
|
+
expect(TimeTrackingProjectModel.validate({ name: 'Website', description: 'Updated' }, 'change')).toBe(true);
|
|
122
|
+
expect(TimeTrackingProjectModel.validate({ name: 'Website', maximumHours: 80 }, 'change')).toBe(true);
|
|
123
|
+
expect(TimeTrackingProjectModel.validate({ ...validChange, categories: undefined }, 'change')).toBe(true);
|
|
124
|
+
expect(TimeTrackingProjectModel.validate({ name: 'Website', categories: [{ id: 'design', name: 'Design', maximumHours: 30, costsPerHour: 90 }] }, 'change')).toBe(true);
|
|
125
|
+
expect(TimeTrackingProjectModel.validate({ description: 'Updated' }, 'change')).toBe(false);
|
|
126
|
+
});
|
|
127
|
+
it('validates the categories that are sent on change', () => {
|
|
128
|
+
expect(TimeTrackingProjectModel.validate({ ...validChange, categories: [{ id: 'design' }] }, 'change')).toBe(false);
|
|
129
|
+
});
|
|
130
|
+
it('rejects edits to the immutable tenant and id', () => {
|
|
131
|
+
expect(TimeTrackingProjectModel.validate({ ...validChange, id: 'other' }, 'change')).toBe(false);
|
|
132
|
+
expect(TimeTrackingProjectModel.validate({ ...validChange, company: 'other' }, 'change')).toBe(false);
|
|
133
|
+
});
|
|
134
|
+
it('marks id, company, project and modes as immutable', () => {
|
|
135
|
+
expect(TimeTrackingProjectModel.immutable).toContain('id');
|
|
136
|
+
expect(TimeTrackingProjectModel.immutable).toContain('company');
|
|
137
|
+
expect(TimeTrackingProjectModel.immutable).toContain('project');
|
|
138
|
+
expect(TimeTrackingProjectModel.immutable).toContain('modes');
|
|
139
|
+
});
|
|
140
|
+
it('keeps the shift plan editable', () => {
|
|
141
|
+
expect(TimeTrackingProjectModel.immutable).not.toContain('shiftPlan');
|
|
142
|
+
});
|
|
143
|
+
it('defines a unique id per company and project', () => {
|
|
144
|
+
expect(TimeTrackingProjectModel.indexes).toContainEqual(expect.objectContaining({
|
|
145
|
+
key: { company: 1, project: 1, id: 1 },
|
|
146
|
+
unique: true,
|
|
147
|
+
name: 'company_project_id-v1',
|
|
148
|
+
}));
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
//# sourceMappingURL=timeTrackingProjectModel.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeTrackingProjectModel.spec.js","sourceRoot":"","sources":["../../tests/timeTrackingProjectModel.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|