lurch 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/.rubocop.yml +29 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +2 -0
- data/LICENSE.md +9 -0
- data/README.md +229 -0
- data/Rakefile +12 -0
- data/TODO.md +22 -0
- data/lib/lurch/changeset.rb +32 -0
- data/lib/lurch/client.rb +92 -0
- data/lib/lurch/collection.rb +111 -0
- data/lib/lurch/configuration.rb +14 -0
- data/lib/lurch/error.rb +13 -0
- data/lib/lurch/errors/bad_request.rb +6 -0
- data/lib/lurch/errors/conflict.rb +6 -0
- data/lib/lurch/errors/forbidden.rb +6 -0
- data/lib/lurch/errors/json_api_error.rb +29 -0
- data/lib/lurch/errors/not_found.rb +6 -0
- data/lib/lurch/errors/not_loaded.rb +13 -0
- data/lib/lurch/errors/relationship_not_loaded.rb +9 -0
- data/lib/lurch/errors/resource_not_loaded.rb +9 -0
- data/lib/lurch/errors/server_error.rb +6 -0
- data/lib/lurch/errors/unauthorized.rb +6 -0
- data/lib/lurch/errors/unprocessable_entity.rb +6 -0
- data/lib/lurch/inflector.rb +60 -0
- data/lib/lurch/logger.rb +7 -0
- data/lib/lurch/middleware/json_api_request.rb +22 -0
- data/lib/lurch/middleware/json_api_response.rb +24 -0
- data/lib/lurch/paginator.rb +71 -0
- data/lib/lurch/payload_builder.rb +43 -0
- data/lib/lurch/query.rb +143 -0
- data/lib/lurch/query_builder.rb +26 -0
- data/lib/lurch/railtie.rb +9 -0
- data/lib/lurch/relationship/has_many.rb +17 -0
- data/lib/lurch/relationship/has_one.rb +21 -0
- data/lib/lurch/relationship/linked.rb +40 -0
- data/lib/lurch/relationship.rb +26 -0
- data/lib/lurch/resource.rb +82 -0
- data/lib/lurch/store.rb +149 -0
- data/lib/lurch/store_configuration.rb +27 -0
- data/lib/lurch/stored_resource.rb +63 -0
- data/lib/lurch/uri_builder.rb +32 -0
- data/lib/lurch/version.rb +3 -0
- data/lib/lurch.rb +65 -0
- data/lurch.gemspec +26 -0
- data/lurch.gif +0 -0
- data/test/helpers/lurch_test.rb +40 -0
- data/test/helpers/response_factory.rb +193 -0
- data/test/lurch/test_configuration.rb +20 -0
- data/test/lurch/test_create_resources.rb +55 -0
- data/test/lurch/test_delete_resources.rb +27 -0
- data/test/lurch/test_errors.rb +29 -0
- data/test/lurch/test_fetch_relationships.rb +50 -0
- data/test/lurch/test_fetch_resources.rb +77 -0
- data/test/lurch/test_inflector.rb +13 -0
- data/test/lurch/test_paginated_collections.rb +125 -0
- data/test/lurch/test_queries.rb +104 -0
- data/test/lurch/test_relationship.rb +17 -0
- data/test/lurch/test_resource.rb +34 -0
- data/test/lurch/test_update_relationships.rb +53 -0
- data/test/lurch/test_update_resources.rb +56 -0
- data/test/test_helper.rb +15 -0
- metadata +235 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative "../test_helper"
|
2
|
+
|
3
|
+
class TestDeleteResources < Minitest::Test
|
4
|
+
include LurchTest
|
5
|
+
|
6
|
+
def test_delete_existing_resource_from_server_using_store
|
7
|
+
stub_get("#{person_type}/1", @response_factory.person_response("1", "Alice"))
|
8
|
+
delete_stub = stub_delete("#{person_type}/1", @response_factory.no_content_response)
|
9
|
+
|
10
|
+
person = @store.from(:people).find("1")
|
11
|
+
response = @store.delete(person)
|
12
|
+
|
13
|
+
assert_requested delete_stub
|
14
|
+
assert response
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_delete_existing_resource_from_server_using_query
|
18
|
+
stub_get("#{person_type}/1", @response_factory.person_response("1", "Alice"))
|
19
|
+
delete_stub = stub_delete("#{person_type}/1", @response_factory.no_content_response)
|
20
|
+
|
21
|
+
person = @store.from(:people).find("1")
|
22
|
+
response = @store.from(:people).delete(person)
|
23
|
+
|
24
|
+
assert_requested delete_stub
|
25
|
+
assert response
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative "../test_helper"
|
2
|
+
|
3
|
+
class TestErrors < Minitest::Test
|
4
|
+
include LurchTest
|
5
|
+
|
6
|
+
def test_401
|
7
|
+
stub_get("#{person_type}/1", @response_factory.unauthorized_response)
|
8
|
+
err = assert_raises(Lurch::Errors::Unauthorized) { @store.from(:people).find("1") }
|
9
|
+
assert_equal "401: Unauthorized", err.message
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_403
|
13
|
+
stub_get("#{person_type}/1", @response_factory.forbidden_response)
|
14
|
+
err = assert_raises(Lurch::Errors::Forbidden) { @store.from(:people).find("1") }
|
15
|
+
assert_equal "403: Forbidden", err.message
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_404
|
19
|
+
stub_get("#{person_type}/999", @response_factory.not_found_response)
|
20
|
+
err = assert_raises(Lurch::Errors::NotFound) { @store.from(:people).find("999") }
|
21
|
+
assert_equal "404: Not Found", err.message
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_500
|
25
|
+
stub_get("#{person_type}/1", @response_factory.server_error_response)
|
26
|
+
err = assert_raises(Lurch::Errors::ServerError) { @store.from(:people).find("1") }
|
27
|
+
assert_equal "500: Internal Server Error", err.message
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require_relative "../test_helper"
|
2
|
+
|
3
|
+
class TestFetchRelationships < Minitest::Test
|
4
|
+
include LurchTest
|
5
|
+
|
6
|
+
def test_fetch_linked_has_one_relationship_from_server
|
7
|
+
stub_get("#{phone_number_type}/1", @response_factory.phone_number_response("1", "Cell", "111-222-3344"))
|
8
|
+
stub_get("#{phone_number_type}/1/contact", @response_factory.person_response("1", "Alice"))
|
9
|
+
|
10
|
+
phone_number = @store.from(:phone_numbers).find("1")
|
11
|
+
|
12
|
+
assert_kind_of Lurch::Relationship::Linked, phone_number.contact
|
13
|
+
assert phone_number.contact.inspect
|
14
|
+
assert_raises(Lurch::Errors::RelationshipNotLoaded) { phone_number.contact.name }
|
15
|
+
err = assert_raises(Lurch::Errors::RelationshipNotLoaded) { phone_number.contact.respond_to?(:name) }
|
16
|
+
assert_equal "Relationship (contact) not loaded, try calling #fetch first.", err.message
|
17
|
+
|
18
|
+
phone_number.contact.fetch
|
19
|
+
person = phone_number.contact
|
20
|
+
|
21
|
+
assert_kind_of Lurch::Resource, person
|
22
|
+
assert_kind_of Lurch::Relationship::Linked, phone_number.relationships[:contact]
|
23
|
+
assert_raises(NoMethodError) { phone_number.relationships[:contact].name }
|
24
|
+
refute phone_number.relationships[:contact].respond_to?(:name)
|
25
|
+
assert_equal "Alice", person.name
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_fetch_linked_has_many_relationship_from_server
|
29
|
+
stub_get("#{person_type}/1", @response_factory.person_response("1", "Alice"))
|
30
|
+
stub_get(
|
31
|
+
"#{person_type}/1/#{@inflector.encode_key(:phone_numbers)}",
|
32
|
+
@response_factory.phone_numbers_response(["1", "Cell", "111-222-3344"], ["2", "Home", "222-111-3344"])
|
33
|
+
)
|
34
|
+
|
35
|
+
person = @store.from(:people).find("1")
|
36
|
+
|
37
|
+
assert_kind_of Lurch::Relationship::Linked, person.phone_numbers
|
38
|
+
assert_equal false, person.phone_numbers.loaded?
|
39
|
+
assert person.phone_numbers.inspect
|
40
|
+
|
41
|
+
person.phone_numbers.fetch
|
42
|
+
phone_numbers = person.phone_numbers
|
43
|
+
|
44
|
+
assert_kind_of Lurch::Collection, phone_numbers
|
45
|
+
assert_equal true, person.phone_numbers.loaded?
|
46
|
+
assert_kind_of Lurch::Relationship::Linked, person.relationships[:phone_numbers]
|
47
|
+
assert_equal 2, phone_numbers.size
|
48
|
+
assert_equal "Cell", phone_numbers.first.name
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require_relative "../test_helper"
|
2
|
+
|
3
|
+
class TestFetchResources < Minitest::Test
|
4
|
+
include LurchTest
|
5
|
+
|
6
|
+
def test_fetch_resource_from_server
|
7
|
+
stub_get("#{person_type}/1", @response_factory.person_response("1", "Alice"))
|
8
|
+
|
9
|
+
person = @store.from(:people).find("1")
|
10
|
+
|
11
|
+
assert_equal "Alice", person.name
|
12
|
+
assert person.inspect
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_fetch_resource_collection_from_server
|
16
|
+
stub_get(person_type, @response_factory.people_response(["1", "Alice"], ["2", "Bob"]))
|
17
|
+
|
18
|
+
people = @store.from(:people).all
|
19
|
+
|
20
|
+
assert_kind_of Lurch::Collection, people
|
21
|
+
assert_equal 2, people.size
|
22
|
+
assert_equal ["Alice", "Bob"], people.map(&:name)
|
23
|
+
assert people.inspect
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_fetch_already_fetched_resource_from_store
|
27
|
+
stub = stub_get("#{person_type}/1", @response_factory.person_response("1", "Alice"))
|
28
|
+
|
29
|
+
@store.from(:people).find("1")
|
30
|
+
|
31
|
+
remove_request_stub(stub)
|
32
|
+
|
33
|
+
assert @store.from(:people).find("1")
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_fetch_resource_from_server_that_includes_has_one_relationship
|
37
|
+
stub_get("#{phone_number_type}/1", @response_factory.phone_number_response("1", "Cell", "111-222-3344", ["1", "Alice"]))
|
38
|
+
|
39
|
+
phone_number = @store.from(:phone_numbers).find("1")
|
40
|
+
|
41
|
+
assert_kind_of Lurch::Relationship::HasOne, phone_number.relationships[:contact]
|
42
|
+
assert phone_number.relationships[:contact].inspect
|
43
|
+
assert_kind_of Lurch::Resource, phone_number.contact
|
44
|
+
assert_equal "Alice", phone_number.contact.name
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_fetch_resource_from_server_that_includes_has_many_relationship
|
48
|
+
stub_get("#{person_type}/1", @response_factory.person_response("1", "Alice", [["1", "Cell", "1112223344"], ["2", "Home", "2221113344"]]))
|
49
|
+
|
50
|
+
person = @store.from(:people).find("1")
|
51
|
+
|
52
|
+
assert_kind_of Lurch::Relationship::HasMany, person.relationships[:phone_numbers]
|
53
|
+
assert person.relationships[:phone_numbers].inspect
|
54
|
+
assert_kind_of Array, person.phone_numbers
|
55
|
+
assert_equal "Cell", person.phone_numbers.first.name
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_fetch_resource_that_includes_resource_identifiers_only
|
59
|
+
stub_get("#{person_type}/1", @response_factory.person_response("1", "Alice", [["1"]], include_phone_numbers: false))
|
60
|
+
|
61
|
+
person = @store.from(:people).find("1")
|
62
|
+
phone_number = person.phone_numbers.first
|
63
|
+
|
64
|
+
assert_equal "1", phone_number.id
|
65
|
+
refute phone_number.loaded?
|
66
|
+
assert phone_number.inspect
|
67
|
+
err = assert_raises(Lurch::Errors::ResourceNotLoaded) { phone_number.name }
|
68
|
+
assert_equal "Resource (PhoneNumber) not loaded, try calling #fetch first.", err.message
|
69
|
+
|
70
|
+
stub_get("#{phone_number_type}/1", @response_factory.phone_number_response("1", "Cell", "111-222-3344"))
|
71
|
+
|
72
|
+
phone_number.fetch
|
73
|
+
|
74
|
+
assert phone_number.loaded?
|
75
|
+
assert_equal "Cell", phone_number.name
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative "../test_helper"
|
2
|
+
|
3
|
+
class TestInflector < Minitest::Test
|
4
|
+
include LurchTest
|
5
|
+
|
6
|
+
def test_bad_inflector
|
7
|
+
err = assert_raises(ArgumentError) { Lurch::Inflector.new(:foo, :pluralize) }
|
8
|
+
assert_equal "Invalid inflection mode: foo", err.message
|
9
|
+
|
10
|
+
err = assert_raises(ArgumentError) { Lurch::Inflector.new(:dasherize, :bar) }
|
11
|
+
assert_equal "Invalid types mode: bar", err.message
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require_relative "../test_helper"
|
2
|
+
|
3
|
+
class TestPaginatedCollections < Minitest::Test
|
4
|
+
include LurchTest
|
5
|
+
|
6
|
+
def test_fetch_paginated_resource_collection_from_server
|
7
|
+
stub_get(person_type, @response_factory.paginated_people_response(10, 1, 2))
|
8
|
+
|
9
|
+
people = @store.from(:people).all
|
10
|
+
|
11
|
+
assert_kind_of Lurch::Collection, people
|
12
|
+
assert_equal 20, people.size
|
13
|
+
assert_equal 10, people.page_size
|
14
|
+
assert_equal 2, people.page_count
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_fetch_next_page_of_paginated_resource_collection_from_server
|
18
|
+
stub_get(person_type, @response_factory.paginated_people_response(10, 1, 2))
|
19
|
+
|
20
|
+
people = @store.from(:people).all
|
21
|
+
|
22
|
+
assert people.next?
|
23
|
+
|
24
|
+
page2_stub = stub_get("#{person_type}?page[number]=2&page[size]=10", @response_factory.paginated_people_response(10, 2, 2))
|
25
|
+
|
26
|
+
people.next_collection
|
27
|
+
|
28
|
+
assert_requested page2_stub
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_fetch_previous_page_of_paginated_resource_collection_from_server
|
32
|
+
stub_get("#{person_type}?page[number]=2&page[size]=10", @response_factory.paginated_people_response(10, 2, 2))
|
33
|
+
|
34
|
+
people = @store.from(:people).page(number: 2, size: 10).all
|
35
|
+
|
36
|
+
assert people.prev?
|
37
|
+
|
38
|
+
page1_stub = stub_get("#{person_type}?page[number]=1&page[size]=10", @response_factory.paginated_people_response(10, 1, 2))
|
39
|
+
|
40
|
+
people.prev_collection
|
41
|
+
|
42
|
+
assert_requested page1_stub
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_fetch_first_page_of_paginated_resource_collection_from_server
|
46
|
+
stub_get("#{person_type}?page[number]=2&page[size]=10", @response_factory.paginated_people_response(10, 2, 2))
|
47
|
+
|
48
|
+
people = @store.from(:people).page(number: 2, size: 10).all
|
49
|
+
|
50
|
+
assert people.first?
|
51
|
+
|
52
|
+
page1_stub = stub_get("#{person_type}?page[number]=1&page[size]=10", @response_factory.paginated_people_response(10, 1, 2))
|
53
|
+
|
54
|
+
people.first_collection
|
55
|
+
|
56
|
+
assert_requested page1_stub
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_fetch_last_page_of_paginated_resource_collection_from_server
|
60
|
+
stub_get(person_type, @response_factory.paginated_people_response(10, 1, 2))
|
61
|
+
|
62
|
+
people = @store.from(:people).all
|
63
|
+
|
64
|
+
assert people.last?
|
65
|
+
|
66
|
+
page2_stub = stub_get("#{person_type}?page[number]=2&page[size]=10", @response_factory.paginated_people_response(10, 2, 2))
|
67
|
+
|
68
|
+
people.last_collection
|
69
|
+
|
70
|
+
assert_requested page2_stub
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_enumerate_paginated_collection_by_resource
|
74
|
+
page1_stub = stub_get(person_type, @response_factory.paginated_people_response(10, 1, 3))
|
75
|
+
page2_stub = stub_get("#{person_type}?page[number]=2&page[size]=10", @response_factory.paginated_people_response(10, 2, 3))
|
76
|
+
page3_stub = stub_get("#{person_type}?page[number]=3&page[size]=10", @response_factory.paginated_people_response(10, 3, 3))
|
77
|
+
|
78
|
+
people = @store.from(:people).all
|
79
|
+
names = people.map(&:name)
|
80
|
+
|
81
|
+
assert_kind_of Array, names
|
82
|
+
assert names.size == 30
|
83
|
+
assert names.first == "Person1"
|
84
|
+
assert names.last == "Person30"
|
85
|
+
|
86
|
+
assert_requested page1_stub
|
87
|
+
assert_requested page2_stub
|
88
|
+
assert_requested page3_stub
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_enumerate_paginated_collection_by_page
|
92
|
+
page1_stub = stub_get(person_type, @response_factory.paginated_people_response(10, 1, 3))
|
93
|
+
page2_stub = stub_get("#{person_type}?page[number]=2&page[size]=10", @response_factory.paginated_people_response(10, 2, 3))
|
94
|
+
page3_stub = stub_get("#{person_type}?page[number]=3&page[size]=10", @response_factory.paginated_people_response(10, 3, 3))
|
95
|
+
|
96
|
+
people = @store.from(:people).all
|
97
|
+
|
98
|
+
people.each_page do |page|
|
99
|
+
assert_kind_of Array, page
|
100
|
+
assert page.size == 10
|
101
|
+
end
|
102
|
+
|
103
|
+
assert_requested page1_stub
|
104
|
+
assert_requested page2_stub
|
105
|
+
assert_requested page3_stub
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_lazy_enumeration
|
109
|
+
page1_stub = stub_get(person_type, @response_factory.paginated_people_response(10, 1, 3))
|
110
|
+
page2_stub = stub_get("#{person_type}?page[number]=2&page[size]=10", @response_factory.paginated_people_response(10, 2, 3))
|
111
|
+
page3_stub = stub_get("#{person_type}?page[number]=3&page[size]=10", @response_factory.paginated_people_response(10, 3, 3))
|
112
|
+
|
113
|
+
people = @store.from(:people).all
|
114
|
+
names = people.lazy.map(&:name).first(20)
|
115
|
+
|
116
|
+
assert_kind_of Array, names
|
117
|
+
assert names.size == 20
|
118
|
+
assert names.first == "Person1"
|
119
|
+
assert names.last == "Person20"
|
120
|
+
|
121
|
+
assert_requested page1_stub
|
122
|
+
assert_requested page2_stub
|
123
|
+
assert_not_requested page3_stub
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require_relative "../test_helper"
|
2
|
+
|
3
|
+
class TestQueries < Minitest::Test
|
4
|
+
include LurchTest
|
5
|
+
|
6
|
+
def test_filter
|
7
|
+
stub = stub_get(
|
8
|
+
"#{person_type}?filter[name]=Alice&filter[foo][]=bar&filter[foo][]=baz",
|
9
|
+
@response_factory.no_content_response
|
10
|
+
)
|
11
|
+
|
12
|
+
@store
|
13
|
+
.from(:people)
|
14
|
+
.filter(name: "Alice", foo: ["bar", "baz"])
|
15
|
+
.all
|
16
|
+
|
17
|
+
assert_requested(stub)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_include
|
21
|
+
stub = stub_get(
|
22
|
+
"#{person_type}?include=#{@inflector.encode_key(:phone_numbers)},friends,friends.#{@inflector.encode_key(:phone_numbers)}",
|
23
|
+
@response_factory.no_content_response
|
24
|
+
)
|
25
|
+
|
26
|
+
@store
|
27
|
+
.from(:people)
|
28
|
+
.include(:phone_numbers, :friends, "friends.phone_numbers")
|
29
|
+
.all
|
30
|
+
|
31
|
+
assert_requested(stub)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_fields
|
35
|
+
stub = stub_get(
|
36
|
+
"#{person_type}?fields[#{person_type}]=name&fields[#{phone_number_type}]=name,number",
|
37
|
+
@response_factory.no_content_response
|
38
|
+
)
|
39
|
+
|
40
|
+
@store
|
41
|
+
.from(:people)
|
42
|
+
.fields([:name])
|
43
|
+
.fields(:phone_number, [:name, :number])
|
44
|
+
.all
|
45
|
+
|
46
|
+
assert_requested(stub)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_sort
|
50
|
+
stub = stub_get(
|
51
|
+
"#{person_type}?sort=name,-foo,bar",
|
52
|
+
@response_factory.no_content_response
|
53
|
+
)
|
54
|
+
|
55
|
+
@store
|
56
|
+
.from(:people)
|
57
|
+
.sort(:name, {foo: :desc}, {bar: :asc})
|
58
|
+
.all
|
59
|
+
|
60
|
+
assert_requested(stub)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_bad_sort
|
64
|
+
assert_raises ArgumentError do
|
65
|
+
@store.from(:people).sort(foo: :bar).all
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_page
|
70
|
+
stub = stub_get(
|
71
|
+
"#{person_type}?page[number]=12&page[size]=50",
|
72
|
+
@response_factory.no_content_response
|
73
|
+
)
|
74
|
+
|
75
|
+
@store
|
76
|
+
.from(:people)
|
77
|
+
.page(number: 12, size: 50)
|
78
|
+
.all
|
79
|
+
|
80
|
+
assert_requested(stub)
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_all
|
84
|
+
stub = stub_get(
|
85
|
+
"#{person_type}?filter[name]=Alice&filter[foo][]=bar&filter[foo][]=baz&include=#{@inflector.encode_key(:phone_numbers)},friends,friends.#{@inflector.encode_key(:phone_numbers)}&fields[#{person_type}]=name&fields[#{phone_number_type}]=name,number&sort=name,-foo,bar&page[number]=12&page[size]=50",
|
86
|
+
@response_factory.no_content_response
|
87
|
+
)
|
88
|
+
|
89
|
+
query = @store
|
90
|
+
.from(:people)
|
91
|
+
.filter(name: "Alice", foo: ["bar", "baz"])
|
92
|
+
.include(:phone_numbers, :friends, "friends.phone_numbers")
|
93
|
+
.fields([:name])
|
94
|
+
.fields(:phone_number, [:name, :number])
|
95
|
+
.sort(:name, {foo: :desc}, {bar: :asc})
|
96
|
+
.page(number: 12, size: 50)
|
97
|
+
|
98
|
+
assert query.inspect
|
99
|
+
|
100
|
+
query.all
|
101
|
+
|
102
|
+
assert_requested(stub)
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative "../test_helper"
|
2
|
+
|
3
|
+
class TestRelationship < Minitest::Test
|
4
|
+
include LurchTest
|
5
|
+
|
6
|
+
def test_bad_relationship_document
|
7
|
+
err = assert_raises(ArgumentError) { Lurch::Relationship.from_document(nil, nil, {}) }
|
8
|
+
assert_equal "Invalid relationship document", err.message
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_nil_has_one_relationship
|
12
|
+
rel = Lurch::Relationship::HasOne.new(nil, nil, {data: nil})
|
13
|
+
|
14
|
+
assert rel.loaded?
|
15
|
+
assert_nil rel.data
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative "../test_helper"
|
2
|
+
|
3
|
+
class TestResource < Minitest::Test
|
4
|
+
include LurchTest
|
5
|
+
|
6
|
+
def test_resource_equality
|
7
|
+
stub_get("#{person_type}/1", @response_factory.person_response("1", "Alice"))
|
8
|
+
stub_get("#{person_type}/2", @response_factory.person_response("2", "Bob"))
|
9
|
+
|
10
|
+
person1 = @store.from(:people).find("1")
|
11
|
+
person1_again = @store.from(:people).find("1")
|
12
|
+
person2 = @store.from(:people).find("2")
|
13
|
+
|
14
|
+
assert person1 == person1_again
|
15
|
+
assert person1.eql? person1_again
|
16
|
+
refute person1.equal? person1_again
|
17
|
+
refute person1 == person2
|
18
|
+
refute person1.eql? person2
|
19
|
+
refute person1.equal? person2
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_resource_attribute_getters
|
23
|
+
stub_get("#{person_type}/1", @response_factory.person_response("1", "Alice"))
|
24
|
+
|
25
|
+
person = @store.from(:people).find("1")
|
26
|
+
|
27
|
+
assert person.name == "Alice"
|
28
|
+
assert person[:name] == "Alice"
|
29
|
+
assert person.respond_to?(:name)
|
30
|
+
|
31
|
+
refute person.respond_to?(:foo)
|
32
|
+
assert_raises(NoMethodError) { person.foo }
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative "../test_helper"
|
2
|
+
|
3
|
+
class TestUpdateRelationships < Minitest::Test
|
4
|
+
include LurchTest
|
5
|
+
|
6
|
+
def test_add_resources_to_has_many_relationship
|
7
|
+
stub_get("#{person_type}/1", @response_factory.person_response("1", "Alice"))
|
8
|
+
stub_get("#{phone_number_type}/1", @response_factory.phone_number_response("1", "Cell", "111-222-3344"))
|
9
|
+
stub_post("#{person_type}/1/relationships/#{@inflector.encode_key(:phone_numbers)}", @response_factory.no_content_response)
|
10
|
+
|
11
|
+
person = @store.from(:people).find("1")
|
12
|
+
phone_number = @store.from(:phone_numbers).find("1")
|
13
|
+
response = @store.add_related(person, :phone_numbers, [phone_number])
|
14
|
+
|
15
|
+
assert_requested :post, "#{@url}/#{person_type}/1/relationships/#{@inflector.encode_key(:phone_numbers)}", body: "{\"data\":[{\"id\":\"1\",\"type\":\"#{phone_number_type}\"}]}"
|
16
|
+
assert response
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_remove_resources_from_has_many_relationship
|
20
|
+
stub_get("#{person_type}/1", @response_factory.person_response("1", "Alice"))
|
21
|
+
stub_get("#{person_type}/1/#{@inflector.encode_key(:phone_numbers)}", @response_factory.phone_numbers_response(["1", "Cell", "111-222-3344"]))
|
22
|
+
stub_delete("#{person_type}/1/relationships/#{@inflector.encode_key(:phone_numbers)}", @response_factory.no_content_response)
|
23
|
+
|
24
|
+
person = @store.from(:people).find("1")
|
25
|
+
phone_number = person.phone_numbers.fetch.first
|
26
|
+
response = @store.remove_related(person, :phone_numbers, [phone_number])
|
27
|
+
|
28
|
+
assert_requested :delete, "#{@url}/#{person_type}/1/relationships/#{@inflector.encode_key(:phone_numbers)}", body: "{\"data\":[{\"id\":\"1\",\"type\":\"#{phone_number_type}\"}]}"
|
29
|
+
assert response
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_replace_resources_for_has_many_relationship
|
33
|
+
stub_get("#{person_type}/1", @response_factory.person_response("1", "Alice"))
|
34
|
+
stub_patch("#{person_type}/1/relationships/#{@inflector.encode_key(:phone_numbers)}", @response_factory.no_content_response)
|
35
|
+
|
36
|
+
person = @store.from(:people).find("1")
|
37
|
+
response = @store.update_related(person, :phone_numbers, [])
|
38
|
+
|
39
|
+
assert_requested :patch, "#{@url}/#{person_type}/1/relationships/#{@inflector.encode_key(:phone_numbers)}", body: '{"data":[]}'
|
40
|
+
assert response
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_replace_resource_for_has_one_relationship
|
44
|
+
stub_get("#{phone_number_type}/1", @response_factory.phone_number_response("1", "Cell", "111-222-3344"))
|
45
|
+
stub_patch("#{phone_number_type}/1/relationships/contact", @response_factory.no_content_response)
|
46
|
+
|
47
|
+
phone_number = @store.from(:phone_numbers).find("1")
|
48
|
+
response = @store.update_related(phone_number, :contact, nil)
|
49
|
+
|
50
|
+
assert_requested :patch, "#{@url}/#{phone_number_type}/1/relationships/contact", body: '{"data":null}'
|
51
|
+
assert response
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require_relative "../test_helper"
|
2
|
+
|
3
|
+
class TestUpdateResources < Minitest::Test
|
4
|
+
include LurchTest
|
5
|
+
|
6
|
+
def test_update_existing_resource_on_server_using_store
|
7
|
+
stub_get("#{person_type}/2", @response_factory.person_response("2", "Bob"))
|
8
|
+
stub_patch("#{person_type}/2", @response_factory.person_response("2", "Robert"))
|
9
|
+
|
10
|
+
person = @store.from(:people).find("2")
|
11
|
+
|
12
|
+
assert_equal "Bob", person.name
|
13
|
+
|
14
|
+
changeset = Lurch::Changeset.new(person, name: "Robert")
|
15
|
+
@store.save(changeset)
|
16
|
+
|
17
|
+
assert changeset.inspect
|
18
|
+
assert_requested :patch, "#{@url}/#{person_type}/2", body: "{\"data\":{\"id\":\"2\",\"type\":\"#{person_type}\",\"attributes\":{\"name\":\"Robert\"}}}"
|
19
|
+
assert_equal "Robert", person.name
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_update_existing_resource_on_server_using_query
|
23
|
+
stub_get("#{person_type}/2", @response_factory.person_response("2", "Bob"))
|
24
|
+
stub_patch("#{person_type}/2", @response_factory.person_response("2", "Robert"))
|
25
|
+
|
26
|
+
person = @store.from(:people).find("2")
|
27
|
+
|
28
|
+
assert_equal "Bob", person.name
|
29
|
+
|
30
|
+
changeset = Lurch::Changeset.new(person)
|
31
|
+
changeset.set(:name, "Robert")
|
32
|
+
@store.to(:people).save(changeset)
|
33
|
+
|
34
|
+
assert_requested :patch, "#{@url}/#{person_type}/2", body: "{\"data\":{\"id\":\"2\",\"type\":\"#{person_type}\",\"attributes\":{\"name\":\"Robert\"}}}"
|
35
|
+
assert_equal "Robert", person.name
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_validation_errors_when_updating_existing_resource
|
39
|
+
stub_get("#{person_type}/2", @response_factory.person_response("2", "Bob"))
|
40
|
+
stub_patch("#{person_type}/2", @response_factory.unprocessable_entity_response("name - can't be blank"))
|
41
|
+
|
42
|
+
person = @store.from(:people).find("2")
|
43
|
+
|
44
|
+
assert_equal "Bob", person.name
|
45
|
+
|
46
|
+
changeset = Lurch::Changeset.new(person, name: "")
|
47
|
+
|
48
|
+
err = assert_raises(Lurch::Errors::UnprocessableEntity) { @store.save(changeset) }
|
49
|
+
assert_equal "422: name - can't be blank", err.message
|
50
|
+
assert_equal 422, changeset.errors.first.status
|
51
|
+
assert_equal "name - can't be blank", changeset.errors.first.detail
|
52
|
+
|
53
|
+
assert_requested :patch, "#{@url}/#{person_type}/2", body: "{\"data\":{\"id\":\"2\",\"type\":\"#{person_type}\",\"attributes\":{\"name\":\"\"}}}"
|
54
|
+
assert_equal "Bob", person.name
|
55
|
+
end
|
56
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "pry"
|
2
|
+
require "simplecov"
|
3
|
+
require "codecov"
|
4
|
+
require "webmock/minitest"
|
5
|
+
|
6
|
+
require_relative "helpers/lurch_test"
|
7
|
+
require_relative "helpers/response_factory"
|
8
|
+
|
9
|
+
SimpleCov.formatter = SimpleCov::Formatter::Codecov
|
10
|
+
SimpleCov.start do
|
11
|
+
add_filter "/test/"
|
12
|
+
end
|
13
|
+
|
14
|
+
require "minitest/autorun"
|
15
|
+
require "lurch"
|