wcc-data 0.3.9 → 0.4.0.pre

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 39ee71b24991611f222411ff406d9d5b8bda3f0b
4
- data.tar.gz: 38c06caa2ebd8c97866dc5fdacdfe40c1140ed41
3
+ metadata.gz: 82f9b734e798bdb01d28323037ba25ea1a87a831
4
+ data.tar.gz: 46b3020ff169cdfa6e687c9933b765a5f7ed26a6
5
5
  SHA512:
6
- metadata.gz: 7dabe6eed115fcd58fd4c6b0c450b4caa70ba8778a2c14ffdff4eb0ecfc2dcb21b65259763a3ccc6e4805d2066c230073d56faabea8836a1ac82228aedf4e1f7
7
- data.tar.gz: 187c70f79ed1b2e9251f37d3d42efa032a5ce38aaef61aabc9df5232eb623be361630a398c123090f06212bab81152b8141fd7edd4cc87f4806d29b12d76a6ff
6
+ metadata.gz: b527b25651b9e1e0930ba6c0f4c4b816e929b9efc664910d1b5dd7ce42936840f2b1ab46e1489654c05490a145426bf3121fb9efd236e4cf03d4d596f8f582d5
7
+ data.tar.gz: 4cf4c852f51a72b46ff553539a72903ef218e314eaafe70651b6945c587efececd064e0f222f2508ba75e6825884954eec81fbf5fc1b64f733ec3e82be292483
data/.env.example ADDED
@@ -0,0 +1,3 @@
1
+ NUCLEUS_CLIENT_ID=client-id-3
2
+ NUCLEUS_CLIENT_SECRET=client-secret-3
3
+ NUCLEUS_URL=http://login.wcc/
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .env*.local
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in wcc-data.gemspec
4
+ gemspec
5
+
6
+ gem 'rack', '~>1.6.5'
data/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'dotenv/tasks'
3
+
4
+ PROJECT_PATH = File.dirname(__FILE__)
5
+ LIB_PATH = File.join(PROJECT_PATH, "lib")
6
+
7
+ task :default => :test
8
+
9
+ desc 'run test examples'
10
+ task :test do
11
+ exec 'rspec .'
12
+ end
13
+
14
+ task :environment => :dotenv do
15
+ $LOAD_PATH.unshift(LIB_PATH)
16
+ require 'wcc/data'
17
+ end
18
+
19
+ task :development => [:environment] do
20
+ WCC::Data.setup do |config|
21
+ conn = config.applications[:nucleus].connection
22
+ conn.use Faraday::Response::Logger
23
+ conn.basic_auth(ENV['NUCLEUS_CLIENT_ID'], ENV['NUCLEUS_CLIENT_SECRET'])
24
+ end
25
+ end
26
+
27
+ desc 'launch IRB shell with base environment loaded'
28
+ task :irb => :environment do
29
+ require 'irb'
30
+ ARGV.clear
31
+ IRB.start
32
+ end
33
+
34
+ desc 'launch IRB shell with development environment loaded'
35
+ task :console => [:development, :irb]
36
+
data/bin/rspec ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'rspec' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("rspec-core", "rspec")
data/circle.yml ADDED
@@ -0,0 +1,6 @@
1
+ machine:
2
+ ruby:
3
+ version: 2.2.2
4
+ dependencies:
5
+ pre:
6
+ - cp .env.example .env
@@ -1,64 +1,83 @@
1
+
2
+ begin
3
+ gem 'faraday'
4
+ require 'faraday'
5
+ rescue Gem::LoadError
6
+ # suppress
7
+ end
8
+
9
+
1
10
  module WCC::Data
2
- class FaradayClientAppTokenAuth < Faraday::Middleware
3
- class RedisCache
4
- DEFAULT_CACHE_KEY = "org.watermark.data.client-app-token-cache-store"
5
- attr_reader :connection, :cache_key
11
+ if defined?(Faraday)
12
+ class FaradayClientAppTokenAuth < Faraday::Middleware
13
+ class RedisCache
14
+ DEFAULT_CACHE_KEY = "org.watermark.data.client-app-token-cache-store"
15
+ attr_reader :connection, :cache_key
6
16
 
