@openally/github.sdk 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.all-contributorsrc +16 -16
- package/.editorconfig +13 -13
- package/.github/dependabot.yml +25 -25
- package/.github/workflows/codeql.yml +78 -78
- package/.github/workflows/node.js.yml +52 -52
- package/.github/workflows/publish.yml +29 -29
- package/.github/workflows/scorecards.yml +76 -76
- package/LICENSE +21 -21
- package/README.md +5 -4
- package/SECURITY.md +5 -5
- package/docs/api/ApiEndpoint.md +31 -2
- package/docs/api/GithubClient.md +3 -3
- package/docs/api/fetchRawFile.md +106 -0
- package/docs/api/repos.md +4 -4
- package/docs/api/users.md +3 -3
- package/eslint.config.mjs +3 -3
- package/package.json +2 -2
- package/src/api/rawFile.ts +73 -0
- package/src/api/repos.ts +19 -5
- package/src/api/users.ts +9 -5
- package/src/class/ApiEndpoint.ts +20 -17
- package/src/class/GithubClient.ts +38 -7
- package/src/constants.ts +3 -0
- package/src/index.ts +4 -0
- package/src/types.ts +8 -0
- package/test/ApiEndpoint.spec.ts +63 -2
- package/test/GithubClient.spec.ts +28 -9
- package/test/createApiProxy.spec.ts +4 -4
- package/test/rawFile.spec.ts +382 -0
- package/test/tsconfig.json +11 -0
|
@@ -107,9 +107,15 @@ describe("GithubClient", () => {
|
|
|
107
107
|
it("should return ApiEndpoints for repo sub-resources", () => {
|
|
108
108
|
const client = new GithubClient();
|
|
109
109
|
|
|
110
|
-
assert.ok(
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
assert.ok(
|
|
111
|
+
client.repos.owner.myrepo.tags() instanceof ApiEndpoint
|
|
112
|
+
);
|
|
113
|
+
assert.ok(
|
|
114
|
+
client.repos.owner.myrepo.pulls() instanceof ApiEndpoint
|
|
115
|
+
);
|
|
116
|
+
assert.ok(
|
|
117
|
+
client.repos.owner.myrepo.workflows() instanceof ApiEndpoint
|
|
118
|
+
);
|
|
113
119
|
});
|
|
114
120
|
|
|
115
121
|
it("should use the configured token when fetching repo data", async() => {
|
|
@@ -126,7 +132,9 @@ describe("GithubClient", () => {
|
|
|
126
132
|
headers: { "content-type": "application/json" }
|
|
127
133
|
});
|
|
128
134
|
|
|
129
|
-
const result = await client.repos.octocat["hello-world"]
|
|
135
|
+
const result = await client.repos.octocat["hello-world"]
|
|
136
|
+
.tags()
|
|
137
|
+
.all();
|
|
130
138
|
|
|
131
139
|
assert.deepEqual(result, [{ name: "v1.0.0" }]);
|
|
132
140
|
});
|
|
@@ -145,22 +153,33 @@ describe("GithubClient", () => {
|
|
|
145
153
|
headers: { "content-type": "application/json" }
|
|
146
154
|
});
|
|
147
155
|
|
|
148
|
-
await assert.doesNotReject(
|
|
156
|
+
await assert.doesNotReject(
|
|
157
|
+
client.repos.octocat["hello-world"].tags().all()
|
|
158
|
+
);
|
|
149
159
|
});
|
|
150
160
|
|
|
151
161
|
it("should fetch workflows with the envelope extractor", async() => {
|
|
152
162
|
const client = new GithubClient();
|
|
163
|
+
const workflows = [{ id: 7, name: "CI" }];
|
|
153
164
|
|
|
154
165
|
mockAgent
|
|
155
166
|
.get(kGithubOrigin)
|
|
156
|
-
.intercept({
|
|
157
|
-
|
|
167
|
+
.intercept({
|
|
168
|
+
path: "/repos/octocat/hello-world/actions/workflows",
|
|
169
|
+
method: "GET"
|
|
170
|
+
})
|
|
171
|
+
.reply(200, JSON.stringify({ total_count: 1, workflows }), {
|
|
158
172
|
headers: { "content-type": "application/json" }
|
|
159
173
|
});
|
|
160
174
|
|
|
161
|
-
const result = await client.repos.octocat["hello-world"]
|
|
175
|
+
const result = await client.repos.octocat["hello-world"]
|
|
176
|
+
.workflows()
|
|
177
|
+
.all();
|
|
162
178
|
|
|
163
|
-
assert.deepEqual(
|
|
179
|
+
assert.deepEqual(
|
|
180
|
+
result,
|
|
181
|
+
workflows
|
|
182
|
+
);
|
|
164
183
|
});
|
|
165
184
|
});
|
|
166
185
|
});
|
|
@@ -8,7 +8,7 @@ import { createApiProxy } from "../src/class/createApiProxy.ts";
|
|
|
8
8
|
|
|
9
9
|
describe("createApiProxy", () => {
|
|
10
10
|
it("should call the factory with the accessed property key", () => {
|
|
11
|
-
const proxy = createApiProxy((key
|
|
11
|
+
const proxy = createApiProxy((key) => key.toUpperCase());
|
|
12
12
|
|
|
13
13
|
assert.equal(proxy.hello, "HELLO");
|
|
14
14
|
assert.equal(proxy.world, "WORLD");
|
|
@@ -16,7 +16,7 @@ describe("createApiProxy", () => {
|
|
|
16
16
|
|
|
17
17
|
it("should call the factory on each property access", () => {
|
|
18
18
|
let callCount = 0;
|
|
19
|
-
const proxy = createApiProxy((key
|
|
19
|
+
const proxy = createApiProxy((key) => {
|
|
20
20
|
callCount++;
|
|
21
21
|
|
|
22
22
|
return key;
|
|
@@ -30,7 +30,7 @@ describe("createApiProxy", () => {
|
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
it("should return different values for different keys", () => {
|
|
33
|
-
const proxy = createApiProxy((key
|
|
33
|
+
const proxy = createApiProxy((key) => {
|
|
34
34
|
return { name: key };
|
|
35
35
|
});
|
|
36
36
|
|
|
@@ -51,7 +51,7 @@ describe("createApiProxy", () => {
|
|
|
51
51
|
});
|
|
52
52
|
|
|
53
53
|
it("should return a plain object (no prototype)", () => {
|
|
54
|
-
const proxy = createApiProxy((key
|
|
54
|
+
const proxy = createApiProxy((key) => key);
|
|
55
55
|
|
|
56
56
|
assert.equal(Object.getPrototypeOf(proxy), null);
|
|
57
57
|
});
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
// Import Node.js Dependencies
|
|
2
|
+
import { describe, it, beforeEach, afterEach } from "node:test";
|
|
3
|
+
import assert from "node:assert/strict";
|
|
4
|
+
|
|
5
|
+
// Import Third-party Dependencies
|
|
6
|
+
import { MockAgent, setGlobalDispatcher, getGlobalDispatcher, type Dispatcher } from "undici";
|
|
7
|
+
|
|
8
|
+
// Import Internal Dependencies
|
|
9
|
+
import { fetchRawFile } from "../src/api/rawFile.ts";
|
|
10
|
+
import { GithubClient } from "../src/class/GithubClient.ts";
|
|
11
|
+
|
|
12
|
+
// CONSTANTS
|
|
13
|
+
const kRawGithubOrigin = "https://raw.githubusercontent.com";
|
|
14
|
+
|
|
15
|
+
describe("fetchRawFile()", () => {
|
|
16
|
+
let mockAgent: MockAgent;
|
|
17
|
+
let originalDispatcher: Dispatcher;
|
|
18
|
+
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
originalDispatcher = getGlobalDispatcher();
|
|
21
|
+
mockAgent = new MockAgent();
|
|
22
|
+
mockAgent.disableNetConnect();
|
|
23
|
+
setGlobalDispatcher(mockAgent);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
afterEach(async() => {
|
|
27
|
+
await mockAgent.close();
|
|
28
|
+
setGlobalDispatcher(originalDispatcher);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe("raw text (no parser)", () => {
|
|
32
|
+
it("should return the raw file content as a string", async() => {
|
|
33
|
+
mockAgent
|
|
34
|
+
.get(kRawGithubOrigin)
|
|
35
|
+
.intercept({ path: "/octocat/hello-world/HEAD/README.md", method: "GET" })
|
|
36
|
+
.reply(200, "# Hello World\n");
|
|
37
|
+
|
|
38
|
+
const result = await fetchRawFile("octocat/hello-world", "README.md");
|
|
39
|
+
|
|
40
|
+
assert.equal(result, "# Hello World\n");
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("should default to ref HEAD", async() => {
|
|
44
|
+
mockAgent
|
|
45
|
+
.get(kRawGithubOrigin)
|
|
46
|
+
.intercept({ path: "/octocat/hello-world/HEAD/README.md", method: "GET" })
|
|
47
|
+
.reply(200, "content");
|
|
48
|
+
|
|
49
|
+
await assert.doesNotReject(
|
|
50
|
+
fetchRawFile("octocat/hello-world", "README.md")
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("should use the provided ref", async() => {
|
|
55
|
+
mockAgent
|
|
56
|
+
.get(kRawGithubOrigin)
|
|
57
|
+
.intercept({ path: "/octocat/hello-world/main/README.md", method: "GET" })
|
|
58
|
+
.reply(200, "content on main");
|
|
59
|
+
|
|
60
|
+
const result = await fetchRawFile("octocat/hello-world", "README.md", { ref: "main" });
|
|
61
|
+
|
|
62
|
+
assert.equal(result, "content on main");
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("should support file paths with directory segments", async() => {
|
|
66
|
+
mockAgent
|
|
67
|
+
.get(kRawGithubOrigin)
|
|
68
|
+
.intercept({ path: "/octocat/hello-world/HEAD/src/index.ts", method: "GET" })
|
|
69
|
+
.reply(200, "export {};\n");
|
|
70
|
+
|
|
71
|
+
const result = await fetchRawFile("octocat/hello-world", "src/index.ts");
|
|
72
|
+
|
|
73
|
+
assert.equal(result, "export {};\n");
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe("parser: \"json\"", () => {
|
|
78
|
+
it("should parse and return the file content as a JSON object", async() => {
|
|
79
|
+
const pkg = { name: "hello-world", version: "1.0.0" };
|
|
80
|
+
|
|
81
|
+
mockAgent
|
|
82
|
+
.get(kRawGithubOrigin)
|
|
83
|
+
.intercept({ path: "/octocat/hello-world/HEAD/package.json", method: "GET" })
|
|
84
|
+
.reply(200, JSON.stringify(pkg));
|
|
85
|
+
|
|
86
|
+
const result = await fetchRawFile<{ name: string; version: string; }>(
|
|
87
|
+
"octocat/hello-world",
|
|
88
|
+
"package.json",
|
|
89
|
+
{ parser: "json" }
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
assert.deepEqual(result, pkg);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("should return unknown by default when parser is \"json\"", async() => {
|
|
96
|
+
mockAgent
|
|
97
|
+
.get(kRawGithubOrigin)
|
|
98
|
+
.intercept({ path: "/octocat/hello-world/HEAD/data.json", method: "GET" })
|
|
99
|
+
.reply(200, JSON.stringify([1, 2, 3]));
|
|
100
|
+
|
|
101
|
+
const result = await fetchRawFile("octocat/hello-world", "data.json", { parser: "json" });
|
|
102
|
+
|
|
103
|
+
assert.deepEqual(result, [1, 2, 3]);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
describe("custom parser function", () => {
|
|
108
|
+
it("should apply a custom parser to the raw content", async() => {
|
|
109
|
+
mockAgent
|
|
110
|
+
.get(kRawGithubOrigin)
|
|
111
|
+
.intercept({ path: "/octocat/hello-world/HEAD/VERSION", method: "GET" })
|
|
112
|
+
.reply(200, "2.3.1\n");
|
|
113
|
+
|
|
114
|
+
const result = await fetchRawFile(
|
|
115
|
+
"octocat/hello-world",
|
|
116
|
+
"VERSION",
|
|
117
|
+
{ parser: (content) => content.trim() }
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
assert.equal(result, "2.3.1");
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it("should pass the raw string content to the parser", async() => {
|
|
124
|
+
const rawContent = "key=value\nfoo=bar\n";
|
|
125
|
+
const captured: string[] = [];
|
|
126
|
+
|
|
127
|
+
mockAgent
|
|
128
|
+
.get(kRawGithubOrigin)
|
|
129
|
+
.intercept({ path: "/octocat/hello-world/HEAD/.env", method: "GET" })
|
|
130
|
+
.reply(200, rawContent);
|
|
131
|
+
|
|
132
|
+
await fetchRawFile(
|
|
133
|
+
"octocat/hello-world",
|
|
134
|
+
".env",
|
|
135
|
+
{
|
|
136
|
+
parser: (content) => {
|
|
137
|
+
captured.push(content);
|
|
138
|
+
|
|
139
|
+
return content;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
assert.equal(captured[0], rawContent);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
describe("headers", () => {
|
|
149
|
+
it("should send the default User-Agent header", async() => {
|
|
150
|
+
mockAgent
|
|
151
|
+
.get(kRawGithubOrigin)
|
|
152
|
+
.intercept({
|
|
153
|
+
path: "/octocat/hello-world/HEAD/README.md",
|
|
154
|
+
method: "GET",
|
|
155
|
+
headers: { "user-agent": "@openally/github.sdk/1.0.0" }
|
|
156
|
+
})
|
|
157
|
+
.reply(200, "content");
|
|
158
|
+
|
|
159
|
+
await assert.doesNotReject(
|
|
160
|
+
fetchRawFile("octocat/hello-world", "README.md")
|
|
161
|
+
);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it("should send a custom User-Agent when provided", async() => {
|
|
165
|
+
mockAgent
|
|
166
|
+
.get(kRawGithubOrigin)
|
|
167
|
+
.intercept({
|
|
168
|
+
path: "/octocat/hello-world/HEAD/README.md",
|
|
169
|
+
method: "GET",
|
|
170
|
+
headers: { "user-agent": "my-app/2.0" }
|
|
171
|
+
})
|
|
172
|
+
.reply(200, "content");
|
|
173
|
+
|
|
174
|
+
await assert.doesNotReject(
|
|
175
|
+
fetchRawFile("octocat/hello-world", "README.md", { userAgent: "my-app/2.0" })
|
|
176
|
+
);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it("should send the Authorization header when a token is provided", async() => {
|
|
180
|
+
mockAgent
|
|
181
|
+
.get(kRawGithubOrigin)
|
|
182
|
+
.intercept({
|
|
183
|
+
path: "/octocat/hello-world/HEAD/README.md",
|
|
184
|
+
method: "GET",
|
|
185
|
+
headers: { authorization: "token secret123" }
|
|
186
|
+
})
|
|
187
|
+
.reply(200, "content");
|
|
188
|
+
|
|
189
|
+
await assert.doesNotReject(
|
|
190
|
+
fetchRawFile("octocat/hello-world", "README.md", { token: "secret123" })
|
|
191
|
+
);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it("should succeed without an Authorization header when no token is provided", async() => {
|
|
195
|
+
// undici's MockAgent will reject the request if the intercepted headers
|
|
196
|
+
// do not match — here we assert no `authorization` key is present by
|
|
197
|
+
// confirming the request succeeds against an interceptor that has no
|
|
198
|
+
// header constraint at all (the positive case with a token is separately tested).
|
|
199
|
+
mockAgent
|
|
200
|
+
.get(kRawGithubOrigin)
|
|
201
|
+
.intercept({ path: "/octocat/hello-world/HEAD/README.md", method: "GET" })
|
|
202
|
+
.reply(200, "content");
|
|
203
|
+
|
|
204
|
+
await assert.doesNotReject(
|
|
205
|
+
fetchRawFile("octocat/hello-world", "README.md")
|
|
206
|
+
);
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
describe("error handling", () => {
|
|
211
|
+
it("should throw on a 404 response", async() => {
|
|
212
|
+
mockAgent
|
|
213
|
+
.get(kRawGithubOrigin)
|
|
214
|
+
.intercept({ path: "/octocat/hello-world/HEAD/missing.txt", method: "GET" })
|
|
215
|
+
.reply(404, "Not Found");
|
|
216
|
+
|
|
217
|
+
await assert.rejects(
|
|
218
|
+
fetchRawFile("octocat/hello-world", "missing.txt"),
|
|
219
|
+
(err: Error) => {
|
|
220
|
+
assert.ok(err.message.includes("404"));
|
|
221
|
+
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it("should throw on a 500 response", async() => {
|
|
228
|
+
mockAgent
|
|
229
|
+
.get(kRawGithubOrigin)
|
|
230
|
+
.intercept({ path: "/octocat/hello-world/HEAD/README.md", method: "GET" })
|
|
231
|
+
.reply(500, "Internal Server Error");
|
|
232
|
+
|
|
233
|
+
await assert.rejects(
|
|
234
|
+
fetchRawFile("octocat/hello-world", "README.md"),
|
|
235
|
+
(err: Error) => {
|
|
236
|
+
assert.ok(err.message.includes("500"));
|
|
237
|
+
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it("should include the repository, ref, and file path in the error message", async() => {
|
|
244
|
+
mockAgent
|
|
245
|
+
.get(kRawGithubOrigin)
|
|
246
|
+
.intercept({ path: "/octocat/hello-world/HEAD/missing.txt", method: "GET" })
|
|
247
|
+
.reply(404, "Not Found");
|
|
248
|
+
|
|
249
|
+
await assert.rejects(
|
|
250
|
+
fetchRawFile("octocat/hello-world", "missing.txt"),
|
|
251
|
+
(err: Error) => {
|
|
252
|
+
assert.ok(err.message.includes("missing.txt"));
|
|
253
|
+
assert.ok(err.message.includes("octocat/hello-world"));
|
|
254
|
+
assert.ok(err.message.includes("HEAD"));
|
|
255
|
+
|
|
256
|
+
return true;
|
|
257
|
+
}
|
|
258
|
+
);
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
describe("GithubClient.fetchRawFile()", () => {
|
|
264
|
+
let mockAgent: MockAgent;
|
|
265
|
+
let originalDispatcher: Dispatcher;
|
|
266
|
+
|
|
267
|
+
beforeEach(() => {
|
|
268
|
+
originalDispatcher = getGlobalDispatcher();
|
|
269
|
+
mockAgent = new MockAgent();
|
|
270
|
+
mockAgent.disableNetConnect();
|
|
271
|
+
setGlobalDispatcher(mockAgent);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
afterEach(async() => {
|
|
275
|
+
await mockAgent.close();
|
|
276
|
+
setGlobalDispatcher(originalDispatcher);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
it("should fetch raw content using the client's token", async() => {
|
|
280
|
+
const client = new GithubClient({ token: "clienttoken" });
|
|
281
|
+
|
|
282
|
+
mockAgent
|
|
283
|
+
.get(kRawGithubOrigin)
|
|
284
|
+
.intercept({
|
|
285
|
+
path: "/octocat/hello-world/HEAD/README.md",
|
|
286
|
+
method: "GET",
|
|
287
|
+
headers: { authorization: "token clienttoken" }
|
|
288
|
+
})
|
|
289
|
+
.reply(200, "# Hello");
|
|
290
|
+
|
|
291
|
+
await assert.doesNotReject(
|
|
292
|
+
client.fetchRawFile("octocat/hello-world", "README.md")
|
|
293
|
+
);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it("should fetch raw content using the client's userAgent", async() => {
|
|
297
|
+
const client = new GithubClient({ userAgent: "my-client/1.0" });
|
|
298
|
+
|
|
299
|
+
mockAgent
|
|
300
|
+
.get(kRawGithubOrigin)
|
|
301
|
+
.intercept({
|
|
302
|
+
path: "/octocat/hello-world/HEAD/README.md",
|
|
303
|
+
method: "GET",
|
|
304
|
+
headers: { "user-agent": "my-client/1.0" }
|
|
305
|
+
})
|
|
306
|
+
.reply(200, "# Hello");
|
|
307
|
+
|
|
308
|
+
await assert.doesNotReject(
|
|
309
|
+
client.fetchRawFile("octocat/hello-world", "README.md")
|
|
310
|
+
);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it("should parse JSON when parser is \"json\"", async() => {
|
|
314
|
+
const client = new GithubClient();
|
|
315
|
+
const pkg = { name: "hello-world", version: "1.0.0" };
|
|
316
|
+
|
|
317
|
+
mockAgent
|
|
318
|
+
.get(kRawGithubOrigin)
|
|
319
|
+
.intercept({ path: "/octocat/hello-world/HEAD/package.json", method: "GET" })
|
|
320
|
+
.reply(200, JSON.stringify(pkg));
|
|
321
|
+
|
|
322
|
+
const result = await client.fetchRawFile<{ name: string; version: string; }>(
|
|
323
|
+
"octocat/hello-world",
|
|
324
|
+
"package.json",
|
|
325
|
+
{ parser: "json" }
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
assert.deepEqual(result, pkg);
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
it("should apply a custom parser function", async() => {
|
|
332
|
+
const client = new GithubClient();
|
|
333
|
+
|
|
334
|
+
mockAgent
|
|
335
|
+
.get(kRawGithubOrigin)
|
|
336
|
+
.intercept({ path: "/octocat/hello-world/main/VERSION", method: "GET" })
|
|
337
|
+
.reply(200, "3.0.0\n");
|
|
338
|
+
|
|
339
|
+
const result = await client.fetchRawFile(
|
|
340
|
+
"octocat/hello-world",
|
|
341
|
+
"VERSION",
|
|
342
|
+
{ ref: "main", parser: (s) => s.trim() }
|
|
343
|
+
);
|
|
344
|
+
|
|
345
|
+
assert.equal(result, "3.0.0");
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
it("should use the ref option when provided", async() => {
|
|
349
|
+
const client = new GithubClient();
|
|
350
|
+
|
|
351
|
+
mockAgent
|
|
352
|
+
.get(kRawGithubOrigin)
|
|
353
|
+
.intercept({ path: "/octocat/hello-world/v2.0.0/CHANGELOG.md", method: "GET" })
|
|
354
|
+
.reply(200, "## v2.0.0\n");
|
|
355
|
+
|
|
356
|
+
const result = await client.fetchRawFile(
|
|
357
|
+
"octocat/hello-world",
|
|
358
|
+
"CHANGELOG.md",
|
|
359
|
+
{ ref: "v2.0.0" }
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
assert.equal(result, "## v2.0.0\n");
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
it("should throw when the file is not found", async() => {
|
|
366
|
+
const client = new GithubClient();
|
|
367
|
+
|
|
368
|
+
mockAgent
|
|
369
|
+
.get(kRawGithubOrigin)
|
|
370
|
+
.intercept({ path: "/octocat/hello-world/HEAD/missing.txt", method: "GET" })
|
|
371
|
+
.reply(404, "Not Found");
|
|
372
|
+
|
|
373
|
+
await assert.rejects(
|
|
374
|
+
client.fetchRawFile("octocat/hello-world", "missing.txt"),
|
|
375
|
+
(err: Error) => {
|
|
376
|
+
assert.ok(err.message.includes("404"));
|
|
377
|
+
|
|
378
|
+
return true;
|
|
379
|
+
}
|
|
380
|
+
);
|
|
381
|
+
});
|
|
382
|
+
});
|