puppet_forge 1.0.6 → 2.0.0

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.
Files changed (45) hide show
  1. data/CHANGELOG.md +23 -0
  2. data/MAINTAINERS +13 -0
  3. data/README.md +48 -6
  4. data/lib/puppet_forge.rb +4 -0
  5. data/lib/puppet_forge/connection.rb +81 -0
  6. data/lib/puppet_forge/connection/connection_failure.rb +26 -0
  7. data/lib/puppet_forge/error.rb +34 -0
  8. data/lib/{her → puppet_forge}/lazy_accessors.rb +20 -27
  9. data/lib/{her → puppet_forge}/lazy_relations.rb +28 -9
  10. data/lib/puppet_forge/middleware/symbolify_json.rb +72 -0
  11. data/lib/puppet_forge/tar.rb +10 -0
  12. data/lib/puppet_forge/tar/mini.rb +81 -0
  13. data/lib/puppet_forge/unpacker.rb +68 -0
  14. data/lib/puppet_forge/v3.rb +11 -0
  15. data/lib/puppet_forge/v3/base.rb +106 -73
  16. data/lib/puppet_forge/v3/base/paginated_collection.rb +23 -14
  17. data/lib/puppet_forge/v3/metadata.rb +197 -0
  18. data/lib/puppet_forge/v3/module.rb +2 -1
  19. data/lib/puppet_forge/v3/release.rb +33 -8
  20. data/lib/puppet_forge/v3/user.rb +2 -0
  21. data/lib/puppet_forge/version.rb +1 -1
  22. data/puppet_forge.gemspec +6 -3
  23. data/spec/fixtures/v3/modules/puppetlabs-apache.json +21 -1
  24. data/spec/fixtures/v3/releases/puppetlabs-apache-0.0.1.json +4 -1
  25. data/spec/integration/forge/v3/module_spec.rb +79 -0
  26. data/spec/integration/forge/v3/release_spec.rb +75 -0
  27. data/spec/integration/forge/v3/user_spec.rb +70 -0
  28. data/spec/spec_helper.rb +15 -8
  29. data/spec/unit/forge/connection/connection_failure_spec.rb +30 -0
  30. data/spec/unit/forge/connection_spec.rb +53 -0
  31. data/spec/unit/{her → forge}/lazy_accessors_spec.rb +20 -13
  32. data/spec/unit/{her → forge}/lazy_relations_spec.rb +60 -46
  33. data/spec/unit/forge/middleware/symbolify_json_spec.rb +63 -0
  34. data/spec/unit/forge/tar/mini_spec.rb +85 -0
  35. data/spec/unit/forge/tar_spec.rb +9 -0
  36. data/spec/unit/forge/unpacker_spec.rb +58 -0
  37. data/spec/unit/forge/v3/base/paginated_collection_spec.rb +68 -46
  38. data/spec/unit/forge/v3/base_spec.rb +1 -1
  39. data/spec/unit/forge/v3/metadata_spec.rb +300 -0
  40. data/spec/unit/forge/v3/module_spec.rb +14 -36
  41. data/spec/unit/forge/v3/release_spec.rb +9 -30
  42. data/spec/unit/forge/v3/user_spec.rb +7 -7
  43. metadata +127 -41
  44. checksums.yaml +0 -7
  45. data/lib/puppet_forge/middleware/json_for_her.rb +0 -37
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "uri": "/v3/releases/puppetlabs-apache-0.0.1",
3
+ "slug": "puppetlabs-apache-0.0.1",
3
4
  "module": {
4
5
  "uri": "/v3/modules/puppetlabs-apache",
6
+ "slug": "puppetlabs-apache",
5
7
  "name": "apache",
6
8
  "owner": {
7
9
  "uri": "/v3/users/puppetlabs",
10
+ "slug": "puppetlabs",
8
11
  "username": "puppetlabs",
9
12
  "gravatar_id": "fdd009b7c1ec96e088b389f773e87aec"
10
13
  }
@@ -90,4 +93,4 @@
90
93
  "created_at": "2010-05-20 22:43:44 -0700",
91
94
  "updated_at": "2010-05-20 22:43:44 -0700",
92
95
  "deleted_at": null
93
- }
96
+ }
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+
3
+ describe PuppetForge::V3::Module do
4
+ before do
5
+
6
+ PuppetForge.host = "https://forge-aio01-petest.puppetlabs.com/"
7
+ PuppetForge::V3::Base.conn = PuppetForge::Connection.make_connection(PuppetForge.host, nil, {:ssl => {:verify => false} })
8
+ end
9
+
10
+ context "::find" do
11
+ context "gets information on an existing module and" do
12
+ let (:mod) { PuppetForge::V3::Module.find('puppetforgegemtesting-thorin') }
13
+
14
+ it "returns a PuppetForge::V3::Module." do
15
+ expect(mod).to be_a(PuppetForge::V3::Module)
16
+ end
17
+
18
+ it "exposes the API information." do
19
+ expect(mod).to respond_to(:uri)
20
+ expect(mod).to respond_to(:owner)
21
+ expect(mod).to respond_to(:current_release)
22
+ expect(mod).to respond_to(:releases)
23
+
24
+ expect(mod.uri).to be_a(String)
25
+ expect(mod.owner).to be_a(PuppetForge::V3::User)
26
+ expect(mod.current_release).to be_a(PuppetForge::V3::Release)
27
+ expect(mod.releases.first).to be_a(PuppetForge::V3::Release)
28
+ end
29
+
30
+ end
31
+
32
+ context "raises Faraday::ResourceNotFound when" do
33
+ let (:mod) { PuppetForge::V3::Module.find('puppetforgegemtesting-bilbo') }
34
+
35
+ it "the module does not exist" do
36
+ expect { mod }.to raise_error(Faraday::ResourceNotFound)
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
43
+ context "::where" do
44
+ context "finds matching resources" do
45
+
46
+ it "only returns modules that match the query" do
47
+ modules = PuppetForge::V3::Module.where(:owner => 'puppetforgegemtesting')
48
+
49
+ expect(modules).to be_a(PuppetForge::V3::Base::PaginatedCollection)
50
+ modules.each do |mod|
51
+ expect(mod.owner.username).to eq('puppetforgegemtesting')
52
+ end
53
+
54
+ end
55
+
56
+ it "returns a paginated response" do
57
+ modules = PuppetForge::V3::Module.where(:owner => 'puppetforgegemtesting', :limit => 1)
58
+
59
+ expect(modules.limit).to eq(1)
60
+ expect(modules.total).to eq(2)
61
+
62
+ expect(modules.next).not_to be_nil
63
+ end
64
+
65
+ end
66
+
67
+ context "does not find matching resources" do
68
+ it "returns an empty PaginatedCollection" do
69
+ modules = PuppetForge::V3::Module.where(:owner => 'absentuser')
70
+
71
+ expect(modules).to be_a(PuppetForge::V3::Base::PaginatedCollection)
72
+
73
+ expect(modules.size).to eq(0)
74
+ expect(modules.empty?).to be(true)
75
+ end
76
+ end
77
+ end
78
+ end
79
+
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe PuppetForge::V3::Release do
4
+ before do
5
+ PuppetForge.host = "https://forge-aio01-petest.puppetlabs.com/"
6
+ PuppetForge::V3::Base.conn = PuppetForge::Connection.make_connection(PuppetForge.host, nil, {:ssl => {:verify => false} })
7
+ end
8
+
9
+ context "#find" do
10
+ context "when the release exists," do
11
+
12
+ it "find returns a PuppetForge::V3::Release." do
13
+ release = PuppetForge::V3::Release.find('puppetforgegemtesting-thorin-0.0.1')
14
+
15
+ expect(release).to be_a(PuppetForge::V3::Release)
16
+ end
17
+
18
+ it "it exposes the API information." do
19
+ release = PuppetForge::V3::Release.find('puppetforgegemtesting-thorin-0.0.1')
20
+
21
+ expect(release).to respond_to(:uri)
22
+
23
+ expect(release.uri).to be_a(String)
24
+ end
25
+
26
+ end
27
+
28
+ context "when the release doesn't exist," do
29
+ let (:release) { PuppetForge::V3::Release.find('puppetforgegemtesting-bilbo-0.0.1') }
30
+
31
+ it "find returns nil." do
32
+ expect { release }.to raise_error(Faraday::ResourceNotFound)
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+
39
+ context "::where" do
40
+ context "finds matching resources" do
41
+
42
+ it "only returns releases that match the query" do
43
+ releases = PuppetForge::V3::Release.where(:module => 'puppetforgegemtesting-thorin')
44
+
45
+ expect(releases).to be_a(PuppetForge::V3::Base::PaginatedCollection)
46
+
47
+ expect(releases.first.version).to eq("0.0.2")
48
+ expect(releases[1].version).to eq("0.0.1")
49
+
50
+ end
51
+
52
+ it "returns a paginated response" do
53
+ releases = PuppetForge::V3::Release.where(:module => 'puppetforgegemtesting-thorin', :limit => 1)
54
+
55
+ expect(releases.limit).to eq(1)
56
+ expect(releases.total).to eq(2)
57
+
58
+ expect(releases.next).not_to be_nil
59
+ end
60
+
61
+ end
62
+
63
+ context "does not find matching resources" do
64
+ it "returns an empty PaginatedCollection" do
65
+ releases = PuppetForge::V3::Release.where(:module => 'puppetforgegemtesting-notamodule')
66
+
67
+ expect(releases).to be_a(PuppetForge::V3::Base::PaginatedCollection)
68
+
69
+ expect(releases.size).to eq(0)
70
+ expect(releases.empty?).to be(true)
71
+ end
72
+ end
73
+ end
74
+ end
75
+
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ describe PuppetForge::V3::User do
4
+ before do
5
+ PuppetForge.host = "https://forge-aio01-petest.puppetlabs.com/"
6
+ PuppetForge::V3::Base.conn = PuppetForge::Connection.make_connection(PuppetForge.host, nil, {:ssl => {:verify => false} })
7
+ end
8
+
9
+ context "#find" do
10
+ context "when the user exists," do
11
+
12
+ it "find returns a PuppetForge::V3::User." do
13
+ user = PuppetForge::V3::User.find('puppetforgegemtesting')
14
+ expect(user).to be_a(PuppetForge::V3::User)
15
+ end
16
+
17
+ it "it exposes the API information." do
18
+ user = PuppetForge::V3::User.find('puppetforgegemtesting')
19
+
20
+ expect(user).to respond_to(:uri)
21
+ expect(user).to respond_to(:modules)
22
+
23
+ expect(user.uri).to be_a(String)
24
+ expect(user.modules).to be_a(PuppetForge::V3::Base::PaginatedCollection)
25
+ end
26
+
27
+ end
28
+
29
+ context "when the user doesn't exists," do
30
+ let (:user) { PuppetForge::V3::User.find('notauser') }
31
+
32
+ it "find returns nil." do
33
+ expect { user }.to raise_error(Faraday::ResourceNotFound)
34
+ end
35
+
36
+ end
37
+ end
38
+
39
+ context "::where" do
40
+ context "finds matching resources" do
41
+
42
+ it "returns sorted users" do
43
+ users = PuppetForge::V3::User.where(:sort_by => 'releases')
44
+
45
+ expect(users).to be_a(PuppetForge::V3::Base::PaginatedCollection)
46
+
47
+ previous_releases = users.first.release_count
48
+ users.each do |user|
49
+ expect(user.release_count).to be <= previous_releases
50
+ previous_releases = user.release_count
51
+ end
52
+
53
+ end
54
+
55
+ it "returns a paginated response" do
56
+ users = PuppetForge::V3::User.where(:limit => 1)
57
+
58
+ expect(users.limit).to eq(1)
59
+
60
+ 2.times do
61
+ expect(users).not_to be_nil
62
+ users = users.next
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+ end
70
+
@@ -10,18 +10,25 @@ end
10
10
 
