txgh-server 2.0.0 → 2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7e58e68da42392ba7ad13d0bbe7fe8240062a4ca
4
- data.tar.gz: 83cb94af972bd003c0fcbe6c57718a4a9b6716f7
3
+ metadata.gz: 9e75d11d351052dcae4752db36b41f3bfe213b7c
4
+ data.tar.gz: 26d3a5ace61faa39884854fc336e70490fbb1bd6
5
5
  SHA512:
6
- metadata.gz: 212276130dac852ac0083f4070c20beb4824418a1e36f2d2baafd0c210f6fa3a49f819a0f581dd5eb777cd18ae3efbf7cbdf9cb7638ea70f3f22547b79a5adec
7
- data.tar.gz: aa3c2d6acccc503f41a5cb1f0faacf5b93ab0aa349f9eb0566562f830df55ff81081ea3542d45b10d2d1b32c5b8bd3e6390612f665cd018ab7ec1f3fda99ec0e
6
+ metadata.gz: 9a230bc3d628166f714d41a4705c85b1331c44f267b9c593e5049903149f91ca379d050a5f8e7ed31b09ac52eebaa01ae0bc903c235044ed10c6a322e9df1b9a
7
+ data.tar.gz: 2c594d254994d92586b44653448387e450e52931719f6819e0657a7dc7e472a375c72a55bac7abdf00652f837e268d5d9824b2cb310c1e0a8e0e96b45e8e9bdc
@@ -15,8 +15,7 @@ module TxghServer
15
15
  begin
16
16
  resp.write_to(out)
17
17
  rescue => e
18
- Txgh.events.publish_error(e)
19
- raise e
18
+ Txgh.events.publish_error!(e)
20
19
  end
21
20
  end
22
21
  else
@@ -1,14 +1,26 @@
1
+ require 'octokit'
2
+ require 'txgh'
3
+
1
4
  module TxghServer
2
5
  module Triggers
3
6
  class PullHandler < Handler
4
7
 
5
8
  def execute
6
9
  puller.pull_slug(resource_slug)
10
+ update_github_status
7
11
  respond_with(200, true)
8
12
  end
9
13
 
10
14
  private
11
15
 
16
+ def update_github_status
17
+ Txgh::GithubStatus.update(project, repo, branch)
18
+ rescue Octokit::UnprocessableEntity
19
+ # raised because we've tried to create too many statuses for the commit
20
+ rescue Txgh::TransifexNotFoundError
21
+ # raised if transifex resource can't be found
22
+ end
23
+
12
24
  def puller
13
25
  @puller ||= Txgh::Puller.new(project, repo, branch)
14
26
  end
@@ -1,14 +1,26 @@
1
+ require 'octokit'
2
+ require 'txgh'
3
+
1
4
  module TxghServer
2
5
  module Triggers
3
6
  class PushHandler < Handler
4
7
 
5
8
  def execute
6
9
  pusher.push_slug(resource_slug)
10
+ update_github_status
7
11
  respond_with(200, true)
8
12
  end
9
13
 
10
14
  private
11
15
 
16
+ def update_github_status
17
+ Txgh::GithubStatus.update(project, repo, branch)
18
+ rescue Octokit::UnprocessableEntity
19
+ # raised because we've tried to create too many statuses for the commit
20
+ rescue Txgh::TransifexNotFoundError
21
+ # raised if transifex resource can't be found
22
+ end
23
+
12
24
  def pusher
13
25
  @pusher ||= Txgh::Pusher.new(project, repo, branch)
14
26
  end
@@ -1,3 +1,3 @@
1
1
  module TxghServer
2
- VERSION = '2.0.0'
2
+ VERSION = '2.1.0'
3
3
  end
@@ -3,7 +3,7 @@ module TxghServer
3
3
  module Github
4
4
  class DeleteAttributes
5
5
  ATTRIBUTES = [
6
- :repo_name, :ref, :ref_type
6
+ :event, :repo_name, :ref, :ref_type
7
7
  ]
8
8
 
9
9
  class << self
@@ -15,6 +15,10 @@ module TxghServer
15
15
  )
16
16
  end
17
17
 
