siren_client 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.
@@ -0,0 +1,17 @@
1
+ require 'sinatra'
2
+ require 'json'
3
+
4
+ class TestServer < Sinatra::Base
5
+ @@url = 'http://localhost:9292'
6
+
7
+ use Rack::Auth::Basic, "SirenClient Test API" do |username, password|
8
+ username == 'admin' and password == '1234'
9
+ end
10
+
11
+ before do
12
+ content_type 'application/vnd.siren+json'
13
+ end
14
+ end
15
+
16
+ # Require all the endpoint files that build the api.
17
+ Dir[__dir__ + "/endpoints/*.rb"].each {|file| require file }
@@ -0,0 +1,86 @@
1
+ require 'helper/spec_helper'
2
+
3
+ describe SirenClient::Action do
4
+ let (:action_data) { {"name"=>"search","method"=>"GET","href"=>"http://example.com/products","fields"=>[{"name"=>"search","type"=>"text"}]} }
5
+
6
+ describe '.new(data)' do
7
+ it 'raise an error if wrong type is provided' do
8
+ expect { SirenClient::Action.new([]) }.to raise_error(ArgumentError)
9
+ end
10
+ it 'can be instanciated with a hash' do
11
+ expect(SirenClient::Action.new(action_data)).to be_a SirenClient::Action
12
+ end
13
+ end
14
+
15
+ let (:action) {
16
+ SirenClient::Action.new(action_data, {
17
+ headers: { "Accept" => "application/json" }
18
+ })
19
+ }
20
+ describe '.config' do
21
+ it 'is a hash' do
22
+ expect(action.config).to be_a Hash
23
+ end
24
+ it 'can access a property of the config' do
25
+ expect(action.config[:headers]['Accept']).to eq('application/json')
26
+ end
27
+ end
28
+ describe '.payload' do
29
+ it 'is a hash' do
30
+ expect(action.payload).to be_a Hash
31
+ end
32
+ end
33
+ describe '.name' do
34
+ it 'is a string' do
35
+ expect(action.name).to be_a String
36
+ end
37
+ end
38
+ describe '.classes' do
39
+ it 'is an array' do
40
+ expect(action.classes).to be_a Array
41
+ end
42
+ end
43
+ describe '.method' do
44
+ it 'is a string' do
45
+ expect(action.method).to be_a String
46
+ end
47
+ it 'defaults to GET' do
48
+ expect(SirenClient::Action.new({ }).method).to eq('get')
49
+ end
50
+ end
51
+ describe '.href' do
52
+ it 'is a string' do
53
+ expect(action.href).to be_a String
54
+ end
55
+ end
56
+ describe '.title' do
57
+ it 'is a string' do
58
+ expect(action.title).to be_a String
59
+ end
60
+ end
61
+ describe '.type' do
62
+ it 'is a string' do
63
+ expect(action.type).to be_a String
64
+ end
65
+ it 'defaults to \'application/x-www-form-urlencoded\'' do
66
+ expect(action.type).to eq('application/x-www-form-urlencoded')
67
+ end
68
+ end
69
+ describe '.fields' do
70
+ it 'is an array' do
71
+ expect(action.fields).to be_a Array
72
+ end
73
+ it 'is an array of SirenClient::Field\'s' do
74
+ action.fields.each do |field|
75
+ expect(field).to be_a SirenClient::Field
76
+ end
77
+ end
78
+ end
79
+ describe '.where(params)' do
80
+ it 'executes the action without any parameters' do
81
+ # I'm expecting an error here, all I want to see is that the url it being traversed.
82
+ expect { action.where }.to raise_error
83
+ end
84
+ # The rest will be tested in the live specs.
85
+ end
86
+ end
@@ -0,0 +1,52 @@
1
+ require 'helper/spec_helper'
2
+
3
+ describe SirenClient do
4
+ let (:url_error_msg) { 'You must supply a valid url to SirenClient.get' }
5
+ let (:invalid_param_msg) { 'You must supply either a string or hash to SirenClient.get' }
6
+
7
+ describe '.get(config)' do
8
+ it "raise an error if no options are provided" do
9
+ expect { SirenClient.get }.to raise_error(ArgumentError)
10
+ end
11
+ it "raise an error if an improper param is provided" do
12
+ expect { SirenClient.get([1, 2, 3]) }.to raise_error(ArgumentError, invalid_param_msg)
13
+ expect { SirenClient.get(nil) }.to raise_error(ArgumentError, invalid_param_msg)
14
+ end
15
+ it "raise an error if no url is provided" do
16
+ expect { SirenClient.get(url: nil) }.to raise_error(ArgumentError, url_error_msg)
17
+ end
18
+ it "raise an error if an invalid url is provided" do
19
+ expect { SirenClient.get('error on me') }.to raise_error(SirenClient::InvalidURIError)
20
+ end
21
+ it "raise an error if the url does not return json" do
22
+ expect { SirenClient.get('http://google.com') }.to raise_error(SirenClient::InvalidResponseError)
23
+ end
24
+ end
25
+ describe '.logger(before)' do
26
+ it 'is a standard ruby logger instance' do
27
+ expect(SirenClient.logger).to be_a Logger
28
+ end
29
+ end
30
+ describe '.logger=' do
31
+ it 'raise an error if it does not respect the logger interface' do
32
+ expect { SirenClient.logger = "error" }.to raise_error
33
+ end
34
+ it 'accepts an instance that respects the logger interface' do
35
+ SirenClient.logger = Logger.new(STDOUT)
36
+ SirenClient.logger.level = Logger::WARN
37
+ expect(SirenClient.logger).to be_a Logger
38
+ end
39
+ end
40
+ describe '.logger(after)' do
41
+ it 'responds to .info(str)' do
42
+ expect(SirenClient.logger.respond_to?(:info)).to eq(true)
43
+ end
44
+ it 'responds to .warn(str)' do
45
+ expect(SirenClient.logger.respond_to?(:warn)).to eq(true)
46
+ end
47
+ it 'responds to .error(str)' do
48
+ expect(SirenClient.logger.respond_to?(:error)).to eq(true)
49
+ end
50
+ end
51
+ # Remainder will be tested in live spec
52
+ end
@@ -0,0 +1,179 @@
1
+ require 'helper/spec_helper'
2
+
3
+ describe SirenClient::Entity do
4
+
5
+ describe '.new(data)' do
6
+ it 'raise an error if no param is provided' do
7
+ expect { SirenClient::Entity.new }.to raise_error(ArgumentError)
8
+ end
9
+ it 'raise an error if an invalid type is provided' do
10
+ expect { SirenClient::Entity.new([]) }.to raise_error(ArgumentError)
11
+ end
12
+ it 'raise an error if an invalid url is provided' do
13
+ expect { SirenClient::Entity.new('error me') }.to raise_error(SirenClient::InvalidURIError)
14
+ end
15
+ it 'raise an error if the url does not return json' do
16
+ expect { SirenClient::Entity.new('http://www.google.com') }.to raise_error(SirenClient::InvalidResponseError)
17
+ end
18
+ # it 'can be instanciated with a proper url' do
19
+ # expect(SirenClient::Entity.new(valid_url)).to be_a SirenClient::Entity
20
+ # end
21
+ it 'can be instanciated with a hash of data' do
22
+ expect(SirenClient::Entity.new(siren_body)).to be_a SirenClient::Entity
23
+ end
24
+ end
25
+
26
+ let (:entity) {
27
+ SirenClient::Entity.new(siren_body, {
28
+ headers: { "Accept" => "application/json" }
29
+ })
30
+ }
31
+ describe '.config' do
32
+ it 'is a hash' do
33
+ expect(entity.config).to be_a Hash
34
+ end
35
+ it 'can access property in the config' do
36
+ expect(entity.config[:headers]['Accept']).to eq('application/json')
37
+ end
38
+ end
39
+ describe '.payload' do
40
+ it 'is a hash' do
41
+ expect(entity.payload).to be_a Hash
42
+ end
43
+ end
44
+ describe '.classes' do
45
+ it 'is an array' do
46
+ expect(entity.classes).to be_a Array
47
+ end
48
+ end
49
+ describe '.properties' do
50
+ it 'is a hash' do
51
+ expect(entity.properties).to be_a Hash
52
+ end
53
+ it 'can access a property' do
54
+ expect(entity.properties['page']).to eq(1)
55
+ end
56
+ it 'can access a property directly on the entity' do
57
+ expect(entity.page).to eq(1)
58
+ end
59
+ end
60
+ describe '.entities' do
61
+ it 'is an array' do
62
+ expect(entity.entities).to be_a Array
63
+ end
64
+ it 'is an array of SirenClient::Entity\'s' do
65
+ entity.entities.each do |ent|
66
+ expect(ent).to be_a SirenClient::Entity
67
+ end
68
+ end
69
+ end
70
+ describe '.rels' do
71
+ it 'is an array' do
72
+ expect(entity.rels).to be_a Array
73
+ end
74
+ end
75
+ describe '.links' do
76
+ it 'is a hash' do
77
+ expect(entity.links).to be_a Hash
78
+ end
79
+ it 'is a hash of { key => SirenClient::Link }\'s' do
80
+ expect {
81
+ entity.links.each do |key, link|
82
+ expect(key).to be_a String
83
+ expect(link).to be_a SirenClient::Link
84
+ end
85
+ }.to_not raise_error
86
+ end
87
+ it 'can access a link' do
88
+ expect(entity.links['self']).to be_a SirenClient::Link
89
+ end
90
+ end
91
+ describe '.actions' do
92
+ it 'is a hash' do
93
+ expect(entity.actions).to be_a Hash
94
+ end
95
+ it 'is a hash of { key => SirenClient::Action }\'s' do
96
+ expect {
97
+ entity.actions.each do |name, action|
98
+ expect(name).to be_a String
99
+ expect(action).to be_a SirenClient::Action
100
+ end
101
+ }.to_not raise_error
102
+ end
103
+ it 'can access an action' do
104
+ expect(entity.actions['filter_concepts']).to be_a SirenClient::Action
105
+ end
106
+ end
107
+ # This will be empty unless it's an entity sub-link.
108
+ describe '.href' do
109
+ it 'is a string' do
110
+ expect(entity.href).to be_a String
111
+ end
112
+ it 'should be empty' do
113
+ expect(entity.href).to eq('')
114
+ end
115
+ end
116
+ # Similar to SirenClient::Link.go this function will create a
117
+ # new entity from the .href method. For entity sub-links only.
118
+ describe '.go' do
119
+ let (:graph) { entity[0] }
120
+ it 'return nil if it\'s NOT an entity sub-link' do
121
+ expect(entity.go).to eq(nil)
122
+ end
123
+ it 'initiate a request if it IS an entity sub-link' do
124
+ expect { graph.entities[0].go }.to raise_error
125
+ end
126
+ end
127
+ describe '.invalidkey' do
128
+ it 'will throw a NoMethodError' do
129
+ expect { entity.thisdoesntexist }.to raise_error(NoMethodError)
130
+ end
131
+ end
132
+ describe '.validkey' do
133
+ let (:graph) { entity[0] }
134
+ it 'can access an entity sub-link within the entity' do
135
+ expect { graph.messages }.to raise_error
136
+ end
137
+ it 'can access a link directly on the entity' do
138
+ expect { entity.next }.to raise_error
139
+ end
140
+ it 'can access an action directly on the entity' do
141
+ expect(entity.filter_concepts).to be_a SirenClient::Action
142
+ end
143
+ end
144
+ describe '.title' do
145
+ it 'is a string' do
146
+ expect(entity.title).to be_a String
147
+ end
148
+ end
149
+ describe '.type' do
150
+ it 'is a string' do
151
+ expect(entity.type).to be_a String
152
+ end
153
+ end
154
+ describe '.length' do
155
+ it 'can return the size of @entities' do
156
+ expect(entity.length).to eq(1)
157
+ end
158
+ end
159
+ describe '[x]' do
160
+ it 'can get the first element' do
161
+ expect(entity[0]).to be_a SirenClient::Entity
162
+ end
163
+ it 'can get the last element' do
164
+ expect(entity[-1]).to be_a SirenClient::Entity
165
+ end
166
+ it 'causes entity sub-links to be traversed' do
167
+ expect(entity[0]).to be_a SirenClient::Entity
168
+ end
169
+ end
170
+ describe '.each' do
171
+ it 'can iterate over all the entities' do
172
+ expect {
173
+ entity.each do |ent|
174
+ expect(ent).to be_a SirenClient::Entity
175
+ end
176
+ }.to_not raise_error
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,44 @@
1
+ require 'helper/spec_helper'
2
+
3
+ describe SirenClient::Field do
4
+ let (:field_data) { {"name"=>"search","type"=>"text"} }
5
+
6
+ describe '.new(data)' do
7
+ it 'raise an error if wrong type is provided' do
8
+ expect { SirenClient::Field.new([]) }.to raise_error(ArgumentError)
9
+ end
10
+ it 'can be instanciated with a hash' do
11
+ expect(SirenClient::Field.new(field_data)).to be_a SirenClient::Field
12
+ end
13
+ end
14
+
15
+ let (:field) { SirenClient::Field.new(field_data) }
16
+ describe '.payload' do
17
+ it 'is a hash' do
18
+ expect(field.payload).to be_a Hash
19
+ end
20
+ end
21
+ describe '.name' do
22
+ it 'is a string' do
23
+ expect(field.name).to be_a String
24
+ end
25
+ end
26
+ describe '.type' do
27
+ it 'is a string' do
28
+ expect(field.type).to be_a String
29
+ end
30
+ it 'default to "text"' do
31
+ expect(SirenClient::Field.new({ }).type).to eq('text')
32
+ end
33
+ end
34
+ describe '.value' do
35
+ it 'is a string' do
36
+ expect(field.value).to be_a String
37
+ end
38
+ end
39
+ describe '.title' do
40
+ it 'is a string' do
41
+ expect(field.title).to be_a String
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,47 @@
1
+ require 'helper/spec_helper'
2
+
3
+ describe SirenClient::Link do
4
+ let (:link_data) { {"rel"=>["self"],"href"=>"http://example.com/products/03283378000P"} }
5
+
6
+ describe '.new(data)' do
7
+ it 'raise an error if wrong type is provided' do
8
+ expect { SirenClient::Link.new([]) }.to raise_error(ArgumentError)
9
+ end
10
+ it 'can be instanciated with a hash' do
11
+ expect(SirenClient::Link.new(link_data)).to be_a SirenClient::Link
12
+ end
13
+ end
14
+
15
+ let (:link) { SirenClient::Link.new(link_data) }
16
+ describe '.go' do
17
+ it 'follows the link\'s href' do
18
+ # We just need to know that the link will make the request.
19
+ expect { link.go }.to raise_error(SirenClient::InvalidResponseError)
20
+ end
21
+ end
22
+ describe '.payload' do
23
+ it 'is a hash' do
24
+ expect(link.payload).to be_a Hash
25
+ end
26
+ end
27
+ describe '.rels' do
28
+ it 'is an array' do
29
+ expect(link.rels).to be_a Array
30
+ end
31
+ end
32
+ describe '.href' do
33
+ it 'is a string' do
34
+ expect(link.href).to be_a String
35
+ end
36
+ end
37
+ describe '.title' do
38
+ it 'is a string' do
39
+ expect(link.title).to be_a String
40
+ end
41
+ end
42
+ describe '.type' do
43
+ it 'is a string' do
44
+ expect(link.type).to be_a String
45
+ end
46
+ end
47
+ end
metadata ADDED
@@ -0,0 +1,240 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: siren_client
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Chason Choate
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.13'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: sinatra
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: sinatra-simple-auth
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: byebug
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: guard
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: guard-rspec
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ description: SirenClient provides an ActiveRecord-like syntax to traverse Siren APIs.
168
+ email:
169
+ - cha55son@gmail.com
170
+ executables: []
171
+ extensions: []
172
+ extra_rdoc_files: []
173
+ files:
174
+ - ".gitignore"
175
+ - ".rspec"
176
+ - Gemfile
177
+ - Guardfile
178
+ - LICENSE.txt
179
+ - README.md
180
+ - Rakefile
181
+ - bin/siren_cli
182
+ - lib/siren_cli.rb
183
+ - lib/siren_cli/shell.rb
184
+ - lib/siren_cli/version.rb
185
+ - lib/siren_client.rb
186
+ - lib/siren_client/action.rb
187
+ - lib/siren_client/base.rb
188
+ - lib/siren_client/entity.rb
189
+ - lib/siren_client/exceptions.rb
190
+ - lib/siren_client/field.rb
191
+ - lib/siren_client/link.rb
192
+ - lib/siren_client/version.rb
193
+ - siren_client.gemspec
194
+ - spec/helper/live_spec_helper.rb
195
+ - spec/helper/spec_helper.rb
196
+ - spec/live/traverse_spec.rb
197
+ - spec/support/endpoints/concepts.rb
198
+ - spec/support/endpoints/root.rb
199
+ - spec/support/test_server.rb
200
+ - spec/unit/action_spec.rb
201
+ - spec/unit/base_spec.rb
202
+ - spec/unit/entity_spec.rb
203
+ - spec/unit/field_spec.rb
204
+ - spec/unit/link_spec.rb
205
+ homepage: https://github.com/cha55son/siren_client
206
+ licenses:
207
+ - MIT
208
+ metadata: {}
209
+ post_install_message:
210
+ rdoc_options: []
211
+ require_paths:
212
+ - lib
213
+ required_ruby_version: !ruby/object:Gem::Requirement
214
+ requirements:
215
+ - - ">="
216
+ - !ruby/object:Gem::Version
217
+ version: '0'
218
+ required_rubygems_version: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ requirements: []
224
+ rubyforge_project:
225
+ rubygems_version: 2.4.5
226
+ signing_key:
227
+ specification_version: 4
228
+ summary: A client to traverse Siren APIs https://github.com/kevinswiber/siren
229
+ test_files:
230
+ - spec/helper/live_spec_helper.rb
231
+ - spec/helper/spec_helper.rb
232
+ - spec/live/traverse_spec.rb
233
+ - spec/support/endpoints/concepts.rb
234
+ - spec/support/endpoints/root.rb
235
+ - spec/support/test_server.rb
236
+ - spec/unit/action_spec.rb
237
+ - spec/unit/base_spec.rb
238
+ - spec/unit/entity_spec.rb
239
+ - spec/unit/field_spec.rb
240
+ - spec/unit/link_spec.rb