11
11
  require 'puppet_forge'
12
12
 
13
- module StubbingHer
13
+ module StubbingFaraday
14
+
14
15
  def stub_api_for(klass)
15
- klass.use_api begin
16
- Her::API.new :url => "http://api.example.com" do |c|
17
- c.use PuppetForge::Middleware::JSONForHer
18
- c.adapter(:test) { |s| yield(s) }
16
+ allow(klass).to receive(:conn) do
17
+ Faraday.new :url => "http://api.example.com" do |builder|
18
+ builder.use PuppetForge::Middleware::SymbolifyJson
19
+ builder.response(:json, :content_type => /\bjson$/)
20
+ builder.response(:raise_error)
21
+ builder.use(:connection_failure)
22
+
23
+ builder.adapter(:test) { |s| yield(s) }
19
24
  end
20
25
  end
26
+
27
+ stubs = Faraday::Adapter::Test::Stubs.new
21
28
  end
22
29
 
23
- def stub_fixture(api, method, path)
24
- api.send(method, path) do |env|
30
+ def stub_fixture(stubs, method, path)
31
+ stubs.send(method, path) do |env|
25
32
  load_fixture([ env[:url].path, env[:url].query ].compact.join('?'))
26
33
  end
27
34
  end
@@ -51,7 +58,7 @@ RSpec.configure do |config|
51
58
  config.run_all_when_everything_filtered = true
