Files
rentall-app/backend/tests/unit/utils/s3KeyValidator.test.js
2025-12-12 13:33:24 -05:00

113 lines
4.3 KiB
JavaScript

const { validateS3Keys } = require('../../../utils/s3KeyValidator');
describe('S3 Key Validator', () => {
describe('validateS3Keys', () => {
const validUuid1 = '550e8400-e29b-41d4-a716-446655440000';
const validUuid2 = '660e8400-e29b-41d4-a716-446655440001';
test('should accept valid arrays of keys', () => {
const keys = [
`items/${validUuid1}.jpg`,
`items/${validUuid2}.png`,
];
expect(validateS3Keys(keys, 'items')).toEqual({ valid: true });
});
test('should accept valid keys for each folder', () => {
expect(validateS3Keys([`profiles/${validUuid1}.jpg`], 'profiles')).toEqual({ valid: true });
expect(validateS3Keys([`items/${validUuid1}.png`], 'items')).toEqual({ valid: true });
expect(validateS3Keys([`messages/${validUuid1}.gif`], 'messages')).toEqual({ valid: true });
expect(validateS3Keys([`forum/${validUuid1}.webp`], 'forum')).toEqual({ valid: true });
expect(validateS3Keys([`condition-checks/${validUuid1}.jpeg`], 'condition-checks')).toEqual({ valid: true });
});
test('should accept different valid extensions', () => {
const extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
for (const ext of extensions) {
expect(validateS3Keys([`items/${validUuid1}.${ext}`], 'items')).toEqual({ valid: true });
}
});
test('should be case-insensitive for extensions', () => {
expect(validateS3Keys([`items/${validUuid1}.JPG`], 'items')).toEqual({ valid: true });
expect(validateS3Keys([`items/${validUuid1}.PNG`], 'items')).toEqual({ valid: true });
});
test('should accept empty arrays', () => {
expect(validateS3Keys([], 'items')).toEqual({ valid: true });
});
test('should reject non-array input', () => {
const result = validateS3Keys('not-an-array', 'items');
expect(result.valid).toBe(false);
expect(result.error).toBe('Keys must be an array');
});
test('should reject arrays exceeding maxKeys', () => {
const keys = Array(6).fill(`items/${validUuid1}.jpg`);
const result = validateS3Keys(keys, 'items', { maxKeys: 5 });
expect(result.valid).toBe(false);
expect(result.error).toContain('Maximum 5 keys allowed');
});
test('should reject duplicate keys', () => {
const keys = [
`items/${validUuid1}.jpg`,
`items/${validUuid1}.jpg`,
];
const result = validateS3Keys(keys, 'items');
expect(result.valid).toBe(false);
expect(result.error).toBe('Duplicate keys not allowed');
});
test('should reject keys with wrong folder prefix', () => {
const result = validateS3Keys([`profiles/${validUuid1}.jpg`], 'items');
expect(result.valid).toBe(false);
expect(result.invalidKeys).toHaveLength(1);
});
test('should reject invalid UUID format', () => {
const result = validateS3Keys(['items/invalid-uuid.jpg'], 'items');
expect(result.valid).toBe(false);
});
test('should reject non-image extensions', () => {
const result = validateS3Keys([`items/${validUuid1}.exe`], 'items');
expect(result.valid).toBe(false);
});
test('should reject path traversal attempts', () => {
const result = validateS3Keys([`../items/${validUuid1}.jpg`], 'items');
expect(result.valid).toBe(false);
});
test('should reject empty or null keys in array', () => {
expect(validateS3Keys([''], 'items').valid).toBe(false);
expect(validateS3Keys([null], 'items').valid).toBe(false);
});
test('should reject invalid folder names', () => {
const result = validateS3Keys([`items/${validUuid1}.jpg`], 'invalid-folder');
expect(result.valid).toBe(false);
});
test('should return invalid keys in error response', () => {
const keys = [
`items/${validUuid1}.jpg`,
'invalid-key.jpg',
`items/${validUuid2}.exe`,
];
const result = validateS3Keys(keys, 'items');
expect(result.valid).toBe(false);
expect(result.invalidKeys).toHaveLength(2);
});
test('should use default maxKeys of 20', () => {
const keys = Array(20).fill(0).map((_, i) =>
`items/550e8400-e29b-41d4-a716-44665544${String(i).padStart(4, '0')}.jpg`
);
expect(validateS3Keys(keys, 'items')).toEqual({ valid: true });
});
});
});