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.
- data/CHANGELOG.md +23 -0
- data/MAINTAINERS +13 -0
- data/README.md +48 -6
- data/lib/puppet_forge.rb +4 -0
- data/lib/puppet_forge/connection.rb +81 -0
- data/lib/puppet_forge/connection/connection_failure.rb +26 -0
- data/lib/puppet_forge/error.rb +34 -0
- data/lib/{her → puppet_forge}/lazy_accessors.rb +20 -27
- data/lib/{her → puppet_forge}/lazy_relations.rb +28 -9
- data/lib/puppet_forge/middleware/symbolify_json.rb +72 -0
- data/lib/puppet_forge/tar.rb +10 -0
- data/lib/puppet_forge/tar/mini.rb +81 -0
- data/lib/puppet_forge/unpacker.rb +68 -0
- data/lib/puppet_forge/v3.rb +11 -0
- data/lib/puppet_forge/v3/base.rb +106 -73
- data/lib/puppet_forge/v3/base/paginated_collection.rb +23 -14
- data/lib/puppet_forge/v3/metadata.rb +197 -0
- data/lib/puppet_forge/v3/module.rb +2 -1
- data/lib/puppet_forge/v3/release.rb +33 -8
- data/lib/puppet_forge/v3/user.rb +2 -0
- data/lib/puppet_forge/version.rb +1 -1
- data/puppet_forge.gemspec +6 -3
- data/spec/fixtures/v3/modules/puppetlabs-apache.json +21 -1
- data/spec/fixtures/v3/releases/puppetlabs-apache-0.0.1.json +4 -1
- data/spec/integration/forge/v3/module_spec.rb +79 -0
- data/spec/integration/forge/v3/release_spec.rb +75 -0
- data/spec/integration/forge/v3/user_spec.rb +70 -0
- data/spec/spec_helper.rb +15 -8
- data/spec/unit/forge/connection/connection_failure_spec.rb +30 -0
- data/spec/unit/forge/connection_spec.rb +53 -0
- data/spec/unit/{her → forge}/lazy_accessors_spec.rb +20 -13
- data/spec/unit/{her → forge}/lazy_relations_spec.rb +60 -46
- data/spec/unit/forge/middleware/symbolify_json_spec.rb +63 -0
- data/spec/unit/forge/tar/mini_spec.rb +85 -0
- data/spec/unit/forge/tar_spec.rb +9 -0
- data/spec/unit/forge/unpacker_spec.rb +58 -0
- data/spec/unit/forge/v3/base/paginated_collection_spec.rb +68 -46
- data/spec/unit/forge/v3/base_spec.rb +1 -1
- data/spec/unit/forge/v3/metadata_spec.rb +300 -0
- data/spec/unit/forge/v3/module_spec.rb +14 -36
- data/spec/unit/forge/v3/release_spec.rb +9 -30
- data/spec/unit/forge/v3/user_spec.rb +7 -7
- metadata +127 -41
- checksums.yaml +0 -7
- 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
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -10,18 +10,25 @@ end
|
|
10
10
|
|
11
11
|
require 'puppet_forge'
|
12
12
|
|
13
|
-
module
|
13
|
+
module StubbingFaraday
|
14
|
+
|
14
15
|
def stub_api_for(klass)
|
15
|
-
klass.
|
16
|
-
|
17
|
-
|
18
|
-
|
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(
|
24
|
-
|
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
|
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
|
3
|
+
describe PuppetForge::LazyAccessors do
|
5
4
|
let(:klass) do
|
6
|
-
|
7
|
-
include Her::Model
|
8
|
-
include Her::LazyAccessors
|
5
|
+
class PuppetForge::V3::Thing < PuppetForge::V3::Base
|
9
6
|
|
10
|
-
|
11
|
-
|
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(
|
84
|
-
api.get('/things/1') do
|
85
|
-
[ 200, { 'Content-Type' => 'json' }, remote_data
|
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(
|
126
|
-
api.get('/things/1') do
|
127
|
-
[ 200, { 'Content-Type' => 'json' }, remote_data
|
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
|
5
|
-
|
6
|
-
ctx = self
|
3
|
+
describe PuppetForge::LazyRelations do
|
4
|
+
class PuppetForge::V3::Parent < PuppetForge::V3::Base
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
lazy :relation, 'Thing'
|
7
|
+
lazy :chained, 'Parent'
|
8
|
+
lazy_collection :relations, 'Thing'
|
9
|
+
lazy_collection :parents, 'Parent'
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
lazy_collection :parents, self
|
11
|
+
def uri
|
12
|
+
"/parents/#{slug}"
|
13
|
+
end
|
16
14
|
|
17
|
-
def
|
18
|
-
"
|
15
|
+
def slug
|
16
|
+
"1"
|
19
17
|
end
|
20
18
|
end
|
21
|
-
end
|
22
19
|
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
class PuppetForge::V3::Thing < PuppetForge::V3::Base
|
21
|
+
|
22
|
+
# Needed for #inspect
|
23
|
+
def uri
|
24
|
+
"/things/1"
|
25
|
+
end
|
26
26
|
|
27
|
-
|
28
|
-
|
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
|
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(
|
98
|
-
|
99
|
-
[ 200, { 'Content-Type' => 'json' }, remote_data
|
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(
|
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
|
154
|
+
[ 200, { 'Content-Type' => 'json' }, data ]
|
143
155
|
end
|
144
|
-
end
|
145
156
|
|
146
|
-
|
147
|
-
|
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(
|
171
|
-
api.get('/
|
172
|
-
[ 200, { 'Content-Type' => 'json' }, remote_data
|
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(
|
225
|
-
api.get('/things/1') do
|
226
|
-
[ 200, { 'Content-Type' => 'json' }, remote_data
|
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(
|
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
|
282
|
+
[ 200, { 'Content-Type' => 'json' }, data ]
|
270
283
|
end
|
271
|
-
end
|
272
284
|
|
273
|
-
|
274
|
-
|
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(
|
298
|
-
api.get('/
|
299
|
-
[ 200, { 'Content-Type' => 'json' }, remote_data
|
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
|