diff --git a/.ci/build.sh b/.ci/build.sh index 8419a80..5eb50b8 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -39,33 +39,37 @@ then wget https://swift.org/builds/swift-$VERSION-release/$OS/swift-$VERSION-RELEASE/$SWIFTFILE.tar.gz tar -zxf $SWIFTFILE.tar.gz export PATH=$PWD/$SWIFTFILE/usr/bin:"${PATH}" +else + echo "📚 Installing Dependencies" + brew tap vapor/homebrew-tap + brew install ctls fi echo "📅 Version: `swift --version`"; echo "🚀 Building"; swift build -if [[ $? != 0 ]]; -then +if [[ $? != 0 ]]; +then echo "❌ Build failed"; - exit 1; + exit 1; fi echo "💼 Building Release"; swift build -c release -if [[ $? != 0 ]]; -then +if [[ $? != 0 ]]; +then echo "❌ Build for release failed"; - exit 1; + exit 1; fi echo "🔎 Testing"; swift test -if [[ $? != 0 ]]; -then +if [[ $? != 0 ]]; +then echo "❌ Tests failed"; - exit 1; + exit 1; fi echo "✅ Done" diff --git a/Package.swift b/Package.swift index fb6b12d..8b31ab7 100644 --- a/Package.swift +++ b/Package.swift @@ -4,12 +4,12 @@ let package = Package( name: "VaporAPNS", targets: [], dependencies: [ - .Package(url: "https://github.com/vapor/json.git", majorVersion: 1, minor: 0), + .Package(url: "https://github.com/vapor/json.git", majorVersion: 2), .Package(url: "https://github.com/vapor/clibressl.git", majorVersion: 1), - .Package(url: "https://github.com/vapor/console.git", majorVersion: 1), + .Package(url: "https://github.com/vapor/console.git", majorVersion: 2), .Package(url: "https://github.com/matthijs2704/SwiftString.git", majorVersion: 1, minor: 0), .Package(url: "https://github.com/boostcode/CCurl.git", majorVersion: 0, minor: 2), - .Package(url: "https://github.com/vapor/jwt.git", majorVersion: 1) + .Package(url: "https://github.com/vapor/jwt.git", majorVersion: 2) ], exclude: ["Images"] ) diff --git a/Sources/VaporAPNS/Jay+Utils.swift b/Sources/VaporAPNS/Jay+Utils.swift deleted file mode 100644 index 55cdb7b..0000000 --- a/Sources/VaporAPNS/Jay+Utils.swift +++ /dev/null @@ -1,148 +0,0 @@ -// -// Jay+Utils.swift -// VaporAPNS -// -// Created by Matthijs Logemann on 30/09/2016. -// -// - -// -// Conversions.swift -// Jay -// -// Created by Honza Dvorsky on 5/16/16. -// -// - -import Jay -import Foundation - -//Useful methods for easier manipulation of type-safe JSON - -extension JSON { - - /// Returns the `JSON` as `[String: JSON]` if valid, else `nil`. - public var dictionary: [Swift.String: JSON]? { - guard case .object(let dict) = self else { return nil } - return dict - } - - /// Returns the `JSON` as `[JSON]` if valid, else `nil`. - public var array: [JSON]? { - guard case .array(let arr) = self else { return nil } - return arr - } - - /// Returns the `JSON` as an `Int` if valid, else `nil`. - public var int: Int? { - guard case .number(let number) = self else { return nil } - guard case .integer(let jsonInt) = number else { return nil } - return jsonInt - } - - /// Returns the `JSON` as a `UInt` if valid, else `nil`. - public var uint: UInt? { - guard case .number(let number) = self else { return nil } - switch number { - case .integer(let int): return UInt(int) - case .unsignedInteger(let uint): return uint - default: return nil - } - } - - /// Returns the `JSON` as a `Double` if valid, else `nil`. - public var double: Double? { - guard case .number(let number) = self else { return nil } - switch number { - case .double(let dbl): return dbl - case .integer(let int): return Double(int) - case .unsignedInteger(let uint): return Double(uint) - } - } - - /// Returns the `JSON` as a `String` if valid, else `nil`. - public var string: Swift.String? { - guard case .string(let str) = self else { return nil } - return str - } - - /// Returns the `JSON` as a `Bool` if valid, else `nil`. - public var boolean: Bool? { - guard case .boolean(let bool) = self else { return nil } - return bool - } - - /// Returns the `JSON` as `NSNull` if valid, else `nil`. - public var null: NSNull? { - guard case .null = self else { return nil } - return NSNull() - } -} - -//Thanks for the inspiration for the following initializers, https://github.com/Zewo/JSON/blob/master/Source/JSON.swift - -extension JSON: ExpressibleByNilLiteral { - - public init(nilLiteral: ()) { - self = .null - } -} - -extension JSON: ExpressibleByBooleanLiteral { - - /// Create a `JSON` instance initialized to the provided `booleanLiteral`. - public init(booleanLiteral value: BooleanLiteralType) { - self = .boolean(value) - } -} - -extension JSON: ExpressibleByIntegerLiteral { - - /// Create a `JSON` instance initialized to the provided `integerLiteral`. - public init(integerLiteral value: IntegerLiteralType) { - self = .number(.integer(value)) - } -} - -extension JSON: ExpressibleByFloatLiteral { - - /// Create a `JSON` instance initialized to the provided `floatLiteral`. - public init(floatLiteral value: FloatLiteralType) { - self = .number(.double(value)) - } -} - -extension JSON: ExpressibleByStringLiteral { - - /// Create a `JSON` instance initialized to the provided `unicodeScalarLiteral`. - public init(unicodeScalarLiteral value: Swift.String) { - self = .string(value) - } - - /// Create a `JSON` instance initialized to the provided `extendedGraphemeClusterLiteral`. - public init(extendedGraphemeClusterLiteral value: Swift.String) { - self = .string(value) - } - - - /// Create a `JSON` instance initialized to the provided `stringLiteral`. - public init(stringLiteral value: StringLiteralType) { - self = .string(value) - } -} - -extension JSON: ExpressibleByArrayLiteral { - public init(arrayLiteral elements: JSON...) { - self = .array(elements) - } -} - -extension JSON: ExpressibleByDictionaryLiteral { - public init(dictionaryLiteral elements: (String, JSON)...) { - var items: [String: JSON] = [:] - for pair in elements { - items[pair.0] = pair.1 - } - self = .object(items) - } -} diff --git a/Sources/VaporAPNS/Options.swift b/Sources/VaporAPNS/Options.swift index cf6600d..1104958 100644 --- a/Sources/VaporAPNS/Options.swift +++ b/Sources/VaporAPNS/Options.swift @@ -96,44 +96,38 @@ public struct Options: CustomStringConvertible, NodeInitializable { } - public init(node: Node, in context: Context) throws { - if let topic = node["topic"]?.string { - self.topic = topic - }else { + public init(node: Node) throws { + guard let topic = node["topic"]?.string else { throw InitializeError.noTopic } + self.topic = topic if let portRaw = node["port"]?.int, let port = Port(rawValue: portRaw) { self.port = port } - var hasAnyAuthentication = false - var hasBothAuthentication = false - - if let certPath = node["certificatePath"]?.string, let keyPath = node["keyPath"]?.string { - hasAnyAuthentication = true - self.certPath = certPath - self.keyPath = keyPath - - } + var hasAuthentication = false if let privateKeyLocation = node["keyPath"]?.string, let keyId = node["keyId"]?.string { - if hasAnyAuthentication { hasBothAuthentication = true } - hasAnyAuthentication = true + hasAuthentication = true let (priv, pub) = try privateKeyLocation.tokenString() self.privateKey = priv self.publicKey = pub self.keyId = keyId } - - guard hasAnyAuthentication else { - throw InitializeError.noAuthentication + + if let certPath = node["certificatePath"]?.string, let keyPath = node["keyPath"]?.string { + if hasAuthentication { + print ("You've seem to have specified both authentication methods, choosing preferred APNS Auth Key method...") + } else { + hasAuthentication = true + self.certPath = certPath + self.keyPath = keyPath + } } - if hasBothAuthentication { - print ("You've seem to have specified both authentication methods, choosing preferred APNS Auth Key method...") - certPath = nil - keyPath = nil + guard hasAuthentication else { + throw InitializeError.noAuthentication } } diff --git a/Sources/VaporAPNS/Payload.swift b/Sources/VaporAPNS/Payload.swift index a8dbde7..f8d0b0e 100644 --- a/Sources/VaporAPNS/Payload.swift +++ b/Sources/VaporAPNS/Payload.swift @@ -69,73 +69,73 @@ open class Payload: JSONRepresentable { if contentAvailable { apsPayloadData["content-available"] = true } else { - - // Create alert dictionary - var alert: [String: NodeRepresentable] = [:] - - if let title = title { - alert["title"] = title - } - - if let titleLocKey = titleLocKey { - alert["title-loc-key"] = titleLocKey - if let titleLocArgs = titleLocArgs { - alert["title-loc-args"] = try titleLocArgs.makeNode() + // Create alert dictionary + var alert: [String: NodeRepresentable] = [:] + + if let title = title { + alert["title"] = title } - } - - if let subtitle = subtitle { - alert["subtitle"] = subtitle - } - - if let body = body { - alert["body"] = body - }else { - if let bodyLocKey = bodyLocKey { - alert["loc-key"] = bodyLocKey + + if let titleLocKey = titleLocKey { + alert["title-loc-key"] = titleLocKey - if let bodyLocArgs = bodyLocArgs { - alert["loc-args"] = try bodyLocArgs.makeNode() + if let titleLocArgs = titleLocArgs { + alert["title-loc-args"] = try titleLocArgs.makeNode(in: nil) } } + + if let subtitle = subtitle { + alert["subtitle"] = subtitle + } + + if let body = body { + alert["body"] = body + } else { + if let bodyLocKey = bodyLocKey { + alert["loc-key"] = bodyLocKey + + if let bodyLocArgs = bodyLocArgs { + alert["loc-args"] = try bodyLocArgs.makeNode(in: nil) + } + } + } + + if let actionLocKey = actionLocKey { + alert["action-loc-key"] = actionLocKey + } + + if let launchImage = launchImage { + alert["launch-image"] = launchImage + } + // Alert dictionary created + + apsPayloadData["alert"] = try alert.makeNode(in: nil) + + if let badge = badge { + apsPayloadData["badge"] = badge + } + + if let sound = sound { + apsPayloadData["sound"] = sound + } + + if let category = category { + apsPayloadData["category"] = category + } + + if hasMutableContent { + apsPayloadData["mutable-content"] = 1 + } + } - if let actionLocKey = actionLocKey { - alert["action-loc-key"] = actionLocKey - } - - if let launchImage = launchImage { - alert["launch-image"] = launchImage - } - // Alert dictionary created - - apsPayloadData["alert"] = try alert.makeNode() - - if let badge = badge { - apsPayloadData["badge"] = badge - } - - if let sound = sound { - apsPayloadData["sound"] = sound - } - - if let category = category { - apsPayloadData["category"] = category - } - - if hasMutableContent { - apsPayloadData["mutable-content"] = 1 - } - - } - - payloadData["aps"] = try apsPayloadData.makeNode() + payloadData["aps"] = try apsPayloadData.makeNode(in: nil) for (key, value) in extra { payloadData[key] = value } - let json = try JSON(node: try payloadData.makeNode()) + let json = JSON(node: try payloadData.makeNode(in: nil)) return json } } diff --git a/Sources/VaporAPNS/String+APNS.swift b/Sources/VaporAPNS/String+APNS.swift index 5af9d6e..2563c29 100644 --- a/Sources/VaporAPNS/String+APNS.swift +++ b/Sources/VaporAPNS/String+APNS.swift @@ -75,35 +75,35 @@ extension String { // print (privateKey) let privData = privateKey.dataFromHexadecimalString()! - let privBase64String = try String.init(bytes: privData.base64Encoded) + let privBase64String = String(bytes: privData.base64Encoded) let pubData = publicKey.dataFromHexadecimalString()! - let pubBase64String = try String.init(bytes: pubData.base64Encoded) - + let pubBase64String = String(bytes: pubData.base64Encoded) + return (privBase64String, pubBase64String) } - /// Create `NSData` from hexadecimal string representation - /// - /// This takes a hexadecimal representation and creates a `NSData` object. Note, if the string has any spaces or non-hex characters (e.g. starts with '<' and with a '>'), those are ignored and only hex characters are processed. - /// - /// - returns: Data represented by this hexadecimal string. - - func dataFromHexadecimalString() -> Data? { - var data = Data(capacity: characters.count / 2) - - let regex = try! NSRegularExpression(pattern: "[0-9a-f]{1,2}", options: .caseInsensitive) - regex.enumerateMatches(in: self, options: [], range: NSMakeRange(0, characters.count)) { match, flags, stop in - let range = self.range(from: match!.range) - let byteString = self.substring(with: range!) - var num = UInt8(byteString, radix: 16) - data.append(&num!, count: 1) - } - - return data + /// Create `NSData` from hexadecimal string representation + /// + /// This takes a hexadecimal representation and creates a `NSData` object. Note, if the string has any spaces or non-hex characters (e.g. starts with '<' and with a '>'), those are ignored and only hex characters are processed. + /// + /// - returns: Data represented by this hexadecimal string. + + func dataFromHexadecimalString() -> Data? { + var data = Data(capacity: characters.count / 2) + + let regex = try! NSRegularExpression(pattern: "[0-9a-f]{1,2}", options: .caseInsensitive) + regex.enumerateMatches(in: self, options: [], range: NSMakeRange(0, characters.count)) { match, flags, stop in + let range = self.range(from: match!.range) + let byteString = self.substring(with: range!) + var num = UInt8(byteString, radix: 16) + data.append(&num!, count: 1) } + + return data + } func splitByLength(_ length: Int) -> [String] { var result = [String]() diff --git a/Sources/VaporAPNS/VaporAPNS.swift b/Sources/VaporAPNS/VaporAPNS.swift index 1f58556..5671c8a 100644 --- a/Sources/VaporAPNS/VaporAPNS.swift +++ b/Sources/VaporAPNS/VaporAPNS.swift @@ -3,7 +3,6 @@ import SwiftString import JSON import CCurl import JSON -import Jay import JWT import Console @@ -19,7 +18,7 @@ open class VaporAPNS { if options.forceCurlInstall { let curlupdater = CurlUpdater() curlupdater.updateCurl() - }else { + } else { let curlVersionChecker = CurlVersionHelper() curlVersionChecker.checkVersion() } @@ -72,11 +71,12 @@ open class VaporAPNS { var curlHeaders: UnsafeMutablePointer? if !options.usesCertificateAuthentication { let privateKey = options.privateKey!.bytes.base64Decoded - + let claims: [Claim] = [ + IssuerClaim(string: options.teamId!), + IssuedAtClaim() + ] let jwt = try! JWT(additionalHeaders: [KeyID(options.keyId!)], - payload: Node([IssuerClaim(options.teamId!), - IssuedAtClaim()]), - encoding: Base64URLEncoding(), + payload: JSON(claims), signer: ES256(key: privateKey)) let tokenString = try! jwt.createToken() @@ -84,7 +84,7 @@ open class VaporAPNS { let publicKey = options.publicKey!.bytes.base64Decoded do { - let jwt2 = try JWT(token: tokenString, encoding: Base64URLEncoding()) + let jwt2 = try JWT(token: tokenString) do { try jwt2.verifySignature(using: ES256(key: publicKey)) } catch { @@ -140,15 +140,13 @@ open class VaporAPNS { if responseData != "" { // Get JSON from loaded data string - let json = try! Jay.init(formatting: .minified).jsonFromData(try! responseData.makeBytes()) - - if (json.dictionary?.keys.contains("reason"))! { - result = Result.error(apnsId: message.messageId, deviceToken: deviceToken, error: APNSError.init(errorReason: json.dictionary!["reason"]!.string!)) - }else { + let jsonNode = JSON(.bytes(responseData.makeBytes()), in: nil).makeNode(in: nil) + if let reason = jsonNode["reason"]?.string { + result = Result.error(apnsId: message.messageId, deviceToken: deviceToken, error: APNSError.init(errorReason: reason)) + } else { result = Result.success(apnsId: message.messageId, deviceToken: deviceToken, serviceStatus: .success) } - - }else { + } else { result = Result.success(apnsId: message.messageId, deviceToken: deviceToken, serviceStatus: .success) } @@ -166,7 +164,6 @@ open class VaporAPNS { // todo: Better unknown error handling? return Result.networkError(error: SimpleError.string(message: errorString)) - } } diff --git a/Tests/VaporAPNSTests/ApplePushMessageTests.swift b/Tests/VaporAPNSTests/ApplePushMessageTests.swift index 112e0fc..40a4687 100644 --- a/Tests/VaporAPNSTests/ApplePushMessageTests.swift +++ b/Tests/VaporAPNSTests/ApplePushMessageTests.swift @@ -17,9 +17,9 @@ class ApplePushMessageTests: XCTestCase { let pushMessage = ApplePushMessage(topic: "com.apple.Test", priority: .immediately, expirationDate: nil, payload: simplePayload,sandbox: true, collapseIdentifier: "collapseID", threadIdentifier: "threadId") XCTAssertEqual(pushMessage.topic, "com.apple.Test") - XCTAssertTrue(pushMessage.sandbox) - XCTAssertEqual(pushMessage.collapseIdentifier, "collapseID") - XCTAssertEqual(pushMessage.threadIdentifier, "threadId") + XCTAssertTrue(pushMessage.sandbox) + XCTAssertEqual(pushMessage.collapseIdentifier, "collapseID") + XCTAssertEqual(pushMessage.threadIdentifier, "threadId") XCTAssertEqual(pushMessage.priority, .immediately) XCTAssertNil(pushMessage.expirationDate) XCTAssertEqual(try! pushMessage.payload.makeJSON(), try! simplePayload.makeJSON()) diff --git a/Sources/VaporAPNS/JSON+String.swift b/Tests/VaporAPNSTests/JSON+String.swift similarity index 75% rename from Sources/VaporAPNS/JSON+String.swift rename to Tests/VaporAPNSTests/JSON+String.swift index 106abe0..dd97e08 100644 --- a/Sources/VaporAPNS/JSON+String.swift +++ b/Tests/VaporAPNSTests/JSON+String.swift @@ -2,7 +2,7 @@ // JSON+String.swift // VaporAPNS // -// Created by Matthijs Logemann on 01/10/2016. +// Created by Jimmy Arts on 19/05/2017. // // @@ -12,7 +12,7 @@ import JSON extension JSON { func toString() throws -> String { let bytes = try self.serialize(prettyPrint: false) - let data = Data.init(bytes: bytes) + let data = Data(bytes: bytes) let plString = String(data: data, encoding: .utf8) return plString! } diff --git a/Tests/VaporAPNSTests/PayloadTests.swift b/Tests/VaporAPNSTests/PayloadTests.swift index f369862..e208aa4 100644 --- a/Tests/VaporAPNSTests/PayloadTests.swift +++ b/Tests/VaporAPNSTests/PayloadTests.swift @@ -8,79 +8,95 @@ import Foundation import XCTest +import JSON @testable import class VaporAPNS.Payload -class PayloadTests: XCTestCase { // TODO: Set this up so others can test this 😉 - - override func setUp() { -// print ("Hi") - } +class PayloadTests: XCTestCase { func testInitializer() throws { } func testSimplePush() throws { - let expectedJSON = "{\"aps\":{\"alert\":{\"body\":\"Test\"}}}" + let expectedJSON = Node(node: .object(["aps": .object(["alert": .object(["body": .string("Test")])])]), in: nil) - let payload = Payload.init(message: "Test") - let plJosn = try payload.makeJSON() - let plString = try plJosn.toString() + let payload = Payload(message: "Test") + let plJSON = try payload.makeJSON() + let plNode = plJSON.makeNode(in: nil) - XCTAssertEqual(plString, expectedJSON) + XCTAssertNotNil(plNode["aps"]?["alert"]?["body"]?.string) + XCTAssertEqual(plNode["aps"]?["alert"]?["body"]?.string, expectedJSON["aps"]?["alert"]?["body"]?.string) } func testTitleBodyPush() throws { - let expectedJSON = "{\"aps\":{\"alert\":{\"body\":\"Test body\",\"title\":\"Test title\"}}}" + let expectedJSON = Node(node: .object(["aps": .object(["alert": .object(["body": .string("Test body"), "title": .string("Test title")])])]), in: nil) let payload = Payload.init(title: "Test title", body: "Test body") - let plJosn = try payload.makeJSON() - let plString = try plJosn.toString() + let plJSON = try payload.makeJSON() + let plNode = plJSON.makeNode(in: nil) - XCTAssertEqual(plString, expectedJSON) + XCTAssertNotNil(plNode["aps"]?["alert"]?["body"]?.string) + XCTAssertEqual(plNode["aps"]?["alert"]?["body"]?.string, expectedJSON["aps"]?["alert"]?["body"]?.string) + XCTAssertNotNil(plNode["aps"]?["alert"]?["title"]?.string) + XCTAssertEqual(plNode["aps"]?["alert"]?["title"]?.string, expectedJSON["aps"]?["alert"]?["title"]?.string) } func testTitleBodyBadgePush() throws { - let expectedJSON = "{\"aps\":{\"alert\":{\"body\":\"Test body\",\"title\":\"Test title\"},\"badge\":10}}" + let expectedJSON = Node(node: .object(["aps": .object(["alert": .object(["body": .string("Test body"), "title": .string("Test title")]), "badge": .number(.int(10))])]), in: nil) let payload = Payload.init(title: "Test title", body: "Test body", badge: 10) - let plJosn = try payload.makeJSON() - let plString = try plJosn.toString() + let plJSON = try payload.makeJSON() + let plNode = plJSON.makeNode(in: nil) - XCTAssertEqual(plString, expectedJSON) + XCTAssertNotNil(plNode["aps"]?["alert"]?["body"]?.string) + XCTAssertEqual(plNode["aps"]?["alert"]?["body"]?.string, expectedJSON["aps"]?["alert"]?["body"]?.string) + XCTAssertNotNil(plNode["aps"]?["alert"]?["title"]?.string) + XCTAssertEqual(plNode["aps"]?["alert"]?["title"]?.string, expectedJSON["aps"]?["alert"]?["title"]?.string) + XCTAssertNotNil(plNode["aps"]?["badge"]?.int) + XCTAssertEqual(plNode["aps"]?["badge"]?.int, expectedJSON["aps"]?["badge"]?.int) } func testTitleSubtitleBodyPush() throws { - let expectedJSON = "{\"aps\":{\"alert\":{\"body\":\"Test body\",\"subtitle\":\"Test subtitle\",\"title\":\"Test title\"}}}" + let expectedJSON = Node(node: .object(["aps": .object(["alert": .object(["body": .string("Test body"), "title": .string("Test title"), "subtitle": .string("Test subtitle")])])]), in: nil) let payload = Payload.init(title: "Test title", body: "Test body") payload.subtitle = "Test subtitle" - let plJosn = try payload.makeJSON() - let plString = try plJosn.toString() + let plJSON = try payload.makeJSON() + let plNode = plJSON.makeNode(in: nil) - XCTAssertEqual(plString, expectedJSON) + XCTAssertNotNil(plNode["aps"]?["alert"]?["body"]?.string) + XCTAssertEqual(plNode["aps"]?["alert"]?["body"]?.string, expectedJSON["aps"]?["alert"]?["body"]?.string) + XCTAssertNotNil(plNode["aps"]?["alert"]?["title"]?.string) + XCTAssertEqual(plNode["aps"]?["alert"]?["title"]?.string, expectedJSON["aps"]?["alert"]?["title"]?.string) + XCTAssertNotNil(plNode["aps"]?["alert"]?["subtitle"]?.string) + XCTAssertEqual(plNode["aps"]?["alert"]?["subtitle"]?.string, expectedJSON["aps"]?["alert"]?["subtitle"]?.string) } func testContentAvailablePush() throws { - let expectedJSON = "{\"aps\":{\"content-available\":true}}" + let expectedJSON = Node(node: .object(["aps": .object(["content-available": .bool(true)])]), in: nil) let payload = Payload.contentAvailable - let plJosn = try payload.makeJSON() - let plString = try plJosn.toString() + let plJSON = try payload.makeJSON() + let plNode = plJSON.makeNode(in: nil) - XCTAssertEqual(plString, expectedJSON) + XCTAssertNotNil(plNode["aps"]?["content-available"]?.bool) + XCTAssertEqual(plNode["aps"]?["content-available"]?.bool, expectedJSON["aps"]?["content-available"]?.bool) } func testContentAvailableWithExtrasPush() throws { - let expectedJSON = "{\"IntKey\":101,\"StringKey\":\"StringExtra1\",\"aps\":{\"content-available\":true}}" - let linuxExpectedJSON = "{\"aps\":{\"content-available\":true},\"IntKey\":101,\"StringKey\":\"StringExtra1\"}" + let expectedJSON = Node(node: .object(["aps": .object(["content-available": .bool(true)]), "IntKey": .number(.int(101)), "StringKey": .string("StringExtra1")]), in: nil) let payload = Payload.contentAvailable payload.extra["StringKey"] = "StringExtra1" payload.extra["IntKey"] = 101 - let plJosn = try payload.makeJSON() - let plString = try plJosn.toString() + let plJSON = try payload.makeJSON() + let plNode = plJSON.makeNode(in: nil) - XCTAssertTrue(plString == expectedJSON || plString == linuxExpectedJSON) + XCTAssertNotNil(plNode["aps"]?["content-available"]?.bool) + XCTAssertEqual(plNode["aps"]?["content-available"]?.bool, expectedJSON["aps"]?["content-available"]?.bool) + XCTAssertNotNil(plNode["StringKey"]?.string) + XCTAssertEqual(plNode["StringKey"]?.string, expectedJSON["StringKey"]?.string) + XCTAssertNotNil(plNode["IntKey"]?.int) + XCTAssertEqual(plNode["IntKey"]?.int, expectedJSON["IntKey"]?.int) } static var allTests : [(String, (PayloadTests) -> () throws -> Void)] { diff --git a/Tests/VaporAPNSTests/TestAPNSAuthKey.p8 b/Tests/VaporAPNSTests/TestAPNSAuthKey.p8 index 4438426..5de0dfe 100644 --- a/Tests/VaporAPNSTests/TestAPNSAuthKey.p8 +++ b/Tests/VaporAPNSTests/TestAPNSAuthKey.p8 @@ -1,3 +1,6 @@ -----BEGIN PRIVATE KEY----- -MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgsQgtXIZadsFpJogUOyHTKhlor4SPSmj/nmMbYVHq7oKgCgYIKoZIzj0DAQehRANCAASqisAeoaV6fUs1hrd2MZx4AhJHG0viUq4aKpHqq7vzX+tjHhPefESIimLCxQP3M3RO04QreOms53lNCAZzArkF ------END PRIVATE KEY----- +MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgsQgtXIZadsFpJogU + OyHTKhlor4SPSmj/nmMbYVHq7oKgCgYIKoZIzj0DAQehRANCAASqisAeoaV6fUs + 1 hrd2MZx4AhJHG0viUq4aKpHqq7vzX+tjHhPefESIimLCxQP3M3RO04QreOms5 + 3 lN CAZzArkF +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/Tests/VaporAPNSTests/VaporAPNSTests.swift b/Tests/VaporAPNSTests/VaporAPNSTests.swift index bf9cc1a..93e3e53 100644 --- a/Tests/VaporAPNSTests/VaporAPNSTests.swift +++ b/Tests/VaporAPNSTests/VaporAPNSTests.swift @@ -9,37 +9,18 @@ import XCTest @testable import VaporAPNS import JWT -import JSON - import Foundation -import CLibreSSL -import Core -class VaporAPNSTests: XCTestCase { // TODO: Set this up so others can test this 😉 +class VaporAPNSTests: XCTestCase { let vaporAPNS: VaporAPNS! = nil - override func setUp() { -// print ("Hi") - } - func testLoadPrivateKey() throws { - var filepath = "" - let fileManager = FileManager.default - - #if os(Linux) - filepath = fileManager.currentDirectoryPath.appending("/Tests/VaporAPNSTests/TestAPNSAuthKey.p8") - #else - if let filepathe = Bundle.init(for: type(of: self)).path(forResource: "TestAPNSAuthKey", ofType: "p8") { - filepath = filepathe - }else { - filepath = fileManager.currentDirectoryPath.appending("/Tests/VaporAPNSTests/TestAPNSAuthKey.p8") - } - #endif - print (filepath) + let folderPath = #file.components(separatedBy: "/").dropLast().joined(separator: "/") + let filePath = "\(folderPath)/TestAPNSAuthKey.p8" - if fileManager.fileExists(atPath: filepath) { - let (privKey, pubKey) = try filepath.tokenString() + if FileManager.default.fileExists(atPath: filePath) { + let (privKey, pubKey) = try filePath.tokenString() XCTAssertEqual(privKey, "ALEILVyGWnbBaSaIFDsh0yoZaK+Ej0po/55jG2FR6u6C") XCTAssertEqual(pubKey, "BKqKwB6hpXp9SzWGt3YxnHgCEkcbS+JSrhoqkeqru/Nf62MeE958RIiKYsLFA/czdE7ThCt46azneU0IBnMCuQU=") } else { @@ -48,9 +29,11 @@ class VaporAPNSTests: XCTestCase { // TODO: Set this up so others can test this } func testEncoding() throws { + let claims: [Claim] = [IssuerClaim(string: "D86BEC0E8B"), IssuedAtClaim()] + let claimsNode = Node(claims) let jwt = try! JWT( additionalHeaders: [KeyID("E811E6AE22")], - payload: Node([IssuerClaim("D86BEC0E8B"), IssuedAtClaim()]), + payload: claimsNode.converted(to: JSON.self), signer: ES256(key: "ALEILVyGWnbBaSaIFDsh0yoZaK+Ej0po/55jG2FR6u6C".bytes.base64Decoded)) let tokenString = try! jwt.createToken() @@ -58,10 +41,8 @@ class VaporAPNSTests: XCTestCase { // TODO: Set this up so others can test this do { let jwt2 = try JWT(token: tokenString) try jwt2.verifySignature(using: ES256(key: "BKqKwB6hpXp9SzWGt3YxnHgCEkcbS+JSrhoqkeqru/Nf62MeE958RIiKYsLFA/czdE7ThCt46azneU0IBnMCuQU=".bytes.base64Decoded)) - XCTAssertTrue(true) // Since verifySignature will throw on an invalid signature, we'll just pass true here } catch { - print(error) - XCTFail("Couldn't verify token") + XCTFail("Couldn't verify token, failed with error: \(error)") } }