siren_client 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4925d2e19eecb6f0cf7cc864099089e0b6f18fa3
4
- data.tar.gz: f277ababef5cee15f59c437dd6c20e1b84873aa7
3
+ metadata.gz: 1d38e18a3d8e7b27a74a1bf4e39a87de411eba9b
4
+ data.tar.gz: 533cc402ef1239c82ccdac742caaaf9fb0dff276
5
5
  SHA512:
6
- metadata.gz: 4532ad1cdb6fbab5ae42a02127ebba0ec2610268dde0bfbe62d0c07850704c35f93a45f79018ba81de54a623802665c7b0a49b7c94cef3dbd66637ebddceccc9
7
- data.tar.gz: d71716ea6cad51b955cad7ec2b8c9467fa2d0a81f51056d49b9b0431314a5958895187ca26022b11fa41737f8d6f843569c23a0490afd736eb4b0564b50e90a5
6
+ metadata.gz: bc1e058531f13b91a3f043861407bda4a978a55566650a4f00f7de1043b2db8f9f150aba0c0852a47eae4caff867ac6da1888b39491c64fc638cd7e24ab58dd8
7
+ data.tar.gz: ee8785bd0cc1ee33529aebe40d2dea9eeee3b84635fb2623935033752296a889f50ac55750c0a5f4c523ef0a95249079867abbd21a7b1a9dedc73980be31a405
data/README.md CHANGED
@@ -99,6 +99,38 @@ action.fields.each do |field|
99
99
  end
