spec/cfoundry/uaaclient_spec.rb in cfoundry-0.4.21 vs spec/cfoundry/uaaclient_spec.rb in cfoundry-0.5.0

- old
+ new

@@ -1,17 +1,32 @@ require "spec_helper" describe CFoundry::UAAClient do let(:target) { "https://uaa.example.com" } let(:uaa) { CFoundry::UAAClient.new(target) } + let(:auth_header) { "bearer access-token" } + before do + uaa.token = CFoundry::AuthToken.new(auth_header) + end + + shared_examples "UAA wrapper" do + it "converts UAA errors to CFoundry equivalents" do + mock(uaa).wrap_uaa_errors { nil } + subject + end + end + describe '#prompts' do subject { uaa.prompts } + include_examples "UAA wrapper" + # GET (target)/login it "receives the prompts from /login" do stub_request(:get, "#{target}/login").to_return :status => 200, + :headers => {'Content-Type' => 'application/json'}, :body => <<EOF { "timestamp": "2012-11-08T13:32:18+0000", "commit_id": "ebbf817", "app": { @@ -40,103 +55,92 @@ end describe '#authorize' do let(:username) { "foo@bar.com" } let(:password) { "test" } + let(:creds) { {:username => username, :password => password} } + let(:state) { 'somestate' } + let(:redirect_uri) { 'https://uaa.cloudfoundry.com/redirect/vmc' } + let(:auth) { Object.new } - subject { uaa.authorize(:username => username, :password => password) } + subject { uaa.authorize(username, password) } - it 'returns the token on successful authentication' do - stub_request( - :post, - "#{target}/oauth/authorize" - ).with( - :query => { - "client_id" => uaa.client_id, - "redirect_uri" => uaa.redirect_uri, - "response_type" => "token" - } - ).to_return( - :status => 302, - :headers => { - "Location" => "#{uaa.redirect_uri}#access_token=bar&token_type=foo&fizz=buzz&foo=bar" - } - ) + before { stub(uaa).token_issuer.stub!.implicit_grant_with_creds { auth } } - expect(subject).to eq "foo bar" + include_examples "UAA wrapper" + + it 'returns the token on successful authentication' do + stub(uaa).token_issuer.mock!.implicit_grant_with_creds(creds) { auth } + expect(subject).to eq auth end - it 'raises CFoundry::Denied if authentication fails' do - stub_request( - :post, - "#{target}/oauth/authorize" - ).with( - :query => { - "client_id" => uaa.client_id, - "redirect_uri" => uaa.redirect_uri, - "response_type" => "token" - } - ).to_return( - :status => 401, - :headers => { - "Location" => "#{uaa.redirect_uri}#access_token=bar&token_type=foo&fizz=buzz&foo=bar" - }, - :body => <<EOF - { - "error": "unauthorized", - "error_description": "Bad credentials" - } -EOF - ) + context 'when authorization fails' do + context 'in the expected way' do + it 'raises a CFoundry::Denied error' do + stub(uaa).token_issuer.stub!.implicit_grant_with_creds { raise CF::UAA::BadResponse.new("401: FooBar") } - expect { subject }.to raise_error( - CFoundry::Denied, "401: Bad credentials") + expect { subject }.to raise_error(CFoundry::Denied, "401: Authorization failed") + end + end + + context 'in an unexpected way' do + it 'raises a CFoundry::Denied error' do + stub(uaa).token_issuer.stub!.implicit_grant_with_creds { raise CF::UAA::BadResponse.new("no_status_code") } + expect { subject }.to raise_error(CFoundry::Denied, "400: Authorization failed") + end + end end end describe '#users' do subject { uaa.users } it 'requests /Users' do - req = stub_request(:get, "#{target}/Users").to_return( - :body => '{ "fake_data": "123" }') - expect(subject).to eq({ :fake_data => "123" }) - expect(req).to have_been_requested + stub_request(:get, "#{target}/Users").with( + :headers => { "authorization" => auth_header } + ).to_return( + :headers => {'Content-Type' => 'application/json'}, + :body => '{ "resources": [] }' + ) + expect(subject).to eq({'resources' => []}) end + + context "when there is no token" do + before { uaa.token = nil } + + it "doesn't blow up" do + stub_request(:get, "#{target}/Users").to_return( + :headers => {'Content-Type' => 'application/json'}, + :body => '{ "resources": [] }' + ) + expect(subject).to eq({'resources' => []}) + end + end end describe '#change_password' do let(:guid) { "foo-bar-baz" } let(:old) { "old-pass" } let(:new) { "new-pass" } subject { uaa.change_password(guid, new, old) } + include_examples "UAA wrapper" + it 'sends a password change request' do - req = stub_request( - :put, - "#{target}/Users/#{guid}/password" - ).with( - :body => { - :password => new, - :oldPassword => old - }, + req = stub_request(:put, "#{target}/Users/#{guid}/password").with( :headers => { - "Content-Type" => "application/json", - "Accept" => "application/json" + "Content-Type" => "application/json;charset=utf-8", + "Accept" => "application/json;charset=utf-8", + "Authorization" => auth_header } ).to_return( :status => 200, - :body => <<EOF - { - "status": "ok", - "message": "password_updated" - } -EOF + :headers => {'Content-Type' => 'application/json'}, + :body => '{ "status": "ok", "message": "password_updated" }' ) - subject expect(req).to have_been_requested end end @@ -145,25 +149,26 @@ let(:password) { "password" } let(:response) { MultiJson.encode({}) } subject { uaa.password_score(password) } + include_examples "UAA wrapper" + before do - @request = stub_request(:post, "#{target}/password/score").with( - :body => {:password => password, }, - :headers => { "Accept" => "application/json" } + stub_request(:post, "#{target}/password/score").with( + :body => 'password=password', + :headers => { + 'Accept' => 'application/json;charset=utf-8', + 'Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8', + } ).to_return( :status => 200, + :headers => {'Content-Type' => 'application/json'}, :body => response ) end - it 'sends a password change request' do - subject - expect(@request).to have_been_requested - end - context 'when the score is 0 and the required is 0' do let(:response) { MultiJson.encode "score" => 0, "requiredScore" => 0 } it { should == :good } end @@ -196,71 +201,93 @@ let(:response) { MultiJson.encode "score" => 11, "requiredScore" => 5 } it { should == :weak } end end - describe '#request_uri' do - subject { uaa.request_uri URI.parse(uaa.target + "/foo"), Net::HTTP::Get } + describe "#add_user" do + let(:email) { 'test@test.com' } + let(:password) { 'secret' } - context 'when an HTTPNotFound error occurs' do - before { + subject { uaa.add_user(email, password) } - stub_request(:get, 'https://uaa.example.com/foo').to_return :status => 404, - :body => "NOT FOUND" - } + context 'with valid data' do + it "should add a user" do + req = + stub_request(:post, "https://uaa.example.com/Users").with( + :body => + { :userName => email, + :emails => [{ :value => email }], + :password => password, + :name => { :givenName => email, :familyName => email } + } + ).to_return( + :status => 200, + :body => '{ "id" : "id" }', + :headers => { "Content-Type" => 'application/json' } + ) - it 'raises the correct error' do - expect {subject}.to raise_error CFoundry::NotFound, "404: NOT FOUND" + expect(subject).to eq({"id" => "id"}) + expect(req).to have_been_requested end end + end + describe "#wrap_uaa_errors" do + subject { uaa.send(:wrap_uaa_errors) { raise error } } - shared_examples "Denied tests" do - before { - stub_request(:get, 'https://uaa.example.com/foo').to_return :status => error_code, - :body => "{\"error_description\":\"Something detailed\"}" - } + context "when the block raises CF::UAA::BadResponse" do + let(:error) { CF::UAA::BadResponse } - it 'raises the correct error' do - expect {subject}.to raise_error CFoundry::Denied, "#{error_code}: Something detailed" + it "raises CFoundry::BadResponse" do + expect { subject }.to raise_exception(CFoundry::BadResponse) end end + context "when the block raises CF::UAA::NotFound" do + let(:error) { CF::UAA::NotFound } - context 'when an HTTPForbidden error occurs' do - let(:error_code) { 403 } - include_examples "Denied tests" + it "raises CFoundry::NotFound" do + expect { subject }.to raise_exception(CFoundry::NotFound) + end end - context 'when an HTTPUnauthorized error occurs' do - let(:error_code) { 401 } - include_examples "Denied tests" - end + context "when the block raises CF::UAA::InvalidToken" do + let(:error) { CF::UAA::InvalidToken } - context 'when an HTTPBadRequest error occurs' do - let(:error_code) { 400 } - include_examples "Denied tests" + it "raises CFoundry::Denied" do + expect { subject }.to raise_exception(CFoundry::Denied) + end end - context "when an HTTPConflict error occurs" do - before { - stub_request(:get, 'https://uaa.example.com/foo').to_return :status => 409, - :body => "{\"message\":\"There was a conflict\"}" - } + context "when the block raises CF::UAA::TargetError" do + let(:error) { CF::UAA::TargetError.new({ "error" => "foo", "error_description" => "bar" }) } - it 'raises the correct error' do - expect {subject}.to raise_error CFoundry::Denied, "409: There was a conflict" + it "raises CFoundry::UAAError" do + expect { subject }.to raise_exception(CFoundry::UAAError, "foo: bar") end end + end - context "when any other type of error occurs" do - before { - stub_request(:get, 'https://uaa.example.com/foo').to_return :status => 411, - :body => "NOT LONG ENOUGH" - } + describe "#token_issuer" do + it "has logging level 0 if #trace is true" do + uaa.trace = true + expect(uaa.send(:token_issuer).logger.level).to eq 0 + end - it 'raises the correct error' do - expect {subject}.to raise_error CFoundry::BadResponse, "411: NOT LONG ENOUGH" - end + it "has logging level 1 if #trace is false" do + uaa.trace = false + expect(uaa.send(:token_issuer).logger.level).to eq 1 + end + end + + describe "#scim" do + it "has logging level 0 if #trace is true" do + uaa.trace = true + expect(uaa.send(:scim).logger.level).to eq 0 + end + + it "has logging level 1 if #trace is false" do + uaa.trace = false + expect(uaa.send(:scim).logger.level).to eq 1 end end end