shipit-engine 0.33.0 → 0.34.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.
- checksums.yaml +4 -4
- data/README.md +13 -2
- data/app/assets/stylesheets/_pages/_deploy.scss +0 -2
- data/app/controllers/shipit/api/ccmenu_controller.rb +1 -1
- data/app/controllers/shipit/api/deploys_controller.rb +2 -0
- data/app/controllers/shipit/api/rollbacks_controller.rb +2 -1
- data/app/controllers/shipit/api/stacks_controller.rb +1 -0
- data/app/controllers/shipit/deploys_controller.rb +1 -1
- data/app/controllers/shipit/stacks_controller.rb +2 -2
- data/app/controllers/shipit/tasks_controller.rb +2 -2
- data/app/controllers/shipit/webhooks_controller.rb +23 -4
- data/app/helpers/shipit/shipit_helper.rb +0 -1
- data/app/jobs/shipit/deliver_hook_job.rb +1 -1
- data/app/jobs/shipit/github_sync_job.rb +13 -9
- data/app/jobs/shipit/update_github_last_deployed_ref_job.rb +1 -1
- data/app/models/shipit/anonymous_user.rb +6 -2
- data/app/models/shipit/check_run.rb +36 -0
- data/app/models/shipit/commit.rb +20 -9
- data/app/models/shipit/commit_checks.rb +13 -13
- data/app/models/shipit/commit_deployment.rb +3 -3
- data/app/models/shipit/commit_deployment_status.rb +3 -3
- data/app/models/shipit/deploy.rb +16 -11
- data/app/models/shipit/deploy_spec/lerna_discovery.rb +12 -4
- data/app/models/shipit/duration.rb +2 -0
- data/app/models/shipit/hook.rb +26 -2
- data/app/models/shipit/merge_request.rb +9 -7
- data/app/models/shipit/pull_request.rb +1 -1
- data/app/models/shipit/release_status.rb +1 -1
- data/app/models/shipit/repository.rb +9 -3
- data/app/models/shipit/review_stack.rb +16 -2
- data/app/models/shipit/stack.rb +59 -25
- data/app/models/shipit/status/group.rb +1 -1
- data/app/models/shipit/task.rb +6 -2
- data/app/models/shipit/task_execution_strategy/default.rb +4 -5
- data/app/models/shipit/team.rb +4 -2
- data/app/models/shipit/user.rb +4 -0
- data/app/models/shipit/webhooks/handlers/pull_request/review_stack_adapter.rb +1 -1
- data/app/models/shipit/webhooks/handlers/push_handler.rb +4 -1
- data/app/serializers/shipit/merge_request_serializer.rb +1 -1
- data/app/validators/subset_validator.rb +1 -1
- data/app/views/layouts/merge_status.html.erb +1 -1
- data/app/views/shipit/stacks/_banners.html.erb +2 -1
- data/app/views/shipit/stacks/new.html.erb +1 -1
- data/config/secrets.development.example.yml +24 -0
- data/config/secrets.development.shopify.yml +20 -9
- data/db/migrate/20210325194053_remove_stacks_branch_default.rb +5 -0
- data/db/migrate/20210504200438_add_github_updated_at_to_check_runs.rb +5 -0
- data/lib/shipit.rb +39 -15
- data/lib/shipit/command.rb +7 -6
- data/lib/shipit/commands.rb +9 -2
- data/lib/shipit/engine.rb +2 -0
- data/lib/shipit/flock.rb +8 -1
- data/lib/shipit/github_app.rb +7 -5
- data/lib/shipit/octokit_iterator.rb +3 -3
- data/lib/shipit/simple_message_verifier.rb +2 -2
- data/lib/shipit/stack_commands.rb +28 -4
- data/lib/shipit/task_commands.rb +6 -0
- data/lib/shipit/version.rb +1 -1
- data/lib/snippets/publish-lerna-independent-packages +35 -34
- data/lib/snippets/publish-lerna-independent-packages-legacy +39 -0
- data/test/controllers/api/ccmenu_controller_test.rb +1 -1
- data/test/controllers/api/deploys_controller_test.rb +17 -0
- data/test/controllers/api/stacks_controller_test.rb +21 -7
- data/test/controllers/webhooks_controller_test.rb +26 -11
- data/test/dummy/app/assets/config/manifest.js +3 -0
- data/test/dummy/config/application.rb +1 -1
- data/test/dummy/config/database.yml +9 -0
- data/test/dummy/config/environments/development.rb +1 -1
- data/test/dummy/config/secrets_double_github_app.yml +79 -0
- data/test/dummy/db/schema.rb +5 -4
- data/test/dummy/db/seeds.rb +1 -0
- data/test/fixtures/payloads/check_suite_master.json +2 -30
- data/test/fixtures/payloads/push_master.json +1 -1
- data/test/fixtures/payloads/push_not_master.json +1 -1
- data/test/fixtures/shipit/commits.yml +2 -2
- data/test/fixtures/shipit/hooks.yml +1 -0
- data/test/fixtures/shipit/tasks.yml +1 -1
- data/test/helpers/json_helper.rb +5 -1
- data/test/jobs/github_sync_job_test.rb +2 -1
- data/test/models/commit_deployment_status_test.rb +3 -3
- data/test/models/commits_test.rb +2 -0
- data/test/models/deploy_spec_test.rb +7 -0
- data/test/models/deploys_test.rb +18 -0
- data/test/models/hook_test.rb +30 -1
- data/test/models/merge_request_test.rb +19 -4
- data/test/models/shipit/check_run_test.rb +124 -5
- data/test/models/shipit/review_stack_test.rb +38 -6
- data/test/models/shipit/stacks_test.rb +42 -4
- data/test/models/shipit/webhooks/handlers/pull_request/review_stack_adapter_test.rb +24 -0
- data/test/models/tasks_test.rb +22 -0
- data/test/test_helper.rb +15 -0
- data/test/unit/anonymous_user_serializer_test.rb +1 -1
- data/test/unit/command_test.rb +5 -0
- data/test/unit/commit_serializer_test.rb +1 -1
- data/test/unit/deploy_commands_test.rb +70 -14
- data/test/unit/deploy_serializer_test.rb +1 -1
- data/test/unit/github_app_test.rb +2 -3
- data/test/unit/github_apps_test.rb +416 -0
- data/test/unit/shipit_deployment_checks_test.rb +77 -0
- data/test/unit/shipit_test.rb +14 -0
- data/test/unit/user_serializer_test.rb +1 -1
- metadata +202 -191
|
@@ -11,7 +11,7 @@ module Shipit
|
|
|
11
11
|
assert_equal DeploySerializer, serializer
|
|
12
12
|
serialized = serializer.new(deploy).to_json
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
assert_json_document(serialized, "commits.0.author.name", first_commit_author.name)
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
end
|
|
@@ -18,7 +18,7 @@ module Shipit
|
|
|
18
18
|
|
|
19
19
|
test "#initialize doesn't raise if given an empty config" do
|
|
20
20
|
assert_nothing_raised do
|
|
21
|
-
GitHubApp.new({})
|
|
21
|
+
GitHubApp.new(nil, {})
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
@@ -183,7 +183,6 @@ module Shipit
|
|
|
183
183
|
.any_instance
|
|
184
184
|
.expects(:create_app_installation_access_token).with(config[:installation_id], anything)
|
|
185
185
|
.returns(second_token)
|
|
186
|
-
|
|
187
186
|
first_token = valid_app.token
|
|
188
187
|
|
|
189
188
|
first_cached_token = Rails.cache.fetch(@token_cache_key)
|
|
@@ -199,7 +198,7 @@ module Shipit
|
|
|
199
198
|
private
|
|
200
199
|
|
|
201
200
|
def app(extra_config = {})
|
|
202
|
-
GitHubApp.new(default_config.deep_merge(extra_config))
|
|
201
|
+
GitHubApp.new(nil, default_config.deep_merge(extra_config))
|
|
203
202
|
end
|
|
204
203
|
|
|
205
204
|
def default_config
|
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'test_helper'
|
|
3
|
+
|
|
4
|
+
module Shipit
|
|
5
|
+
class GitHubAppsTestOrgOne < ActiveSupport::TestCase
|
|
6
|
+
setup do
|
|
7
|
+
@organization = "OrgOne"
|
|
8
|
+
@github = app(@organization)
|
|
9
|
+
@enterprise = app(@organization, domain: 'github.example.com')
|
|
10
|
+
@rails_env = Rails.env
|
|
11
|
+
@token_cache_key = "github:integration:#{@organization.downcase}:access-token"
|
|
12
|
+
Rails.cache.delete(@token_cache_key)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
teardown do
|
|
16
|
+
Rails.env = @rails_env
|
|
17
|
+
Rails.cache.delete(@token_cache_key)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
test "#domain defaults to github.com" do
|
|
21
|
+
assert_equal 'github.com', @github.domain
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
test "#url returns the HTTPS url to the github installation" do
|
|
25
|
+
assert_equal 'https://github.example.com', @enterprise.url
|
|
26
|
+
assert_equal 'https://github.example.com/foo/bar', @enterprise.url('/foo/bar')
|
|
27
|
+
assert_equal 'https://github.example.com/foo/bar/baz', @enterprise.url('foo/bar', 'baz')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
test "#new_client retruns an Octokit::Client configured to use the github installation" do
|
|
31
|
+
assert_equal 'https://github.example.com/', @enterprise.new_client.web_endpoint
|
|
32
|
+
assert_equal 'https://github.example.com/api/v3/', @enterprise.new_client.api_endpoint
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
test "#oauth_config.last[:client_options] is nil if domain is not overriden" do
|
|
36
|
+
assert_nil @github.oauth_config.last[:client_options][:site]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
test "#oauth_config.last[:client_options] returns Enterprise endpoint if domain is overriden" do
|
|
40
|
+
assert_equal 'https://github.example.com/api/v3/', @enterprise.oauth_config.last[:client_options][:site]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
test "#initialize doesn't raise if given an empty config" do
|
|
44
|
+
assert_nothing_raised do
|
|
45
|
+
GitHubApp.new(@organization, {})
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
test "#api_status" do
|
|
50
|
+
stub_request(:get, "https://www.githubstatus.com/api/v2/components.json").to_return(
|
|
51
|
+
status: 200,
|
|
52
|
+
body: %(
|
|
53
|
+
{
|
|
54
|
+
"page":{},
|
|
55
|
+
"components":[
|
|
56
|
+
{
|
|
57
|
+
"id":"brv1bkgrwx7q",
|
|
58
|
+
"name":"API Requests",
|
|
59
|
+
"status":"operational",
|
|
60
|
+
"created_at":"2017-01-31T20:01:46.621Z",
|
|
61
|
+
"updated_at":"2019-07-23T18:41:18.197Z",
|
|
62
|
+
"position":2,
|
|
63
|
+
"description":"Requests for GitHub APIs",
|
|
64
|
+
"showcase":false,
|
|
65
|
+
"group_id":null,
|
|
66
|
+
"page_id":"kctbh9vrtdwd",
|
|
67
|
+
"group":false,
|
|
68
|
+
"only_show_if_degraded":false
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
),
|
|
73
|
+
)
|
|
74
|
+
assert_equal "operational", app(@organization).api_status[:status]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
test "#github token is refreshed after expiration" do
|
|
78
|
+
Rails.env = 'not_test'
|
|
79
|
+
config = {
|
|
80
|
+
app_id: "test_id",
|
|
81
|
+
installation_id: "test_installation_id",
|
|
82
|
+
private_key: "test_private_key",
|
|
83
|
+
}
|
|
84
|
+
initial_token = OpenStruct.new(
|
|
85
|
+
token: "some_initial_github_token",
|
|
86
|
+
expires_at: Time.now.utc + 60.minutes,
|
|
87
|
+
)
|
|
88
|
+
second_token = OpenStruct.new(
|
|
89
|
+
token: "some_new_github_token",
|
|
90
|
+
expires_at: initial_token.expires_at + 60.minutes,
|
|
91
|
+
)
|
|
92
|
+
auth_payload = "test_auth_payload"
|
|
93
|
+
|
|
94
|
+
GitHubApp.any_instance.expects(:authentication_payload).twice.returns(auth_payload)
|
|
95
|
+
valid_app = app(@organization, config)
|
|
96
|
+
|
|
97
|
+
freeze_time do
|
|
98
|
+
Octokit::Client
|
|
99
|
+
.any_instance
|
|
100
|
+
.expects(:create_app_installation_access_token).twice.with(config[:installation_id], anything)
|
|
101
|
+
.returns(initial_token, second_token)
|
|
102
|
+
|
|
103
|
+
initial_token = valid_app.token
|
|
104
|
+
initial_cached_token = Rails.cache.fetch(@token_cache_key)
|
|
105
|
+
assert_equal initial_token, initial_cached_token.to_s
|
|
106
|
+
|
|
107
|
+
travel 5.minutes
|
|
108
|
+
assert_equal initial_token, valid_app.token
|
|
109
|
+
|
|
110
|
+
travel_to initial_cached_token.expires_at + 5.minutes
|
|
111
|
+
assert_equal second_token.token, valid_app.token
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
test "#github token is refreshed in refresh window before expiry" do
|
|
116
|
+
Rails.env = 'not_test'
|
|
117
|
+
config = {
|
|
118
|
+
app_id: "test_id",
|
|
119
|
+
installation_id: "test_installation_id",
|
|
120
|
+
private_key: "test_private_key",
|
|
121
|
+
}
|
|
122
|
+
initial_token = OpenStruct.new(
|
|
123
|
+
token: "some_initial_github_token",
|
|
124
|
+
expires_at: Time.now.utc + 60.minutes,
|
|
125
|
+
)
|
|
126
|
+
second_token = OpenStruct.new(
|
|
127
|
+
token: "some_new_github_token",
|
|
128
|
+
expires_at: initial_token.expires_at + 60.minutes,
|
|
129
|
+
)
|
|
130
|
+
auth_payload = "test_auth_payload"
|
|
131
|
+
|
|
132
|
+
GitHubApp.any_instance.expects(:authentication_payload).twice.returns(auth_payload)
|
|
133
|
+
valid_app = app(@organization, config)
|
|
134
|
+
|
|
135
|
+
freeze_time do
|
|
136
|
+
Octokit::Client
|
|
137
|
+
.any_instance
|
|
138
|
+
.expects(:create_app_installation_access_token).twice.with(config[:installation_id], anything)
|
|
139
|
+
.returns(initial_token, second_token)
|
|
140
|
+
|
|
141
|
+
initial_token = valid_app.token
|
|
142
|
+
initial_cached_token = Rails.cache.fetch(@token_cache_key)
|
|
143
|
+
assert_equal initial_token, initial_cached_token.to_s
|
|
144
|
+
|
|
145
|
+
# Travel forward, but before the token is refreshed, so the cached value should be the same.
|
|
146
|
+
travel 40.minutes
|
|
147
|
+
assert_equal initial_token, valid_app.token
|
|
148
|
+
|
|
149
|
+
# Travel to when the token should refresh, but is not expired, which should result in our cache.fetch update block.
|
|
150
|
+
travel 15.minutes
|
|
151
|
+
updated_token = valid_app.token
|
|
152
|
+
assert_not_equal initial_token, updated_token
|
|
153
|
+
|
|
154
|
+
cached_token = Rails.cache.fetch(@token_cache_key)
|
|
155
|
+
assert_operator cached_token.expires_at, :>, initial_cached_token.expires_at
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
test "#github token is missing refresh_at field" do
|
|
160
|
+
# $debugging = true
|
|
161
|
+
Rails.env = 'not_test'
|
|
162
|
+
config = {
|
|
163
|
+
app_id: "test_id",
|
|
164
|
+
installation_id: "test_installation_id",
|
|
165
|
+
private_key: "test_private_key",
|
|
166
|
+
}
|
|
167
|
+
initial_cached_token = Shipit::GitHubApp::Token.new("some_initial_github_token", Time.now.utc - 1.minute)
|
|
168
|
+
initial_cached_token.instance_variable_set(:@refresh_at, nil)
|
|
169
|
+
|
|
170
|
+
second_token = OpenStruct.new(
|
|
171
|
+
token: "some_new_github_token",
|
|
172
|
+
expires_at: initial_cached_token.expires_at + 60.minutes,
|
|
173
|
+
)
|
|
174
|
+
auth_payload = "test_auth_payload"
|
|
175
|
+
|
|
176
|
+
GitHubApp.any_instance.expects(:authentication_payload).returns(auth_payload)
|
|
177
|
+
valid_app = app(@organization, config)
|
|
178
|
+
|
|
179
|
+
freeze_time do
|
|
180
|
+
valid_app.instance_variable_set(:@token, initial_cached_token)
|
|
181
|
+
Rails.cache.write(@token_cache_key, initial_cached_token, expires_in: 1.minute)
|
|
182
|
+
|
|
183
|
+
Octokit::Client
|
|
184
|
+
.any_instance
|
|
185
|
+
.expects(:create_app_installation_access_token).with(config[:installation_id], anything)
|
|
186
|
+
.returns(second_token)
|
|
187
|
+
|
|
188
|
+
first_token = valid_app.token
|
|
189
|
+
|
|
190
|
+
first_cached_token = Rails.cache.fetch(@token_cache_key)
|
|
191
|
+
assert_equal first_token, first_cached_token.to_s
|
|
192
|
+
|
|
193
|
+
travel_to first_cached_token.expires_at + 5.minutes
|
|
194
|
+
new_token = valid_app.token
|
|
195
|
+
|
|
196
|
+
assert_equal second_token.token, new_token
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
private
|
|
201
|
+
|
|
202
|
+
def app(organization, extra_config = {})
|
|
203
|
+
GitHubApp.new(organization, double_github_app_config.deep_merge(extra_config))
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def double_github_app_config
|
|
207
|
+
YAML.load_file('test/dummy/config/secrets_double_github_app.yml')
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
class GitHubAppsTestOrgTwo < ActiveSupport::TestCase
|
|
212
|
+
setup do
|
|
213
|
+
@organization = "OrgTwo"
|
|
214
|
+
@github = app(@organization)
|
|
215
|
+
@enterprise = app(@organization, domain: 'github.example.com')
|
|
216
|
+
@rails_env = Rails.env
|
|
217
|
+
@token_cache_key = "github:integration:#{@organization.downcase}:access-token"
|
|
218
|
+
Rails.cache.delete(@token_cache_key)
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
teardown do
|
|
222
|
+
Rails.env = @rails_env
|
|
223
|
+
Rails.cache.delete(@token_cache_key)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
test "#domain defaults to github.com" do
|
|
227
|
+
assert_equal 'github.com', @github.domain
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
test "#url returns the HTTPS url to the github installation" do
|
|
231
|
+
assert_equal 'https://github.example.com', @enterprise.url
|
|
232
|
+
assert_equal 'https://github.example.com/foo/bar', @enterprise.url('/foo/bar')
|
|
233
|
+
assert_equal 'https://github.example.com/foo/bar/baz', @enterprise.url('foo/bar', 'baz')
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
test "#new_client retruns an Octokit::Client configured to use the github installation" do
|
|
237
|
+
assert_equal 'https://github.example.com/', @enterprise.new_client.web_endpoint
|
|
238
|
+
assert_equal 'https://github.example.com/api/v3/', @enterprise.new_client.api_endpoint
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
test "#oauth_config.last[:client_options] is nil if domain is not overriden" do
|
|
242
|
+
assert_nil @github.oauth_config.last[:client_options][:site]
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
test "#oauth_config.last[:client_options] returns Enterprise endpoint if domain is overriden" do
|
|
246
|
+
assert_equal 'https://github.example.com/api/v3/', @enterprise.oauth_config.last[:client_options][:site]
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
test "#initialize doesn't raise if given an empty config" do
|
|
250
|
+
assert_nothing_raised do
|
|
251
|
+
GitHubApp.new(@organization, {})
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
test "#api_status" do
|
|
256
|
+
stub_request(:get, "https://www.githubstatus.com/api/v2/components.json").to_return(
|
|
257
|
+
status: 200,
|
|
258
|
+
body: %(
|
|
259
|
+
{
|
|
260
|
+
"page":{},
|
|
261
|
+
"components":[
|
|
262
|
+
{
|
|
263
|
+
"id":"brv1bkgrwx7q",
|
|
264
|
+
"name":"API Requests",
|
|
265
|
+
"status":"operational",
|
|
266
|
+
"created_at":"2017-01-31T20:01:46.621Z",
|
|
267
|
+
"updated_at":"2019-07-23T18:41:18.197Z",
|
|
268
|
+
"position":2,
|
|
269
|
+
"description":"Requests for GitHub APIs",
|
|
270
|
+
"showcase":false,
|
|
271
|
+
"group_id":null,
|
|
272
|
+
"page_id":"kctbh9vrtdwd",
|
|
273
|
+
"group":false,
|
|
274
|
+
"only_show_if_degraded":false
|
|
275
|
+
}
|
|
276
|
+
]
|
|
277
|
+
}
|
|
278
|
+
),
|
|
279
|
+
)
|
|
280
|
+
assert_equal "operational", app(@organization).api_status[:status]
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
test "#github token is refreshed after expiration" do
|
|
284
|
+
Rails.env = 'not_test'
|
|
285
|
+
config = {
|
|
286
|
+
app_id: "test_id",
|
|
287
|
+
installation_id: "test_installation_id",
|
|
288
|
+
private_key: "test_private_key",
|
|
289
|
+
}
|
|
290
|
+
initial_token = OpenStruct.new(
|
|
291
|
+
token: "some_initial_github_token",
|
|
292
|
+
expires_at: Time.now.utc + 60.minutes,
|
|
293
|
+
)
|
|
294
|
+
second_token = OpenStruct.new(
|
|
295
|
+
token: "some_new_github_token",
|
|
296
|
+
expires_at: initial_token.expires_at + 60.minutes,
|
|
297
|
+
)
|
|
298
|
+
auth_payload = "test_auth_payload"
|
|
299
|
+
|
|
300
|
+
GitHubApp.any_instance.expects(:authentication_payload).twice.returns(auth_payload)
|
|
301
|
+
valid_app = app(@organization, config)
|
|
302
|
+
|
|
303
|
+
freeze_time do
|
|
304
|
+
Octokit::Client
|
|
305
|
+
.any_instance
|
|
306
|
+
.expects(:create_app_installation_access_token).twice.with(config[:installation_id], anything)
|
|
307
|
+
.returns(initial_token, second_token)
|
|
308
|
+
|
|
309
|
+
initial_token = valid_app.token
|
|
310
|
+
initial_cached_token = Rails.cache.fetch(@token_cache_key)
|
|
311
|
+
assert_equal initial_token, initial_cached_token.to_s
|
|
312
|
+
|
|
313
|
+
travel 5.minutes
|
|
314
|
+
assert_equal initial_token, valid_app.token
|
|
315
|
+
|
|
316
|
+
travel_to initial_cached_token.expires_at + 5.minutes
|
|
317
|
+
assert_equal second_token.token, valid_app.token
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
test "#github token is refreshed in refresh window before expiry" do
|
|
322
|
+
Rails.env = 'not_test'
|
|
323
|
+
config = {
|
|
324
|
+
app_id: "test_id",
|
|
325
|
+
installation_id: "test_installation_id",
|
|
326
|
+
private_key: "test_private_key",
|
|
327
|
+
}
|
|
328
|
+
initial_token = OpenStruct.new(
|
|
329
|
+
token: "some_initial_github_token",
|
|
330
|
+
expires_at: Time.now.utc + 60.minutes,
|
|
331
|
+
)
|
|
332
|
+
second_token = OpenStruct.new(
|
|
333
|
+
token: "some_new_github_token",
|
|
334
|
+
expires_at: initial_token.expires_at + 60.minutes,
|
|
335
|
+
)
|
|
336
|
+
auth_payload = "test_auth_payload"
|
|
337
|
+
|
|
338
|
+
GitHubApp.any_instance.expects(:authentication_payload).twice.returns(auth_payload)
|
|
339
|
+
valid_app = app(@organization, config)
|
|
340
|
+
|
|
341
|
+
freeze_time do
|
|
342
|
+
Octokit::Client
|
|
343
|
+
.any_instance
|
|
344
|
+
.expects(:create_app_installation_access_token).twice.with(config[:installation_id], anything)
|
|
345
|
+
.returns(initial_token, second_token)
|
|
346
|
+
|
|
347
|
+
initial_token = valid_app.token
|
|
348
|
+
initial_cached_token = Rails.cache.fetch(@token_cache_key)
|
|
349
|
+
assert_equal initial_token, initial_cached_token.to_s
|
|
350
|
+
|
|
351
|
+
# Travel forward, but before the token is refreshed, so the cached value should be the same.
|
|
352
|
+
travel 40.minutes
|
|
353
|
+
assert_equal initial_token, valid_app.token
|
|
354
|
+
|
|
355
|
+
# Travel to when the token should refresh, but is not expired, which should result in our cache.fetch update block.
|
|
356
|
+
travel 15.minutes
|
|
357
|
+
updated_token = valid_app.token
|
|
358
|
+
assert_not_equal initial_token, updated_token
|
|
359
|
+
|
|
360
|
+
cached_token = Rails.cache.fetch(@token_cache_key)
|
|
361
|
+
assert_operator cached_token.expires_at, :>, initial_cached_token.expires_at
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
test "#github token is missing refresh_at field" do
|
|
366
|
+
# $debugging = true
|
|
367
|
+
Rails.env = 'not_test'
|
|
368
|
+
config = {
|
|
369
|
+
app_id: "test_id",
|
|
370
|
+
installation_id: "test_installation_id",
|
|
371
|
+
private_key: "test_private_key",
|
|
372
|
+
}
|
|
373
|
+
initial_cached_token = Shipit::GitHubApp::Token.new("some_initial_github_token", Time.now.utc - 1.minute)
|
|
374
|
+
initial_cached_token.instance_variable_set(:@refresh_at, nil)
|
|
375
|
+
|
|
376
|
+
second_token = OpenStruct.new(
|
|
377
|
+
token: "some_new_github_token",
|
|
378
|
+
expires_at: initial_cached_token.expires_at + 60.minutes,
|
|
379
|
+
)
|
|
380
|
+
auth_payload = "test_auth_payload"
|
|
381
|
+
|
|
382
|
+
GitHubApp.any_instance.expects(:authentication_payload).returns(auth_payload)
|
|
383
|
+
valid_app = app(@organization, config)
|
|
384
|
+
|
|
385
|
+
freeze_time do
|
|
386
|
+
valid_app.instance_variable_set(:@token, initial_cached_token)
|
|
387
|
+
Rails.cache.write(@token_cache_key, initial_cached_token, expires_in: 1.minute)
|
|
388
|
+
|
|
389
|
+
Octokit::Client
|
|
390
|
+
.any_instance
|
|
391
|
+
.expects(:create_app_installation_access_token).with(config[:installation_id], anything)
|
|
392
|
+
.returns(second_token)
|
|
393
|
+
|
|
394
|
+
first_token = valid_app.token
|
|
395
|
+
|
|
396
|
+
first_cached_token = Rails.cache.fetch(@token_cache_key)
|
|
397
|
+
assert_equal first_token, first_cached_token.to_s
|
|
398
|
+
|
|
399
|
+
travel_to first_cached_token.expires_at + 5.minutes
|
|
400
|
+
new_token = valid_app.token
|
|
401
|
+
|
|
402
|
+
assert_equal second_token.token, new_token
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
private
|
|
407
|
+
|
|
408
|
+
def app(organization, extra_config = {})
|
|
409
|
+
GitHubApp.new(organization, double_github_app_config.deep_merge(extra_config))
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
def double_github_app_config
|
|
413
|
+
YAML.load_file('test/dummy/config/secrets_double_github_app.yml')
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
end
|