7
- def initialize(connection, cache_key: DEFAULT_CACHE_KEY)
8
- @connection = connection
9
- @cache_key = cache_key
10
- end
17
+ def initialize(connection, cache_key: DEFAULT_CACHE_KEY)
18
+ @connection = connection
19
+ @cache_key = cache_key
20
+ end
11
21
 
12
- def [](hostname)
13
- connection.call { |r| r.hget cache_key, hostname }
14
- end
22
+ def [](hostname)
23
+ connection.call { |r| r.hget cache_key, hostname }
24
+ end
15
25
 
16
- def []=(hostname, token)
17
- if token
18
- connection.call { |r| r.hset cache_key, hostname, token }
19
- else
20
- connection.call { |r| r.hdel cache_key, hostname }
26
+ def []=(hostname, token)
27
+ if token
28
+ connection.call { |r| r.hset cache_key, hostname, token }
29
+ else
30
+ connection.call { |r| r.hdel cache_key, hostname }
31
+ end
21
32
  end
22
33
  end
23
- end
24
34
 
25
- attr_reader :cache, :token_factory
35
+ attr_reader :cache, :token_factory
26
36
 
27
- def initialize(app, cache: default_cache, token_factory: method(:default_token_factory))
28
- super(app)
29
- @cache = cache
30
- @token_factory = token_factory
31
- end
37
+ def initialize(app, cache: default_cache, token_factory: method(:default_token_factory))
38
+ super(app)
39
+ @cache = cache
40
+ @token_factory = token_factory
41
+ end
32
42
 
33
- def token_for(host)
34
- @cache[host] ||= token_factory.(host)
35
- end
43
+ def token_for(host)
44
+ @cache[host] ||= token_factory.(host)
45
+ end
36
46
 
37
- def call(env, retry_on_forbidden: true)
38
- request_body = env[:body]
39
- host = env[:url].host
40
- env[:request_headers]["Authorization"] = "Bearer #{token_for(host)}"
41
- @app.call(env).on_complete do |response_env|
42
- response = Faraday::Response.new(response_env)
43
- cache[host] = nil unless response.success?
44
- if response.status == 403 && retry_on_forbidden
45
- env[:body] = request_body
46
- call(env, retry_on_forbidden: false)
47
+ def call(env, retry_on_forbidden: true)
48
+ request_body = env[:body]
49
+ host = env[:url].host
50
+ env[:request_headers]["Authorization"] = "Bearer #{token_for(host)}"
51
+ @app.call(env).on_complete do |response_env|
52
+ response = Faraday::Response.new(response_env)
53
+ cache[host] = nil unless response.success?
54
+ if response.status == 403 && retry_on_forbidden
55
+ env[:body] = request_body
56
+ call(env, retry_on_forbidden: false)
57
+ end
47
58
  end
48
59
  end
49
- end
50
60
 
51
- private
61
+ private
52
62
 
53
- def default_token_factory(host)
54
- WCC::Data::Nucleus::ClientAppToken.create(hostname: host).token
55
- end
63
+ def default_token_factory(host)
64
+ WCC::Data::Nucleus::ClientAppToken.create(hostname: host).token
65
+ end
56
66
 
57
- def default_cache
58
- RedisCache.new(Sidekiq.method(:redis))
67
+ def default_cache
68
+ RedisCache.new(Sidekiq.method(:redis))
69
+ end
70
+ end
71
+ else
72
+ class FaradayClientAppTokenAuth
73
+ def initialize(app, cache: default_cache, token_factory: method(:default_token_factory))
74
+ raise NotSupportedError, 'Please include the "faraday" gem to use this authentication method'
75
+ end
59
76
  end
60
77
  end
61
78
  end
62
79
 
63
- Faraday::Middleware.register_middleware :client_app_token => lambda { WCC::Data::FaradayClientAppTokenAuth }
80
+ if defined?(Faraday)
81
+ Faraday::Middleware.register_middleware :client_app_token => lambda { WCC::Data::FaradayClientAppTokenAuth }
82
+ end
64
83
 
@@ -27,11 +27,11 @@ module WCC::Data::Nucleus
27
27
  code: 'FTW',
28
28
  name: 'Fort Worth',
29
29
  key: :ft_worth,
30
- street: '8000 Western Hills Blvd',
30
+ street: '3345 Winthrop Avenue',
31
31
  city: 'Fort Worth',
32
32
  state: 'TX',
