git_reflow 0.8.3 → 0.8.4

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.
@@ -0,0 +1,665 @@
1
+ require 'spec_helper'
2
+
3
+ describe GitReflow::Workflows::Core do
4
+ let(:feature_branch) { 'new-feature' }
5
+ let(:existing_pull_requests) { Fixture.new('pull_requests/pull_requests.json').to_json_hashie }
6
+ let(:existing_gh_pull_request) { GitReflow::GitServer::GitHub::PullRequest.new existing_pull_requests.first }
7
+ let(:pull_request_message_file) { "#{GitReflow.git_root_dir}/.git/GIT_REFLOW_PR_MSG" }
8
+
9
+ before do
10
+ allow(GitReflow).to receive(:current_branch).and_return(feature_branch)
11
+ allow_any_instance_of(HighLine).to receive(:choose)
12
+ end
13
+
14
+ describe ".setup" do
15
+ subject { GitReflow::Workflows::Core.setup }
16
+
17
+ before do
18
+ allow(File).to receive(:exist?).and_return(false)
19
+ stub_command_line_inputs({
20
+ 'Set the minimum number of approvals (leaving blank will require approval from all commenters): ' => ''
21
+ })
22
+ end
23
+
24
+ specify { expect { subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all core.editor \"#{GitReflow.default_editor}\"" }
25
+ specify { expect { subject }.to have_said "Updated git's editor (via git config key 'core.editor') to: #{GitReflow.default_editor}.", :notice }
26
+
27
+ context "core.editor git config has already been set" do
28
+ before do
29
+ allow(GitReflow::Config).to receive(:get) { "" }
30
+ allow(GitReflow::Config).to receive(:get).with('core.editor').and_return('emacs')
31
+ end
32
+
33
+ specify { expect { subject }.to_not have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all core.editor \"#{GitReflow.default_editor}\"" }
34
+ end
35
+
36
+ context "git-reflow has not been setup before" do
37
+ it "notifies the user of global setup" do
38
+ expect { subject }.to have_said "We'll walk you through setting up git-reflow's defaults for all your projects.", :notice
39
+ expect { subject }.to have_said "In the future, you can run \`git-reflow setup\` from the root of any project you want to setup differently.", :notice
40
+ expect { subject }.to have_said "To adjust these settings globally, you can run \`git-reflow setup --global\`.", :notice
41
+ end
42
+
43
+ it "creates a .gitconfig.reflow file and includes it in the user's global git config" do
44
+ expect { subject }.to have_run_command "touch #{GitReflow::Config::CONFIG_FILE_PATH}"
45
+ expect { subject }.to have_run_command_silently "git config --global --add include.path \"#{GitReflow::Config::CONFIG_FILE_PATH}\""
46
+
47
+ expect { subject }.to have_said "Created #{GitReflow::Config::CONFIG_FILE_PATH} for git-reflow specific configurations.", :notice
48
+ expect { subject }.to have_said "Added #{GitReflow::Config::CONFIG_FILE_PATH} to include.path in $HOME/.gitconfig.", :notice
49
+ end
50
+
51
+ it "sets the default approval minimum and regex" do
52
+ expect { subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all constants.minimumApprovals \"\""
53
+ expect { subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all constants.approvalRegex \"#{GitReflow::GitServer::PullRequest::DEFAULT_APPROVAL_REGEX}\""
54
+ end
55
+
56
+ context "when setting a custom approval minimum" do
57
+ before do
58
+ stub_command_line_inputs({
59
+ 'Set the minimum number of approvals (leaving blank will require approval from all commenters): ' => '3'
60
+ })
61
+ end
62
+
63
+ specify { expect { subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all constants.minimumApprovals \"3\"" }
64
+ end
65
+ end
66
+
67
+ context "git-reflow has been setup before" do
68
+ before do
69
+ allow(File).to receive(:exist?).and_return(true)
70
+ end
71
+
72
+ it "doesn't create another .gitconfig.reflow file" do
73
+ expect { subject }.to_not have_run_command "touch #{GitReflow::Config::CONFIG_FILE_PATH}"
74
+ expect { subject }.to_not have_said "Created #{GitReflow::Config::CONFIG_FILE_PATH} for git-reflow specific configurations.", :notice
75
+ end
76
+
77
+ it "doesn't add the .gitconfig.reflow file to the git-config include path" do
78
+ expect { subject }.to_not have_run_command_silently "git config --global --add include.path \"#{GitReflow::Config::CONFIG_FILE_PATH}\""
79
+
80
+ expect { subject }.to_not have_said "Added #{GitReflow::Config::CONFIG_FILE_PATH} to include.path in $HOME/.gitconfig.", :notice
81
+ end
82
+ end
83
+ end
84
+
85
+ describe ".start" do
86
+ let(:feature_branch) { 'new_feature' }
87
+ subject { GitReflow::Workflows::Core.start feature_branch: feature_branch }
88
+
89
+ it "updates the local repo and starts creates a new branch" do
90
+ expect { subject }.to have_run_commands_in_order [
91
+ "git checkout master",
92
+ "git pull origin master",
93
+ "git push origin master:refs/heads/#{feature_branch}",
94
+ "git checkout --track -b #{feature_branch} origin/#{feature_branch}"
95
+ ]
96
+ end
97
+
98
+ context "but no branch name is provided" do
99
+ let(:feature_branch) { "" }
100
+
101
+ it "doesn't run any commands and returns usage" do
102
+ expect { subject }.to_not have_run_command "git checkout master"
103
+ expect { subject }.to_not have_run_command "git pull origin master"
104
+ expect { subject }.to_not have_run_command "git push origin master:refs/heads/#{feature_branch}"
105
+ expect { subject }.to_not have_run_command "git checkout --track -b #{feature_branch} origin/#{feature_branch}"
106
+ expect { subject }.to have_said "usage: git-reflow start [new-branch-name]", :error
107
+ end
108
+ end
109
+
110
+ it "starts from a different base branch when one is supplied" do
111
+ expect { GitReflow::Workflows::Core.start feature_branch: feature_branch, base: 'development' }.to have_run_commands_in_order [
112
+ "git checkout development",
113
+ "git pull origin development",
114
+ "git push origin development:refs/heads/#{feature_branch}",
115
+ "git checkout --track -b #{feature_branch} origin/#{feature_branch}"
116
+ ]
117
+ end
118
+ end
119
+
120
+ describe ".review" do
121
+ let(:feature_branch) { 'new-feature' }
122
+ let(:user) { 'reenhanced' }
123
+ let(:password) { 'shazam' }
124
+ let(:repo) { 'repo' }
125
+ let(:inputs) { {} }
126
+
127
+ before do
128
+ allow(GitReflow).to receive(:remote_user).and_return(user)
129
+ allow(GitReflow).to receive(:git_server).and_return(GitReflow::GitServer)
130
+ allow(GitReflow.git_server).to receive(:get_build_status).and_return(Struct.new(:state, :description, :url, :target_url).new)
131
+ allow(GitReflow.git_server).to receive(:find_open_pull_request).and_return(nil)
132
+ allow(GitReflow.git_server).to receive(:create_pull_request).and_return(existing_gh_pull_request)
133
+ allow(File).to receive(:open).with(pull_request_message_file, 'w')
134
+ allow(File).to receive(:read).with(pull_request_message_file).and_return("bingo")
135
+ allow(File).to receive(:delete)
136
+
137
+ stub_command_line_inputs({
138
+ "Submit pull request? (Y)" => ""
139
+ })
140
+ end
141
+
142
+ subject { GitReflow::Workflows::Core.review inputs }
143
+
144
+ it "fetches updates to the base branch" do
145
+ expect { subject }.to have_run_command "git fetch origin master"
146
+ end
147
+
148
+ it "pushes the current branch to the remote repo" do
149
+ expect { subject }.to have_run_command "git push origin #{feature_branch}"
150
+ end
151
+
152
+ it "uses the current branch name as the text for the PR" do
153
+ fake_file = double
154
+ expect(File).to receive(:open).with(pull_request_message_file, "w").and_yield(fake_file)
155
+ expect(fake_file).to receive(:write).with(GitReflow.current_branch)
156
+ subject
157
+ end
158
+
159
+ it "opens the pull request file for modification" do
160
+ allow(File).to receive(:open).with(pull_request_message_file, 'w')
161
+ expect { subject }.to have_run_command "#{GitReflow.git_editor_command} #{pull_request_message_file}"
162
+ end
163
+
164
+ it "reads the file then cleans up the temporary pull request message file" do
165
+ expect(File).to receive(:read).with(pull_request_message_file)
166
+ expect(File).to receive(:delete).with(pull_request_message_file)
167
+ subject
168
+ end
169
+
170
+ it "displays a review of the PR before submitting it" do
171
+ expect { subject }.to have_said "\nReview your PR:\n"
172
+ expect { subject }.to have_said "Title:\nbingo\n\n"
173
+ expect { subject }.to have_said "Body:\n\n\n"
174
+ end
175
+
176
+ context "and a PR template exists" do
177
+ let(:template_content) { "hey now" }
178
+ before do
179
+ allow(GitReflow).to receive(:pull_request_template).and_return(template_content)
180
+ end
181
+
182
+ it "uses the template's content for the PR" do
183
+ fake_file = double
184
+ expect(File).to receive(:open).with(pull_request_message_file, "w").and_yield(fake_file)
185
+ expect(fake_file).to receive(:write).with(template_content)
186
+ subject
187
+ end
188
+
189
+ end
190
+
191
+ context "providing a base branch" do
192
+ let(:inputs) {{ base: "development" }}
193
+
194
+ before do
195
+ stub_command_line_inputs({
196
+ 'Submit pull request? (Y)' => 'yes'
197
+ })
198
+ end
199
+
200
+ it "creates a pull request using the custom base branch" do
201
+ expect(GitReflow.git_server).to receive(:create_pull_request).with({
202
+ title: 'bingo',
203
+ body: "\n",
204
+ head: "#{user}:#{feature_branch}",
205
+ base: inputs[:base]
206
+ })
207
+ subject
208
+ end
209
+ end
210
+
211
+ context "providing only a title" do
212
+ let(:inputs) {{ title: "Amazing new feature" }}
213
+
214
+ before do
215
+ stub_command_line_inputs({
216
+ 'Submit pull request? (Y)' => 'yes'
217
+ })
218
+ end
219
+
220
+ it "creates a pull request with only the given title" do
221
+ expect(GitReflow.git_server).to receive(:create_pull_request).with({
222
+ title: inputs[:title],
223
+ body: nil,
224
+ head: "#{user}:#{feature_branch}",
225
+ base: 'master'
226
+ })
227
+ subject
228
+ end
229
+
230
+ it "does not bother opening any template file" do
231
+ expect(File).to_not receive(:open)
232
+ expect(File).to_not receive(:read)
233
+ expect(File).to_not receive(:delete)
234
+ subject
235
+ end
236
+ end
237
+
238
+ context "providing only a body" do
239
+ let(:inputs) {{ body: "Please pull this in!" }}
240
+
241
+ before do
242
+ stub_command_line_inputs({
243
+ 'Submit pull request? (Y)' => 'yes'
244
+ })
245
+ end
246
+
247
+ it "creates a pull request with the body as both title and body" do
248
+ expect(GitReflow.git_server).to receive(:create_pull_request).with({
249
+ title: inputs[:body],
250
+ body: inputs[:body],
251
+ head: "#{user}:#{feature_branch}",
252
+ base: 'master'
253
+ })
254
+ subject
255
+ end
256
+ end
257
+
258
+ context "providing both title and body" do
259
+ let(:inputs) {{ title: "Amazing new feature", body: "Please pull this in!" }}
260
+
261
+ before do
262
+ stub_command_line_inputs({
263
+ 'Submit pull request? (Y)' => 'yes'
264
+ })
265
+ end
266
+
267
+ it "creates a pull request with only the given title" do
268
+ expect(GitReflow.git_server).to receive(:create_pull_request).with({
269
+ title: inputs[:title],
270
+ body: inputs[:body],
271
+ head: "#{user}:#{feature_branch}",
272
+ base: 'master'
273
+ })
274
+ subject
275
+ end
276
+ end
277
+
278
+ context "with existing pull request" do
279
+ before do
280
+ expect(GitReflow.git_server).to receive(:find_open_pull_request).and_return(existing_gh_pull_request)
281
+ allow(existing_gh_pull_request).to receive(:display_pull_request_summary)
282
+ end
283
+
284
+ specify { expect{subject}.to have_said "A pull request already exists for these branches:", :notice }
285
+
286
+ it "displays a notice that an existing PR exists" do
287
+ expect(existing_gh_pull_request).to receive(:display_pull_request_summary)
288
+ subject
289
+ end
290
+ end
291
+
292
+ context "approving PR submission" do
293
+ before do
294
+ stub_command_line_inputs({
295
+ 'Submit pull request? (Y)' => 'yes'
296
+ })
297
+ end
298
+
299
+ it "creates a pull request" do
300
+ expect(GitReflow.git_server).to receive(:create_pull_request).with({
301
+ title: 'bingo',
302
+ body: "\n",
303
+ head: "#{user}:#{feature_branch}",
304
+ base: 'master'
305
+ })
306
+ subject
307
+ end
308
+
309
+ it "notifies the user that the pull request was created" do
310
+ expect(GitReflow.git_server).to receive(:create_pull_request).and_return(existing_gh_pull_request)
311
+ expect{ subject }.to have_said "Successfully created pull request ##{existing_gh_pull_request.number}: #{existing_gh_pull_request.title}\nPull Request URL: #{existing_gh_pull_request.html_url}\n", :success
312
+ end
313
+ end
314
+
315
+ context "aborting during PR template review" do
316
+ before do
317
+ stub_command_line_inputs({
318
+ 'Submit pull request? (Y)' => 'no'
319
+ })
320
+ end
321
+
322
+ it "does not create a pull request" do
323
+ expect(GitReflow.git_server).to_not receive(:create_pull_request)
324
+ subject
325
+ end
326
+
327
+ it "notifies the user that the review was aborted" do
328
+ expect { subject }.to have_said "Review aborted. No pull request has been created.", :review_halted
329
+ end
330
+ end
331
+ end
332
+
333
+ describe ".status" do
334
+ let(:feature_branch) { 'new-feature' }
335
+ let(:destination_branch) { nil }
336
+
337
+ subject { GitReflow::Workflows::Core.status destination_branch: destination_branch }
338
+
339
+ before do
340
+ allow(GitReflow).to receive(:git_server).and_return(GitReflow::GitServer)
341
+ allow(GitReflow.git_server).to receive(:get_build_status).and_return(Struct.new(:state, :description, :url, :target_url).new)
342
+ allow(GitReflow).to receive(:current_branch).and_return(feature_branch)
343
+ allow(existing_gh_pull_request).to receive(:display_pull_request_summary)
344
+ end
345
+
346
+ context "with no existing pull request" do
347
+ before { allow(GitReflow.git_server).to receive(:find_open_pull_request).with({from: feature_branch, to: 'master'}).and_return(nil) }
348
+ it { expect{ subject }.to have_said "No pull request exists for #{feature_branch} -> master", :notice }
349
+ it { expect{ subject }.to have_said "Run 'git reflow review master' to start the review process", :notice }
350
+ end
351
+
352
+ context "with an existing pull request" do
353
+ let(:destination_branch) { 'master' }
354
+ before do
355
+ allow(GitReflow.git_server).to receive(:find_open_pull_request).and_return(existing_gh_pull_request)
356
+ end
357
+
358
+ it "displays a summary of the pull request" do
359
+ expect(existing_gh_pull_request).to receive(:display_pull_request_summary)
360
+ expect{ subject }.to have_said "Here's the status of your review:"
361
+ end
362
+
363
+ context "with custom destination branch" do
364
+ let(:destination_branch) { 'develop' }
365
+
366
+ it "uses the custom destination branch to lookup the pull request" do
367
+ expect(GitReflow.git_server).to receive(:find_open_pull_request).with({from: feature_branch, to: destination_branch}).and_return(existing_gh_pull_request)
368
+ subject
369
+ end
370
+ end
371
+ end
372
+ end
373
+
374
+ describe ".deploy" do
375
+ let(:deploy_command) { "bundle exec cap #{destination} deploy" }
376
+ let(:destination) { nil }
377
+ subject { GitReflow::Workflows::Core.deploy(destination_server: destination) }
378
+
379
+ before do
380
+ stub_command_line_inputs({
381
+ "Enter the command you use to deploy to default (leaving blank will skip deployment)" => "bundle exec cap deploy",
382
+ "Enter the command you use to deploy to #{destination} (leaving blank will skip deployment)" => "bundle exec cap #{destination} deploy"
383
+ })
384
+ end
385
+
386
+ it "sets the local git-config for reflow.deploy-to-default-command" do
387
+ expect(GitReflow::Config).to receive(:set).with('reflow.deploy-to-default-command', deploy_command.squeeze, local: true)
388
+ subject
389
+ end
390
+
391
+ it "runs the staging deploy command" do
392
+ expect { subject }.to have_run_command(deploy_command.squeeze)
393
+ end
394
+
395
+ context "staging" do
396
+ let(:destination) { "staging" }
397
+
398
+ it "sets the local git-config for reflow.deploy-to-staging-command" do
399
+ expect(GitReflow::Config).to receive(:set).with('reflow.deploy-to-staging-command', deploy_command, local: true)
400
+ subject
401
+ end
402
+
403
+ it "runs the staging deploy command" do
404
+ expect { subject }.to have_run_command(deploy_command)
405
+ end
406
+ end
407
+ end
408
+
409
+ describe ".stage" do
410
+ let(:feature_branch) { 'new-feature' }
411
+
412
+ subject { GitReflow::Workflows::Core.stage }
413
+
414
+ before do
415
+ allow(GitReflow).to receive(:current_branch).and_return(feature_branch)
416
+ allow(GitReflow::Config).to receive(:get).and_call_original
417
+ allow(GitReflow::Workflows::Core).to receive(:deploy)
418
+ end
419
+
420
+ it "checks out and updates the staging branch" do
421
+ expect(GitReflow::Config).to receive(:get).with('reflow.staging-branch', local: true).and_return('staging')
422
+ expect { subject }.to have_run_commands_in_order([
423
+ "git checkout staging",
424
+ "git pull origin staging",
425
+ "git merge #{feature_branch}",
426
+ "git push origin staging"
427
+ ])
428
+ end
429
+
430
+ context "merge is not successful" do
431
+ before do
432
+ allow(GitReflow::Config).to receive(:get).with('reflow.staging-branch', local: true).and_return('staging')
433
+ allow(GitReflow).to receive(:run_command_with_label).and_call_original
434
+ expect(GitReflow).to receive(:run_command_with_label).with("git merge #{feature_branch}", with_system: true).and_return(false)
435
+ end
436
+
437
+ it "notifies the user of unsuccessful merge" do
438
+ expect { subject }.to have_said "There were issues merging your feature branch to staging.", :error
439
+ end
440
+
441
+ it "does not push any changes to the remote repo" do
442
+ expect { subject }.to_not have_run_command "git push origin staging"
443
+ end
444
+
445
+ it "does not deploy to staging" do
446
+ expect(GitReflow::Workflows::Core).to_not receive(:deploy)
447
+ subject
448
+ end
449
+ end
450
+
451
+ context "merge is successful" do
452
+ before do
453
+ allow(GitReflow::Config).to receive(:get).with('reflow.staging-branch', local: true).and_return('staging')
454
+ allow(GitReflow).to receive(:run_command_with_label).and_call_original
455
+ expect(GitReflow).to receive(:run_command_with_label).with("git merge #{feature_branch}", with_system: true).and_return(true).and_call_original
456
+ end
457
+
458
+ specify { expect{ subject }.to have_run_command "git push origin staging" }
459
+
460
+ context "and deployment is successful" do
461
+ before { expect(GitReflow::Workflows::Core).to receive(:deploy).with(destination_server: :staging).and_return(true) }
462
+ specify { expect{ subject }.to have_said "Deployed to Staging.", :success }
463
+ end
464
+
465
+ context "but deployment is not successful" do
466
+ before { allow(GitReflow::Workflows::Core).to receive(:deploy).with(destination_server: :staging).and_return(false) }
467
+ specify { expect{ subject }.to have_said "There were issues deploying to staging.", :error }
468
+ end
469
+ end
470
+
471
+ context "no staging branch has been setup" do
472
+ before do
473
+ allow(GitReflow::Config).to receive(:get).with('reflow.staging-branch', local: true).and_return('')
474
+ stub_command_line_inputs({
475
+ "What's the name of your staging branch? (default: 'staging') " => "bobby"
476
+ })
477
+ end
478
+
479
+ it "sets the reflow.staging-branch git config to 'staging'" do
480
+ expect(GitReflow::Config).to receive(:set).with("reflow.staging-branch", "bobby", local: true)
481
+ subject
482
+ end
483
+
484
+ it "checks out and updates the staging branch" do
485
+ allow(GitReflow::Config).to receive(:set).with("reflow.staging-branch", "bobby", local: true)
486
+ expect { subject }.to have_run_commands_in_order([
487
+ "git checkout bobby",
488
+ "git pull origin bobby",
489
+ "git merge #{feature_branch}",
490
+ "git push origin bobby"
491
+ ])
492
+ end
493
+
494
+ context "and I don't enter one in" do
495
+ before do
496
+ stub_command_line_inputs({
497
+ "What's the name of your staging branch? (default: 'staging') " => ""
498
+ })
499
+ end
500
+
501
+ it "sets the reflow.staging-branch git config to 'staging'" do
502
+ expect { subject }.to have_run_command_silently "git config --replace-all reflow.staging-branch \"staging\""
503
+ end
504
+
505
+ it "checks out and updates the staging branch" do
506
+ expect { subject }.to have_run_commands_in_order([
507
+ "git checkout staging",
508
+ "git pull origin staging",
509
+ "git merge #{feature_branch}",
510
+ "git push origin staging"
511
+ ])
512
+ end
513
+ end
514
+ end
515
+ end
516
+
517
+ describe ".deliver" do
518
+ let(:feature_branch) { 'new-feature' }
519
+ let(:user) { 'reenhanced' }
520
+ let(:repo) { 'repo' }
521
+
522
+ subject { GitReflow::Workflows::Core.deliver }
523
+
524
+ before do
525
+ allow(GitReflow).to receive(:git_server).and_return(GitReflow::GitServer)
526
+ allow(GitReflow).to receive(:remote_user).and_return(user)
527
+ allow(GitReflow).to receive(:current_branch).and_return(feature_branch)
528
+ allow(GitReflow.git_server).to receive(:get_build_status).and_return(Struct.new(:state, :description, :url, :target_url).new)
529
+ end
530
+
531
+ context "pull request does not exist" do
532
+ before { allow(GitReflow.git_server).to receive(:find_open_pull_request).with( from: feature_branch, to: 'master').and_return(nil) }
533
+ specify { expect{ subject }.to have_said "No pull request exists for #{user}:#{feature_branch}\nPlease submit your branch for review first with \`git reflow review\`", :deliver_halted }
534
+ end
535
+
536
+ context "pull request exists" do
537
+ before do
538
+ allow(GitReflow.git_server).to receive(:find_open_pull_request).with( from: feature_branch, to: 'master').and_return(existing_gh_pull_request)
539
+ allow(GitReflow::Workflows::Core).to receive(:status)
540
+ end
541
+
542
+ context "and PR passes all QA checks" do
543
+ before { allow(existing_gh_pull_request).to receive(:good_to_merge?).and_return(true) }
544
+
545
+ it "displays the status of the PR" do
546
+ allow(existing_gh_pull_request).to receive(:merge!)
547
+ expect(GitReflow::Workflows::Core).to receive(:status).with(destination_branch: 'master')
548
+ subject
549
+ end
550
+
551
+ it "merges the feature branch" do
552
+ expect(existing_gh_pull_request).to receive(:merge!)
553
+ subject
554
+ end
555
+
556
+ context "but there is an error from the git server" do
557
+ let(:github_error) { Github::Error::UnprocessableEntity.new(eval(Fixture.new('pull_requests/pull_request_exists_error.json').to_s)) }
558
+ before do
559
+ allow(existing_gh_pull_request).to receive(:merge!).and_raise github_error
560
+ end
561
+
562
+ it "notifies the user of the error" do
563
+ expect { subject }.to have_said "Github Error: #{github_error.inspect}", :error
564
+ end
565
+ end
566
+ end
567
+
568
+ context "and PR fails some QA checks" do
569
+ before do
570
+ allow(existing_gh_pull_request).to receive(:good_to_merge?).and_return(false)
571
+ allow(existing_gh_pull_request).to receive(:rejection_message).and_return("I think you need a hug.")
572
+ end
573
+
574
+ it "does not merge the feature branch" do
575
+ expect(existing_gh_pull_request).to_not receive(:merge!)
576
+ subject
577
+ end
578
+
579
+ it "does not display the status of the PR" do
580
+ expect(GitReflow::Workflows::Core).to_not receive(:status).with(destination_branch: 'master')
581
+ subject
582
+ end
583
+
584
+ it "notifies the user of the reason the merge is unsafe" do
585
+ expect { subject }.to have_said "I think you need a hug.", :deliver_halted
586
+ end
587
+
588
+ context "but forcing the deliver" do
589
+ subject { GitReflow::Workflows::Core.deliver force: true }
590
+
591
+ before do
592
+ allow(existing_gh_pull_request).to receive(:good_to_merge?).with(force: true).and_return(true)
593
+ allow(existing_gh_pull_request).to receive(:merge!).with(force: true, base: 'master', skip_lgtm: true)
594
+ end
595
+
596
+ it "displays the status of the PR" do
597
+ expect(GitReflow::Workflows::Core).to receive(:status).with(destination_branch: 'master')
598
+ subject
599
+ end
600
+
601
+ it "merges the feature branch anyway" do
602
+ expect(existing_gh_pull_request).to receive(:merge!).with(force: true, base: 'master', skip_lgtm: true)
603
+ subject
604
+ end
605
+ end
606
+ end
607
+
608
+ context "and using a custom base branch" do
609
+ subject { GitReflow::Workflows::Core.deliver base: 'development' }
610
+ before do
611
+ expect(GitReflow.git_server).to receive(:find_open_pull_request).with( from: feature_branch, to: 'development').and_return(existing_gh_pull_request)
612
+ allow(existing_gh_pull_request).to receive(:good_to_merge?).and_return(true)
613
+ end
614
+
615
+
616
+ it "displays the status of the PR" do
617
+ allow(existing_gh_pull_request).to receive(:merge!).with(base: 'development')
618
+ expect(GitReflow::Workflows::Core).to receive(:status).with(destination_branch: 'development')
619
+ subject
620
+ end
621
+
622
+ it "merges the feature branch" do
623
+ expect(existing_gh_pull_request).to receive(:merge!).with(base: 'development')
624
+ subject
625
+ end
626
+ end
627
+ end
628
+ end
629
+
630
+ describe ".refresh" do
631
+ subject { GitReflow::Workflows::Core.refresh }
632
+
633
+ it "updates the feature branch with default remote repo and base branch" do
634
+ expect(GitReflow).to receive(:update_feature_branch).with(remote: 'origin', base: 'master')
635
+ subject
636
+ end
637
+
638
+ context "providing a custom base branch" do
639
+ subject { GitReflow::Workflows::Core.refresh base: 'development' }
640
+
641
+ it "updates the feature branch with default remote repo and base branch" do
642
+ expect(GitReflow).to receive(:update_feature_branch).with(remote: 'origin', base: 'development')
643
+ subject
644
+ end
645
+ end
646
+
647
+ context "provding a custom remote repo" do
648
+ subject { GitReflow::Workflows::Core.refresh remote: 'upstream' }
649
+
650
+ it "updates the feature branch with default remote repo and base branch" do
651
+ expect(GitReflow).to receive(:update_feature_branch).with(remote: 'upstream', base: 'master')
652
+ subject
653
+ end
654
+ end
655
+
656
+ context "providing a custom base branch and remote repo" do
657
+ subject { GitReflow::Workflows::Core.refresh remote: 'upstream', base: 'development' }
658
+
659
+ it "updates the feature branch with default remote repo and base branch" do
660
+ expect(GitReflow).to receive(:update_feature_branch).with(remote: 'upstream', base: 'development')
661
+ subject
662
+ end
663
+ end
664
+ end
665
+ end