37 lines
1.2 KiB
TypeScript
37 lines
1.2 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { base64UrlToBytes } from '@/utils/encoding/base64UrlToBytes';
|
|
import { bytesToBase64Url } from '@/utils/encoding/bytesToBase64Url';
|
|
|
|
const BASE64URL_PATTERN = /^[A-Za-z0-9_-]*$/;
|
|
|
|
describe('bytesToBase64Url', () => {
|
|
it('uses only URL-safe characters and omits padding', () => {
|
|
const bytes = new Uint8Array([255, 254, 253, 252, 251, 250]);
|
|
|
|
const encoded = bytesToBase64Url(bytes);
|
|
|
|
expect(BASE64URL_PATTERN.test(encoded)).toBe(true);
|
|
expect(encoded.includes('+')).toBe(false);
|
|
expect(encoded.includes('/')).toBe(false);
|
|
expect(encoded.includes('=')).toBe(false);
|
|
});
|
|
|
|
it('roundtrips with base64UrlToBytes', () => {
|
|
for (const length of [0, 1, 2, 3, 4, 12, 16, 32, 64]) {
|
|
const bytes = new Uint8Array(length);
|
|
|
|
crypto.getRandomValues(bytes);
|
|
|
|
expect(base64UrlToBytes(bytesToBase64Url(bytes))).toEqual(bytes);
|
|
}
|
|
});
|
|
|
|
it('differs from standard base64 when URL encoding is required', () => {
|
|
const bytes = new Uint8Array([251, 255, 255]);
|
|
|
|
expect(bytesToBase64Url(bytes)).not.toBe(
|
|
btoa(Array.from(bytes, b => String.fromCharCode(b)).join(''))
|
|
);
|
|
});
|
|
});
|