codelocks 1.0.1 → 2.0.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 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