vend 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 36886eb6986fbeb8cea81493ff3f87cfc75d2e7c
4
+ data.tar.gz: d0bc6a8d32403071b1bcead22e49bd74771cb83b
5
+ SHA512:
6
+ metadata.gz: de2eeb7b4b76dd5d1fbbad65784fb63df20c1cd80314886e7cf9bbc5e69642c92340bbcd94c7ff9988d13f07481b9b38cabaac129094e81129bc8d414e352a44
7
+ data.tar.gz: e1539bfb0b731bb01b9ce40a38d888518b32db7dc66bc259fb223bc5b31048a07f388e52f6c22889641f4adb8e280a7c9e06645f6405e4c5cc01b9f461b885f3
data/.gitignore CHANGED
@@ -4,3 +4,5 @@ Gemfile.lock
4
4
  pkg/*
5
5
  doc/*
6
6
  .rvmrc
7
+ use-cases/
8
+ .idea*
@@ -1,4 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.2
4
3
  - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.1
@@ -1,4 +1,4 @@
1
- = Vend API Gem
1
+ = Vend API Gem {<img src="https://travis-ci.org/trineo/vend-ruby.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/trineo/vend-ruby]
2
2
 
3
3
  This gem provides access to Vend's REST API.
4
4
 
@@ -6,3 +6,40 @@ This gem provides access to Vend's REST API.
6
6
 
7
7
  At the time of writing, this is located at
8
8
  https://docs.google.com/document/pub?id=13JiV6771UcrkmawFRxzvVl3tf5PGSTBH56RYy0-5cps
9
+
10
+ == Using Vend API via Oauth 2.0
11
+
12
+ You will need to implement the following steps to connect your application to a Vend Retailer account.
13
+
14
+ =====1 Requesting authorisation url. User must be redirected to this url in order to receive authorisation code.
15
+
16
+ auth_code = Vend::Oauth2::AuthCode.new(STORE, CLIENT_ID, SECRET, REDIRECT_URI)
17
+ url = auth_code.authorize_url
18
+
19
+ Url will look like:
20
+ https://secure.vendhq.com/connect?response_type=code&client_id={client_id}&redirect_uri={redirect_uri}&state={state}
21
+
22
+ After successful authorisation, you will be redirected to:
23
+ {redirect_uri}?code={code}&domain_prefix={domain_prefix}&state={state}
24
+
25
+
26
+ =====2 Requesting access token.
27
+
28
+ auth_code = Vend::Oauth2::AuthCode.new(STORE, CLIENT_ID, SECRET, REDIRECT_URI)
29
+ token = auth_code.token_from_code(params[:code])
30
+
31
+ Where <b>token</b> is an instance of OAuth2::AccessToken http://www.rubydoc.info/gems/oauth2/1.0.0/OAuth2/AccessToken
32
+
33
+ =====3 Using the token to access the Vend API.
34
+
35
+ client = Vend::Oauth2::Client.new(STORE, AUTH_TOKEN)
36
+ client.Product.all.each do |product|
37
+ puts product.name
38
+ end
39
+
40
+ =====4 Refreshing the access token
41
+
42
+ auth_code = Vend::Oauth2::AuthCode.new(STORE, CLIENT_ID, SECRET, REDIRECT_URI)
43
+ token = auth_code.refresh_token(auth_token, refresh_token)
44
+
45
+ The response payload may include a refresh token, if so, you need to update your currently stored refresh token.
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require "bundler/gem_tasks"
2
2
 
3
3
  require 'rubygems'
4
4
  require 'rspec/core/rake_task'
5
- require 'rake/rdoctask'
5
+ require 'rdoc/task'
6
6
 
7
7
  Dir.glob('lib/tasks/*.rake').each { |r| import r }
8
8
 
@@ -22,3 +22,6 @@ require 'vend/resource/user'
22
22
 
23
23
  require 'vend/http_client'
24
24
  require 'vend/client'
25
+
26
+ require 'vend/oauth2/client'
27
+ require 'vend/oauth2/auth_code'
@@ -1,5 +1,4 @@
1
1
  module Vend
2
-
3
2
  # This Base class provides the basic mapping between Vend::Resource subclasses
4
3
  # and the HTTP endpoints in the Vend API.
5
4
  #
@@ -90,9 +89,9 @@ module Vend
90
89
  end
91
90
  available_scopes << method_name
92
91
  end
93
-
92
+
94
93
  def self.findable_by(field, options = {})
95
-
94
+
96
95
  (class << self ; self ; end).instance_eval do
97
96
  define_method("find_by_#{field}") do |client, *args|
98
97
  search(client, options[:as] || field, *args)
@@ -10,13 +10,14 @@ module Vend
10
10
 
11
11
  include Logable
12
12
 
13
- attr_accessor :base_url, :verify_ssl, :username, :password
13
+ attr_accessor :base_url, :verify_ssl, :username, :password, :auth_token
14
14
  alias :verify_ssl? :verify_ssl
15
15
 
16
16
  def initialize(options = {})
17
17
  @base_url = options[:base_url]
18
18
  @username = options[:username]
19
19
  @password = options[:password]
20
+ @auth_token = options[:auth_token]
20
21
  @verify_ssl = if options.has_key?(:verify_ssl)
21
22
  options[:verify_ssl]
22
23
  else
@@ -74,7 +75,8 @@ module Vend
74
75
  # FIXME extract method
75
76
  method = ("Net::HTTP::" + options[:method].to_s.classify).constantize
76
77
  request = method.new(url.path + url_params_for(options[:url_params]))
77
- request.basic_auth username, password
78
+ request.basic_auth username, password if username && password
79
+ request['Authorization'] = "Bearer #{auth_token}" if auth_token
78
80
 
79
81
  request.body = options[:body] if options[:body]
80
82
  logger.debug url
@@ -0,0 +1,48 @@
1
+ require 'oauth2'
2
+
3
+ module Vend
4
+ module Oauth2
5
+
6
+ class AuthCode
7
+
8
+ DEFAULT_OPTIONS = {}
9
+ AUTHORIZE_URL = '/connect'
10
+ TOKEN_URL = '/api/1.0/token'
11
+
12
+ attr_accessor :store, :client_id, :secret, :redirect_uri
13
+
14
+ def initialize(store, client_id, secret, redirect_uri, options = {})
15
+ @store = store
16
+ @client_id = client_id
17
+ @secret = secret
18
+ @redirect_uri = redirect_uri
19
+ @options = DEFAULT_OPTIONS.merge(options)
20
+ end
21
+
22
+ def authorize_url
23
+ get_oauth2_client.auth_code.authorize_url(:redirect_uri => redirect_uri)
24
+ end
25
+
26
+ def token_from_code(code)
27
+ client = get_oauth2_client(store)
28
+ client.auth_code.get_token(code, :redirect_uri => redirect_uri)
29
+ end
30
+
31
+ def refresh_token(auth_token, refresh_token)
32
+ access_token = OAuth2::AccessToken.new(get_oauth2_client(store), auth_token, {refresh_token: refresh_token})
33
+ access_token.refresh!
34
+ end
35
+
36
+ protected
37
+ def get_oauth2_client(domain_prefix = 'secure')
38
+ OAuth2::Client.new(client_id, secret, {
39
+ site: "https://#{domain_prefix}.vendhq.com",
40
+ authorize_url: AUTHORIZE_URL,
41
+ token_url: TOKEN_URL
42
+ })
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,31 @@
1
+ module Vend
2
+ module Oauth2
3
+
4
+ class Client < Vend::Client
5
+
6
+ DEFAULT_OPTIONS = {}
7
+
8
+ include Logable
9
+
10
+ attr_accessor :store, :auth_token
11
+
12
+ def initialize(store, auth_token, options = {})
13
+ @store = store
14
+ @auth_token = auth_token
15
+ @options = DEFAULT_OPTIONS.merge(options)
16
+ end
17
+
18
+ def http_client
19
+ @http_client ||= Vend::HttpClient.new(http_client_options)
20
+ end
21
+
22
+ def http_client_options
23
+ options.merge(
24
+ :auth_token => @auth_token, :base_url => base_url
25
+ )
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+ end
@@ -90,7 +90,7 @@ module Vend
90
90
  end
91
91
 
92
92
  def get_scope(name)
93
-
93
+
94
94
  result = scopes.find { |scope| scope.name == name }
95
95
  if result.nil?
96
96
  raise ScopeNotFoundError.new(
@@ -1,3 +1,3 @@
1
1
  module Vend #:nodoc:
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Vend::Resource::Product do
4
-
5
4
  let(:expected_attributes) do
6
5
  {
7
6
  'id' => '6cc53042-3d5f-11e0-8697-4040f540b50a',
@@ -2,13 +2,16 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  require 'rubygems'
3
3
  require 'bundler/setup'
4
4
  require 'webmock/rspec'
5
+ require 'rspec/its'
6
+ require 'pry'
5
7
  Dir["./spec/support/**/*.rb"].each {|f| require f}