100
100
  ```
101
101
 
102
+ ## Accessing the raw response
103
+
104
+ SirenClient can give you the raw response if needed. Some scenarios where this is useful:
105
+
106
+ * When the API doesn't return a siren JSON structure.
107
+ * Verifying response headers, status code, etc
108
+
109
+ You can access the raw response with the following examples:
110
+
111
+ ```ruby
112
+ root = SirentClient.get(...)
113
+
114
+ # For sub-entities i.e. one named `test_concepts`
115
+ root.with_raw_response.test_concepts
116
+
117
+ # For links
118
+ root.with_raw_response.concepts
119
+
120
+ # For actions (this is different from the others)
121
+ root.filter_concepts.with_raw_response.where(...)
122
+ ```
123
+
124
+ Once you get the raw response instance you can call the following functions:
125
+
126
+ ```ruby
127
+ raw.class == SirenClient::RawResponse
128
+ raw.body # Returns the raw body of the response
129
+ raw.code # Returns the HTTP status code
130
+ raw.message # Returns the HTTP message i.e. "OK"
131
+ raw.headers # A hash of the headers in the response
132
+ ```
133
+
102
134
  ## Development
103
135
 
104
136
  Run the following commands to start development:
data/lib/siren_client.rb CHANGED
@@ -10,6 +10,8 @@ require 'active_support/core_ext/hash'
10
10
 
11
11
  # SirenClient files
12
12
  require "#{dir}/exceptions"
13
+ require "#{dir}/raw_response"
14
+ require "#{dir}/modules/with_raw_response"
13
15
  require "#{dir}/link"
14
16
  require "#{dir}/field"
15
17
  require "#{dir}/action"
@@ -1,9 +1,12 @@
1
1
  module SirenClient
2
2
  class Action
3
+ include Modules::WithRawResponse
4
+
3
5
  attr_accessor :href
4
6
  attr_reader :payload, :name, :classes, :method, :title, :type, :fields, :config
5
7
 
6
8
  def initialize(data, config={})
9
+ super()
7
10
  if data.class != Hash
8
11
  raise ArgumentError, "You must pass in a Hash to SirenClient::Action.new"
9
12
  end
@@ -17,8 +20,8 @@ module SirenClient
17
20
  @title = @payload['title'] || ''
18
21
  @type = @payload['type'] || 'application/x-www-form-urlencoded'
19
22
  @fields = @payload['fields'] || []
20
- @fields.map! do |data|
21
- SirenClient::Field.new(data)
23
+ @fields.map! do |field_data|
24
+ SirenClient::Field.new(field_data)
22
25
  end
23
26
  end
24
27
 
@@ -37,7 +40,12 @@ module SirenClient
37
40
  SirenClient.logger.debug " #{k}: #{v}"
38
41
  end
39
42
  SirenClient.logger.debug ' ' + options[:body].to_query unless options[:body].empty?
40
- Entity.new(HTTParty.send(@method.to_sym, @href, options).parsed_response, @config)
43
+ if next_response_is_raw?
44
+ disable_raw_response
45
+ generate_raw_response(self.href, @config)
46
+ else
47
+ Entity.new(HTTParty.send(@method.to_sym, @href, options).parsed_response, @config)
48
+ end
41
49
  rescue URI::InvalidURIError => e
42
50
  raise InvalidURIError, e.message
43
51
  rescue JSON::ParserError => e
@@ -1,16 +1,19 @@
1
1
  module SirenClient
2
2
  class Entity
3
3
  include Enumerable
4
+ include Modules::WithRawResponse
5
+
4
6
  attr_accessor :href
5
7
  attr_reader :payload, :classes, :properties, :entities, :rels,
6
8
  :links, :actions, :title, :type, :config
7
9
 
8
10
 
9
11
  def initialize(data, config={})
12
+ super()
10
13
  @config = { format: :json }.merge config
11
14
  if data.class == String
12
15
  unless data.class == String && data.length > 0
13
- raise InvalidURIError, 'An invalid url was passed to SirenClient::Entity.new.'
16
+ raise InvalidURIError, 'An invalid url was passed to SirenClient::Entity.new.'
14
17
  end
15
18
  begin
16
19
  SirenClient.logger.debug "GET #{data}"
@@ -21,9 +24,9 @@ module SirenClient
21
24
  raise InvalidResponseError, e.message
22
25
  end
23
26
  elsif data.class == Hash
24
- @payload = data
27
+ @payload = data
25
28
  else
26
- raise ArgumentError, "You must pass in either a url(String) or an entity(Hash) to SirenClient::Entity.new"
29
+ raise ArgumentError, "You must pass in either a url(String) or an entity(Hash) to SirenClient::Entity.new"
27
30
  end
28
31
  parse_data
29
32
  end
@@ -31,7 +34,16 @@ module SirenClient
31
34
  # Execute an entity sub-link if called directly
32
35
  # otherwise just return the entity.
33
36
  def [](i)
34
- @entities[i].href.empty? ? @entities[i] : @entities[i].go rescue nil
37
+ if @entities[i].href.empty?
38
+ @entities[i]
39
+ else
40
+ if next_response_is_raw?
41
+ disable_raw_response
42
+ @entities[i].with_raw_response.go
43
+ else
44
+ @entities[i].go
45
+ end
46
+ end
35
47
  end
36
48
 
37
49
  def each(&block)
@@ -58,7 +70,12 @@ module SirenClient
58
70
  ### Entity sub-links only
59
71
  def go
60
72
  return if self.href.empty?
61
- self.class.new(self.href, @config)
73
+ if next_response_is_raw?
74
+ disable_raw_response
75
+ generate_raw_response(self.href, @config)
76
+ else
77
+ self.class.new(self.href, @config)
78
+ end
62
79
  end
63
80
 
64
81
  def method_missing(method, *args)
@@ -70,22 +87,39 @@ module SirenClient
70
87
  end
71
88
  # Does it match an entity sub-link's class?
72
89
  @entities.each do |ent|
73
- return ent.go if ent.href &&
74
- (ent.classes.map { |c| c.underscore }).include?(method_str.underscore)
90
+ if ent.href && (ent.classes.map { |c| underscore_name c }).include?(underscore_name(method_str))
91
+ if next_response_is_raw?
92
+ disable_raw_response
93
+ return ent.with_raw_response.go
94
+ else
95
+ return ent.go
96
+ end
97
+ end
75
98
  end
76
99
  # Does it match a link, if so traverse it and return the entity.
77
100
  @links.each do |key, link|
78
- return link.go if method_str == key.underscore
101
+ if method_str == underscore_name(key)
102
+ if next_response_is_raw?
103
+ disable_raw_response
104
+ return link.with_raw_response.go
105
+ else
106
+ return link.go
107
+ end
108
+ end
79
109
  end
80
110
  # Does it match an action, if so return the action.
81
111
  @actions.each do |key, action|
82
- return action if method_str == key.underscore
112
+ return action if method_str == underscore_name(key)
83
113
  end
84
114
  raise NoMethodError, "The method \"#{method_str}\" does not match a property, action, or link on SirenClient::Entity."
85
115
  end
86
116
 
87
117
  private
88
118
 
119
+ def underscore_name(str)
120
+ str.underscore.gsub(' ', '_')
121
+ end
122
+
89
123
  def parse_data
90
124
  return if @payload.nil?
91
125
  @classes = @payload['class'] || []
@@ -1,9 +1,12 @@
1
1
  module SirenClient
2
2
  class Link
3
+ include Modules::WithRawResponse
4
+
3
5
  attr_accessor :href
4
6
  attr_reader :payload, :rels, :title, :type, :config
5
7
 
6
8
  def initialize(data, config={})
9
+ super()
7
10
  if data.class != Hash
8
11
  raise ArgumentError, "You must pass in a Hash to SirenClient::Link.new"
9
12
  end
@@ -17,7 +20,12 @@ module SirenClient
17
20
  end
18
21
 
19
22
  def go
20
- Entity.new(self.href, @config)
23
+ if next_response_is_raw?
24
+ disable_raw_response
25
+ generate_raw_response(self.href, @config)
26
+ else
27
+ Entity.new(self.href, @config)
28
+ end
21
29
  end
22
30
  end
23
31
  end
@@ -0,0 +1,28 @@
1
+ module SirenClient
2
+ module Modules
3
+ module WithRawResponse
4
+ def initialize
5
+ @_next_response_is_raw = false
6
+ end
7
+
8
+ def with_raw_response
9
+ @_next_response_is_raw = true
10
+ self
11
+ end
12
+
13
+ def disable_raw_response
14
+ @_next_response_is_raw = false
15
+ end
16
+
17
+ def next_response_is_raw?
18
+ @_next_response_is_raw
19
+ end
20
+
21
+ private
22
+
23
+ def generate_raw_response(url, config)
24
+ RawResponse.new HTTParty.get(url, config)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,26 @@
1
+ module SirenClient
2
+ class RawResponse
3
+ def initialize(http_res)
4
+ unless http_res.class == HTTParty::Response
5
+ raise InvalidResponseError, "SirenClient::RawResponse expects a HTTParty::Response instance."
6
+ end
7
+ @response = http_res
8
+ end
9
+
10
+ def body
11
+ @response.body
12
+ end
13
+
14
+ def code
15
+ @response.code
16
+ end
17
+
18
+ def message
19
+ @response.message.strip
20
+ end
21
+
22
+ def headers
23
+ @response.headers
24
+ end
25
+ end
26
+ end
@@ -1,3 +1,3 @@
1
1
  module SirenClient
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -62,6 +62,9 @@ describe SirenClient do
62
62
  expect(client.concepts).to be_a SirenClient::Entity
63
63
  expect(client.concepts.links['self'].href).to eq(URL + '/concepts')
64
64
  end
65
+ it 'to follow the link with spaces' do
66
+ expect(client.concepts_with_spaces).to be_a SirenClient::Entity
67
+ end
65
68
  end
66
69
  context 'when accessing an action with GET' do
67
70
  it 'to return an action' do
@@ -81,6 +84,9 @@ describe SirenClient do
81
84
  it 'to return an action' do
82
85
  expect(client.filter_concepts_post).to be_a SirenClient::Action
83
86
  end
87
+ it 'to return an action with spaces' do
88
+ expect(client.filter_concepts_post_with_spaces).to be_a SirenClient::Action
89
+ end
84
90
  context 'with .where' do
85
91
  it 'to execute the action' do
86
92
  params = { search: 'obama' }
@@ -98,4 +104,40 @@ describe SirenClient do
98
104
  expect(concepts).to be_a SirenClient::Entity
99
105
  end
100
106
  end
107
+ context 'when accessing the raw response' do
108
+ context 'links' do
109
+ it 'to return a RawResponse instance' do
110
+ expect(client.with_raw_response.concepts).to be_a SirenClient::RawResponse
111
+ end
112
+ it 'to return an Entity on the second request' do
113
+ client.with_raw_response.concepts
114
+ expect(client.concepts).to be_a SirenClient::Entity
115
+ end
116
+ end
117
+ context 'actions' do
118
+ params = { search: 'obama' }
119
+ it 'to return a RawResponse instance' do
120
+ expect(client.filter_concepts_get.with_raw_response.where(params)).to be_a SirenClient::RawResponse
121
+ end
122
+ it 'to return an Entity on the second request' do
123
+ client.filter_concepts_get.with_raw_response.where(params)
124
+ expect(client.concepts).to be_a SirenClient::Entity
125
+ end
126
+ end
127
+ it 'to provide the raw body' do
128
+ expect(client.with_raw_response.concepts.body).to eq(HTTParty.get(URL + '/concepts', basic_auth: { username: 'admin', password: '1234' }).body)
129
+ end
130
+ it 'to provide the raw status code' do
131
+ expect(client.with_raw_response.concepts.code).to eq(200)
132
+ end
133
+ it 'to provide the raw message' do
134
+ expect(client.with_raw_response.concepts.message).to eq("OK")
135
+ end
136
+ it 'to provide the raw headers' do
137
+ expect(client.with_raw_response.concepts.headers).to include(
138
+ "content-type", "content-length", "server", "date", "connection"
139
+ )
140
+ end
141
+ end
142
+
101
143
  end
@@ -16,6 +16,11 @@ class TestServer < Sinatra::Base
16
16
  "href":"#{@@url}/concepts",
17
17
  "title": "Concepts"
18
18
  },
19
+ {
20
+ "rel": ["collection", "concepts with spaces"],
21
+ "href":"#{@@url}/concepts",
22
+ "title": "Concepts"
23
+ },
19
24
  { "rel": ["messages", "collection"],
20
25
  "href": "#{@@url}/messages",
21
26
  "title":"Messages"
@@ -70,6 +75,7 @@ class TestServer < Sinatra::Base
70
75
  }
71
76
  ]
72
77
  },
78
+ { "name": "filter concepts post with spaces" },
73
79
  {
74
80
  "name":"filter-messages",
75
81
  "method":"GET",
@@ -231,6 +231,19 @@ describe SirenClient::Entity do
231
231
  expect { entity.prev_page }.to raise_error Errno::ECONNREFUSED
232
232
  end
233
233
  end
234
+ describe '.with_raw_response' do
235
+ it 'returns the entity' do
236
+ expect(entity.with_raw_response).to eq(entity)
237
+ end
238
+ it 'sets the entity to return a raw response for the `next` request' do
239
+ entity.with_raw_response
240
+ expect(entity.next_response_is_raw?).to eq(true)
241
+ end
242
+ it 'should still allow a network request to be made' do
243
+ entity.with_raw_response
244
+ expect { entity.with_raw_response.prev_page }.to raise_error Errno::ECONNREFUSED
245
+ end
246
+ end
234
247
  # Entities enumerable support
235
248
  describe "enumerable support" do
236
249
  describe '.each' do
File without changes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: siren_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chason Choate
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-17 00:00:00.000000000 Z
11
+ date: 2016-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -190,6 +190,8 @@ files:
190
190
  - lib/siren_client/exceptions.rb
191
191
  - lib/siren_client/field.rb
192
192
  - lib/siren_client/link.rb
193
+ - lib/siren_client/modules/with_raw_response.rb
194
+ - lib/siren_client/raw_response.rb
193
195
  - lib/siren_client/version.rb
194
196
  - siren_client.gemspec
195
197
  - spec/helper/live_spec_helper.rb
@@ -203,6 +205,7 @@ files:
203
205
  - spec/unit/entity_spec.rb
204
206
  - spec/unit/field_spec.rb
205
207
  - spec/unit/link_spec.rb
208
+ - spec/unit/raw_response.rb
206
209
  homepage: https://github.com/cha55son/siren_client
207
210
  licenses:
208
211
  - MIT
@@ -239,3 +242,4 @@ test_files:
239
242
  - spec/unit/entity_spec.rb
240
243
  - spec/unit/field_spec.rb
241
244
  - spec/unit/link_spec.rb
245
+ - spec/unit/raw_response.rb