render 0.0.1
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/.gitignore +20 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +49 -0
- data/LICENSE.txt +22 -0
- data/extensions/boolean.rb +3 -0
- data/extensions/dottable_hash.rb +113 -0
- data/extensions/enumerable.rb +36 -0
- data/extensions/hash.rb +52 -0
- data/initialize.rb +7 -0
- data/lib/render/attribute.rb +99 -0
- data/lib/render/errors.rb +64 -0
- data/lib/render/generator.rb +14 -0
- data/lib/render/graph.rb +106 -0
- data/lib/render/schema.rb +114 -0
- data/lib/render/version.rb +3 -0
- data/lib/render.rb +42 -0
- data/rakefile.rb +11 -0
- data/readme.md +90 -0
- data/render.gemspec +30 -0
- data/spec/functional/representation/attribute_spec.rb +29 -0
- data/spec/functional/representation/nested_schemas_spec.rb +103 -0
- data/spec/functional/representation/schema_spec.rb +86 -0
- data/spec/integration/nested_graph_spec.rb +77 -0
- data/spec/integration/single_graph_spec.rb +75 -0
- data/spec/schemas/film.json +8 -0
- data/spec/schemas/films.json +13 -0
- data/spec/support/helpers.rb +3 -0
- data/spec/support.rb +7 -0
- data/spec/unit/extensions/boolean_spec.rb +7 -0
- data/spec/unit/render/attribute_spec.rb +128 -0
- data/spec/unit/render/generator_spec.rb +39 -0
- data/spec/unit/render/graph_spec.rb +205 -0
- data/spec/unit/render/schema_spec.rb +250 -0
- data/spec/unit/render_spec.rb +81 -0
- metadata +217 -0
data/spec/support.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
module Render
|
2
|
+
describe Attribute do
|
3
|
+
describe "#initialize" do
|
4
|
+
describe "#name" do
|
5
|
+
it "is set from options key" do
|
6
|
+
options = { id: { type: UUID } }
|
7
|
+
Attribute.new(options).name.should == :id
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#type" do
|
12
|
+
it "is set from options" do
|
13
|
+
type = Integer
|
14
|
+
attribute = Attribute.new({ type: type })
|
15
|
+
attribute.type.should == type
|
16
|
+
end
|
17
|
+
|
18
|
+
it "is set from name hash" do
|
19
|
+
type = String
|
20
|
+
attribute = Attribute.new({ id: { type: UUID } })
|
21
|
+
attribute.type.should == UUID
|
22
|
+
end
|
23
|
+
|
24
|
+
it "determines type from string" do
|
25
|
+
Attribute.new({ type: "string" }).type.should == String
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#schema" do
|
30
|
+
it "is set to nil if its a regular attribute" do
|
31
|
+
Attribute.new({ id: { type: UUID } }).schema.should == nil
|
32
|
+
end
|
33
|
+
|
34
|
+
it "is initiazed from options" do
|
35
|
+
options = {
|
36
|
+
film: {
|
37
|
+
type: Object,
|
38
|
+
attributes: {
|
39
|
+
year: { type: Integer }
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
schema = Attribute.new(options).schema
|
45
|
+
schema.title.should == :film
|
46
|
+
schema.type.should == Object
|
47
|
+
attributes = schema.attributes
|
48
|
+
attributes.size.should == 1
|
49
|
+
attribute = attributes.first
|
50
|
+
attribute.name.should == :year
|
51
|
+
attribute.type.should == Integer
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "enums" do
|
56
|
+
it "sets enum values" do
|
57
|
+
enum_values = ["foo", "bar", "baz"]
|
58
|
+
attribute = Attribute.new({ type: String, enum: enum_values })
|
59
|
+
attribute.enums.should == enum_values
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#to_hash" do
|
65
|
+
it "converts attributes to hashes" do
|
66
|
+
attributes = { foo: { type: String } }
|
67
|
+
attribute = Attribute.new(attributes)
|
68
|
+
attribute.to_hash.should == { foo: nil }
|
69
|
+
end
|
70
|
+
|
71
|
+
it "converts attributes to hashes with values" do
|
72
|
+
attributes = { foo: { type: String } }
|
73
|
+
attribute = Attribute.new(attributes)
|
74
|
+
attribute.to_hash("bar").should == { foo: "bar" }
|
75
|
+
end
|
76
|
+
|
77
|
+
it "converts schema values to hashes" do
|
78
|
+
schema_name = "foo"
|
79
|
+
attributes = {
|
80
|
+
schema_name => {
|
81
|
+
type: Object,
|
82
|
+
attributes: {
|
83
|
+
attribute: { type: String }
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
value = "baz"
|
89
|
+
data = { attribute: value }
|
90
|
+
|
91
|
+
attribute = Attribute.new(attributes)
|
92
|
+
attribute.to_hash(data).should == { foo: { :attribute => value } }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "#value" do
|
97
|
+
context "offline mode" do
|
98
|
+
before(:all) do
|
99
|
+
@original_live = Render.live
|
100
|
+
Render.live = false
|
101
|
+
end
|
102
|
+
|
103
|
+
after(:all) do
|
104
|
+
Render.live = @original_live
|
105
|
+
end
|
106
|
+
|
107
|
+
it "generate value based on type" do
|
108
|
+
supported_classes = [
|
109
|
+
String,
|
110
|
+
Integer
|
111
|
+
]
|
112
|
+
|
113
|
+
supported_classes.each do |klass|
|
114
|
+
Attribute.new({ type: klass }).default_value.should be_a(klass)
|
115
|
+
end
|
116
|
+
UUID.validate(Attribute.new({ type: UUID }).default_value).should be_true
|
117
|
+
end
|
118
|
+
|
119
|
+
it "generates value from enum" do
|
120
|
+
enums = ["horror", "comedy", "drama"]
|
121
|
+
attribute = Attribute.new({ genre: { enum: enums, type: String } })
|
122
|
+
enums.should include(attribute.default_value)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "render/generator"
|
2
|
+
|
3
|
+
module Render
|
4
|
+
describe Generator do
|
5
|
+
it "exists" do
|
6
|
+
expect { Generator }.to_not raise_error
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "attributes" do
|
10
|
+
before(:each) do
|
11
|
+
@mandatory_options = { algorithm: proc {} }
|
12
|
+
end
|
13
|
+
|
14
|
+
it "is a type-specific generator for flexibility" do
|
15
|
+
Generator.new(@mandatory_options.merge({ type: String })).type.should == String
|
16
|
+
end
|
17
|
+
|
18
|
+
it "has a matcher to only be used on specific attributes" do
|
19
|
+
matcher = %r{.*name.*}
|
20
|
+
Generator.new(@mandatory_options.merge({ matcher: matcher })).matcher.should == matcher
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#algorith" do
|
24
|
+
it "has an algorithm that generates a value to be used" do
|
25
|
+
algorithm = lambda { "The Darjeeling limited" }
|
26
|
+
Generator.new({ algorithm: algorithm }).algorithm.should == algorithm
|
27
|
+
end
|
28
|
+
|
29
|
+
it "raises an error if algorithm does not respond to call" do
|
30
|
+
expect {
|
31
|
+
Generator.new({ algorithm: "want this to be the fake value" })
|
32
|
+
}.to raise_error(Errors::Generator::MalformedAlgorithm)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "render/graph"
|
3
|
+
require "uuid"
|
4
|
+
|
5
|
+
module Render
|
6
|
+
describe Graph do
|
7
|
+
before(:each) do
|
8
|
+
@schema = double(:schema)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe ".initialize" do
|
12
|
+
it "has defaults" do
|
13
|
+
graph = Graph.new(@schema)
|
14
|
+
graph.raw_endpoint.should == ""
|
15
|
+
graph.relationships.should == {}
|
16
|
+
graph.graphs.should == []
|
17
|
+
graph.parental_params.should == {}
|
18
|
+
graph.config.should == {}
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "schema" do
|
22
|
+
it "sets argument" do
|
23
|
+
graph = Graph.new(@schema)
|
24
|
+
graph.schema.should == @schema
|
25
|
+
end
|
26
|
+
|
27
|
+
it "creates new schema from symbol (for loaded schema lookup)" do
|
28
|
+
Schema.should_receive(:new).with(:film).and_return(:new_schema)
|
29
|
+
Graph.new(:film).schema.should == :new_schema
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "sets attributes" do
|
34
|
+
relationships = { director_id: :id }
|
35
|
+
graphs = [double(:graph)]
|
36
|
+
graph = Graph.new(@schema, {
|
37
|
+
relationships: relationships,
|
38
|
+
graphs: graphs,
|
39
|
+
})
|
40
|
+
|
41
|
+
graph.relationships.should == relationships
|
42
|
+
graph.graphs.should == graphs
|
43
|
+
end
|
44
|
+
|
45
|
+
it "treats non-used attributes as config" do
|
46
|
+
relationships = { some: :relationship }
|
47
|
+
graphs = [double(:some_graph)]
|
48
|
+
client_id = UUID.generate
|
49
|
+
graph = Graph.new(@schema, {
|
50
|
+
relationships: relationships,
|
51
|
+
graphs: graphs,
|
52
|
+
client_id: client_id
|
53
|
+
})
|
54
|
+
|
55
|
+
graph.config.should == { client_id: client_id }
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#raw_endpoint" do
|
59
|
+
it "is set with endpoint" do
|
60
|
+
endpoint = "http://endpoint.local"
|
61
|
+
graph = Graph.new(@schema, { endpoint: endpoint })
|
62
|
+
graph.raw_endpoint.should == endpoint
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
it "initializes params from endpoint" do
|
67
|
+
endpoint = "http://endpoint.local/:id?client_id=:client_id"
|
68
|
+
graph = Graph.new(@schema, { endpoint: endpoint })
|
69
|
+
graph.params.should == { id: nil, client_id: nil }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe ".endpoint" do
|
74
|
+
it "returns #raw_endpoint" do
|
75
|
+
simple_endpoint = "http://endpoint.local"
|
76
|
+
graph = Graph.new(@schema, { endpoint: simple_endpoint })
|
77
|
+
graph.endpoint.should == simple_endpoint
|
78
|
+
end
|
79
|
+
|
80
|
+
it "interpolates parental_params" do
|
81
|
+
director_id = UUID.generate
|
82
|
+
endpoint = "http://endpoint.local/directors/:id"
|
83
|
+
interpolated_endpoint = "http://endpoint.local/directors/#{director_id}"
|
84
|
+
|
85
|
+
relationships = { director_id: :id }
|
86
|
+
graph = Graph.new(@schema, { endpoint: endpoint, relationships: relationships })
|
87
|
+
graph.parental_params[:id] = director_id
|
88
|
+
|
89
|
+
graph.endpoint.should == interpolated_endpoint
|
90
|
+
end
|
91
|
+
|
92
|
+
it "interpolates config attributes" do
|
93
|
+
client_id = UUID.generate
|
94
|
+
endpoint = "http://endpoint.local/?:client_id"
|
95
|
+
interpolated_endpoint = "http://endpoint.local/?client_id=#{client_id}"
|
96
|
+
|
97
|
+
graph = Graph.new(@schema, { endpoint: endpoint, client_id: client_id })
|
98
|
+
graph.endpoint.should == interpolated_endpoint
|
99
|
+
end
|
100
|
+
|
101
|
+
it "interpolates multiple path and query values" do
|
102
|
+
the_shinning = UUID.generate
|
103
|
+
kubrick = UUID.generate
|
104
|
+
client_id = UUID.generate
|
105
|
+
client_secret = UUID.generate
|
106
|
+
|
107
|
+
endpoint = "http://endpoint.local/directors/:id/films/:film_id?:client_id&:client_secret"
|
108
|
+
interpolated_endpoint = "http://endpoint.local/directors/#{kubrick}/films/#{the_shinning}?client_id=#{client_id}&client_secret=#{client_secret}"
|
109
|
+
|
110
|
+
graph = Graph.new(@schema, { endpoint: endpoint, client_id: client_id, client_secret: client_secret })
|
111
|
+
graph.parental_params = { id: kubrick, film_id: the_shinning }
|
112
|
+
|
113
|
+
graph.endpoint.should == interpolated_endpoint
|
114
|
+
end
|
115
|
+
|
116
|
+
it "raises an error if no value can be found" do
|
117
|
+
endpoint = "http://endpoint.com/?:undefined_key"
|
118
|
+
graph = Graph.new(@schema, { endpoint: endpoint })
|
119
|
+
|
120
|
+
expect {
|
121
|
+
graph.endpoint
|
122
|
+
}.to raise_error(Errors::Graph::EndpointKeyNotFound)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe ".pull" do
|
127
|
+
it "returns its schema's data" do
|
128
|
+
pull = { film: { id: UUID.generate } }
|
129
|
+
@schema.stub({ pull: pull })
|
130
|
+
|
131
|
+
graph = Graph.new(@schema)
|
132
|
+
graph.pull.should == pull
|
133
|
+
end
|
134
|
+
|
135
|
+
it "sends interpolated endpoint to its schema" do
|
136
|
+
endpoint = "http://endpoint.local/?:client_id"
|
137
|
+
client_id = UUID.generate
|
138
|
+
graph = Graph.new(@schema, { endpoint: endpoint, client_id: client_id })
|
139
|
+
|
140
|
+
@schema.should_receive(:pull).with({ endpoint: graph.endpoint }).and_return(@pull)
|
141
|
+
graph.pull.should == @pull
|
142
|
+
end
|
143
|
+
|
144
|
+
context "with nested graphs" do
|
145
|
+
before(:each) do
|
146
|
+
Render.stub({ live: false })
|
147
|
+
|
148
|
+
director_schema = {
|
149
|
+
title: "director",
|
150
|
+
type: Object,
|
151
|
+
attributes: { id: { type: UUID } }
|
152
|
+
}
|
153
|
+
@director_schema = Schema.new(director_schema)
|
154
|
+
|
155
|
+
film_schema = {
|
156
|
+
title: "film",
|
157
|
+
type: Object,
|
158
|
+
attributes: { director_id: { type: UUID } }
|
159
|
+
}
|
160
|
+
@film_schema = Schema.new(film_schema)
|
161
|
+
end
|
162
|
+
|
163
|
+
it "merges nested graphs" do
|
164
|
+
pulled_data = { a: "attribute" }
|
165
|
+
@director_schema.stub({ pull: pulled_data })
|
166
|
+
|
167
|
+
director = Graph.new(@director_schema)
|
168
|
+
film = Graph.new(@film_schema, { graphs: [director]})
|
169
|
+
|
170
|
+
film_graph = film.pull[@film_schema.title.to_sym]
|
171
|
+
film_graph.should include(pulled_data)
|
172
|
+
end
|
173
|
+
|
174
|
+
it "uses parent data to calculate endpoint" do
|
175
|
+
director_id = UUID.generate
|
176
|
+
film = Graph.new(@film_schema)
|
177
|
+
film.schema.stub({ pull: { film: { director_id: director_id } } })
|
178
|
+
|
179
|
+
endpoint = "http://endpoint.local/directors/:id"
|
180
|
+
interpolated_endpoint = "http://endpoint.local/directors/#{director_id}"
|
181
|
+
relationships = { director_id: :id }
|
182
|
+
director = Graph.new(@director_schema, { endpoint: endpoint, relationships: relationships })
|
183
|
+
|
184
|
+
film.graphs << director
|
185
|
+
director.schema.should_receive(:pull).with do |args|
|
186
|
+
args[:endpoint].should == interpolated_endpoint
|
187
|
+
end.and_return({})
|
188
|
+
|
189
|
+
film.pull
|
190
|
+
end
|
191
|
+
|
192
|
+
context "offline" do
|
193
|
+
it "uses parent data for childrens attributes" do
|
194
|
+
relationships = { director_id: :id }
|
195
|
+
director = Graph.new(@director_schema, { relationships: relationships })
|
196
|
+
film = Graph.new(@film_schema, { graphs: [director]})
|
197
|
+
|
198
|
+
film_graph = film.pull[@film_schema.title.to_sym]
|
199
|
+
film_graph[@director_schema.title.to_sym][:id].should == film_graph[:director_id]
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
@@ -0,0 +1,250 @@
|
|
1
|
+
require "render"
|
2
|
+
|
3
|
+
module Render
|
4
|
+
describe Schema do
|
5
|
+
before(:each) do
|
6
|
+
@film_schema = {
|
7
|
+
title: "film",
|
8
|
+
type: Object,
|
9
|
+
attributes: {
|
10
|
+
name: { type: String },
|
11
|
+
genre: { type: String }
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
@films_schema = {
|
16
|
+
title: "films",
|
17
|
+
type: Array,
|
18
|
+
elements: {
|
19
|
+
title: :film,
|
20
|
+
attributes: {
|
21
|
+
name: { type: String },
|
22
|
+
genre: { type: String }
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
@director_schema = {
|
28
|
+
title: "director",
|
29
|
+
type: Object,
|
30
|
+
attributes: {
|
31
|
+
films: {
|
32
|
+
type: Array,
|
33
|
+
elements: {
|
34
|
+
type: Object,
|
35
|
+
attributes: {
|
36
|
+
name: { type: String },
|
37
|
+
year: { type: Integer }
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#initialize" do
|
46
|
+
describe "#schema" do
|
47
|
+
before(:each) do
|
48
|
+
@schema = { attributes: {} }
|
49
|
+
end
|
50
|
+
|
51
|
+
it "is set to hash argument" do
|
52
|
+
Schema.new(@schema).schema.should == @schema
|
53
|
+
end
|
54
|
+
|
55
|
+
it "is set to preloaded schema" do
|
56
|
+
Render.stub({ schemas: { film: @schema } })
|
57
|
+
Schema.new(:film).schema.should == @schema
|
58
|
+
end
|
59
|
+
|
60
|
+
it "raises an error if preloaded schema cannot be found" do
|
61
|
+
expect {
|
62
|
+
Schema.new(:unloaded_schema)
|
63
|
+
}.to raise_error(Render::Errors::Schema::NotFound)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it "sets title from schema" do
|
68
|
+
title = "films"
|
69
|
+
schema = { title: title, attributes: {} }
|
70
|
+
Schema.new(schema).title.should == title
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#type" do
|
74
|
+
it "is set from schema" do
|
75
|
+
type = [Array, Object].sample
|
76
|
+
schema = { type: type, attributes: {} }
|
77
|
+
Schema.new(schema).type.should == type
|
78
|
+
end
|
79
|
+
|
80
|
+
it "is parsed from string" do
|
81
|
+
schema = { type: "string", attributes: {} }
|
82
|
+
Schema.new(schema).type.should == String
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "#attributes" do
|
87
|
+
it "is set with simple Attributes" do
|
88
|
+
simple_schema = {
|
89
|
+
attributes: {
|
90
|
+
name: { type: String },
|
91
|
+
genre: { type: String }
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
schema = Schema.new(simple_schema)
|
96
|
+
schema.attributes.size.should == 2
|
97
|
+
schema.attributes.any? { |a| a.name == :name && a.type == String }.should == true
|
98
|
+
schema.attributes.any? { |a| a.name == :genre && a.type == String }.should == true
|
99
|
+
end
|
100
|
+
|
101
|
+
it "is set with array archetypes" do
|
102
|
+
archetype_schema = {
|
103
|
+
elements: {
|
104
|
+
type: String
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
attributes = Schema.new(archetype_schema).attributes
|
109
|
+
attributes.size.should == 1
|
110
|
+
attributes.first.type.should == String
|
111
|
+
end
|
112
|
+
|
113
|
+
it "is set with schema-Attributes" do
|
114
|
+
nested_schema = {
|
115
|
+
attributes: {
|
116
|
+
film: {
|
117
|
+
type: Object,
|
118
|
+
attributes: {
|
119
|
+
name: { type: String }
|
120
|
+
}
|
121
|
+
}
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
125
|
+
schema = Schema.new(nested_schema)
|
126
|
+
schema.attributes.size.should == 1
|
127
|
+
schema.attributes.first.schema.should be
|
128
|
+
end
|
129
|
+
|
130
|
+
it "is set with array-Attributes" do
|
131
|
+
array_schema = {
|
132
|
+
elements: {
|
133
|
+
film: {
|
134
|
+
type: Object,
|
135
|
+
attributes: {
|
136
|
+
name: { type: String }
|
137
|
+
}
|
138
|
+
}
|
139
|
+
}
|
140
|
+
}
|
141
|
+
schema = Schema.new(array_schema)
|
142
|
+
schema.attributes.size.should == 1
|
143
|
+
schema.attributes.first.schema.should be
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "#pull" do
|
149
|
+
context "live" do
|
150
|
+
it "returns schema with values from endpoint" do
|
151
|
+
endpoint = "http://endpoint.local"
|
152
|
+
name = "The Shining"
|
153
|
+
genre = "Horror"
|
154
|
+
response_body = { film: { name: name, genre: genre } }
|
155
|
+
response = { status: 200, body: response_body.to_json }
|
156
|
+
stub_request(:get, endpoint).to_return(response)
|
157
|
+
|
158
|
+
film = Schema.new(@film_schema)
|
159
|
+
film.pull({ endpoint: endpoint }).should == response_body
|
160
|
+
end
|
161
|
+
|
162
|
+
it "raises error if response is not 2xx" do
|
163
|
+
endpoint = "http://endpoint.local"
|
164
|
+
response = { status: 403, body: "OMGWTFBBQ" }
|
165
|
+
stub_request(:get, endpoint).to_return(response)
|
166
|
+
|
167
|
+
expect {
|
168
|
+
film = Schema.new(@film_schema)
|
169
|
+
film.pull({ endpoint: endpoint })
|
170
|
+
}.to raise_error(Errors::Schema::RequestError)
|
171
|
+
end
|
172
|
+
|
173
|
+
it "returns meaningful error when response contains invalid JSON" do
|
174
|
+
endpoint = "http://enpoint.local"
|
175
|
+
stub_request(:get, endpoint).to_return({ body: "Server Error: 500" })
|
176
|
+
|
177
|
+
expect {
|
178
|
+
Schema.new(@film_schema).pull({ endpoint: endpoint })
|
179
|
+
}.to raise_error(Errors::Schema::InvalidResponse)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context "faked" do
|
184
|
+
before(:each) do
|
185
|
+
Render.stub({ live: false })
|
186
|
+
end
|
187
|
+
|
188
|
+
it "returns schema with fake values" do
|
189
|
+
film = Schema.new(@film_schema)
|
190
|
+
film = film.pull[:film]
|
191
|
+
film[:name].should be_a(String)
|
192
|
+
film[:genre].should be_a(String)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
it "handles responses that do not use schema title as root key" do
|
197
|
+
endpoint = "http://endpoint.local"
|
198
|
+
response_body = { name: "the name", genre: "the genre" }
|
199
|
+
response = { status: 200, body: response_body.to_json }
|
200
|
+
stub_request(:get, endpoint).to_return(response)
|
201
|
+
|
202
|
+
film = Schema.new(@film_schema)
|
203
|
+
film.pull({ endpoint: endpoint }).should == { film: response_body }
|
204
|
+
end
|
205
|
+
|
206
|
+
it "handles Array responses" do
|
207
|
+
endpoint = "http://endpoint.local"
|
208
|
+
first_name = "The Shining"
|
209
|
+
second_name = "Eyes Wide Shut"
|
210
|
+
genre = "Horror"
|
211
|
+
|
212
|
+
response_body = [
|
213
|
+
{ name: first_name, genre: genre },
|
214
|
+
{ name: second_name, genre: genre }
|
215
|
+
]
|
216
|
+
response = { status: 200, body: response_body.to_json }
|
217
|
+
stub_request(:get, endpoint).to_return(response)
|
218
|
+
|
219
|
+
film = Schema.new(@films_schema)
|
220
|
+
film.pull({ endpoint: endpoint }).should == { films: response_body }
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
describe "#serialize" do
|
225
|
+
it "returns parsed array elements" do
|
226
|
+
Render.stub({ live: false })
|
227
|
+
director = Schema.new(@director_schema)
|
228
|
+
|
229
|
+
kubrick = "Stanley Kubrick"
|
230
|
+
first_film = "Flying Padre: An RKO-Pathe Screenliner"
|
231
|
+
year = 1951
|
232
|
+
data = {
|
233
|
+
films: [{
|
234
|
+
name: first_film,
|
235
|
+
notInSchema: "experimental",
|
236
|
+
year: year
|
237
|
+
}]
|
238
|
+
}
|
239
|
+
|
240
|
+
director.serialize(data).should == {
|
241
|
+
films: [{
|
242
|
+
name: first_film,
|
243
|
+
year: year
|
244
|
+
}]
|
245
|
+
}
|
246
|
+
end
|
247
|
+
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|