18
+ def event(payload)
19
+ 'delete'
20
+ end
21
+
18
22
  def repo_name(payload)
19
23
  payload.fetch('repository').fetch('full_name')
20
24
  end
@@ -1,11 +1,9 @@
1
- require 'set'
2
-
3
1
  module TxghServer
4
2
  module Webhooks
5
3
  module Github
6
4
  class PushAttributes
7
5
  ATTRIBUTES = [
8
- :repo_name, :ref, :before, :after,
6
+ :event, :repo_name, :ref, :before, :after,
9
7
  :added_files, :modified_files, :author
10
8
  ]
11
9
 
@@ -18,6 +16,10 @@ module TxghServer
18
16
  )
19
17
  end
20
18
 
19
+ def event(payload)
20
+ 'push'
21
+ end
22
+
21
23
  def repo_name(payload)
22
24
  payload.fetch('repository').fetch('full_name')
23
25
  end
@@ -1,4 +1,6 @@
1
1
  require 'set'
2
+ require 'octokit'
3
+ require 'txgh'
2
4
 
3
5
  module TxghServer
4
6
  module Webhooks
@@ -23,12 +25,12 @@ module TxghServer
23
25
  if should_process?
24
26
  logger.info('found branch in github request')
25
27
 
26
- updater = Txgh::ResourceUpdater.new(project, repo, logger)
27
- categories = { 'author' => attributes.author }
28
-
29
- added_and_modified_resources.each do |resource|
30
- updater.update_resource(resource, categories)
28
+ pusher.push_resources(added_and_modified_resources) do |tx_resource|
29
+ # block should return categories for the passed-in resource
30
+ { 'author' => attributes.author }
31
31
  end
32
+
33
+ update_github_status
32
34
  end
33
35
 
34
36
  respond_with(200, true)
@@ -36,9 +38,21 @@ module TxghServer
36
38
 
37
39
  private
38
40
 
41
+ def update_github_status
42
+ Txgh::GithubStatus.update(project, repo, branch)
43
+ rescue Octokit::UnprocessableEntity
44
+ # raised because we've tried to create too many statuses for the commit
45
+ rescue Txgh::TransifexNotFoundError
46
+ # raised if transifex resource can't be found
47
+ end
48
+
49
+ def pusher
50
+ @pusher ||= Txgh::Pusher.new(project, repo, branch)
51
+ end
52
+
39
53
  # finds the resources that were updated in each commit
40
54
  def added_and_modified_resources
41
- attributes.files.each_with_object(Set.new) do |file, ret|
55
+ @amr ||= attributes.files.each_with_object(Set.new) do |file, ret|
42
56
  logger.info("processing added/modified file: #{file}")
43
57
 
44
58
  if tx_resources.include?(file)
@@ -1,4 +1,6 @@
1
1
  require 'logger'
2
+ require 'txgh'
3
+ require 'octokit'
2
4
 
3
5
  module TxghServer
4
6
  module Webhooks
@@ -21,14 +23,26 @@ module TxghServer
21
23
  logger.info(resource_slug)
22
24
 
23
25
  check_error_response || begin
24
- committer = Txgh::ResourceCommitter.new(project, repo, logger)
25
- committer.commit_resource(tx_resource, branch, language)
26
+ puller.pull_resource(tx_resource, [language])
27
+ update_github_status
26
28
  respond_with(200, true)
27
29
  end
28
30
  end
29
31
 
30
32
  private
31
33
 
34
+ def update_github_status
35
+ Txgh::GithubStatus.update(project, repo, branch)
36
+ rescue Octokit::UnprocessableEntity
37
+ # raised because we've tried to create too many statuses for the commit
38
+ rescue Txgh::TransifexNotFoundError
39
+ # raised if transifex resource can't be found
40
+ end
41
+
42
+ def puller
43
+ @puller ||= Txgh::Puller.new(project, repo, branch)
44
+ end
45
+
32
46
  def check_error_response
33
47
  check_supported_language || check_tx_config || check_tx_resource
34
48
  end
@@ -277,9 +277,8 @@ describe TxghServer::TriggerEndpoints do
277
277
  updater = double(:updater)