33
- zip: '76108',
34
- geo: [32.739972, -97.455414]
33
+ zip: '76116',
34
+ geo: [32.7280064, -97.4146727]
35
35
  },
36
36
  {
37
37
  id: 3,
@@ -54,28 +54,6 @@ module WCC::Data::Nucleus
54
54
  state: 'TX',
55
55
  zip: '75034',
56
56
  geo: [33.130761, -96.822322]
57
- },
58
- {
59
- id: 5,
60
- code: 'SDL',
61
- name: 'South Dallas',
62
- key: :south_dallas,
63
- street: '3400 Garden Ln',
64
- city: 'Dallas',
65
- state: 'TX',
66
- zip: '75215',
67
- geo: [32.758418, -96.743966]
68
- },
69
- {
70
- id: 6,
71
- code: 'ROC',
72
- name: 'Rockwall',
73
- key: :rockwall,
74
- street: '1565 Airport Rd',
75
- city: 'Rockwall',
76
- state: 'TX',
77
- zip: '75087',
78
- geo: [32.926936, -96.439255]
79
57
  }
80
58
  ]
81
59
  end
@@ -1,5 +1,5 @@
1
1
  module WCC
2
2
  module Data
3
- VERSION = '0.3.9'.freeze
3
+ VERSION = '0.4.0.pre'.freeze
4
4
  end
5
5
  end
