Skip to content

Commit 27f5e59

Browse files
committed
Merge pull request #1 from cb-talent-development/feature/results-object
Feature/results object
2 parents a3a7c2a + c9835c0 commit 27f5e59

File tree

12 files changed

+204
-59
lines changed

12 files changed

+204
-59
lines changed

Gemfile.lock

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
cortex-client (0.2.5)
4+
cortex-client (0.2.6)
55
faraday (~> 0.9)
66
faraday_middleware (~> 0.9.0)
77
oauth2 (~> 0.9)
@@ -15,6 +15,9 @@ GEM
1515
faraday_middleware (0.9.1)
1616
faraday (>= 0.7.4, < 0.10)
1717
jwt (1.0.0)
18+
metaclass (0.0.4)
19+
mocha (1.1.0)
20+
metaclass (~> 0.0.1)
1821
multi_json (1.10.1)
1922
multi_xml (0.5.5)
2023
multipart-post (2.0.0)
@@ -44,5 +47,6 @@ PLATFORMS
4447

4548
DEPENDENCIES
4649
cortex-client!
50+
mocha
4751
rake (~> 10.3.2)
4852
rspec (~> 3.0)

cortex-client.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Gem::Specification.new do |s|
1515

1616
s.add_development_dependency 'rake', '~> 10.3.2'
1717
s.add_development_dependency 'rspec', '~> 3.0'
18+
s.add_development_dependency 'mocha'
1819

1920
s.add_dependency 'faraday', '~> 0.9'
2021
s.add_dependency 'faraday_middleware', '~> 0.9.0'

lib/cortex/client.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require 'cortex/resource'
44
require 'cortex/posts'
55
require 'cortex/users'
6+
require 'cortex/result'
67
require 'oauth2'
78

89
module Cortex

lib/cortex/posts.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
module Cortex
22
class Posts < Cortex::Resource
3-
def query(params = nil)
3+
def query(params = {})
44
client.get('/posts', params)
55
end
66

7-
def feed(params = nil)
7+
def feed(params = {})
88
client.get('/posts/feed', params)
99
end
1010

1111
def get(id)
1212
client.get("/posts/#{id}")
1313
end
1414

15+
def get_published(id)
16+
client.get("/posts/feed/#{id}")
17+
end
18+
1519
def save(post)
1620
client.save('/posts', post)
1721
end
@@ -24,7 +28,7 @@ def filters
2428
client.get('/posts/filters')
2529
end
2630

27-
def related(id, params = nil)
31+
def related(id, params = {})
2832
client.get("/posts/feed/#{id}/related", params)
2933
end
3034

lib/cortex/request.rb

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,30 +30,15 @@ def delete(path)
3030
response = connection.delete do |r|
3131
r.url base_url + path
3232
end
33-
response.status < 300
34-
end
35-
36-
def delete!(path)
37-
response = connection.delete do |r|
38-
r.url base_url + path
39-
end
40-
if response.status < 300
41-
true
42-
else
43-
raise parse_response(response)
44-
end
33+
parse_response(response)
4534
end
4635

4736
def save(path, model)
4837
model[:id] ? put("#{path}/#{model[:id]}", model) : post(path, model)
4938
end
5039

5140
def parse_response(response)
52-
if response.status < 300 || (response.body.kind_of?(Hash) && response.body['error'])
53-
OpenStruct.new({body: response.body, headers: { status: response.status }.merge(response.headers.select { |k| ['content-range', 'x-total-items'].include? k }) })
54-
else
55-
OpenStruct.new({body: {error: response.body, status: response.status, original: response}, headers: { status: response.status }})
56-
end
41+
Cortex::Result.new(response.body, response.headers, response.status)
5742
end
5843
end
5944
end

lib/cortex/result.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
module Cortex
2+
class Result
3+
attr_reader :raw_headers, :contents, :total_items, :page, :per_page, :errors, :range_start, :range_end, :range
4+
5+
def initialize(body, headers, status)
6+
@contents = body
7+
@raw_headers = headers
8+
@status = status
9+
@total_items = headers['x-total-items'] unless headers['x-total-items'].nil?
10+
parse_headers(headers)
11+
@errors = find_errors
12+
end
13+
14+
def is_error?
15+
@status >= 400 || (@contents.is_a?(Hash) && @contents.has_key?('errors'))
16+
end
17+
18+
private
19+
20+
def parse_headers(headers)
21+
if headers['x-total-items']
22+
@count = headers['x-total-items']
23+
end
24+
if headers['content-range']
25+
matches = headers['content-range'].match(/^(\w+) (\d+)\-(\d+):(\d+)\/\d+$/i)
26+
@per_page = matches[4].to_i
27+
@range_start = matches[2].to_i
28+
@range_end = matches[3].to_i
29+
@range = "#{@range_start}-#{@range_end}"
30+
@page = (@range_end / @per_page) + 1
31+
end
32+
end
33+
34+
def find_errors
35+
if is_error?
36+
if @contents.is_a?(Hash)
37+
if @contents.has_key?('errors')
38+
Array(@contents['errors'])
39+
else
40+
Array(@contents['message'])
41+
end
42+
else
43+
Array(@contents)
44+
end
45+
else
46+
Array(nil)
47+
end
48+
end
49+
end
50+
end