52
59
  config.filter_run :focus
53
60
 
54
- config.include StubbingHer
61
+ config.include StubbingFaraday
55
62
 
56
63
  # Run specs in random order to surface order dependencies. If you find an
57
64
  # order dependency and want to debug it, you can fix the order by providing
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ # The adapter NetHttp must be required before the SocketError (used below) is accessible
4
+ require 'faraday/adapter/net_http'
5
+
6
+ describe PuppetForge::Connection::ConnectionFailure do
7
+
8
+ subject do
9
+ Faraday.new('https://my-site.url/some-path') do |builder|
10
+ builder.use(:connection_failure)
11
+
12
+ builder.adapter :test do |stub|
13
+ stub.get('/connectfail') { raise Faraday::ConnectionFailed.new(SocketError.new("getaddrinfo: Name or service not known"), :hi) }
14
+ end
15
+ end
16
+ end
17
+
18
+ it "includes the base URL in the error message" do
19
+ expect {
20
+ subject.get('/connectfail')
21
+ }.to raise_error(Faraday::ConnectionFailed, "Unable to connect to https://my-site.url: getaddrinfo: Name or service not known")
22
+ end
23
+
24
+ it "includes the proxy host in the error message when set" do
25
+ subject.proxy('https://some-unreachable.proxy:3128')
26
+ expect {
27
+ subject.get('/connectfail')
28
+ }.to raise_error(Faraday::ConnectionFailed, "Unable to connect to https://my-site.url (using proxy https://some-unreachable.proxy:3128): getaddrinfo: Name or service not known")
29
+ end
30
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe PuppetForge::Connection do
4
+ before(:each) do
5
+ PuppetForge.host = "https://forgeapi.puppetlabs.com"
6
+ end
7
+
8
+ let(:test_conn) do
9
+ PuppetForge::Connection
10
+ end
11
+
12
+ describe 'creating a new connection' do
13
+
14
+ let(:faraday_stubs) { Faraday::Adapter::Test::Stubs.new }
15
+
16
+ subject { test_conn.make_connection('https://some.site/url', [:test, faraday_stubs]) }
17
+
18
+ it 'parses response bodies with a JSON content-type into a hash' do
19
+ faraday_stubs.get('/json') { [200, {'Content-Type' => 'application/json'}, '{"hello": "world"}'] }
20
+ expect(subject.get('/json').body).to eq(:hello => 'world')
21
+ end
22
+
23
+ it 'returns the response body as-is when the content-type is not JSON' do
24
+ faraday_stubs.get('/binary') { [200, {'Content-Type' => 'application/octet-stream'}, 'I am a big bucket of binary data'] }
25
+ expect(subject.get('/binary').body).to eq('I am a big bucket of binary data')
26
+ end
27
+
28
+ it 'raises errors when the request has an error status code' do
29
+ faraday_stubs.get('/error') { [503, {}, "The server caught fire and cannot service your request right now"] }
30
+
31
+ expect {
32
+ subject.get('/error')
33
+ }.to raise_error(Faraday::ClientError, "the server responded with status 503")
34
+ end
35
+
36
+ context 'when an authorization value is provided' do
37
+ before(:each) do
38
+ allow(described_class).to receive(:authorization).and_return("auth-test value")
39
+ end
40
+
41
+ it 'sets authorization header on requests' do
42
+ expect(subject.headers).to include(:authorization => "auth-test value")
43
+ end
44
+ end
45
+ end
46
+
47
+ describe 'creating a default connection' do
48
+ it 'creates a connection with the PuppetForge host' do
49
+ conn = test_conn.default_connection
50
+ expect(conn.url_prefix.to_s).to eq 'https://forgeapi.puppetlabs.com/'
51
+ end
52
+ end
53
+ end
@@ -1,14 +1,17 @@
1
1
  require 'spec_helper'
