restful 0.2.20
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/CHANGES.markdown +40 -0
- data/LICENSE.markdown +22 -0
- data/README.markdown +126 -0
- data/Rakefile +22 -0
- data/TODO.markdown +10 -0
- data/init.rb +1 -0
- data/lib/restful.rb +65 -0
- data/lib/restful/apimodel/attribute.rb +17 -0
- data/lib/restful/apimodel/collection.rb +22 -0
- data/lib/restful/apimodel/link.rb +21 -0
- data/lib/restful/apimodel/map.rb +41 -0
- data/lib/restful/apimodel/resource.rb +23 -0
- data/lib/restful/converters/active_record.rb +160 -0
- data/lib/restful/rails.rb +22 -0
- data/lib/restful/rails/action_controller.rb +14 -0
- data/lib/restful/rails/active_record/configuration.rb +219 -0
- data/lib/restful/rails/active_record/metadata_tools.rb +102 -0
- data/lib/restful/serializers/atom_like_serializer.rb +51 -0
- data/lib/restful/serializers/base.rb +58 -0
- data/lib/restful/serializers/hash_serializer.rb +46 -0
- data/lib/restful/serializers/json_serializer.rb +18 -0
- data/lib/restful/serializers/params_serializer.rb +46 -0
- data/lib/restful/serializers/xml_serializer.rb +160 -0
- data/rails/init.rb +1 -0
- data/restful.gemspec +17 -0
- data/test/converters/active_record_converter_test.rb +147 -0
- data/test/converters/basic_types_converter_test.rb +99 -0
- data/test/fixtures/models/paginated_collection.rb +3 -0
- data/test/fixtures/models/person.rb +29 -0
- data/test/fixtures/models/pet.rb +5 -0
- data/test/fixtures/models/wallet.rb +5 -0
- data/test/fixtures/people.json.yaml +107 -0
- data/test/fixtures/people.xml.yaml +117 -0
- data/test/fixtures/pets.json.yaml +20 -0
- data/test/fixtures/pets.xml.yaml +31 -0
- data/test/rails/active_record_metadata_test.rb +23 -0
- data/test/rails/configuration_test.rb +47 -0
- data/test/rails/restful_publish_test.rb +54 -0
- data/test/serializers/atom_serializer_test.rb +33 -0
- data/test/serializers/json_serializer_test.rb +90 -0
- data/test/serializers/params_serializer_test.rb +76 -0
- data/test/serializers/xml_serializer_test.rb +51 -0
- data/test/test_helper.rb +154 -0
- metadata +106 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'restful/serializers/base'
|
2
|
+
|
3
|
+
#
|
4
|
+
# Vanilla Hash.
|
5
|
+
#
|
6
|
+
module Restful
|
7
|
+
module Serializers
|
8
|
+
class HashSerializer < Base
|
9
|
+
|
10
|
+
serializer_name :hash
|
11
|
+
|
12
|
+
def serialize(obj, options = {})
|
13
|
+
case obj.type
|
14
|
+
when :link then obj.value
|
15
|
+
when :simple_attribute then serialize(obj.value)
|
16
|
+
when :collection then serialize_collection(obj)
|
17
|
+
when :map then serialize_array_of_apimodels(obj.values)
|
18
|
+
when :resource then serialize_array_of_apimodels(obj.values, { "restful_url" => obj.full_url })
|
19
|
+
else
|
20
|
+
formatted_ruby_type(obj)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def serialize_collection(collection)
|
27
|
+
if entries = collection.total_entries
|
28
|
+
{ :total_entries => entries, collection.name => serialize_unpaginated_collection(collection) }
|
29
|
+
else
|
30
|
+
serialize_unpaginated_collection(collection)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def serialize_unpaginated_collection(collection)
|
35
|
+
collection.value.map { |r| serialize(r) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def serialize_array_of_apimodels(apimodels, defaults = {})
|
39
|
+
apimodels.inject(defaults) do |memo, apimodel|
|
40
|
+
memo[apimodel.name.to_s.underscore.to_sym] = serialize(apimodel)
|
41
|
+
memo
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'restful/serializers/base'
|
2
|
+
require 'yajl'
|
3
|
+
|
4
|
+
#
|
5
|
+
# AR params hash.
|
6
|
+
#
|
7
|
+
module Restful
|
8
|
+
module Serializers
|
9
|
+
class JsonSerializer < Base
|
10
|
+
|
11
|
+
serializer_name :json
|
12
|
+
|
13
|
+
def serialize(resource, options = {})
|
14
|
+
Yajl::Encoder.encode HashSerializer.new.serialize(resource, options)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'restful/serializers/base'
|
2
|
+
require 'builder'
|
3
|
+
|
4
|
+
#
|
5
|
+
# AR params hash.
|
6
|
+
#
|
7
|
+
module Restful
|
8
|
+
module Serializers
|
9
|
+
class ParamsSerializer < Base
|
10
|
+
|
11
|
+
serializer_name :params
|
12
|
+
|
13
|
+
def serialize(resource, options = {})
|
14
|
+
params = {}
|
15
|
+
resource.values.each do |value|
|
16
|
+
if value.type == :collection # serialize the stuffs
|
17
|
+
resources = value.value
|
18
|
+
next if resources.empty?
|
19
|
+
name = resources.first.name.pluralize
|
20
|
+
|
21
|
+
array = []
|
22
|
+
resources.each do |resource|
|
23
|
+
array << serialize(resource)
|
24
|
+
end
|
25
|
+
|
26
|
+
params["#{paramify_keys(value.name)}_attributes".to_sym] = array
|
27
|
+
elsif value.type == :link
|
28
|
+
params[paramify_keys(value.name).to_sym] = Restful::Rails.tools.dereference(value.value)
|
29
|
+
elsif value.type == :resource
|
30
|
+
params["#{paramify_keys(value.name)}_attributes".to_sym] = serialize(value)
|
31
|
+
else # plain ole
|
32
|
+
params[paramify_keys(value.name).to_sym] = value.value # no need to format dates etc - just pass objects through.
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
params
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def paramify_keys(original_key)
|
42
|
+
original_key.to_s.tr("-", "_")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'restful/serializers/base'
|
2
|
+
require "rexml/document"
|
3
|
+
require 'builder'
|
4
|
+
|
5
|
+
#
|
6
|
+
# Converts an APIModel to and from XML.
|
7
|
+
#
|
8
|
+
module Restful
|
9
|
+
module Serializers
|
10
|
+
class XMLSerializer < Base
|
11
|
+
|
12
|
+
serializer_name :xml
|
13
|
+
|
14
|
+
def serialize(resource, options = {})
|
15
|
+
|
16
|
+
xml = options[:builder] || Builder::XmlMarkup.new(:indent => 2)
|
17
|
+
xml.instruct! unless options[:instruct].is_a?(FalseClass)
|
18
|
+
|
19
|
+
raise NotImplementedError.new("xml serialization of maps has not been implemented. ") if resource.class == Restful::ApiModel::Map
|
20
|
+
|
21
|
+
if resource.is_a?(Restful::ApiModel::Collection)
|
22
|
+
add_collection(resource, xml, show_as_array = false)
|
23
|
+
else
|
24
|
+
xml.tag!(*root_element(resource)) do
|
25
|
+
add_link_to(resource, xml, :self => true)
|
26
|
+
|
27
|
+
resource.values.each do |value|
|
28
|
+
if value.type == :collection # serialize the stuffs
|
29
|
+
add_collection(value, xml)
|
30
|
+
elsif value.type == :link
|
31
|
+
add_link_to(value, xml)
|
32
|
+
elsif value.type == :resource
|
33
|
+
serialize(value, {:instruct => false, :builder => xml})
|
34
|
+
else # plain ole
|
35
|
+
add_tag(xml, value)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# returns a resource, or collection of resources.
|
43
|
+
def deserialize(xml, options = {})
|
44
|
+
build_resource(REXML::Document.new(xml).root)
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
def add_collection(value, xml, show_as_array = true)
|
50
|
+
resources = value.value
|
51
|
+
if first_resource = resources.first
|
52
|
+
xml.tag!(first_resource.name.pluralize, (show_as_array ? collections_decorations : {})) do
|
53
|
+
resources.each do |resource|
|
54
|
+
serialize(resource, { :instruct => false, :builder => xml })
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def add_link_to(resource, builder, options = {})
|
61
|
+
is_self = !!options[:self]
|
62
|
+
|
63
|
+
attributes = {:type => "link"}
|
64
|
+
attributes.merge!(:nil => "true") if resource.full_url.blank?
|
65
|
+
builder.tag!((is_self ? "restful-url" : transform_link_name(resource.name)), resource.full_url, attributes)
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_tag(builder, value)
|
69
|
+
|
70
|
+
if value.extended_type == :hash
|
71
|
+
build_hash(builder, value)
|
72
|
+
else
|
73
|
+
builder.tag!(value.name.to_s.dasherize, serialize_attribute(value), decorations(value))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def build_hash(builder, value)
|
78
|
+
builder.tag!(value.name.to_s.dasherize) do
|
79
|
+
value.value.each do |k, v|
|
80
|
+
builder.tag! k.to_s.dasherize, v
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def decorations(value)
|
86
|
+
decorations = {}
|
87
|
+
|
88
|
+
if value.extended_type == :binary
|
89
|
+
decorations[:encoding] = 'base64'
|
90
|
+
end
|
91
|
+
|
92
|
+
if value.extended_type != :string and value.extended_type != :notype
|
93
|
+
decorations[:type] = value.extended_type
|
94
|
+
end
|
95
|
+
|
96
|
+
if value.extended_type == :datetime
|
97
|
+
decorations[:type] = :datetime
|
98
|
+
end
|
99
|
+
|
100
|
+
if value.value.nil?
|
101
|
+
decorations[:nil] = true
|
102
|
+
end
|
103
|
+
|
104
|
+
if value.value.is_a?(FalseClass) || value.value.is_a?(TrueClass)
|
105
|
+
decorations[:type] = :boolean
|
106
|
+
end
|
107
|
+
|
108
|
+
decorations
|
109
|
+
end
|
110
|
+
|
111
|
+
def collections_decorations
|
112
|
+
{ :type => "array" }
|
113
|
+
end
|
114
|
+
|
115
|
+
def root_element(resource, options = {})
|
116
|
+
[resource.name]
|
117
|
+
end
|
118
|
+
|
119
|
+
# turns a rexml node into a Resource
|
120
|
+
def build_resource(node)
|
121
|
+
resource = root_resource(node)
|
122
|
+
|
123
|
+
node.elements.each do |el|
|
124
|
+
type = calculate_node_type(el)
|
125
|
+
resource.values << case type
|
126
|
+
|
127
|
+
when :link : build_link(el, type)
|
128
|
+
when :datetime
|
129
|
+
Restful.attr(el.name, DateTime.parse(el.text), type)
|
130
|
+
when :resource
|
131
|
+
build_resource(el)
|
132
|
+
when :array
|
133
|
+
Restful.collection(el.name, el.elements.map { |child| build_resource(child) }, type)
|
134
|
+
else
|
135
|
+
Restful.attr(el.name, el.text, type)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
resource
|
140
|
+
end
|
141
|
+
|
142
|
+
def calculate_node_type(el)
|
143
|
+
if el.children.size > 1 && el.attributes["type"].blank?
|
144
|
+
return :resource
|
145
|
+
else
|
146
|
+
(el.attributes["type"] || "string").to_sym
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def build_link(el, type)
|
151
|
+
Restful.link(revert_link_name(el.name), nil, el.text, type)
|
152
|
+
end
|
153
|
+
|
154
|
+
def root_resource(node)
|
155
|
+
url = node.delete_element("restful-url").try(:text)
|
156
|
+
Restful.resource(node.name, :url => url)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'restful'
|
data/restful.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "restful"
|
3
|
+
s.version = "0.2.20"
|
4
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
5
|
+
s.authors = ["Daniel Bornkessel", "Rany Keddo"]
|
6
|
+
s.date = "2009-08-11"
|
7
|
+
s.email = "M4SSIVE@m4ssive.com"
|
8
|
+
s.extra_rdoc_files = %w{ README.markdown }
|
9
|
+
s.files = %w{ CHANGES.markdown init.rb lib/restful/apimodel/attribute.rb lib/restful/apimodel/collection.rb lib/restful/apimodel/link.rb lib/restful/apimodel/map.rb lib/restful/apimodel/resource.rb lib/restful/converters/active_record.rb lib/restful/rails/action_controller.rb lib/restful/rails/active_record/configuration.rb lib/restful/rails/active_record/metadata_tools.rb lib/restful/rails.rb lib/restful/serializers/atom_like_serializer.rb lib/restful/serializers/base.rb lib/restful/serializers/hash_serializer.rb lib/restful/serializers/json_serializer.rb lib/restful/serializers/params_serializer.rb lib/restful/serializers/xml_serializer.rb lib/restful.rb LICENSE.markdown rails/init.rb Rakefile README.markdown restful.gemspec test/converters/active_record_converter_test.rb test/converters/basic_types_converter_test.rb test/fixtures/models/paginated_collection.rb test/fixtures/models/person.rb test/fixtures/models/pet.rb test/fixtures/models/wallet.rb test/fixtures/people.json.yaml test/fixtures/people.xml.yaml test/fixtures/pets.json.yaml test/fixtures/pets.xml.yaml test/rails/active_record_metadata_test.rb test/rails/configuration_test.rb test/rails/restful_publish_test.rb test/serializers/atom_serializer_test.rb test/serializers/json_serializer_test.rb test/serializers/params_serializer_test.rb test/serializers/xml_serializer_test.rb test/test_helper.rb TODO.markdown }
|
10
|
+
s.has_rdoc = true
|
11
|
+
s.rdoc_options = ["--line-numbers", "--inline-source"]
|
12
|
+
s.homepage = "http://github.com/M4SSIVE/restful"
|
13
|
+
s.require_paths = %w{ lib }
|
14
|
+
s.requirements = %w{ brianmario-yajl-ruby }
|
15
|
+
s.rubygems_version = "1.3.1"
|
16
|
+
s.summary = "api niceness. "
|
17
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper.rb'
|
2
|
+
|
3
|
+
#
|
4
|
+
# FIXME: remove xml serialzation here and test resource directly.
|
5
|
+
#
|
6
|
+
context "active record converter" do
|
7
|
+
setup do
|
8
|
+
Person.restful_publish(:name, :wallet, :current_location, :pets => [:name, :species])
|
9
|
+
Pet.restful_publish(:person_id, :name) # person_id gets converted to a link automagically.
|
10
|
+
|
11
|
+
@person = Person.create(:name => "Joe Bloggs", :current_location => "Under a tree", :birthday => "1976-04-03")
|
12
|
+
@wallet = @person.wallet = Wallet.create!(:contents => "something in the wallet")
|
13
|
+
@pet = @person.pets.create(:name => "Mietze", :species => "cat")
|
14
|
+
end
|
15
|
+
|
16
|
+
teardown do
|
17
|
+
reset_config
|
18
|
+
end
|
19
|
+
|
20
|
+
specify "should publish link and not resource when :oldest_pet_restful_url, where oldest_pet is a defined method" do
|
21
|
+
Person.restful_publish(:oldest_pet_restful_url)
|
22
|
+
@person.to_restful.links.size.should.== 1
|
23
|
+
@person.to_restful.links.first.name.should.== "oldest-pet-restful-url"
|
24
|
+
end
|
25
|
+
|
26
|
+
specify "should publish link and not a nested resource with :wallet_restful_url" do
|
27
|
+
Person.restful_publish(:wallet_restful_url)
|
28
|
+
@person.to_restful.links.size.should.== 1
|
29
|
+
@person.to_restful.links.first.name.should.== "wallet-restful-url"
|
30
|
+
@person.to_restful.links.first.value.should.== @wallet.restful_url
|
31
|
+
end
|
32
|
+
|
33
|
+
specify "should be able to force expansion. force expanded attributes can never be collapsed. " do
|
34
|
+
Wallet.restful_publish(:contents)
|
35
|
+
Person.restful_publish(:name, :wallet, :current_location, { :pets => [:name, :species], :restful_options => { :force_expand => :wallet } })
|
36
|
+
Pet.restful_publish(:owner, :name)
|
37
|
+
|
38
|
+
@pet.to_restful
|
39
|
+
end
|
40
|
+
|
41
|
+
specify "should return link attributes from a model" do
|
42
|
+
@pet.to_restful.links.map { |node| node.name }.sort.should.equal [:person_id]
|
43
|
+
end
|
44
|
+
|
45
|
+
specify "should convert a NULL inner association such as person.wallet to a link with a null value" do
|
46
|
+
@person.wallet = nil
|
47
|
+
|
48
|
+
wallet = @person.to_restful(:restful_options => { :expansion => :collapsed }).links.select { |link| link.name == "wallet-restful-url" }.first
|
49
|
+
wallet.should.not.== nil
|
50
|
+
wallet.value.should.== nil
|
51
|
+
end
|
52
|
+
|
53
|
+
specify "should return plain attributes from a model" do
|
54
|
+
@pet.to_restful.simple_attributes.map { |node| node.name }.should.equal [:name]
|
55
|
+
end
|
56
|
+
|
57
|
+
specify "should return collections attributes from a model" do
|
58
|
+
restful = @person.to_restful
|
59
|
+
restful.collections.map { |node| node.name }.sort.should.equal [:pets]
|
60
|
+
end
|
61
|
+
|
62
|
+
specify "should set correct type for date" do
|
63
|
+
restful = @person.to_restful :birthday
|
64
|
+
restful.simple_attributes.detect { |node| node.name == :birthday }.extended_type.should.== :date
|
65
|
+
end
|
66
|
+
|
67
|
+
specify "should be able to convert themselves to an apimodel containing all and only the attributes exposed by Model.publish_api" do
|
68
|
+
resource = @person.to_restful
|
69
|
+
|
70
|
+
resource.simple_attributes.select { |node| node.name == :name }.should.not.blank
|
71
|
+
resource.simple_attributes.select { |node| node.name == :biography }.should.blank
|
72
|
+
|
73
|
+
mietze = @person.to_restful.collections .select { |node| node.name == :pets }.first.value.first
|
74
|
+
mietze.simple_attributes.size.should.== 2
|
75
|
+
mietze.simple_attributes.select { |node| node.name == :name }.should.not.blank
|
76
|
+
mietze.simple_attributes.select { |node| node.name == :species }.should.not.blank
|
77
|
+
end
|
78
|
+
|
79
|
+
specify "should be able to convert themselves to an apimodel containing all and only the attributes exposed by Model.publish_api. this holds true if to_restful is called with some configuration options. " do
|
80
|
+
resource = @person.to_restful(:restful_options => { :nested => false })
|
81
|
+
resource.simple_attributes.select { |node| node.name == :name }.should.not.blank
|
82
|
+
resource.simple_attributes.select { |node| node.name == :biography }.should.blank
|
83
|
+
|
84
|
+
mietze = resource.collections .select { |node| node.name == :pets }.first.value.first
|
85
|
+
mietze.simple_attributes.size.should.== 2
|
86
|
+
mietze.simple_attributes.select { |node| node.name == :name }.should.not.blank
|
87
|
+
mietze.simple_attributes.select { |node| node.name == :species }.should.not.blank
|
88
|
+
end
|
89
|
+
|
90
|
+
specify "should be able to override to_restful published fields by passing them into the method" do
|
91
|
+
api = @person.to_restful(:pets)
|
92
|
+
|
93
|
+
api.simple_attributes.should.blank?
|
94
|
+
api.collections.map { |node| node.name }.sort.should.equal [:pets]
|
95
|
+
end
|
96
|
+
|
97
|
+
specify "should be able to handle relations that are nil/null" do
|
98
|
+
@person.wallet = nil
|
99
|
+
@person.save!
|
100
|
+
@person.reload
|
101
|
+
|
102
|
+
assert_nothing_raised do
|
103
|
+
@person.to_restful
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
specify "should be able to expand a :belongs_to relationship" do
|
108
|
+
xml_should_eql_fixture(@pet.to_restful_xml(:owner), "pets", :nameless_pet)
|
109
|
+
end
|
110
|
+
|
111
|
+
specify "should return collapsed resources by default when :expansion => :collapsed is passed" do
|
112
|
+
Person.restful_publish(:name, :wallet, :restful_options => { :expansion => :collapsed })
|
113
|
+
xml_should_eql_fixture(@person.to_restful_xml, "people", :joe_bloggs)
|
114
|
+
end
|
115
|
+
|
116
|
+
specify "should be able to export content generated by methods that return strings" do
|
117
|
+
xml_should_eql_fixture(@person.to_restful_xml(:location_sentence), "people", :no_wallet)
|
118
|
+
end
|
119
|
+
|
120
|
+
specify "should be able to export content generated by methods (not attributes) and compute the correct style" do
|
121
|
+
xml_should_eql_fixture(@person.to_restful_xml(:oldest_pet), "people", :with_oldest_pet)
|
122
|
+
end
|
123
|
+
|
124
|
+
specify "should be able to export content generated by methods (not attributes) while filtering with a nested configuration" do
|
125
|
+
xml_should_eql_fixture(@person.to_restful_xml(:oldest_pet => [:species]), "people", :with_oldest_pet_species)
|
126
|
+
end
|
127
|
+
|
128
|
+
specify "should create element with nil='true' attribute if no relation is set" do
|
129
|
+
@person.wallet = nil
|
130
|
+
@person.save
|
131
|
+
|
132
|
+
xml_should_eql_fixture(@person.to_restful_xml(:wallet), "people", :joe_with_zwiebelleder)
|
133
|
+
end
|
134
|
+
|
135
|
+
specify "should include attributes when include parameter is passed to to_restful" do
|
136
|
+
Person.restful_publish(:name)
|
137
|
+
Pet.restful_publish(:name)
|
138
|
+
|
139
|
+
@person = Person.create
|
140
|
+
@pet = @person.pets.create(:name => "Mietze")
|
141
|
+
|
142
|
+
@pet.to_restful(:include => :owner).values.map(&:name).should.include :owner
|
143
|
+
Pet.restful_config.whitelisted.include?(:owner).should.equal false
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper.rb'
|
2
|
+
|
3
|
+
context "basic types converter" do
|
4
|
+
|
5
|
+
teardown { reset_config }
|
6
|
+
|
7
|
+
specify "should be able to convert a hash to a resource map" do
|
8
|
+
Person.restful_publish(:name)
|
9
|
+
resource = { "zeperson" => @person = Person.create(:name => "fuddzle") }.to_restful
|
10
|
+
resource.should.is_a?(Restful::ApiModel::Map)
|
11
|
+
|
12
|
+
attrs = resource.simple_attributes
|
13
|
+
attrs.size.should.== 1
|
14
|
+
attrs.first.name.should.== "zeperson"
|
15
|
+
|
16
|
+
attrs.first.value.values.first.value.== "fuddzle"
|
17
|
+
end
|
18
|
+
|
19
|
+
specify "should raise exception if not all array contents respond to .to_restful" do
|
20
|
+
Person.restful_publish(:name)
|
21
|
+
|
22
|
+
should.raise(TypeError) do
|
23
|
+
[""].to_restful
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
specify "should convert an empty array to a restful collection" do
|
28
|
+
collection = [].to_restful
|
29
|
+
collection.name.should.== "nil-classes"
|
30
|
+
end
|
31
|
+
|
32
|
+
specify "should infer array name from first element class" do
|
33
|
+
collection = [Pet.new].to_restful
|
34
|
+
collection.name.should.== "pets"
|
35
|
+
end
|
36
|
+
|
37
|
+
specify "should infer array name from first element base_class if it is an active_record object" do
|
38
|
+
collection = [Emu.new, Pet.new].to_restful
|
39
|
+
collection.name.should.== "pets"
|
40
|
+
end
|
41
|
+
|
42
|
+
specify "should convert an array to a restful collection" do
|
43
|
+
Person.restful_publish(:name)
|
44
|
+
|
45
|
+
collection = [Person.create(:name => "Joe Bloggs")].to_restful
|
46
|
+
collection.name.should.== "people"
|
47
|
+
collection.value.size.should.== 1
|
48
|
+
collection.value.first.simple_attributes.first.value.should.== "Joe Bloggs"
|
49
|
+
end
|
50
|
+
|
51
|
+
specify "should set total_entries on the restful collection if the array responds to this" do
|
52
|
+
Person.restful_publish(:name)
|
53
|
+
people = PaginatedCollection.new([Person.create(:name => "Joe Bloggs")])
|
54
|
+
people.total_entries = 1001
|
55
|
+
|
56
|
+
collection = people.to_restful
|
57
|
+
collection.total_entries.should.== 1001
|
58
|
+
end
|
59
|
+
|
60
|
+
specify "should set name on collection if array responds to .name and has this set" do
|
61
|
+
Person.restful_publish(:name)
|
62
|
+
people = PaginatedCollection.new()
|
63
|
+
people.total_entries = 0
|
64
|
+
people.name = "people"
|
65
|
+
|
66
|
+
collection = people.to_restful
|
67
|
+
collection.name.should.== "people"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "basic types converter :includes" do
|
72
|
+
|
73
|
+
specify "should include extra attributes for hashes" do
|
74
|
+
Person.restful_publish(:name)
|
75
|
+
Pet.restful_publish(:name)
|
76
|
+
|
77
|
+
@person = Person.create
|
78
|
+
@pet = @person.pets.create(:name => "Mietze")
|
79
|
+
|
80
|
+
map = { :pet => @pet }.to_restful(:include => :owner)
|
81
|
+
map.values.first.name.should.== :pet
|
82
|
+
map.values.first.value.values.map(&:name).should.include :owner
|
83
|
+
|
84
|
+
Pet.restful_config.whitelisted.include?(:owner).should.equal false
|
85
|
+
end
|
86
|
+
|
87
|
+
specify "should include extra attributes for arrays" do
|
88
|
+
Person.restful_publish(:name)
|
89
|
+
Pet.restful_publish(:name)
|
90
|
+
|
91
|
+
@person = Person.create
|
92
|
+
@pet = @person.pets.create(:name => "Mietze")
|
93
|
+
|
94
|
+
collection = [@pet].to_restful(:include => :owner)
|
95
|
+
collection.value.first.values.map(&:name).should.include :owner
|
96
|
+
|
97
|
+
Pet.restful_config.whitelisted.include?(:owner).should.equal false
|
98
|
+
end
|
99
|
+
end
|