@@ -0,0 +1,24 @@
1
+ SPEC_DIR = File.dirname(__FILE__)
2
+ FIXTURES_DIR = File.join(SPEC_DIR, "fixtures")
3
+
4
+ $LOAD_PATH.unshift File.join(SPEC_DIR, "..", "lib")
5
+ $LOAD_PATH.unshift SPEC_DIR
6
+
7
+ require 'dotenv'
8
+ Dotenv.load
9
+
10
+ require 'wcc/data'
11
+ require 'sidekiq'
12
+
13
+ Dir[File.join(SPEC_DIR, "support", "*.rb")].each do |support_file|
14
+ require "support/#{File.basename(support_file, ".rb")}"
15
+ end
16
+
17
+ RSpec.configure do |config|
18
+ config.run_all_when_everything_filtered = true
19
+ config.filter_run :focus
20
+
21
+ config.order = 'random'
22
+
23
+ ENV['NUCLEUS_URL'] ||= 'http://login.wcc'
24
+ end
@@ -0,0 +1,16 @@
1
+ shared_examples_for :inheritable_class_attributes do |name|
2
+ let(:subclass) { Class.new(subject) }
3
+
4
+ it "inherited value is the same as parent class" do
5
+ subject.send(:instance_variable_set, :"@#{name}", foo: :bar)
6
+ expect(subject.send(name)).to eq(foo: :bar)
7
+ expect(subclass.send(name)).to eq(foo: :bar)
8
+ end
9
+
10
+ it "inherited reference is unique from the parent class" do
11
+ subject.send(:instance_variable_set, :"@#{name}", foo: :bar)
12
+ subclass.send(name)[:bar] = :baz
13
+ expect(subject.send(name)).to eq(foo: :bar)
14
+ end
15
+ end
16
+
@@ -0,0 +1,113 @@
1
+ require 'spec_helper'
2
+
3
+ describe WCC::Data::Config::Application do
4
+ let(:unit) { WCC::Data::Config::Application }
5
+ subject { unit.new(:name) }
6
+
7
+ describe "#initialize" do
8
+ it "takes a single name symbol and stores in @name" do
9
+ obj = unit.new(:name)
10
+ expect(obj.name).to eq(:name)
11
+ end
12
+
13
+ it "takes a connection option and stores it in @connection" do
14
+ obj = unit.new(:name, connection: "foo")
15
+ expect(obj.connection).to eq("foo")
16
+ end
17
+
18
+ it "sets to a blank Faraday::Connection" do
19
+ obj = unit.new(:name)
20
+ expect(obj.connection).to be_a(Faraday::Connection)
21
+ end
22
+ end
23
+
24
+ describe "#uri=" do
25
+ it "converts a string to a URI and stores in @uri" do
26
+ subject.uri = "http://test"
27
+ expect(subject.uri).to be_a(URI)
28
+ expect(subject.uri.scheme).to eq("http")
29
+ end
30
+
31
+ it "uses the URI object if set with a URI" do
32
+ subject.uri = test_value = URI("http://test")
33
+ expect(subject.uri).to eq(test_value)
34
+ end
35
+ end
36
+
37
+ describe "#service" do
38
+ before(:each) do
39
+ subject.uri = "http://test.com/"
40
+ end
41
+
42
+ it "returns a service object based on the URI" do
43
+ obj = subject.service
44
+ expect(obj).to be_a(WCC::Data::Service)
45
+ expect(obj.uri).to eq(subject.uri)
46
+ end
47
+
48
+ it "passes the application connection through to the service" do
49
+ obj = subject.service
50
+ expect(obj.connection).to eq(subject.connection)
51
+ end
52
+ end
53
+
54
+ describe "@connection" do
55
+ it "gets and sets" do
56
+ subject.connection = "foo"
57
+ expect(subject.connection).to eq("foo")
58
+ end
59
+ end
60
+ end
61
+
62
+ describe WCC::Data::Config do
63
+ let(:unit) { WCC::Data::Config }
64
+ subject { unit.new }
65
+
66
+
67
+ describe "#applications" do
68
+ it "returns a hash" do
69
+ expect(subject.applications).to be_a(Hash)
70
+ end
71
+
72
+ it "defaults empty keys to an application" do
73
+ expect(subject.applications[:foo]).to be_a(WCC::Data::Config::Application)
74
+ end
75
+
76
+ it "contains a default entry for :nucleus" do
77
+ expect(subject.applications[:nucleus].uri).to eq(
78
+ URI(ENV['NUCLEUS_URL'])
79
+ )
80
+ end
81
+
82
+ context "with APP_CLIENT_ID and APP_CLIENT_SECRET ENV vars set" do
83
+ after do
84
+ ENV['APP_CLIENT_ID'] = ENV['APP_CLIENT_SECRET'] = nil
85
+ end
86
+
87
+ it "sets the connection's basic auth for nucleus" do
88
+ ENV['APP_CLIENT_ID'] = "test"
89
+ ENV['APP_CLIENT_SECRET'] = "value"
90
+
91
+ header = subject.applications[:nucleus].connection.headers["Authorization"]
92
+
93
+ expect(header)
94
+ .to eq(Faraday::Request::BasicAuthentication.header("test", "value"))
95
+ end
96
+ end
97
+
98
+ context "with APP_CLIENT_ID and APP_CLIENT_SECRET not both set" do
99
+ it "does not set the basic auth for nucleus" do
100
+ header = subject.applications[:nucleus].connection.headers["Authorization"]
101
+
102
+ expect(header).to be_nil
103
+ end
104
+ end
105
+ end
106
+
107
+ describe "#apps alias" do
108
+ it "aliases to #applications" do
109
+ expect(subject.apps).to eq(subject.applications)
110
+ end
111
+ end
112
+
113
+ end
@@ -0,0 +1,176 @@
1
+ require "spec_helper"
2
+
3
+ describe WCC::Data::EnumeratedType do
4
+
5
+ context "with configured attributes" do
6
+ let(:type) {
7
+ Class.new(described_class) do
8
+ attributes :test1, :test2
9
+ end
10
+ }
11
+ let(:object) { type.new(data) }
12
+ let(:data) {
13
+ {
14
+ test1: "test data 1",
15
+ test2: "test data 2",
16
+ ignored: "",
17
+ }
18
+ }
19
+
20
+ it "adds a method for all arguments passed" do
21
+ expect(object).to respond_to(:test1)
22
+ expect(object).to respond_to(:test2)
23
+ end
24
+
25
+ it "sets values from initialize hash" do
26
+ expect(object.test1).to eq("test data 1")
27
+ expect(object.test2).to eq("test data 2")
28
+ end
29
+
30
+ describe "::defined_attributes" do
31
+ it "should return attributes" do
32
+ expect(type.defined_attributes).to eq([:test1, :test2])
33
+ end
34
+ end
35
+ end
36
+
37
+ context "with child classes" do
38
+ let(:parent) {
39
+ Class.new(described_class) do
40
+ attributes :attr1
41
+ attributes :attr2
42
+ end
43
+ }
44
+ let(:child) {
45
+ Class.new(parent) do
46
+ attributes :attr3, :attr4
47
+ end
48
+ }
49
+ let(:parent_object) { parent.new(data) }
50
+ let(:child_object) { child.new(data) }
51
+ let(:data) {
52
+ {
53
+ attr1: "data1",
54
+ attr2: "data2",
55
+ attr3: "data3",
56
+ attr4: "data4",
57
+ }
58
+ }
59
+
60
+ describe "parent class" do
61
+ it "does not include child attributes" do
62
+ expect(parent_object).to_not respond_to(:attr3)
63
+ expect(parent_object).to_not respond_to(:attr4)
64
+ end
65
+
66
+ it "includes both attributes" do
67
+ expect(parent_object).to respond_to(:attr1)
68
+ expect(parent_object).to respond_to(:attr2)
69
+ end
70
+
71
+ it "sets both attributes on initialize" do
72
+ expect(parent_object.attr1).to eq("data1")
73
+ expect(parent_object.attr2).to eq("data2")
74
+ end
75
+ end
76
+
77
+ describe "child class" do
78
+ it "includes all defined_attributes" do
79
+ expect(child.defined_attributes).to eq([:attr1, :attr2, :attr3, :attr4])
80
+ end
81
+
82
+ it "includes parent attributes and child attributes readers" do
83
+ expect(child_object.attr1).to eq("data1")
84
+ expect(child_object.attr2).to eq("data2")
85
+ expect(child_object.attr3).to eq("data3")
86
+ expect(child_object.attr4).to eq("data4")
87
+ end
88
+ end
89
+
90
+ end
91
+
92
+ context "with db, matches?, and attributes configured" do
93
+ let(:type) {
94
+ Class.new(described_class) do
95
+ attributes :id, :name, :key
96
+
97
+ def matches?(value)
98
+ [id, key].include?(value)
99
+ end
100
+
101
+ def self.db
102
+ [
103
+ { id: 1, name: "One", key: :one },
104
+ { id: 2, name: "Two", key: :two },
105
+ { id: 3, name: "Three", key: :three },
106
+ { id: 4, name: "Four", key: :three },
107
+ ]
108
+ end
109
+ end
110
+ }
111
+
112
+ describe "::[]" do
113
+ it "returns an instance of type if match found" do
114
+ expect(type[1]).to be_a(type)
115
+ end
116
+
117
+ it "returns nil if no match found" do
118
+ expect(type[:nil]).to be_nil
119
+ end
120
+
121
+ it "returns first match when multiple matches present" do
122
+ expect(type[:three]).to eq(type.all[2])
123
+ end
124
+ end
125
+
126
+ describe "::all" do
127
+ it "returns instances of EnumeratedType for each item in db" do
128
+ expect(type.all.size).to eq(4)
129
+ expect(type.all[0]).to be_a(type)
130
+ expect(type.all[1]).to be_a(type)
131
+ expect(type.all[2]).to be_a(type)
132
+ expect(type.all[3]).to be_a(type)
133
+ end
134
+
135
+ it "sets attributes for each record properly" do
136
+ expect(type.all[0].id).to eq(1)
137
+ expect(type.all[0].name).to eq("One")
138
+ expect(type.all[0].key).to eq(:one)
139
+ expect(type.all[1].key).to eq(:two)
140
+ expect(type.all[2].key).to eq(:three)
141
+ end
142
+
143
+ it "caches the results" do
144
+ expect(type.all[0].object_id).to eq(type.all[0].object_id)
145
+ end
146
+ end
147
+
148
+ describe "::reset" do
149
+ it "clears out all and forces new object creation" do
150
+ first_id = type.all[0].object_id
151
+ type.reset
152
+ expect(type.all[0].object_id).to_not eq(first_id)
153
+ end
154
+ end
155
+ end
156
+
157
+ describe "#initialize" do
158
+ it "allows passing no argument" do
159
+ expect { described_class.new }.to_not raise_error
160
+ end
161
+ end
162
+
163
+ describe "::db" do
164
+ it "raises NotImplementedError with instructions" do
165
+ expect { described_class.db }.to raise_error(NotImplementedError, /subclass/i)
166
+ end
167
+ end
168
+
169
+ describe "#matches?" do
170
+ it "raises NotImplementedError with instructions" do
171
+ object = described_class.new({})
172
+ expect { object.matches?(:val) }.to raise_error(NotImplementedError, /subclass/i)
173
+ end
174
+ end
175
+
176
+ end