From 00173e5c30b62970470d5c8b8a6f88722d7bb0b5 Mon Sep 17 00:00:00 2001 From: CMK Date: Wed, 27 Jan 2021 16:01:20 +0800 Subject: [PATCH] feat: add Mastodon.API.App.create API --- Mastodon.xcodeproj/project.pbxproj | 4 + .../xcschemes/xcschememanagement.plist | 27 ++++++- Mastodon/Generated/Assets.swift | 6 +- Mastodon/Generated/Strings.swift | 8 +- Mastodon/Mastodon.xctestplan | 31 ++++++++ MastodonSDK.xctestplan | 24 ++++++ .../MastodonSDK/API/Mastodon+API+App.swift | 21 ++++- .../MastodonSDK/API/Mastodon+API.swift | 23 ++++-- .../Response/Mastodon+Response+Content.swift | 79 +++++++++++++++++++ MastodonSDK/Tests/LinuxMain.swift | 7 -- .../MastodonSDKTests/MastodonSDKTests.swift | 35 ++++++-- .../MastodonSDKTests/XCTestManifests.swift | 9 --- 12 files changed, 236 insertions(+), 38 deletions(-) create mode 100644 Mastodon/Mastodon.xctestplan create mode 100644 MastodonSDK.xctestplan create mode 100644 MastodonSDK/Sources/MastodonSDK/Response/Mastodon+Response+Content.swift delete mode 100644 MastodonSDK/Tests/LinuxMain.swift delete mode 100644 MastodonSDK/Tests/MastodonSDKTests/XCTestManifests.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 8bb802b6b..4cef307c8 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -150,6 +150,8 @@ DB8AF55625C137A8002E6C99 /* HomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewController.swift; sourceTree = ""; }; DB8AF55C25C138B7002E6C99 /* UIViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewController.swift; sourceTree = ""; }; DB8AF56725C13E2A002E6C99 /* HomeTimelineIndex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTimelineIndex.swift; sourceTree = ""; }; + DBF53F5F25C14E88008AAC7B /* Mastodon.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = Mastodon.xctestplan; path = Mastodon/Mastodon.xctestplan; sourceTree = ""; }; + DBF53F6025C14E9D008AAC7B /* MastodonSDK.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = MastodonSDK.xctestplan; sourceTree = ""; }; EC6E707B68A67DB08EC288FA /* Pods-MastodonTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.debug.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -254,6 +256,8 @@ DB427DC925BAA00100D1B89D = { isa = PBXGroup; children = ( + DBF53F5F25C14E88008AAC7B /* Mastodon.xctestplan */, + DBF53F6025C14E9D008AAC7B /* MastodonSDK.xctestplan */, DB3D0FED25BAA42200EAA174 /* MastodonSDK */, DB427DD425BAA00100D1B89D /* Mastodon */, DB427DEB25BAA00100D1B89D /* MastodonTests */, diff --git a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist index ec856def9..12419edb6 100644 --- a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,12 +7,35 @@ CoreDataStack.xcscheme_^#shared#^_ orderHint - 8 + 6 Mastodon.xcscheme_^#shared#^_ orderHint - 9 + 5 + + + SuppressBuildableAutocreation + + DB427DD125BAA00100D1B89D + + primary + + + DB427DE725BAA00100D1B89D + + primary + + + DB427DF225BAA00100D1B89D + + primary + + + DB89B9F525C10FD0008580ED + + primary + diff --git a/Mastodon/Generated/Assets.swift b/Mastodon/Generated/Assets.swift index 9d169beb4..62a06accc 100644 --- a/Mastodon/Generated/Assets.swift +++ b/Mastodon/Generated/Assets.swift @@ -64,7 +64,11 @@ internal extension ColorAsset.Color { // swiftlint:disable convenience_type private final class BundleToken { static let bundle: Bundle = { - Bundle(for: BundleToken.self) + #if SWIFT_PACKAGE + return Bundle.module + #else + return Bundle(for: BundleToken.self) + #endif }() } // swiftlint:enable convenience_type diff --git a/Mastodon/Generated/Strings.swift b/Mastodon/Generated/Strings.swift index c51bbaea9..e06859b3f 100644 --- a/Mastodon/Generated/Strings.swift +++ b/Mastodon/Generated/Strings.swift @@ -25,6 +25,12 @@ extension L10n { // swiftlint:disable convenience_type private final class BundleToken { - static let bundle = Bundle(for: BundleToken.self) + static let bundle: Bundle = { + #if SWIFT_PACKAGE + return Bundle.module + #else + return Bundle(for: BundleToken.self) + #endif + }() } // swiftlint:enable convenience_type diff --git a/Mastodon/Mastodon.xctestplan b/Mastodon/Mastodon.xctestplan new file mode 100644 index 000000000..b7693b556 --- /dev/null +++ b/Mastodon/Mastodon.xctestplan @@ -0,0 +1,31 @@ +{ + "configurations" : [ + { + "id" : "63D68260-F74D-4CA6-ADBC-B1263DD6BE55", + "name" : "Configuration 1", + "options" : { + + } + } + ], + "defaultOptions" : { + + }, + "testTargets" : [ + { + "target" : { + "containerPath" : "container:Mastodon.xcodeproj", + "identifier" : "DB427DE725BAA00100D1B89D", + "name" : "MastodonTests" + } + }, + { + "target" : { + "containerPath" : "container:Mastodon.xcodeproj", + "identifier" : "DB427DF225BAA00100D1B89D", + "name" : "MastodonUITests" + } + } + ], + "version" : 1 +} diff --git a/MastodonSDK.xctestplan b/MastodonSDK.xctestplan new file mode 100644 index 000000000..14cf031db --- /dev/null +++ b/MastodonSDK.xctestplan @@ -0,0 +1,24 @@ +{ + "configurations" : [ + { + "id" : "5119353D-C795-4264-89FD-8376D9B144F8", + "name" : "Configuration 1", + "options" : { + + } + } + ], + "defaultOptions" : { + + }, + "testTargets" : [ + { + "target" : { + "containerPath" : "container:MastodonSDK", + "identifier" : "MastodonSDKTests", + "name" : "MastodonSDKTests" + } + } + ], + "version" : 1 +} diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+App.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+App.swift index c555f5046..6985bbd5c 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+App.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+App.swift @@ -5,14 +5,22 @@ // Created by xiaojian sun on 2021/1/25. // -import Combine import Foundation +import Combine -public extension Mastodon.API.App { +extension Mastodon.API.App { static func appEndpointURL(domain: String) -> URL { return Mastodon.API.endpointURL(domain: domain).appendingPathComponent("apps") } + + public static func create( + session: URLSession, + query: CreateQuery + ) -> AnyPublisher, Error> { + fatalError() + } + } @@ -41,13 +49,18 @@ extension Mastodon.API.App { } } - struct CreateAnAppQuery { + struct CreateQuery { public let clientName: String public let redirectURIs: String public let scopes: String? public let website: String? - public init(clientName: String, redirectURIs: String, scopes: String?, website: String?) { + public init( + clientName: String, + redirectURIs: String = "urn:ietf:wg:oauth:2.0:oob", + scopes: String? = "read write follow push", + website: String? + ) { self.clientName = clientName self.redirectURIs = redirectURIs self.scopes = scopes diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift index e83f29fb5..b21c44cd0 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API.swift @@ -9,11 +9,7 @@ import Foundation import NIOHTTP1 public extension Mastodon.API { - - static func endpointURL(domain: String) -> URL { - return URL(string: "https://" + domain + "/api/v1/")! - } - + static let timeoutInterval: TimeInterval = 10 static let decoder: JSONDecoder = { let decoder = JSONDecoder() @@ -21,10 +17,25 @@ public extension Mastodon.API { return decoder }() - static let httpHeaderDateFormatter = ISO8601DateFormatter() +} + +extension Mastodon.API { enum Error { } enum App { } +} + +extension Mastodon.API { + + static func endpointURL(domain: String) -> URL { + return URL(string: "https://" + domain + "/api/v1/")! + } + + static func request( + url: URL + ) -> URLRequest { + fatalError() + } } diff --git a/MastodonSDK/Sources/MastodonSDK/Response/Mastodon+Response+Content.swift b/MastodonSDK/Sources/MastodonSDK/Response/Mastodon+Response+Content.swift new file mode 100644 index 000000000..f99614311 --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Response/Mastodon+Response+Content.swift @@ -0,0 +1,79 @@ +// +// Mastodon+Response+Content.swift +// +// +// Created by MainasuK Cirno on 2021/1/27. +// + +import Foundation + +extension Mastodon.Response { + public struct Content { + + // entity + public let value: T + + // standard fields + public let date: Date? + + // application fields + public let rateLimit: RateLimit? + public let responseTime: Int? + + public var networkDate: Date { + return date ?? Date() + } + + public init(value: T, response: URLResponse) { + self.value = value + + self.date = { + guard let string = (response as? HTTPURLResponse)?.value(forHTTPHeaderField: "date") else { return nil } + return Mastodon.API.httpHeaderDateFormatter.date(from: string) + }() + + self.rateLimit = RateLimit(response: response) + self.responseTime = { + guard let string = (response as? HTTPURLResponse)?.value(forHTTPHeaderField: "x-response-time") else { return nil } + return Int(string) + }() + } + + } +} + +extension Mastodon.Response.Content { + public struct RateLimit { + + public let limit: Int + public let remaining: Int + public let reset: Date + + public init(limit: Int, remaining: Int, reset: Date) { + self.limit = limit + self.remaining = remaining + self.reset = reset + } + + public init?(response: URLResponse) { + guard let response = response as? HTTPURLResponse else { + return nil + } + + guard let limitString = response.value(forHTTPHeaderField: "X-RateLimit-Limit"), + let limit = Int(limitString), + let remainingString = response.value(forHTTPHeaderField: "X-RateLimit-Remaining"), + let remaining = Int(remainingString) else { + return nil + } + + guard let resetTimestampString = response.value(forHTTPHeaderField: "X-RateLimit-Reset"), + let reset = Mastodon.API.httpHeaderDateFormatter.date(from: resetTimestampString) else { + return nil + } + + self.init(limit: limit, remaining: remaining, reset: reset) + } + + } +} diff --git a/MastodonSDK/Tests/LinuxMain.swift b/MastodonSDK/Tests/LinuxMain.swift deleted file mode 100644 index 5b06c1211..000000000 --- a/MastodonSDK/Tests/LinuxMain.swift +++ /dev/null @@ -1,7 +0,0 @@ -import XCTest - -import MastodonSDKTests - -var tests = [XCTestCaseEntry]() -tests += MastodonSDKTests.allTests() -XCTMain(tests) diff --git a/MastodonSDK/Tests/MastodonSDKTests/MastodonSDKTests.swift b/MastodonSDK/Tests/MastodonSDKTests/MastodonSDKTests.swift index ff273005c..73ff16ee8 100644 --- a/MastodonSDK/Tests/MastodonSDKTests/MastodonSDKTests.swift +++ b/MastodonSDK/Tests/MastodonSDKTests/MastodonSDKTests.swift @@ -1,14 +1,33 @@ import XCTest +import Combine @testable import MastodonSDK final class MastodonSDKTests: XCTestCase { - func testExample() { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct - // results. - } + + var disposeBag = Set() + + let domain = "mstdn.jp" + let session = URLSession(configuration: .ephemeral) + + func testCreateAnAnpplication() throws { + let theExpectation = expectation(description: "Create An Application") + + let query = Mastodon.API.App.CreateQuery( + clientName: "XCTest", + website: nil + ) + Mastodon.API.App.create(session: session, query: query) + .receive(on: DispatchQueue.main) + .sink { completion in + + } receiveValue: { response in + theExpectation.fulfill() + } + .store(in: &disposeBag) - static var allTests = [ - ("testExample", testExample), - ] + wait(for: [theExpectation], timeout: 10.0) + } + + + } diff --git a/MastodonSDK/Tests/MastodonSDKTests/XCTestManifests.swift b/MastodonSDK/Tests/MastodonSDKTests/XCTestManifests.swift deleted file mode 100644 index 8685c3172..000000000 --- a/MastodonSDK/Tests/MastodonSDKTests/XCTestManifests.swift +++ /dev/null @@ -1,9 +0,0 @@ -import XCTest - -#if !canImport(ObjectiveC) -public func allTests() -> [XCTestCaseEntry] { - return [ - testCase(MastodonSDKTests.allTests), - ] -} -#endif