Skip to content

Commit

Permalink
Merge pull request #19 from jmatsu/use_official_validation
Browse files Browse the repository at this point in the history
Use the official validation instead
  • Loading branch information
jmatsu authored Aug 14, 2018
2 parents b12a1cb + c5d0d01 commit 05f7bc2
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 72 deletions.
1 change: 1 addition & 0 deletions lib/remocon.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
require "fileutils"
require "net/http"
require "googleauth"
require "tempfile"

require "remocon/util/array"
require "remocon/util/hash"
Expand Down
8 changes: 0 additions & 8 deletions lib/remocon/command/lib/interpreter_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ def parameter_hash
@parameter_hash ||= sort_parameters(read_parameters.first)
end

def parameter_errors
@parameter_errors ||= read_parameters.second
end

def read_conditions
@read_conditions ||= begin
condition_interpreter = Remocon::ConditionFileInterpreter.new(require_conditions_file_path)
Expand All @@ -43,10 +39,6 @@ def condition_array
@condition_array ||= sort_conditions(read_conditions.first)
end

def condition_errors
@condition_errors ||= read_conditions.second
end

def condition_names
@condition_names ||= condition_array.map { |e| e[:name] }
end
Expand Down
25 changes: 25 additions & 0 deletions lib/remocon/command/lib/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,31 @@ def self.push(config)
return response, response_body
end

def self.validate(config, config_temp_file)
raise "etag should be specified. If you want to ignore this error, then please add --force option" unless config.etag

client, uri = Request.build_client(config)

headers = {
"Authorization" => "Bearer #{config.token}",
"Content-Type" => "application/json; UTF8",
"If-Match" => config.etag,
}

request = Net::HTTP::Put.new("#{uri.request_uri}?validate_only=true", headers)
request.body = +""
request.body << config_temp_file.read.delete("\r\n")

response = client.request(request)

response_body = begin
json_str = response.try(:read_body)
(json_str ? JSON.parse(json_str) : {}).with_indifferent_access
end

return response, response_body
end

def self.pull(config)
raw_json, etag = open(config.endpoint, "Authorization" => "Bearer #{config.token}") do |io|
[io.read, io.meta["etag"]]
Expand Down
41 changes: 28 additions & 13 deletions lib/remocon/command/validate_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,36 @@ def require_conditions_file_path
def run
validate_options

errors = parameter_errors + condition_errors + etag_errors
artifact = {
conditions: condition_array,
parameters: parameter_hash
}.skip_nil_values.stringify_values

print_errors(errors)
response, body = Tempfile.open do |t|
t.write(JSON.pretty_generate(artifact))
t.flush

errors.empty?
end
Request.validate(config, t)
end

def print_errors(errors)
if errors.empty?
STDOUT.puts "No error was found."
else
errors.each do |e|
STDERR.puts "#{e.class} #{e.message}"
STDERR.puts e.backtrace&.join("\n")
if response.kind_of?(Net::HTTPOK)
if response.header["etag"] =~ /^.*-0$/
if etag_errors.empty?
STDOUT.puts "valid"
true
else
# validation api cannot validate etag
STDERR.puts "the latest etag was updated"
false
end
else
# https://firebase.google.com/docs/remote-config/use-config-rest#validate_before_publishing
STDERR.puts "api server returned 200 but etag is not followed the valid format"
false
end
else
STDERR.puts body
false
end
end

Expand All @@ -46,15 +61,15 @@ def print_errors(errors)
def validate_options
raise ValidationError, "A condition file must exist" unless File.exist?(config.conditions_file_path)
raise ValidationError, "A parameter file must exist" unless File.exist?(config.parameters_file_path)
raise ValidationError, "An etag file must exist" unless File.exist?(config.etag_file_path)
raise ValidationError, "An etag must be specified" unless config.etag
end

def remote_etag
@remote_etag ||= Remocon::Request.fetch_etag(config)
end

def etag_errors
if config.etag != remote_etag
if config.etag != "*" && config.etag != remote_etag
[ValidationError.new("#{config.etag} is found but the latest etag is #{remote_etag || 'none'}")]
else
[]
Expand Down
22 changes: 0 additions & 22 deletions spec/remocon/command/lib/interpreter_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,6 @@ def require_conditions_file_path
end
end

context "#parameter_errors" do
before do
allow(helper).to receive(:read_parameters).and_return([nil, errors])
end

it "should return errors" do
expect(helper).to receive(:read_parameters)
expect(helper.parameter_errors).to eq(errors)
end
end

context "#read_conditions" do
let(:interpreter) { double("mock") }

Expand All @@ -89,17 +78,6 @@ def require_conditions_file_path
end
end

context "#condition_errors" do
before do
allow(helper).to receive(:read_conditions).and_return([nil, errors])
end

it "should return a result of ConditionFileInterpreter" do
expect(helper).to receive(:read_conditions)
expect(helper.condition_errors).to eq(errors)
end
end

context "#condition_names" do
before do
allow(helper).to receive(:read_conditions).and_return([conditions, nil])
Expand Down
18 changes: 18 additions & 0 deletions spec/remocon/command/lib/request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,24 @@ module Remocon
end
end

context "#validate" do
it "should send a json request with an etag and a token" do
expect(Net::HTTP::Put).to receive(:new).with(URI.parse("https://firebaseremoteconfig.googleapis.com/v1/projects/fixture/remoteConfig?validate_only=true").request_uri, any_args) do |_, headers|
expect(headers).to include(
"Authorization" => "Bearer valid_token",
"Content-Type" => "application/json; UTF8",
"If-Match" => "raw_etag"
)
end.and_call_original

Tempfile.open do |t|
t.write("{}")

Request.validate(config, t)
end
end
end

context "#pull" do
it "should request with a token" do
expect(Request).to receive(:open).with("https://firebaseremoteconfig.googleapis.com/v1/projects/fixture/remoteConfig", {
Expand Down
31 changes: 2 additions & 29 deletions spec/remocon/command/validate_command_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ module Command
before do
allow(STDOUT).to receive(:puts)
allow(STDERR).to receive(:puts)
allow_any_instance_of(Net::HTTPOK).to receive(:header).and_return({ "etag" => "XYZXYZXYZXYZ-0" })
allow(Remocon::Request).to receive(:validate).and_return([Net::HTTPOK.new(nil, 200, nil), "{}"])
end

context "etags are mismatch" do
Expand All @@ -86,10 +88,6 @@ module Command
end

it "should return an error" do
expect(command).to receive(:print_errors).with(any_args) do |errors|
expect(errors.any? { |e| e.kind_of?(ValidationError) }).to be_truthy
end

expect(command.run).to be_falsey
end
end
Expand All @@ -100,35 +98,10 @@ module Command
end

it "should not return any errors" do
expect(command).to receive(:print_errors).with([])
expect(command.run).to be_truthy
end
end
end

context "a parameters file is invalid" do
let(:options) do
{
parameters: fixture_path("invalid_parameters_1.yml"),
conditions: fixture_path("valid_conditions.yml"),
etag: fixture_path("etag_file"),
id: "dragon",
token: "valid_token"
}
end

before do
allow(Remocon::Request).to receive(:fetch_etag).and_return("XYZXYZXYZXYZ")
end

it "should return an error" do
expect(command).to receive(:print_errors).with(any_args) do |errors|
expect(errors.any? { |e| e.kind_of?(ValidationError) }).to be_truthy
end

expect(command.run).to be_falsey
end
end
end
end
end

0 comments on commit 05f7bc2

Please sign in to comment.