6
8
 
7
9
  require 'cgi'
8
10
  require 'vend'
9
11
 
10
12
  RSpec.configure do |config|
11
-
13
+ config.mock_with(:rspec) { |c| c.syntax = [:should, :expect] }
14
+ config.expect_with(:rspec) { |c| c.syntax = [:should, :expect] }
12
15
  end
13
16
 
14
17
  def get_mock_response(file)
@@ -5,7 +5,7 @@ RSpec::Matchers.define :have_attributes do |expected|
5
5
  end
6
6
  end
7
7
 
8
- failure_message_for_should do |actual|
8
+ failure_message do |actual|
9
9
  "expected #{actual.attrs} to match #{expected}"
10
10
  end
11
11
  end
@@ -18,10 +18,9 @@ def build_receiver
18
18
  end
19
19
 
20
20
  shared_examples "a resource with a collection GET endpoint" do
21
-
22
- let(:username) {"foo"}
23
- let(:password) {"bar"}
24
- let(:store) {"baz"}
21
+ let(:username) { "foo".freeze }
22
+ let(:password) { "bar".freeze }
23
+ let(:store) { "baz".freeze }
25
24
  let(:append_to_url) { '' }
26
25
 
27
26
  let(:client) do
@@ -33,23 +32,23 @@ shared_examples "a resource with a collection GET endpoint" do
33
32
  username, password, store, class_basename.to_s.underscore.pluralize,
