api_resource 0.6.21 → 0.6.22
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.
- checksums.yaml +4 -4
- data/.yardopts +1 -0
- data/Gemfile.lock +1 -1
- data/LICENSE.txt +22 -0
- data/README.md +16 -9
- data/docs/Attributes.md +64 -0
- data/docs/Caching.md +45 -0
- data/docs/GettingStarted.md +149 -0
- data/docs/Relationships.md +136 -0
- data/docs/ResourceDefinition.md +80 -0
- data/docs/Retrieval.md +279 -0
- data/docs/Serialization.md +56 -0
- data/lib/api_resource/associations/has_many_remote_object_proxy.rb +2 -2
- data/lib/api_resource/attributes.rb +16 -4
- data/lib/api_resource/base.rb +98 -19
- data/lib/api_resource/conditions/abstract_condition.rb +241 -129
- data/lib/api_resource/conditions/include_condition.rb +7 -1
- data/lib/api_resource/conditions/pagination_condition.rb +37 -0
- data/lib/api_resource/conditions/where_condition.rb +19 -0
- data/lib/api_resource/conditions.rb +18 -2
- data/lib/api_resource/connection.rb +27 -13
- data/lib/api_resource/exceptions.rb +11 -11
- data/lib/api_resource/finders/abstract_finder.rb +176 -95
- data/lib/api_resource/finders/multi_object_association_finder.rb +10 -9
- data/lib/api_resource/finders/resource_finder.rb +59 -49
- data/lib/api_resource/finders/single_finder.rb +5 -6
- data/lib/api_resource/finders/single_object_association_finder.rb +52 -51
- data/lib/api_resource/finders.rb +1 -1
- data/lib/api_resource/formats/file_upload_format.rb +75 -0
- data/lib/api_resource/formats.rb +4 -1
- data/lib/api_resource/response.rb +108 -0
- data/lib/api_resource/scopes.rb +62 -5
- data/lib/api_resource/serializer.rb +1 -1
- data/lib/api_resource/typecasters/boolean_typecaster.rb +1 -0
- data/lib/api_resource/typecasters/integer_typecaster.rb +1 -0
- data/lib/api_resource/typecasters/time_typecaster.rb +12 -4
- data/lib/api_resource/version.rb +1 -1
- data/lib/api_resource.rb +1 -0
- data/spec/lib/associations/has_one_remote_object_proxy_spec.rb +4 -4
- data/spec/lib/associations_spec.rb +3 -3
- data/spec/lib/attributes_spec.rb +16 -1
- data/spec/lib/base_spec.rb +121 -39
- data/spec/lib/conditions/{abstract_conditions_spec.rb → abstract_condition_spec.rb} +23 -11
- data/spec/lib/conditions/pagination_condition_spec.rb +88 -0
- data/spec/lib/finders/multi_object_association_finder_spec.rb +55 -27
- data/spec/lib/finders/resource_finder_spec.rb +26 -2
- data/spec/lib/finders/single_object_association_finder_spec.rb +14 -6
- data/spec/lib/finders_spec.rb +81 -81
- data/spec/lib/observing_spec.rb +3 -4
- data/spec/lib/response_spec.rb +18 -0
- data/spec/lib/scopes_spec.rb +25 -1
- data/spec/lib/typecasters/boolean_typecaster_spec.rb +1 -1
- data/spec/lib/typecasters/integer_typecaster_spec.rb +1 -1
- data/spec/lib/typecasters/time_typecaster_spec.rb +6 -0
- data/spec/support/files/bg-awesome.jpg +0 -0
- data/spec/support/mocks/test_resource_mocks.rb +26 -16
- data/spec/support/requests/test_resource_requests.rb +27 -23
- metadata +24 -4
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ApiResource
|
4
|
+
|
5
|
+
module Conditions
|
6
|
+
|
7
|
+
describe PaginationCondition do
|
8
|
+
|
9
|
+
context '.paginate' do
|
10
|
+
|
11
|
+
it 'returns an object that knows it is paginated from the base
|
12
|
+
class' do
|
13
|
+
paginated = TestResource.paginate(page: 1, per_page: 10).active
|
14
|
+
expect(paginated).to be_paginated
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'returns an object that knows it is paginated from a scope' do
|
18
|
+
paginated = TestResource.active.paginate(
|
19
|
+
page: 1,
|
20
|
+
per_page: 10
|
21
|
+
)
|
22
|
+
expect(paginated).to be_paginated
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
context '#current_page' do
|
28
|
+
|
29
|
+
it 'knows its page number' do
|
30
|
+
paginated = TestResource.paginate(page: 1, per_page: 10).active
|
31
|
+
expect(paginated.current_page).to be 1
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
context '#offset' do
|
37
|
+
|
38
|
+
it 'passes along the headers for the total number of entries' do
|
39
|
+
paginated = TestResource.paginate(
|
40
|
+
page: 2,
|
41
|
+
per_page: 10
|
42
|
+
)
|
43
|
+
expect(paginated.offset).to be 10
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
context '#per_page' do
|
49
|
+
|
50
|
+
it 'knows its number per page' do
|
51
|
+
paginated = TestResource.paginate(
|
52
|
+
page: 2,
|
53
|
+
per_page: 100
|
54
|
+
)
|
55
|
+
expect(paginated.per_page).to be 100
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
context '#total_entries' do
|
61
|
+
|
62
|
+
it 'passes along the headers for the total number of entries' do
|
63
|
+
paginated = TestResource.paginate(
|
64
|
+
page: 1,
|
65
|
+
per_page: 10
|
66
|
+
)
|
67
|
+
expect(paginated.total_entries).to be 100
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
context '#total_pages' do
|
73
|
+
|
74
|
+
it 'calculates the number of pages' do
|
75
|
+
paginated = TestResource.paginate(
|
76
|
+
page: 1,
|
77
|
+
per_page: 12
|
78
|
+
)
|
79
|
+
expect(paginated.total_pages).to be 9
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -5,39 +5,67 @@ describe "MultiObjectAssociationFinder" do
|
|
5
5
|
before(:each) do
|
6
6
|
TestResource.reload_resource_definition
|
7
7
|
end
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
8
|
+
|
9
|
+
context "#load" do
|
10
|
+
|
11
|
+
it "should build a proper load path and call into the connection" do
|
12
|
+
TestResource.connection.expects(:get).with("test_resources.json?id[]=1&id[]=2").returns([])
|
13
|
+
|
14
|
+
ApiResource::Finders::MultiObjectAssociationFinder.new(
|
15
|
+
TestResource,
|
16
|
+
stub(remote_path: "test_resources", to_query: "id[]=1&id[]=2", :blank_conditions? => false)
|
17
|
+
).load
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should load a has many association properly" do
|
21
|
+
# much of this test already lies in resource_finder_spec.rb
|
22
|
+
# this just verifies that the data is passed in correctly
|
23
|
+
finder = ApiResource::Finders::MultiObjectAssociationFinder.new(
|
24
|
+
TestResource,
|
25
|
+
stub(
|
26
|
+
remote_path: "test_resources",
|
27
|
+
blank_conditions?: true,
|
28
|
+
eager_load?: true,
|
29
|
+
included_objects: [:has_many_objects]
|
30
|
+
)
|
31
|
+
)
|
32
|
+
|
33
|
+
tr = TestResource.new
|
34
|
+
tr.stubs(:id).returns(1)
|
35
|
+
tr.stubs(:has_many_object_ids).returns([1,2])
|
36
|
+
TestResource.connection.expects(:get).with("test_resources.json").returns([4])
|
37
|
+
TestResource.expects(:instantiate_collection).with([4]).returns([tr])
|
38
|
+
|
39
|
+
finder.expects(:load_includes).with(has_many_objects: [1,2]).returns(5)
|
40
|
+
finder.expects(:apply_includes).with([tr], 5).returns(6)
|
41
|
+
|
42
|
+
finder.load.should eql([tr])
|
43
|
+
end
|
16
44
|
end
|
17
45
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
TestResource
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
46
|
+
context "#select" do
|
47
|
+
|
48
|
+
it "properly sends #select to its internal object" do
|
49
|
+
|
50
|
+
TestResource.connection.stubs(:get)
|
51
|
+
.with("test_resources.json?id[]=1&id[]=2")
|
52
|
+
.returns([{"name" => "Dan"}])
|
53
|
+
|
54
|
+
finder = ApiResource::Finders::MultiObjectAssociationFinder.new(
|
55
|
+
TestResource,
|
56
|
+
stub(
|
57
|
+
remote_path: "test_resources",
|
58
|
+
to_query: "id[]=1&id[]=2",
|
59
|
+
blank_conditions?: false,
|
60
|
+
included_objects: [],
|
61
|
+
eager_load?: true
|
62
|
+
)
|
28
63
|
)
|
29
|
-
)
|
30
64
|
|
31
|
-
|
32
|
-
tr.stubs(:id).returns(1)
|
33
|
-
tr.stubs(:has_many_object_ids).returns([1,2])
|
34
|
-
TestResource.connection.expects(:get).with("test_resources.json").returns([4])
|
35
|
-
TestResource.expects(:instantiate_collection).with([4]).returns([tr])
|
65
|
+
expect(finder.select{|r| r.name == 'Dan'}.length).to eql(1)
|
36
66
|
|
37
|
-
|
38
|
-
finder.expects(:apply_includes).with([tr], 5).returns(6)
|
67
|
+
end
|
39
68
|
|
40
|
-
finder.load.should eql([tr])
|
41
69
|
end
|
42
70
|
|
43
71
|
end
|
@@ -4,7 +4,6 @@ describe "ResourceFinder" do
|
|
4
4
|
|
5
5
|
before(:each) do
|
6
6
|
TestResource.reload_resource_definition
|
7
|
-
|
8
7
|
end
|
9
8
|
|
10
9
|
it "should load normally without includes using connection.get" do
|
@@ -20,7 +19,7 @@ describe "ResourceFinder" do
|
|
20
19
|
TestResource.connection.expects(:get).with("/test_resources.json?ids%5B%5D=1&ids%5B%5D=2&ids%5B%5D=3")
|
21
20
|
|
22
21
|
ApiResource::Finders::ResourceFinder.new(
|
23
|
-
TestResource,
|
22
|
+
TestResource,
|
24
23
|
mock(:to_hash => {:ids => [1,2,3]})
|
25
24
|
).load
|
26
25
|
end
|
@@ -75,4 +74,29 @@ describe "ResourceFinder" do
|
|
75
74
|
obj.second.has_many_objects.collect(&:id).should eql([2])
|
76
75
|
end
|
77
76
|
|
77
|
+
context 'Headers returned from the server' do
|
78
|
+
|
79
|
+
context '#total_entries' do
|
80
|
+
|
81
|
+
it 'stores the ApiResource-Total-Entries as total_entries' do
|
82
|
+
|
83
|
+
finder = ApiResource::Finders::ResourceFinder.new(
|
84
|
+
TestResource,
|
85
|
+
ApiResource::Conditions::PaginationCondition.new(
|
86
|
+
TestResource,
|
87
|
+
{ page: 2, per_page: 10 }
|
88
|
+
)
|
89
|
+
)
|
90
|
+
|
91
|
+
finder.load
|
92
|
+
|
93
|
+
expect(finder.total_entries).to be 100
|
94
|
+
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
78
102
|
end
|
@@ -7,12 +7,20 @@ describe "SingleObjectAssociationFinder" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should build a proper load path and call into the connection" do
|
10
|
-
TestResource.connection
|
10
|
+
TestResource.connection
|
11
|
+
.expects(:get)
|
12
|
+
.with("test_resources.json?id[]=1&id[]=2")
|
13
|
+
.returns(nil)
|
11
14
|
|
12
|
-
ApiResource::Finders::SingleObjectAssociationFinder.new(
|
15
|
+
finder = ApiResource::Finders::SingleObjectAssociationFinder.new(
|
13
16
|
TestResource,
|
14
|
-
stub(
|
15
|
-
|
17
|
+
stub(
|
18
|
+
:remote_path => "test_resources",
|
19
|
+
:to_query => "id[]=1&id[]=2",
|
20
|
+
:blank_conditions? => false
|
21
|
+
)
|
22
|
+
)
|
23
|
+
finder.load
|
16
24
|
end
|
17
25
|
|
18
26
|
it "should load a has many association properly" do
|
@@ -21,9 +29,9 @@ describe "SingleObjectAssociationFinder" do
|
|
21
29
|
finder = ApiResource::Finders::SingleObjectAssociationFinder.new(
|
22
30
|
TestResource,
|
23
31
|
stub(
|
24
|
-
:remote_path => "test_resources",
|
32
|
+
:remote_path => "test_resources",
|
25
33
|
:blank_conditions? => true,
|
26
|
-
:eager_load? => true,
|
34
|
+
:eager_load? => true,
|
27
35
|
:included_objects => [:has_many_objects]
|
28
36
|
)
|
29
37
|
)
|
data/spec/lib/finders_spec.rb
CHANGED
@@ -2,114 +2,114 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe ApiResource::Finders do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
before(:each) do
|
6
|
+
TestResource.reload_resource_definition
|
7
|
+
end
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
it "should be able to find a single object" do
|
10
|
+
TestResource.connection.expects(:get).with("/test_resources/1.json")
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
TestResource.find(1)
|
13
|
+
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
it "should be able to find with parameters, params syntax" do
|
16
|
+
TestResource.connection.expects(:get).with("/test_resources.json?active=true")
|
17
|
+
TestResource.all(:params => {:active => true})
|
18
|
+
end
|
19
19
|
|
20
|
-
|
21
|
-
|
20
|
+
it "should be able to find with parameters without the params syntax" do
|
21
|
+
TestResource.connection.expects(:get).with("/test_resources.json?active=true&passive=false")
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
TestResource.all(:active => true, :passive => false)
|
24
|
+
end
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
it "should be able to chain find on top of a scope" do
|
27
|
+
TestResource.connection.expects(:get).with("/test_resources.json?active=true&passive=true")
|
28
|
+
TestResource.active.all(:passive => true)
|
29
|
+
end
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
it "should be able to find a single object as an enumerable after a scope" do
|
32
|
+
TestResource.connection.expects(:get)
|
33
|
+
.with("/test_resources.json?birthday%5Bdate%5D=5&find%5Bids%5D=1").returns([{"id" => 10}])
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
val = TestResource.birthday(5).find(1)
|
36
|
+
val.first.should be_a(TestResource)
|
37
|
+
end
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
it "should be able to find multiple objects after a scope" do
|
40
|
+
TestResource.connection.expects(:get)
|
41
|
+
.with("/test_resources.json?birthday%5Bdate%5D=5&find%5Bids%5D=1").returns([{"id" => 10}, {"id" => 8}])
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
val = TestResource.birthday(5).find(1)
|
44
|
+
val.should be_a(Array)
|
45
|
+
val.first.should be_a(TestResource)
|
46
|
+
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
it "should be able to find the first/last object" do
|
49
|
+
TestResource.connection.expects(:get)
|
50
|
+
.with("/test_resources.json?first=true").returns([{"id" => 10}])
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
val = TestResource.first
|
53
|
+
val.should be_a(TestResource)
|
54
|
+
end
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
56
|
+
it "should pass first and last as params" do
|
57
|
+
TestResource.connection.expects(:get)
|
58
|
+
.with("/test_resources.json?first=true")
|
59
59
|
|
60
|
-
|
60
|
+
val = TestResource.first
|
61
61
|
|
62
|
-
|
63
|
-
|
62
|
+
TestResource.connection.expects(:get)
|
63
|
+
.with("/test_resources.json?last=true")
|
64
64
|
|
65
|
-
|
66
|
-
|
65
|
+
val = TestResource.last
|
66
|
+
end
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
|
68
|
+
it "should not pass all as a param, even when all records are requested" do
|
69
|
+
TestResource.connection.expects(:get)
|
70
|
+
.with("/test_resources.json")
|
71
71
|
|
72
|
-
|
73
|
-
|
72
|
+
val = TestResource.all
|
73
|
+
end
|
74
74
|
|
75
|
-
|
76
|
-
|
77
|
-
|
75
|
+
it "should be able to chain find on top of an includes call" do
|
76
|
+
TestResource.connection.expects(:get).with("/test_resources/1.json").returns({"id" => 1, "has_many_object_ids" => [1,2]})
|
77
|
+
HasManyObject.connection.expects(:get).with("/has_many_objects.json?ids%5B%5D=1&ids%5B%5D=2").returns([])
|
78
78
|
|
79
|
-
|
80
|
-
|
79
|
+
TestResource.includes(:has_many_objects).find(1)
|
80
|
+
end
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
|
82
|
+
it "should be able to chain find on top of an includes call and a scope" do
|
83
|
+
TestResource.connection.expects(:get).with("/test_resources.json?birthday%5Bdate%5D=5&find%5Bids%5D=1").returns({"id" => 1, "has_many_object_ids" => [1,2]})
|
84
|
+
HasManyObject.connection.expects(:get).with("/has_many_objects.json?ids%5B%5D=1&ids%5B%5D=2").returns([])
|
85
85
|
|
86
|
-
|
87
|
-
|
86
|
+
TestResource.includes(:has_many_objects).birthday(5).find(1)
|
87
|
+
end
|
88
88
|
|
89
|
-
|
90
|
-
|
91
|
-
|
89
|
+
it "should disregard condition order" do
|
90
|
+
TestResource.connection.expects(:get).with("/test_resources.json?birthday%5Bdate%5D=5&find%5Bids%5D=1").returns({"id" => 1, "has_many_object_ids" => [1,2]})
|
91
|
+
HasManyObject.connection.expects(:get).with("/has_many_objects.json?ids%5B%5D=1&ids%5B%5D=2").returns([])
|
92
92
|
|
93
|
-
|
94
|
-
|
93
|
+
TestResource.birthday(5).includes(:has_many_objects).find(1)
|
94
|
+
end
|
95
95
|
|
96
|
-
|
97
|
-
|
98
|
-
|
96
|
+
it "should be able to use a scope with arguments" do
|
97
|
+
TestResource.connection.expects(:get)
|
98
|
+
.with("/test_resources.json?active=true&birthday%5Bdate%5D=5").returns([{"id" => 10}])
|
99
99
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
100
|
+
res = TestResource.active.birthday(5).all
|
101
|
+
res.should be_a(Array)
|
102
|
+
res.first.id.should eql(10)
|
103
|
+
end
|
104
104
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
105
|
+
it "should be able to use a scope with multiple arguments" do
|
106
|
+
TestResource.connection.expects(:get)
|
107
|
+
.with("/test_resources.json?boolean%5Ba%5D=5&boolean%5Bb%5D=10")
|
108
|
+
.returns([{:id => 20}])
|
109
109
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
110
|
+
res = TestResource.boolean(5, 10).all
|
111
|
+
res.should be_a(Array)
|
112
|
+
res.first.id.should eql(20)
|
113
|
+
end
|
114
114
|
|
115
115
|
end
|
data/spec/lib/observing_spec.rb
CHANGED
@@ -77,16 +77,15 @@ describe "Observing" do
|
|
77
77
|
end
|
78
78
|
|
79
79
|
it "should run callbacks before observers" do
|
80
|
-
|
81
|
-
klass.class_eval <<-EOE, __FILE__, __LINE__ + 1
|
80
|
+
class ChildObserverResource < TestResource
|
82
81
|
before_save :abort_save
|
83
82
|
|
84
83
|
def abort_save
|
85
84
|
return false
|
86
85
|
end
|
87
|
-
|
86
|
+
end
|
88
87
|
|
89
|
-
tr =
|
88
|
+
tr = ChildObserverResource.new
|
90
89
|
tr.expects(:abort_save).returns(false)
|
91
90
|
tr.expects(:notify_observers).never
|
92
91
|
tr.expects(:save_without_callbacks).never
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ApiResource
|
4
|
+
|
5
|
+
describe Response do
|
6
|
+
|
7
|
+
context '#initialize' do
|
8
|
+
|
9
|
+
it 'handles a blank body' do
|
10
|
+
raw_response = stub(headers: {}, body: nil)
|
11
|
+
expect(Response.new(raw_response)).to be_blank
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
data/spec/lib/scopes_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ApiResource::Scopes do
|
4
|
-
|
4
|
+
|
5
5
|
before(:all) do
|
6
6
|
ScopeResource.class_eval do
|
7
7
|
scope :no_arg, {}
|
@@ -12,6 +12,7 @@ describe ApiResource::Scopes do
|
|
12
12
|
scope :req_and_opt_args, {arg1: :req, arg2: :opt}
|
13
13
|
scope :var_args, {ids: :rest}
|
14
14
|
scope :mix_args, {id: :req, vararg: :rest}
|
15
|
+
scope :date_scope, {start_date: :req, end_date: :req}
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
@@ -59,6 +60,18 @@ describe ApiResource::Scopes do
|
|
59
60
|
ScopeResource.add_scopes(one_arg: {id: 5})
|
60
61
|
end
|
61
62
|
|
63
|
+
it 'does not apply scopes with a blank argument' do
|
64
|
+
ScopeResource.expects(:one_arg).never
|
65
|
+
ScopeResource.add_scopes(one_arg: {id: ""})
|
66
|
+
ScopeResource.add_scopes(one_arg: {id: nil})
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'does not apply scopes when a parameter is missing' do
|
70
|
+
ScopeResource.expects(:two_args).never
|
71
|
+
ScopeResource.add_scopes(two_args: { page: 1 })
|
72
|
+
ScopeResource.add_scopes(two_args: { per_page: 1 })
|
73
|
+
end
|
74
|
+
|
62
75
|
it 'applies scopes with an array argument' do
|
63
76
|
ScopeResource.expects(:one_array_arg).with([5]).returns(ScopeResource)
|
64
77
|
ScopeResource.add_scopes(one_array_arg: {ids: [5]})
|
@@ -93,6 +106,17 @@ describe ApiResource::Scopes do
|
|
93
106
|
ScopeResource.expects(:mix_args).with(4,[5,6,7]).returns(ScopeResource)
|
94
107
|
ScopeResource.add_scopes(mix_args: {id: 4, vararg: [5,6,7]})
|
95
108
|
end
|
109
|
+
|
110
|
+
it 'parses dates if the parameters are correctly named' do
|
111
|
+
ScopeResource.expects(:date_scope)
|
112
|
+
.with(instance_of(Date), instance_of(Date))
|
113
|
+
.returns(ScopeResource)
|
114
|
+
|
115
|
+
ScopeResource.add_scopes({
|
116
|
+
date_scope: { start_date: 'May 6, 2013', end_date: 'June 8, 2014' }
|
117
|
+
})
|
118
|
+
end
|
119
|
+
|
96
120
|
end
|
97
121
|
|
98
122
|
end
|
@@ -13,7 +13,7 @@ describe ApiResource::Typecast::BooleanTypecaster do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should return false for any other conceivable input" do
|
16
|
-
[Date.new, Time.new, Date.today, Time.now,
|
16
|
+
[Date.new, Time.new, Date.today, Time.now, false, Float, 2.0, 2, "", "bad value"].each do |val|
|
17
17
|
klass.from_api(val).should be_instance_of(FalseClass)
|
18
18
|
end
|
19
19
|
end
|
@@ -22,7 +22,7 @@ describe ApiResource::Typecast::IntegerTypecaster do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should be able to typecast any value you can think of" do
|
25
|
-
klass.from_api(nil).should eql(
|
25
|
+
klass.from_api(nil).should eql(nil)
|
26
26
|
klass.from_api("").should eql(nil)
|
27
27
|
klass.from_api(BasicObject).should eql(0)
|
28
28
|
klass.from_api("abc").should eql(0)
|
@@ -29,6 +29,12 @@ describe ApiResource::Typecast::TimeTypecaster do
|
|
29
29
|
val.day.should eql(28)
|
30
30
|
end
|
31
31
|
|
32
|
+
it "should parse a date not in ISO format with a time zone" do
|
33
|
+
val = klass.from_api("2012-12-21T19:29:20-04:00")
|
34
|
+
val.hour.should eql(23)
|
35
|
+
val.zone.to_s.should eql("UTC")
|
36
|
+
end
|
37
|
+
|
32
38
|
it "should parse a date not in ISO format" do
|
33
39
|
val = klass.from_api("2012/08/09")
|
34
40
|
val.year.should eql(2012)
|
Binary file
|
@@ -1,47 +1,57 @@
|
|
1
1
|
include ApiResource
|
2
2
|
|
3
3
|
Mocks.define do
|
4
|
-
|
4
|
+
|
5
5
|
endpoint("/test_resources/new") do
|
6
6
|
get(HashDealer.roll(:new_test_object))
|
7
|
+
get(HashDealer.roll(:new_test_object), params: {type: 'X'}.matcher)
|
7
8
|
end
|
8
|
-
|
9
|
+
|
9
10
|
endpoint("/test_resources") do
|
10
|
-
post(HashDealer.roll(:test_resource).merge(:
|
11
|
-
post(HashDealer.roll(:test_resource).merge(:
|
11
|
+
post(HashDealer.roll(:test_resource).merge(id: 1), params: {test_resource: HashDealer.roll(:test_resource).matcher})
|
12
|
+
post(HashDealer.roll(:test_resource).merge(id: 1), params: {test_resource: HashDealer.roll(:test_resource_with_roles).matcher})
|
12
13
|
get((0..4).to_a.collect{HashDealer.roll(:test_resource)})
|
13
|
-
get((0..4).to_a.collect{HashDealer.roll(:test_resource)}, :
|
14
|
-
get((0..4).to_a.collect{HashDealer.roll(:test_resource)}, :
|
15
|
-
get((0..4).to_a.collect{HashDealer.roll(:test_resource)}, :
|
16
|
-
get((0..4).to_a.collect{HashDealer.roll(:test_resource)}, :
|
14
|
+
get((0..4).to_a.collect{HashDealer.roll(:test_resource)}, params: {active: true})
|
15
|
+
get((0..4).to_a.collect{HashDealer.roll(:test_resource)}, params: {all: true})
|
16
|
+
get((0..4).to_a.collect{HashDealer.roll(:test_resource)}, params: {first: true})
|
17
|
+
get((0..4).to_a.collect{HashDealer.roll(:test_resource)}, params: {last: true})
|
18
|
+
|
19
|
+
get(
|
20
|
+
(0..4).to_a.collect{HashDealer.roll(:test_resource)},
|
21
|
+
params: { page: 1, per_page: 10 }.matcher,
|
22
|
+
response_headers: {
|
23
|
+
"ApiResource-Total-Entries" => 100
|
24
|
+
}
|
25
|
+
)
|
26
|
+
|
17
27
|
end
|
18
|
-
|
28
|
+
|
19
29
|
endpoint("/test_resources/:id") do
|
20
30
|
get(HashDealer.roll(:test_resource_with_proxies)) do |params|
|
21
31
|
self.merge(params)
|
22
32
|
end
|
23
33
|
delete({})
|
24
|
-
put({}, :
|
34
|
+
put({}, params: {test_resource: HashDealer.roll(:test_resource).matcher})
|
25
35
|
end
|
26
|
-
|
36
|
+
|
27
37
|
endpoint("/child_test_resources/new") do
|
28
38
|
get({})
|
29
39
|
end
|
30
|
-
|
40
|
+
|
31
41
|
endpoint("/child_test_resource2s/new") do
|
32
42
|
get({})
|
33
43
|
end
|
34
|
-
|
44
|
+
|
35
45
|
endpoint("/another_test_resources/new") do
|
36
46
|
get({})
|
37
47
|
end
|
38
|
-
|
48
|
+
|
39
49
|
endpoint("/test_classes/new") do
|
40
50
|
get({})
|
41
51
|
end
|
42
|
-
|
52
|
+
|
43
53
|
endpoint("/children/new") do
|
44
54
|
get({})
|
45
55
|
end
|
46
|
-
|
56
|
+
|
47
57
|
end
|