test/paid/api_resource_test.rb in paid-0.1.0 vs test/paid/api_resource_test.rb in paid-1.0.0

- old
+ new

@@ -1,358 +1,28 @@ -# -*- coding: utf-8 -*- require File.expand_path('../../test_helper', __FILE__) module Paid class ApiResourceTest < Test::Unit::TestCase - should 'creating a new APIResource should not fetch over the network' do - @mock.expects(:get).never - Paid::Customer.new('someid') + + should 'have an id attribute' do + assert(Paid::APIResource.method_defined?(:id)) + assert(Paid::APIResource.method_defined?(:id=)) end - should 'creating a new APIResource from a hash should not fetch over the network' do - @mock.expects(:get).never - Paid::Customer.construct_from(id: 'somecustomer', - object: 'customer', - email: 'someone@example.com', - name: 'Some Business', - account_id: 'acct_1234') + should 'have an object attribute' do + assert(Paid::APIResource.method_defined?(:object)) + assert(Paid::APIResource.method_defined?(:object=)) end - should 'setting an attribute should not cause a network request' do - @mock.expects(:get).never - @mock.expects(:post).never - c = Paid::Customer.new('test_customer') - c.name = 'Another Name' + should 'have a default path' do + mr = MockResource.new('fake_id') + assert_equal("#{MockResource.path}/fake_id", mr.path) end - should 'accessing id should not issue a fetch' do + should 'raise an InvalidRequestError when no ID is present for instance path' do @mock.expects(:get).never - c = Paid::Customer.new('test_customer') - c.id + c = MockResource.new + assert_raises(Paid::InvalidRequestError) { c.refresh } end - should 'not specifying api credentials should raise an exception' do - Paid.api_key = nil - assert_raises Paid::AuthenticationError do - Paid::Customer.new('test_customer').refresh - end - end - - should 'specifying api credentials containing whitespace should raise an exception' do - Paid.api_key = 'key ' - assert_raises Paid::AuthenticationError do - Paid::Customer.new('test_customer').refresh - end - end - - should 'specifying invalid api credentials should raise an exception' do - Paid.api_key = 'invalid' - response = test_response(test_invalid_api_key_error, 401) - assert_raises Paid::AuthenticationError do - @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 401)) - Paid::Customer.retrieve('failing_customer') - end - end - - should 'AuthenticationErrors should have an http status, http body, and JSON body' do - Paid.api_key = 'invalid' - response = test_response(test_invalid_api_key_error, 401) - begin - @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 401)) - Paid::Customer.retrieve('failing_customer') - rescue Paid::AuthenticationError => e - assert_equal(401, e.http_status) - assert_equal(true, !!e.http_body) - assert_equal(true, !!e.json_body[:error][:message]) - assert_equal(test_invalid_api_key_error[:error][:message], e.json_body[:error][:message]) - end - end - - should 'send paid account as header when set' do - paid_account = 'acct_0000' - Paid.expects(:execute_request).with do |opts| - opts[:headers][:paid_account] == paid_account - end.returns(test_response(test_transaction)) - - Paid::Transaction.create({ amount: 100 }, - paid_account: paid_account, api_key: 'sk_test_local') - end - - should 'not send paid account as header when not set' do - Paid.expects(:execute_request).with do |opts| - opts[:headers][:paid_account].nil? - end.returns(test_response(test_transaction)) - - Paid::Transaction.create( - { - amount: 200, - description: 'This is a description.', - customer: 'somecustomer' - - }, - 'sk_test_local' - ) - end - - context 'when specifying per-object credentials' do - context 'with no global API key set' do - should 'use the per-object credential when creating' do - Paid.expects(:execute_request).with do |opts| - opts[:headers][:authorization] == 'Bearer sk_test_local' - end.returns(test_response(test_transaction)) - - Paid::Transaction.create( - { - amount: 200, - description: 'This is a description.', - customer: 'somecustomer' - }, - 'sk_test_local' - ) - end - end - - context 'with a global API key set' do - setup do - Paid.api_key = 'global' - end - - teardown do - Paid.api_key = nil - end - - should 'use the per-object credential when creating' do - Paid.expects(:execute_request).with do |opts| - opts[:headers][:authorization] == 'Bearer local' - end.returns(test_response(test_transaction)) - - Paid::Transaction.create( - { - amount: 200, - description: 'This is a description.', - customer: 'somecustomer' - }, - 'local' - ) - end - - should 'use the per-object credential when retrieving and making other calls' do - Paid.expects(:execute_request).with do |opts| - opts[:url] == "#{Paid.api_base}/v0/transactions/tr_test_transaction" && - opts[:headers][:authorization] == 'Bearer local' - end.returns(test_response(test_transaction)) - - ch = Paid::Transaction.retrieve('tr_test_transaction', 'local') - end - end - end - - context 'with valid credentials' do - should 'send along the idempotency-key header' do - Paid.expects(:execute_request).with do |opts| - opts[:headers][:idempotency_key] == 'bar' - end.returns(test_response(test_transaction)) - - Paid::Transaction.create( - { - amount: 200, - description: 'This is a description.', - customer: 'somecustomer' - }, - idempotency_key: 'bar', - api_key: 'local' - ) - end - - should 'urlencode values in GET params' do - response = test_response(test_transaction_array) - @mock.expects(:get).with("#{Paid.api_base}/v0/transactions?customer=test%20customer", nil, nil).returns(response) - transactions = Paid::Transaction.all(customer: 'test customer').data - assert transactions.is_a? Array - end - - should 'a 400 should give an InvalidRequestError with http status, body, and JSON body' do - response = test_response(test_missing_id_error, 400) - @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 404)) - begin - Paid::Customer.retrieve('foo') - rescue Paid::InvalidRequestError => e - assert_equal(400, e.http_status) - assert_equal(true, !!e.http_body) - assert_equal(true, e.json_body.is_a?(Hash)) - end - end - - should 'a 401 should give an AuthenticationError with http status, body, and JSON body' do - response = test_response(test_missing_id_error, 401) - @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 404)) - begin - Paid::Customer.retrieve('foo') - rescue Paid::AuthenticationError => e - assert_equal(401, e.http_status) - assert_equal(true, !!e.http_body) - assert_equal(true, e.json_body.is_a?(Hash)) - end - end - - should 'a 404 should give an InvalidRequestError with http status, body, and JSON body' do - response = test_response(test_missing_id_error, 404) - @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 404)) - begin - Paid::Customer.retrieve('foo') - rescue Paid::InvalidRequestError => e - assert_equal(404, e.http_status) - assert_equal(true, !!e.http_body) - assert_equal(true, e.json_body.is_a?(Hash)) - end - end - - should 'setting a nil value for a param should exclude that param from the request' do - @mock.expects(:get).with do |url, _api_key, _params| - uri = URI(url) - query = CGI.parse(uri.query) - (url =~ %r{^#{Paid.api_base}/v0/transactions?} && - query.keys.sort == %w(offset sad)) - end.returns(test_response(count: 1, data: [test_transaction])) - Paid::Transaction.all(count: nil, offset: 5, sad: false) - - @mock.expects(:post).with do |url, api_key, params| - url == "#{Paid.api_base}/v0/transactions" && - api_key.nil? && - CGI.parse(params) == { 'amount' => ['100'] } - end.returns(test_response(count: 1, data: [test_transaction])) - Paid::Transaction.create(amount: 100) - end - - should 'requesting with a unicode ID should result in a request' do - response = test_response(test_missing_id_error, 404) - @mock.expects(:get).once.with("#{Paid.api_base}/v0/customers/%E2%98%83", nil, nil).raises(RestClient::ExceptionWithResponse.new(response, 404)) - c = Paid::Customer.new('☃') - assert_raises(Paid::InvalidRequestError) { c.refresh } - end - - should 'requesting with no ID should result in an InvalidRequestError with no request' do - c = Paid::Customer.new - assert_raises(Paid::InvalidRequestError) { c.refresh } - end - - should 'making a GET request with parameters should have a query string and no body' do - params = { limit: 1 } - @mock.expects(:get).once.with("#{Paid.api_base}/v0/transactions?limit=1", nil, nil).returns(test_response([test_transaction])) - Paid::Transaction.all(params) - end - - should 'making a POST request with parameters should have a body and no query string' do - params = { amount: 100, alias: 'test_alias' } - @mock.expects(:post).once.with do |_url, get, post| - get.nil? && CGI.parse(post) == { 'amount' => ['100'], 'alias' => ['test_alias'] } - end.returns(test_response(test_transaction)) - Paid::Transaction.create(params) - end - - should 'loading an object should issue a GET request' do - @mock.expects(:get).once.returns(test_response(test_customer)) - c = Paid::Customer.new('test_customer') - c.refresh - end - - should 'using array accessors should be the same as the method interface' do - @mock.expects(:get).once.returns(test_response(test_customer)) - c = Paid::Customer.new('test_customer') - c.refresh - assert_equal c.created, c[:created] - assert_equal c.created, c['created'] - c['created'] = 12_345 - assert_equal c.created, 12_345 - end - - should 'accessing a property other than id or parent on an unfetched object should fetch it' do - @mock.expects(:get).once.returns(test_response(test_customer)) - c = Paid::Customer.new('test_customer') - c.transactions - end - - should 'updating an object should issue a POST request with only the changed properties' do - @mock.expects(:post).with do |url, api_key, params| - url == "#{Paid.api_base}/v0/customers/cus_test_customer" && - api_key.nil? && - CGI.parse(params) == { 'description' => ['another_mn'] } - end.once.returns(test_response(test_customer)) - c = Paid::Customer.construct_from(test_customer) - c.description = 'another_mn' - c.save - end - - should 'updating should merge in returned properties' do - @mock.expects(:post).once.returns(test_response(test_customer)) - c = Paid::Customer.new('cus_test_customer') - c.description = 'another_mn' - c.save - # assert_equal false, c.livemode - end - - should 'deleting should send no props and result in an object that has no props other deleted' do - @mock.expects(:get).never - @mock.expects(:post).never - @mock.expects(:delete).with("#{Paid.api_base}/v0/customers/cus_test_customer", nil, nil).once.returns(test_response('id' => 'test_customer', 'deleted' => true)) - - c = Paid::Customer.construct_from(test_customer) - c.delete - assert_equal true, c.deleted - - assert_raises NoMethodError do - c.livemode - end - end - - should 'loading an object with properties that have specific types should instantiate those classes' do - @mock.expects(:get).once.returns(test_response(test_transaction)) - t = Paid::Transaction.retrieve('test_transaction') - assert t.is_a?(Paid::PaidObject) && t.object == 'transaction' - end - - should 'loading all of an APIResource should return an array of recursively instantiated objects' do - @mock.expects(:get).once.returns(test_response(test_transaction_array)) - t = Paid::Transaction.all.data - assert t.is_a? Array - assert t[0].is_a? Paid::Transaction - assert t[0].is_a?(Paid::PaidObject) && t[0].object == 'transaction' - end - - context 'error checking' do - should '404s should raise an InvalidRequestError' do - response = test_response(test_missing_id_error, 404) - @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 404)) - - rescued = false - begin - Paid::Customer.new('test_customer').refresh - assert false # shouldn't get here either - rescue Paid::InvalidRequestError => e # we don't use assert_raises because we want to examine e - rescued = true - assert e.is_a? Paid::InvalidRequestError - assert_equal 'id', e.param - assert_equal 'Missing id', e.message - end - - assert_equal true, rescued - end - - should '5XXs should raise an APIError' do - response = test_response(test_api_error, 500) - @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 500)) - - rescued = false - begin - Paid::Customer.new('test_customer').refresh - assert false # shouldn't get here either - rescue Paid::APIError => e # we don't use assert_raises because we want to examine e - rescued = true - assert e.is_a? Paid::APIError - end - - assert_equal true, rescued - end - end - end end end