cortex-client 0.2.6 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -1
- data/README.md +18 -6
- data/cortex-client.gemspec +1 -0
- data/lib/cortex/client.rb +1 -0
- data/lib/cortex/posts.rb +7 -3
- data/lib/cortex/request.rb +2 -17
- data/lib/cortex/result.rb +50 -0
- data/lib/cortex/version.rb +1 -1
- data/spec/client_spec.rb +1 -1
- data/spec/posts_spec.rb +20 -13
- data/spec/request_spec.rb +71 -20
- data/spec/result_spec.rb +43 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/users_spec.rb +4 -4
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77658369ff63cdc4448149946ae675efb937dc9d
|
4
|
+
data.tar.gz: 8326bee51ecb3d16f66eee959b1186a3fb9ec3da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a64a29148d0b1561e594664343792624e86edff7d5dafc62a808c8c2fe3785ab3898c71d49d55d827624f1303090af9e643ea81b578c6ddf8f6e75034c87ab6
|
7
|
+
data.tar.gz: 63d4568bd71a1f538b35dcabc25241fa9bf9e72939a2286a47564a2b49ab20241fab381e47074b06d50aebb438ab2e353f9739e376af71233243ec3bf2ff05a9
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cortex-client (0.
|
4
|
+
cortex-client (0.3.0)
|
5
5
|
faraday (~> 0.9)
|
6
6
|
faraday_middleware (~> 0.9.0)
|
7
7
|
oauth2 (~> 0.9)
|
@@ -15,6 +15,9 @@ GEM
|
|
15
15
|
faraday_middleware (0.9.1)
|
16
16
|
faraday (>= 0.7.4, < 0.10)
|
17
17
|
jwt (1.0.0)
|
18
|
+
metaclass (0.0.4)
|
19
|
+
mocha (1.1.0)
|
20
|
+
metaclass (~> 0.0.1)
|
18
21
|
multi_json (1.10.1)
|
19
22
|
multi_xml (0.5.5)
|
20
23
|
multipart-post (2.0.0)
|
@@ -44,5 +47,6 @@ PLATFORMS
|
|
44
47
|
|
45
48
|
DEPENDENCIES
|
46
49
|
cortex-client!
|
50
|
+
mocha
|
47
51
|
rake (~> 10.3.2)
|
48
52
|
rspec (~> 3.0)
|
data/README.md
CHANGED
@@ -5,9 +5,7 @@
|
|
5
5
|
|
6
6
|
Ruby client library for [cortex](https://github.com/cb-talent-development/cortex)'s API.
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
Please note that 0.1.0 and onward now require a hash be passed. You can access the previous functionality with the access_token key:
|
8
|
+
## Constructor
|
11
9
|
|
12
10
|
```ruby
|
13
11
|
require 'cortex-client'
|
@@ -31,12 +29,26 @@ client = Cortex::Client.new(key: 'my-app-id', secret: 'secrey-key-ssh', base_url
|
|
31
29
|
end
|
32
30
|
```
|
33
31
|
|
32
|
+
## Result object
|
33
|
+
|
34
|
+
Cortex::Client will return a Cortex::Result object. The following methods are available:
|
35
|
+
|
36
|
+
- contents
|
37
|
+
- is_error?
|
38
|
+
- errors
|
39
|
+
- page
|
40
|
+
- per_page
|
41
|
+
- total_items
|
42
|
+
- range
|
43
|
+
- range_start
|
44
|
+
- range_end
|
45
|
+
- raw_headers
|
46
|
+
|
34
47
|
### Supported Endpoints
|
35
48
|
|
36
|
-
- *Users* - me, get
|
37
|
-
- *Posts* - query, get, save, delete, feed
|
49
|
+
- *Users* - me, get, save
|
50
|
+
- *Posts* - query, get, save, delete, feed, feed/get, feed/get/released, feed/authors
|
38
51
|
|
39
52
|
### TODO
|
40
53
|
- Handle pagination
|
41
|
-
- Support for search queries
|
42
54
|
- /media
|
data/cortex-client.gemspec
CHANGED
@@ -15,6 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
|
16
16
|
s.add_development_dependency 'rake', '~> 10.3.2'
|
17
17
|
s.add_development_dependency 'rspec', '~> 3.0'
|
18
|
+
s.add_development_dependency 'mocha'
|
18
19
|
|
19
20
|
s.add_dependency 'faraday', '~> 0.9'
|
20
21
|
s.add_dependency 'faraday_middleware', '~> 0.9.0'
|
data/lib/cortex/client.rb
CHANGED
data/lib/cortex/posts.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
module Cortex
|
2
2
|
class Posts < Cortex::Resource
|
3
|
-
def query(params =
|
3
|
+
def query(params = {})
|
4
4
|
client.get('/posts', params)
|
5
5
|
end
|
6
6
|
|
7
|
-
def feed(params =
|
7
|
+
def feed(params = {})
|
8
8
|
client.get('/posts/feed', params)
|
9
9
|
end
|
10
10
|
|
@@ -12,6 +12,10 @@ module Cortex
|
|
12
12
|
client.get("/posts/#{id}")
|
13
13
|
end
|
14
14
|
|
15
|
+
def get_published(id)
|
16
|
+
client.get("/posts/feed/#{id}")
|
17
|
+
end
|
18
|
+
|
15
19
|
def save(post)
|
16
20
|
client.save('/posts', post)
|
17
21
|
end
|
@@ -24,7 +28,7 @@ module Cortex
|
|
24
28
|
client.get('/posts/filters')
|
25
29
|
end
|
26
30
|
|
27
|
-
def related(id, params =
|
31
|
+
def related(id, params = {})
|
28
32
|
client.get("/posts/feed/#{id}/related", params)
|
29
33
|
end
|
30
34
|
|
data/lib/cortex/request.rb
CHANGED
@@ -30,18 +30,7 @@ module Cortex
|
|
30
30
|
response = connection.delete do |r|
|
31
31
|
r.url base_url + path
|
32
32
|
end
|
33
|
-
response
|
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)
|
45
34
|
end
|
46
35
|
|
47
36
|
def save(path, model)
|
@@ -49,11 +38,7 @@ module Cortex
|
|
49
38
|
end
|
50
39
|
|
51
40
|
def parse_response(response)
|
52
|
-
|
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)
|
57
42
|
end
|
58
43
|
end
|
59
44
|
end
|
@@ -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, :status
|
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
|
data/lib/cortex/version.rb
CHANGED
data/spec/client_spec.rb
CHANGED
data/spec/posts_spec.rb
CHANGED
@@ -1,25 +1,32 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Cortex::Posts do
|
3
|
+
RSpec.describe Cortex::Posts do
|
4
4
|
|
5
5
|
let(:client) { Cortex::Client.new(access_token: '123') }
|
6
6
|
|
7
7
|
describe :get do
|
8
8
|
it 'should correctly make the request' do
|
9
|
-
|
9
|
+
client.expects(:get).with('/posts/1').returns('response')
|
10
10
|
expect(client.posts.get(1)).to eq('response')
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
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
|
+
|
14
21
|
describe :feed do
|
15
22
|
it 'should correctly make the request' do
|
16
|
-
|
23
|
+
client.expects(:get).with('/posts/feed', {}).returns('response')
|
17
24
|
expect(client.posts.feed()).to eq('response')
|
18
25
|
end
|
19
26
|
|
20
27
|
it 'should accept parameters and send them with the request' do
|
21
|
-
|
22
|
-
expect(client.posts.feed(q: 'Test*')).to eq('
|
28
|
+
client.expects(:get).with('/posts/feed', {q: "Test*"}).returns('response')
|
29
|
+
expect(client.posts.feed(q: 'Test*')).to eq('response')
|
23
30
|
end
|
24
31
|
end
|
25
32
|
|
@@ -27,7 +34,7 @@ describe Cortex::Posts do
|
|
27
34
|
context 'with an existing post' do
|
28
35
|
it 'should correctly make the request' do
|
29
36
|
post = {:id => 1, :title => 'Post'}
|
30
|
-
|
37
|
+
client.expects(:put).with('/posts/1', post).returns('response')
|
31
38
|
expect(client.posts.save(post)).to eq('response')
|
32
39
|
end
|
33
40
|
end
|
@@ -35,7 +42,7 @@ describe Cortex::Posts do
|
|
35
42
|
context 'with a new post' do
|
36
43
|
it 'should correctly make the request' do
|
37
44
|
post = {:title => 'Post'}
|
38
|
-
|
45
|
+
client.expects(:post).with('/posts', post).returns('response')
|
39
46
|
expect(client.posts.save(post)).to eq('response')
|
40
47
|
end
|
41
48
|
end
|
@@ -43,22 +50,22 @@ describe Cortex::Posts do
|
|
43
50
|
|
44
51
|
describe :filters do
|
45
52
|
it 'should correctly make the request' do
|
46
|
-
|
47
|
-
expect(client.posts.filters()).to eq('
|
53
|
+
client.expects(:get).with('/posts/filters').returns('response')
|
54
|
+
expect(client.posts.filters()).to eq('response')
|
48
55
|
end
|
49
56
|
end
|
50
57
|
|
51
58
|
describe :related do
|
52
59
|
it 'should correctly make the request' do
|
53
|
-
|
54
|
-
expect(client.posts.related(1)).to eq('
|
60
|
+
client.expects(:get).with('/posts/feed/1/related', {}).returns('response')
|
61
|
+
expect(client.posts.related(1)).to eq('response')
|
55
62
|
end
|
56
63
|
end
|
57
64
|
|
58
65
|
describe :authors do
|
59
66
|
it 'should correctly make the request' do
|
60
|
-
|
61
|
-
expect(client.posts.authors).to eq('
|
67
|
+
client.expects(:get).with('/posts/feed/authors').returns('response')
|
68
|
+
expect(client.posts.authors).to eq('response')
|
62
69
|
end
|
63
70
|
end
|
64
71
|
end
|
data/spec/request_spec.rb
CHANGED
@@ -3,31 +3,82 @@ require 'spec_helper'
|
|
3
3
|
describe Cortex::Request do
|
4
4
|
let(:client) { Cortex::Client.new(access_token: '123') }
|
5
5
|
|
6
|
-
context '
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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)
|
11
14
|
end
|
12
|
-
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
23
56
|
end
|
24
57
|
end
|
25
58
|
|
26
|
-
context '
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
31
82
|
end
|
32
83
|
end
|
33
84
|
end
|
data/spec/result_spec.rb
ADDED
@@ -0,0 +1,43 @@
|
|
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
|
+
it 'should expose the http status' do
|
39
|
+
expect(result.status).to eq 200
|
40
|
+
expect(failed.status).to eq 403
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/users_spec.rb
CHANGED
@@ -6,7 +6,7 @@ describe Cortex::Users do
|
|
6
6
|
|
7
7
|
describe :me do
|
8
8
|
it 'should correctly make the request' do
|
9
|
-
|
9
|
+
client.expects(:get).with('/users/me').returns('response')
|
10
10
|
response = client.users.me
|
11
11
|
expect(response).to eq('response')
|
12
12
|
end
|
@@ -14,7 +14,7 @@ describe Cortex::Users do
|
|
14
14
|
|
15
15
|
describe :get do
|
16
16
|
it 'should correctly make the request' do
|
17
|
-
|
17
|
+
client.expects(:get).with('/users/1').returns('response')
|
18
18
|
expect(client.users.get(1)).to eq('response')
|
19
19
|
end
|
20
20
|
end
|
@@ -23,7 +23,7 @@ describe Cortex::Users do
|
|
23
23
|
context 'with an existing user' do
|
24
24
|
it 'should correctly make the request' do
|
25
25
|
user = {:id => 1, :email => 'user@cbcortex.com'}
|
26
|
-
|
26
|
+
client.expects(:put).with('/users/1', user).returns('response')
|
27
27
|
response = client.users.save(user)
|
28
28
|
expect(response).to eq('response')
|
29
29
|
end
|
@@ -32,7 +32,7 @@ describe Cortex::Users do
|
|
32
32
|
context 'with a new user' do
|
33
33
|
it 'should correctly make the request' do
|
34
34
|
user = {:email => 'user@cbcortex.com'}
|
35
|
-
|
35
|
+
client.expects(:post).with('/users', user).returns('response')
|
36
36
|
response = client.users.save(user)
|
37
37
|
expect(response).to eq('response')
|
38
38
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cortex-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bennett Goble
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '3.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mocha
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: faraday
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -99,11 +113,13 @@ files:
|
|
99
113
|
- lib/cortex/posts.rb
|
100
114
|
- lib/cortex/request.rb
|
101
115
|
- lib/cortex/resource.rb
|
116
|
+
- lib/cortex/result.rb
|
102
117
|
- lib/cortex/users.rb
|
103
118
|
- lib/cortex/version.rb
|
104
119
|
- spec/client_spec.rb
|
105
120
|
- spec/posts_spec.rb
|
106
121
|
- spec/request_spec.rb
|
122
|
+
- spec/result_spec.rb
|
107
123
|
- spec/spec_helper.rb
|
108
124
|
- spec/users_spec.rb
|
109
125
|
homepage: https://github.com/cb-talent-development/cortex-client
|
@@ -134,5 +150,6 @@ test_files:
|
|
134
150
|
- spec/client_spec.rb
|
135
151
|
- spec/posts_spec.rb
|
136
152
|
- spec/request_spec.rb
|
153
|
+
- spec/result_spec.rb
|
137
154
|
- spec/spec_helper.rb
|
138
155
|
- spec/users_spec.rb
|