Commit 9d7818c
Changed files (8)
lib
scim
kit
spec
lib/scim/kit/cli/app.rb
@@ -108,7 +108,7 @@ module Scim
end
def reporter
- @reporter ||= Reporter.new(shell)
+ @reporter ||= Reporter.new
end
def settings
lib/scim/kit/cli/reporter.rb
@@ -7,8 +7,9 @@ module Scim
SUCCESS = 0
FAILURE = 1
- def initialize(shell)
- @shell = shell
+ def initialize(out = $stdout, err = $stderr)
+ @out = out
+ @err = err
end
def report(result)
@@ -16,7 +17,7 @@ module Scim
end
def report_validation(result, errors)
- shell.say(pretty(result.body))
+ out.puts(pretty(result.body))
return SUCCESS if errors.empty?
failure(validation_errors: errors)
@@ -25,27 +26,27 @@ module Scim
# --validate was asked for and could not be carried out, so the
# response is reported but the command still fails.
def report_unvalidated(result)
- shell.say(pretty(result.body))
+ out.puts(pretty(result.body))
FAILURE
end
def success(body)
- shell.say(pretty(body))
+ out.puts(pretty(body))
SUCCESS
end
def failure(body)
- shell.say_error(pretty(body))
+ err.puts(pretty(body))
FAILURE
end
def warn(message)
- shell.say_error("warning: #{message}")
+ err.puts("warning: #{message}")
end
private
- attr_reader :shell
+ attr_reader :out, :err
def pretty(body)
JSON.pretty_generate(body)
lib/scim/kit/cli/settings.rb
@@ -47,10 +47,10 @@ module Scim
attr_reader :options, :env
def validate(url)
- raise Thor::Error, '--url is required' if url.to_s.empty?
+ raise InvalidOption, '--url is required' if url.to_s.empty?
unless absolute_http?(url)
- raise Thor::Error,
+ raise InvalidOption,
"--url must be an absolute http(s) URL, got #{url.inspect}"
end
@@ -67,7 +67,7 @@ module Scim
def split_header(header)
name, value = header.split(':', 2)
if value.nil?
- raise Thor::Error,
+ raise InvalidOption,
"malformed --header #{header.inspect} " \
'(expected "Name: Value")'
end
lib/scim/kit/cli.rb
@@ -46,6 +46,8 @@ module Scim
class InvalidResponse < Error; end
+ class InvalidOption < Error; end
+
# SCIM collection endpoints (/Schemas, /ResourceTypes) return a
# ListResponse per RFC 7644 section 4, but some servers return a
# bare array. Return the underlying array for either shape, or nil.
spec/scim/kit/cli/app_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'exits 1' do
- allow($stderr).to receive(:print)
+ allow($stderr).to receive(:puts)
expect(exit_status { call.call(app, 'Nope') }).to eq(1)
end
@@ -47,7 +47,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'exits 1' do
- allow($stderr).to receive(:print)
+ allow($stderr).to receive(:puts)
expect(exit_status { call.call(app, 'User') }).to eq(1)
end
@@ -80,7 +80,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'exits 0' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
expect(exit_status { app.discover }).to eq(0)
end
@@ -93,14 +93,14 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'reports the failure without requesting Schemas' do
- allow($stderr).to receive(:print)
+ allow($stderr).to receive(:puts)
exit_status { app.discover }
expect(a_request(:get, "#{base_url}/Schemas")).not_to have_been_made
end
it 'exits 1' do
- allow($stderr).to receive(:print)
+ allow($stderr).to receive(:puts)
expect(exit_status { app.discover }).to eq(1)
end
@@ -166,7 +166,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'exits 0' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
instance = app('validate' => true)
expect(exit_status { instance.discover }).to eq(0)
@@ -193,7 +193,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'flags the bare array as non-compliant with ListResponse format' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
instance = app('validate' => true)
expect { exit_status { instance.discover } }
@@ -214,7 +214,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'prints validation errors to stderr' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
instance = app('validate' => true)
expect { exit_status { instance.discover } }
@@ -222,8 +222,8 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'exits 1' do
- allow($stdout).to receive(:print)
- allow($stderr).to receive(:print)
+ allow($stdout).to receive(:puts)
+ allow($stderr).to receive(:puts)
instance = app('validate' => true)
expect(exit_status { instance.discover }).to eq(1)
@@ -268,7 +268,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'exits 0' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
expect(exit_status { instance.list('User') }).to eq(0)
end
@@ -286,7 +286,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'exits 1' do
- allow($stderr).to receive(:print)
+ allow($stderr).to receive(:puts)
expect(exit_status { app.list('User') }).to eq(1)
end
@@ -330,7 +330,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'exits 0' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
instance = app('validate' => true)
expect(exit_status { instance.list('User') }).to eq(0)
@@ -351,7 +351,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'exits 0 without demanding attributes the server was not asked for' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
instance = app('validate' => true, 'attributes' => 'id')
expect(exit_status { instance.list('User') }).to eq(0)
@@ -381,7 +381,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'warns about the undeclared extension' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
instance = app('validate' => true)
expect { exit_status { instance.list('User') } }
@@ -389,8 +389,8 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'still exits 0' do
- allow($stdout).to receive(:print)
- allow($stderr).to receive(:print)
+ allow($stdout).to receive(:puts)
+ allow($stderr).to receive(:puts)
instance = app('validate' => true)
expect(exit_status { instance.list('User') }).to eq(0)
@@ -411,7 +411,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'prints validation errors to stderr' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
instance = app('validate' => true)
expect { exit_status { instance.list('User') } }
@@ -419,8 +419,8 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'exits 1' do
- allow($stdout).to receive(:print)
- allow($stderr).to receive(:print)
+ allow($stdout).to receive(:puts)
+ allow($stderr).to receive(:puts)
instance = app('validate' => true)
expect(exit_status { instance.list('User') }).to eq(1)
@@ -441,7 +441,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'warns that it could not validate' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
instance = app('validate' => true)
expect { exit_status { instance.list('User') } }
@@ -449,8 +449,8 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'exits 1 rather than reporting an unvalidated success' do
- allow($stdout).to receive(:print)
- allow($stderr).to receive(:print)
+ allow($stdout).to receive(:puts)
+ allow($stderr).to receive(:puts)
instance = app('validate' => true)
expect(exit_status { instance.list('User') }).to eq(1)
@@ -478,7 +478,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'exits 0' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
expect(exit_status { instance.get('User', '123') }).to eq(0)
end
@@ -488,7 +488,7 @@ RSpec.describe Scim::Kit::Cli::App do
it 'escapes a space rather than raising URI::InvalidURIError' do
stub = stub_request(:get, "#{base_url}/Users/mo%20khan")
.to_return(status: 200, body: {}.to_json)
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
exit_status { app.get('User', 'mo khan') }
@@ -498,7 +498,7 @@ RSpec.describe Scim::Kit::Cli::App do
it 'escapes separators so an id cannot traverse the endpoint' do
stub = stub_request(:get, "#{base_url}/Users/..%2Fadmin%23x%3Fy")
.to_return(status: 200, body: {}.to_json)
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
exit_status { app.get('User', '../admin#x?y') }
@@ -518,7 +518,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'exits 1' do
- allow($stderr).to receive(:print)
+ allow($stderr).to receive(:puts)
expect(exit_status { app.get('User', '123') }).to eq(1)
end
@@ -556,7 +556,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'exits 0' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
instance = app('validate' => true)
expect(exit_status { instance.get('User', '123') }).to eq(0)
@@ -571,7 +571,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'prints validation errors to stderr' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
instance = app('validate' => true)
expect { exit_status { instance.get('User', '123') } }
@@ -579,8 +579,8 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'exits 1' do
- allow($stdout).to receive(:print)
- allow($stderr).to receive(:print)
+ allow($stdout).to receive(:puts)
+ allow($stderr).to receive(:puts)
instance = app('validate' => true)
expect(exit_status { instance.get('User', '123') }).to eq(1)
@@ -598,7 +598,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'sends repeated --header flags as request headers' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
instance = app('header' => ['Authorization: Bearer xyz', 'X-Test: value'])
exit_status { instance.list('User') }
@@ -620,7 +620,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'exits 1 with a usage message when RESOURCE_TYPE is missing' do
- allow($stderr).to receive(:print)
+ allow($stderr).to receive(:puts)
expect { exit_status { described_class.start(['list', '--url', base_url]) } }
.to output(/no arguments/).to_stderr
@@ -636,7 +636,7 @@ RSpec.describe Scim::Kit::Cli::App do
it 'reads --url from SCIM_KIT_URL when --url is omitted' do
ENV['SCIM_KIT_URL'] = base_url
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
status = exit_status { described_class.start(%w[list User]) }
@@ -652,7 +652,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
before do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
stub_request(:get, "#{base_url}/Users")
.with(headers: headers).to_return(status: 200, body: '{}')
end
@@ -667,7 +667,7 @@ RSpec.describe Scim::Kit::Cli::App do
end
it 'exits 1 with a usage message for a malformed --header' do
- allow($stderr).to receive(:print)
+ allow($stderr).to receive(:puts)
argv = ['list', 'User', '--url', base_url, '--header', 'BearerXYZ']
expect { exit_status { described_class.start(argv) } }
spec/scim/kit/cli/reporter_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.describe Scim::Kit::Cli::Reporter do
- subject { described_class.new(Thor::Shell::Basic.new) }
+ subject { described_class.new }
let(:body) { { id: '123' } }
let(:pretty) { JSON.pretty_generate(body) }
@@ -15,7 +15,7 @@ RSpec.describe Scim::Kit::Cli::Reporter do
end
it 'returns a success status' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
expect(subject.report(result)).to eq(0)
end
@@ -29,7 +29,7 @@ RSpec.describe Scim::Kit::Cli::Reporter do
end
it 'returns a failure status' do
- allow($stderr).to receive(:print)
+ allow($stderr).to receive(:puts)
expect(subject.report(result)).to eq(1)
end
@@ -46,7 +46,7 @@ RSpec.describe Scim::Kit::Cli::Reporter do
end
it 'returns a success status' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
expect(subject.report_validation(result, [])).to eq(0)
end
@@ -56,22 +56,22 @@ RSpec.describe Scim::Kit::Cli::Reporter do
let(:errors) { ['root is missing required keys: id'] }
it 'prints the errors to stderr' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
expect { subject.report_validation(result, errors) }
.to output(/validation_errors/).to_stderr
end
it 'still prints the body to stdout' do
- allow($stderr).to receive(:print)
+ allow($stderr).to receive(:puts)
expect { subject.report_validation(result, errors) }
.to output(/#{pretty}/).to_stdout
end
it 'returns a failure status' do
- allow($stdout).to receive(:print)
- allow($stderr).to receive(:print)
+ allow($stdout).to receive(:puts)
+ allow($stderr).to receive(:puts)
expect(subject.report_validation(result, errors)).to eq(1)
end
@@ -85,7 +85,7 @@ RSpec.describe Scim::Kit::Cli::Reporter do
end
it 'returns a failure status' do
- allow($stderr).to receive(:print)
+ allow($stderr).to receive(:puts)
expect(subject.failure(detail: 'boom')).to eq(1)
end
@@ -97,7 +97,7 @@ RSpec.describe Scim::Kit::Cli::Reporter do
end
it 'returns a success status' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
expect(subject.success(body)).to eq(0)
end
@@ -112,7 +112,7 @@ RSpec.describe Scim::Kit::Cli::Reporter do
end
it 'returns a failure status' do
- allow($stdout).to receive(:print)
+ allow($stdout).to receive(:puts)
expect(subject.report_unvalidated(result)).to eq(1)
end
spec/scim/kit/cli/resource_validation_spec.rb
@@ -3,7 +3,7 @@
RSpec.describe Scim::Kit::Cli::ResourceValidation do
subject { described_class.new(resolver, reporter) }
- let(:reporter) { Scim::Kit::Cli::Reporter.new(Thor::Shell::Basic.new) }
+ let(:reporter) { Scim::Kit::Cli::Reporter.new }
let(:entry) { { name: 'User', schema: core_urn } }
let(:core_urn) { 'urn:ietf:params:scim:schemas:core:2.0:User' }
let(:schema) do
@@ -62,7 +62,7 @@ RSpec.describe Scim::Kit::Cli::ResourceValidation do
end
it 'returns nil so the caller can flag it as unvalidated' do
- allow($stderr).to receive(:print)
+ allow($stderr).to receive(:puts)
expect(subject.errors_for(entry, resource)).to be_nil
end
@@ -87,7 +87,7 @@ RSpec.describe Scim::Kit::Cli::ResourceValidation do
end
it 'still validates the resource' do
- allow($stderr).to receive(:print)
+ allow($stderr).to receive(:puts)
expect(subject.errors_for(entry, resource)).to eql([])
end
spec/scim/kit/cli/settings_spec.rb
@@ -18,27 +18,27 @@ RSpec.describe Scim::Kit::Cli::Settings do
it 'raises when neither is given' do
expect { settings({}).url }
- .to raise_error(Thor::Error, /--url is required/)
+ .to raise_error(Scim::Kit::Cli::InvalidOption, /--url is required/)
end
it 'raises when the url is blank' do
expect { settings({ url: '' }).url }
- .to raise_error(Thor::Error, /--url is required/)
+ .to raise_error(Scim::Kit::Cli::InvalidOption, /--url is required/)
end
it 'raises when the url has no scheme' do
expect { settings({ url: 'example.com/scim/v2' }).url }
- .to raise_error(Thor::Error, /--url must be an absolute http/)
+ .to raise_error(Scim::Kit::Cli::InvalidOption, /--url must be an absolute http/)
end
it 'raises when the url scheme is not http(s)' do
expect { settings({ url: 'ftp://example.com' }).url }
- .to raise_error(Thor::Error, /--url must be an absolute http/)
+ .to raise_error(Scim::Kit::Cli::InvalidOption, /--url must be an absolute http/)
end
it 'raises when the url is unparseable' do
expect { settings({ url: 'http://exa mple.com' }).url }
- .to raise_error(Thor::Error, /--url must be an absolute http/)
+ .to raise_error(Scim::Kit::Cli::InvalidOption, /--url must be an absolute http/)
end
it 'accepts an http url' do
@@ -71,7 +71,7 @@ RSpec.describe Scim::Kit::Cli::Settings do
it 'raises on a header without a colon' do
expect { settings({ header: ['nope'] }).headers }
- .to raise_error(Thor::Error, /malformed --header/)
+ .to raise_error(Scim::Kit::Cli::InvalidOption, /malformed --header/)
end
end