2
- require 'json'
3
2
 
4
- describe Her::LazyAccessors do
3
+ describe PuppetForge::LazyAccessors do
5
4
  let(:klass) do
6
- Class.new do
7
- include Her::Model
8
- include Her::LazyAccessors
5
+ class PuppetForge::V3::Thing < PuppetForge::V3::Base
9
6
 
10
- def request_path
11
- "/things/#{id}"
7
+ # Needed for #inspect
8
+ def uri
9
+ "/things/1"
10
+ end
11
+
12
+ # Needed for fetch
13
+ def slug
14
+ "1"
12
15
  end
13
16
 
14
17
  def standalone_method
@@ -30,9 +33,13 @@ describe Her::LazyAccessors do
30
33
  def remote_shadow
31
34
  "-#{super}-"
32
35
  end
36
+
33
37
  end
38
+
39
+ PuppetForge::V3::Thing
34
40
  end
35
41
 
42
+ let(:base_class) { PuppetForge::V3::Base }
36
43
  let(:local_data) { { :id => 1, :local => 'data', :shadow => 'x' } }
37
44
  let(:remote_data) { local_data.merge(:remote => 'DATA', :remote_shadow => 'X') }
38
45
 
@@ -80,9 +87,9 @@ describe Her::LazyAccessors do
80
87
 
