Skip to content

Commit

Permalink
Get rid of JSONSerialization
Browse files Browse the repository at this point in the history
  • Loading branch information
fpseverino committed Oct 26, 2024
1 parent c93f073 commit d390bc7
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 29 deletions.
4 changes: 2 additions & 2 deletions Sources/Passes/DTOs/PersonalizationJSON.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
/// It also contains a description of the program and (optionally) the program’s terms and conditions.
///
/// > Tip: See the [documentation](https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/PassKit_PG/PassPersonalization.html#//apple_ref/doc/uid/TP40012195-CH12-SW2) to understand the keys.
public struct PersonalizationJSON: Encodable, Sendable {
public struct PersonalizationJSON: Codable, Sendable {
/// The contents of this array define the data requested from the user.
///
/// The signup form’s fields are generated based on these keys.
Expand Down Expand Up @@ -42,7 +42,7 @@ public struct PersonalizationJSON: Encodable, Sendable {

extension PersonalizationJSON {
/// Personal information requested by the signup form.
public enum PersonalizationField: String, Encodable, Sendable {
public enum PersonalizationField: String, Codable, Sendable {
/// Prompts the user for their name.
///
/// `fullName`, `givenName`, and `familyName` are submitted in the personalize request.
Expand Down
20 changes: 18 additions & 2 deletions Tests/OrdersTests/OrderData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ extension OrderData {
}
}

struct OrderJSONData: OrderJSON.Properties {
extension OrderJSON.SchemaVersion: Decodable {}
extension OrderJSON.OrderType: Decodable {}
extension OrderJSON.OrderStatus: Decodable {}

struct OrderJSONData: OrderJSON.Properties, Decodable {
let schemaVersion = OrderJSON.SchemaVersion.v1
let orderTypeIdentifier = "order.com.example.pet-store"
let orderIdentifier: String
Expand All @@ -61,11 +65,23 @@ struct OrderJSONData: OrderJSON.Properties {

private let webServiceURL = "https://www.example.com/api/orders/"

struct MerchantData: OrderJSON.Merchant {
enum CodingKeys: String, CodingKey {
case schemaVersion
case orderTypeIdentifier, orderIdentifier, orderType, orderNumber
case createdAt, updatedAt
case status, merchant
case orderManagementURL, authenticationToken, webServiceURL
}

struct MerchantData: OrderJSON.Merchant, Decodable {
let merchantIdentifier = "com.example.pet-store"
let displayName: String
let url = "https://www.example.com/"
let logo = "pet_store_logo.png"

enum CodingKeys: String, CodingKey {
case merchantIdentifier, displayName, url, logo
}
}

init(data: OrderData, order: Order) {
Expand Down
13 changes: 7 additions & 6 deletions Tests/OrdersTests/OrdersTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Zip
@Suite("Orders Tests")
struct OrdersTests {
let ordersURI = "/api/orders/v1/"
let decoder = JSONDecoder()

@Test("Order Generation", arguments: [true, false])
func orderGeneration(useEncryptedKey: Bool) async throws {
Expand All @@ -24,17 +25,17 @@ struct OrdersTests {
#expect(FileManager.default.fileExists(atPath: orderFolder.path.appending("/signature")))

#expect(FileManager.default.fileExists(atPath: orderFolder.path.appending("/order.json")))
let passJSONData = try String(contentsOfFile: orderFolder.path.appending("/order.json")).data(using: .utf8)
let passJSON = try JSONSerialization.jsonObject(with: passJSONData!) as! [String: Any]
#expect(passJSON["authenticationToken"] as? String == order.authenticationToken)
let orderJSONData = try String(contentsOfFile: orderFolder.path.appending("/order.json")).data(using: .utf8)
let orderJSON = try decoder.decode(OrderJSONData.self, from: orderJSONData!)
#expect(orderJSON.authenticationToken == order.authenticationToken)
let orderID = try order.requireID().uuidString
#expect(passJSON["orderIdentifier"] as? String == orderID)
#expect(orderJSON.orderIdentifier == orderID)

let manifestJSONData = try String(contentsOfFile: orderFolder.path.appending("/manifest.json")).data(using: .utf8)
let manifestJSON = try JSONSerialization.jsonObject(with: manifestJSONData!) as! [String: Any]
let manifestJSON = try decoder.decode([String: String].self, from: manifestJSONData!)
let iconData = try Data(contentsOf: orderFolder.appendingPathComponent("/icon.png"))
let iconHash = Array(SHA256.hash(data: iconData)).hex
#expect(manifestJSON["icon.png"] as? String == iconHash)
#expect(manifestJSON["icon.png"] == iconHash)
#expect(manifestJSON["pet_store_logo.png"] != nil)
}
}
Expand Down
27 changes: 22 additions & 5 deletions Tests/PassesTests/PassData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ extension PassData {
}
}

struct PassJSONData: PassJSON.Properties {
extension PassJSON.FormatVersion: Decodable {}
extension PassJSON.BarcodeFormat: Decodable {}
extension PassJSON.TransitType: Decodable {}

struct PassJSONData: PassJSON.Properties, Decodable {
let description: String
let formatVersion = PassJSON.FormatVersion.v1
let organizationName = "vapor-community"
Expand All @@ -55,29 +59,33 @@ struct PassJSONData: PassJSON.Properties {
let teamIdentifier = "K6512ZA2S5"

private let webServiceURL = "https://www.example.com/api/passes/"
private let authenticationToken: String
let authenticationToken: String
private let logoText = "Vapor Community"
private let sharingProhibited = true
let backgroundColor = "rgb(207, 77, 243)"
let foregroundColor = "rgb(255, 255, 255)"

let barcodes = Barcode(message: "test")
struct Barcode: PassJSON.Barcodes {
struct Barcode: PassJSON.Barcodes, Decodable {
let format = PassJSON.BarcodeFormat.qr
let message: String
let messageEncoding = "iso-8859-1"

enum CodingKeys: String, CodingKey {
case format, message, messageEncoding
}
}

let boardingPass = Boarding(transitType: .air)
struct Boarding: PassJSON.BoardingPass {
struct Boarding: PassJSON.BoardingPass, Decodable {
let transitType: PassJSON.TransitType
let headerFields: [PassField]
let primaryFields: [PassField]
let secondaryFields: [PassField]
let auxiliaryFields: [PassField]
let backFields: [PassField]

struct PassField: PassJSON.PassFieldContent {
struct PassField: PassJSON.PassFieldContent, Decodable {
let key: String
let label: String
let value: String
Expand All @@ -93,6 +101,15 @@ struct PassJSONData: PassJSON.Properties {
}
}

enum CodingKeys: String, CodingKey {
case description
case formatVersion
case organizationName, passTypeIdentifier, serialNumber, teamIdentifier
case webServiceURL, authenticationToken
case logoText, sharingProhibited, backgroundColor, foregroundColor
case barcodes, boardingPass
}

init(data: PassData, pass: Pass) {
self.description = data.title
self.serialNumber = pass.id!.uuidString
Expand Down
29 changes: 15 additions & 14 deletions Tests/PassesTests/PassesTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Zip
@Suite("Passes Tests")
struct PassesTests {
let passesURI = "/api/passes/v1/"
let decoder = JSONDecoder()

@Test("Pass Generation", arguments: [true, false])
func passGeneration(useEncryptedKey: Bool) async throws {
Expand All @@ -25,17 +26,17 @@ struct PassesTests {

#expect(FileManager.default.fileExists(atPath: passFolder.path.appending("/pass.json")))
let passJSONData = try String(contentsOfFile: passFolder.path.appending("/pass.json")).data(using: .utf8)
let passJSON = try JSONSerialization.jsonObject(with: passJSONData!) as! [String: Any]
#expect(passJSON["authenticationToken"] as? String == pass.authenticationToken)
let passJSON = try decoder.decode(PassJSONData.self, from: passJSONData!)
#expect(passJSON.authenticationToken == pass.authenticationToken)
let passID = try pass.requireID().uuidString
#expect(passJSON["serialNumber"] as? String == passID)
#expect(passJSON["description"] as? String == passData.title)
#expect(passJSON.serialNumber == passID)
#expect(passJSON.description == passData.title)

let manifestJSONData = try String(contentsOfFile: passFolder.path.appending("/manifest.json")).data(using: .utf8)
let manifestJSON = try JSONSerialization.jsonObject(with: manifestJSONData!) as! [String: Any]
let manifestJSON = try decoder.decode([String: String].self, from: manifestJSONData!)
let iconData = try Data(contentsOf: passFolder.appendingPathComponent("/icon.png"))
let iconHash = Array(Insecure.SHA1.hash(data: iconData)).hex
#expect(manifestJSON["icon.png"] as? String == iconHash)
#expect(manifestJSON["icon.png"] == iconHash)
#expect(manifestJSON["logo.png"] != nil)
#expect(manifestJSON["personalizationLogo.png"] != nil)
}
Expand Down Expand Up @@ -79,21 +80,21 @@ struct PassesTests {

#expect(FileManager.default.fileExists(atPath: passFolder.path.appending("/pass.json")))
let passJSONData = try String(contentsOfFile: passFolder.path.appending("/pass.json")).data(using: .utf8)
let passJSON = try JSONSerialization.jsonObject(with: passJSONData!) as! [String: Any]
#expect(passJSON["authenticationToken"] as? String == pass.authenticationToken)
let passJSON = try decoder.decode(PassJSONData.self, from: passJSONData!)
#expect(passJSON.authenticationToken == pass.authenticationToken)
let passID = try pass.requireID().uuidString
#expect(passJSON["serialNumber"] as? String == passID)
#expect(passJSON["description"] as? String == passData.title)
#expect(passJSON.serialNumber == passID)
#expect(passJSON.description == passData.title)

let personalizationJSONData = try String(contentsOfFile: passFolder.path.appending("/personalization.json")).data(using: .utf8)
let personalizationJSON = try JSONSerialization.jsonObject(with: personalizationJSONData!) as! [String: Any]
#expect(personalizationJSON["description"] as? String == "Hello, World!")
let personalizationJSON = try decoder.decode(PersonalizationJSON.self, from: personalizationJSONData!)
#expect(personalizationJSON.description == "Hello, World!")

let manifestJSONData = try String(contentsOfFile: passFolder.path.appending("/manifest.json")).data(using: .utf8)
let manifestJSON = try JSONSerialization.jsonObject(with: manifestJSONData!) as! [String: Any]
let manifestJSON = try decoder.decode([String: String].self, from: manifestJSONData!)
let iconData = try Data(contentsOf: passFolder.appendingPathComponent("/personalizationLogo.png"))
let iconHash = Array(Insecure.SHA1.hash(data: iconData)).hex
#expect(manifestJSON["personalizationLogo.png"] as? String == iconHash)
#expect(manifestJSON["personalizationLogo.png"] == iconHash)
}
}

Expand Down

0 comments on commit d390bc7

Please sign in to comment.