codelocks 1.0.1 → 2.0.0

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: 22a32b897d94688bf6f6a455987b58f0c05d251c
4
- data.tar.gz: 7c58c530ddc5ea411222c82d0f66b95e286b3e51
3
+ metadata.gz: 95679230c6136305c9e70650b31100d9d53bcc54
4
+ data.tar.gz: 7a4e35c3bc4d007e93bd3254a174b933db9b6126
5
5
  SHA512:
6
- metadata.gz: e8860b06e8c2b86a4a5f388b3e9d57a9ffb5b8ea2de4e36ec897f5f793a019d9a9ca05d9cfb8129c010a1dbd9df4ac4035d3c27bcff34d410c6dacbccd4e1ace
7
- data.tar.gz: 6ac150201dfc62c9cefc77a88dd8bab938b0405c63cc28f7b66436bf66a540240768553842e2c11ced71a20c04bfb34891fb8d3219b77c4d4c48e6386ce07fa9
6
+ metadata.gz: 2a61b480d8b59951b11130b39df8976a8d1311becd4cf460f347def4a1f74b8f6ce080e0d54d0c4c10e3cf50383e44311fc123e744fd3b59ac558cc8245f6343
7
+ data.tar.gz: 762f6fc396ffbe55806698dd3405f94912b7a675ef16f5377d232b6ac4971132af86ddcbbe7a7548ada89ee9a99aed730f467a6732cac56543dd0b7751847aa8
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.2.3
data/README.md CHANGED
@@ -1,9 +1,14 @@
1
1
  # Codelocks
2
2
 
