ruby_json_api_client 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +25 -0
- data/Rakefile +2 -0
- data/lib/ruby_json_api_client/adapters/ams_adapter.rb +15 -0
- data/lib/ruby_json_api_client/adapters/json_api_adapter.rb +15 -0
- data/lib/ruby_json_api_client/adapters/rest_adapter.rb +80 -0
- data/lib/ruby_json_api_client/base.rb +98 -0
- data/lib/ruby_json_api_client/collection.rb +13 -0
- data/lib/ruby_json_api_client/serializers/ams_serializer.rb +187 -0
- data/lib/ruby_json_api_client/serializers/json_api_serializer.rb +93 -0
- data/lib/ruby_json_api_client/store.rb +171 -0
- data/lib/ruby_json_api_client/version.rb +3 -0
- data/lib/ruby_json_api_client.rb +14 -0
- data/ruby_json_api_client.gemspec +34 -0
- data/spec/integration/ams/find_spec.rb +46 -0
- data/spec/integration/ams/has_many_links_spec.rb +161 -0
- data/spec/integration/ams/has_many_sideload_spec.rb +170 -0
- data/spec/integration/ams/has_one_links_spec.rb +57 -0
- data/spec/integration/ams/has_one_sideload_spec.rb +87 -0
- data/spec/integration/ams/query_spec.rb +65 -0
- data/spec/integration/json_api/find_spec.rb +44 -0
- data/spec/integration/json_api/query_spec.rb +65 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/support/classes.rb +26 -0
- data/spec/unit/adapters/json_api_spec.rb +4 -0
- data/spec/unit/adapters/rest_spec.rb +109 -0
- data/spec/unit/base_spec.rb +60 -0
- data/spec/unit/collection_spec.rb +17 -0
- data/spec/unit/serializers/ams_spec.rb +480 -0
- data/spec/unit/serializers/json_api_spec.rb +114 -0
- data/spec/unit/store_spec.rb +243 -0
- metadata +262 -0
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "AMS load has_one sideloaded records" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
RubyJsonApiClient::Store.register_adapter(:ams, {
|
7
|
+
hostname: 'www.example.com'
|
8
|
+
});
|
9
|
+
|
10
|
+
RubyJsonApiClient::Store.register_serializer(:ams)
|
11
|
+
|
12
|
+
RubyJsonApiClient::Store.default(:ams)
|
13
|
+
end
|
14
|
+
|
15
|
+
context "using standard sideloading" do
|
16
|
+
before(:each) do
|
17
|
+
response = {
|
18
|
+
person: {
|
19
|
+
id: 123,
|
20
|
+
firstname: "ryan",
|
21
|
+
item_id: 1
|
22
|
+
},
|
23
|
+
items: [{
|
24
|
+
id: 1,
|
25
|
+
name: "first"
|
26
|
+
}, {
|
27
|
+
id: 2,
|
28
|
+
name: "second"
|
29
|
+
}]
|
30
|
+
}.to_json
|
31
|
+
|
32
|
+
stub_request(:get, "http://www.example.com/people/123")
|
33
|
+
.to_return(
|
34
|
+
status: 200,
|
35
|
+
body: response,
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:person) { Person.new(id: 123) }
|
40
|
+
let!(:item) { person.item }
|
41
|
+
|
42
|
+
context "the person" do
|
43
|
+
subject { person }
|
44
|
+
its(:id) { should eq(123) }
|
45
|
+
its(:firstname) { should eq('ryan') }
|
46
|
+
end
|
47
|
+
|
48
|
+
context "the item" do
|
49
|
+
subject { item }
|
50
|
+
its(:name) { should eq('first') }
|
51
|
+
its(:id) { should eq(1) }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "using a different relationship class name" do
|
56
|
+
before(:each) do
|
57
|
+
response = {
|
58
|
+
person: {
|
59
|
+
id: 123,
|
60
|
+
firstname: "ryan",
|
61
|
+
item_id: 1,
|
62
|
+
favorite_item_id: 2
|
63
|
+
},
|
64
|
+
favorite_items: [{
|
65
|
+
id: 1,
|
66
|
+
name: "first"
|
67
|
+
},{
|
68
|
+
id: 2,
|
69
|
+
name: "second"
|
70
|
+
}]
|
71
|
+
}.to_json
|
72
|
+
|
73
|
+
stub_request(:get, "http://www.example.com/people/123")
|
74
|
+
.to_return(
|
75
|
+
status: 200,
|
76
|
+
body: response,
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
let(:person) { Person.new(id: 123) }
|
81
|
+
let(:favorite_item) { person.favorite_item }
|
82
|
+
|
83
|
+
subject { favorite_item }
|
84
|
+
its(:name) { should eq('second') }
|
85
|
+
its(:id) { should eq(2) }
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "AMS query records" do
|
4
|
+
context "that are people" do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
RubyJsonApiClient::Store.register_adapter(:ams, {
|
8
|
+
hostname: 'www.example.com'
|
9
|
+
});
|
10
|
+
|
11
|
+
RubyJsonApiClient::Store.register_serializer(:ams)
|
12
|
+
|
13
|
+
RubyJsonApiClient::Store.default(:ams)
|
14
|
+
end
|
15
|
+
|
16
|
+
context "that exists" do
|
17
|
+
before(:each) do
|
18
|
+
response = {
|
19
|
+
people: [{
|
20
|
+
id: 123,
|
21
|
+
firstname: 'ryan',
|
22
|
+
lastname: 'test'
|
23
|
+
},{
|
24
|
+
id: 456,
|
25
|
+
firstname: 'testing',
|
26
|
+
lastname: 'again'
|
27
|
+
}]
|
28
|
+
}
|
29
|
+
|
30
|
+
json = response.to_json
|
31
|
+
|
32
|
+
stub_request(:get, "http://www.example.com/people?test=true")
|
33
|
+
.to_return(
|
34
|
+
status: 200,
|
35
|
+
headers: { 'Content-Length' => json.size },
|
36
|
+
body: json,
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
let(:result) { Person.where(test: true) }
|
41
|
+
subject { result }
|
42
|
+
|
43
|
+
it { should have(2).people }
|
44
|
+
|
45
|
+
context "verifying the first record" do
|
46
|
+
subject { result[0] }
|
47
|
+
its(:id) { should eq(123) }
|
48
|
+
its(:full_name) { should eq('ryan test') }
|
49
|
+
end
|
50
|
+
|
51
|
+
context "verify the second record" do
|
52
|
+
subject { result[1] }
|
53
|
+
its(:id) { should eq(456) }
|
54
|
+
its(:full_name) { should eq('testing again') }
|
55
|
+
end
|
56
|
+
|
57
|
+
context "and are mappable" do
|
58
|
+
subject { result.map(&:firstname) }
|
59
|
+
it { should have(2).first_names }
|
60
|
+
it { should include('ryan') }
|
61
|
+
it { should include('testing') }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "JSON API find single" do
|
4
|
+
context "person" do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
RubyJsonApiClient::Store.register_adapter(:json_api, {
|
8
|
+
hostname: 'www.example.com'
|
9
|
+
});
|
10
|
+
|
11
|
+
RubyJsonApiClient::Store.register_serializer(:json_api)
|
12
|
+
|
13
|
+
RubyJsonApiClient::Store.default(:json_api)
|
14
|
+
end
|
15
|
+
|
16
|
+
context "it exists" do
|
17
|
+
before(:each) do
|
18
|
+
response = {
|
19
|
+
people: [{
|
20
|
+
id: 123,
|
21
|
+
firstname: 'ryan',
|
22
|
+
lastname: 'test'
|
23
|
+
}]
|
24
|
+
}
|
25
|
+
|
26
|
+
json = response.to_json
|
27
|
+
|
28
|
+
stub_request(:get, "http://www.example.com/people/123")
|
29
|
+
.to_return(
|
30
|
+
status: 200,
|
31
|
+
headers: { 'Content-Length' => json.size },
|
32
|
+
body: json,
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
context "loads the right model" do
|
37
|
+
subject { Person.find(123) }
|
38
|
+
its(:id) { should eq(123) }
|
39
|
+
its(:firstname) { should eq("ryan") }
|
40
|
+
its(:full_name) { should eq("ryan test") }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "JSON API query records" do
|
4
|
+
context "that are people" do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
RubyJsonApiClient::Store.register_adapter(:json_api, {
|
8
|
+
hostname: 'www.example.com'
|
9
|
+
});
|
10
|
+
|
11
|
+
RubyJsonApiClient::Store.register_serializer(:json_api)
|
12
|
+
|
13
|
+
RubyJsonApiClient::Store.default(:json_api)
|
14
|
+
end
|
15
|
+
|
16
|
+
context "that exists" do
|
17
|
+
before(:each) do
|
18
|
+
response = {
|
19
|
+
people: [{
|
20
|
+
id: 123,
|
21
|
+
firstname: 'ryan',
|
22
|
+
lastname: 'test'
|
23
|
+
},{
|
24
|
+
id: 456,
|
25
|
+
firstname: 'testing',
|
26
|
+
lastname: 'again'
|
27
|
+
}]
|
28
|
+
}
|
29
|
+
|
30
|
+
json = response.to_json
|
31
|
+
|
32
|
+
stub_request(:get, "http://www.example.com/people?test=true")
|
33
|
+
.to_return(
|
34
|
+
status: 200,
|
35
|
+
headers: { 'Content-Length' => json.size },
|
36
|
+
body: json,
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
let(:result) { Person.where(test: true) }
|
41
|
+
subject { result }
|
42
|
+
|
43
|
+
it { should have(2).people }
|
44
|
+
|
45
|
+
context "verifying the first record" do
|
46
|
+
subject { result[0] }
|
47
|
+
its(:id) { should eq(123) }
|
48
|
+
its(:full_name) { should eq('ryan test') }
|
49
|
+
end
|
50
|
+
|
51
|
+
context "verify the second record" do
|
52
|
+
subject { result[1] }
|
53
|
+
its(:id) { should eq(456) }
|
54
|
+
its(:full_name) { should eq('testing again') }
|
55
|
+
end
|
56
|
+
|
57
|
+
context "and are mappable" do
|
58
|
+
subject { result.map(&:firstname) }
|
59
|
+
it { should have(2).first_names }
|
60
|
+
it { should include('ryan') }
|
61
|
+
it { should include('testing') }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
class Person < RubyJsonApiClient::Base
|
2
|
+
field :firstname
|
3
|
+
field :lastname
|
4
|
+
|
5
|
+
has_many :items
|
6
|
+
has_many :other_items, class_name: 'Item'
|
7
|
+
|
8
|
+
has_one :item
|
9
|
+
has_one :favorite_item, class_name: 'Item'
|
10
|
+
|
11
|
+
def full_name
|
12
|
+
"#{firstname} #{lastname}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Item < RubyJsonApiClient::Base
|
17
|
+
field :name
|
18
|
+
end
|
19
|
+
|
20
|
+
class CellPhone < RubyJsonApiClient::Base
|
21
|
+
field :number
|
22
|
+
end
|
23
|
+
|
24
|
+
class Thing < RubyJsonApiClient::Base
|
25
|
+
identifier :uuid
|
26
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RubyJsonApiClient::RestAdapter do
|
4
|
+
let(:adapter) do
|
5
|
+
RubyJsonApiClient::RestAdapter.new(
|
6
|
+
hostname: 'www.example.com',
|
7
|
+
namespace: 'testing',
|
8
|
+
secure: true
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe :initialize do
|
13
|
+
subject { adapter }
|
14
|
+
its(:hostname) { should eq('www.example.com') }
|
15
|
+
its(:secure) { should eq(true) }
|
16
|
+
its(:namespace) { should eq('testing') }
|
17
|
+
end
|
18
|
+
|
19
|
+
describe :single_path do
|
20
|
+
context Person do
|
21
|
+
subject { adapter.single_path(Person, { id: 1 }) }
|
22
|
+
it { should == "testing/people/1" }
|
23
|
+
end
|
24
|
+
|
25
|
+
context Thing do
|
26
|
+
subject { adapter.single_path(Thing, { id: 2 }) }
|
27
|
+
it { should == "testing/things/2" }
|
28
|
+
end
|
29
|
+
|
30
|
+
context CellPhone do
|
31
|
+
subject { adapter.single_path(CellPhone, { id: 3 }) }
|
32
|
+
it { should == "testing/cell_phones/3" }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe :collection_path do
|
37
|
+
context Person do
|
38
|
+
subject { adapter.collection_path(Person, {}) }
|
39
|
+
it { should == "testing/people" }
|
40
|
+
end
|
41
|
+
|
42
|
+
context Thing do
|
43
|
+
subject { adapter.collection_path(Thing, {}) }
|
44
|
+
it { should == "testing/things" }
|
45
|
+
end
|
46
|
+
|
47
|
+
context CellPhone do
|
48
|
+
subject { adapter.collection_path(CellPhone, {}) }
|
49
|
+
it { should == "testing/cell_phones" }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe :find do
|
54
|
+
let(:person) { Person.new }
|
55
|
+
|
56
|
+
it "should make the right http request" do
|
57
|
+
status = 200
|
58
|
+
headers = {}
|
59
|
+
body = "{}"
|
60
|
+
|
61
|
+
expect(adapter).to receive(:http_request)
|
62
|
+
.with(:get, "testing/people/1", {})
|
63
|
+
.and_return([status, headers, body])
|
64
|
+
|
65
|
+
expect(adapter.find(Person, 1)).to eq(body)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should raise an error if the status is 500" do
|
69
|
+
status = 500
|
70
|
+
headers = {}
|
71
|
+
body = "{}"
|
72
|
+
|
73
|
+
expect(adapter).to receive(:http_request)
|
74
|
+
.with(:get, "testing/people/1", {})
|
75
|
+
.and_return([status, headers, body])
|
76
|
+
|
77
|
+
expect { adapter.find(Person, 1) }.to raise_error
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe :find_many do
|
82
|
+
let(:person) { Person.new }
|
83
|
+
let(:people) { [person, person] }
|
84
|
+
|
85
|
+
it "should make the right http request" do
|
86
|
+
status = 200
|
87
|
+
headers = {}
|
88
|
+
body = "{}"
|
89
|
+
|
90
|
+
expect(adapter).to receive(:http_request)
|
91
|
+
.with(:get, "testing/people", { sort: :asc })
|
92
|
+
.and_return([status, headers, body])
|
93
|
+
|
94
|
+
expect(adapter.find_many(Person, sort: :asc)).to eq(body)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should error if the status is 500" do
|
98
|
+
status = 500
|
99
|
+
headers = {}
|
100
|
+
body = "{}"
|
101
|
+
|
102
|
+
expect(adapter).to receive(:http_request)
|
103
|
+
.with(:get, "testing/people", { sort: :asc })
|
104
|
+
.and_return([status, headers, body])
|
105
|
+
|
106
|
+
expect { adapter.find_many(Person, sort: :asc) }.to raise_error
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RubyJsonApiClient::Base do
|
4
|
+
class Person < RubyJsonApiClient::Base
|
5
|
+
field :firstname, :string
|
6
|
+
validates :firstname, presence: true
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
describe :field do
|
11
|
+
it "should setup attributes for the model" do
|
12
|
+
person = Person.new
|
13
|
+
person.firstname = 'ryan'
|
14
|
+
expect(person.firstname).to eq 'ryan'
|
15
|
+
end
|
16
|
+
|
17
|
+
context "that has validations" do
|
18
|
+
context "that fail" do
|
19
|
+
subject { Person.new.valid? }
|
20
|
+
it { should eq(false) }
|
21
|
+
end
|
22
|
+
|
23
|
+
context "that pass" do
|
24
|
+
subject { Person.new(firstname: 'ryan').valid? }
|
25
|
+
it { should eq(true) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe :identifer do
|
31
|
+
it "should default to id" do
|
32
|
+
expect(Person._identifier).to eq :id
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should be able to change the identifier" do
|
36
|
+
|
37
|
+
expect(Thing._identifier).to eq :uuid
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe :belongs_to do
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
describe :has_many do
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
describe :persisted? do
|
50
|
+
it "should be persisted if it has an id" do
|
51
|
+
person = Person.new
|
52
|
+
person.instance_variable_set(:@id, 1)
|
53
|
+
expect(person.persisted?).to eql(true)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should not be persisted if there is no id" do
|
57
|
+
expect(Person.new.persisted?).to eql(false)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RubyJsonApiClient::Collection do
|
4
|
+
let(:collection) { RubyJsonApiClient::Collection.new([1,2,3]) }
|
5
|
+
|
6
|
+
subject { collection }
|
7
|
+
|
8
|
+
its(:size) { should eq(3) }
|
9
|
+
its(:first) { should eq(1) }
|
10
|
+
|
11
|
+
context "mappable" do
|
12
|
+
subject { collection.map(&:succ) }
|
13
|
+
it { should have(3).elements }
|
14
|
+
it { should include(2, 3, 4) }
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|