@userfront/core
Version:
Userfront core JS library
69 lines (67 loc) • 3.38 kB
JavaScript
import { getJwtPayload } from "../src/utils";
import { createIdToken } from "./config/utils";
import * as fc from "fast-check";
describe("utils", () => {
describe("getJwtPayload", () => {
it("should correctly decode a JWT containing printable ASCII characters", () => {
// A property-based test using fast-check: https://fast-check.dev/
// An assertion: execute a property, and throw if it fails
fc.assert(
// A property: asserts that, given some specified data generated by one or more "arbitraries",
// a "predicate" is true.
// Read a property as a statement:
// For any x, y, ... -> the arbitraries
// that fulfill the conditions a, b, ... -> filters on the arbitraries
// the predicates p, q, ... are always true. -> the predicate
fc.property(
// An arbitrary printable ASCII string, between length 1 and 100
fc.string({ minLength: 1, maxLength: 100 }),
// The predicate - the fact that we assert about our program
// Taken together, read the test as:
// For any printable ASCII string,
// that is between 1 and 100 characters long,
// it is always true that, when we encode it into a JWT and then decode it,
// the resulting string is equal to the original string
// To run the test, fast-check generates many arbitrary values and tests the predicate for each.
// If a failure is found, it progressively "shrinks" the arbitrary to produce a minimal counterexample.
//
// For example, if getJwtPayload throws for strings that contain "Z", the initial failure might
// be a string like "asd81*s=Z92,. zka9*". The shrinking process will test "smaller" values until
// it finds the "smallest" value that fails the test, "Z", and report that as the counterexample.
//
// (The precise meaning of "smaller" depends on the arbitrary, but it's usually intuitive: shorter strings,
// smaller numbers, arrays with fewer elements, objects with fewer fields, ...)
(name) => {
const token = createIdToken({ name });
const payload = getJwtPayload(token);
// A predicate fails if it returns false or throws.
// We can use Jest assertions, so we could also write
// expect(payload.name).toBe(name);
return payload.name === name;
}
)
);
});
// Property-based test for DEV-228 (accents are modified in user's name upon login) is fixed
it("should correctly decode a JWT containing characters from the full Unicode space", () => {
fc.assert(
fc.property(
fc.fullUnicodeString({ minLength: 1, maxLength: 100 })
.map((str) => JSON.parse(JSON.stringify({ str })).str),
(name) => {
const token = createIdToken({ name });
const payload = getJwtPayload(token);
return payload.name === name;
}
)
);
})
// Example-based test for DEV-228
it("should correctly decode a JWT containing the string 'foo bår'", () => {
const name = "foo bãr";
const token = createIdToken({ name });
const payload = getJwtPayload(token);
expect(payload.name).toBe(name);
})
});
});