-
Notifications
You must be signed in to change notification settings - Fork 48
Expand file tree
/
Copy pathGitHubAPITests.swift
More file actions
162 lines (127 loc) · 5.83 KB
/
GitHubAPITests.swift
File metadata and controls
162 lines (127 loc) · 5.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//
// GitHubAPITests.swift
//
import XCTest
import OpenAPIKit30
import Yams
#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif
final class GitHubAPICampatibilityTests: XCTestCase {
var githubAPI: Result<OpenAPI.Document, Error>? = nil
var apiDoc: OpenAPI.Document? {
guard case .success(let document) = githubAPI else { return nil }
return document
}
override func setUp() {
/*
NOTE: As of 2/17/2021 the latest released version of GitHub's API documentation
does not pass but the latest commit does; I will pin this test to that
commit for now.
*/
if githubAPI == nil {
// Test file can be redownloaded from
// https://raw.githubusercontent.com/github/rest-api-description/e4f28959fbc6c9fc4eea823b495061dded87e84d/descriptions/ghes-3.0/ghes-3.0.yaml
githubAPI = Result {
let currentWorkingDirectory = FileManager.default.currentDirectoryPath
return try YAMLDecoder().decode(
OpenAPI.Document.self,
from: String(
contentsOf: URL(
filePath: "./Tests/inputs/ghes-3.0.yaml",
relativeTo: URL(filePath: currentWorkingDirectory, directoryHint: .isDirectory)),
encoding: .utf8)
)
}
}
}
func test_successfullyParsedDocument() throws {
switch githubAPI {
case nil:
XCTFail("Did not attempt to pull GitHub API documentation like expected.")
case .failure(let error):
let prettyError = OpenAPI.Error(from: error)
XCTFail(prettyError.localizedDescription + "\n coding path: " + prettyError.codingPathString)
case .success:
break
}
}
func test_passesValidation() throws {
guard let apiDoc = apiDoc else { return }
let warnings = try apiDoc.validate(strict: false)
XCTAssertEqual(warnings.count, 4)
}
func test_successfullyParsedBasicMetadata() throws {
guard let apiDoc = apiDoc else { return }
// title is GitHub v3 REST API
XCTAssertEqual(apiDoc.info.title, "GitHub v3 REST API")
// description is set
XCTAssertFalse(apiDoc.info.description?.isEmpty ?? true)
// contact name is Support
XCTAssertEqual(apiDoc.info.contact?.name, "Support")
// contact URL was parsed as https://support.github.com/contact
XCTAssertEqual(apiDoc.info.contact?.url, URL(string: "https://support.github.com/contact")!)
// no contact email is provided
XCTAssert(apiDoc.info.contact?.email?.isEmpty ?? true)
// there is at least one tag defined
XCTAssertFalse(apiDoc.tags?.isEmpty ?? true)
// server is specified
XCTAssertNotNil(apiDoc.servers.first)
}
func test_successfullyParsedRoutes() throws {
guard let apiDoc = apiDoc else { return }
// just check for a few of the known paths
XCTAssert(apiDoc.paths.contains(key: "/"))
XCTAssert(apiDoc.paths.contains(key: "/app"))
XCTAssert(apiDoc.paths.contains(key: "/app-manifests/{code}/conversions"))
XCTAssert(apiDoc.paths.contains(key: "/app/installations"))
XCTAssert(apiDoc.paths.contains(key: "/app/installations/{installation_id}"))
XCTAssert(apiDoc.paths.contains(key: "/app/installations/{installation_id}/access_tokens"))
// check for a known POST response
XCTAssertNotNil(apiDoc.paths["/app/installations/{installation_id}/access_tokens"]?.pathItemValue?.post?.responses[status: 201])
// and a known GET response
XCTAssertNotNil(apiDoc.paths["/app/installations/{installation_id}"]?.pathItemValue?.get?.responses[status: 200])
// check for parameters
XCTAssertFalse(apiDoc.paths["/app/installations/{installation_id}"]?.pathItemValue?.get?.parameters.isEmpty ?? true)
}
func test_successfullyParsedComponents() throws {
guard let apiDoc = apiDoc else { return }
// check for a known parameter
XCTAssertNotNil(apiDoc.components.parameters["per_page"])
XCTAssertTrue(apiDoc.components.parameters["per_page"]?.context.inQuery ?? false)
// check for known schema
XCTAssertNotNil(apiDoc.components.schemas["simple-user"])
// check for header
XCTAssertNotNil(apiDoc.components.headers["link"])
}
func test_someReferences() throws {
guard let apiDoc = apiDoc else { return }
let installationsPath = apiDoc.paths["/app/installations/{installation_id}"]
let installationsParameters = try installationsPath?.pathItemValue?.get?.parameters.compactMap(apiDoc.components.lookup)
XCTAssertNotNil(installationsParameters)
XCTAssertEqual(installationsParameters?.count, 1)
XCTAssertEqual(installationsParameters?.first?.description, "installation_id parameter")
XCTAssertEqual(installationsParameters?.first?.context, .path)
}
func test_dereferencedComponents() throws {
guard let apiDoc = apiDoc else { return }
let dereferencedDoc = try apiDoc.locallyDereferenced()
// params are all $refs to Components Object
XCTAssertTrue(
dereferencedDoc.paths["/app/installations/{installation_id}"]?.get?.parameters
.contains { param in param.description == "installation_id parameter" }
?? false
)
}
func test_resolveDocument() throws {
guard let apiDoc = apiDoc else { return }
let resolvedDoc = try apiDoc.locallyDereferenced().resolved()
XCTAssertEqual(resolvedDoc.routes.count, apiDoc.paths.count)
XCTAssertEqual(resolvedDoc.endpoints.count, 664)
}
}