fourchette 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Guardfile +1 -1
- data/LICENSE.txt +1 -1
- data/README.md +10 -0
- data/Rakefile +3 -3
- data/bin/fourchette +5 -5
- data/fourchette.gemspec +18 -18
- data/lib/fourchette.rb +10 -11
- data/lib/fourchette/fork.rb +44 -19
- data/lib/fourchette/github.rb +29 -22
- data/lib/fourchette/heroku.rb +32 -28
- data/lib/fourchette/logger.rb +1 -1
- data/lib/fourchette/pgbackups.rb +18 -9
- data/lib/fourchette/pull_request.rb +4 -4
- data/lib/fourchette/tarball.rb +6 -5
- data/lib/fourchette/version.rb +1 -1
- data/lib/fourchette/web.rb +1 -1
- data/lib/fourchette/web/hooks.rb +3 -3
- data/lib/fourchette/web/tarball.rb +6 -3
- data/spec/lib/fourchette/fork_spec.rb +27 -22
- data/spec/lib/fourchette/github_spec.rb +44 -44
- data/spec/lib/fourchette/heroku_spec.rb +82 -49
- data/spec/lib/fourchette/logger_spec.rb +1 -1
- data/spec/lib/fourchette/pull_request_spec.rb +37 -12
- data/spec/lib/fourchette/tarball_spec.rb +24 -18
- data/spec/lib/web/hooks_spec.rb +10 -10
- data/spec/lib/web/tarball_spec.rb +14 -15
- data/spec/spec_helper.rb +1 -1
- data/spec/support/silent-logger.rb +2 -2
- data/spec/support/sinatra_helper.rb +1 -1
- data/templates/Gemfile +1 -1
- data/templates/Rakefile +1 -1
- data/templates/callbacks.rb +4 -4
- data/templates/config/puma.rb +1 -1
- metadata +5 -5
data/lib/fourchette/logger.rb
CHANGED
data/lib/fourchette/pgbackups.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'heroku/client/pgbackups'
|
2
2
|
class Fourchette::Pgbackups
|
3
3
|
include Fourchette::Logger
|
4
4
|
|
@@ -6,34 +6,43 @@ class Fourchette::Pgbackups
|
|
6
6
|
@heroku = Fourchette::Heroku.new
|
7
7
|
end
|
8
8
|
|
9
|
-
def copy
|
9
|
+
def copy(from, to)
|
10
10
|
ensure_pgbackups_is_present(from)
|
11
11
|
ensure_pgbackups_is_present(to)
|
12
12
|
|
13
13
|
from_url, from_name = pg_details_for(from)
|
14
14
|
to_url, to_name = pg_details_for(to)
|
15
15
|
|
16
|
-
@client = Heroku::Client::Pgbackups.new pgbackup_url(from)+'/api'
|
16
|
+
@client = Heroku::Client::Pgbackups.new pgbackup_url(from) + '/api'
|
17
17
|
@client.create_transfer(from_url, from_name, to_url, to_name)
|
18
18
|
end
|
19
19
|
|
20
20
|
private
|
21
|
-
|
22
|
-
|
21
|
+
|
22
|
+
def ensure_pgbackups_is_present(heroku_app_name)
|
23
|
+
unless existing_backups?
|
23
24
|
logger.info "Adding pgbackups to #{heroku_app_name}"
|
24
25
|
@heroku.client.addon.create(heroku_app_name, { plan: 'pgbackups' })
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
28
|
-
def
|
29
|
+
def existing_backups?
|
30
|
+
@heroku.client.addon.list(heroku_app_name).select do |addon|
|
31
|
+
addon['name'] == 'pgbackups'
|
32
|
+
end.any?
|
33
|
+
end
|
34
|
+
|
35
|
+
def pg_details_for(app_name)
|
29
36
|
@heroku.config_vars(app_name).each do |key, value|
|
30
|
-
|
37
|
+
if key.start_with?('HEROKU_POSTGRESQL_') && key.end_with?('_URL')
|
38
|
+
return [value, key]
|
39
|
+
end
|
31
40
|
end
|
32
41
|
end
|
33
42
|
|
34
|
-
def pgbackup_url
|
43
|
+
def pgbackup_url(app_name)
|
35
44
|
@heroku.config_vars(app_name).each do |k, v|
|
36
45
|
return v if k == 'PGBACKUPS_URL'
|
37
46
|
end
|
38
47
|
end
|
39
|
-
end
|
48
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class Fourchette::PullRequest
|
2
2
|
include SuckerPunch::Job
|
3
3
|
|
4
|
-
def perform
|
4
|
+
def perform(params)
|
5
5
|
return if qa_skip?(params)
|
6
6
|
|
7
7
|
callbacks = Fourchette::Callbacks.new(params)
|
@@ -25,8 +25,8 @@ class Fourchette::PullRequest
|
|
25
25
|
|
26
26
|
private
|
27
27
|
|
28
|
-
def qa_skip?
|
29
|
-
params['pull_request']['title']
|
28
|
+
def qa_skip?(params)
|
29
|
+
pr_title = params['pull_request']['title']
|
30
|
+
pr_title.downcase.include?('[qa skip]')
|
30
31
|
end
|
31
|
-
|
32
32
|
end
|
data/lib/fourchette/tarball.rb
CHANGED
@@ -12,20 +12,21 @@ class Fourchette::Tarball
|
|
12
12
|
end
|
13
13
|
|
14
14
|
private
|
15
|
+
|
15
16
|
def prepare_tarball(github_git_url, branch_name)
|
16
17
|
clone_path = "tmp/#{SecureRandom.uuid}"
|
17
18
|
clone(github_git_url, branch_name, clone_path)
|
18
19
|
tar(clone_path)
|
19
20
|
end
|
20
21
|
|
21
|
-
def clone(github_git_url,branch_name, clone_path)
|
22
|
-
logger.info
|
22
|
+
def clone(github_git_url, branch_name, clone_path)
|
23
|
+
logger.info 'Cloning repository...'
|
23
24
|
repo = Git.clone(github_git_url, clone_path, recursive: true)
|
24
25
|
repo.checkout(branch_name)
|
25
26
|
end
|
26
27
|
|
27
28
|
def tar(path)
|
28
|
-
logger.info
|
29
|
+
logger.info 'Preparing tarball...'
|
29
30
|
filepath = "#{path}/#{expiration_timestamp}.tar.gz"
|
30
31
|
system("tar -zcf #{filepath} -C #{path} .")
|
31
32
|
filepath
|
@@ -36,8 +37,8 @@ class Fourchette::Tarball
|
|
36
37
|
end
|
37
38
|
|
38
39
|
def tarball_to_url(filepath, github_repo)
|
39
|
-
logger.info
|
40
|
+
logger.info 'Tarball to URL as a service in progress...'
|
40
41
|
cleaned_path = filepath.gsub('tmp/', '').gsub('.tar.gz', '')
|
41
42
|
"#{ENV['FOURCHETTE_APP_URL']}/#{github_repo}/#{cleaned_path}"
|
42
43
|
end
|
43
|
-
end
|
44
|
+
end
|
data/lib/fourchette/version.rb
CHANGED
data/lib/fourchette/web.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
require_relative 'web/hooks'
|
2
|
-
require_relative 'web/tarball'
|
2
|
+
require_relative 'web/tarball'
|
data/lib/fourchette/web/hooks.rb
CHANGED
@@ -4,7 +4,10 @@ get '/:github_user/:github_repo/:uuid/:expiration_timestamp' do
|
|
4
4
|
'Oops...'
|
5
5
|
else
|
6
6
|
logger.info('Serving a tarball!')
|
7
|
-
filepath = Fourchette::Tarball.new.filepath(
|
8
|
-
|
7
|
+
filepath = Fourchette::Tarball.new.filepath(
|
8
|
+
params['uuid'],
|
9
|
+
params['expiration_timestamp']
|
10
|
+
)
|
11
|
+
send_file filepath, type: 'application/x-tgz'
|
9
12
|
end
|
10
|
-
end
|
13
|
+
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Fourchette::Fork do
|
4
4
|
subject { described_class.new(params) }
|
5
5
|
|
6
|
-
let(:params)
|
6
|
+
let(:params) do
|
7
7
|
{
|
8
8
|
'pull_request' => {
|
9
9
|
'number' => 1,
|
@@ -12,20 +12,21 @@ describe Fourchette::Fork do
|
|
12
12
|
}
|
13
13
|
}
|
14
14
|
}
|
15
|
-
|
15
|
+
end
|
16
16
|
let(:fork_name) { 'my-fork-pr-1' }
|
17
17
|
|
18
18
|
before do
|
19
|
-
stub_const(
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
stub_const(
|
20
|
+
'ENV',
|
21
|
+
'FOURCHETTE_HEROKU_APP_PREFIX' => 'my-fork',
|
22
|
+
'FOURCHETTE_HEROKU_APP_TO_FORK' => 'my-heroku-app-name'
|
23
|
+
)
|
23
24
|
end
|
24
25
|
|
25
26
|
describe '#create' do
|
26
27
|
it 'calls #update and #create_unless_exists' do
|
27
|
-
subject.
|
28
|
-
subject.
|
28
|
+
expect(subject).to receive(:create_unless_exists)
|
29
|
+
expect(subject).to receive(:update)
|
29
30
|
subject.create
|
30
31
|
end
|
31
32
|
end
|
@@ -37,43 +38,47 @@ describe Fourchette::Fork do
|
|
37
38
|
|
38
39
|
context 'app does NOT exists' do
|
39
40
|
before do
|
40
|
-
Fourchette::Heroku.
|
41
|
+
allow_any_instance_of(Fourchette::Heroku).to receive(:app_exists?).and_return(false)
|
41
42
|
end
|
42
43
|
|
43
44
|
it 'calls the fork creation' do
|
44
|
-
subject.
|
45
|
-
Fourchette::Heroku.
|
45
|
+
allow(subject).to receive(:post_fork_url)
|
46
|
+
expect_any_instance_of(Fourchette::Heroku).to receive(:fork)
|
47
|
+
.with('my-heroku-app-name', fork_name)
|
46
48
|
end
|
47
49
|
|
48
50
|
it 'post the URL to the fork on the GitHub PR' do
|
49
|
-
Fourchette::Heroku.
|
50
|
-
Fourchette::Heroku.
|
51
|
-
|
51
|
+
allow_any_instance_of(Fourchette::Heroku).to receive(:fork)
|
52
|
+
allow_any_instance_of(Fourchette::Heroku).to receive_message_chain(:client, :app, :info)
|
53
|
+
.and_return('web_url' => 'rainforestqa.com')
|
54
|
+
expect_any_instance_of(Fourchette::GitHub).to receive(:comment_pr)
|
55
|
+
.with(1, 'Test URL: rainforestqa.com')
|
52
56
|
end
|
53
57
|
end
|
54
58
|
|
55
59
|
context 'app DOES exists' do
|
56
60
|
before do
|
57
|
-
Fourchette::Heroku.
|
61
|
+
allow_any_instance_of(Fourchette::Heroku).to receive(:app_exists?).and_return(true)
|
58
62
|
end
|
59
63
|
|
60
64
|
it 'does nothing' do
|
61
|
-
Fourchette::GitHub.
|
62
|
-
Fourchette::Heroku.
|
65
|
+
expect_any_instance_of(Fourchette::GitHub).not_to receive(:comment_pr)
|
66
|
+
expect_any_instance_of(Fourchette::Heroku).not_to receive(:fork)
|
63
67
|
end
|
64
68
|
end
|
65
69
|
end
|
66
70
|
|
67
71
|
describe '#delete' do
|
68
72
|
it 'calls deletes the fork' do
|
69
|
-
Fourchette::GitHub.
|
70
|
-
Fourchette::Heroku.
|
73
|
+
allow_any_instance_of(Fourchette::GitHub).to receive(:comment_pr)
|
74
|
+
expect_any_instance_of(Fourchette::Heroku).to receive(:delete).with(fork_name)
|
71
75
|
subject.delete
|
72
76
|
end
|
73
77
|
|
74
78
|
it 'comments on the GitHub PR' do
|
75
|
-
Fourchette::Heroku.
|
76
|
-
Fourchette::GitHub.
|
79
|
+
allow_any_instance_of(Fourchette::Heroku).to receive(:delete)
|
80
|
+
expect_any_instance_of(Fourchette::GitHub).to receive(:comment_pr)
|
81
|
+
.with(1, 'Test app deleted!')
|
77
82
|
subject.delete
|
78
83
|
end
|
79
84
|
end
|
@@ -89,4 +94,4 @@ describe Fourchette::Fork do
|
|
89
94
|
describe '#pr_number' do
|
90
95
|
it { expect(subject.pr_number).to eq 1 }
|
91
96
|
end
|
92
|
-
end
|
97
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Fourchette::GitHub do
|
4
4
|
subject { described_class.new }
|
@@ -6,122 +6,122 @@ describe Fourchette::GitHub do
|
|
6
6
|
let(:fake_hooks) { [] }
|
7
7
|
|
8
8
|
let(:fake_hook) do
|
9
|
-
hook = double(
|
10
|
-
hook.
|
11
|
-
hook.
|
9
|
+
hook = double('hook')
|
10
|
+
allow(hook).to receive(:config).and_return(nil)
|
11
|
+
allow(hook).to receive(:id).and_return(123)
|
12
12
|
hook
|
13
13
|
end
|
14
14
|
|
15
15
|
let(:fake_fourchette_hook) do
|
16
|
-
fake_hook.config.
|
16
|
+
allow(fake_hook.config).to receive(:fourchette_env).and_return('something')
|
17
17
|
fake_hook
|
18
18
|
end
|
19
19
|
|
20
20
|
let(:fake_enabled_fourchette_hook) do
|
21
|
-
fake_fourchette_hook.
|
21
|
+
allow(fake_fourchette_hook).to receive(:active).and_return(true)
|
22
22
|
fake_fourchette_hook
|
23
23
|
end
|
24
24
|
|
25
25
|
let(:fake_disabled_fourchette_hook) do
|
26
|
-
fake_fourchette_hook.
|
26
|
+
allow(fake_fourchette_hook).to receive(:active).and_return(false)
|
27
27
|
fake_fourchette_hook
|
28
28
|
end
|
29
29
|
|
30
30
|
before do
|
31
31
|
allow_message_expectations_on_nil
|
32
|
-
subject.
|
33
|
-
Octokit::Client.
|
32
|
+
allow(subject).to receive(:hooks).and_return(fake_hooks)
|
33
|
+
allow_any_instance_of(Octokit::Client).to receive(:edit_hook)
|
34
34
|
end
|
35
35
|
|
36
|
-
describe
|
37
|
-
context
|
36
|
+
describe '#enable_hook' do
|
37
|
+
context 'when there is alerady a Fourchette hook' do
|
38
38
|
|
39
|
-
context
|
39
|
+
context 'when the hook was enabled' do
|
40
40
|
let(:fake_hooks) { [fake_enabled_fourchette_hook] }
|
41
41
|
|
42
|
-
it
|
43
|
-
Octokit::Client.
|
42
|
+
it 'does NOT enable the hook' do
|
43
|
+
expect_any_instance_of(Octokit::Client).not_to receive(:edit_hook)
|
44
44
|
|
45
45
|
subject.enable_hook
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
context
|
49
|
+
context 'when the hook was disabled' do
|
50
50
|
let(:fake_hooks) { [fake_disabled_fourchette_hook] }
|
51
51
|
|
52
|
-
it
|
53
|
-
Octokit::Client.
|
52
|
+
it 'enables the hook' do
|
53
|
+
expect_any_instance_of(Octokit::Client).to receive(:edit_hook)
|
54
54
|
|
55
55
|
subject.enable_hook
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
context
|
61
|
-
it
|
62
|
-
Octokit::Client.
|
60
|
+
context 'when there is no Fourchette hook yet' do
|
61
|
+
it 'adds a hook' do
|
62
|
+
expect_any_instance_of(Octokit::Client).to receive(:create_hook)
|
63
63
|
|
64
64
|
subject.enable_hook
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
describe
|
70
|
-
context
|
69
|
+
describe '#disable_hook' do
|
70
|
+
context 'where there is an active Fourchette hook' do
|
71
71
|
let(:fake_hooks) { [fake_enabled_fourchette_hook] }
|
72
72
|
|
73
|
-
it
|
74
|
-
Octokit::Client.
|
73
|
+
it 'disables the hook' do
|
74
|
+
expect_any_instance_of(Octokit::Client).to receive(:edit_hook)
|
75
75
|
|
76
76
|
subject.disable_hook
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
-
context
|
80
|
+
context 'when there is a disabled Fourchette hook' do
|
81
81
|
let(:fake_hooks) { [fake_disabled_fourchette_hook] }
|
82
|
-
it
|
83
|
-
subject.
|
82
|
+
it 'does not try to disable a hook' do
|
83
|
+
expect(subject).not_to receive(:disable)
|
84
84
|
subject.disable_hook
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
-
context
|
89
|
-
it
|
90
|
-
subject.
|
88
|
+
context 'when there is no Fourchette hook' do
|
89
|
+
it 'does not try to disable a hook' do
|
90
|
+
expect(subject).not_to receive(:disable)
|
91
91
|
subject.disable_hook
|
92
92
|
end
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
describe
|
96
|
+
describe '#update_hook' do
|
97
97
|
let(:fake_hooks) { [fake_enabled_fourchette_hook] }
|
98
98
|
|
99
|
-
it
|
100
|
-
subject
|
101
|
-
.
|
99
|
+
it 'calls toggle_active_state_to' do
|
100
|
+
expect(subject)
|
101
|
+
.to receive(:toggle_active_state_to)
|
102
102
|
subject.update_hook
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
|
-
describe
|
107
|
-
it
|
108
|
-
subject.
|
109
|
-
Octokit::Client.
|
106
|
+
describe '#delete_hook' do
|
107
|
+
it 'deletes the hook on GitHub' do
|
108
|
+
allow(subject).to receive(:fourchette_hook).and_return(fake_hook)
|
109
|
+
expect_any_instance_of(Octokit::Client).to receive(:remove_hook)
|
110
110
|
|
111
111
|
subject.delete_hook
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
|
-
describe
|
115
|
+
describe '#comment_pr' do
|
116
116
|
before do
|
117
|
-
stub_const(
|
117
|
+
stub_const('ENV', 'FOURCHETTE_GITHUB_PROJECT' => 'my-project')
|
118
118
|
end
|
119
119
|
|
120
|
-
it
|
121
|
-
Octokit::Client
|
122
|
-
.
|
120
|
+
it 'adds a comment' do
|
121
|
+
expect_any_instance_of(Octokit::Client)
|
122
|
+
.to receive(:add_comment).with('my-project', 1, 'yo!')
|
123
123
|
|
124
|
-
subject.comment_pr(1,
|
124
|
+
subject.comment_pr(1, 'yo!')
|
125
125
|
end
|
126
126
|
end
|
127
127
|
end
|
@@ -14,14 +14,16 @@ describe Fourchette::Heroku do
|
|
14
14
|
before do
|
15
15
|
client = double('client')
|
16
16
|
client_app = double('client')
|
17
|
-
client_app.
|
18
|
-
client.
|
17
|
+
allow(client_app).to receive(:list).and_return(app_list)
|
18
|
+
allow(client).to receive(:app).and_return(client_app)
|
19
19
|
config_var = double('config_var')
|
20
|
-
client.
|
20
|
+
allow(client).to receive(:config_var).and_return(config_var)
|
21
21
|
|
22
|
-
client.app.
|
22
|
+
allow(client.app).to receive(:info).and_return(
|
23
|
+
'git_url' => 'git@heroku.com/something.git'
|
24
|
+
)
|
23
25
|
|
24
|
-
heroku.
|
26
|
+
allow(heroku).to receive(:client).and_return(client)
|
25
27
|
end
|
26
28
|
|
27
29
|
describe '#app_exists?' do
|
@@ -32,42 +34,46 @@ describe Fourchette::Heroku do
|
|
32
34
|
|
33
35
|
describe '#fork' do
|
34
36
|
before do
|
35
|
-
heroku.
|
36
|
-
heroku.
|
37
|
-
heroku.
|
38
|
-
heroku.
|
39
|
-
heroku.
|
37
|
+
allow(heroku).to receive(:create_app)
|
38
|
+
allow(heroku).to receive(:copy_config)
|
39
|
+
allow(heroku).to receive(:copy_add_ons)
|
40
|
+
allow(heroku).to receive(:copy_pg)
|
41
|
+
allow(heroku).to receive(:copy_rack_and_rails_env_again)
|
40
42
|
end
|
41
43
|
|
42
|
-
|
44
|
+
%w(
|
45
|
+
create_app copy_config copy_add_ons copy_pg copy_rack_and_rails_env_again
|
46
|
+
).each do |method_name|
|
43
47
|
it "calls `#{method_name}'" do
|
44
|
-
heroku.
|
48
|
+
expect(heroku).to receive(method_name)
|
45
49
|
heroku.fork(from_app_name, to_app_name)
|
46
50
|
end
|
47
51
|
end
|
48
52
|
end
|
49
53
|
|
50
54
|
describe '#git_url' do
|
51
|
-
it
|
55
|
+
it 'returns the correct git URL' do
|
56
|
+
expect(heroku.git_url(to_app_name)).to eq 'git@heroku.com/something.git'
|
57
|
+
end
|
52
58
|
end
|
53
59
|
|
54
60
|
describe '#delete' do
|
55
61
|
it 'calls delete on the Heroku client' do
|
56
|
-
heroku.client.app.
|
62
|
+
expect(heroku.client.app).to receive(:delete).with(to_app_name)
|
57
63
|
heroku.delete(to_app_name)
|
58
64
|
end
|
59
65
|
end
|
60
66
|
|
61
67
|
describe '#config_vars' do
|
62
68
|
it 'calls config_var.info on the Heroku client' do
|
63
|
-
heroku.client.config_var.
|
69
|
+
expect(heroku.client.config_var).to receive(:info).with(from_app_name)
|
64
70
|
heroku.config_vars(from_app_name)
|
65
71
|
end
|
66
72
|
end
|
67
73
|
|
68
74
|
describe '#create_app' do
|
69
75
|
it 'calls app.create on the Heroku client' do
|
70
|
-
heroku.client.app.
|
76
|
+
expect(heroku.client.app).to receive(:create).with(name: to_app_name)
|
71
77
|
heroku.create_app(to_app_name)
|
72
78
|
end
|
73
79
|
end
|
@@ -80,37 +86,41 @@ describe Fourchette::Heroku do
|
|
80
86
|
'DATABASE_URL' => 'FAIL@POSTGRES/DB'
|
81
87
|
}
|
82
88
|
end
|
83
|
-
let(:cleaned_vars) { { 'WHATEVER' => 'ok'} }
|
89
|
+
let(:cleaned_vars) { { 'WHATEVER' => 'ok' } }
|
84
90
|
|
85
91
|
it 'calls #config_vars' do
|
86
|
-
heroku.client.config_var.
|
87
|
-
heroku.
|
92
|
+
allow(heroku.client.config_var).to receive(:update)
|
93
|
+
expect(heroku).to receive(:config_vars).with(from_app_name).and_return(vars)
|
88
94
|
heroku.copy_config(from_app_name, to_app_name)
|
89
95
|
end
|
90
96
|
|
91
97
|
it 'updates config vars without postgres URLs' do
|
92
|
-
heroku.client.config_var.
|
93
|
-
|
98
|
+
expect(heroku.client.config_var).to receive(:update)
|
99
|
+
.with(to_app_name, cleaned_vars)
|
100
|
+
allow(heroku).to receive(:config_vars).and_return(vars)
|
94
101
|
heroku.copy_config('from', to_app_name)
|
95
102
|
end
|
96
103
|
end
|
97
104
|
|
98
105
|
describe '#copy_add_ons' do
|
99
|
-
let(:addon_list) { [
|
106
|
+
let(:addon_list) { [{ 'plan' => { 'name' => 'redistogo' } }] }
|
100
107
|
|
101
108
|
before do
|
102
|
-
heroku.client.
|
103
|
-
heroku.client.addon.
|
104
|
-
heroku.client.addon.
|
109
|
+
allow(heroku.client).to receive(:addon).and_return(double('addon'))
|
110
|
+
allow(heroku.client.addon).to receive(:create)
|
111
|
+
allow(heroku.client.addon).to receive(:list).and_return(addon_list)
|
105
112
|
end
|
106
113
|
|
107
114
|
it 'gets the addon list' do
|
108
|
-
heroku.client.addon.
|
115
|
+
expect(heroku.client.addon).to receive(:list).with(from_app_name)
|
116
|
+
.and_return(addon_list)
|
109
117
|
heroku.copy_add_ons(from_app_name, to_app_name)
|
110
118
|
end
|
111
119
|
|
112
120
|
it 'creates addons' do
|
113
|
-
heroku.client.addon.
|
121
|
+
expect(heroku.client.addon).to receive(:create).with(
|
122
|
+
to_app_name, plan: 'redistogo'
|
123
|
+
)
|
114
124
|
heroku.copy_add_ons(from_app_name, to_app_name)
|
115
125
|
end
|
116
126
|
end
|
@@ -118,16 +128,32 @@ describe Fourchette::Heroku do
|
|
118
128
|
describe '#copy_pg' do
|
119
129
|
|
120
130
|
before do
|
121
|
-
heroku.client.
|
122
|
-
heroku.client.addon.
|
131
|
+
allow(heroku.client).to receive(:addon).and_return(double('addon'))
|
132
|
+
allow(heroku.client.addon).to receive(:list).and_return(addon_list)
|
123
133
|
end
|
124
134
|
|
125
135
|
context 'when a heroku-postgresql addon is enabled' do
|
126
|
-
let(:addon_list) { [{ 'addon_service' => { 'name' =>
|
136
|
+
let(:addon_list) { [{ 'addon_service' => { 'name' => addon_name } }] }
|
137
|
+
|
138
|
+
shared_examples 'app with pg' do
|
139
|
+
it 'calls Fourchette::Pgbackups#copy' do
|
140
|
+
expect_any_instance_of(Fourchette::Pgbackups).to receive(:copy).with(
|
141
|
+
from_app_name, to_app_name
|
142
|
+
)
|
143
|
+
heroku.copy_pg(from_app_name, to_app_name)
|
144
|
+
end
|
145
|
+
end
|
127
146
|
|
128
|
-
|
129
|
-
|
130
|
-
|
147
|
+
context "when the addon name is 'Heroku Postgres'" do
|
148
|
+
let(:addon_name) { 'Heroku Postgres' }
|
149
|
+
|
150
|
+
it_behaves_like 'app with pg'
|
151
|
+
end
|
152
|
+
|
153
|
+
context "when the addon name is 'heroku-postgresql'" do
|
154
|
+
let(:addon_name) { 'heroku-postgresql' }
|
155
|
+
|
156
|
+
it_behaves_like 'app with pg'
|
131
157
|
end
|
132
158
|
end
|
133
159
|
|
@@ -135,51 +161,58 @@ describe Fourchette::Heroku do
|
|
135
161
|
let(:addon_list) { [{ 'addon_service' => { 'name' => 'redistogo' } }] }
|
136
162
|
|
137
163
|
it 'does not call Fourchette::Pgbackups#copy' do
|
138
|
-
# Had to work around lack of support for any_instance and
|
139
|
-
#
|
164
|
+
# Had to work around lack of support for any_instance and
|
165
|
+
# should_not_receive
|
166
|
+
# See https://github.com/rspec/rspec-mocks/issues/164 for more details
|
140
167
|
count = 0
|
141
|
-
Fourchette::Pgbackups.
|
142
|
-
|
143
|
-
|
168
|
+
allow_any_instance_of(Fourchette::Pgbackups).to receive(:copy) do |_from_app_name, _to_app_name|
|
169
|
+
count += 1
|
170
|
+
end
|
144
171
|
heroku.copy_pg(from_app_name, to_app_name)
|
145
|
-
count.
|
172
|
+
expect(count).to eq(0)
|
146
173
|
end
|
147
174
|
end
|
148
175
|
end
|
149
176
|
|
150
|
-
describe '#
|
177
|
+
describe '#copy_rack_and_rails_env_again' do
|
151
178
|
context 'with RACK_ENV or RAILS_ENV setup' do
|
152
179
|
before do
|
153
|
-
heroku.
|
180
|
+
allow(heroku).to receive(:get_original_env).and_return('RACK_ENV' => 'qa')
|
154
181
|
end
|
155
182
|
|
156
183
|
it 'updates the config vars' do
|
157
|
-
heroku.client.config_var.
|
158
|
-
|
184
|
+
expect(heroku.client.config_var).to receive(:update).with(
|
185
|
+
to_app_name, 'RACK_ENV' => 'qa'
|
186
|
+
)
|
187
|
+
heroku.copy_rack_and_rails_env_again(from_app_name, to_app_name)
|
159
188
|
end
|
160
189
|
end
|
161
190
|
|
162
191
|
context 'with NO env setup' do
|
163
192
|
before do
|
164
|
-
heroku.
|
193
|
+
allow(heroku).to receive(:get_original_env).and_return({})
|
165
194
|
end
|
166
195
|
|
167
196
|
it 'does not update config vars' do
|
168
|
-
heroku.client.config_var.
|
169
|
-
heroku.
|
197
|
+
expect(heroku.client.config_var).not_to receive(:update)
|
198
|
+
heroku.copy_rack_and_rails_env_again(from_app_name, to_app_name)
|
170
199
|
end
|
171
200
|
end
|
172
201
|
end
|
173
202
|
|
174
203
|
describe '#get_original_env' do
|
175
204
|
before do
|
176
|
-
stub_cong_var = {
|
177
|
-
|
205
|
+
stub_cong_var = {
|
206
|
+
'RACK_ENV' => 'qa',
|
207
|
+
'RAILS_ENV' => 'staging',
|
208
|
+
'DATABASE_URL' => 'postgres://....'
|
209
|
+
}
|
210
|
+
allow(heroku).to receive_message_chain(:client, :config_var, :info).and_return(stub_cong_var)
|
178
211
|
end
|
179
212
|
|
180
213
|
it 'returns the set env vars' do
|
181
214
|
return_value = heroku.get_original_env(from_app_name)
|
182
|
-
expect(return_value).to eq(
|
215
|
+
expect(return_value).to eq('RACK_ENV' => 'qa', 'RAILS_ENV' => 'staging')
|
183
216
|
end
|
184
217
|
end
|
185
218
|
end
|