feat: add servers & categories API

This commit is contained in:
CMK 2021-02-18 19:36:49 +08:00
parent aa6d59fd98
commit 587d16a829
5 changed files with 183 additions and 0 deletions

View File

@ -0,0 +1,71 @@
//
// Mastodon+API+Server.swift
//
//
// Created by MainasuK Cirno on 2021-2-18.
//
import Foundation
import Combine
extension Mastodon.API.Server {
static let serversEndpointURL = Mastodon.API.joinMastodonEndpointURL.appendingPathComponent("servers")
static let categoriesEndpointURL = Mastodon.API.joinMastodonEndpointURL.appendingPathComponent("categories")
public static func servers(
session: URLSession,
query: ServersQuery
) -> AnyPublisher<Mastodon.Response.Content<[Mastodon.Entity.Server]>, Error> {
let request = Mastodon.API.get(
url: serversEndpointURL,
query: query,
authorization: nil
)
return session.dataTaskPublisher(for: request)
.tryMap { data, response in
let value = try Mastodon.API.decode(type: [Mastodon.Entity.Server].self, from: data, response: response)
return Mastodon.Response.Content(value: value, response: response)
}
.eraseToAnyPublisher()
}
public static func categories(
session: URLSession
) -> AnyPublisher<Mastodon.Response.Content<[Mastodon.Entity.Category]>, Error> {
let request = Mastodon.API.get(
url: categoriesEndpointURL,
query: nil,
authorization: nil
)
return session.dataTaskPublisher(for: request)
.tryMap { data, response in
let value = try Mastodon.API.decode(type: [Mastodon.Entity.Category].self, from: data, response: response)
return Mastodon.Response.Content(value: value, response: response)
}
.eraseToAnyPublisher()
}
}
extension Mastodon.API.Server {
public struct ServersQuery: Codable, GetQuery {
public let language: String?
public let category: String?
public init(language: String?, category: String?) {
self.language = language
self.category = category
}
var queryItems: [URLQueryItem]? {
var items: [URLQueryItem] = []
language.flatMap { items.append(URLQueryItem(name: "language", value: $0)) }
category.flatMap { items.append(URLQueryItem(name: "category", value: $0)) }
guard !items.isEmpty else { return nil }
return items
}
}
}

View File

@ -79,6 +79,8 @@ extension Mastodon.API {
return URL(string: "https://" + domain + "/api/v2/")!
}
static let joinMastodonEndpointURL = URL(string: "https://api.joinmastodon.org/")!
}
extension Mastodon.API {
@ -87,6 +89,7 @@ extension Mastodon.API {
public enum Instance { }
public enum OAuth { }
public enum Timeline { }
public enum Server { }
public enum Favorites { }
}

View File

@ -0,0 +1,22 @@
//
// Mastodon+Entity+Category.swift
//
//
// Created by MainasuK Cirno on 2021-2-18.
//
import Foundation
extension Mastodon.Entity {
public struct Category: Codable {
public let category: String
public let serversCount: Int
enum CodingKeys: String, CodingKey {
case category
case serversCount = "servers_count"
}
}
}

View File

@ -0,0 +1,42 @@
//
// Mastodon+Entity+Server.swift
//
//
// Created by MainasuK Cirno on 2021-2-18.
//
import Foundation
extension Mastodon.Entity {
public struct Server: Codable {
public let domain: String
public let version: String
public let description: String
public let languages: [String]
public let region: String
public let categories: [String]
public let proxiedThumbnail: String
public let totalUsers: Int
public let lastWeekUsers: Int
public let approvalRequired: Bool
public let language: String
public let category: String
enum CodingKeys: String, CodingKey {
case domain
case version
case description
case languages
case region
case categories
case proxiedThumbnail = "proxied_thumbnail"
case totalUsers = "total_users"
case lastWeekUsers = "last_week_users"
case approvalRequired = "approval_required"
case language
case category
}
}
}

View File

@ -0,0 +1,45 @@
//
// MastodonSDK+API+ServerTests.swift
//
//
// Created by MainasuK Cirno on 2021-2-18.
//
import os.log
import XCTest
import Combine
@testable import MastodonSDK
extension MastodonSDKTests {
func testServers() throws {
try _testServers(query: Mastodon.API.Server.ServersQuery(language: nil, category: nil))
try _testServers(query: Mastodon.API.Server.ServersQuery(language: "en", category: "tech"))
}
func _testServers(query: Mastodon.API.Server.ServersQuery) throws {
let theExpectation = expectation(description: "Fetch Server List")
Mastodon.API.Server.servers(
session: session,
query: query
)
.receive(on: DispatchQueue.main)
.sink { completion in
switch completion {
case .failure(let error):
XCTFail(error.localizedDescription)
case .finished:
break
}
} receiveValue: { response in
XCTAssert(!response.value.isEmpty)
theExpectation.fulfill()
}
.store(in: &disposeBag)
wait(for: [theExpectation], timeout: 10.0)
}
}