94 lines
3.6 KiB
JavaScript
94 lines
3.6 KiB
JavaScript
|
|
/**
|
||
|
|
* Property-Based Tests: FP Submissions Cleanup
|
||
|
|
*
|
||
|
|
* Feature: fp-submissions-cleanup
|
||
|
|
*
|
||
|
|
* Tests the pure filtering functions used to determine which FP submissions
|
||
|
|
* are visible in the Queue Panel and which show the dismiss button.
|
||
|
|
*
|
||
|
|
* Validates: Requirements 1.1, 2.1, 2.2, 2.3
|
||
|
|
*/
|
||
|
|
|
||
|
|
const fc = require('fast-check');
|
||
|
|
const { filterVisibleSubmissions, shouldShowDismissButton } = require('../routes/ivantiFpWorkflow');
|
||
|
|
|
||
|
|
// --- Generators ---
|
||
|
|
|
||
|
|
const lifecycleStatusArb = fc.constantFrom('submitted', 'approved', 'rejected', 'rework', 'resubmitted');
|
||
|
|
|
||
|
|
const dismissedAtArb = fc.oneof(
|
||
|
|
fc.constant(null),
|
||
|
|
fc.date({ min: new Date('2020-01-01'), max: new Date('2030-12-31') }).map(d => d.toISOString())
|
||
|
|
);
|
||
|
|
|
||
|
|
const submissionArb = fc.record({
|
||
|
|
id: fc.integer({ min: 1, max: 100000 }),
|
||
|
|
lifecycle_status: lifecycleStatusArb,
|
||
|
|
dismissed_at: dismissedAtArb,
|
||
|
|
user_id: fc.integer({ min: 1, max: 1000 }),
|
||
|
|
ivanti_workflow_batch_id: fc.string({ minLength: 1, maxLength: 20 })
|
||
|
|
});
|
||
|
|
|
||
|
|
const submissionsArrayArb = fc.array(submissionArb, { minLength: 0, maxLength: 50 });
|
||
|
|
|
||
|
|
// --- Property 1: Submission Visibility Filter ---
|
||
|
|
|
||
|
|
describe('Feature: fp-submissions-cleanup, Property 1: Submission Visibility Filter', () => {
|
||
|
|
/**
|
||
|
|
* For any array of FP submission objects with arbitrary lifecycle_status values
|
||
|
|
* and arbitrary dismissed_at values, filterVisibleSubmissions(submissions) should
|
||
|
|
* return only submissions where lifecycle_status is NOT "approved" AND dismissed_at
|
||
|
|
* is null. Additionally, every submission in the input that satisfies both conditions
|
||
|
|
* must appear in the output, and the output length must be <= input length.
|
||
|
|
*
|
||
|
|
* Validates: Requirements 1.1, 2.2, 2.3
|
||
|
|
*/
|
||
|
|
it('returns only non-approved and non-dismissed submissions', () => {
|
||
|
|
fc.assert(
|
||
|
|
fc.property(submissionsArrayArb, (submissions) => {
|
||
|
|
const result = filterVisibleSubmissions(submissions);
|
||
|
|
|
||
|
|
// Output length must be <= input length
|
||
|
|
expect(result.length).toBeLessThanOrEqual(submissions.length);
|
||
|
|
|
||
|
|
// Every item in the result must be non-approved and non-dismissed
|
||
|
|
for (const s of result) {
|
||
|
|
expect(s.lifecycle_status).not.toBe('approved');
|
||
|
|
expect(s.dismissed_at).toBeNull();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Every input item that satisfies both conditions must appear in the output
|
||
|
|
const expected = submissions.filter(
|
||
|
|
s => s.lifecycle_status !== 'approved' && s.dismissed_at == null
|
||
|
|
);
|
||
|
|
expect(result).toEqual(expected);
|
||
|
|
}),
|
||
|
|
{ numRuns: 100 }
|
||
|
|
);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
// --- Property 2: Dismiss Button Visibility Predicate ---
|
||
|
|
|
||
|
|
describe('Feature: fp-submissions-cleanup, Property 2: Dismiss Button Visibility Predicate', () => {
|
||
|
|
/**
|
||
|
|
* For any FP submission object with a lifecycle_status value drawn from
|
||
|
|
* {submitted, approved, rejected, rework, resubmitted} and a dismissed_at value
|
||
|
|
* (null or timestamp), the dismiss button should be rendered if and only if
|
||
|
|
* lifecycle_status === 'rejected' AND dismissed_at is null.
|
||
|
|
*
|
||
|
|
* Validates: Requirements 2.1
|
||
|
|
*/
|
||
|
|
it('returns true iff status is rejected and dismissed_at is null', () => {
|
||
|
|
fc.assert(
|
||
|
|
fc.property(submissionArb, (submission) => {
|
||
|
|
const result = shouldShowDismissButton(submission);
|
||
|
|
const expected = submission.lifecycle_status === 'rejected' && submission.dismissed_at == null;
|
||
|
|
|
||
|
|
expect(result).toBe(expected);
|
||
|
|
}),
|
||
|
|
{ numRuns: 100 }
|
||
|
|
);
|
||
|
|
});
|
||
|
|
});
|