Skip to content

Commit 02b9c68

Browse files
committed
Adds tests for AccessTokenRefreshingGitHubClient
1 parent 087b763 commit 02b9c68

File tree

1 file changed

+248
-0
lines changed

1 file changed

+248
-0
lines changed
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
import AccessTokenRefreshingGitHubClient from "../../../src/common/github/AccessTokenRefreshingGitHubClient"
2+
import {
3+
GraphQLQueryRequest,
4+
GetRepositoryContentRequest,
5+
GetPullRequestCommentsRequest,
6+
AddCommentToPullRequestRequest
7+
} from "../../../src/common/github/IGitHubClient"
8+
9+
test("It forwards a GraphQL request", async () => {
10+
let forwardedRequest: GraphQLQueryRequest | undefined
11+
const sut = new AccessTokenRefreshingGitHubClient({
12+
async getOAuthToken() {
13+
return { accessToken: "foo", refreshToken: "bar" }
14+
},
15+
async storeOAuthToken() {}
16+
}, {
17+
async refreshOAuthToken() {
18+
return { accessToken: "foo", refreshToken: "bar" }
19+
}
20+
}, {
21+
async graphql(request: GraphQLQueryRequest) {
22+
forwardedRequest = request
23+
return {}
24+
},
25+
async getRepositoryContent() {
26+
return { downloadURL: "https://example.com" }
27+
},
28+
async getPullRequestComments() {
29+
return []
30+
},
31+
async addCommentToPullRequest() {}
32+
})
33+
const request: GraphQLQueryRequest = {
34+
query: "foo",
35+
variables: { hello: "world" }
36+
}
37+
await sut.graphql(request)
38+
expect(forwardedRequest).toEqual(request)
39+
})
40+
41+
test("It forwards a request to get the repository content", async () => {
42+
let forwardedRequest: GetRepositoryContentRequest | undefined
43+
const sut = new AccessTokenRefreshingGitHubClient({
44+
async getOAuthToken() {
45+
return { accessToken: "foo", refreshToken: "bar" }
46+
},
47+
async storeOAuthToken() {}
48+
}, {
49+
async refreshOAuthToken() {
50+
return { accessToken: "foo", refreshToken: "bar" }
51+
}
52+
}, {
53+
async graphql() {
54+
return {}
55+
},
56+
async getRepositoryContent(request: GetRepositoryContentRequest) {
57+
forwardedRequest = request
58+
return { downloadURL: "https://example.com" }
59+
},
60+
async getPullRequestComments() {
61+
return []
62+
},
63+
async addCommentToPullRequest() {}
64+
})
65+
const request: GetRepositoryContentRequest = {
66+
repositoryOwner: "foo",
67+
repositoryName: "bar",
68+
path: "hello",
69+
ref: "world"
70+
}
71+
await sut.getRepositoryContent(request)
72+
expect(forwardedRequest).toEqual(request)
73+
})
74+
75+
test("It forwards a request to get comments to a pull request", async () => {
76+
let forwardedRequest: GetPullRequestCommentsRequest | undefined
77+
const sut = new AccessTokenRefreshingGitHubClient({
78+
async getOAuthToken() {
79+
return { accessToken: "foo", refreshToken: "bar" }
80+
},
81+
async storeOAuthToken() {}
82+
}, {
83+
async refreshOAuthToken() {
84+
return { accessToken: "foo", refreshToken: "bar" }
85+
}
86+
}, {
87+
async graphql() {
88+
return {}
89+
},
90+
async getRepositoryContent() {
91+
return { downloadURL: "https://example.com" }
92+
},
93+
async getPullRequestComments(request: GetPullRequestCommentsRequest) {
94+
forwardedRequest = request
95+
return []
96+
},
97+
async addCommentToPullRequest() {}
98+
})
99+
const request: GetPullRequestCommentsRequest = {
100+
appInstallationId: 1234,
101+
repositoryOwner: "foo",
102+
repositoryName: "bar",
103+
pullRequestNumber: 42
104+
}
105+
await sut.getPullRequestComments(request)
106+
expect(forwardedRequest).toEqual(request)
107+
})
108+
109+
test("It forwards a request to add a comment to a pull request", async () => {
110+
let forwardedRequest: AddCommentToPullRequestRequest | undefined
111+
const sut = new AccessTokenRefreshingGitHubClient({
112+
async getOAuthToken() {
113+
return { accessToken: "foo", refreshToken: "bar" }
114+
},
115+
async storeOAuthToken() {}
116+
}, {
117+
async refreshOAuthToken() {
118+
return { accessToken: "foo", refreshToken: "bar" }
119+
}
120+
}, {
121+
async graphql() {
122+
return {}
123+
},
124+
async getRepositoryContent() {
125+
return { downloadURL: "https://example.com" }
126+
},
127+
async getPullRequestComments() {
128+
return []
129+
},
130+
async addCommentToPullRequest(request: AddCommentToPullRequestRequest) {
131+
forwardedRequest = request
132+
}
133+
})
134+
const request: AddCommentToPullRequestRequest = {
135+
appInstallationId: 1234,
136+
repositoryOwner: "foo",
137+
repositoryName: "bar",
138+
pullRequestNumber: 42,
139+
body: "Hello world!"
140+
}
141+
await sut.addCommentToPullRequest(request)
142+
expect(forwardedRequest).toEqual(request)
143+
})
144+
145+
test("It retries with a refreshed access token when receiving HTTP 401", async () => {
146+
let didRefreshAccesstoken = false
147+
let didRespondWithAuthorizationError = false
148+
const sut = new AccessTokenRefreshingGitHubClient({
149+
async getOAuthToken() {
150+
return { accessToken: "foo", refreshToken: "bar" }
151+
},
152+
async storeOAuthToken() {}
153+
}, {
154+
async refreshOAuthToken() {
155+
didRefreshAccesstoken = true
156+
return { accessToken: "foo", refreshToken: "bar" }
157+
}
158+
}, {
159+
async graphql() {
160+
if (!didRespondWithAuthorizationError) {
161+
didRespondWithAuthorizationError = true
162+
throw { status: 401 }
163+
}
164+
return []
165+
},
166+
async getRepositoryContent() {
167+
return { downloadURL: "https://example.com" }
168+
},
169+
async getPullRequestComments() {
170+
return []
171+
},
172+
async addCommentToPullRequest() {}
173+
})
174+
const request: GraphQLQueryRequest = {
175+
query: "foo",
176+
variables: { hello: "world" }
177+
}
178+
await sut.graphql(request)
179+
expect(didRefreshAccesstoken).toBeTruthy()
180+
})
181+
182+
test("It only retries a request once when receiving HTTP 401", async () => {
183+
let requestCount = 0
184+
const sut = new AccessTokenRefreshingGitHubClient({
185+
async getOAuthToken() {
186+
return { accessToken: "foo", refreshToken: "bar" }
187+
},
188+
async storeOAuthToken() {}
189+
}, {
190+
async refreshOAuthToken() {
191+
return { accessToken: "foo", refreshToken: "bar" }
192+
}
193+
}, {
194+
async graphql() {
195+
requestCount += 1
196+
throw { status: 401 }
197+
},
198+
async getRepositoryContent() {
199+
return { downloadURL: "https://example.com" }
200+
},
201+
async getPullRequestComments() {
202+
return []
203+
},
204+
async addCommentToPullRequest() {}
205+
})
206+
const request: GraphQLQueryRequest = {
207+
query: "foo",
208+
variables: { hello: "world" }
209+
}
210+
// When receiving the second HTTP 401 the call should fail.
211+
await expect(sut.graphql(request)).rejects.toEqual({ status: 401 })
212+
// We expect two requests:
213+
// 1. The initial request that failed after which we refreshed the access token.
214+
// 2. The second request that failed after which we gave up.
215+
expect(requestCount).toEqual(2)
216+
})
217+
218+
test("It does not refresh an access token when the initial request was successful", async () => {
219+
let didRefreshAccesstoken = false
220+
const sut = new AccessTokenRefreshingGitHubClient({
221+
async getOAuthToken() {
222+
return { accessToken: "foo", refreshToken: "bar" }
223+
},
224+
async storeOAuthToken() {}
225+
}, {
226+
async refreshOAuthToken() {
227+
didRefreshAccesstoken = true
228+
return { accessToken: "foo", refreshToken: "bar" }
229+
}
230+
}, {
231+
async graphql() {
232+
return []
233+
},
234+
async getRepositoryContent() {
235+
return { downloadURL: "https://example.com" }
236+
},
237+
async getPullRequestComments() {
238+
return []
239+
},
240+
async addCommentToPullRequest() {}
241+
})
242+
const request: GraphQLQueryRequest = {
243+
query: "foo",
244+
variables: { hello: "world" }
245+
}
246+
await sut.graphql(request)
247+
expect(didRefreshAccesstoken).toBeFalsy()
248+
})

0 commit comments

Comments
 (0)