From fc12731e39b8206dc1e7a6774f76c596bdf13678 Mon Sep 17 00:00:00 2001 From: Angela Brett Date: Thu, 8 Jul 2021 16:10:11 +0200 Subject: [PATCH 1/7] Updated FiskalyHttpClient to include the smaersUrl and miceUrl needed for v2 (requires new client library) Made all unit tests also show the log from the client library, for easier debugging Added an end-to-end test for V2 --- FiskalySDK.xcodeproj/project.pbxproj | 16 +- FiskalySDK/Classes/FiskalyHttpClient.swift | 22 +- FiskalySDK/Classes/JsonRpc/JsonRpcError.swift | 2 +- FiskalySDKTests/FiskalyAPITests.swift | 187 +++++---------- FiskalySDKTests/FiskalyAPITestsV1.swift | 137 +++++++++++ FiskalySDKTests/FiskalyAPITestsV2.swift | 216 ++++++++++++++++++ 6 files changed, 439 insertions(+), 141 deletions(-) create mode 100644 FiskalySDKTests/FiskalyAPITestsV1.swift create mode 100644 FiskalySDKTests/FiskalyAPITestsV2.swift diff --git a/FiskalySDK.xcodeproj/project.pbxproj b/FiskalySDK.xcodeproj/project.pbxproj index bc5e77e..f85ef28 100644 --- a/FiskalySDK.xcodeproj/project.pbxproj +++ b/FiskalySDK.xcodeproj/project.pbxproj @@ -23,7 +23,7 @@ /* Begin PBXBuildFile section */ 1FA3FA8E2491671A00348FDE /* FiskalyRequestClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FA3FA8D2491671A00348FDE /* FiskalyRequestClient.swift */; }; 6AAD637224606FEF00D2E36A /* FiskalyClientTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AAD637124606FEF00D2E36A /* FiskalyClientTests.swift */; }; - 6AAD63742460700B00D2E36A /* FiskalyAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AAD63732460700B00D2E36A /* FiskalyAPITests.swift */; }; + 6AAD63742460700B00D2E36A /* FiskalyAPITestsV1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AAD63732460700B00D2E36A /* FiskalyAPITestsV1.swift */; }; 6AD8BBF024486B18000D47BD /* JsonRpcRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AD8BBEF24486B18000D47BD /* JsonRpcRequest.swift */; }; 6AD8BBF924488C73000D47BD /* JsonRpcResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AD8BBF824488C73000D47BD /* JsonRpcResponse.swift */; }; 6AD8BBFB24488C82000D47BD /* JsonRpcError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AD8BBFA24488C82000D47BD /* JsonRpcError.swift */; }; @@ -34,6 +34,8 @@ D9BFF5C4244629610032D061 /* FiskalySDKTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9BFF5C3244629610032D061 /* FiskalySDKTests.swift */; }; D9BFF5C6244629610032D061 /* FiskalySDK.h in Headers */ = {isa = PBXBuildFile; fileRef = D9BFF5B8244629610032D061 /* FiskalySDK.h */; settings = {ATTRIBUTES = (Public, ); }; }; D9F90FEF24478702002057D3 /* FiskalyHttpClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9F90FEE24478702002057D3 /* FiskalyHttpClient.swift */; }; + E98898022695B28E00508F08 /* FiskalyAPITestsV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98898012695B28E00508F08 /* FiskalyAPITestsV2.swift */; }; + E98898042695C58D00508F08 /* FiskalyAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98898032695C58D00508F08 /* FiskalyAPITests.swift */; }; E99EA8502678968A00B04017 /* com.fiskaly.client-ios-all-v1.2.200.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = E99EA84F2678968A00B04017 /* com.fiskaly.client-ios-all-v1.2.200.xcframework */; }; E99EA8512678968A00B04017 /* com.fiskaly.client-ios-all-v1.2.200.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = E99EA84F2678968A00B04017 /* com.fiskaly.client-ios-all-v1.2.200.xcframework */; }; /* End PBXBuildFile section */ @@ -51,7 +53,7 @@ /* Begin PBXFileReference section */ 1FA3FA8D2491671A00348FDE /* FiskalyRequestClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FiskalyRequestClient.swift; sourceTree = ""; }; 6AAD637124606FEF00D2E36A /* FiskalyClientTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FiskalyClientTests.swift; sourceTree = ""; }; - 6AAD63732460700B00D2E36A /* FiskalyAPITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FiskalyAPITests.swift; sourceTree = ""; }; + 6AAD63732460700B00D2E36A /* FiskalyAPITestsV1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FiskalyAPITestsV1.swift; sourceTree = ""; }; 6AD8BBEF24486B18000D47BD /* JsonRpcRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JsonRpcRequest.swift; sourceTree = ""; }; 6AD8BBF824488C73000D47BD /* JsonRpcResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JsonRpcResponse.swift; sourceTree = ""; }; 6AD8BBFA24488C82000D47BD /* JsonRpcError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JsonRpcError.swift; sourceTree = ""; }; @@ -68,6 +70,8 @@ D9F90FEE24478702002057D3 /* FiskalyHttpClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FiskalyHttpClient.swift; sourceTree = ""; }; D9F90FF424478A8C002057D3 /* readme.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = readme.md; sourceTree = ""; }; E951483C268233DC0026A559 /* build_xcframework.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = build_xcframework.sh; sourceTree = ""; }; + E98898012695B28E00508F08 /* FiskalyAPITestsV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FiskalyAPITestsV2.swift; sourceTree = ""; }; + E98898032695C58D00508F08 /* FiskalyAPITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FiskalyAPITests.swift; sourceTree = ""; }; E99EA84F2678968A00B04017 /* com.fiskaly.client-ios-all-v1.2.200.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = "com.fiskaly.client-ios-all-v1.2.200.xcframework"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -161,7 +165,9 @@ D9BFF5C3244629610032D061 /* FiskalySDKTests.swift */, D9BFF5C5244629610032D061 /* Info.plist */, 6AAD637124606FEF00D2E36A /* FiskalyClientTests.swift */, - 6AAD63732460700B00D2E36A /* FiskalyAPITests.swift */, + 6AAD63732460700B00D2E36A /* FiskalyAPITestsV1.swift */, + E98898012695B28E00508F08 /* FiskalyAPITestsV2.swift */, + E98898032695C58D00508F08 /* FiskalyAPITests.swift */, ); path = FiskalySDKTests; sourceTree = ""; @@ -343,8 +349,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6AAD63742460700B00D2E36A /* FiskalyAPITests.swift in Sources */, + 6AAD63742460700B00D2E36A /* FiskalyAPITestsV1.swift in Sources */, 6AAD637224606FEF00D2E36A /* FiskalyClientTests.swift in Sources */, + E98898022695B28E00508F08 /* FiskalyAPITestsV2.swift in Sources */, + E98898042695C58D00508F08 /* FiskalyAPITests.swift in Sources */, D9BFF5C4244629610032D061 /* FiskalySDKTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/FiskalySDK/Classes/FiskalyHttpClient.swift b/FiskalySDK/Classes/FiskalyHttpClient.swift index c747ae5..82c07ce 100644 --- a/FiskalySDK/Classes/FiskalyHttpClient.swift +++ b/FiskalySDK/Classes/FiskalyHttpClient.swift @@ -2,7 +2,7 @@ import Foundation public class FiskalyHttpClient { - private var context: String + private var context: String = "" private let client: RequestClient /* @@ -16,16 +16,15 @@ public class FiskalyHttpClient { password: String? = "", organizationId: String? = "", environment: String? = "", - client: RequestClient = FiskalyRequestClient()) throws { + client: RequestClient = FiskalyRequestClient(), + smaersUrl: String? = nil, + miceUrl: String? = nil + ) throws { self.client = client - // this needs to be done because xcode cries that self.context is used before be initialized - - self.context = "" - // version is hardcorded because using versionNumber from header file strips patch number - let contextRequestParams: [String: Any] = [ + var contextRequestParams: [String: Any] = [ "api_key": apiKey as Any, "api_secret": apiSecret as Any, "base_url": baseUrl, @@ -35,6 +34,13 @@ public class FiskalyHttpClient { "environment": environment as Any, "sdk_version": "iOS SDK 1.2.100" ] + + //these should only be set for v2 + if let smaersUrl = smaersUrl, let miceUrl = miceUrl { + contextRequestParams["smaers_url"] = smaersUrl + contextRequestParams["mice_url"] = miceUrl + //contextRequestParams["base_url"] = "http://backend:3000" + } let request = JsonRpcRequest(method: "create-context", params: contextRequestParams) let response = try performJsonRpcRequest(request: request, ResultCreateContext.self) @@ -196,7 +202,7 @@ public class FiskalyHttpClient { throw FiskalyError.sdkError(message: "Client response not decodable into class. \(error), data = \(jsonData)") } - print(response.error?.data?.response.body ?? "NO ERROR") + print(response.error?.data?.response.body ?? response.error?.message ?? "NO ERROR") return response } diff --git a/FiskalySDK/Classes/JsonRpc/JsonRpcError.swift b/FiskalySDK/Classes/JsonRpc/JsonRpcError.swift index 0087f3e..5cb89d7 100644 --- a/FiskalySDK/Classes/JsonRpc/JsonRpcError.swift +++ b/FiskalySDK/Classes/JsonRpc/JsonRpcError.swift @@ -16,6 +16,6 @@ public class JsonRpcError: Error, Codable { extension JsonRpcError: CustomDebugStringConvertible { public var debugDescription: String { - return "JSON RPC error \(code): \(message)\n\(data?.context ?? "no context")" + return "JSON RPC error \(code): \(message)\n\(data?.context ?? "no additional data")" } } diff --git a/FiskalySDKTests/FiskalyAPITests.swift b/FiskalySDKTests/FiskalyAPITests.swift index b815ca8..40671fc 100644 --- a/FiskalySDKTests/FiskalyAPITests.swift +++ b/FiskalySDKTests/FiskalyAPITests.swift @@ -1,138 +1,69 @@ +// +// FiskalyAPITests.swift +// FiskalySDKTests +// +// Created by Angela Brett on 07.07.21. +// Copyright © 2021 fiskaly. All rights reserved. +// + +import Foundation + import XCTest @testable import FiskalySDK +//Superclass that sets up the client to have verbose logging and outputs the logging from the client into the console so you have more detail if a test fails. class FiskalyAPITests: XCTestCase { - - func testKassensichvRequest() throws { - let client = try FiskalyHttpClient( - apiKey: ProcessInfo.processInfo.environment["API_KEY"]!, - apiSecret: ProcessInfo.processInfo.environment["API_SECRET"]!, - baseUrl: "https://kassensichv.io/api/v1/" - ) - let response = try client.request( - method: "GET", - path: "/tss") - XCTAssertEqual(response.status, 200) + var client:FiskalyHttpClient! + private var logPath:String! + + func setUpLogging(methodName:String) { + //set up debug logging within the client library so we can show more detail in the test log + + //methodName is the full name of the currently running test + let testName = methodName.replacingOccurrences(of: "-[\(String(describing: Self.self))", with: "").replacingOccurrences(of: "]", with: "") + + logPath = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("fiskaly-tests-\(testName)").appendingPathExtension("log").path + + do { + //remove the previous log for this test so we can just show the results for this run + if FileManager.default.fileExists(atPath: logPath) { + try FileManager.default.removeItem(atPath: logPath) + } + + //set up client logging for this test + let _ = try client.config( + debugLevel: 3, + debugFile: logPath, + clientTimeout: 1500, + smaersTimeout: 1500, + httpProxy: "") + print("Client log is at \(logPath ?? "")") + } catch { + print("Could not set up client logging: \(error)") + //we can still continue with the test in this case + } } - - func testManagementRequest() throws { - let client = try FiskalyHttpClient( - apiKey: "", - apiSecret: "", - baseUrl: "https://dashboard.fiskaly.com/api/v0/", - email: ProcessInfo.processInfo.environment["EMAIL"]!, - password: ProcessInfo.processInfo.environment["PASSWORD"]! - ) - let response = try client.request( - method: "GET", - path: "/organizations") - XCTAssertEqual(response.status, 200) + func showClientLog() { + //now show all the logging from the client during this test + if let logContents = try? String(contentsOfFile: logPath) { + print("Log contents: \(logContents)") + } } - - func testTransactionRequest() throws { - let client = try FiskalyHttpClient( - apiKey: ProcessInfo.processInfo.environment["API_KEY"]!, - apiSecret: ProcessInfo.processInfo.environment["API_SECRET"]!, - baseUrl: "https://kassensichv.io/api/v1/" - ) - - // create TSS - - let tssUUID = UUID().uuidString - - let tssBody = [ - "description": "iOS Test TSS", - "state": "INITIALIZED" - ] - let tssBodyData = try? JSONSerialization.data(withJSONObject: tssBody) - let tssBodyEncoded = tssBodyData?.base64EncodedString() - - let responseCreateTSS = try client.request( - method: "PUT", - path: "tss/\(tssUUID)", - body: tssBodyEncoded!) - XCTAssertEqual(responseCreateTSS.status, 200) - - // create Client - - let clientUUID = UUID().uuidString - - let clientBody = [ - "serial_number": "iOS Test Client Serial" - ] - let clientBodyData = try? JSONSerialization.data(withJSONObject: clientBody) - let clientBodyEncoded = clientBodyData?.base64EncodedString() - - let responseCreateClient = try client.request( - method: "PUT", - path: "tss/\(tssUUID)/client/\(clientUUID)", - body: clientBodyEncoded!) - XCTAssertEqual(responseCreateClient.status, 200) - - // create Transaction - - let transactionUUID = UUID().uuidString - - let transactionBody = [ - "state": "ACTIVE", - "client_id": clientUUID - ] - let transactionBodyData = try? JSONSerialization.data(withJSONObject: transactionBody) - let transactionBodyEncoded = transactionBodyData?.base64EncodedString() - - let responseCreateTransaction = try client.request( - method: "PUT", - path: "tss/\(tssUUID)/tx/\(transactionUUID)", - body: transactionBodyEncoded!) - XCTAssertEqual(responseCreateTransaction.status, 200) - - // finish Transaction - - let transactionFinishBody: [String: Any] = [ - "state": "FINISHED", - "client_id": clientUUID, - "schema": [ - "standard_v1": [ - "receipt": [ - "receipt_type": "RECEIPT", - "amounts_per_vat_rate": [ - ["vat_rate": "19", "amount": "14.28"] - ], - "amounts_per_payment_type": [ - ["payment_type": "NON_CASH", "amount": "14.28"] - ] - ] - ] - ] - ] - let transactionFinishBodyData = try? JSONSerialization.data(withJSONObject: transactionFinishBody) - let transactionFinishBodyEncoded = transactionFinishBodyData?.base64EncodedString() - - let responseFinishTransaction = try client.request( - method: "PUT", - path: "tss/\(tssUUID)/tx/\(transactionUUID)", - query: ["last_revision": "1"], - body: transactionFinishBodyEncoded!) - XCTAssertEqual(responseFinishTransaction.status, 200) - } - - func testQueryArray() throws { - let client = try FiskalyHttpClient( - apiKey: ProcessInfo.processInfo.environment["API_KEY"]!, - apiSecret: ProcessInfo.processInfo.environment["API_SECRET"]!, - baseUrl: "https://kassensichv.io/api/v1/" - ) - - let query: [String: Any] = [ - "states": ["INITIALIZED", "DISABLED"] - ] - + + func clientRequest(method: String, path: String, query: [String : Any]? = nil, body: Any? = nil, headers:[String:String]? = nil) throws -> FiskalySDK.HttpResponse { + guard let client = self.client else { + throw FiskalyError.sdkError(message: "Client could not be initialised") + } + + let bodyData = try JSONSerialization.data(withJSONObject: body ?? Dictionary()) + let bodyString = bodyData.base64EncodedString() let response = try client.request( - method: "GET", - path: "/tss", - query: query) + method: method, + path: path, + query: query, + headers: headers, + body: bodyString) XCTAssertEqual(response.status, 200) - + return response } - } diff --git a/FiskalySDKTests/FiskalyAPITestsV1.swift b/FiskalySDKTests/FiskalyAPITestsV1.swift new file mode 100644 index 0000000..7a94975 --- /dev/null +++ b/FiskalySDKTests/FiskalyAPITestsV1.swift @@ -0,0 +1,137 @@ +import XCTest +@testable import FiskalySDK + +class FiskalyAPITestsV1: FiskalyAPITests { + + override func setUpWithError() throws { + client = try FiskalyHttpClient( + apiKey: ProcessInfo.processInfo.environment["API_KEY"]!, + apiSecret: ProcessInfo.processInfo.environment["API_SECRET"]!, + baseUrl: "https://kassensichv.io/api/v1/" + ) + + setUpLogging(methodName: self.name) + } + + override func tearDown() { + showClientLog() + } + + func testKassensichvRequest() throws { + let response = try client.request( + method: "GET", + path: "/tss") + XCTAssertEqual(response.status, 200) + } +//this does not seem to work with the new client; it apparently can't create a context with just email and password + func testManagementRequest() throws { + let client = try FiskalyHttpClient( + apiKey: "", + apiSecret: "", + baseUrl: "https://dashboard.fiskaly.com/api/v0/", + email: ProcessInfo.processInfo.environment["EMAIL"]!, + password: ProcessInfo.processInfo.environment["PASSWORD"]! + ) + let response = try client.request( + method: "GET", + path: "/organizations") + XCTAssertEqual(response.status, 200) + } + + func testTransactionRequest() throws { + + // create TSS + + let tssUUID = UUID().uuidString + + let tssBody = [ + "description": "iOS Test TSS", + "state": "INITIALIZED" + ] + let tssBodyData = try? JSONSerialization.data(withJSONObject: tssBody) + let tssBodyEncoded = tssBodyData?.base64EncodedString() + + let responseCreateTSS = try client.request( + method: "PUT", + path: "tss/\(tssUUID)", + body: tssBodyEncoded! + ) + XCTAssertEqual(responseCreateTSS.status, 200) + + // create Client + + let clientUUID = UUID().uuidString + + let clientBody = [ + "serial_number": "iOS Test Client Serial" + ] + let clientBodyData = try? JSONSerialization.data(withJSONObject: clientBody) + let clientBodyEncoded = clientBodyData?.base64EncodedString() + + let responseCreateClient = try client.request( + method: "PUT", + path: "tss/\(tssUUID)/client/\(clientUUID)", + body: clientBodyEncoded!) + XCTAssertEqual(responseCreateClient.status, 200) + + // create Transaction + + let transactionUUID = UUID().uuidString + + let transactionBody = [ + "state": "ACTIVE", + "client_id": clientUUID + ] + let transactionBodyData = try? JSONSerialization.data(withJSONObject: transactionBody) + let transactionBodyEncoded = transactionBodyData?.base64EncodedString() + + let responseCreateTransaction = try client.request( + method: "PUT", + path: "tss/\(tssUUID)/tx/\(transactionUUID)", + body: transactionBodyEncoded!) + XCTAssertEqual(responseCreateTransaction.status, 200) + + // finish Transaction + + let transactionFinishBody: [String: Any] = [ + "state": "FINISHED", + "client_id": clientUUID, + "schema": [ + "standard_v1": [ + "receipt": [ + "receipt_type": "RECEIPT", + "amounts_per_vat_rate": [ + ["vat_rate": "19", "amount": "14.28"] + ], + "amounts_per_payment_type": [ + ["payment_type": "NON_CASH", "amount": "14.28"] + ] + ] + ] + ] + ] + let transactionFinishBodyData = try? JSONSerialization.data(withJSONObject: transactionFinishBody) + let transactionFinishBodyEncoded = transactionFinishBodyData?.base64EncodedString() + + let responseFinishTransaction = try client.request( + method: "PUT", + path: "tss/\(tssUUID)/tx/\(transactionUUID)", + query: ["last_revision": "1"], + body: transactionFinishBodyEncoded!) + XCTAssertEqual(responseFinishTransaction.status, 200) + } + + func testQueryArray() throws { + let query: [String: Any] = [ + "states": ["INITIALIZED", "DISABLED"] + ] + + let response = try client.request( + method: "GET", + path: "/tss", + query: query) + XCTAssertEqual(response.status, 200) + + } + +} diff --git a/FiskalySDKTests/FiskalyAPITestsV2.swift b/FiskalySDKTests/FiskalyAPITestsV2.swift new file mode 100644 index 0000000..48fb1f6 --- /dev/null +++ b/FiskalySDKTests/FiskalyAPITestsV2.swift @@ -0,0 +1,216 @@ +// +// FiskalyAPITestsV2.swift +// FiskalySDKTests +// +// Created by Angela Brett on 07.07.21. +// Copyright © 2021 fiskaly. All rights reserved. +// + +import XCTest +@testable import FiskalySDK + +class FiskalyAPITestsV2: FiskalyAPITests { + + override func setUpWithError() throws { + client = try FiskalyHttpClient( + apiKey: ProcessInfo.processInfo.environment["V2_API_KEY"]!, + apiSecret: ProcessInfo.processInfo.environment["V2_API_SECRET"]!, + baseUrl: "https://sign.fiskaly.dev/api/v2", + smaersUrl: "http://smaers-gateway:8080", + miceUrl: "https://mice.fiskaly.dev" + ) + + setUpLogging(methodName: self.name) + } + + override func tearDown() { + showClientLog() + } + + func disableTSS(_ tssUUID:String) throws { + try setTSSState(tssUUID, state: "DISABLED") + } + + func setTSSState(_ tssUUID:String,state:String) throws { + let disableTSSBody = [ + "state" : state + ] + let _ = try clientRequest(method: "PATCH", + path: "tss/\(tssUUID)", + body: disableTSSBody + ) + } + + //This is actually done by the client so doesn't need to be done here. + func testV2Authentication() throws { + let authenticateBody = [ + "api_key": ProcessInfo.processInfo.environment["V2_API_KEY"]!, + "api_secret": ProcessInfo.processInfo.environment["V2_API_SECRET"], + "base_url":"http://backend:3000", + "smaers_url":"http://smaers-gateway:8080" + ] + + let authBodyData = try? JSONSerialization.data(withJSONObject: authenticateBody) + let authBodyEncoded = authBodyData?.base64EncodedString() + + let responseAuthenticate = try client.request( + method: "POST", + path: "auth", + body: authBodyEncoded!) + XCTAssertEqual(responseAuthenticate.status, 200) + } + + //This is basically an end-to-end test rather than a unit test, but most of these steps won't work without the previous ones + //todo: add some mocking so we can test the individual steps without the server, keys, etc. + func testTransactionRequest() throws { + + //try clientRequest(method: "h", path: "hkh") + + // create TSS + + let tssUUID = UUID().uuidString + + let tssBody = [ + "description": "iOS Test TSS", + "state": "INITIALIZED" + ] + + let responseCreateTSS = try clientRequest( + method: "PUT", + path: "tss/\(tssUUID)", + body: tssBody + ) + + //this is the only chance to get the admin puk, which we will need to change the admin pin later + let responseBodyData = Data(base64Encoded: responseCreateTSS.body) + XCTAssertNotNil(responseBodyData,"Create TSS response body is not valid base64") + let responseBody = try JSONSerialization.jsonObject(with: responseBodyData!, options: []) as? [String: Any] + XCTAssertNotNil(responseBody,"Create TSS response body is not valid JSON") + let adminPUK = responseBody!["admin_puk"] + XCTAssertNotNil(adminPUK,"Create TSS response body did not contain Admin PUK") + + // personalise TSS + + try setTSSState(tssUUID, state: "UNINITIALIZED") + + // change admin pin + let adminPIN = "1234567890" + let changeAdminPinBody = [ + "admin_puk": adminPUK, + "new_admin_pin": adminPIN + ] + let _ = try clientRequest(method: "PATCH", path: "tss/\(tssUUID)/admin", body: changeAdminPinBody) + + //authenticate Admin + let _ = try clientRequest(method: "POST", path: "tss/\(tssUUID)/admin/auth", body: ["admin_pin":adminPIN]) + + //Initialise TSS + try setTSSState(tssUUID, state: "INITIALIZED") + + // create Client + + let clientUUID = UUID().uuidString + + let clientBody = [ + "serial_number": "iOS Test Client Serial" + ] + + let responseCreateClient = try clientRequest( + method: "PUT", + path: "tss/\(tssUUID)/client/\(clientUUID)", + body: clientBody) + XCTAssertEqual(responseCreateClient.status, 200) + + // logout admin + let _ = try clientRequest(method: "POST", path: "tss/\(tssUUID)/admin/logout", body: nil) + + // authenticate client + let _ = try clientRequest(method: "POST", path: "tss/\(tssUUID)/client/\(clientUUID)/auth") + + // create Transaction + + let transactionUUID = UUID().uuidString + + let transactionBody = [ + "state": "ACTIVE", + "client_id": clientUUID + ] + var transactionRevision = 1; + let _ = try clientRequest( + method: "PUT", + path: "tss/\(tssUUID)/tx/\(transactionUUID)", + query: ["tx_revision":transactionRevision], + body: transactionBody) + + // update transaction + transactionRevision += 1 + let updateTransactionBody: [String: Any] = [ + "schema": [ + "standard_v1": [ + "receipt": [ + "receipt_type": "RECEIPT", + "amounts_per_vat_rate": [ + [ + "vat_rate": "NORMAL", + "amount": "21.42" + ] + ], + "amounts_per_payment_type": [ + [ + "payment_type": "NON_CASH", + "amount": "21.42" + ] + ] + ] + ] + ], + "state": "ACTIVE", + "client_id": clientUUID + ] + let _ = try clientRequest( + method: "PUT", + path: "tss/\(tssUUID)/tx/\(transactionUUID)", + query: ["tx_revision": transactionRevision], + body: updateTransactionBody) + + // finish Transaction + transactionRevision += 1 + let transactionFinishBody: [String: Any] = [ + "schema": [ + "standard_v1": [ + "receipt": [ + "receipt_type": "RECEIPT", + "amounts_per_vat_rate": [ + [ + "vat_rate": "NORMAL", + "amount": "21.42" + ] + ], + "amounts_per_payment_type": [ + [ + "payment_type": "NON_CASH", + "amount": "21.42" + ] + ] + ] + ] + ], + "state": "FINISHED", + "client_id": clientUUID + ] + + let _ = try clientRequest( + method: "PUT", + path: "tss/\(tssUUID)/tx/\(transactionUUID)", + query: ["tx_revision": transactionRevision], + body: transactionFinishBody) + + + //authenticate Admin again so we can disable TSS + + let _ = try clientRequest(method: "POST", path: "tss/\(tssUUID)/admin/auth", body: ["admin_pin":adminPIN]) + + //disable TSS (otherwise we will get 'Limit of active TSS reached' errors + try disableTSS(tssUUID) + } +} From 18a58b46ece07c27d81e6219611f96d0b5283373 Mon Sep 17 00:00:00 2001 From: Angela Brett Date: Fri, 9 Jul 2021 09:45:14 +0200 Subject: [PATCH 2/7] Removed space in name of logfile --- FiskalySDKTests/FiskalyAPITests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FiskalySDKTests/FiskalyAPITests.swift b/FiskalySDKTests/FiskalyAPITests.swift index 40671fc..2a5a02a 100644 --- a/FiskalySDKTests/FiskalyAPITests.swift +++ b/FiskalySDKTests/FiskalyAPITests.swift @@ -19,8 +19,8 @@ class FiskalyAPITests: XCTestCase { func setUpLogging(methodName:String) { //set up debug logging within the client library so we can show more detail in the test log - //methodName is the full name of the currently running test - let testName = methodName.replacingOccurrences(of: "-[\(String(describing: Self.self))", with: "").replacingOccurrences(of: "]", with: "") + //methodName is the full name of the currently running test, Objective-C style, e.g. -[FiskalyAPITestsV2 testTransactionRequest], so we trim it down to just e.g. testTransactionRequest + let testName = methodName.replacingOccurrences(of: "-[\(String(describing: Self.self)) ", with: "").replacingOccurrences(of: "]", with: "") logPath = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("fiskaly-tests-\(testName)").appendingPathExtension("log").path From 5393e3e1476f33cf82a7c3fc40becb2d2fe60b69 Mon Sep 17 00:00:00 2001 From: Angela Brett Date: Tue, 27 Jul 2021 19:05:42 +0200 Subject: [PATCH 3/7] Removed smaersUrl from FiskalyHTTPClient initializer, since it is not needed any more and causes a crash in the client library Updated URLs in tests --- FiskalySDK/Classes/FiskalyHttpClient.swift | 7 ++----- FiskalySDKTests/FiskalyAPITestsV2.swift | 7 +++---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/FiskalySDK/Classes/FiskalyHttpClient.swift b/FiskalySDK/Classes/FiskalyHttpClient.swift index 82c07ce..c6c879b 100644 --- a/FiskalySDK/Classes/FiskalyHttpClient.swift +++ b/FiskalySDK/Classes/FiskalyHttpClient.swift @@ -17,7 +17,6 @@ public class FiskalyHttpClient { organizationId: String? = "", environment: String? = "", client: RequestClient = FiskalyRequestClient(), - smaersUrl: String? = nil, miceUrl: String? = nil ) throws { self.client = client @@ -35,11 +34,9 @@ public class FiskalyHttpClient { "sdk_version": "iOS SDK 1.2.100" ] - //these should only be set for v2 - if let smaersUrl = smaersUrl, let miceUrl = miceUrl { - contextRequestParams["smaers_url"] = smaersUrl + //this should only be set for v2 + if let miceUrl = miceUrl { contextRequestParams["mice_url"] = miceUrl - //contextRequestParams["base_url"] = "http://backend:3000" } let request = JsonRpcRequest(method: "create-context", params: contextRequestParams) diff --git a/FiskalySDKTests/FiskalyAPITestsV2.swift b/FiskalySDKTests/FiskalyAPITestsV2.swift index 48fb1f6..08ee3eb 100644 --- a/FiskalySDKTests/FiskalyAPITestsV2.swift +++ b/FiskalySDKTests/FiskalyAPITestsV2.swift @@ -15,9 +15,8 @@ class FiskalyAPITestsV2: FiskalyAPITests { client = try FiskalyHttpClient( apiKey: ProcessInfo.processInfo.environment["V2_API_KEY"]!, apiSecret: ProcessInfo.processInfo.environment["V2_API_SECRET"]!, - baseUrl: "https://sign.fiskaly.dev/api/v2", - smaersUrl: "http://smaers-gateway:8080", - miceUrl: "https://mice.fiskaly.dev" + baseUrl: "https://kassensichv.fiskaly.dev/api/v2", + miceUrl: "https://kassensichv-middleware.fiskaly.dev" ) setUpLogging(methodName: self.name) @@ -46,7 +45,7 @@ class FiskalyAPITestsV2: FiskalyAPITests { let authenticateBody = [ "api_key": ProcessInfo.processInfo.environment["V2_API_KEY"]!, "api_secret": ProcessInfo.processInfo.environment["V2_API_SECRET"], - "base_url":"http://backend:3000", + //"base_url":"http://backend:3000", "smaers_url":"http://smaers-gateway:8080" ] From 98b7fdd98bff027e2ea4a1687d216cd266b60736 Mon Sep 17 00:00:00 2001 From: Angela Brett Date: Wed, 11 Aug 2021 17:21:57 +0200 Subject: [PATCH 4/7] Removed an inaccurate comment from when I was testing with invalid credentials --- FiskalySDKTests/FiskalyAPITestsV1.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FiskalySDKTests/FiskalyAPITestsV1.swift b/FiskalySDKTests/FiskalyAPITestsV1.swift index 7a94975..ceed2a5 100644 --- a/FiskalySDKTests/FiskalyAPITestsV1.swift +++ b/FiskalySDKTests/FiskalyAPITestsV1.swift @@ -23,7 +23,7 @@ class FiskalyAPITestsV1: FiskalyAPITests { path: "/tss") XCTAssertEqual(response.status, 200) } -//this does not seem to work with the new client; it apparently can't create a context with just email and password + func testManagementRequest() throws { let client = try FiskalyHttpClient( apiKey: "", From 60f9b6e1ecc1fdea1e671d77b043c10557ee96a4 Mon Sep 17 00:00:00 2001 From: Angela Brett Date: Wed, 11 Aug 2021 18:33:31 +0200 Subject: [PATCH 5/7] Removed a test that it doesn't make sense to do here --- FiskalySDKTests/FiskalyAPITestsV2.swift | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/FiskalySDKTests/FiskalyAPITestsV2.swift b/FiskalySDKTests/FiskalyAPITestsV2.swift index 08ee3eb..7d4ee51 100644 --- a/FiskalySDKTests/FiskalyAPITestsV2.swift +++ b/FiskalySDKTests/FiskalyAPITestsV2.swift @@ -40,25 +40,6 @@ class FiskalyAPITestsV2: FiskalyAPITests { ) } - //This is actually done by the client so doesn't need to be done here. - func testV2Authentication() throws { - let authenticateBody = [ - "api_key": ProcessInfo.processInfo.environment["V2_API_KEY"]!, - "api_secret": ProcessInfo.processInfo.environment["V2_API_SECRET"], - //"base_url":"http://backend:3000", - "smaers_url":"http://smaers-gateway:8080" - ] - - let authBodyData = try? JSONSerialization.data(withJSONObject: authenticateBody) - let authBodyEncoded = authBodyData?.base64EncodedString() - - let responseAuthenticate = try client.request( - method: "POST", - path: "auth", - body: authBodyEncoded!) - XCTAssertEqual(responseAuthenticate.status, 200) - } - //This is basically an end-to-end test rather than a unit test, but most of these steps won't work without the previous ones //todo: add some mocking so we can test the individual steps without the server, keys, etc. func testTransactionRequest() throws { From 0eee8e4ec283019208f2ec0bfed743619951287b Mon Sep 17 00:00:00 2001 From: Angela Brett Date: Thu, 12 Aug 2021 10:05:47 +0200 Subject: [PATCH 6/7] Fixed URLs in v2 tests, and removed call to authenticate client, since that is not needed or available any more --- FiskalySDKTests/FiskalyAPITestsV2.swift | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/FiskalySDKTests/FiskalyAPITestsV2.swift b/FiskalySDKTests/FiskalyAPITestsV2.swift index 7d4ee51..d362af9 100644 --- a/FiskalySDKTests/FiskalyAPITestsV2.swift +++ b/FiskalySDKTests/FiskalyAPITestsV2.swift @@ -15,8 +15,8 @@ class FiskalyAPITestsV2: FiskalyAPITests { client = try FiskalyHttpClient( apiKey: ProcessInfo.processInfo.environment["V2_API_KEY"]!, apiSecret: ProcessInfo.processInfo.environment["V2_API_SECRET"]!, - baseUrl: "https://kassensichv.fiskaly.dev/api/v2", - miceUrl: "https://kassensichv-middleware.fiskaly.dev" + baseUrl: "https://kassensichv.fiskaly.com/api/v2", + miceUrl: "https://kassensichv-middleware.fiskaly.com" ) setUpLogging(methodName: self.name) @@ -103,9 +103,6 @@ class FiskalyAPITestsV2: FiskalyAPITests { // logout admin let _ = try clientRequest(method: "POST", path: "tss/\(tssUUID)/admin/logout", body: nil) - - // authenticate client - let _ = try clientRequest(method: "POST", path: "tss/\(tssUUID)/client/\(clientUUID)/auth") // create Transaction From bd2439d919b4cf90ee9a15800f63bec597b8fa17 Mon Sep 17 00:00:00 2001 From: Angela Brett Date: Fri, 13 Aug 2021 13:40:09 +0200 Subject: [PATCH 7/7] Made the tests pass when there are no API keys etc. configured, so the test action on GitHub passes --- FiskalySDKTests/FiskalyAPITests.swift | 19 +++++----- FiskalySDKTests/FiskalyAPITestsV1.swift | 46 ++++++++++++++++--------- FiskalySDKTests/FiskalyAPITestsV2.swift | 25 ++++++++------ 3 files changed, 56 insertions(+), 34 deletions(-) diff --git a/FiskalySDKTests/FiskalyAPITests.swift b/FiskalySDKTests/FiskalyAPITests.swift index 2a5a02a..ffcf560 100644 --- a/FiskalySDKTests/FiskalyAPITests.swift +++ b/FiskalySDKTests/FiskalyAPITests.swift @@ -13,8 +13,8 @@ import XCTest //Superclass that sets up the client to have verbose logging and outputs the logging from the client into the console so you have more detail if a test fails. class FiskalyAPITests: XCTestCase { - var client:FiskalyHttpClient! - private var logPath:String! + var client:FiskalyHttpClient? + private var logPath:String? func setUpLogging(methodName:String) { //set up debug logging within the client library so we can show more detail in the test log @@ -22,16 +22,17 @@ class FiskalyAPITests: XCTestCase { //methodName is the full name of the currently running test, Objective-C style, e.g. -[FiskalyAPITestsV2 testTransactionRequest], so we trim it down to just e.g. testTransactionRequest let testName = methodName.replacingOccurrences(of: "-[\(String(describing: Self.self)) ", with: "").replacingOccurrences(of: "]", with: "") - logPath = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("fiskaly-tests-\(testName)").appendingPathExtension("log").path + let path = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("fiskaly-tests-\(testName)").appendingPathExtension("log").path + logPath = path do { //remove the previous log for this test so we can just show the results for this run - if FileManager.default.fileExists(atPath: logPath) { - try FileManager.default.removeItem(atPath: logPath) + if FileManager.default.fileExists(atPath: path) { + try FileManager.default.removeItem(atPath: path) } //set up client logging for this test - let _ = try client.config( + let _ = try client?.config( debugLevel: 3, debugFile: logPath, clientTimeout: 1500, @@ -45,8 +46,10 @@ class FiskalyAPITests: XCTestCase { } func showClientLog() { //now show all the logging from the client during this test - if let logContents = try? String(contentsOfFile: logPath) { - print("Log contents: \(logContents)") + if let logPath = logPath { + if let logContents = try? String(contentsOfFile: logPath) { + print("Log contents: \(logContents)") + } } } diff --git a/FiskalySDKTests/FiskalyAPITestsV1.swift b/FiskalySDKTests/FiskalyAPITestsV1.swift index ceed2a5..74d3c3f 100644 --- a/FiskalySDKTests/FiskalyAPITestsV1.swift +++ b/FiskalySDKTests/FiskalyAPITestsV1.swift @@ -4,13 +4,16 @@ import XCTest class FiskalyAPITestsV1: FiskalyAPITests { override func setUpWithError() throws { + if let apiKey=ProcessInfo.processInfo.environment["API_KEY"], let apiSecret=ProcessInfo.processInfo.environment["API_SECRET"] { client = try FiskalyHttpClient( - apiKey: ProcessInfo.processInfo.environment["API_KEY"]!, - apiSecret: ProcessInfo.processInfo.environment["API_SECRET"]!, + apiKey: apiKey, + apiSecret: apiSecret, baseUrl: "https://kassensichv.io/api/v1/" ) - setUpLogging(methodName: self.name) + } else { + print("FiskalyAPITestsV1 not running because API_KEY and API_SECRET were not set.") + } } override func tearDown() { @@ -18,6 +21,9 @@ class FiskalyAPITestsV1: FiskalyAPITests { } func testKassensichvRequest() throws { + guard let client=client else { + return + } let response = try client.request( method: "GET", path: "/tss") @@ -25,21 +31,27 @@ class FiskalyAPITestsV1: FiskalyAPITests { } func testManagementRequest() throws { - let client = try FiskalyHttpClient( - apiKey: "", - apiSecret: "", - baseUrl: "https://dashboard.fiskaly.com/api/v0/", - email: ProcessInfo.processInfo.environment["EMAIL"]!, - password: ProcessInfo.processInfo.environment["PASSWORD"]! - ) - let response = try client.request( - method: "GET", - path: "/organizations") - XCTAssertEqual(response.status, 200) + if let email=ProcessInfo.processInfo.environment["EMAIL"], let password=ProcessInfo.processInfo.environment["PASSWORD"] { + let client = try FiskalyHttpClient( + apiKey: "", + apiSecret: "", + baseUrl: "https://dashboard.fiskaly.com/api/v0/", + email: email, + password:password + ) + let response = try client.request( + method: "GET", + path: "/organizations") + XCTAssertEqual(response.status, 200) + } else { + print("testManagementRequest not running because EMAIL and PASSWORD were not set.") + } } func testTransactionRequest() throws { - + guard let client=client else { + return + } // create TSS let tssUUID = UUID().uuidString @@ -122,10 +134,12 @@ class FiskalyAPITestsV1: FiskalyAPITests { } func testQueryArray() throws { + guard let client=client else { + return + } let query: [String: Any] = [ "states": ["INITIALIZED", "DISABLED"] ] - let response = try client.request( method: "GET", path: "/tss", diff --git a/FiskalySDKTests/FiskalyAPITestsV2.swift b/FiskalySDKTests/FiskalyAPITestsV2.swift index d362af9..97706cd 100644 --- a/FiskalySDKTests/FiskalyAPITestsV2.swift +++ b/FiskalySDKTests/FiskalyAPITestsV2.swift @@ -12,14 +12,18 @@ import XCTest class FiskalyAPITestsV2: FiskalyAPITests { override func setUpWithError() throws { - client = try FiskalyHttpClient( - apiKey: ProcessInfo.processInfo.environment["V2_API_KEY"]!, - apiSecret: ProcessInfo.processInfo.environment["V2_API_SECRET"]!, - baseUrl: "https://kassensichv.fiskaly.com/api/v2", - miceUrl: "https://kassensichv-middleware.fiskaly.com" - ) - - setUpLogging(methodName: self.name) + if let apiKey=ProcessInfo.processInfo.environment["V2_API_KEY"], let apiSecret=ProcessInfo.processInfo.environment["V2_API_SECRET"] { + client = try FiskalyHttpClient( + apiKey: apiKey, + apiSecret: apiSecret, + baseUrl: "https://kassensichv.fiskaly.com/api/v2", + miceUrl: "https://kassensichv-middleware.fiskaly.com" + ) + + setUpLogging(methodName: self.name) + } else { + print("FiskalyAPITestsV2 not running because V2_API_KEY and V2_API_SECRET were not set.") + } } override func tearDown() { @@ -43,8 +47,9 @@ class FiskalyAPITestsV2: FiskalyAPITests { //This is basically an end-to-end test rather than a unit test, but most of these steps won't work without the previous ones //todo: add some mocking so we can test the individual steps without the server, keys, etc. func testTransactionRequest() throws { - - //try clientRequest(method: "h", path: "hkh") + guard client != nil else { + return + } // create TSS