wcc-data 0.1.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 +7 -0
- data/.env.example +3 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +36 -0
- data/circle.yml +6 -0
- data/lib/wcc/data.rb +26 -0
- data/lib/wcc/data/config.rb +45 -0
- data/lib/wcc/data/enumerated_type.rb +63 -0
- data/lib/wcc/data/faraday_client_app_token_auth.rb +64 -0
- data/lib/wcc/data/mapper.rb +16 -0
- data/lib/wcc/data/mapper/attributes.rb +54 -0
- data/lib/wcc/data/mapper/json_response.rb +20 -0
- data/lib/wcc/data/mapper/rest_configuration.rb +36 -0
- data/lib/wcc/data/mapper/rest_query.rb +28 -0
- data/lib/wcc/data/model.rb +11 -0
- data/lib/wcc/data/nucleus.rb +15 -0
- data/lib/wcc/data/nucleus/address.rb +17 -0
- data/lib/wcc/data/nucleus/base.rb +6 -0
- data/lib/wcc/data/nucleus/campus.rb +47 -0
- data/lib/wcc/data/nucleus/client_app_token.rb +30 -0
- data/lib/wcc/data/nucleus/contact.rb +33 -0
- data/lib/wcc/data/nucleus/gender.rb +26 -0
- data/lib/wcc/data/nucleus/group.rb +18 -0
- data/lib/wcc/data/nucleus/marital_status.rb +41 -0
- data/lib/wcc/data/nucleus/user.rb +49 -0
- data/lib/wcc/data/rack_client_app_token_auth.rb +77 -0
- data/lib/wcc/data/response.rb +29 -0
- data/lib/wcc/data/rest_endpoint.rb +33 -0
- data/lib/wcc/data/service.rb +55 -0
- data/lib/wcc/data/version.rb +5 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/inheritable_class_attribute_examples.rb +16 -0
- data/spec/wcc/data/config_spec.rb +113 -0
- data/spec/wcc/data/enumerated_type_spec.rb +176 -0
- data/spec/wcc/data/faraday_client_app_token_auth_spec.rb +224 -0
- data/spec/wcc/data/mapper/attributes_spec.rb +94 -0
- data/spec/wcc/data/mapper/json_response_spec.rb +50 -0
- data/spec/wcc/data/mapper/rest_configuration_spec.rb +43 -0
- data/spec/wcc/data/mapper/rest_query_spec.rb +50 -0
- data/spec/wcc/data/model_spec.rb +33 -0
- data/spec/wcc/data/nucleus/campus_spec.rb +29 -0
- data/spec/wcc/data/rack_client_app_token_auth_spec.rb +219 -0
- data/spec/wcc/data/response_spec.rb +57 -0
- data/spec/wcc/data/rest_endpoint_spec.rb +71 -0
- data/spec/wcc/data/service_spec.rb +128 -0
- data/spec/wcc/data_spec.rb +25 -0
- data/wcc-data.gemspec +28 -0
- metadata +194 -0
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe WCC::Data::Mapper::Attributes do
|
4
|
+
let(:klass) {
|
5
|
+
Class.new do
|
6
|
+
include WCC::Data::Mapper::Attributes
|
7
|
+
end
|
8
|
+
}
|
9
|
+
|
10
|
+
describe "::attribute" do
|
11
|
+
subject { klass }
|
12
|
+
it_behaves_like :inheritable_class_attributes, :attributes
|
13
|
+
|
14
|
+
it "takes a name and optional options and stores them in ::attributes" do
|
15
|
+
subject.attribute :name, foo: :bar
|
16
|
+
expect(subject.attributes).to eq("name" => { foo: :bar })
|
17
|
+
end
|
18
|
+
|
19
|
+
it "freezes the options hash" do
|
20
|
+
subject.attribute :name
|
21
|
+
expect { subject.attributes["name"][:foo] = "foo" }.to raise_error(RuntimeError)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "defines an instance method by the same name" do
|
25
|
+
expect(subject.new).to_not respond_to(:name)
|
26
|
+
subject.attribute :name
|
27
|
+
expect(subject.new).to respond_to(:name)
|
28
|
+
end
|
29
|
+
|
30
|
+
context "defined instance method" do
|
31
|
+
it "returns the value set on the instance for this attribute" do
|
32
|
+
subject.attribute :name
|
33
|
+
obj = subject.new("name" => "foo")
|
34
|
+
expect(obj.name).to eq("foo")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "with writer option" do
|
39
|
+
it "defines a writer instance method" do
|
40
|
+
subject.attribute :name, writer: true
|
41
|
+
obj = subject.new("name" => "foo")
|
42
|
+
obj.name = "bar"
|
43
|
+
expect(obj.name).to eq("bar")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#initialize" do
|
49
|
+
subject { klass }
|
50
|
+
|
51
|
+
it "takes a hash of attributes and sets it to @attributes" do
|
52
|
+
obj = subject.new(foo: :bar)
|
53
|
+
expect(obj.attributes).to eq(foo: :bar)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "#[]" do
|
58
|
+
before(:each) do
|
59
|
+
klass.attribute :name
|
60
|
+
end
|
61
|
+
subject { klass.new("name" => "foo", "other" => :value) }
|
62
|
+
|
63
|
+
it "returns raw values of defined attributes" do
|
64
|
+
expect(subject[:name]).to eq("foo")
|
65
|
+
expect(subject["name"]).to eq("foo")
|
66
|
+
end
|
67
|
+
|
68
|
+
it "returns a key error for undefined attributes" do
|
69
|
+
expect { subject[:other] }.to raise_error(KeyError)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#[]=" do
|
74
|
+
before(:each) do
|
75
|
+
klass.attribute :name
|
76
|
+
end
|
77
|
+
subject { klass.new("name" => "foo", "other" => :value) }
|
78
|
+
|
79
|
+
it "sets raw values of defined attributes" do
|
80
|
+
subject[:name] = "value1"
|
81
|
+
expect(subject[:name]).to eq("value1")
|
82
|
+
end
|
83
|
+
|
84
|
+
it "allows string values as key" do
|
85
|
+
subject["name"] = "value1"
|
86
|
+
expect(subject[:name]).to eq("value1")
|
87
|
+
end
|
88
|
+
|
89
|
+
it "returns a key error for undefined attributes" do
|
90
|
+
expect { subject[:other] = "value" }.to raise_error(KeyError)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe WCC::Data::Mapper::JSONResponse do
|
4
|
+
let(:klass) {
|
5
|
+
Class.new do
|
6
|
+
extend WCC::Data::Mapper::JSONResponse
|
7
|
+
|
8
|
+
attr_accessor :val
|
9
|
+
def initialize(val=nil) @val = val end
|
10
|
+
end
|
11
|
+
}
|
12
|
+
|
13
|
+
describe "::new_from_response" do
|
14
|
+
let(:singular_response) {
|
15
|
+
double(json: { key: "value" }, status: 200)
|
16
|
+
}
|
17
|
+
let(:plural_response) {
|
18
|
+
double(json: [
|
19
|
+
{ name: "abc" },
|
20
|
+
{ name: "def" },
|
21
|
+
], status: 200)
|
22
|
+
}
|
23
|
+
|
24
|
+
it "returns a new instance from singular response" do
|
25
|
+
obj = klass.new_from_response(singular_response)
|
26
|
+
expect(obj).to be_a(klass)
|
27
|
+
expect(obj.val).to eq(singular_response.json)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns array of instances from array response" do
|
31
|
+
obj = klass.new_from_response(plural_response)
|
32
|
+
expect(obj).to be_a(Array)
|
33
|
+
expect(obj[0].val).to eq(plural_response.json[0])
|
34
|
+
expect(obj[1].val).to eq(plural_response.json[1])
|
35
|
+
end
|
36
|
+
|
37
|
+
it "raises RecordNotFound when response status is 404" do
|
38
|
+
allow(singular_response).to receive(:status).and_return(404)
|
39
|
+
expect { klass.new_from_response(singular_response) }
|
40
|
+
.to raise_error(WCC::Data::Mapper::RecordNotFound)
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
it "raises InvalidResponse error for non-json objects" do
|
45
|
+
expect { klass.new_from_response(double(json: 1, status: 200)) }
|
46
|
+
.to raise_error(WCC::Data::Mapper::InvalidResponse)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe WCC::Data::Mapper::RESTConfiguration do
|
4
|
+
let(:klass) {
|
5
|
+
Class.new.tap do |klass|
|
6
|
+
klass.extend described_class
|
7
|
+
end
|
8
|
+
}
|
9
|
+
subject { klass }
|
10
|
+
before(:each) do
|
11
|
+
WCC::Data.config.applications[:rest_configuration_test].uri = "http://test.app/"
|
12
|
+
subject.set_endpoint(:rest_configuration_test, "bar/")
|
13
|
+
end
|
14
|
+
after(:each) do
|
15
|
+
WCC::Data.config.applications.delete(:rest_configuration_test)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "::set_endpoint" do
|
19
|
+
it_behaves_like :inheritable_class_attributes, :endpoint_config
|
20
|
+
|
21
|
+
it "sets @endpoint_config hash with values from args" do
|
22
|
+
expect(subject.endpoint_config).to eq(app: :rest_configuration_test, uri: "bar/")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "::endpoint" do
|
27
|
+
it "returns instance of RESTEndpoint" do
|
28
|
+
expect(subject.endpoint).to be_a(WCC::Data::RESTEndpoint)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "sets service using appname and provided URI string" do
|
32
|
+
expect(subject.endpoint.service.uri).to eq(URI("http://test.app/bar/"))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "lazy configuration" do
|
37
|
+
it "sets endpoint data only when endpoint is called" do
|
38
|
+
WCC::Data.config.applications[:rest_configuration_test].uri = "http://new.test.app/"
|
39
|
+
expect(subject.endpoint.service.uri).to eq(URI("http://new.test.app/bar/"))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe WCC::Data::Mapper::RESTQuery do
|
4
|
+
let(:klass) {
|
5
|
+
Class.new.tap do |klass|
|
6
|
+
klass.extend described_class
|
7
|
+
end
|
8
|
+
}
|
9
|
+
|
10
|
+
let(:endpoint) { double(:endpoint) }
|
11
|
+
before(:each) do
|
12
|
+
allow(klass).to receive(:endpoint) { endpoint }
|
13
|
+
end
|
14
|
+
|
15
|
+
shared_examples_for :handles_undefined_endpoint do |method, args|
|
16
|
+
let(:endpoint) { nil }
|
17
|
+
it "raises an EndpointUndefined exception" do
|
18
|
+
expect { klass.send(method, *args) }.to raise_error(WCC::Data::Mapper::EndpointUndefined)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "::find" do
|
23
|
+
it_behaves_like :handles_undefined_endpoint, :find, :id_param
|
24
|
+
|
25
|
+
it "calls show(id) on defined endpoint and builds on response" do
|
26
|
+
expect(endpoint).to receive(:show).with(:id_param).and_return(:response)
|
27
|
+
expect(klass).to receive(:new_from_response).with(:response).and_return(:new_response)
|
28
|
+
expect(klass.find(:id_param)).to eq(:new_response)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "::list" do
|
33
|
+
it_behaves_like :handles_undefined_endpoint, :list, :params
|
34
|
+
|
35
|
+
it "calls index(params) on defined endpoint and builds on response" do
|
36
|
+
expect(endpoint).to receive(:index).with(params: :params).and_return(:response)
|
37
|
+
expect(klass).to receive(:new_from_response).with(:response).and_return(:new_response)
|
38
|
+
expect(klass.list(:params)).to eq(:new_response)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "allows calling with no params" do
|
42
|
+
expect(endpoint).to receive(:index).with(params: {})
|
43
|
+
expect(klass).to receive(:new_from_response)
|
44
|
+
klass.list
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe WCC::Data::Model do
|
4
|
+
|
5
|
+
describe "inherited behavior" do
|
6
|
+
subject { described_class }
|
7
|
+
|
8
|
+
includes = [
|
9
|
+
WCC::Data::Mapper::Attributes,
|
10
|
+
]
|
11
|
+
|
12
|
+
extensions = [
|
13
|
+
WCC::Data::Mapper::JSONResponse,
|
14
|
+
WCC::Data::Mapper::RESTConfiguration,
|
15
|
+
WCC::Data::Mapper::RESTQuery,
|
16
|
+
]
|
17
|
+
|
18
|
+
includes.each do |mod|
|
19
|
+
it "includes #{mod}" do
|
20
|
+
expect(subject.ancestors).to include(mod)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
extensions.each do |mod|
|
25
|
+
it "extends #{mod}" do
|
26
|
+
extended_modules = (class << subject; self; end).included_modules
|
27
|
+
expect(extended_modules).to include(mod)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe WCC::Data::Nucleus::Campus do
|
4
|
+
it "inherits EnumeratedType functionality" do
|
5
|
+
expect(described_class.ancestors).to include(WCC::Data::EnumeratedType)
|
6
|
+
end
|
7
|
+
|
8
|
+
context "with defined data" do
|
9
|
+
|
10
|
+
it "defines Dallas campus" do
|
11
|
+
dallas = described_class[:dallas]
|
12
|
+
expect(dallas).to be_a(described_class)
|
13
|
+
expect(dallas.name).to eq("Dallas")
|
14
|
+
end
|
15
|
+
|
16
|
+
it "defines Fort Worth campus" do
|
17
|
+
dallas = described_class[:ft_worth]
|
18
|
+
expect(dallas).to be_a(described_class)
|
19
|
+
expect(dallas.name).to eq("Fort Worth")
|
20
|
+
end
|
21
|
+
|
22
|
+
it "defines Plano campus" do
|
23
|
+
dallas = described_class[:plano]
|
24
|
+
expect(dallas).to be_a(described_class)
|
25
|
+
expect(dallas.name).to eq("Plano")
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,219 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe WCC::Data::RackClientAppTokenAuth do
|
4
|
+
|
5
|
+
describe WCC::Data::RackClientAppTokenAuth::RedisCache do
|
6
|
+
let(:connection) { instance_spy(Redis) }
|
7
|
+
let(:connection_lambda) { -> (&blk) { blk.call(connection) } }
|
8
|
+
|
9
|
+
describe "#initialize" do
|
10
|
+
it "requires a callable for Redis connection" do
|
11
|
+
expect { described_class.new }.to raise_error(ArgumentError)
|
12
|
+
obj = described_class.new(connection_lambda)
|
13
|
+
expect(obj.connection).to eq(connection_lambda)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "allows setting a :cache_key option to change the token store" do
|
17
|
+
obj = described_class.new(connection_lambda, cache_key: "store")
|
18
|
+
expect(obj.cache_key).to eq("store")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "allows setting the :cache_length" do
|
22
|
+
obj = described_class.new(connection_lambda, cache_length: 5)
|
23
|
+
expect(obj.cache_length).to eq(5)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "defaults :cache_key to the value of the DEFAULT_CACHE_KEY constant" do
|
27
|
+
obj = described_class.new(connection_lambda)
|
28
|
+
expect(obj.cache_key).to eq(described_class::DEFAULT_CACHE_KEY)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "defaults :cache_length to the value of DEFAULT_CACHE_LENGTH constant" do
|
32
|
+
obj = described_class.new(connection_lambda)
|
33
|
+
expect(obj.cache_length).to eq(described_class::DEFAULT_CACHE_LENGTH)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#<<" do
|
38
|
+
subject(:auth) { described_class.new(connection_lambda, cache_key: "test", cache_length: 123) }
|
39
|
+
|
40
|
+
it "calls SET with @cache_key joined to token by a dot and set to '1'" do
|
41
|
+
auth << "token"
|
42
|
+
expect(connection).to have_received(:set).with("test.token", "1")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "calls EXPIRE with the configured cache length" do
|
46
|
+
auth << "token"
|
47
|
+
expect(connection).to have_received(:expire).with("test.token", 123)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#find" do
|
52
|
+
subject(:auth) { described_class.new(connection_lambda, cache_key: "test") }
|
53
|
+
|
54
|
+
it "returns the value from GET on the joined token key" do
|
55
|
+
expect(connection).to receive(:get).with("test.token").and_return("1")
|
56
|
+
expect(auth.find("token")).to eq("1")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#initialize" do
|
62
|
+
it "takes an app argument and sets to @app" do
|
63
|
+
obj = described_class.new(:app)
|
64
|
+
expect(obj.app).to eq(:app)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "takes a :cache option and sets to @cache" do
|
68
|
+
obj = described_class.new(:app, cache: :cache)
|
69
|
+
expect(obj.cache).to eq(:cache)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "takes a :lookup_token and sets to @lookup_token" do
|
73
|
+
obj = described_class.new(:app, lookup_token: :lookup)
|
74
|
+
expect(obj.lookup_token).to eq(:lookup)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "defaults :cache option to an instance of RedisCache" do
|
78
|
+
obj = described_class.new(:app)
|
79
|
+
expect(obj.cache).to be_a(described_class::RedisCache)
|
80
|
+
expect(obj.cache.connection).to eq(Sidekiq.method(:redis))
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "default :lookup_token value" do
|
84
|
+
it "tries to fetch a token with the given value" do
|
85
|
+
expect(WCC::Data::Nucleus::ClientAppToken)
|
86
|
+
.to receive(:find).with("abc123").and_return(:val)
|
87
|
+
expect(described_class.new(:app).lookup_token.("abc123"))
|
88
|
+
.to eq(:val)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "returns nil when InvalidResponse raised" do
|
92
|
+
allow(WCC::Data::Nucleus::ClientAppToken)
|
93
|
+
.to receive(:find).and_raise(WCC::Data::Mapper::InvalidResponse)
|
94
|
+
expect(described_class.new(:app).lookup_token.("abc123"))
|
95
|
+
.to be_nil
|
96
|
+
end
|
97
|
+
|
98
|
+
it "returns nil when RecordNotFound raised" do
|
99
|
+
allow(WCC::Data::Nucleus::ClientAppToken)
|
100
|
+
.to receive(:find).and_raise(WCC::Data::Mapper::RecordNotFound)
|
101
|
+
expect(described_class.new(:app).lookup_token.("abc123"))
|
102
|
+
.to be_nil
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "#find" do
|
109
|
+
let(:cache) { instance_spy(described_class::RedisCache) }
|
110
|
+
subject(:auth) { described_class.new(:app, cache: cache) }
|
111
|
+
|
112
|
+
context "with token in the cache" do
|
113
|
+
before do
|
114
|
+
allow(auth.cache).to receive(:find).with("abc123").and_return("1")
|
115
|
+
end
|
116
|
+
|
117
|
+
it "calls find with token on the cache and then returns cached value" do
|
118
|
+
expect(auth.find("abc123"))
|
119
|
+
.to eq("1")
|
120
|
+
end
|
121
|
+
|
122
|
+
it "does not call lookup_token" do
|
123
|
+
expect(auth.lookup_token).to_not receive(:call)
|
124
|
+
auth.find("abc123")
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context "with an empty cache" do
|
129
|
+
before do
|
130
|
+
allow(cache).to receive(:find).and_return(nil)
|
131
|
+
end
|
132
|
+
|
133
|
+
it "calls lookup_token with the token" do
|
134
|
+
expect(auth.lookup_token)
|
135
|
+
.to receive(:call).with("abc123").and_return(true)
|
136
|
+
expect(auth.find("abc123")).to eq(true)
|
137
|
+
end
|
138
|
+
|
139
|
+
context "with a valid token" do
|
140
|
+
before do
|
141
|
+
allow(auth.lookup_token).to receive(:call).and_return(true)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "shovels the value into the cache" do
|
145
|
+
expect(cache).to receive(:<<).with("abc123")
|
146
|
+
auth.find("abc123")
|
147
|
+
end
|
148
|
+
|
149
|
+
it "returns a truthy value" do
|
150
|
+
expect(auth.find("abc123")).to be_truthy
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context "with an invalid token" do
|
155
|
+
before do
|
156
|
+
allow(auth.lookup_token).to receive(:call).and_return(false)
|
157
|
+
end
|
158
|
+
|
159
|
+
it "does not shovel value into the cache" do
|
160
|
+
expect(auth.cache).to_not receive(:<<)
|
161
|
+
auth.find("abc123")
|
162
|
+
end
|
163
|
+
|
164
|
+
it "returns a falsey value" do
|
165
|
+
expect(auth.find("abc123")).to be_falsey
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe "#call" do
|
172
|
+
subject(:auth) { described_class.new(-> (env) {}, cache: cache) }
|
173
|
+
let(:cache) { instance_spy(described_class::RedisCache) }
|
174
|
+
let(:env) {
|
175
|
+
{
|
176
|
+
"HTTP_AUTHORIZATION" => "Bearer abc123",
|
177
|
+
}
|
178
|
+
}
|
179
|
+
|
180
|
+
|
181
|
+
it "passes the bearer token onto the find method" do
|
182
|
+
expect(auth).to receive(:find).with("abc123")
|
183
|
+
auth.call(env)
|
184
|
+
end
|
185
|
+
|
186
|
+
context "truthy find result" do
|
187
|
+
before do
|
188
|
+
allow(auth).to receive(:find).and_return(true)
|
189
|
+
end
|
190
|
+
|
191
|
+
it "passes the request on to the app" do
|
192
|
+
expect(auth.app).to receive(:call).with(env)
|
193
|
+
auth.call(env)
|
194
|
+
end
|
195
|
+
|
196
|
+
it "returns the value of app" do
|
197
|
+
allow(auth.app).to receive(:call).and_return(:value)
|
198
|
+
expect(auth.call(env)).to eq(:value)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context "falsey find result" do
|
203
|
+
before do
|
204
|
+
allow(auth).to receive(:find).and_return(false)
|
205
|
+
end
|
206
|
+
|
207
|
+
it "does not call app" do
|
208
|
+
expect(auth.app).to_not receive(:call)
|
209
|
+
auth.call(env)
|
210
|
+
end
|
211
|
+
|
212
|
+
it "returns a 403 response" do
|
213
|
+
response = auth.call(env)
|
214
|
+
|
215
|
+
expect(response).to eq([403, {}, '{"error":"Invalid Bearer Token"}'])
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|