| 1 | import { assert, describe, it } from "@effect/vitest" |
| 2 | import { Result } from "effect" |
| 3 | import * as Base64Url from "effect/encoding/Base64Url" |
| 4 | |
| 5 | describe("Base64Url", () => { |
| 6 | it("encodes strings and bytes without padding", () => { |
| 7 | assert.strictEqual(Base64Url.encode("hello?"), "aGVsbG8_") |
| 8 | assert.strictEqual(Base64Url.encode(new Uint8Array([251, 255])), "-_8") |
| 9 | }) |
| 10 | |
| 11 | it("decodes padded and unpadded input", () => { |
| 12 | const expected = new Uint8Array([72, 101, 108, 108, 111, 63]) |
| 13 | assert.deepStrictEqual(Result.getOrThrow(Base64Url.decode("SGVsbG8_")), expected) |
| 14 | assert.deepStrictEqual(Result.getOrThrow(Base64Url.decode("-_8=")), new Uint8Array([251, 255])) |
| 15 | assert.strictEqual(Result.getOrThrow(Base64Url.decodeString("8J-Riw")), "👋") |
| 16 | assert.strictEqual(Result.getOrThrow(Base64Url.decodeString("8J-Riw==")), "👋") |
| 17 | }) |
| 18 | |
| 19 | it("rejects the standard Base64 alphabet and malformed lengths", () => { |
| 20 | const invalidAlphabet = Base64Url.decode("+/8=") |
| 21 | assert.isTrue(Result.isFailure(invalidAlphabet)) |
| 22 | if (Result.isFailure(invalidAlphabet)) { |
| 23 | assert.strictEqual(invalidAlphabet.failure.kind, "Decode") |
| 24 | assert.strictEqual(invalidAlphabet.failure.module, "Base64Url") |
| 25 | assert.strictEqual(invalidAlphabet.failure.input, "+/8=") |
| 26 | } |
| 27 | |
| 28 | assert.isTrue(Result.isFailure(Base64Url.decode("a"))) |
| 29 | }) |
| 30 | |
| 31 | it("rejects malformed padding", () => { |
| 32 | for (const input of ["SGVsbG8_=", "SGVsbG8_==", "AAAA=", "AAAA==", "AAA=="]) { |
| 33 | assert.isTrue(Result.isFailure(Base64Url.decode(input)), input) |
| 34 | } |
| 35 | }) |
| 36 | }) |