278
278
  expect(Txgh::ResourceUpdater).to receive(:new).and_return(updater)
279
279
  expect(Txgh::GithubApi).to receive(:new).and_return(github_api)
280
- expect(github_api).to receive(:get_ref).and_return(object: { sha: 'abc123' })
281
280
 
282
- expect(updater).to receive(:update_resource) do |resource, sha|
281
+ expect(updater).to receive(:update_resource) do |resource, categories|
283
282
  expected_branch = Txgh::Utils.absolute_branch(branch)
284
283
  expect(resource.branch).to eq(expected_branch)
285
284
  expect(resource.project_slug).to eq(project_name)
@@ -288,6 +287,8 @@ describe TxghServer::TriggerEndpoints do
288
287
  )
289
288
  end
290
289
 
290
+ expect(Txgh::GithubStatus).to receive(:update)
291
+
291
292
  patch '/push', params
292
293
  expect(last_response).to be_ok
293
294
  end
@@ -313,16 +314,15 @@ describe TxghServer::TriggerEndpoints do
313
314
 
314
315
  it 'updates translations (in all locales) in the expected repo' do
315
316
  committer = double(:committer)
316
- languages = [{ 'language_code' => 'pt' }, { 'language_code' => 'ja' }]
317
- project_config['languages'] = %w(pt ja)
317
+ languages = %w(pt ja)
318
+ project_config['languages'] = languages
318
319
  expect(Txgh::ResourceCommitter).to receive(:new).and_return(committer)
319
320
  expect(Txgh::TransifexApi).to receive(:new).and_return(transifex_api)
320
- expect(transifex_api).to receive(:get_languages).and_return(languages)
321
321
 
322
322
  languages.each do |language|
323
323
  expect(committer).to receive(:commit_resource) do |resource, branch, lang|
324
324
  expect(branch).to eq(branch)
325
- expect(lang).to eq(language['language_code'])
325
+ expect(lang).to eq(language)
326
326
  expect(resource.branch).to eq(branch)
327
327
  expect(resource.project_slug).to eq(project_name)