spec/client_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
require 'spec_helper'
22

3-
describe Cortex::Client do
3+
RSpec.describe Cortex::Client do
44

55
let(:access_token) { '123' }
66
let(:base_url) { 'http://localhost:3000' }

spec/posts_spec.rb

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,71 @@
11
require 'spec_helper'
22

3-
describe Cortex::Posts do
3+
RSpec.describe Cortex::Posts do
44

55
let(:client) { Cortex::Client.new(access_token: '123') }
66

77
describe :get do
88
it 'should correctly make the request' do
9-
expect(client).to receive(:get).with('/posts/1').and_return('response')
9+
client.expects(:get).with('/posts/1').returns('response')
1010
expect(client.posts.get(1)).to eq('response')
1111
end
1212
end
1313

14+
describe :get_published do
15+
it 'should correctly make the request' do
16+
client.expects(:get).with('/posts/feed/1').returns('response')
17+
expect(client.posts.get_published(1)).to eq('response')
18+
end
19+
end
20+
1421
describe :feed do
1522
it 'should correctly make the request' do
16-
expect(client).to receive(:get).with('/posts/feed', nil).and_return('response')
23+
client.expects(:get).with('/posts/feed', {}).returns('response')
1724
expect(client.posts.feed()).to eq('response')
1825
end
1926

2027
it 'should accept parameters and send them with the request' do
21-
expect(client).to receive(:get).with('/posts/feed', {q: "Test*"}).and_return('success')
22-
expect(client.posts.feed(q: 'Test*')).to eq('success')
28+
client.expects(:get).with('/posts/feed', {q: "Test*"}).returns('response')
29+
expect(client.posts.feed(q: 'Test*')).to eq('response')
2330
end
2431
end
2532

2633
describe :save do
2734
context 'with an existing post' do
2835
it 'should correctly make the request' do
2936
post = {:id => 1, :title => 'Post'}
30-
expect(client).to receive(:put).with('/posts/1', post).and_return('response')
37+
client.expects(:put).with('/posts/1', post).returns('response')
3138
expect(client.posts.save(post)).to eq('response')
3239
end
3340
end
3441

3542
context 'with a new post' do
3643
it 'should correctly make the request' do
3744
post = {:title => 'Post'}
38-
expect(client).to receive(:post).with('/posts', post).and_return('response')
45+
client.expects(:post).with('/posts', post).returns('response')
3946
expect(client.posts.save(post)).to eq('response')
4047
end
4148
end
4249
end
4350

4451
describe :filters do
4552
it 'should correctly make the request' do
46-
expect(client).to receive(:get).with('/posts/filters').and_return('success')
47-
expect(client.posts.filters()).to eq('success')
53+
client.expects(:get).with('/posts/filters').returns('response')
54+
expect(client.posts.filters()).to eq('response')
4855
end
4956
end
5057

5158
describe :related do
5259
it 'should correctly make the request' do
53-
expect(client).to receive(:get).with('/posts/feed/1/related', nil).and_return('success')
54-
expect(client.posts.related(1)).to eq('success')
60+
client.expects(:get).with('/posts/feed/1/related', {}).returns('response')
61+
expect(client.posts.related(1)).to eq('response')
5562
end
5663
end
5764

5865
describe :authors do
5966
it 'should correctly make the request' do
60-
expect(client).to receive(:get).with('/posts/feed/authors').and_return('success')
61-
expect(client.posts.authors).to eq('success')
67+
client.expects(:get).with('/posts/feed/authors').returns('response')
68+
expect(client.posts.authors).to eq('response')
6269
end
6370
end
6471
end

spec/request_spec.rb

Lines changed: 71 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,82 @@
33
describe Cortex::Request do
44
let(:client) { Cortex::Client.new(access_token: '123') }
55

6-
context 'with a cortex error response' do
7-
it 'should return the error object' do
8-
body = {'error' => 'Validation error or something'}
9-
response = OpenStruct.new(status: 422, body: body, headers: { :whatever => "Whatever"})
10-
expect(client.parse_response(response).to_h).to eq({ :body => body, :headers => {status: 422}})
6+
context 'Request Methods' do
7+
let(:response) { OpenStruct.new({body: "Body", headers: {}, status: 200} ) }
8+
let(:model) { { title: 'Test' } }
9+
10+
before(:each) do
11+
@connection = stub
12+
Cortex::Client.any_instance.stubs(:connection).returns(@connection)
13+
Cortex::Result.any_instance.stubs(:new).with(response).returns(true)
1114
end
12-
end
1315

