feat: add Mastodon.API.App.create API
This commit is contained in:
parent
3dc6ec165e
commit
00173e5c30
|
@ -150,6 +150,8 @@
|
|||
DB8AF55625C137A8002E6C99 /* HomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewController.swift; sourceTree = "<group>"; };
|
||||
DB8AF55C25C138B7002E6C99 /* UIViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewController.swift; sourceTree = "<group>"; };
|
||||
DB8AF56725C13E2A002E6C99 /* HomeTimelineIndex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTimelineIndex.swift; sourceTree = "<group>"; };
|
||||
DBF53F5F25C14E88008AAC7B /* Mastodon.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = Mastodon.xctestplan; path = Mastodon/Mastodon.xctestplan; sourceTree = "<group>"; };
|
||||
DBF53F6025C14E9D008AAC7B /* MastodonSDK.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = MastodonSDK.xctestplan; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
|
@ -254,6 +256,8 @@
|
|||
DB427DC925BAA00100D1B89D = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DBF53F5F25C14E88008AAC7B /* Mastodon.xctestplan */,
|
||||
DBF53F6025C14E9D008AAC7B /* MastodonSDK.xctestplan */,
|
||||
DB3D0FED25BAA42200EAA174 /* MastodonSDK */,
|
||||
DB427DD425BAA00100D1B89D /* Mastodon */,
|
||||
DB427DEB25BAA00100D1B89D /* MastodonTests */,
|
||||
|
|
|
@ -7,12 +7,35 @@
|
|||
<key>CoreDataStack.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>8</integer>
|
||||
<integer>6</integer>
|
||||
</dict>
|
||||
<key>Mastodon.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>9</integer>
|
||||
<integer>5</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>DB427DD125BAA00100D1B89D</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>DB427DE725BAA00100D1B89D</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>DB427DF225BAA00100D1B89D</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>DB89B9F525C10FD0008580ED</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -5,15 +5,23 @@
|
|||
// 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<Mastodon.Response.Content<Mastodon.API.App.Application>, Error> {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension Mastodon.API.App {
|
||||
|
@ -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
|
||||
|
|
|
@ -10,10 +10,6 @@ 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()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
//
|
||||
// Mastodon+Response+Content.swift
|
||||
//
|
||||
//
|
||||
// Created by MainasuK Cirno on 2021/1/27.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Mastodon.Response {
|
||||
public struct Content<T> {
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
import XCTest
|
||||
|
||||
import MastodonSDKTests
|
||||
|
||||
var tests = [XCTestCaseEntry]()
|
||||
tests += MastodonSDKTests.allTests()
|
||||
XCTMain(tests)
|
|
@ -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<AnyCancellable>()
|
||||
|
||||
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)
|
||||
|
||||
wait(for: [theExpectation], timeout: 10.0)
|
||||
}
|
||||
|
||||
static var allTests = [
|
||||
("testExample", testExample),
|
||||
]
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
import XCTest
|
||||
|
||||
#if !canImport(ObjectiveC)
|
||||
public func allTests() -> [XCTestCaseEntry] {
|
||||
return [
|
||||
testCase(MastodonSDKTests.allTests),
|
||||
]
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue