import { Base64 } from 'js-base64' import { diff } from 'jest-diff' // Reference: https://jestjs.io/docs/expect#custom-matchers-api const base64Matchers = (): jest.ExpectExtendMap => ({ /** * Compares a Base64-encoded object to an expected JS value. * This approach of decoding first avoids false-negatives associated with different ordering of object keys. */ base64ToEqual(actual: string, expected: unknown): jest.CustomMatcherResult { const options = { comment: 'Base64 parsed and equal', isNot: this.isNot, promise: this.promise, } let decoded try { decoded = Base64.decode(actual) } catch (err) { const errMessage = err && typeof err === 'object' && (err as Error).message return { pass: false, message: () => `Failed to decode Base64: ${errMessage}`, } } let parsed: unknown try { parsed = JSON.parse(decoded) } catch (err) { const errMessage = err && typeof err === 'object' && (err as Error).message return { pass: false, message: () => `Failed to parse as JSON: ${errMessage}`, } } const pass = this.equals(parsed, expected) let message: () => string if (pass) { message = () => `${this.utils.matcherHint( 'base64ToEqual', undefined, undefined, options )}\n\n` + `Expected: not ${this.utils.printExpected(expected)}\n` + `Received: ${this.utils.printReceived(parsed)}` } else { message = () => { const diffString = diff(expected, parsed, { expand: this.expand, }) let result = `${this.utils.matcherHint( 'base64ToEqual', undefined, undefined, options )}\n\n` if (diffString && diffString.includes('- Expect')) { result += `Difference:\n\n${diffString}` } else { result += `Expected: ${this.utils.printExpected(expected)}\n` + `Received: ${this.utils.printReceived(parsed)}` } return result } } return { message, pass, } }, }) export default base64Matchers