34
33
  append_to_url
35
34
  ]
35
+
36
36
  stub_request(:get, url).to_return(
37
37
  :status => 200, :body => get_mock_from_path(:get)
38
38
  )
39
39
 
40
40
  collection = build_receiver.all
41
- collection.count.should == expected_collection_length
41
+ expect(collection.count).to eq(expected_collection_length)
42
42
 
43
43
  first = collection.first
44
- first.should have_attributes(expected_attributes)
44
+ expect(first).to have_attributes(expected_attributes)
45
45
  end
46
46
  end
47
47
 
48
48
  shared_examples "a resource with a singular GET endpoint" do
49
-
50
- let(:username) {"foo"}
51
- let(:password) {"bar"}
52
- let(:store) {"baz"}
49
+ let(:username) { "foo".freeze }
50
+ let(:password) { "bar".freeze }
51
+ let(:store) { "baz".freeze }
53
52
 
54
53
  let(:client) do
55
54
  Vend::Client.new(store, username, password)
@@ -65,21 +64,20 @@ shared_examples "a resource with a singular GET endpoint" do
65
64
  end
66
65
 
67
66
  shared_examples "a resource with a DELETE endpoint" do
68
-
69
- let(:username) {"foo"}
70
- let(:password) {"bar"}
71
- let(:store) {"baz"}
67
+ let(:username) { "foo".freeze }
68
+ let(:password) { "bar".freeze }
69
+ let(:store) { "baz".freeze }
72
70
 
73
71
  let(:client) do
74
72
  Vend::Client.new(store, username, password)
75
73
  end
76
74
 
77
75
  it "deletes the resource" do
