
In a number of Cask specs, the value of the `homepage` stanza is currently set to https://example.com. As of 2018-11-28, the TLS certificate served by example.com seems to be expired, possibly due to an oversight on ICANN’s side. While the certificate is certainly going to be renewed soon, it would be desirable for Homebrew’s test result to be less dependent on ICANN’s actions. This commit changes the homepages of all test Casks to http://brew.sh, whose domain and TLS certificate are both controlled by Homebrew.
245 lines
7.2 KiB
Ruby
245 lines
7.2 KiB
Ruby
describe Cask::Artifact::App, :cask do
|
|
let(:cask) { Cask::CaskLoader.load(cask_path("local-caffeine")) }
|
|
let(:command) { SystemCommand }
|
|
let(:force) { false }
|
|
let(:app) { cask.artifacts.find { |a| a.is_a?(described_class) } }
|
|
|
|
let(:source_path) { cask.staged_path.join("Caffeine.app") }
|
|
let(:target_path) { Cask::Config.global.appdir.join("Caffeine.app") }
|
|
|
|
let(:install_phase) { app.install_phase(command: command, force: force) }
|
|
let(:uninstall_phase) { app.uninstall_phase(command: command, force: force) }
|
|
|
|
before do
|
|
InstallHelper.install_without_artifacts(cask)
|
|
end
|
|
|
|
describe "install_phase" do
|
|
it "installs the given app using the proper target directory" do
|
|
install_phase
|
|
|
|
expect(target_path).to be_a_directory
|
|
expect(source_path).not_to exist
|
|
end
|
|
|
|
describe "when app is in a subdirectory" do
|
|
let(:cask) {
|
|
Cask::Cask.new("subdir") do
|
|
url "file://#{TEST_FIXTURE_DIR}/cask/caffeine.zip"
|
|
homepage "https://brew.sh/local-caffeine"
|
|
version "1.2.3"
|
|
sha256 "67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94"
|
|
app "subdir/Caffeine.app"
|
|
end
|
|
}
|
|
|
|
it "installs the given app using the proper target directory" do
|
|
appsubdir = cask.staged_path.join("subdir").tap(&:mkpath)
|
|
FileUtils.mv(source_path, appsubdir)
|
|
|
|
install_phase
|
|
|
|
expect(target_path).to be_a_directory
|
|
expect(appsubdir.join("Caffeine.app")).not_to exist
|
|
end
|
|
end
|
|
|
|
it "only uses apps when they are specified" do
|
|
staged_app_copy = source_path.sub("Caffeine.app", "Caffeine Deluxe.app")
|
|
FileUtils.cp_r source_path, staged_app_copy
|
|
|
|
install_phase
|
|
|
|
expect(target_path).to be_a_directory
|
|
expect(source_path).not_to exist
|
|
|
|
expect(Cask::Config.global.appdir.join("Caffeine Deluxe.app")).not_to exist
|
|
expect(cask.staged_path.join("Caffeine Deluxe.app")).to exist
|
|
end
|
|
|
|
describe "when the target already exists" do
|
|
before do
|
|
target_path.mkpath
|
|
end
|
|
|
|
it "avoids clobbering an existing app" do
|
|
expect { install_phase }.to raise_error(
|
|
Cask::CaskError,
|
|
"It seems there is already an App at '#{target_path}'.",
|
|
)
|
|
|
|
expect(source_path).to be_a_directory
|
|
expect(target_path).to be_a_directory
|
|
expect(File.identical?(source_path, target_path)).to be false
|
|
|
|
contents_path = target_path.join("Contents/Info.plist")
|
|
expect(contents_path).not_to exist
|
|
end
|
|
|
|
describe "given the force option" do
|
|
let(:force) { true }
|
|
|
|
before do
|
|
allow(User).to receive(:current).and_return(User.new("fake_user"))
|
|
end
|
|
|
|
describe "target is both writable and user-owned" do
|
|
it "overwrites the existing app" do
|
|
stdout = <<~EOS
|
|
==> Removing App '#{target_path}'.
|
|
==> Moving App 'Caffeine.app' to '#{target_path}'.
|
|
EOS
|
|
|
|
stderr = <<~EOS
|
|
Warning: It seems there is already an App at '#{target_path}'; overwriting.
|
|
EOS
|
|
|
|
expect { install_phase }
|
|
.to output(stdout).to_stdout
|
|
.and output(stderr).to_stderr
|
|
|
|
expect(source_path).not_to exist
|
|
expect(target_path).to be_a_directory
|
|
|
|
contents_path = target_path.join("Contents/Info.plist")
|
|
expect(contents_path).to exist
|
|
end
|
|
end
|
|
|
|
describe "target is user-owned but contains read-only files" do
|
|
before do
|
|
FileUtils.touch "#{target_path}/foo"
|
|
FileUtils.chmod 0555, target_path
|
|
end
|
|
|
|
after do
|
|
FileUtils.chmod 0755, target_path
|
|
end
|
|
|
|
it "overwrites the existing app" do
|
|
expect(command).to receive(:run).with(
|
|
"/bin/chmod", args: [
|
|
"-R", "--", "u+rwx", target_path
|
|
], must_succeed: false
|
|
).and_call_original
|
|
expect(command).to receive(:run).with(
|
|
"/bin/chmod", args: [
|
|
"-R", "-N", target_path
|
|
], must_succeed: false
|
|
).and_call_original
|
|
expect(command).to receive(:run).with(
|
|
"/usr/bin/chflags", args: [
|
|
"-R", "--", "000", target_path
|
|
], must_succeed: false
|
|
).and_call_original
|
|
|
|
stdout = <<~EOS
|
|
==> Removing App '#{target_path}'.
|
|
==> Moving App 'Caffeine.app' to '#{target_path}'.
|
|
EOS
|
|
|
|
stderr = <<~EOS
|
|
Warning: It seems there is already an App at '#{target_path}'; overwriting.
|
|
EOS
|
|
|
|
expect { install_phase }
|
|
.to output(stdout).to_stdout
|
|
.and output(stderr).to_stderr
|
|
|
|
expect(source_path).not_to exist
|
|
expect(target_path).to be_a_directory
|
|
|
|
contents_path = target_path.join("Contents/Info.plist")
|
|
expect(contents_path).to exist
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "when the target is a broken symlink" do
|
|
let(:deleted_path) { cask.staged_path.join("Deleted.app") }
|
|
|
|
before do
|
|
deleted_path.mkdir
|
|
File.symlink(deleted_path, target_path)
|
|
deleted_path.rmdir
|
|
end
|
|
|
|
it "leaves the target alone" do
|
|
expect { install_phase }.to raise_error(
|
|
Cask::CaskError, "It seems there is already an App at '#{target_path}'."
|
|
)
|
|
expect(target_path).to be_a_symlink
|
|
end
|
|
|
|
describe "given the force option" do
|
|
let(:force) { true }
|
|
|
|
it "overwrites the existing app" do
|
|
stdout = <<~EOS
|
|
==> Removing App '#{target_path}'.
|
|
==> Moving App 'Caffeine.app' to '#{target_path}'.
|
|
EOS
|
|
|
|
stderr = <<~EOS
|
|
Warning: It seems there is already an App at '#{target_path}'; overwriting.
|
|
EOS
|
|
|
|
expect { install_phase }
|
|
.to output(stdout).to_stdout
|
|
.and output(stderr).to_stderr
|
|
|
|
expect(source_path).not_to exist
|
|
expect(target_path).to be_a_directory
|
|
|
|
contents_path = target_path.join("Contents/Info.plist")
|
|
expect(contents_path).to exist
|
|
end
|
|
end
|
|
end
|
|
|
|
it "gives a warning if the source doesn't exist" do
|
|
source_path.rmtree
|
|
|
|
message = "It seems the App source '#{source_path}' is not there."
|
|
|
|
expect { install_phase }.to raise_error(Cask::CaskError, message)
|
|
end
|
|
end
|
|
|
|
describe "uninstall_phase" do
|
|
it "deletes managed apps" do
|
|
install_phase
|
|
|
|
expect(target_path).to exist
|
|
|
|
uninstall_phase
|
|
|
|
expect(target_path).not_to exist
|
|
end
|
|
end
|
|
|
|
describe "summary" do
|
|
let(:description) { app.class.english_description }
|
|
let(:contents) { app.summarize_installed }
|
|
|
|
it "returns the correct english_description" do
|
|
expect(description).to eq("Apps")
|
|
end
|
|
|
|
describe "app is correctly installed" do
|
|
it "returns the path to the app" do
|
|
install_phase
|
|
|
|
expect(contents).to eq("#{target_path} (#{target_path.abv})")
|
|
end
|
|
end
|
|
|
|
describe "app is missing" do
|
|
it "returns a warning and the supposed path to the app" do
|
|
expect(contents).to match(/.*Missing App.*: #{target_path}/)
|
|
end
|
|
end
|
|
end
|
|
end
|