3
- [![Circle CI](https://circleci.com/gh/kansohq/codelocks.svg?style=svg)](https://circleci.com/gh/kansohq/codelocks)
3
+ [![Gem Version](https://badge.fury.io/rb/codelocks.svg)](https://badge.fury.io/rb/codelocks)
4
4
 
5
5
  A simple gem to wrap the Codelocks NetCode API, for generating key codes to operate their physical locks.
6
6
 
7
+ # API Versions
8
+
9
+ If you are using an API version prior to v4.1, you need to use the latest v1 release of this gem.
10
+ v2 is a large rewrite in order to support the new API.
11
+
7
12
  ## Installation
8
13
 
9
14
  Add this line to your application's Gemfile:
@@ -25,15 +30,17 @@ Or install it yourself as:
25
30
  Configure your API credentials, either by setting the following two environment variables:
26
31
 
27
32
  ```
33
+ CODELOCKS_BASE_URI
28
34
  CODELOCKS_API_KEY
29
- CODELOCKS_PAIRING_ID
35
+ CODELOCKS_ACCESS_KEY
30
36
  ```
31
37
 
32
38
  Or by setting them directly in Ruby:
33
39
 
34
40
  ```ruby
41
+ Codelocks.base_uri = "http://something.com"
35
42
  Codelocks.api_key = "blargh"
36
- Codelocks.pairing_id = "argh"
43
+ Codelocks.access_key = "argh"
37
44
  ```
38
45
 
39
46
  API documentation with information on methods is [available on RubyDoc.info](http://www.rubydoc.info/github/kansohq/codelocks/master).
data/codelocks.gemspec CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "rspec", "~> 3.3"
24
24
  spec.add_development_dependency "vcr", "~> 2.9"
25
25
  spec.add_development_dependency "dotenv", "~> 2.0"
26
+ spec.add_development_dependency "pry"
26
27
 
27
28
  spec.add_dependency "faraday", "~> 0.8.11"
28
29
 
data/lib/codelocks.rb CHANGED
@@ -1,22 +1,23 @@
1
1
  require "faraday"
2
2
 
3
3
  require "codelocks/version"
4
+ require "codelocks/request"
5
+ require "codelocks/response"
6
+ require "codelocks/lock"
4
7
  require "codelocks/net_code"
5
- require "codelocks/net_code/request"
6
- require "codelocks/net_code/response"
7
8
 
8
9
  module Codelocks
9
10
  class CodelocksError < StandardError; end
10
11
 
11
12
  class << self
12
- attr_writer :api_key, :pairing_id
13
+ attr_writer :base_uri, :api_key, :access_key
13
14
 
14
15
  # The base URI used for API request
15
16
  #
16
17
  # @return [String] the base URI
17
18
 
18
19
  def base_uri
19
- "https://api-2445581366752.apicast.io/api/v3"
20
+ @base_uri || ENV['CODELOCKS_BASE_URI'] || (raise CodelocksError.new("No base URI specified"))
20
21
  end
21
22
 
22
23
  # Return the configured API key or raise an exception
@@ -27,12 +28,13 @@ module Codelocks
27
28
  @api_key || ENV['CODELOCKS_API_KEY'] || (raise CodelocksError.new("No API key specified"))
28
29
  end
29
30
 
30
- # Return the configured pairing ID or raise an exception
31
+ # Return the access key. This is tied to the K3 Connect App.
32
+ # This can be nil, as for certain models of locks you will provide a 6 digit ID instead.
31
33
  #
32
- # @return [String] the pairing ID
34
+ # @return [String] the access key
33
35
 
34
- def pairing_id
35
- @pairing_id || ENV['CODELOCKS_PAIRING_ID'] || (raise CodelocksError.new("No pairing ID specified"))
36
+ def access_key
37
+ @access_key || ENV['CODELOCKS_ACCESS_KEY']
36
38
  end
37
39
 
38
40
  # Faraday connection object
@@ -0,0 +1,19 @@
1
+ module Codelocks
2
+ class Lock
3
+ class << self
4
+ # Fetch a list of locks. Requires the access key env var to be set
5
+ #
6
+ # @return [Codelocks::NetCode::Response]
7
+
8
+ def all
9
+ if !Codelocks.access_key
10
+ raise CodelocksError.new("An access key must be provided")
11
+ end
12
+
13
+ Request.create("lock",
14
+ "accesskey": Codelocks.access_key
15
+ )
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,54 +1,142 @@
1
1
  module Codelocks
2
- module NetCode
2
+ class NetCode
3
3
  class << self
4
4
  # Predefined method for generating a new NetCode
5
5
  #
6
6
  # @option [String] :lock_id The lock identifier
7
- # @option [Time] :start_time (Time.now) The start datetime object
8
- # @option [Integer] :duration The number of hours the generated code should be valid for from the start_time
7
+ # @option [String] :lock_model (K3CONNECT) The type of lock
8
+ # @option [Time] :start (Time.now) The start datetime object
9
+ # @option [Integer] :duration (0) The number of hours the generated code should be valid for from the start_time
10
+ # @option [Boolean] :urm (false) Generate an URM code
11
+ # @option [String] :identifier (Codelocks.access_key) The access key or lock identifier
9
12
  #
10
13
  # @return [Codelocks::NetCode::Response]
11
14
 
12
- def generate_netcode(lock_id: nil, start_time: Time.now, duration: nil)
13
- Request.create("netcode/ncgenerator/getnetcode", {
14
- id: "N#{lock_id}",
15
- sd: start_time.strftime("%d/%m/%Y"),
16
- st: start_time.strftime("%H"),
17
- du: convert_duration(duration)
18
- })
15
+ def generate_netcode(opts = {})
16
+ netcode = new(opts)
17
+
18
+ if !netcode.identifier
19
+ raise CodelocksError.new("Either a lock identifier or an access key must be provided")
20
+ end
21
+
22
+ Request.create("netcode/#{netcode.lock_id}",
23
+ "id": netcode.lock_id,
24
+ "start": netcode.start_datetime,
25
+ "duration": netcode.duration_id,
26
+ "lockmodel": netcode.lock_model,
27
+ "identifier": netcode.identifier
28
+ )
19
29
  end
30
+ end
20
31
 
21
- private
32
+ attr_accessor :opts
22
33
 
23
- # Convert a duration in hours to the NetCode duration option
24
- #
25
- # @param [Integer] duration number of hours duration
26
- #
27
- # @return [Integer]
28
-
29
- def convert_duration(duration = 0)
30
- case
31
- when duration == 0
32
- duration
33
- when duration <= 12 # less than 13 hours
34
- duration -1
35
- when (13..24).include?(duration) # 1 day
36
- 12
37
- when (25..48).include?(duration) # 2 days
38
- 13
39
- when (49..72).include?(duration) # 3 days
40
- 14
41
- when (73..96).include?(duration) # 4 days
42
- 15
43
- when (97..120).include?(duration) # 5 days
44
- 16
45
- when (121..144).include?(duration) # 6 days
46
- 17
47
- when (145..168).include?(duration) # 7 days
48
- 18
49
- when duration > 168 # more than 7 days, generates a URM code
50
- 19
51
- end
34
+ def initialize(opts = {})
35
+ self.opts = {
36
+ lock_model: nil || "K3CONNECT",
37
+ lock_id: nil,
38
+ start: Time.now,
39
+ duration: 0,
40
+ urm: false,
41
+ identifier: nil
42
+ }.merge(opts)
43
+ end
44
+
45
+ def method_missing(method, *args, &block)
46
+ return opts[method] if opts.include?(method)
47
+ super
48
+ end
49
+
50
+ # Return either a supplied identifier or the predefined access key
51
+ #
52
+ # @return [String]
53
+
54
+ def identifier
55
+ opts[:identifier] || Codelocks.access_key
56
+ end
57
+
58
+ # String representing the start date in YYYY-MM-DD format
59
+ #
60
+ # @return [String]
61
+
62
+ def start_date
63
+ start.strftime("%Y-%m-%d")
64
+ end
65
+
66
+ # String representing the start time. Hour has a leading zero
67
+ #
68
+ # @return [String]
69
+
70
+ def start_time
71
+ if urm? && duration_id >= 31 # URM enabled and >= 24 hours duration
72
+ "00:00"
73
+ else
74
+ start.strftime("%H:%M")
75
+ end
76
+ end
77
+
78
+ # Full date time formatted for API use
79
+ #
80
+ # @return [String]
81
+
82
+ def start_datetime
83
+ [start_date, start_time].join(" ")
84
+ end
85
+
86
+ # NetCode duration ID
87
+ #
88
+ # @return [Integer]
89
+
90
+ def duration_id
91
+ base_duration + urm_offset
92
+ end
93
+
94
+ # Are URM codes enabled?
95
+ #
96
+ # @return [Boolean]
97
+
98
+ def urm?
99
+ !!urm
100
+ end
101
+
102
+ private
103
+
104
+ # Convert a duration in hours to the NetCode duration ID
105
+ #
106
+ # @return [Integer]
107
+
108
+ def base_duration
109
+ case duration
110
+ when 0
111
+ 0
112
+ when 1..12 # less than 13 hours
113
+ duration - 1
114
+ when 13..24 # 1 day
115
+ 12
116
+ when 25..48 # 2 days
117
+ 13
118
+ when 49..72 # 3 days
119
+ 14
120
+ when 73..96 # 4 days
121
+ 15
122
+ when 97..120 # 5 days
123
+ 16
124
+ when 121..144 # 6 days
125
+ 17
126
+ else # 7 days
127
+ 18
128
+ end
129
+ end
130
+
131
+ # Convert a URM enabled boolean to a NetCode duration offset
132
+ #
133
+ # @return [Integer]
134
+
135
+ def urm_offset
136
+ if urm?
137
+ 19
138
+ else
139
+ 0
52
140
  end
53
141
  end
54
142
  end
@@ -0,0 +1,29 @@
1
+ module Codelocks
2
+ class Request
3
+ class << self
4
+ # Perform a request against the NetCode API
5
+ #
6
+ # @param [String] path the URI path to perform the request against
7
+ # @param [Hash] params defined in Codelocks::NetCode
8
+ #
9
+ # @return [Codelocks::NetCode::Response]
10
+
11
+ def create(path, params = {})
12
+ response = Codelocks.connection.get(path, default_params.merge(params)) do |req|
13
+ req.headers['x-api-key'] = Codelocks.api_key
14
+ end
15
+
16
+ Response.new(response)
17
+ end
18
+
19
+ private
20
+ # The default params used in NetCode endpoint requests
21
+ #
22
+ # @return [Hash]
23
+
24
+ def default_params
25
+ {}
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,51 @@
1
+ require "json"
2
+
3
+ module Codelocks
4
+ class Response
5
+ attr_reader :response
6
+
7
+ # Initialize the response object
8
+ #
9
+ # @param [Faraday::Response] faraday_response
10
+
11
+ def initialize(faraday_response)
12
+ @response = faraday_response
13
+ end
14
+
15
+ # Was the request successful?
16
+ #
17
+ # @return [Truthy]
18
+
19
+ def success?
20
+ response.success?
21
+ end
22
+
23
+ # Parse the response from the server
24
+ #
25
+ # @return [Hash,Nil]
26
+
27
+ def body
28
+ @body ||= JSON.parse(response.body)
29
+ end
30
+
31
+ # Convenience method for fetching the error message
32
+ #
33
+ # @return [String]
34
+
35
+ def error_message
36
+ if !success?
37
+ body["Message"]
38
+ end
39
+ rescue JSON::ParserError => ex
40
+ ex.message
41
+ end
42
+
43
+ # Simple method missing accessor for reading returned attributes
44
+ #
45
+ # @return [String] the raw returned string from the API
46
+
47
+ def method_missing(method_name, *opts, &block)
48
+ body[method_name.to_s] if body.is_a?(Hash)
49
+ end
50
+ end
51
+ end
@@ -1,3 +1,3 @@
1
1
  module Codelocks
2
- VERSION = "1.0.1"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -0,0 +1,52 @@
1
+ require "spec_helper"
2
+
3
+ describe Codelocks::Lock do
4
+ describe ".all" do
5
+ subject { Codelocks::Lock.all }
6
+
7
+ before do
8
+ Codelocks.base_uri = ENV["CODELOCKS_BASE_URI"] || "wibble"
9
+ Codelocks.api_key = ENV["CODELOCKS_API_KEY"] || "wobble"
10
+ end
11
+
12
+ context "valid access key" do
13
+ before do
14
+ Codelocks.access_key = ENV["CODELOCKS_ACCESS_KEY"] || "wubble"
15
+ end
16
+
17
+ around(:each) do |example|
18
+ VCR.use_cassette("valid_access_key", erb: true, match_requests_on: [:method]) do
19
+ example.run
20
+ end
21
+ end
22
+
23
+ it { is_expected.to be_a(Codelocks::Response) }
24
+
25
+ it "is successful" do
26
+ expect(subject.success?).to be true
27
+ end
28
+
29
+ it "doesn't return an error" do
30
+ expect(subject.error_message).to be nil
31
+ end
32
+ end
33
+
34
+ context "invalid access key" do
35
+ before do
36
+ Codelocks.access_key = "abracadabra"
37
+ end
38
+
39
+ around(:each) do |example|
40
+ VCR.use_cassette("invalid_access_key", erb: true, match_requests_on: [:method]) do
41
+ example.run
42
+ end
43
+ end
44
+
45
+ it { is_expected.to be_a(Codelocks::Response) }
46
+
47
+ it "returns an error" do
48
+ expect(subject.error_message).to be_a(String)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -1,7 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Codelocks::NetCode do
4
- describe "#generate_netcode" do
4
+ describe ".generate_netcode" do
5
5
  let(:lock_id) { nil }
6
6
  let(:start_time) { Time.now }
7
7
  let(:duration) { 1 }
@@ -9,12 +9,13 @@ describe Codelocks::NetCode do
9
9
  subject { Codelocks::NetCode.generate_netcode(lock_id: lock_id, start_time: start_time, duration: duration) }
10
10
 
11
11
  before do
12
- Codelocks.api_key = ENV['CODELOCKS_API_KEY'] || "wibble"
13
- Codelocks.pairing_id = ENV['CODELOCKS_PAIRING_ID'] || "wobble"
12
+ Codelocks.base_uri = ENV["CODELOCKS_BASE_URI"] || "wibble"
13
+ Codelocks.api_key = ENV["CODELOCKS_API_KEY"] || "wobble"
14
+ Codelocks.access_key = ENV["CODELOCKS_ACCESS_KEY"] || "wubble"
14
15
  end
15
16
 
16
17
  context "valid lock ID" do
17
- let(:lock_id) { ENV['CODELOCKS_LOCK_ID'] || "valid" }
18
+ let(:lock_id) { ENV["CODELOCKS_LOCK_ID"] || "valid" }
18
19
 
19
20
  around(:each) do |example|
20
21
  VCR.use_cassette("valid_lock_id", erb: true, match_requests_on: [:method]) do
@@ -22,22 +23,22 @@ describe Codelocks::NetCode do
22
23
  end
23
24
  end
24
25
 
25
- it { is_expected.to be_a(Codelocks::NetCode::Response) }
26
+ it { is_expected.to be_a(Codelocks::Response) }
26
27
 
27
28
  it "is successful" do
28
29
  expect(subject.success?).to be true
29
30
  end
30
31
 
31
32
  it "returns a valid netcode" do
32
- expect(subject.netcode).to be_a(String)
33
+ expect(subject.ActualNetcode).to be_a(String)
33
34
  end
34
35
 
35
36
  it "returns a valid starttime" do
36
- expect(subject.starttime).to be_a(String)
37
+ expect(subject.Startdate).to be_a(String)
37
38
  end
38
39
 
39
40
  it "doesn't return an error" do
40
- expect(subject.error).to be nil
41
+ expect(subject.error_message).to be nil
41
42
  end
42
43
  end
43
44
 
@@ -50,28 +51,138 @@ describe Codelocks::NetCode do
50
51
  end
51
52
  end
52
53
 
53
- it { is_expected.to be_a(Codelocks::NetCode::Response) }
54
+ it { is_expected.to be_a(Codelocks::Response) }
54
55
 
55
- it "returns an error" do
56
- expect(subject.error).to be_a(String)
56
+ it "returns an error message" do
57
+ expect(subject.error_message).to be_a(String)
57
58
  end
59
+ end
60
+ end
58
61
 
59
- it "returns an error message" do
60
- expect(subject.message).to be_a(String)
62
+ let(:lock_id) { "001" }
63
+ let(:start) { Time.new(2016, 1, 1, 14, 0, 0) }
64
+ let(:duration) { 0 }
65
+ let(:urm) { false }
66
+
67
+ subject(:netcode) { Codelocks::NetCode.new(lock_id: lock_id, start: start, duration: duration, urm: urm) }
68
+
69
+ describe "#start_date" do
70
+ subject { netcode.start_date }
71
+ it { is_expected.to eq "2016-01-01" }
72
+ end
73
+
74
+ describe "#start_time" do
75
+ subject { netcode.start_time }
76
+
77
+ context "URM disabled and any duration ID" do
78
+ let(:urm) { false }
79
+ before { allow(netcode).to receive(:duration_id) { 31 } }
80
+ it { is_expected.to eq "14:00" }
81
+ end
82
+
83
+ context "URM enabled and duration ID under 31" do
84
+ let(:urm) { true }
85
+ before { allow(netcode).to receive(:duration_id) { 30 } }
86
+ it { is_expected.to eq "14:00" }
87
+ end
88
+
89
+ context "URM enabled and duration ID over 30" do
90
+ let(:urm) { true }
91
+ before { allow(netcode).to receive(:duration_id) { 31 } }
92
+ it { is_expected.to eq "00:00" }
93
+ end
94
+ end
95
+
96
+ describe "#start_datetime" do
97
+ subject { netcode.start_datetime }
98
+ it { is_expected.to eq("2016-01-01 14:00") }
99
+ end
100
+
101
+ describe "#duration_id" do
102
+ context "URM disabled" do
103
+ let(:urm) { false }
104
+
105
+ context "zero duration" do
106
+ it "return 0" do
107
+ allow(netcode).to receive(:duration) { 0 }
108
+ expect(netcode.duration_id).to eq 0
109
+ end
110
+ end
111
+
112
+ context "up to half a day" do
113
+ it "returns minus one from the duration" do
114
+ (1..12).each do |i|
115
+ allow(netcode).to receive(:duration) { i }
116
+ expect(netcode.duration_id).to eq i - 1
117
+ end
118
+ end
119
+ end
120
+
121
+ context "whole days" do
122
+ it "returns number of days counting from 11" do
123
+ (1..7).each do |i|
124
+ allow(netcode).to receive(:duration) { i * 24 }
125
+ expect(netcode.duration_id).to eq 11 + i
126
+ end
127
+ end
128
+ end
129
+
130
+ context "over 7 days" do
131
+ it "returns 18" do
132
+ allow(netcode).to receive(:duration) { 8 * 24 }
133
+ expect(netcode.duration_id).to eq 18
134
+ end
135
+ end
136
+ end
137
+
138
+ context "URM enabled" do
139
+ let(:urm) { true }
140
+
141
+ context "zero duration" do
142
+ it "return 19" do
143
+ allow(netcode).to receive(:duration) { 0 }
144
+ expect(netcode.duration_id).to eq 19
145
+ end
146
+ end
147
+
148
+ context "up to half a day" do
149
+ it "returns 19 minus one from the duration" do
150
+ (1..12).each do |i|
151
+ allow(netcode).to receive(:duration) { i }
152
+ expect(netcode.duration_id).to eq 19 + i - 1
153
+ end
154
+ end
155
+ end
156
+
157
+ context "whole days" do
158
+ it "returns number of days counting from 30" do
159
+ (1..7).each do |i|
160
+ allow(netcode).to receive(:duration) { i * 24 }
161
+ expect(netcode.duration_id).to eq 19 + 11 + i
162
+ end
163
+ end
164
+ end
165
+
166
+ context "over 7 days" do
167
+ it "returns 37" do
168
+ allow(netcode).to receive(:duration) { 8 * 24 }
169
+ expect(netcode.duration_id).to eq 19 + 18
170
+ end
61
171
  end
62
172
  end
63
173
  end
64
174
 
65
- describe '#convert_duration' do
66
- subject { Codelocks::NetCode.send(:convert_duration, duration) }
67
- let(:duration) { rand(0..1000) }
175
+ describe "#urm?" do
176
+ subject { netcode.urm? }
68
177
 
69
- it "doesn't return an error" do
70
- expect { subject }.not_to raise_error
178
+ context "URM disabled" do
179
+ let(:urm) { false }
180
+ it { is_expected.to eq false }
71
181
  end
72
182
 
73
- it "returns an integer" do
74
- expect(subject).to be_a(Integer)
183
+ context "URM enabled" do
184
+ let(:urm) { true }
185
+ it { is_expected.to eq true }
75
186
  end
76
187
  end
77
188
  end
@@ -1,44 +1,40 @@
1
1
  require "spec_helper"
2
2
 
3
- describe Codelocks::NetCode::Request do
3
+ describe Codelocks::Request do
4
4
  before do
5
+ Codelocks.base_uri = "http://wobble.com/"
5
6
  Codelocks.api_key = "wibble"
6
- Codelocks.pairing_id = "wobble"
7
7
  end
8
8
 
9
9
  describe "#create" do
10
- let(:response) { double('faraday_response') }
11
- let(:path) { "netcode/ncgenerator/getnetcode" }
12
10
  let(:params) do
13
- {
14
- id: "lock"
15
- }
11
+ { id: "lock" }
16
12
  end
17
13
 
18
14
  let(:default_params) do
19
- {
20
- api_key: "wibble",
21
- pairing_id: "wobble"
22
- }
15
+ {}
23
16
  end
24
17
 
25
18
  let(:all_params) { default_params.merge(params) }
26
19
 
20
+ let(:response) { double('faraday_response') }
21
+ let(:path) { "netcode/#{params[:id]}" }
22
+
27
23
  before do
28
24
  allow(Codelocks.connection).to receive(:get) { response }
29
- allow(Codelocks::NetCode::Request).to receive(:default_params) { default_params }
25
+ allow(Codelocks::Request).to receive(:default_params) { default_params }
30
26
  end
31
27
 
32
28
 
33
29
  it "performs a get request" do
34
30
  expect(Codelocks.connection).to receive(:get).with(path, all_params)
35
- Codelocks::NetCode::Request.create(path, params)
31
+ Codelocks::Request.create(path, params)
36
32
  end
37
33
 
38
34
  it "returns a response object" do
39
35
  expect(
40
- Codelocks::NetCode::Request.create(path, params)
41
- ).to be_a(Codelocks::NetCode::Response)
36
+ Codelocks::Request.create(path, params)
37
+ ).to be_a(Codelocks::Response)
42
38
  end
43
39
  end
44
40
  end
@@ -1,12 +1,12 @@
1
1
  require "spec_helper"
2
2
 
3
- describe Codelocks::NetCode::Response do
4
- let(:response) { Codelocks::NetCode::Response.new(faraday_response) }
3
+ describe Codelocks::Response do
4
+ let(:response) { Codelocks::Response.new(faraday_response) }
5
5
  let(:faraday_response) { double('faraday_response', success?: true, body: '{"test": "thing"}') }
6
6
 
7
7
  before do
8
+ Codelocks.base_uri = "http://wobble.com/"
8
9
  Codelocks.api_key = "wibble"
9
- Codelocks.pairing_id = "wobble"
10
10
  end
11
11
 
12
12
  describe "#initialize" do
@@ -33,18 +33,11 @@ describe Codelocks::NetCode::Response do
33
33
 
34
34
  describe "#body" do
35
35
  subject { response.body }
36
+ it { is_expected.to be_a(Hash) }
37
+ end
36
38
 
37
- context "success? is true" do
38
- before { allow(faraday_response).to receive(:success?) { true } }
39
-
40
- it { is_expected.to be_a(Hash) }
41
- end
42
-
43
- context "success? is false" do
44
- before { allow(faraday_response).to receive(:success?) { false } }
45
-
46
- it { is_expected.to be nil }
47
- end
39
+ describe "#error_message" do
40
+ #TODO
48
41
  end
49
42
 
50
43
  describe "#method_missing" do
@@ -4,7 +4,21 @@ describe Codelocks do
4
4
  describe "#base_uri" do
5
5
  subject { Codelocks.base_uri }
6
6
 
7
- it { is_expected.to be_a(String) }
7
+ before { allow(ENV).to receive(:[]) { nil } }
8
+
9
+ context "is present" do
10
+ before { Codelocks.base_uri = "test" }
11
+
12
+ it { is_expected.to eq("test") }
13
+ end
14
+
15
+ context "is not present" do
16
+ before { Codelocks.base_uri = nil }
17
+
18
+ it "raises an exception" do
19
+ expect { subject }.to raise_error(Codelocks::CodelocksError)
20
+ end
21
+ end
8
22
  end
9
23
 
10
24
  describe "#api_key" do
@@ -27,26 +41,25 @@ describe Codelocks do
27
41
  end
28
42
  end
29
43
 
30
- describe "#pairing_id" do
31
- subject { Codelocks.pairing_id }
44
+ describe "#access_key" do
45
+ subject { Codelocks.access_key }
32
46
 
33
47
  before { allow(ENV).to receive(:[]) { nil } }
34
48
 
35
49
  context "is present" do
36
- before { Codelocks.pairing_id = "test" }
50
+ before { Codelocks.access_key = "test" }
37
51
 
38
52
  it { is_expected.to eq("test") }
39
53
  end
40
54
 
41
55
  context "is not present" do
42
- before { Codelocks.pairing_id = nil }
56
+ before { Codelocks.access_key = nil }
43
57
 
44
- it "raises an exception" do
45
- expect { subject }.to raise_error(Codelocks::CodelocksError)
46
- end
58
+ it { is_expected.to eq(nil) }
47
59
  end
48
60
  end
49
61
 
62
+
50
63
  describe "#connection" do
51
64
  subject { Codelocks.connection }
52
65
 
@@ -0,0 +1,40 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: "<BASE_URI>/lock?accesskey=<ACCESS_KEY>"
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.9.2
12
+ x-api-key:
13
+ - "<API_KEY>"
14
+ response:
15
+ status:
16
+ code: 401
17
+ message:
18
+ headers:
19
+ content-type:
20
+ - application/json
21
+ content-length:
22
+ - '0'
23
+ connection:
24
+ - close
25
+ date:
26
+ - Thu, 26 May 2016 12:25:28 GMT
27
+ x-amzn-requestid:
28
+ - ee1e1ebc-233c-11e6-90fb-e7ebd021b93a
29
+ x-cache:
30
+ - Error from cloudfront
31
+ via:
32
+ - 1.1 b24665a554e30571f85b913251577ced.cloudfront.net (CloudFront)
33
+ x-amz-cf-id:
34
+ - 1JTnbI60plpNMGMqU_lc7t2jr03ZA6qd65GjG7VjBFI1izgkpWqIow==
35
+ body:
36
+ encoding: UTF-8
37
+ string: ''
38
+ http_version:
39
+ recorded_at: Thu, 26 May 2016 12:25:28 GMT
40
+ recorded_with: VCR 2.9.3
@@ -2,42 +2,39 @@
2
2
  http_interactions:
3
3
  - request:
4
4
  method: get
5
- uri: https://api-2445581366752.apicast.io/api/v3/netcode/ncgenerator/getnetcode?user_key=<%= ENV['CODELOCKS_API_KEY'] || "wibble" %>&pid=<%= ENV['CODELOCKS_PAIRING_ID'] || "wobble" %>&id=Ninvalid&sd=20%2F10%2F2015&st=17&du=0
5
+ uri: "<BASE_URI>/netcode/invalid?id=invalid&start=2016-05-26+14%3A23&duration=0&lockmodel=K3CONNECT&identifier=<ACCESS_KEY>"
6
6
  body:
7
7
  encoding: US-ASCII
8
8
  string: ''
9
9
  headers:
10
10
  User-Agent:
11
11
  - Faraday v0.8.11
12
+ x-api-key:
13
+ - "<API_KEY>"
12
14
  response:
13
15
  status:
14
- code: 200
16
+ code: 400
15
17
  message:
16
18
  headers:
17
- cache-control:
18
- - no-store, no-cache, must-revalidate, post-check=0, pre-check=0
19
19
  content-type:
20
- - text/html; charset=UTF-8
21
- date:
22
- - Tue, 20 Oct 2015 16:08:07 GMT
23
- expires:
24
- - Thu, 19 Nov 1981 08:52:00 GMT
25
- pragma:
26
- - no-cache
27
- server:
28
- - openresty/1.5.11.1
29
- set-cookie:
30
- - cpt=6f3e912e9b229f18247850a374fb632aba7dcdcb; expires=Tue, 20-Oct-2015 18:08:20
31
- GMT; path=/; HttpOnly
32
- x-powered-by:
33
- - ASP.NET, 3scale API Management - http://www.3scale.net
20
+ - application/json
34
21
  content-length:
35
- - '76'
22
+ - '69'
36
23
  connection:
37
- - Close
24
+ - close
25
+ date:
26
+ - Thu, 26 May 2016 13:23:14 GMT
27
+ x-amzn-requestid:
28
+ - 0049c971-2345-11e6-b022-a34fe19ecf32
29
+ x-cache:
30
+ - Error from cloudfront
31
+ via:
32
+ - 1.1 77bdacfea247b6cbe84dffa90da5a554.cloudfront.net (CloudFront)
33
+ x-amz-cf-id:
34
+ - 18E863E-jYTMX-cnjhtKxk5tHW7KtAGh9SQutjmZSYhad-42blmbsw==
38
35
  body:
39
36
  encoding: UTF-8
40
- string: '{"error":"Lock not found","message":"Please check the identifier provided."}'
37
+ string: '{"Message":"[\"[Invalid Data] ID (Expected: 12 or 32 characters)\"]"}'
41
38
  http_version:
42
- recorded_at: Tue, 20 Oct 2015 16:08:07 GMT
39
+ recorded_at: Thu, 26 May 2016 13:23:14 GMT
43
40
  recorded_with: VCR 2.9.3
@@ -0,0 +1,42 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: "<BASE_URI>/lock?accesskey=<ACCESS_KEY>"
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.9.2
12
+ x-api-key:
13
+ - "<API_KEY>"
14
+ response:
15
+ status:
16
+ code: 200
17
+ message:
18
+ headers:
19
+ content-type:
20
+ - application/json
21
+ content-length:
22
+ - '5248'
23
+ connection:
24
+ - close
25
+ date:
26
+ - Thu, 26 May 2016 12:25:27 GMT
27
+ access-control-allow-origin:
28
+ - "*"
29
+ x-amzn-requestid:
30
+ - ed3d5b8d-233c-11e6-abb5-dd54f7056380
31
+ x-cache:
32
+ - Miss from cloudfront
33
+ via:
34
+ - 1.1 421be81da20d58871d64dfde02cb2c46.cloudfront.net (CloudFront)
35
+ x-amz-cf-id:
36
+ - oppo1gBUyNzCnsGnsO8X4GZQZJxBinpZuOOjO34tKnj_hTbfvGWixQ==
37
+ body:
38
+ encoding: UTF-8
39
+ string: '[{"LockId":"<LOCK_ID>","LockName":"<LOCK_NAME>","BatteryStatus":"FULL","BatteryUpdated":"2016-05-24T00:00:00","Manufacturer":"CODELOCKS","ModelName":"<MODEL_NAME>","FirmwareVersion":"1.0.2","Timezone":"Europe/London","TimezoneOffset":"+0100","DstStart":"2016-03-27T00:00:00","DstEnd":"2016-10-30T00:00:00","DstTime":"01:00","PairingDate":"2016-05-24T00:00:00"},{"LockId":"<LOCK_ID>","LockName":"<LOCK_NAME>","BatteryStatus":"UNKNOWN","BatteryUpdated":"1970-01-01T00:00:00","Manufacturer":"CODELOCKS","ModelName":"<MODEL_NAME>","FirmwareVersion":"1.0.2","Timezone":"Europe/London","TimezoneOffset":"+0100","DstStart":"2016-03-27T00:00:00","DstEnd":"2016-10-30T00:00:00","DstTime":"01:00","PairingDate":"2016-05-05T00:00:00"},{"LockId":"<LOCK_ID>","LockName":"<LOCK_NAME>","BatteryStatus":"FULL","BatteryUpdated":"2016-05-23T00:00:00","Manufacturer":"CODELOCKS","ModelName":"<MODEL_NAME>","FirmwareVersion":"1.0.2","Timezone":"Europe/London","TimezoneOffset":"+0100","DstStart":"2016-03-27T00:00:00","DstEnd":"2016-10-30T00:00:00","DstTime":"01:00","PairingDate":"2016-05-23T00:00:00"}]'
40
+ http_version:
41
+ recorded_at: Thu, 26 May 2016 12:25:27 GMT
42
+ recorded_with: VCR 2.9.3
@@ -2,42 +2,39 @@
2
2
  http_interactions:
3
3
  - request:
4
4
  method: get
5
- uri: https://api-2445581366752.apicast.io/api/v3/netcode/ncgenerator/getnetcode?user_key=<%= ENV['CODELOCKS_API_KEY'] || "wibble" %>&pid=<%= ENV['CODELOCKS_PAIRING_ID'] || "wobble" %>&id=N<%= ENV['CODELOCKS_LOCK_ID'] || "valid" %>&sd=20%2F10%2F2015&st=17&du=0
5
+ uri: "<BASE_URI>/netcode/LOCK_ID?id=LOCK_ID&start=2016-05-26+14%3A22&duration=0&lockmodel=K3CONNECT&identifier=<ACCESS_KEY>"
6
6
  body:
7
7
  encoding: US-ASCII
8
8
  string: ''
9
9
  headers:
10
10
  User-Agent:
11
11
  - Faraday v0.8.11
12
+ x-api-key:
13
+ - "<API_KEY>"
12
14
  response:
13
15
  status:
14
16
  code: 200
15
17
  message:
16
18
  headers:
17
- cache-control:
18
- - no-store, no-cache, must-revalidate, post-check=0, pre-check=0
19
19
  content-type:
20
20
  - application/json
21
- date:
22
- - Tue, 20 Oct 2015 16:08:05 GMT
23
- expires:
24
- - Thu, 19 Nov 1981 08:52:00 GMT
25
- pragma:
26
- - no-cache
27
- server:
28
- - openresty/1.5.11.1
29
- set-cookie:
30
- - cpt=30457e50b3e443bcd1407f77f7b39d71df699388; expires=Tue, 20-Oct-2015 18:08:19
31
- GMT; path=/; HttpOnly
32
- x-powered-by:
33
- - ASP.NET, 3scale API Management - http://www.3scale.net
34
21
  content-length:
35
- - '53'
22
+ - '213'
36
23
  connection:
37
- - Close
24
+ - close
25
+ date:
26
+ - Thu, 26 May 2016 13:22:19 GMT
27
+ x-amzn-requestid:
28
+ - dea40c96-2344-11e6-bba4-25d390521298
29
+ x-cache:
30
+ - Miss from cloudfront
31
+ via:
32
+ - 1.1 968f3ab48a1dd74b47de55452b46203d.cloudfront.net (CloudFront)
33
+ x-amz-cf-id:
34
+ - irPt9j9LX0JKOdnk809FtOnBaEdgV-oyvUxJRxbBmQuprkmDVkSTDA==
38
35
  body:
39
36
  encoding: UTF-8
40
- string: '{"netcode":"000000","starttime":"2015\/10\/20\/17:0"}'
37
+ string: '{"Startdate":"2016-05-26T14:00:00","DurationHours":1,"DurationDays":0,"Mode":"standard","SubMode":"alltime","Timecode":null,"ActualNetcode":"178627","Resultstatus":null,"LockId":"LOCK_ID"}'
41
38
  http_version:
42
- recorded_at: Tue, 20 Oct 2015 16:08:05 GMT
39
+ recorded_at: Thu, 26 May 2016 13:22:19 GMT
43
40
  recorded_with: VCR 2.9.3
data/spec/spec_helper.rb CHANGED
@@ -3,11 +3,13 @@ Dotenv.load
3
3
 
4
4
  require "codelocks"
5
5
  require "vcr"
6
+ require "pry"
6
7
 
7
8
  VCR.configure do |config|
8
9
  config.cassette_library_dir = "spec/fixtures/vcr_cassettes"
9
10
  config.hook_into :faraday
11
+ config.filter_sensitive_data("<BASE_URI>") { Codelocks.base_uri }
10
12
  config.filter_sensitive_data("<API_KEY>") { Codelocks.api_key }
11
- config.filter_sensitive_data("<PAIRING_ID>") { Codelocks.pairing_id }
12
- config.filter_sensitive_data("<LOCK_ID>") { ENV['CODELOCKS_LOCK_ID'] }
13
+ config.filter_sensitive_data("<ACCESS_KEY>") { Codelocks.access_key }
14
+ config.filter_sensitive_data("LOCK_ID") { ENV['CODELOCKS_LOCK_ID'] }
13
15
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codelocks
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert May
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-21 00:00:00.000000000 Z
11
+ date: 2016-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '2.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: faraday
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -102,21 +116,26 @@ extensions: []
102
116
  extra_rdoc_files: []
103
117
  files:
104
118
  - ".gitignore"
119
+ - ".ruby-version"
105
120
  - Gemfile
106
121
  - LICENSE.txt
107
122
  - README.md
108
123
  - Rakefile
109
124
  - codelocks.gemspec
110
125
  - lib/codelocks.rb
126
+ - lib/codelocks/lock.rb
111
127
  - lib/codelocks/net_code.rb
112
- - lib/codelocks/net_code/request.rb
113
- - lib/codelocks/net_code/response.rb
128
+ - lib/codelocks/request.rb
129
+ - lib/codelocks/response.rb
114
130
  - lib/codelocks/version.rb
115
- - spec/codelocks/net_code/request_spec.rb
116
- - spec/codelocks/net_code/response_spec.rb
131
+ - spec/codelocks/lock_spec.rb
117
132
  - spec/codelocks/net_code_spec.rb
133
+ - spec/codelocks/request_spec.rb
134
+ - spec/codelocks/response_spec.rb
118
135
  - spec/codelocks_spec.rb
136
+ - spec/fixtures/vcr_cassettes/invalid_access_key.yml
119
137
  - spec/fixtures/vcr_cassettes/invalid_lock_id.yml
138
+ - spec/fixtures/vcr_cassettes/valid_access_key.yml
120
139
  - spec/fixtures/vcr_cassettes/valid_lock_id.yml
121
140
  - spec/spec_helper.rb
122
141
  homepage: http://www.codelocks.co.uk
@@ -144,11 +163,14 @@ signing_key:
144
163
  specification_version: 4
145
164
  summary: A simple API wrapper for the CodeLocks API
146
165
  test_files:
147
- - spec/codelocks/net_code/request_spec.rb
148
- - spec/codelocks/net_code/response_spec.rb
166
+ - spec/codelocks/lock_spec.rb
149
167
  - spec/codelocks/net_code_spec.rb
168
+ - spec/codelocks/request_spec.rb
169
+ - spec/codelocks/response_spec.rb
150
170
  - spec/codelocks_spec.rb
171
+ - spec/fixtures/vcr_cassettes/invalid_access_key.yml
151
172
  - spec/fixtures/vcr_cassettes/invalid_lock_id.yml
173
+ - spec/fixtures/vcr_cassettes/valid_access_key.yml
152
174
  - spec/fixtures/vcr_cassettes/valid_lock_id.yml
153
175
  - spec/spec_helper.rb
154
176
  has_rdoc:
@@ -1,34 +0,0 @@
1
- module Codelocks
2
- module NetCode
3
- class Request
4
- class << self
5
- # Perform a request against the NetCode API
6
- #
7
- # @param [String] path the URI path to perform the request against
8
- # @param [Hash] params
9
- # @option params [String] :sd The start date in format dd/mm/yyyy
10
- # @option params [String] :st The start time, 0 spaced: 00-23
11
- # @option params [Integer] :duration The duration for the code to be valid for
12
- #
13
- # @return [Codelocks::NetCode::Response]
14
-
15
- def create(path, params = {})
16
- response = Codelocks.connection.get(path, default_params.merge(params))
17
- Response.new(response)
18
- end
19
-
20
- private
21
- # The default params used in NetCode endpoint requests
22
- #
23
- # @return [Hash]
24
-
25
- def default_params
26
- {
27
- user_key: Codelocks.api_key,
28
- pid: Codelocks.pairing_id,
29
- }
30
- end
31
- end
32
- end
33
- end
34
- end
@@ -1,43 +0,0 @@
1
- require "json"
2
-
3
- module Codelocks
4
- module NetCode
5
- class Response
6
- attr_reader :response
7
-
8
- # Initialize the response object
9
- #
10
- # @param [Faraday::Response] faraday_response
11
-
12
- def initialize(faraday_response)
13
- @response = faraday_response
14
- end
15
-
16
- # Was the request successful?
17
- #
18
- # @return [Truthy]
19
-
20
- def success?
21
- response.success?
22
- end
23
-
24
- # Parse the response from the server if successful
25
- #
26
- # @return [Hash,Nil]
27
-
28
- def body
29
- if success?
30
- @body ||= JSON.parse(response.body)
31
- end
32
- end
33
-
34
- # Simple method missing accessor for reading returned attributes
35
- #
36
- # @return [String] the raw returned string from the API
37
-
38
- def method_missing(method_name, *opts, &block)
39
- body[method_name.to_s]
40
- end
41
- end
42
- end
43
- end