76
+
78
77
  stub_request(:delete, "https://#{username}:#{password}@#{store}.vendhq.com/api/#{class_basename.to_s.underscore.pluralize}/#{expected_attributes['id']}").
79
- to_return(:status => 200, :body => {})
78
+ to_return(status: 200, body: {}.to_json)
80
79
 
81
80
  objekt = build_receiver.build(expected_attributes)
82
- objekt.delete.should be_true
81
+ expect(objekt.delete).to be_truthy
83
82
  end
84
-
85
83
  end
@@ -9,7 +9,7 @@ end
9
9
  shared_examples_for "it has a logger" do
10
10
  describe "#logger" do
11
11
 
12
- let(:logger) { mock("logger") }
12
+ let(:logger) { double("logger") }
13
13
 
14
14
  it "defaults to a null logger" do
15
15
  subject.logger.should be_instance_of(Vend::NullLogger)
@@ -7,7 +7,7 @@ describe Vend::BaseFactory do
7
7
  class Vend::Resource::Foo < Vend::Base #:nodoc:
8
8
  end
9
9
 
10
- let(:client) { mock() }
10
+ let(:client) { double() }
11
11
  subject { Vend::Resource::FooFactory.new(client, Vend::Resource::Foo) }
12
12
 
13
13
  it "initializes correctly" do
@@ -5,349 +5,316 @@ describe Vend::Base do
5
5
  url_scope :bar
6
6
  end
7
7
 
