/
api-client.test.ts
183 lines (151 loc) · 6.17 KB
/
api-client.test.ts
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
import * as Config from '@oclif/config'
import cli from 'cli-ux'
import base, {expect} from 'fancy-test'
import nock from 'nock'
import * as sinon from 'sinon'
import {Command as CommandBase} from '../src/command'
import {RequestId, requestIdHeader} from '../src/request-id'
// tslint:disable no-http-string
class Command extends CommandBase {
async run() {}
}
const netrc = require('netrc-parser').default
netrc.loadSync = function (this: typeof netrc) {
netrc.machines = {
'api.heroku.com': {password: 'mypass'}
}
}
let env = process.env
let api: nock.Scope
beforeEach(() => {
process.env = {}
api = nock('https://api.heroku.com')
})
afterEach(() => {
process.env = env
api.done()
})
const test = base
.add('config', () => Config.load())
describe('api_client', () => {
test
.it('makes an HTTP request', async ctx => {
api = nock('https://api.heroku.com', {
reqheaders: {authorization: 'Bearer mypass'},
})
api.get('/apps').reply(200, [{name: 'myapp'}])
const cmd = new Command([], ctx.config)
const {body} = await cmd.heroku.get('/apps')
expect(body).to.deep.equal([{name: 'myapp'}])
// expect(netrc.loadSync).toBeCalled()
})
test
.it('can override authorization header', async ctx => {
api = nock('https://api.heroku.com', {
reqheaders: {authorization: 'Bearer myotherpass'},
})
api.get('/apps').reply(200, [{name: 'myapp'}])
const cmd = new Command([], ctx.config)
const {body} = await cmd.heroku.get('/apps', {headers: {Authorization: 'Bearer myotherpass'}})
expect(body).to.deep.equal([{name: 'myapp'}])
})
describe('with HEROKU_HEADERS', () => {
test
.it('makes an HTTP request with HEROKU_HEADERS', async ctx => {
process.env.HEROKU_HEADERS = '{"x-foo": "bar"}'
api = nock('https://api.heroku.com', {
reqheaders: {'x-foo': 'bar'},
})
api.get('/apps').reply(200, [{name: 'myapp'}])
const cmd = new Command([], ctx.config)
const {body} = await cmd.heroku.get('/apps')
expect(body).to.deep.equal([{name: 'myapp'}])
})
})
describe('with HEROKU_HOST', () => {
test
.it('makes an HTTP request with HEROKU_HOST', async ctx => {
process.env.HEROKU_HOST = 'http://localhost:5000'
api = nock('http://localhost:5000')
api.get('/apps').reply(200, [{name: 'myapp'}])
const cmd = new Command([], ctx.config)
const {body} = await cmd.heroku.get('/apps')
expect(body).to.deep.equal([{name: 'myapp'}])
})
})
test
.it('2fa no preauth', async ctx => {
api = nock('https://api.heroku.com')
api.get('/apps').reply(403, {id: 'two_factor'})
let _api = api as any
_api.get('/apps').matchHeader('heroku-two-factor-code', '123456').reply(200, [{name: 'myapp'}])
const cmd = new Command([], ctx.config)
Object.defineProperty(cli, 'prompt', {
get: () => () => Promise.resolve('123456')
})
const {body} = await cmd.heroku.get('/apps')
expect(body).to.deep.equal([{name: 'myapp'}])
})
test
.it('2fa preauth', async ctx => {
api = nock('https://api.heroku.com')
api.get('/apps/myapp').reply(403, {id: 'two_factor', app: {name: 'myapp'}})
let _api = api as any
_api.put('/apps/myapp/pre-authorizations').matchHeader('heroku-two-factor-code', '123456').reply(200, {})
api.get('/apps/myapp').reply(200, {name: 'myapp'})
api.get('/apps/anotherapp').reply(200, {name: 'anotherapp'})
api.get('/apps/myapp/config').reply(200, {foo: 'bar'})
api.get('/apps/myapp/dynos').reply(200, {web: 1})
const cmd = new Command([], ctx.config)
Object.defineProperty(cli, 'prompt', {
get: () => () => Promise.resolve('123456')
})
const info = cmd.heroku.get('/apps/myapp')
const anotherapp = cmd.heroku.get('/apps/anotherapp')
const _config = cmd.heroku.get('/apps/myapp/config')
const dynos = cmd.heroku.get('/apps/myapp/dynos')
expect((await info).body).to.deep.equal({name: 'myapp'})
expect((await anotherapp).body).to.deep.equal({name: 'anotherapp'})
expect((await _config).body).to.deep.equal({foo: 'bar'})
expect((await dynos).body).to.deep.equal({web: 1})
})
context('request ids', function () {
let generateStub: any
beforeEach(function () {
RequestId.empty()
generateStub = sinon.stub(RequestId, '_generate')
})
afterEach(function () {
generateStub.restore()
})
test
.it('makes requests with a generated request id', async ctx => {
const cmd = new Command([], ctx.config)
generateStub.returns('random-uuid')
api = nock('https://api.heroku.com').get('/apps').reply(200, [{name: 'myapp'}])
const {request} = await cmd.heroku.get('/apps')
expect(request.getHeader(requestIdHeader)).to.deep.equal('random-uuid')
})
test
.it('makes requests including previous request ids', async ctx => {
const cmd = new Command([], ctx.config)
api = nock('https://api.heroku.com').get('/apps').twice().reply(200, [{name: 'myapp'}])
generateStub.returns('random-uuid')
await cmd.heroku.get('/apps')
generateStub.returns('second-random-uuid')
const {request: secondRequest} = await cmd.heroku.get('/apps')
expect(secondRequest.getHeader(requestIdHeader)).to.deep.equal('second-random-uuid,random-uuid')
})
test
.it('tracks response request ids for subsequent request ids', async ctx => {
const cmd = new Command([], ctx.config)
const existingRequestIds = ['first-existing-request-id', 'second-existing-request-id'].join(',')
api = nock('https://api.heroku.com').get('/apps').twice().reply(() => [200, JSON.stringify({name: 'myapp'}), {[requestIdHeader]: existingRequestIds}])
generateStub.returns('random-uuid')
await cmd.heroku.get('/apps')
generateStub.returns('second-random-uuid')
const {request: secondRequest} = await cmd.heroku.get('/apps')
expect(secondRequest.getHeader(requestIdHeader)).to.deep.equal('second-random-uuid,first-existing-request-id,second-existing-request-id,random-uuid')
})
})
})