81
88
  describe 'remote attributes' do
82
89
  before do
83
- stub_api_for(klass) do |api|
84
- api.get('/things/1') do
85
- [ 200, { 'Content-Type' => 'json' }, remote_data.to_json ]
90
+ stub_api_for(base_class) do |api|
91
+ api.get('/v3/things/1') do
92
+ [ 200, { 'Content-Type' => 'json' }, remote_data ]
86
93
  end
87
94
  end
88
95
  end
@@ -122,9 +129,9 @@ describe Her::LazyAccessors do
122
129
 
123
130
  describe 'unsatisfiable attributes' do
124
131
  before do
125
- stub_api_for(klass) do |api|
126
- api.get('/things/1') do
127
- [ 200, { 'Content-Type' => 'json' }, remote_data.to_json ]
132
+ stub_api_for(base_class) do |api|
133
+ api.get('/v3/things/1') do
134
+ [ 200, { 'Content-Type' => 'json' }, remote_data ]
128
135
  end
129
136
  end
130
137
  end
@@ -1,31 +1,32 @@
1
1
  require 'spec_helper'
2
- require 'json'
3
2
 
4
- describe Her::LazyRelations do
5
- let(:klass) do |*args|
6
- ctx = self
3
+ describe PuppetForge::LazyRelations do
4
+ class PuppetForge::V3::Parent < PuppetForge::V3::Base
7
5
 
8
- Class.new do
9
- include Her::Model
10
- include Her::LazyRelations
6
+ lazy :relation, 'Thing'
7
+ lazy :chained, 'Parent'
8
+ lazy_collection :relations, 'Thing'
9
+ lazy_collection :parents, 'Parent'
11
10
 
12
- lazy :relation, ctx.related_class
13
- lazy :chained, self
14
- lazy_collection :relations, ctx.related_class
15
- lazy_collection :parents, self
11
+ def uri
12
+ "/parents/#{slug}"
13
+ end
16
14
 
17
- def request_path
18
- "/parents/#{id}"
15
+ def slug
16
+ "1"
19
17
  end
20
18
  end
21
- end
22
19
 
23
- let(:related_class) do
24
- Class.new do
25
- include Her::Model
20
+ class PuppetForge::V3::Thing < PuppetForge::V3::Base
21
+
22
+ # Needed for #inspect
23
+ def uri
24
+ "/things/1"
25
+ end
26
26
 
27
- def request_path
28
- "/things/#{id}"
27
+ # Needed for fetch
28
+ def slug
29
+ "1"
29
30
  end
30
31
 
31
32
  def standalone_method
@@ -47,7 +48,16 @@ describe Her::LazyRelations do
47
48
  def remote_shadow
48
49
  "-#{super}-"
49
50
  end
51
+
50
52
  end
53
+
54
+ let(:base_class) { PuppetForge::V3::Base }
55
+ let(:klass) do |*args|
56
+ PuppetForge::V3::Parent
57
+ end
58
+
59
+ let(:related_class) do
60
+ PuppetForge::V3::Thing
51
61
  end
52
62
 
53
63
  let(:local_data) { { :id => 1, :local => 'data', :shadow => 'x' } }
@@ -56,7 +66,9 @@ describe Her::LazyRelations do
56
66
  describe '.lazy' do
57
67
  subject { klass.new(:relation => local_data).relation }
58
68
 
59
- it { should be_a(related_class) }
69
+ it do
70
+ should be_a(related_class)
71
+ end
60
72
 
61
73
  it 'does not call methods to #inspect' do
62
74
  expect(subject).not_to receive(:shadow)
@@ -94,9 +106,9 @@ describe Her::LazyRelations do
94
106
 
95
107
  describe 'remote attributes' do
96
108
  before do
