
livecheck currently doesn't support `POST` requests but it wasn't entirely clear how best to handle that. I initially approached it as a `Post` strategy but unfortunately that would have required us to handle response body parsing (e.g., JSON, XML, etc.) in some fashion. We could borrow some of the logic from related strategies but we would still be stuck having to update `Post` whenever we add a strategy for a new format. Instead, this implements `POST` support by borrowing ideas from the `using: :post` and `data` `url` options found in formulae. This uses a `post_form` option to handle form data and `post_json` to handle JSON data, encoding the hash argument for each into the appropriate format. The presence of either option means that curl will use a `POST` request. With this approach, we can make a `POST` request using any strategy that calls `Strategy::page_headers` or `::page_content` (directly or indirectly) and everything else works the same as usual. The only change needed in related strategies was to pass the options through to the `Strategy` methods. For example, if we need to parse a JSON response from a `POST` request, we add a `post_data` or `post_json` hash to the `livecheck` block `url` and use `strategy :json` with a `strategy` block. This leans on existing patterns that we're already familiar with and shouldn't require any notable maintenance burden when adding new strategies, so it seems like a better approach than a `Post` strategy.
186 lines
4.5 KiB
Ruby
186 lines
4.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "formula"
|
|
require "livecheck"
|
|
|
|
RSpec.describe Livecheck do
|
|
let(:f) do
|
|
formula do
|
|
homepage "https://brew.sh"
|
|
url "https://brew.sh/test-0.0.1.tgz"
|
|
head "https://github.com/Homebrew/brew.git"
|
|
end
|
|
end
|
|
let(:livecheck_f) { described_class.new(f.class) }
|
|
|
|
let(:c) do
|
|
Cask::CaskLoader.load(+<<-RUBY)
|
|
cask "test" do
|
|
version "0.0.1,2"
|
|
|
|
url "https://brew.sh/test-0.0.1.dmg"
|
|
name "Test"
|
|
desc "Test cask"
|
|
homepage "https://brew.sh"
|
|
end
|
|
RUBY
|
|
end
|
|
let(:livecheck_c) { described_class.new(c) }
|
|
|
|
let(:post_hash) do
|
|
{
|
|
"empty" => "",
|
|
"boolean" => "true",
|
|
"number" => "1",
|
|
"string" => "a + b = c",
|
|
}
|
|
end
|
|
|
|
describe "#formula" do
|
|
it "returns nil if not set" do
|
|
expect(livecheck_f.formula).to be_nil
|
|
end
|
|
|
|
it "returns the String if set" do
|
|
livecheck_f.formula("other-formula")
|
|
expect(livecheck_f.formula).to eq("other-formula")
|
|
end
|
|
|
|
it "raises a TypeError if the argument isn't a String" do
|
|
expect do
|
|
livecheck_f.formula(123)
|
|
end.to raise_error TypeError
|
|
end
|
|
end
|
|
|
|
describe "#cask" do
|
|
it "returns nil if not set" do
|
|
expect(livecheck_c.cask).to be_nil
|
|
end
|
|
|
|
it "returns the String if set" do
|
|
livecheck_c.cask("other-cask")
|
|
expect(livecheck_c.cask).to eq("other-cask")
|
|
end
|
|
end
|
|
|
|
describe "#regex" do
|
|
it "returns nil if not set" do
|
|
expect(livecheck_f.regex).to be_nil
|
|
end
|
|
|
|
it "returns the Regexp if set" do
|
|
livecheck_f.regex(/foo/)
|
|
expect(livecheck_f.regex).to eq(/foo/)
|
|
end
|
|
end
|
|
|
|
describe "#skip" do
|
|
it "sets @skip to true when no argument is provided" do
|
|
expect(livecheck_f.skip).to be true
|
|
expect(livecheck_f.instance_variable_get(:@skip)).to be true
|
|
expect(livecheck_f.instance_variable_get(:@skip_msg)).to be_nil
|
|
end
|
|
|
|
it "sets @skip to true and @skip_msg to the provided String" do
|
|
expect(livecheck_f.skip("foo")).to be true
|
|
expect(livecheck_f.instance_variable_get(:@skip)).to be true
|
|
expect(livecheck_f.instance_variable_get(:@skip_msg)).to eq("foo")
|
|
end
|
|
end
|
|
|
|
describe "#skip?" do
|
|
it "returns the value of @skip" do
|
|
expect(livecheck_f.skip?).to be false
|
|
|
|
livecheck_f.skip
|
|
expect(livecheck_f.skip?).to be true
|
|
end
|
|
end
|
|
|
|
describe "#strategy" do
|
|
it "returns nil if not set" do
|
|
expect(livecheck_f.strategy).to be_nil
|
|
end
|
|
|
|
it "returns the Symbol if set" do
|
|
livecheck_f.strategy(:page_match)
|
|
expect(livecheck_f.strategy).to eq(:page_match)
|
|
end
|
|
end
|
|
|
|
describe "#throttle" do
|
|
it "returns nil if not set" do
|
|
expect(livecheck_f.throttle).to be_nil
|
|
end
|
|
|
|
it "returns the Integer if set" do
|
|
livecheck_f.throttle(10)
|
|
expect(livecheck_f.throttle).to eq(10)
|
|
end
|
|
end
|
|
|
|
describe "#url" do
|
|
let(:url_string) { "https://brew.sh" }
|
|
|
|
it "returns nil if not set" do
|
|
expect(livecheck_f.url).to be_nil
|
|
end
|
|
|
|
it "returns a string when set to a string" do
|
|
livecheck_f.url(url_string)
|
|
expect(livecheck_f.url).to eq(url_string)
|
|
end
|
|
|
|
it "returns the URL symbol if valid" do
|
|
livecheck_f.url(:head)
|
|
expect(livecheck_f.url).to eq(:head)
|
|
|
|
livecheck_f.url(:homepage)
|
|
expect(livecheck_f.url).to eq(:homepage)
|
|
|
|
livecheck_f.url(:stable)
|
|
expect(livecheck_f.url).to eq(:stable)
|
|
|
|
livecheck_c.url(:url)
|
|
expect(livecheck_c.url).to eq(:url)
|
|
end
|
|
|
|
it "sets `url_options` when provided" do
|
|
post_args = { post_form: post_hash }
|
|
livecheck_f.url(url_string, **post_args)
|
|
expect(livecheck_f.url_options).to eq(post_args)
|
|
end
|
|
|
|
it "raises an ArgumentError if the argument isn't a valid Symbol" do
|
|
expect do
|
|
livecheck_f.url(:not_a_valid_symbol)
|
|
end.to raise_error ArgumentError
|
|
end
|
|
|
|
it "raises an ArgumentError if both `post_form` and `post_json` arguments are provided" do
|
|
expect do
|
|
livecheck_f.url(:stable, post_form: post_hash, post_json: post_hash)
|
|
end.to raise_error ArgumentError
|
|
end
|
|
end
|
|
|
|
describe "#to_hash" do
|
|
it "returns a Hash of all instance variables" do
|
|
expect(livecheck_f.to_hash).to eq(
|
|
{
|
|
"cask" => nil,
|
|
"formula" => nil,
|
|
"regex" => nil,
|
|
"skip" => false,
|
|
"skip_msg" => nil,
|
|
"strategy" => nil,
|
|
"throttle" => nil,
|
|
"url" => nil,
|
|
"url_options" => nil,
|
|
},
|
|
)
|
|
end
|
|
end
|
|
end
|