From e4e7ba158771298e5c6ee712a2c66c2042aa2dad Mon Sep 17 00:00:00 2001 From: Alexander Cerutti Date: Tue, 11 Apr 2023 23:09:55 +0200 Subject: [PATCH] Removed old TS tests --- package.json | 3 +- spec/Bundle.ts | 123 ----- spec/FieldsArray.ts | 227 -------- spec/PKPass.ts | 1236 ------------------------------------------- spec/utils.ts | 39 -- tsconfig.spec.json | 9 - 6 files changed, 1 insertion(+), 1636 deletions(-) delete mode 100644 spec/Bundle.ts delete mode 100644 spec/FieldsArray.ts delete mode 100644 spec/PKPass.ts delete mode 100644 spec/utils.ts delete mode 100644 tsconfig.spec.json diff --git a/package.json b/package.json index 8e66226..77ec09c 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,8 @@ "main": "lib/index.js", "scripts": { "build": "npm run build:src", - "build:all": "npm run build:src && npm run build:examples && npm run build:spec", + "build:all": "npm run build:src && npm run build:examples", "build:src": "rimraf lib && npx tsc -p tsconfig.dist.json", - "build:spec": "rimraf \"./spec/*.!(ts)\" && npx tsc -p tsconfig.spec.json", "prepublishOnly": "npm run build", "test": "NODE_OPTIONS=\"--experimental-vm-modules --no-warnings\" jest -c jest.config.cjs --silent" }, diff --git a/spec/Bundle.ts b/spec/Bundle.ts deleted file mode 100644 index f418ca4..0000000 --- a/spec/Bundle.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { Stream } from "stream"; -import { Buffer } from "buffer"; -import * as Messages from "../lib/messages"; -import { default as Bundle, filesSymbol } from "../lib/Bundle"; - -describe("Bundle", () => { - let bundle: InstanceType; - - beforeEach(() => { - bundle = new Bundle("application/vnd.apple.pkpass"); - }); - - describe("freezable", () => { - it("should expose freeze method and bundle itself to be frozen", () => { - const [bundle, freeze] = Bundle.freezable("any/any"); - freeze(); - expect(bundle.isFrozen).toBe(true); - }); - }); - - describe("mimeType", () => { - it("should throw an error if no mime-type is specified in the constructor", () => { - // @ts-expect-error - expect(() => new Bundle()).toThrowError( - Error, - Messages.BUNDLE.MIME_TYPE_MISSING, - ); - }); - - it("should expose the mime-type as public property", () => { - expect(bundle.mimeType).toBe("application/vnd.apple.pkpass"); - }); - }); - - describe("addBuffer", () => { - it("should allow to add buffers", () => { - const buffer = Buffer.alloc(0); - bundle.addBuffer("pass.json", buffer); - - expect(bundle[filesSymbol]).toEqual({ "pass.json": buffer }); - }); - }); - - describe("exporting", () => { - describe("getAsStream", () => { - it("should return a stream", () => { - addEmptyFilesToBundle(bundle); - - expect(bundle.getAsStream()).toBeInstanceOf(Stream); - }); - - it("should freeze the bundle", () => { - bundle.getAsStream(); - expect(bundle.isFrozen).toBe(true); - }); - - it("should throw error if a file is attempted to be added when bundle is frozen", () => { - addEmptyFilesToBundle(bundle); - - bundle.getAsStream(); - - expect(() => - bundle.addBuffer("icon.png", Buffer.alloc(0)), - ).toThrowError(Error, Messages.BUNDLE.CLOSED); - }); - }); - - describe("getAsBuffer", () => { - it("should return a buffer", () => { - addEmptyFilesToBundle(bundle); - - expect(bundle.getAsBuffer()).toBeInstanceOf(Buffer); - }); - - it("should freeze the bundle", () => { - bundle.getAsBuffer(); - expect(bundle.isFrozen).toBe(true); - }); - - it("should throw error if a file is attempted to be added when bundle is frozen", () => { - addEmptyFilesToBundle(bundle); - - bundle.getAsBuffer(); - - expect(() => - bundle.addBuffer("icon.png", Buffer.alloc(0)), - ).toThrowError(Error, Messages.BUNDLE.CLOSED); - }); - }); - - describe("getAsRaw", () => { - it("should freeze the bundle", () => { - bundle.getAsRaw(); - expect(bundle.isFrozen).toBe(true); - }); - - it("should return an object with filePath as key and Buffer as value", () => { - bundle.addBuffer("pass.json", Buffer.alloc(0)); - bundle.addBuffer("signature", Buffer.alloc(0)); - bundle.addBuffer("en.lproj/pass.strings", Buffer.alloc(0)); - bundle.addBuffer("en.lproj/icon.png", Buffer.alloc(0)); - - const list = bundle.getAsRaw(); - - expect(list["pass.json"]).not.toBeUndefined(); - expect(list["pass.json"]).toBeInstanceOf(Buffer); - expect(list["signature"]).not.toBeUndefined(); - expect(list["signature"]).toBeInstanceOf(Buffer); - expect(list["en.lproj/pass.strings"]).not.toBeUndefined(); - expect(list["en.lproj/pass.strings"]).toBeInstanceOf(Buffer); - expect(list["en.lproj/icon.png"]).not.toBeUndefined(); - expect(list["en.lproj/icon.png"]).toBeInstanceOf(Buffer); - }); - }); - }); -}); - -function addEmptyFilesToBundle(bundle: Bundle) { - const buffer = Buffer.alloc(0); - bundle.addBuffer("pass.json", buffer); - bundle.addBuffer("icon@2x.png", buffer); - bundle.addBuffer("icon@3x.png", buffer); -} diff --git a/spec/FieldsArray.ts b/spec/FieldsArray.ts deleted file mode 100644 index c2043f0..0000000 --- a/spec/FieldsArray.ts +++ /dev/null @@ -1,227 +0,0 @@ -import { PKPass } from "../lib"; -import FieldsArray from "../lib/FieldsArray"; -import * as Messages from "../lib/messages"; -import * as Schemas from "../lib/schemas"; - -describe("FieldsArray", () => { - let fa: FieldsArray; - let frozen = false; - let pool: Set; - - beforeEach(() => { - frozen = false; - pool = new Set(); - fa = new FieldsArray( - { - get isFrozen() { - return frozen; - }, - } as PKPass /** Fake pass. This is okay for testing */, - pool, - Schemas.Field, - ); - }); - - it("should extend an array", () => { - expect(fa instanceof Array).toBe(true); - }); - - describe("push", () => { - it("should prevent adding new fields if pass is frozen", () => { - frozen = true; - - expect(() => fa.push({ key: "t1", value: "v1" })).toThrowError( - Error, - Messages.BUNDLE.CLOSED, - ); - }); - - it("should allow adding fields", () => { - expect(fa.push({ key: "t1", value: "v1" })).toBe(1); - expect(fa.length).toBe(1); - expect(fa[0]).toEqual({ key: "t1", value: "v1" }); - }); - - it("should preserve order of input items when adding fields", () => { - expect( - fa.push({ key: "t1", value: "v1" }, { key: "t2", value: "v2" }), - ).toBe(2); - expect(fa.length).toBe(2); - expect(fa[0]).toEqual({ key: "t1", value: "v1" }); - expect(fa[1]).toEqual({ key: "t2", value: "v2" }); - }); - - it("should add the key to the pool", () => { - fa.push({ key: "t1", value: "v1" }); - - expect(pool.has("t1")).toBe(true); - }); - - it("should log a warning if key already exists and omit that object", () => { - fa.push({ key: "t1", value: "v1" }); - - console.warn = jasmine.createSpy("log"); - - fa.push({ key: "t1", value: "v1" }); - - expect(console.warn).toHaveBeenCalledWith( - Messages.FIELDS.REPEATED_KEY.replace("%s", "t1"), - ); - - expect(fa.length).toBe(1); - }); - - it("should log a warning if input items contain undefined and, then, ignore it", () => { - console.warn = jasmine.createSpy("log"); - - fa.push(undefined, { key: "t1", value: "v1" }); - - expect(console.warn).toHaveBeenCalledWith( - Messages.FIELDS.INVALID.replace("%s", "undefined"), - ); - - expect(fa.length).toBe(1); - }); - }); - - describe("pop", () => { - beforeEach(() => { - fa.push({ key: "t1", value: "v1" }); - }); - - it("should prevent popping out fields if pass is frozen", () => { - frozen = true; - - expect(() => fa.pop()).toThrowError(Error, Messages.BUNDLE.CLOSED); - }); - - it("should popping out fields", () => { - expect(fa.pop()).toEqual({ key: "t1", value: "v1" }); - expect(fa.length).toBe(0); - expect(fa[0]).toBeUndefined(); - }); - - it("should remove the key from the pool", () => { - expect(pool.has("t1")).toBe(true); - - fa.pop(); - - expect(pool.has("t1")).toBe(false); - }); - }); - - describe("splice", () => { - beforeEach(() => { - fa.push({ key: "t1", value: "v1" }); - }); - - it("should prevent splicing fields if pass is frozen", () => { - frozen = true; - - expect(() => - fa.splice(0, 1, { key: "k1", value: "v1" }), - ).toThrowError(Error, Messages.BUNDLE.CLOSED); - }); - - it("should remove the key from the pool", () => { - expect(pool.has("t1")).toBe(true); - - fa.splice(0, 1, { key: "k1", value: "v2" }); - - expect(pool.has("t1")).toBe(false); - expect(pool.has("k1")).toBe(true); - }); - - it("should log a warning if key already exists and omit that object", () => { - fa.push({ key: "t2", value: "v2" }); - fa.push({ key: "t3", value: "v3" }); - fa.push({ key: "t4", value: "v4" }); - - console.warn = jasmine.createSpy("log"); - - fa.splice(0, 1, { key: "t2", value: "v2" }); - - expect(console.warn).toHaveBeenCalledWith( - Messages.FIELDS.REPEATED_KEY.replace("%s", "t2"), - ); - - expect(fa.length).toBe(3); - }); - }); - - describe("shift", () => { - beforeEach(() => { - fa.push({ key: "t1", value: "v1" }); - fa.push({ key: "t2", value: "v2" }); - }); - - it("should prevent popping out fields if pass is frozen", () => { - frozen = true; - - expect(() => fa.shift()).toThrowError( - Error, - Messages.BUNDLE.CLOSED, - ); - }); - - it("should shift out fields", () => { - expect(fa.shift()).toEqual({ key: "t1", value: "v1" }); - expect(fa.length).toBe(1); - expect(fa[0]).toEqual({ key: "t2", value: "v2" }); - }); - - it("should remove the key from the pool", () => { - expect(pool.has("t1")).toBe(true); - - fa.shift(); - - expect(pool.has("t1")).toBe(false); - }); - }); - - describe("unshift", () => { - it("should prevent adding new fields if pass is frozen", () => { - frozen = true; - - expect(() => fa.unshift({ key: "t1", value: "v1" })).toThrowError( - Error, - Messages.BUNDLE.CLOSED, - ); - }); - - it("should allow adding fields", () => { - expect(fa.unshift({ key: "t1", value: "v1" })).toBe(1); - expect(fa.length).toBe(1); - expect(fa[0]).toEqual({ key: "t1", value: "v1" }); - }); - - it("should add the key to the pool", () => { - fa.unshift({ key: "t1", value: "v1" }); - - expect(pool.has("t1")).toBe(true); - }); - - it("should log a warning if key already exists and omit that object", () => { - fa.push({ key: "t1", value: "v1" }); - - console.warn = jasmine.createSpy("log"); - - fa.unshift({ key: "t1", value: "v1" }); - - expect(console.warn).toHaveBeenCalledWith( - Messages.FIELDS.REPEATED_KEY.replace("%s", "t1"), - ); - - expect(fa.length).toBe(1); - }); - - it("should preserve order of input items when adding fields", () => { - expect( - fa.push({ key: "t1", value: "v1" }, { key: "t2", value: "v2" }), - ).toBe(2); - expect(fa.length).toBe(2); - expect(fa[0]).toEqual({ key: "t1", value: "v1" }); - expect(fa[1]).toEqual({ key: "t2", value: "v2" }); - }); - }); -}); diff --git a/spec/PKPass.ts b/spec/PKPass.ts deleted file mode 100644 index 8f073c2..0000000 --- a/spec/PKPass.ts +++ /dev/null @@ -1,1236 +0,0 @@ -import { promises as fs } from "fs"; -import * as path from "path"; -import { Buffer } from "buffer"; -import { filesSymbol, freezeSymbol } from "../lib/Bundle"; -import FieldsArray from "../lib/FieldsArray"; -import { PassProps } from "../lib/schemas"; -import * as Messages from "../lib/messages"; -import { - default as PKPass, - localizationSymbol, - certificatesSymbol, - propsSymbol, - passTypeSymbol, - importMetadataSymbol, - closePassSymbol, - createManifestSymbol, -} from "../lib/PKPass"; - -describe("PKPass", () => { - let pass: PKPass; - const baseCerts = { - signerCert: "", - signerKey: "", - wwdr: "", - signerKeyPassphrase: "p477w0rb", - }; - - beforeEach(() => { - pass = new PKPass({}); - console.warn = jasmine.createSpy("warn_logging"); - }); - - describe("constructor", () => { - it("should warn about a non-object buffer parameter", () => { - pass = new PKPass(undefined, baseCerts); - - expect(console.warn).toHaveBeenCalledWith( - Messages.INIT.INVALID_BUFFERS.replace("%s", "undefined"), - ); - }); - }); - - describe("setBeacons", () => { - it("should reset instance.props['beacons'] if 'null' is passed as value", () => { - pass.setBeacons({ - proximityUUID: "0000000000-00000000", - major: 4, - minor: 3, - relevantText: "This is not the Kevin you are looking for.", - }); - - expect(pass.props["beacons"].length).toBe(1); - - pass.setBeacons(null); - - expect(pass.props["beacons"]).toBeUndefined(); - }); - - it("should filter out invalid beacons objects", () => { - /** This is invalid, major should be greater than minor */ - pass.setBeacons( - { - proximityUUID: "0000000000-00000000", - major: 2, - minor: 3, - relevantText: "This is not the Kevin you are looking for.", - }, - // @ts-expect-error - { - major: 2, - minor: 3, - }, - { - proximityUUID: "0000000000-00000", - major: 2, - minor: 1, - }, - ); - - expect(pass.props["beacons"].length).toBe(1); - }); - - it("should always return undefined", () => { - expect(pass.setBeacons(null)).toBeUndefined(); - expect( - pass.setBeacons({ - proximityUUID: "0000000000-00000000", - major: 2, - minor: 3, - relevantText: "This is not the Kevin you are looking for.", - }), - ).toBeUndefined(); - }); - }); - - describe("setLocations", () => { - it("should reset instance.props['locations'] if 'null' is passed as value", () => { - pass.setLocations({ - longitude: 0.25456342344, - latitude: 0.26665773234, - }); - - expect(pass.props["locations"].length).toBe(1); - - pass.setLocations(null); - - expect(pass.props["locations"]).toBeUndefined(); - }); - - it("should filter out invalid beacons objects", () => { - pass.setLocations( - { - // @ts-expect-error - longitude: "unknown", - // @ts-expect-error - latitude: "unknown", - }, - { - altitude: "say hello from here", - longitude: 0.25456342344, - }, - { - longitude: 0.25456342344, - latitude: 0.26665773234, - altitude: 12552.31233321, - relevantText: - /** Hi mom, see how do I fly! */ - "Ciao mamma, guarda come volooo!", - }, - ); - - expect(pass.props["locations"].length).toBe(1); - expect(pass.props["locations"][0].longitude).toBe(0.25456342344); - expect(pass.props["locations"][0].latitude).toBe(0.26665773234); - expect(pass.props["locations"][0].altitude).toBe(12552.31233321); - expect(pass.props["locations"][0].relevantText).toBe( - "Ciao mamma, guarda come volooo!", - ); - }); - - it("should always return undefined", () => { - expect(pass.setLocations(null)).toBeUndefined(); - expect( - pass.setLocations({ - longitude: 0.25456342344, - latitude: 0.26665773234, - altitude: 12552.31233321, - }), - ).toBeUndefined(); - }); - }); - - describe("setNFC", () => { - it("should reset instance.props['nfc'] if 'null' is passed as value", () => { - pass.setNFC({ - encryptionPublicKey: "mimmo", - message: "No message for you here", - }); - - expect(pass.props["nfc"]).toEqual({ - encryptionPublicKey: "mimmo", - message: "No message for you here", - }); - - pass.setNFC(null); - - expect(pass.props["nfc"]).toBeUndefined(); - }); - - it("should throw on invalid objects received", () => { - expect(() => - pass.setNFC({ - // @ts-expect-error - requiresAuth: false, - encryptionPublicKey: "Nope", - }), - ).toThrow(); - }); - - it("should always return undefined", () => { - expect(pass.setNFC(null)).toBeUndefined(); - expect( - pass.setNFC({ - encryptionPublicKey: "mimmo", - message: "No message for you here", - }), - ).toBeUndefined(); - }); - }); - - describe("setExpirationDate", () => { - it("should reset instance.props['expirationDate'] if 'null' is passed as value", () => { - pass.setExpirationDate(new Date(2020, 6, 1, 0, 0, 0, 0)); - // Month starts from 0 in Date Object when used this way, therefore - // we expect one month more - expect(pass.props["expirationDate"]).toBe("2020-07-01T00:00:00Z"); - - pass.setExpirationDate(null); - - expect(pass.props["expirationDate"]).toBeUndefined(); - }); - - it("expects a Date object as the only argument", () => { - pass.setExpirationDate(new Date(2020, 6, 1, 0, 0, 0, 0)); - // Month starts from 0 in Date Object when used this way, therefore - // we expect one month more - expect(pass.props["expirationDate"]).toBe("2020-07-01T00:00:00Z"); - }); - - it("should throw if an invalid date is received", () => { - // @ts-expect-error - expect(() => pass.setExpirationDate("32/18/228317")).toThrowError( - TypeError, - "Cannot set expirationDate. Invalid date 32/18/228317", - ); - - expect(() => pass.setExpirationDate(undefined)).toThrowError( - TypeError, - "Cannot set expirationDate. Invalid date undefined", - ); - - // @ts-expect-error - expect(() => pass.setExpirationDate(5)).toThrowError( - TypeError, - "Cannot set expirationDate. Invalid date 5", - ); - - // @ts-expect-error - expect(() => pass.setExpirationDate({})).toThrowError( - TypeError, - "Cannot set expirationDate. Invalid date [object Object]", - ); - }); - - it("should always return undefined", () => { - expect(pass.setExpirationDate(null)).toBeUndefined(); - expect( - pass.setExpirationDate(new Date(2020, 6, 1, 0, 0, 0, 0)), - ).toBeUndefined(); - }); - }); - - describe("setRelevantDate", () => { - it("should reset instance.props['relevantDate'] if 'null' is passed as value", () => { - pass.setRelevantDate(new Date(2020, 6, 1, 0, 0, 0, 0)); - // Month starts from 0 in Date Object when used this way, therefore - // we expect one month more - expect(pass.props["relevantDate"]).toBe("2020-07-01T00:00:00Z"); - - pass.setRelevantDate(null); - - expect(pass.props["relevantDate"]).toBeUndefined(); - }); - - it("expects a Date object as the only argument", () => { - pass.setRelevantDate(new Date("10-04-2021")); - expect(pass.props["relevantDate"]).toBe("2021-10-04T00:00:00Z"); - }); - - it("should throw if an invalid date is received", () => { - // @ts-expect-error - expect(() => pass.setRelevantDate("32/18/228317")).toThrowError( - TypeError, - "Cannot set relevantDate. Invalid date 32/18/228317", - ); - - expect(() => pass.setRelevantDate(undefined)).toThrowError( - TypeError, - "Cannot set relevantDate. Invalid date undefined", - ); - - // @ts-expect-error - expect(() => pass.setRelevantDate(5)).toThrowError( - TypeError, - "Cannot set relevantDate. Invalid date 5", - ); - - // @ts-expect-error - expect(() => pass.setRelevantDate({})).toThrowError( - TypeError, - "Cannot set relevantDate. Invalid date [object Object]", - ); - }); - - it("should always return undefined", () => { - expect(pass.setRelevantDate(null)).toBeUndefined(); - expect( - pass.setRelevantDate(new Date(2020, 6, 1, 0, 0, 0, 0)), - ).toBeUndefined(); - }); - }); - - describe("setBarcodes", () => { - it("shouldn't apply changes if no data is passed", () => { - const props = pass.props["barcodes"] || []; - const oldAmountOfBarcodes = props?.length ?? 0; - - pass.setBarcodes(); - expect(pass.props["barcodes"]?.length || 0).toBe( - oldAmountOfBarcodes, - ); - }); - - it("should autogenerate all the barcodes objects if a string is provided as message", () => { - pass.setBarcodes("28363516282"); - expect(pass.props["barcodes"].length).toBe(4); - }); - - it("should save changes if object conforming to Schemas.Barcode are provided", () => { - pass.setBarcodes({ - message: "28363516282", - format: "PKBarcodeFormatPDF417", - messageEncoding: "utf8", - }); - - expect(pass.props["barcodes"].length).toBe(1); - }); - - it("should add 'messageEncoding' if missing in valid Schema.Barcode parameters", () => { - pass.setBarcodes({ - message: "28363516282", - format: "PKBarcodeFormatPDF417", - }); - - expect(pass.props["barcodes"][0].messageEncoding).toBe( - "iso-8859-1", - ); - }); - - it("should ignore objects without 'message' property in Schema.Barcode", () => { - pass.setBarcodes( - { - format: "PKBarcodeFormatCode128", - message: "No one can validate meeee", - }, - // @ts-expect-error - { - format: "PKBarcodeFormatPDF417", - }, - ); - - expect(pass.props["barcodes"].length).toBe(1); - }); - - it("should ignore objects and values that not comply with Schema.Barcodes", () => { - const setBarcodesArguments: Parameters = - [ - // @ts-expect-error - 5, - // @ts-expect-error - 10, - // @ts-expect-error - 15, - { - message: "28363516282", - format: "PKBarcodeFormatPDF417", - }, - // @ts-expect-error - 7, - // @ts-expect-error - 1, - ]; - - pass.setBarcodes(...setBarcodesArguments); - - expect(pass.props["barcodes"].length).toBe(1); - }); - - it("should reset barcodes content if parameter is null", () => { - pass.setBarcodes({ - message: "28363516282", - format: "PKBarcodeFormatPDF417", - messageEncoding: "utf8", - }); - - expect(pass.props["barcodes"].length).toBe(1); - - pass.setBarcodes(null); - expect(pass.props["barcodes"]).toBe(undefined); - }); - - it("should always return undefined", () => { - expect(pass.setBarcodes(null)).toBeUndefined(); - expect( - pass.setBarcodes({ - message: "28363516282", - format: "PKBarcodeFormatPDF417", - messageEncoding: "utf8", - }), - ).toBeUndefined(); - }); - }); - - describe("transitType", () => { - it("should accept a new value only if the pass is a boarding pass", () => { - const passBP = new PKPass( - { - "pass.json": Buffer.from( - JSON.stringify({ - boardingPass: {}, - }), - ), - }, - baseCerts, - {}, - ); - - const passCP = new PKPass( - { - "pass.json": Buffer.from( - JSON.stringify({ - coupon: {}, - }), - ), - }, - baseCerts, - {}, - ); - - passBP.transitType = "PKTransitTypeAir"; - expect(passBP.transitType).toBe("PKTransitTypeAir"); - - expect( - () => (passCP.transitType = "PKTransitTypeAir"), - ).toThrowError( - TypeError, - Messages.TRANSIT_TYPE.UNEXPECTED_PASS_TYPE, - ); - - /** boardingPass property doesn't exists, so it throws */ - expect(() => passCP.transitType).toThrow(); - }); - }); - - describe("certificates", () => { - it("should throw an error if certificates provided are not complete or invalid", () => { - expect(() => { - // @ts-expect-error - pass.certificates = { - signerCert: "", - }; - }).toThrow(); - - expect(() => { - pass.certificates = { - // @ts-expect-error - signerCert: 5, - // @ts-expect-error - signerKey: 3, - wwdr: "", - }; - }).toThrow(); - - expect(() => { - pass.certificates = { - signerCert: undefined, - signerKey: null, - wwdr: "", - }; - }).toThrow(); - }); - - it("should accept complete object", () => { - pass.certificates = baseCerts; - expect(pass[certificatesSymbol]).toEqual(baseCerts); - - pass = new PKPass({}, baseCerts); - expect(pass[certificatesSymbol]).toEqual(baseCerts); - }); - }); - - describe("fields getters", () => { - it("should throw error if a type has not been defined", () => { - expect(() => pass.primaryFields).toThrowError(TypeError); - expect(() => pass.secondaryFields).toThrowError(TypeError); - expect(() => pass.auxiliaryFields).toThrowError(TypeError); - expect(() => pass.headerFields).toThrowError(TypeError); - expect(() => pass.backFields).toThrowError(TypeError); - }); - - it("should return an instance of FieldsArray if a type have been set", () => { - pass.type = "boardingPass"; - - expect(pass.primaryFields).toBeInstanceOf(FieldsArray); - expect(pass.secondaryFields).toBeInstanceOf(FieldsArray); - expect(pass.auxiliaryFields).toBeInstanceOf(FieldsArray); - expect(pass.headerFields).toBeInstanceOf(FieldsArray); - expect(pass.backFields).toBeInstanceOf(FieldsArray); - - /** Resetting Fields, when setting type */ - pass.type = "coupon"; - - expect(pass.primaryFields).toBeInstanceOf(FieldsArray); - expect(pass.secondaryFields).toBeInstanceOf(FieldsArray); - expect(pass.auxiliaryFields).toBeInstanceOf(FieldsArray); - expect(pass.headerFields).toBeInstanceOf(FieldsArray); - expect(pass.backFields).toBeInstanceOf(FieldsArray); - - /** Resetting Fields, when setting type */ - pass.type = "storeCard"; - - expect(pass.primaryFields).toBeInstanceOf(FieldsArray); - expect(pass.secondaryFields).toBeInstanceOf(FieldsArray); - expect(pass.auxiliaryFields).toBeInstanceOf(FieldsArray); - expect(pass.headerFields).toBeInstanceOf(FieldsArray); - expect(pass.backFields).toBeInstanceOf(FieldsArray); - - /** Resetting Fields, when setting type */ - pass.type = "eventTicket"; - - expect(pass.primaryFields).toBeInstanceOf(FieldsArray); - expect(pass.secondaryFields).toBeInstanceOf(FieldsArray); - expect(pass.auxiliaryFields).toBeInstanceOf(FieldsArray); - expect(pass.headerFields).toBeInstanceOf(FieldsArray); - expect(pass.backFields).toBeInstanceOf(FieldsArray); - - /** Resetting Fields, when setting type */ - pass.type = "generic"; - - expect(pass.primaryFields).toBeInstanceOf(FieldsArray); - expect(pass.secondaryFields).toBeInstanceOf(FieldsArray); - expect(pass.auxiliaryFields).toBeInstanceOf(FieldsArray); - expect(pass.headerFields).toBeInstanceOf(FieldsArray); - expect(pass.backFields).toBeInstanceOf(FieldsArray); - }); - }); - - describe("type", () => { - describe("getter", () => { - it("should return undefined if no type have been setted", () => { - expect(pass.type).toBeUndefined(); - }); - - it("should return a type if set through pass.json", () => { - pass.addBuffer( - "pass.json", - Buffer.from( - JSON.stringify({ - boardingPass: {}, - }), - ), - ); - - expect(pass.type).toBe("boardingPass"); - }); - }); - - describe("setter", () => { - it("should throw error if a non recognized type is assigned", () => { - expect( - () => - // @ts-expect-error - (pass.type = "asfdg"), - ).toThrow(); - }); - - it("should save the new type under a Symbol in class instance", () => { - pass.type = "boardingPass"; - expect(pass[passTypeSymbol]).toBe("boardingPass"); - }); - - it("should reset fields if they have been previously set", () => { - pass.type = "boardingPass"; - - const { - primaryFields, - secondaryFields, - auxiliaryFields, - headerFields, - backFields, - } = pass; - - pass.type = "coupon"; - - expect(pass.primaryFields).not.toBe(primaryFields); - expect(pass.secondaryFields).not.toBe(secondaryFields); - expect(pass.auxiliaryFields).not.toBe(auxiliaryFields); - expect(pass.headerFields).not.toBe(headerFields); - expect(pass.backFields).not.toBe(backFields); - }); - - it("should delete the previous type if previously setted", () => { - pass.type = "boardingPass"; - pass.type = "coupon"; - - expect(pass["boardingPass"]).toBeUndefined(); - }); - }); - }); - - describe("languages", () => { - it("should get updated when translations gets added through localize", () => { - expect(pass.languages.length).toBe(0); - expect(pass.languages).toEqual([]); - - pass.localize("en", { - buon_giorno: "Good Morning", - buona_sera: "Good Evening", - }); - - expect(pass.languages.length).toBe(1); - expect(pass.languages).toEqual(["en"]); - }); - - it("should get updated when translations are added through .addBuffer", () => { - const validTranslationStringsEN = ` -/* Insert Element menu item */ -"Insert Element" = "Insert Element"; -/* Error string used for unknown error types. */ -"ErrorString_1" = "An unknown error occurred."; - `; - - pass.addBuffer( - "en.lproj/pass.strings", - Buffer.from(validTranslationStringsEN), - ); - - const validTranslationStringsIT = ` -"Insert Element" = "Inserisci elemento"; -"ErrorString_1" = "Un errore sconosciuto รจ accaduto"; - `; - - pass.addBuffer( - "it.lproj/pass.strings", - Buffer.from(validTranslationStringsIT), - ); - - expect(pass.languages).toEqual(["en", "it"]); - }); - }); - - describe("localize", () => { - it("should fail throw if lang is not a string", () => { - // @ts-expect-error - expect(() => pass.localize(null)).toThrowError( - TypeError, - Messages.LANGUAGES.INVALID_LANG.replace("%s", "object"), - ); - - // @ts-expect-error - expect(() => pass.localize(undefined)).toThrowError( - TypeError, - Messages.LANGUAGES.INVALID_LANG.replace("%s", "undefined"), - ); - - // @ts-expect-error - expect(() => pass.localize(5)).toThrowError( - TypeError, - Messages.LANGUAGES.INVALID_LANG.replace("%s", "number"), - ); - - // @ts-expect-error - expect(() => pass.localize(true)).toThrowError( - TypeError, - Messages.LANGUAGES.INVALID_LANG.replace("%s", "boolean"), - ); - - // @ts-expect-error - expect(() => pass.localize({})).toThrowError( - TypeError, - Messages.LANGUAGES.INVALID_LANG.replace("%s", "object"), - ); - }); - - it("should warn developer if no translations have been passed", () => { - // @ts-expect-error - pass.localize("en"); - pass.localize("en", {}); - - expect(console.warn).toHaveBeenCalledWith( - Messages.LANGUAGES.NO_TRANSLATIONS.replace("%s", "en"), - ); - - expect(console.warn).toHaveBeenCalledTimes(2); - }); - - it("should create a new language record if some translations are specifies", () => { - pass.localize("en", { - buon_giorno: "Good Morning", - buona_sera: "Good Evening", - }); - - expect(pass[localizationSymbol]["en"]).toEqual({ - buon_giorno: "Good Morning", - buona_sera: "Good Evening", - }); - }); - - it("should accept later translations and merge them with existing ones", () => { - pass.localize("it", { - say_hi: "ciao", - say_gb: "arrivederci", - }); - - pass.localize("it", { - say_good_morning: "buongiorno", - say_good_evening: "buonasera", - }); - - expect(pass[localizationSymbol]["it"]).toEqual({ - say_hi: "ciao", - say_gb: "arrivederci", - say_good_morning: "buongiorno", - say_good_evening: "buonasera", - }); - }); - - it("should delete a language, all of its translations and all of its files, when null is passed as parameter", () => { - pass.addBuffer("it.lproj/icon@3x.png", Buffer.alloc(0)); - pass.addBuffer("en.lproj/icon@3x.png", Buffer.alloc(0)); - - pass.localize("it", null); - pass.localize("en", null); - - expect(pass[localizationSymbol]["it"]).toBeUndefined(); - expect(pass[localizationSymbol]["en"]).toBeUndefined(); - - expect(pass[filesSymbol]["it.lproj/icon@3x.png"]).toBeUndefined(); - expect(pass[filesSymbol]["en.lproj/icon@3x.png"]).toBeUndefined(); - }); - - it("should always return undefined", () => { - expect(pass.localize("it", null)).toBeUndefined(); - expect( - pass.localize("it", { - say_good_morning: "buongiorno", - say_good_evening: "buonasera", - }), - ).toBeUndefined(); - }); - }); - - describe("addBuffer", () => { - it("should filter out silently manifest and signature files", () => { - pass.addBuffer("manifest.json", Buffer.alloc(0)); - pass.addBuffer("signature", Buffer.alloc(0)); - - expect(Object.keys(pass[filesSymbol]).length).toBe(0); - }); - - it("should accept a pass.json only if not yet imported", () => { - pass.addBuffer( - "pass.json", - Buffer.from( - JSON.stringify({ - boardingPass: {}, - serialNumber: "555555", - }), - ), - ); - - expect(Object.keys(pass[filesSymbol]).length).toBe(1); - - /** Adding it again */ - - pass.addBuffer( - "pass.json", - Buffer.from( - JSON.stringify({ - boardingPass: {}, - serialNumber: "555555", - }), - ), - ); - - /** Expecting it to get ignored */ - expect(Object.keys(pass[filesSymbol]).length).toBe(1); - }); - - it("should accept personalization.json only if it is a valid JSON", () => { - pass.addBuffer( - "personalization.json", - Buffer.from( - JSON.stringify({ - description: - "A test description for a test personalization", - requiredPersonalizationFields: [ - "PKPassPersonalizationFieldName", - "PKPassPersonalizationFieldPostalCode", - "PKPassPersonalizationFieldEmailAddress", - ], - }), - ), - ); - - expect(pass[filesSymbol]["personalization.json"]).toBeInstanceOf( - Buffer, - ); - }); - - it("should reject invalid personalization.json", () => { - pass.addBuffer( - "personalization.json", - Buffer.from( - JSON.stringify({ - requiredPersonalizationFields: [ - "PKPassPersonalizationFieldName", - "PKPassPersonalizationFieldEmailAddressaworng", - ], - }), - ), - ); - - expect(pass[filesSymbol]["personalization.json"]).toBeUndefined( - Buffer, - ); - }); - - it("should redirect .strings files to localization", () => { - const validTranslationStrings = ` -/* Insert Element menu item */ -"Insert Element" = "Insert Element"; -/* Error string used for unknown error types. */ -"ErrorString_1" = "An unknown error occurred."; - `; - - pass.addBuffer( - "en.lproj/pass.strings", - Buffer.from(validTranslationStrings), - ); - - expect(pass[filesSymbol]["en.lproj/pass.string"]).toBeUndefined(); - expect(pass[localizationSymbol]["en"]).toEqual({ - "Insert Element": "Insert Element", - ErrorString_1: "An unknown error occurred.", - }); - }); - - it("should ignore invalid .strings files", () => { - const invalidTranslationStrings = ` -"Insert Element"="Insert Element -"ErrorString_1= "An unknown error occurred." - `; - - pass.addBuffer( - "en.lproj/pass.strings", - Buffer.from(invalidTranslationStrings), - ); - - expect(pass[filesSymbol]["en.lproj/pass.string"]).toBeUndefined(); - expect(pass[localizationSymbol]["en"]).toBeUndefined(); - }); - - it("should convert Windows paths to single UNIX slash", () => { - if (path.sep === "\\") { - pass.addBuffer("en.lproj\\icon@2x.png", Buffer.alloc(0)); - - expect(pass[filesSymbol]["en.lproj/icon@2x.png"]).toBeDefined(); - expect( - pass[filesSymbol]["en.lproj\\icon@2x.png"], - ).toBeUndefined(); - } - }); - }); - - describe("[importMetadataSymbol]", () => { - it("should read data and set type", () => { - pass[importMetadataSymbol]({ - boardingPass: {}, - }); - - expect(pass.type).toBe("boardingPass"); - }); - - it("should push fields to their own fields if a type is found", () => { - const baseField: PassProps["boardingPass"]["headerFields"][0] = { - key: "0", - value: "n/a", - label: "n/d", - }; - - pass[importMetadataSymbol]({ - boardingPass: { - primaryFields: [{ ...baseField, key: "pf0" }], - secondaryFields: [{ ...baseField, key: "sf0" }], - auxiliaryFields: [{ ...baseField, key: "af0" }], - headerFields: [{ ...baseField, key: "hf0" }], - backFields: [{ ...baseField, key: "bf0" }], - }, - } as PassProps); - - expect(pass.primaryFields[0]).toEqual({ ...baseField, key: "pf0" }); - expect(pass.secondaryFields[0]).toEqual({ - ...baseField, - key: "sf0", - }); - expect(pass.auxiliaryFields[0]).toEqual({ - ...baseField, - key: "af0", - }); - expect(pass.headerFields[0]).toEqual({ ...baseField, key: "hf0" }); - expect(pass.backFields[0]).toEqual({ ...baseField, key: "bf0" }); - }); - }); - - describe("[closePassSymbol]", () => { - beforeEach(() => { - pass.addBuffer( - "pass.json", - Buffer.from( - JSON.stringify({ - coupon: { - headerFields: [], - primaryFields: [], - auxiliaryFields: [], - secondaryFields: [], - backFields: [], - }, - serialNumber: "h12kj5b12k3331", - } as PassProps), - ), - ); - }); - - it("should add props to pass.json", () => { - pass.setBarcodes({ - format: "PKBarcodeFormatQR", - message: "meh a test barcode", - }); - - pass.addBuffer("icon@2x.png", Buffer.alloc(0)); - - pass[closePassSymbol](true); - - expect( - JSON.parse(pass[filesSymbol]["pass.json"].toString("utf-8")), - ).toEqual({ - formatVersion: 1, - coupon: { - headerFields: [], - primaryFields: [], - auxiliaryFields: [], - secondaryFields: [], - backFields: [], - }, - serialNumber: "h12kj5b12k3331", - barcodes: [ - { - format: "PKBarcodeFormatQR", - message: "meh a test barcode", - messageEncoding: "iso-8859-1", - }, - ], - }); - }); - - it("Should warn user if no icons have been added to bundle", () => { - pass[closePassSymbol](true); - - expect(console.warn).toHaveBeenCalledWith( - "At least one icon file is missing in your bundle. Your pass won't be openable by any Apple Device.", - ); - }); - - it("should create back again pass.strings files", () => { - pass.localize("it", { - home: "casa", - ciao: "hello", - cosa: "thing", - }); - - pass[closePassSymbol](true); - - expect(pass[filesSymbol]["it.lproj/pass.strings"].length).not.toBe( - 0, - ); - }); - - it("should remove all personalisation if requirements are not met", () => { - pass.addBuffer( - "personalization.json", - Buffer.from( - JSON.stringify({ - description: - "A test description for a test personalization", - requiredPersonalizationFields: [ - "PKPassPersonalizationFieldName", - "PKPassPersonalizationFieldPostalCode", - "PKPassPersonalizationFieldEmailAddress", - ], - }), - ), - ); - - pass.addBuffer("personalizationLogo@2x.png", Buffer.alloc(0)); - - pass[closePassSymbol](true); - - /** Pass is missing nfc data. */ - expect(pass[filesSymbol]["personalization.json"]).toBeUndefined(); - expect( - pass[filesSymbol]["personalizationLogo@2x.png"], - ).toBeUndefined(); - - /** Next: pass will miss personalizationLogo */ - - pass.addBuffer( - "personalization.json", - Buffer.from( - JSON.stringify({ - description: - "A test description for a test personalization", - requiredPersonalizationFields: [ - "PKPassPersonalizationFieldName", - "PKPassPersonalizationFieldPostalCode", - "PKPassPersonalizationFieldEmailAddress", - ], - }), - ), - ); - - pass.setNFC({ - message: "nfc-encrypted-message", - encryptionPublicKey: "none", - }); - - pass[closePassSymbol](true); - - expect(pass[filesSymbol]["personalization.json"]).toBeUndefined(); - expect( - pass[filesSymbol]["personalizationLogo@2x.png"], - ).toBeUndefined(); - }); - - it("should throw if no pass type have specified", () => { - pass.type = undefined; /** reset */ - - expect(() => pass[closePassSymbol](true)).toThrowError( - TypeError, - Messages.CLOSE.MISSING_TYPE, - ); - }); - - it("should throw if a boarding pass is exported without a transitType", () => { - pass.type = "boardingPass"; - - expect(() => pass[closePassSymbol](true)).toThrowError( - TypeError, - Messages.CLOSE.MISSING_TRANSIT_TYPE, - ); - }); - }); - - describe("[createManifestSymbol]", () => { - it("should create a list of SHA-1s", () => { - pass.addBuffer("icon.png", Buffer.alloc(0)); - pass.addBuffer("icon@2x.png", Buffer.alloc(0)); - pass.addBuffer("icon@3x.png", Buffer.alloc(0)); - - expect( - JSON.parse(pass[createManifestSymbol]().toString("utf-8")), - ).toEqual({ - "icon.png": "da39a3ee5e6b4b0d3255bfef95601890afd80709", - "icon@2x.png": "da39a3ee5e6b4b0d3255bfef95601890afd80709", - "icon@3x.png": "da39a3ee5e6b4b0d3255bfef95601890afd80709", - }); - }); - - it("List of Sha-1 of localized files should not contain Windows '\\' slash", () => { - if (path.sep === "\\") { - pass.addBuffer("en.lproj\\icon.png", Buffer.alloc(0)); - pass.addBuffer("en.lproj\\icon@2x.png", Buffer.alloc(0)); - pass.addBuffer("en.lproj\\icon@3x.png", Buffer.alloc(0)); - - const parsedResult = Object.keys( - JSON.parse(pass[createManifestSymbol]().toString("utf-8")), - ); - - expect(parsedResult[0]).toMatch(/en\.lproj\/icon\.png/); - expect(parsedResult[1]).toMatch(/en\.lproj\/icon@2x\.png/); - expect(parsedResult[2]).toMatch(/en\.lproj\/icon@3x\.png/); - } - }); - }); - - describe("[static] from", () => { - it("should throw if source is unavailable", async () => { - await expectAsync( - // @ts-expect-error - PKPass.from(), - ).toBeRejectedWithError( - TypeError, - Messages.FROM.MISSING_SOURCE.replace("%s", "undefined"), - ); - - await expectAsync(PKPass.from(null)).toBeRejectedWithError( - TypeError, - Messages.FROM.MISSING_SOURCE.replace("%s", "null"), - ); - }); - - describe("Prebuilt PKPass", () => { - it("should copy all source's buffers into current one", async () => { - pass.addBuffer( - "index@2x.png", - Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]), - ); - - const newPass = await PKPass.from(pass); - - expect( - newPass[filesSymbol]["index@2x.png"].equals( - pass[filesSymbol]["index@2x.png"], - ), - ).toBe(true); - expect(newPass[filesSymbol]["index@2x.png"]).not.toBe( - pass[filesSymbol]["index@2x.png"], - ); - }); - - it("should accept additional properties to be added to new buffer and ignore unknown props", async () => { - const newPass = await PKPass.from(pass, { - description: "mimmoh", - serialNumber: "626621523738123", - // @ts-expect-error - insert_here_invalid_unknown_parameter_name: false, - }); - - expect(newPass[propsSymbol]["description"]).toBe("mimmoh"); - expect(newPass[propsSymbol]["serialNumber"]).toBe( - "626621523738123", - ); - expect( - newPass[propsSymbol][ - "insert_here_invalid_unknown_parameter_name" - ], - ).toBeUndefined(); - }); - }); - - describe("Template", () => { - it("should reject invalid templates", async () => { - await Promise.all([ - expectAsync( - // @ts-expect-error - PKPass.from(5), - ).toBeRejected(), - expectAsync( - // @ts-expect-error - PKPass.from({}), - ).toBeRejected(), - expectAsync( - /** Empty model validation error */ - PKPass.from({ model: "" }), - ).toBeRejected(), - expectAsync( - /** Missing model error and no certificates */ - // @ts-expect-error - PKPass.from({ certificates: {} }), - ).toBeRejected(), - expectAsync( - // @ts-expect-error - PKPass.from(""), - ).toBeRejected(), - expectAsync( - // @ts-expect-error - PKPass.from(true), - ).toBeRejected(), - expectAsync( - // @ts-expect-error - PKPass.from([]), - ).toBeRejected(), - ]); - }); - - it("should read model from fileSystem and props", async () => { - const footerFile = await fs.readFile( - path.resolve( - __dirname, - "../examples/models/exampleBooking.pass/footer.png", - ), - ); - - const newPass = await PKPass.from( - { - model: path.resolve( - __dirname, - "../examples/models/exampleBooking.pass", - ), - certificates: { - ...baseCerts, - }, - }, - { - voided: true, - }, - ); - - expect(Object.keys(newPass[filesSymbol]).length).toBe(7); - - expect(newPass[filesSymbol]["footer.png"]).not.toBeUndefined(); - expect( - newPass[filesSymbol]["footer.png"].equals(footerFile), - ).toBe(true); - expect(newPass[filesSymbol]["footer.png"]).not.toBe(footerFile); - - expect(newPass[propsSymbol]["voided"]).toBe(true); - }); - }); - }); - - describe("[static] pack", () => { - beforeEach(() => { - /** Bypass to avoid signature and manifest generation */ - pass[freezeSymbol](); - }); - - it("should should throw error if not all the files passed are PKPasses", () => { - expect( - // @ts-expect-error - () => PKPass.pack(pass, "pass.json", pass), - ).toThrowError(Error, Messages.PACK.INVALID); - }); - - it("should output a frozen bundle of bundles", () => { - const pkPassesBundle = PKPass.pack(pass, pass); - - expect( - pkPassesBundle[filesSymbol]["packed-pass-1.pkpass"], - ).toBeInstanceOf(Buffer); - expect( - pkPassesBundle[filesSymbol]["packed-pass-2.pkpass"], - ).toBeInstanceOf(Buffer); - - expect(pkPassesBundle.isFrozen).toBe(true); - }); - - it("should output a bundle with pkpasses mimetype", () => { - const pkPassesBundle = PKPass.pack(pass, pass); - - expect(pkPassesBundle.mimeType).toBe( - "application/vnd.apple.pkpasses", - ); - }); - }); -}); diff --git a/spec/utils.ts b/spec/utils.ts deleted file mode 100644 index 2db95e3..0000000 --- a/spec/utils.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { processDate, removeHidden } from "../lib/utils"; - -describe("Utils", () => { - describe("removeHidden", () => { - it("should remove files that start with dot", () => { - const filesList = [ - "a.png", - "b.png", - ".DS_Store", - "not_the_droids_you_are_looking_for.txt", - ]; - - expect(removeHidden(filesList)).toEqual([ - "a.png", - "b.png", - "not_the_droids_you_are_looking_for.txt", - ]); - }); - }); - - describe("processDate", () => { - it("should throw Invalid date if args[0] is not a date", () => { - //@ts-expect-error - expect(() => processDate(5)).toThrow("Invalid date"); - //@ts-expect-error - expect(() => processDate({})).toThrow("Invalid date"); - //@ts-expect-error - expect(() => processDate("ciao")).toThrow("Invalid date"); - //@ts-expect-error - expect(() => processDate(true)).toThrow("Invalid date"); - }); - - it("should convert a Date object to a valid W3C date", () => { - expect(processDate(new Date(2020, 6, 1, 0, 0, 0, 0))).toBe( - "2020-07-01T00:00:00Z", - ); - }); - }); -}); diff --git a/tsconfig.spec.json b/tsconfig.spec.json deleted file mode 100644 index ae56735..0000000 --- a/tsconfig.spec.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "sourceMap": true - }, - "include": [ - "spec/**/*", - ] -}