97
- stub_api_for(related_class) do |api|
98
- api.get('/things/1') do
99
- [ 200, { 'Content-Type' => 'json' }, remote_data.to_json ]
109
+ stub_api_for(base_class) do |stubs|
110
+ stubs.get('/v3/things/1') do
111
+ [ 200, { 'Content-Type' => 'json' }, remote_data ]
100
112
  end
101
113
  end
102
114
  end
@@ -136,18 +148,17 @@ describe Her::LazyRelations do
136
148
 
137
149
  describe 'remote relations' do
138
150
  before do
139
- stub_api_for(klass) do |api|
140
- api.get('/parents/1') do
151
+ stub_api_for(base_class) do |api|
152
+ api.get('/v3/parents/1') do
141
153
  data = { :id => 1, :relation => local_data }
142
- [ 200, { 'Content-Type' => 'json' }, data.to_json ]
154
+ [ 200, { 'Content-Type' => 'json' }, data ]
143
155
  end
144
- end
145
156
 
146
- stub_api_for(related_class) do |api|
147
- api.get('/things/1') do
148
- [ 200, { 'Content-Type' => 'json' }, remote_data.to_json ]
157
+ api.get('/v3/things/1') do
158
+ [ 200, { 'Content-Type' => 'json' }, remote_data ]
149
159
  end
150
160
  end
161
+
151
162
  end
152
163
 
153
164
  subject { klass.new(:chained => { :id => 1 }) }
@@ -167,13 +178,15 @@ describe Her::LazyRelations do
167
178
 
168
179
  describe 'unsatisfiable attributes' do
169
180
  before do
170
- stub_api_for(klass) do |api|
171
- api.get('/things/1') do
172
- [ 200, { 'Content-Type' => 'json' }, remote_data.to_json ]
181
+ stub_api_for(base_class) do |api|
182
+ api.get('/v3/parents/1') do
183
+ [ 200, { 'Content-Type' => 'json' }, remote_data ]
173
184
  end
174
185
  end
175
186
  end
176
187
 
188
+ subject { klass.new(local_data) }
189
+
177
190
  example 'raise an exception when accessing an unknown attribute' do
178
191
  expect { subject.unknown_attribute }.to raise_error(NoMethodError)
179
192
  end
@@ -221,9 +234,9 @@ describe Her::LazyRelations do
221
234
 
222
235
  describe 'remote attributes' do
223
236
  before do
224
- stub_api_for(related_class) do |api|
225
- api.get('/things/1') do
226
- [ 200, { 'Content-Type' => 'json' }, remote_data.to_json ]
237
+ stub_api_for(base_class) do |api|
238
+ api.get('/v3/things/1') do
239
+ [ 200, { 'Content-Type' => 'json' }, remote_data ]
227
240
  end
228
241
  end
229
242
  end
@@ -263,18 +276,17 @@ describe Her::LazyRelations do
263
276
 
264
277
  describe 'remote relations' do
265
278
  before do
266
- stub_api_for(klass) do |api|
267
- api.get('/parents/1') do
279
+ stub_api_for(base_class) do |api|
280
+ api.get('/v3/parents/1') do
268
281
  data = { :id => 1, :parents => [{ :id => 1, :relation => local_data }] }
269
- [ 200, { 'Content-Type' => 'json' }, data.to_json ]
282
+ [ 200, { 'Content-Type' => 'json' }, data ]
270
283
  end
271
- end
272
284
 
273
- stub_api_for(related_class) do |api|
274
- api.get('/things/1') do
275
- [ 200, { 'Content-Type' => 'json' }, remote_data.to_json ]
285
+ api.get('/v3/things/1') do
286
+ [ 200, { 'Content-Type' => 'json' }, remote_data ]
276
287
  end
277
288
  end
289
+
278
290
  end
279
291
 
280
292
  subject { klass.new(:id => 1) }
@@ -294,13 +306,15 @@ describe Her::LazyRelations do
294
306
 
295
307
  describe 'unsatisfiable attributes' do
296
308
  before do
297
- stub_api_for(klass) do |api|
298
- api.get('/things/1') do
299
- [ 200, { 'Content-Type' => 'json' }, remote_data.to_json ]
309
+ stub_api_for(base_class) do |api|
310
+ api.get('/v3/parents/1') do
311
+ [ 200, { 'Content-Type' => 'json' }, remote_data ]
300
312
  end
301
313
  end
302
314
  end
303
315
 
316
+ subject { klass.new(local_data) }
317
+
304
318
  example 'raise an exception when accessing an unknown attribute' do
305
319
  expect { subject.unknown_attribute }.to raise_error(NoMethodError)
306
320
  end