Files
wehub-resource-sync 070959e133
landing-page-staging / Deploy landing page to staging (push) Has been skipped
landing-page-ci / Validate landing page (push) Failing after 4s
visual-baseline / Capture visual baselines (push) Has been cancelled
bake-plugin-previews / Bake plugin previews (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:00:47 +08:00

95 lines
2.9 KiB
TypeScript

// @vitest-environment jsdom
import { describe, expect, it } from 'vitest';
import { deriveUploadCohort } from '../../src/analytics/upload-tracking';
// `deriveUploadCohort` only reads `name`, `type`, `size` — keep the
// fixture lightweight so 100 MB boundary cases don't allocate real bytes.
function makeFile(name: string, type: string, size: number): File {
return { name, type, size } as unknown as File;
}
describe('deriveUploadCohort', () => {
it('classifies a homogeneous image batch as image', () => {
const cohort = deriveUploadCohort([
makeFile('a.png', 'image/png', 1024),
makeFile('b.jpg', 'image/jpeg', 2048),
]);
expect(cohort).toEqual({
file_count: 2,
file_type: 'image',
file_size_bucket: '0_1mb',
});
});
it('detects zip by MIME', () => {
const cohort = deriveUploadCohort([
makeFile('bundle.zip', 'application/zip', 500),
]);
expect(cohort.file_type).toBe('zip');
});
it('detects zip by .zip extension when MIME is missing', () => {
const cohort = deriveUploadCohort([
makeFile('bundle.ZIP', '', 500),
makeFile('also.zip', 'application/octet-stream', 500),
]);
expect(cohort.file_type).toBe('zip');
});
it('collapses mixed-type batches to other', () => {
const cohort = deriveUploadCohort([
makeFile('a.png', 'image/png', 100),
makeFile('b.pdf', 'application/pdf', 100),
]);
expect(cohort.file_type).toBe('other');
});
it('returns other for an empty batch', () => {
expect(deriveUploadCohort([])).toEqual({
file_count: 0,
file_type: 'other',
file_size_bucket: '0_1mb',
});
});
it('buckets total bytes across the 1/10/100 MB thresholds', () => {
const MB = 1024 * 1024;
const cases: Array<{ total: number; bucket: string }> = [
{ total: MB - 1, bucket: '0_1mb' },
{ total: MB, bucket: '1_10mb' },
{ total: 10 * MB - 1, bucket: '1_10mb' },
{ total: 10 * MB, bucket: '10_100mb' },
{ total: 100 * MB - 1, bucket: '10_100mb' },
{ total: 100 * MB, bucket: '100mb_plus' },
];
for (const { total, bucket } of cases) {
const cohort = deriveUploadCohort([
makeFile('blob.bin', 'application/octet-stream', total),
]);
expect(cohort.file_size_bucket, `total=${total}`).toBe(bucket);
}
});
it('sums sizes across multiple files for the bucket', () => {
const MB = 1024 * 1024;
const cohort = deriveUploadCohort([
makeFile('a.png', 'image/png', 0.6 * MB),
makeFile('b.png', 'image/png', 0.6 * MB),
]);
expect(cohort.file_size_bucket).toBe('1_10mb');
});
it('treats missing size/type defensively', () => {
const cohort = deriveUploadCohort([
{ name: 'x', type: '', size: 0 } as unknown as File,
]);
expect(cohort).toEqual({
file_count: 1,
file_type: 'other',
file_size_bucket: '0_1mb',
});
});
});