vagrant/test/unit/plugins/pushes/heroku/push_test.rb

325 lines
8.1 KiB
Ruby

require_relative "../../../base"
require Vagrant.source_root.join("plugins/pushes/heroku/push")
describe VagrantPlugins::HerokuPush::Push do
include_context "unit"
before(:all) do
I18n.load_path << Vagrant.source_root.join("plugins/pushes/heroku/locales/en.yml")
I18n.reload!
end
let(:env) { isolated_environment }
let(:config) do
double("config",
app: "bacon",
dir: "lib",
git_bin: "git",
remote: "heroku",
)
end
subject { described_class.new(env, config) }
describe "#push" do
let(:branch) { "master" }
let(:root_path) { "/handy/dandy" }
let(:dir) { "#{root_path}/#{config.dir}" }
before do
allow(subject).to receive(:git_branch)
.and_return(branch)
allow(subject).to receive(:verify_git_bin!)
allow(subject).to receive(:verify_git_repo!)
allow(subject).to receive(:has_git_remote?)
allow(subject).to receive(:add_heroku_git_remote)
allow(subject).to receive(:git_push_heroku)
allow(subject).to receive(:execute!)
allow(env).to receive(:root_path)
.and_return(root_path)
end
it "verifies the git bin is present" do
expect(subject).to receive(:verify_git_bin!)
.with(config.git_bin)
subject.push
end
it "verifies the directory is a git repo" do
expect(subject).to receive(:verify_git_repo!)
.with(dir)
subject.push
end
context "when the heroku remote exists" do
before do
allow(subject).to receive(:has_git_remote?)
.and_return(true)
end
it "does not add the heroku remote" do
expect(subject).to_not receive(:add_heroku_git_remote)
subject.push
end
end
context "when the heroku remote does not exist" do
before do
allow(subject).to receive(:has_git_remote?)
.and_return(false)
end
it "adds the heroku remote" do
expect(subject).to receive(:add_heroku_git_remote)
.with(config.remote, config.app, dir)
subject.push
end
end
it "pushes to heroku" do
expect(subject).to receive(:git_push_heroku)
.with(config.remote, branch, dir)
subject.push
end
end
describe "#verify_git_bin!" do
context "when git does not exist" do
before do
allow(Vagrant::Util::Which).to receive(:which)
.with("git")
.and_return(nil)
end
it "raises an exception" do
expect {
subject.verify_git_bin!("git")
} .to raise_error(VagrantPlugins::HerokuPush::Errors::GitNotFound) { |error|
expect(error.message).to eq(I18n.t("heroku_push.errors.git_not_found",
bin: "git",
))
}
end
end
context "when git exists" do
before do
allow(Vagrant::Util::Which).to receive(:which)
.with("git")
.and_return("git")
end
it "does not raise an exception" do
expect { subject.verify_git_bin!("git") }.to_not raise_error
end
end
end
describe "#verify_git_repo!" do
context "when the path is a git repo" do
before do
allow(File).to receive(:directory?)
.with("/repo/path/.git")
.and_return(false)
end
it "raises an exception" do
expect {
subject.verify_git_repo!("/repo/path")
} .to raise_error(VagrantPlugins::HerokuPush::Errors::NotAGitRepo) { |error|
expect(error.message).to eq(I18n.t("heroku_push.errors.not_a_git_repo",
path: "/repo/path",
))
}
end
end
context "when the path is not a git repo" do
before do
allow(File).to receive(:directory?)
.with("/repo/path/.git")
.and_return(true)
end
it "does not raise an exception" do
expect { subject.verify_git_repo!("/repo/path") }.to_not raise_error
end
end
end
describe "#git_push_heroku" do
let(:dir) { "." }
before { allow(subject).to receive(:execute!) }
it "executes the proper command" do
expect(subject).to receive(:execute!)
.with("git",
"--git-dir", "#{dir}/.git",
"--work-tree", dir,
"push", "bacon", "hamlet:master",
)
subject.git_push_heroku("bacon", "hamlet", dir)
end
end
describe "#has_git_remote?" do
let(:dir) { "." }
let(:process) do
double("process",
stdout: "origin\r\nbacon\nhello"
)
end
before do
allow(subject).to receive(:execute!)
.and_return(process)
end
it "executes the proper command" do
expect(subject).to receive(:execute!)
.with("git",
"--git-dir", "#{dir}/.git",
"--work-tree", dir,
"remote",
)
subject.has_git_remote?("bacon", dir)
end
it "returns true when the remote exists" do
expect(subject.has_git_remote?("origin", dir)).to be(true)
expect(subject.has_git_remote?("bacon", dir)).to be(true)
expect(subject.has_git_remote?("hello", dir)).to be(true)
end
it "returns false when the remote does not exist" do
expect(subject.has_git_remote?("nope", dir)).to be(false)
end
end
describe "#add_heroku_git_remote" do
let(:dir) { "." }
before do
allow(subject).to receive(:execute!)
allow(subject).to receive(:heroku_git_url)
.with("app")
.and_return("HEROKU_URL")
end
it "executes the proper command" do
expect(subject).to receive(:execute!)
.with("git",
"--git-dir", "#{dir}/.git",
"--work-tree", dir,
"remote", "add", "bacon", "HEROKU_URL",
)
subject.add_heroku_git_remote("bacon", "app", dir)
end
end
describe "#interpret_app" do
it "returns the basename of the directory" do
expect(subject.interpret_app("/foo/bar/blitz")).to eq("blitz")
end
end
describe "#heroku_git_url" do
it "returns the proper string" do
expect(subject.heroku_git_url("bacon"))
.to eq("git@heroku.com:bacon.git")
end
end
describe "#git_dir" do
it "returns the .git directory for the path" do
expect(subject.git_dir("/path")).to eq("/path/.git")
end
end
describe "#git_branch" do
let(:stdout) { "" }
let(:process) { double("process", stdout: stdout) }
before do
allow(subject).to receive(:execute!)
.and_return(process)
end
let(:branch) { subject.git_branch("/path") }
context "when the branch is prefixed with a star" do
let(:stdout) { "*bacon" }
it "returns the correct name" do
expect(branch).to eq("bacon")
end
end
context "when the branch is prefixed with a star space" do
let(:stdout) { "* bacon" }
it "returns the correct name" do
expect(branch).to eq("bacon")
end
end
context "when the branch is not prefixed" do
let(:stdout) { "bacon" }
it "returns the correct name" do
expect(branch).to eq("bacon")
end
end
end
describe "#execute!" do
let(:exit_code) { 0 }
let(:stdout) { "This is the output" }
let(:stderr) { "This is the errput" }
let(:process) do
double("process",
exit_code: exit_code,
stdout: stdout,
stderr: stderr,
)
end
before do
allow(Vagrant::Util::Subprocess).to receive(:execute)
.and_return(process)
end
it "creates a subprocess" do
expect(Vagrant::Util::Subprocess).to receive(:execute)
expect { subject.execute! }.to_not raise_error
end
it "returns the resulting process" do
expect(subject.execute!).to be(process)
end
context "when the exit code is non-zero" do
let(:exit_code) { 1 }
it "raises an exception" do
klass = VagrantPlugins::HerokuPush::Errors::CommandFailed
cmd = ["foo", "bar"]
expect { subject.execute!(*cmd) }.to raise_error(klass) { |error|
expect(error.message).to eq(I18n.t("heroku_push.errors.command_failed",
cmd: cmd.join(" "),
stdout: stdout,
stderr: stderr,
))
}
end
end
end
end