14-
context 'with a non-cortex error response' do
15-
it 'should return a wrapped response' do
16-
body = 'Catastrophic error'
17-
response = OpenStruct.new(status: 500, body: body, headers: { whatever: "Whatever", status: 500 } )
18-
parsed = client.parse_response(response)
19-
expect(parsed.body[:error]).to eq(body)
20-
expect(parsed.body[:status]).to eq(500)
21-
expect(parsed.body[:original]).to eq(response)
22-
expect(parsed.headers[:status]).to eq(500)
16+
describe '#get' do
17+
it 'should call get' do
18+
@connection.stubs(:get).returns(response).once
19+
expect(client.get('/test/')).to be_truthy
20+
end
21+
end
22+
23+
describe '#post' do
24+
it 'should call post' do
25+
@connection.stubs(:post).returns(response).once
26+
expect(client.post('/test/')).to be_truthy
27+
end
28+
end
29+
30+
describe '#put' do
31+
it 'should call put' do
32+
@connection.stubs(:put).returns(response).once
33+
expect(client.put('/test/')).to be_truthy
34+
end
35+
end
36+
37+
describe '#delete' do
38+
it 'should call delete' do
39+
@connection.stubs(:delete).returns(response).once
40+
expect(client.delete('/test/')).to be_truthy
41+
end
42+
end
43+
44+
describe '#save' do
45+
it 'should post when new' do
46+
@connection.stubs(:post).returns(response).once
47+
expect(client.save('/test/', model)).to be_truthy
48+
end
49+
50+
it 'should put when updating' do
51+
update = model
52+
update[:id] = 1
53+
@connection.stubs(:put).returns(response).once
54+
expect(client.save('/test/', update)).to be_truthy
55+
end
2356
end
2457
end
2558

26-
context 'with a successful response' do
27-
it 'should return the parsed body' do
28-
body = {:id => 1, title: 'A post'}
29-
response = OpenStruct.new(status: 200, body: body, headers: { :whatever => "Whatever" })
30-
expect(client.parse_response(response).to_h).to eq({ body: body, headers: {status: 200}})
59+
context 'Record Parsing' do
60+
let(:body) { "Body" }
61+
let(:headers) { { } }
62+
let(:status) { 200 }
63+
let(:error_status) { 400 }
64+
let(:response) { OpenStruct.new({body: 'Body', headers: {}, status: 200 } ) }
65+
66+
describe 'parse_response' do
67+
before(:each) do
68+
result = stub
69+
Cortex::Result.any_instance.stubs(:new).with(body, headers, status).returns(true)
70+
Cortex::Result.any_instance.stubs(:new).with(body, headers, error_status).returns(true)
71+
end
72+
73+
it 'should construct a successful response' do
74+
expect(client.parse_response(response)).to be_truthy
75+
end
76+
77+
it 'should construct an error response' do
78+
error = response
79+
error.status = error_status
80+
expect(client.parse_response(error)).to be_truthy
81+
end
3182
end
3283
end
3384
end

spec/result_spec.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
require 'spec_helper'
2+
3+
RSpec.describe Cortex::Result do
4+
let(:result) { Cortex::Result.new('body', {'x-total-items' => 10, 'content-range' => "posts 0-9:10/200"}, 200) }
5+
let(:failed) { Cortex::Result.new('failed body', {}, 403) }
6+
7+
it 'should construct' do
8+
expect(result).to be_truthy
9+
expect(failed).to be_truthy
10+
end
11+
12+
it 'should parse the headers' do
13+
expect(result.page).to eq 1
14+
expect(result.per_page).to eq 10
15+
expect(result.range).to eq "0-9"
16+
end
17+
18+
it 'should provide is_error?' do
19+
expect(result.is_error?).to be_falsey
20+
expect(failed.is_error?).to be_truthy
21+
end
22+
23+
it 'should parse errors properly' do
24+
expect(result.errors).to eq []
25+
expect(failed.errors).to eq ['failed body']
26+
end
27+
28+
it 'should expose the contents' do
29+
expect(result.contents).to eq 'body'
30+
expect(failed.contents).to eq 'failed body'
31+
end
32+
33+
it 'should expose the headers' do
34+
expect(result.raw_headers).to eq({ 'x-total-items' => 10, 'content-range' => "posts 0-9:10/200" })
35+
expect(failed.raw_headers).to eq({})
36+
end
37+
38+
end

0 commit comments

Comments
 (0)