328
328
  expect(resource.resource_slug).to(
@@ -331,6 +331,8 @@ describe TxghServer::TriggerEndpoints do
331
331
  end
332
332
  end
333
333
 
334
+ expect(Txgh::GithubStatus).to receive(:update)
335
+
334
336
  patch '/pull', params
335
337
  expect(last_response).to be_ok
336
338
  end
@@ -2,7 +2,7 @@
2
2
  http_interactions:
3
3
  - request:
4
4
  method: get
5
- uri: https://txgh.bot:<TRANSIFEX_PASSWORD>@www.transifex.com/api/2/project/test-project-88/languages/
5
+ uri: https://txgh.bot:<TRANSIFEX_PASSWORD>@www.transifex.com/api/2/project/test-project-88/resources/
6
6
  body:
7
7
  encoding: US-ASCII
8
8
  string: ''
@@ -21,7 +21,7 @@ http_interactions:
21
21
  Server:
22
22
  - nginx
23
23
  Date:
24
- - Wed, 28 Sep 2016 18:33:51 GMT
24
+ - Tue, 04 Oct 2016 21:42:30 GMT
25
25
  Content-Type:
26
26
  - application/json; charset=utf-8
27
27
  Transfer-Encoding:
@@ -31,17 +31,254 @@ http_interactions:
31
31
  Vary:
32
32
  - Accept-Encoding
33
33
  - Authorization, Host, Accept-Language, Cookie
34
+ Content-Language:
35
+ - en
36
+ Expires:
37
+ - Tue, 04 Oct 2016 21:42:30 GMT
38
+ Last-Modified:
39
+ - Tue, 04 Oct 2016 21:42:30 GMT
40
+ Cache-Control:
41
+ - max-age=0
34
42
  X-Frame-Options:
35
43
  - SAMEORIGIN
44
+ X-Content-Type-Options:
45
+ - nosniff
46
+ body:
47
+ encoding: UTF-8
48
+ string: "[\n {\n \"source_language_code\": \"en\", \n \"name\":
49
+ \"sample.po\", \n \"i18n_type\": \"PO\", \n \"priority\": \"1\",
50
+ \n \"slug\": \"samplepo-heads_master\", \n \"categories\": [\n
51
+ \ \"\"\n ]\n }, \n {\n \"source_language_code\":
52
+ \"en\", \n \"name\": \"sample.po\", \n \"i18n_type\": \"PO\",
53
+ \n \"priority\": \"0\", \n \"slug\": \"samplepo\", \n \"categories\":
54
+ [\n \"branch:refs/tags/L10N\", \n \"author:Txgh Bot\"\n
55
+ \ ]\n }, \n {\n \"source_language_code\": \"en\", \n \"name\":
56
+ \"test.yml\", \n \"i18n_type\": \"YML\", \n \"priority\": \"1\",
57
+ \n \"slug\": \"testyml-heads_change_some_shizz\", \n \"categories\":
58
+ [\n \"author:Cameron_Dutro branch:heads/change_some_shizz\"\n ]\n
59
+ \ }, \n {\n \"source_language_code\": \"en\", \n \"name\":
60
+ \"test.yml\", \n \"i18n_type\": \"YML\", \n \"priority\": \"0\",
61
+ \n \"slug\": \"testyml-heads_master\", \n \"categories\": [\n
62
+ \ \"branch:heads/master\"\n ]\n }\n]"
63
+ http_version:
64
+ recorded_at: Tue, 04 Oct 2016 21:42:30 GMT
65
+ - request:
66
+ method: get
67
+ uri: https://api.github.com/repos/txgh-bot/txgh-test-resources/git/refs/heads/master
68
+ body:
69
+ encoding: US-ASCII
70
+ string: ''
71
+ headers:
72
+ Accept:
73
+ - application/vnd.github.v3+json
74
+ User-Agent:
75
+ - Octokit Ruby Gem 4.3.0
76
+ Content-Type:
77
+ - application/json
78
+ Authorization:
79
+ - token <GITHUB_TOKEN>
80
+ Accept-Encoding:
81
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
82
+ response:
83
+ status:
84
+ code: 200
85
+ message: OK
86
+ headers:
87
+ Server:
88
+ - GitHub.com
89
+ Date:
90
+ - Tue, 04 Oct 2016 21:42:30 GMT
91
+ Content-Type:
92
+ - application/json; charset=utf-8
93
+ Transfer-Encoding:
94
+ - chunked
95
+ Status:
96
+ - 200 OK
97
+ X-Ratelimit-Limit:
98
+ - '5000'
99
+ X-Ratelimit-Remaining:
100
+ - '4999'
101
+ X-Ratelimit-Reset:
102
+ - '1475620950'
103
+ Cache-Control:
104
+ - private, max-age=60, s-maxage=60
105
+ Vary:
106
+ - Accept, Authorization, Cookie, X-GitHub-OTP
107
+ - Accept-Encoding
108
+ Etag:
109
+ - W/"a5fe675407899fa4460005cce07b9fe2"
110
+ Last-Modified:
111
+ - Mon, 11 Jan 2016 23:45:43 GMT
112
+ X-Poll-Interval:
113
+ - '300'
114
+ X-Oauth-Scopes:
115
+ - public_repo
116
+ X-Accepted-Oauth-Scopes:
117
+ - ''
118
+ X-Github-Media-Type:
119
+ - github.v3; format=json
120
+ Access-Control-Expose-Headers:
121
+ - ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset,
122
+ X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
123
+ Access-Control-Allow-Origin:
124
+ - "*"
125
+ Content-Security-Policy:
126
+ - default-src 'none'
127
+ Strict-Transport-Security:
128
+ - max-age=31536000; includeSubdomains; preload
129
+ X-Content-Type-Options:
130
+ - nosniff
131
+ X-Frame-Options:
132
+ - deny
133
+ X-Xss-Protection:
134
+ - 1; mode=block
135
+ X-Served-By:
136
+ - 9000e9eef7bb1e89f22030c676da140e
137
+ X-Github-Request-Id:
138
+ - 04358C36:6823:3A08A0E:57F42246
139
+ body:
140
+ encoding: UTF-8
141
+ string: '{"ref":"refs/heads/master","url":"https://api.github.com/repos/txgh-bot/txgh-test-resources/git/refs/heads/master","object":{"sha":"f3edb21f027b70974750649ba29b0090e410ecde","type":"commit","url":"https://api.github.com/repos/txgh-bot/txgh-test-resources/git/commits/f3edb21f027b70974750649ba29b0090e410ecde"}}'
142
+ http_version:
143
+ recorded_at: Tue, 04 Oct 2016 21:42:30 GMT
144
+ - request:
145
+ method: get
146
+ uri: https://txgh.bot:<TRANSIFEX_PASSWORD>@www.transifex.com/api/2/project/test-project-88/resource/samplepo/stats/
147
+ body:
148
+ encoding: US-ASCII
149
+ string: ''
150
+ headers:
151
+ User-Agent:
152
+ - Faraday v0.9.2
153
+ Accept:
154
+ - application/json
155
+ Accept-Encoding:
156
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
157
+ response:
158
+ status:
159
+ code: 200
160
+ message: OK
161
+ headers:
162
+ Server:
163
+ - nginx
164
+ Date:
165
+ - Tue, 04 Oct 2016 21:42:31 GMT
166
+ Content-Type:
167
+ - application/json; charset=utf-8
168
+ Transfer-Encoding:
169
+ - chunked
170
+ Connection:
171
+ - keep-alive
172
+ Vary:
173
+ - Accept-Encoding
174
+ - Authorization, Host, Accept-Language, Cookie
36
175
  Content-Language:
37
176
  - en
177
+ Expires:
178
+ - Tue, 04 Oct 2016 21:42:31 GMT
179
+ Last-Modified:
180
+ - Tue, 04 Oct 2016 21:42:31 GMT
181
+ Cache-Control:
182
+ - max-age=0
183
+ X-Frame-Options:
184
+ - SAMEORIGIN
38
185
  X-Content-Type-Options:
39
186
  - nosniff
40
187
  body:
41
188
  encoding: UTF-8
42
- string: "[\n {\n \"coordinators\": [\n \"txgh.bot\"\n ],
43
- \n \"language_code\": \"el_GR\", \n \"translators\": [], \n
44
- \ \"reviewers\": []\n }\n]"
189
+ string: "{\n \"el_GR\": {\n \"reviewed_percentage\": \"0%\", \n \"completed\":
190
+ \"0%\", \n \"untranslated_words\": 10, \n \"last_commiter\":
191
+ \"\", \n \"reviewed\": 0, \n \"translated_entities\": 0, \n
192
+ \ \"translated_words\": 0, \n \"last_update\": \"2016-01-19 19:08:25\",
193
+ \n \"untranslated_entities\": 10\n }, \n \"ru\": {\n \"reviewed_percentage\":
194
+ \"0%\", \n \"completed\": \"0%\", \n \"untranslated_words\":
195
+ 10, \n \"last_commiter\": \"txgh.bot\", \n \"reviewed\": 0,
196
+ \n \"translated_entities\": 0, \n \"translated_words\": 0, \n
197
+ \ \"last_update\": \"2016-04-01 05:36:37\", \n \"untranslated_entities\":
198
+ 10\n }, \n \"en\": {\n \"reviewed_percentage\": \"0%\", \n \"completed\":
199
+ \"100%\", \n \"untranslated_words\": 0, \n \"last_commiter\":
200
+ \"txgh.bot\", \n \"reviewed\": 0, \n \"translated_entities\":
201
+ 10, \n \"translated_words\": 10, \n \"last_update\": \"2016-01-19
202
+ 19:08:25\", \n \"untranslated_entities\": 0\n }\n}"
203
+ http_version:
204
+ recorded_at: Tue, 04 Oct 2016 21:42:31 GMT
205
+ - request:
206
+ method: post
207
+ uri: https://api.github.com/repos/txgh-bot/txgh-test-resources/statuses/f3edb21f027b70974750649ba29b0090e410ecde
208
+ body:
209
+ encoding: UTF-8
210
+ string: '{"context":"continuous-localization/txgh","target_url":"https://www.transifex.com//test-project-88/content","description":"10/30
211
+ translations complete.","state":"pending"}'
212
+ headers:
213
+ Accept:
214
+ - application/vnd.github.v3+json
215
+ User-Agent:
216
+ - Octokit Ruby Gem 4.3.0
217
+ Content-Type:
218
+ - application/json
219
+ Authorization:
220
+ - token <GITHUB_TOKEN>
221
+ Accept-Encoding:
222
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
223
+ response:
224
+ status:
225
+ code: 201
226
+ message: Created
227
+ headers:
228
+ Server:
229
+ - GitHub.com
230
+ Date:
231
+ - Tue, 04 Oct 2016 21:42:31 GMT
232
+ Content-Type:
233
+ - application/json; charset=utf-8
234
+ Content-Length:
235
+ - '1259'
236
+ Status:
237
+ - 201 Created
238
+ X-Ratelimit-Limit:
239
+ - '5000'
240
+ X-Ratelimit-Remaining:
241
+ - '4998'
242
+ X-Ratelimit-Reset:
243
+ - '1475620950'
244
+ Cache-Control:
245
+ - private, max-age=60, s-maxage=60
246
+ Vary:
247
+ - Accept, Authorization, Cookie, X-GitHub-OTP
248
+ - Accept-Encoding
249
+ Etag:
250
+ - '"592996d2e58de58405c11218b79e486a"'
251
+ X-Oauth-Scopes:
252
+ - public_repo
253
+ X-Accepted-Oauth-Scopes:
254
+ - ''
255
+ Location:
256
+ - https://api.github.com/repos/txgh-bot/txgh-test-resources/statuses/f3edb21f027b70974750649ba29b0090e410ecde
257
+ X-Github-Media-Type:
258
+ - github.v3; format=json
259
+ Access-Control-Expose-Headers:
260
+ - ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset,
261
+ X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
262
+ Access-Control-Allow-Origin:
263
+ - "*"
264
+ Content-Security-Policy:
265
+ - default-src 'none'
266
+ Strict-Transport-Security:
267
+ - max-age=31536000; includeSubdomains; preload
268
+ X-Content-Type-Options:
269
+ - nosniff
270
+ X-Frame-Options:
271
+ - deny
272
+ X-Xss-Protection:
273
+ - 1; mode=block
274
+ X-Served-By:
275
+ - cee4c0729c8e9147e7abcb45b9d69689
276
+ X-Github-Request-Id:
277
+ - 04358C36:6817:11C8B83:57F42247
278
+ body:
279
+ encoding: UTF-8
280
+ string: '{"url":"https://api.github.com/repos/txgh-bot/txgh-test-resources/statuses/f3edb21f027b70974750649ba29b0090e410ecde","id":785751432,"state":"pending","description":"10/30
281
+ translations complete.","target_url":"https://www.transifex.com//test-project-88/content","context":"continuous-localization/txgh","created_at":"2016-10-04T21:42:31Z","updated_at":"2016-10-04T21:42:31Z","creator":{"login":"txgh-bot","id":16723366,"avatar_url":"https://avatars.githubusercontent.com/u/16723366?v=3","gravatar_id":"","url":"https://api.github.com/users/txgh-bot","html_url":"https://github.com/txgh-bot","followers_url":"https://api.github.com/users/txgh-bot/followers","following_url":"https://api.github.com/users/txgh-bot/following{/other_user}","gists_url":"https://api.github.com/users/txgh-bot/gists{/gist_id}","starred_url":"https://api.github.com/users/txgh-bot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/txgh-bot/subscriptions","organizations_url":"https://api.github.com/users/txgh-bot/orgs","repos_url":"https://api.github.com/users/txgh-bot/repos","events_url":"https://api.github.com/users/txgh-bot/events{/privacy}","received_events_url":"https://api.github.com/users/txgh-bot/received_events","type":"User","site_admin":false}}'
45
282
  http_version:
46
- recorded_at: Wed, 28 Sep 2016 18:33:51 GMT
283
+ recorded_at: Tue, 04 Oct 2016 21:42:31 GMT
47
284
  recorded_with: VCR 3.0.3