8
- let(:client) { mock(:client) }
9
- let(:attribute_hash) { {:key => "value"} }
10
- let(:mock_response) {
11
- {
12
- "foos"=>[
13
- {"id"=>"1","bar"=>"baz"},
14
- {"id"=>"2","flar"=>"flum"}
15
- ]
16
- }
8
+ let(:client) { double(:client) }
9
+ let(:attribute_hash) { { key: 'value', 'id' => 1} }
10
+ let(:mock_response) {
11
+ {
12
+ 'foos'=>[
13
+ {'id'=>'1','bar'=>'baz'},
14
+ {'id'=>'2','flar'=>'flum'}
15
+ ]
16
+ }
17
17
  }
18
18
 
19
19
  subject { Vend::Resource::Foo.new(client, :attrs => attribute_hash) }
20
20
 
21
- it "creates an instance of Foo" do
22
- subject.should be_instance_of(Vend::Resource::Foo)
21
+ it 'creates an instance of Foo' do
22
+ expect(subject).to be_instance_of(Vend::Resource::Foo)
23
23
  end
24
24
 
25
- it "assigns the client" do
26
- subject.client.should == client
25
+ it 'assigns the client' do
26
+ expect(subject.client).to eq client
27
27
  end
28
28
 
29
- it "assigns the attributes" do
30
- subject.attrs.should == attribute_hash
29
+ it 'assigns the attributes' do
30
+ expect(subject.attrs).to eq attribute_hash
31
31
  end
32
32
 
33
33
  describe '.build' do
34
- it "builds a Foo" do
35
- Vend::Resource::Foo.build(client, :attrs => attribute_hash).should
36
- be_instance_of(Vend::Resource::Foo)
34
+ it 'builds a Foo' do
35
+ expect(Vend::Resource::Foo.build(client, attrs: attribute_hash)).to be_instance_of(Vend::Resource::Foo)
37
36
  end
38
37
  end
39
38
 
40
39
  describe '.initialize_singular' do
41
-
42
- it "initializes a singular resource from parsed JSON results" do
43
- resource = Vend::Resource::Foo.initialize_singular(client,mock_response)
44
- resource.should be_a Vend::Resource::Foo
45
- resource.bar.should == "baz"
40
+ it 'initializes a singular resource from parsed JSON results' do
41
+ resource = Vend::Resource::Foo.initialize_singular(client, mock_response)
42
+ expect(resource).to be_a Vend::Resource::Foo
43
+ expect(resource.bar).to eq 'baz'
46
44
  end
47
45
 
48
46
  end
49
47
 
50
48
  describe '.initialize_collection' do
51
-
52
49
  subject { Vend::Resource::Foo }
53
50
 
54
- let(:endpoint) { mock("endpoint") }
55
- let(:args) { mock("args") }
56
- let(:resource_collection) { mock("resource_collection") }
51
+ let(:endpoint) { double('endpoint') }
52
+ let(:args) { double('args') }
53
+ let(:resource_collection) { double('resource_collection') }
57
54
 
58
55
  before do
59
- Vend::ResourceCollection.should_receive(:new).with(
56
+ expect(Vend::ResourceCollection).to receive(:new).with(
60
57
  client, subject, endpoint, args
61
58
  ) { resource_collection }
62
59
  end
63
60
 
64
- it "creates a ResourceCollection instance" do
65
- subject.initialize_collection(
66
- client, endpoint, args
67
- ).should == resource_collection
61
+ it 'creates a ResourceCollection instance' do
62
+ expect(
63
+ subject.initialize_collection(client, endpoint, args)
64
+ ).to eq resource_collection
68
65
  end
69
-
70
66
  end
71
67
 
72
68
  describe '.endpoint_name' do
73
-
74
- it "returns the endpoint name" do
75
- Vend::Resource::Foo.endpoint_name.should == 'foo'
69
+ it 'returns the endpoint name' do
70
+ expect(Vend::Resource::Foo.endpoint_name).to eq 'foo'
76
71
  end
77
-
78
72
  end
79
73
 
80
74
  describe '.collection_name' do
81
-
82
- it "returns the collection name" do
83
- Vend::Resource::Foo.collection_name.should == 'foos'
75
+ it 'returns the collection name' do
76
+ expect(Vend::Resource::Foo.collection_name).to eq 'foos'
84
77
  end
85
-
86
78
  end
87
79
 
88
80
  describe '.singular_name' do
89
-
90
- it "returns the collection name plus the id" do
91
- Vend::Resource::Foo.singular_name("1").should == 'foos/1'
92
- Vend::Resource::Foo.singular_name(42).should == 'foos/42'
81
+ it 'returns the collection name plus the id' do
82
+ expect(Vend::Resource::Foo.singular_name('1')).to eq 'foos/1'
83
+ expect(Vend::Resource::Foo.singular_name(42)).to eq 'foos/42'
93
84
  end
94
-
95
85
  end
96
86
 
97
- describe "#singular_name" do
98
-
99
- let(:singular_name) { mock("singular_name")}
100
- let(:id) { 42 }
101
-
102
- before do
103
- subject.stub(:id => id)
104
- described_class.stub(:singular_name).with(id) { singular_name }
87
+ describe '#singular_name' do
88
+ it :singular_name do
89
+ expect(subject.singular_name).to eq "foos/#{subject.id}"
105
90
  end
106
-
107
- its(:singular_name) { should == singular_name }
108
-
109
91
  end
110
92
 
111
93
  describe '.find' do
112
-
113
94
  let(:id) { 1 }
114
- let(:singular_name) { "foos/1" }
95
+ let(:singular_name) { 'foos/1' }
115
96
 
116
97
  before do
117
98
  Vend::Resource::Foo.stub(:singular_name).with(id) { singular_name }
118
99
  end
119
100
 
120
- it "finds a Foo by id" do
121
- mock_response = {"foos"=>[{"id"=>"1","bar"=>"baz"}]}
122
- client.should_receive(:request).with(singular_name) { mock_response }
101
+ it 'finds a Foo by id' do
102
+ mock_response = { 'foos' => [{ 'id' => '1', 'bar' => 'baz' }]}
103
+ expect(client).to receive(:request).with(singular_name) { mock_response }
123
104
  foo = Vend::Resource::Foo.find(client, id)
124
- foo.should be_instance_of(Vend::Resource::Foo)
125
- foo.bar.should == "baz"
105
+ expect(foo).to be_instance_of(Vend::Resource::Foo)
106
+ expect(foo.bar).to eq 'baz'
126
107
  end
127
-
128
108
  end
129
109
 
130
110
  describe '.all' do
131
-
132
111
  subject { Vend::Resource::Foo }
133
112
 
134
- let(:collection_name) { mock("collection_name") }
135
- let(:resource_collection) { mock("resource_collection") }
113
+ let(:collection_name) { double('collection_name') }
114
+ let(:resource_collection) { double('resource_collection') }
136
115
 
137
116
  before do
138
117
  subject.stub(:collection_name => collection_name)
139
118
  end
140
119
 
141
- it "calls initialize_collection with the collection_name" do
142
- subject.should_receive(:initialize_collection).with(
120
+ it 'calls initialize_collection with the collection_name' do
121
+ expect(subject).to receive(:initialize_collection).with(
143
122
  client, collection_name
144
123
  ) { resource_collection }
145
- subject.all(client).should == resource_collection
124
+ expect(subject.all(client)).to eq resource_collection
146
125
  end
147
-
148
126
  end
149
127
 
150
128
  describe '.url_scope' do
151
-
152
129
  subject { Vend::Resource::Foo }
153
130
 
154
- let(:collection_name) { mock("collection_name") }
155
- let(:resource_collection) { mock("resource_collection") }
156
- let(:bar) { mock("bar") }
131
+ let(:collection_name) { double('collection_name') }
132
+ let(:resource_collection) { double('resource_collection') }
133
+ let(:bar) { double('bar') }
157
134
 
158
135
  before do
159
136
  subject.stub(:collection_name => collection_name)
160
137
  end
161
138
 
162
- it "calls initialize_collection with collection_name and :bar arg" do
163
- subject.should_receive(:initialize_collection).with(
139
+ it 'calls initialize_collection with collection_name and :bar arg' do
140
+ expect(subject).to receive(:initialize_collection).with(
164
141
  client, collection_name
165
142
  ) { resource_collection }
166
- resource_collection.should_receive(:scope).with(:bar, bar) {
143
+ expect(resource_collection).to receive(:scope).with(:bar, bar) {
167
144
  resource_collection
168
145
  }
169
- subject.bar(client, bar).should == resource_collection
146
+ expect(subject.bar(client, bar)).to eq resource_collection
170
147
  end
171
-
172
148
  end
173
149
 
174
- describe ".search" do
175
-
150
+ describe '.search' do
176
151
  subject { Vend::Resource::Foo }
177
152
 
178
- let(:collection_name) { mock("collection_name") }
179
- let(:resource_collection) { mock("resource_collection") }
180
- let(:field) { "field" }
181
- let(:query) { "query" }
153
+ let(:collection_name) { double('collection_name') }
154
+ let(:resource_collection) { double('resource_collection') }
155
+ let(:field) { 'field' }
156
+ let(:query) { 'query' }
182
157
 
183
158
  before do
184
159
  subject.stub(:collection_name => collection_name)
185
160
  end
186
161
 
187
- it "calls initialize_collection with collection_name and :outlet_id arg" do
188
- subject.should_receive(:initialize_collection).with(
162
+ it 'calls initialize_collection with collection_name and :outlet_id arg' do
163
+ expect(subject).to receive(:initialize_collection).with(
189
164
  client, collection_name, :url_params => { field.to_sym => query }
190
165
  ) { resource_collection }
191
- subject.search(client, field, query).should == resource_collection
166
+ expect(subject.search(client, field, query)).to eq resource_collection
192
167
  end
193
-
194
168
  end
195
169
 
196
- describe ".build_from_json" do
197
-
170
+ describe '.build_from_json' do
198
171
  subject { Vend::Resource::Foo }
199
172
 
200
- let(:json) { {"foos" => attributes_array} }
201
- let(:attributes_one) { mock("attributes_one") }
202
- let(:attributes_two) { mock("attributes_two") }
173
+ let(:json) { {'foos' => attributes_array} }
174
+ let(:attributes_one) { double('attributes_one') }
175
+ let(:attributes_two) { double('attributes_two') }
203
176
  let(:attributes_array) { [attributes_one, attributes_two] }
204
- let(:instance_one) { mock("instance_one") }
205
- let(:instance_two) { mock("instance_two") }
177
+ let(:instance_one) { double('instance_one') }
178
+ let(:instance_two) { double('instance_two') }
206
179
 
207
180
  specify do
208
181
  subject.stub(:build).with(client, attributes_one) { instance_one }
209
182
  subject.stub(:build).with(client, attributes_two) { instance_two }
210
- subject.build_from_json(client, json).should == [
183
+ expect(subject.build_from_json(client, json)).to eq [
211
184
  instance_one, instance_two
212
185
  ]
213
186
  end
214
-
215
187
  end
216
188
 
217
- describe "dynamic instance methods" do
218
- let(:attrs) { { "one" => "foo", "two" => "bar", "object_id" => "fail" } }
189
+ describe 'dynamic instance methods' do
190
+ let(:attrs) { { 'one' => 'foo', 'two' => 'bar', 'object_id' => 'fail' } }
219
191
  subject { Vend::Resource::Foo.new(client, :attrs => attrs) }
220
192
 
221
- it "responds to top level attributes" do
222
- subject.should respond_to(:one)
223
- subject.should respond_to(:two)
224
- subject.should respond_to(:object_id)
225
-
226
- subject.one.should == "foo"
227
- subject.two.should == "bar"
228
- subject.object_id.should_not == "fail"
229
- subject.attrs['object_id'].should == "fail"
193
+ it 'responds to top level attributes' do
194
+ expect(subject).to respond_to(:one)
195
+ expect(subject).to respond_to(:two)
196
+ expect(subject).to respond_to(:object_id)
197
+ expect(subject.one).to eq 'foo'
198
+ expect(subject.two).to eq 'bar'
199
+ expect(subject.object_id).to_not eq 'fail'
200
+ expect(subject.attrs['object_id']).to eq 'fail'
230
201
  end
231
202
  end
232
203
 
233
- describe "delete!" do
234
-
235
- context "when id is present" do
204
+ describe 'delete!' do
205
+ context 'when id is present' do
236
206
  subject { Vend::Resource::Foo.new(client, :attrs => {'id' => 1}) }
237
207
 
238
- let(:singular_name) { mock("singular_name")}
208
+ let(:singular_name) { double('singular_name')}
239
209
 
240
210
  before do
241
211
  subject.stub(:singular_name => singular_name)
242
212
  end
243
213
 
244
- it "deletes the object" do
245
- client.should_receive(:request).with(singular_name, :method => :delete)
214
+ it 'deletes the object' do
215
+ expect(client).to receive(:request).with(singular_name, method: :delete)
246
216
  subject.delete!
247
217
  end
248
218
  end
249
219
 
250
- context "when id is absent" do
220
+ context 'when id is absent' do
251
221
  subject { Vend::Resource::Foo.new(client, :attrs => {:foo => 'bar'}) }
252
222
 
253
- it "raises Vend::Resource::IllegalAction" do
254
- client.should_not_receive(:request)
223
+ it 'raises Vend::Resource::IllegalAction' do
224
+ expect(client).to_not receive(:request)
255
225
  expect {
256
226
  subject.delete!
257
- }.to raise_error(Vend::Resource::IllegalAction, "Vend::Resource::Foo has no unique ID")
227
+ }.to raise_error(Vend::Resource::IllegalAction, 'Vend::Resource::Foo has no unique ID')
258
228
  end
259
229
  end
260
-
261
230
  end
262
231
 
263
232
  describe 'delete' do
264
-
265
- it "returns false when no id is present" do
266
- objekt = Vend::Resource::Foo.new(client, :attrs => {:foo => 'bar'})
267
- client.should_not_receive(:request)
268
- objekt.delete.should be_false
233
+ it 'returns false when no id is present' do
234
+ subject = Vend::Resource::Foo.new(client, :attrs => {:foo => 'bar'})
235
+ expect(client).to_not receive(:request)
236
+ expect(subject.delete).to be_falsey
269
237
  end
270
-
271
238
  end
272
239
 
273
240
  describe '.default_collection_request_args' do
274
241
  subject { Vend::Resource::Foo }
275
- its(:default_collection_request_args) { should == {} }
242
+ it :default_collection_request_args do
243
+ expect(subject.default_collection_request_args).to eq({})
244
+ end
276
245
  end
277
246
 
278
- describe ".paginates?" do
279
-
247
+ describe '.paginates?' do
280
248
  subject { Vend::Resource::Foo }
281
249
 
282
- it "defaults to false" do
283
- subject.paginates?.should be_false
250
+ it 'defaults to false' do
251
+ expect(subject.paginates?).to be_falsey
284
252
  end
285
-
286
253
  end
287
254
 
288
- describe ".available_scopes" do
255
+ describe '.available_scopes' do
289
256
  subject { Vend::Resource::Foo }
290
- its(:available_scopes) { should == [:bar] }
257
+ it :available_scopes do
258
+ expect(subject.available_scopes).to eq [:bar]
259
+ end
291
260
  end
292
261
 
293
- describe ".accepts_scope?" do
262
+ describe '.accepts_scope?' do
294
263
  let(:scope_name) {:scope_name}
295
264
  subject { Vend::Resource::Foo }
296
-
297
- context "when scope is accepted" do
265
+
266
+ context 'when scope is accepted' do
298
267
  before do
299
- subject.stub(:available_scopes => [scope_name])
268
+ subject.stub(available_scopes: [scope_name])
300
269
  end
301
270
  specify do
302
- subject.accepts_scope?(scope_name).should be_true
271
+ expect(subject.accepts_scope?(scope_name)).to be_truthy
303
272
  end
304
273
  end
305
274
 
306
- context "when scope is not accepted" do
275
+ context 'when scope is not accepted' do
307
276
  before do
308
- subject.stub(:available_scopes => [])
277
+ subject.stub(available_scopes: [])
309
278
  end
310
279
  specify do
311
- subject.accepts_scope?(scope_name).should be_false
280
+ expect(subject.accepts_scope?(scope_name)).to be_falsey
312
281
  end
313
282
  end
314
283
  end
315
284
 
316
- describe ".findable_by" do
285
+ describe '.findable_by' do
317
286
  subject { Vend::Resource::Foo }
318
287
 
319
- let(:args) { mock("args") }
288
+ let(:args) { double('args') }
320
289
 
321
- it "creates a find_by_foo method on the class" do
322
- subject.should_not respond_to(:find_by_foo)
290
+ it 'creates a find_by_foo method on the class' do
291
+ expect(subject).to_not respond_to(:find_by_foo)
323
292
  subject.findable_by(:foo)
324
- subject.should respond_to(:find_by_foo)
293
+ expect(subject).to respond_to(:find_by_foo)
325
294
  end
326
295
 
327
- it "proxies to search" do
296
+ it 'proxies to search' do
328
297
  subject.findable_by(:foo)
329
- subject.should_receive(:search).with(client, :foo, args)
298
+ expect(subject).to receive(:search).with(client, :foo, args)
330
299
  subject.find_by_foo(client, args)
331
300
  end
332
301
 
333
- it "allows a different method name" do
334
- subject.findable_by(:foo, :as => :bar)
335
- subject.should_receive(:search).with(client, :bar, args)
302
+ it 'allows a different method name' do
303
+ subject.findable_by(:foo, as: :bar)
304
+ expect(subject).to receive(:search).with(client, :bar, args)
336
305
  subject.find_by_foo(client, args)
337
306
  end
338
-
339
307
  end
340
308
 
341
- describe ".cast_attribute" do
342
-
309
+ describe '.cast_attribute' do
343
310
  subject { Vend::Resource::Foo }
344
311
 
345
312
  let(:attrs) { {'floater' => '1.23'} }
346
313
 
347
- it "casts to float" do
314
+ it 'casts to float' do
348
315
  subject.cast_attribute :floater, Float
349
- foo = Vend::Resource::Foo.new(client, :attrs => attrs)
350
- foo.floater.should == 1.23
316
+ foo = Vend::Resource::Foo.new(client, attrs: attrs)
317
+ expect(foo.floater).to eq 1.23
351
318
  end
352
319
  end
353
320
  end