clever-ruby 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,6 @@
1
1
  require 'rest_client'
2
2
  require 'multi_json'
3
+ require 'open-uri'
3
4
 
4
5
  require 'clever-ruby/version'
5
6
 
@@ -23,8 +24,11 @@ require 'clever-ruby/event'
23
24
 
24
25
  # Errors
25
26
  require 'clever-ruby/errors/clever_error'
26
- require 'clever-ruby/errors/authentication_error'
27
+
28
+ require 'clever-ruby/errors/api_connection_error'
27
29
  require 'clever-ruby/errors/api_error'
30
+ require 'clever-ruby/errors/authentication_error'
31
+ require 'clever-ruby/errors/invalid_request_error'
28
32
 
29
33
  module Clever
30
34
  class << self
@@ -49,6 +53,16 @@ module Clever
49
53
  end
50
54
  end
51
55
 
56
+ def self.convert_to_query_string(params = nil)
57
+ if params && params.count
58
+ "?" + Util.flatten_params(params).collect { |p|
59
+ "#{URI::encode(p[0].to_s)}=#{URI::encode(p[1].to_s)}"
60
+ }.join('&')
61
+ else
62
+ ''
63
+ end
64
+ end
65
+
52
66
  def self.request(method, url, params=nil, headers={})
53
67
  raise AuthenticationError.new('No API key provided. (HINT: set your API key using "Clever.configure { |config| config.api_key = <API-KEY> }")') unless Clever.api_key
54
68
 
@@ -57,11 +71,7 @@ module Clever
57
71
 
58
72
  case method.to_s.downcase.to_sym
59
73
  when :get, :head, :delete
60
- # Make params into GET parameters
61
- if params && params.count
62
- query_string = Util.flatten_params(params).collect{|p| "#{p[0]}=#{p[1]}"}.join('&')
63
- url += "?#{query_string}"
64
- end
74
+ url += convert_to_query_string(params)
65
75
  payload = nil
66
76
  else
67
77
  payload = params
@@ -123,7 +133,7 @@ module Clever
123
133
  def self.handle_restclient_error(e)
124
134
  case e
125
135
  when RestClient::ServerBrokeConnection, RestClient::RequestTimeout
126
- message = "Could not connect to Clever (#{@@api_base}). Please check your internet connection and try again."
136
+ message = "Could not connect to Clever (#{configuration.api_base}). Please check your internet connection and try again."
127
137
  when SocketError
128
138
  message = "Unexpected error communicating when trying to connect to Clever. HINT: You may be seeing this message because your DNS is not working. To check, try running 'host getclever.com' from the command line."
129
139
  else
@@ -153,7 +163,11 @@ module Clever
153
163
  end
154
164
 
155
165
  def self.invalid_request_error(error, rcode, rbody, error_obj)
156
- InvalidRequestError.new(error[:message], error[:param], rcode, rbody, error_obj)
166
+ if error.is_a? Hash
167
+ InvalidRequestError.new(error[:message], error[:param], rcode, rbody, error_obj)
168
+ else
169
+ InvalidRequestError.new(error, '', rcode, rbody, error_obj)
170
+ end
157
171
  end
158
172
 
159
173
  def self.authentication_error(error, rcode, rbody, error_obj)
@@ -3,7 +3,7 @@ module Clever
3
3
  include Clever::APIOperations::List
4
4
 
5
5
  def optional_attributes
6
- [:previous_attributes]
6
+ []
7
7
  end
8
8
 
9
9
  def object
@@ -12,6 +12,10 @@ module Clever
12
12
  klass.construct_from(data[:object])
13
13
  end
14
14
 
15
+ def previous_attributes
16
+ data[:previous_attributes]
17
+ end
18
+
15
19
  def action
16
20
  type_pieces[1]
17
21
  end
@@ -1,3 +1,3 @@
1
1
  module Clever
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -0,0 +1,184 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://DEMO_KEY:@api.getclever.com/v1.1/districts?
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - ! '*/*; q=0.5, application/xml'
12
+ Accept-Encoding:
13
+ - gzip, deflate
14
+ User-Agent:
15
+ - Ruby
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Access-Control-Allow-Headers:
22
+ - Content-Type,Authorization,X-Requested-With,Accept,Origin,Referer,User-Agent
23
+ Access-Control-Allow-Methods:
24
+ - GET,PUT,POST,DELETE
25
+ Access-Control-Allow-Origin:
26
+ - ! '*'
27
+ Cache-Control:
28
+ - no-cache="set-cookie"
29
+ Content-Type:
30
+ - application/json; charset=utf-8
31
+ Date:
32
+ - Tue, 26 Mar 2013 17:09:46 GMT
33
+ Server:
34
+ - nginx/1.2.7
35
+ Set-Cookie:
36
+ - AWSELB=A91137730E0ED0C3FE64858C01B7DE99906AE563A8CD7BD1CCF9B10870E96BC42024E91EFF14E7F99B23B8AEDFFF8573F9B41FB375FD4A8FC6C6CAF12129D54C280B596A87;PATH=/;MAX-AGE=300
37
+ X-Powered-By:
38
+ - Express
39
+ Content-Length:
40
+ - '174'
41
+ Connection:
42
+ - keep-alive
43
+ body:
44
+ encoding: US-ASCII
45
+ string: ! '{"data":[{"data":{"name":"Demo District","id":"4fd43cc56d11340000000005"},"uri":"/v1.1/districts/4fd43cc56d11340000000005"}],"links":[{"rel":"self","uri":"/v1.1/districts"}]}'
46
+ http_version:
47
+ recorded_at: Tue, 26 Mar 2013 17:09:35 GMT
48
+ - request:
49
+ method: get
50
+ uri: https://DEMO_KEY:@api.getclever.com/v1.1/districts/4fd43cc56d11340000000005
51
+ body:
52
+ encoding: US-ASCII
53
+ string: ''
54
+ headers:
55
+ Accept:
56
+ - ! '*/*; q=0.5, application/xml'
57
+ Accept-Encoding:
58
+ - gzip, deflate
59
+ User-Agent:
60
+ - Ruby
61
+ response:
62
+ status:
63
+ code: 200
64
+ message: OK
65
+ headers:
66
+ Access-Control-Allow-Headers:
67
+ - Content-Type,Authorization,X-Requested-With,Accept,Origin,Referer,User-Agent
68
+ Access-Control-Allow-Methods:
69
+ - GET,PUT,POST,DELETE
70
+ Access-Control-Allow-Origin:
71
+ - ! '*'
72
+ Cache-Control:
73
+ - no-cache="set-cookie"
74
+ Content-Type:
75
+ - application/json; charset=utf-8
76
+ Date:
77
+ - Tue, 26 Mar 2013 17:09:46 GMT
78
+ Server:
79
+ - nginx/1.2.7
80
+ Set-Cookie:
81
+ - AWSELB=A91137730E0ED0C3FE64858C01B7DE99906AE563A8CD7BD1CCF9B10870E96BC42024E91EFF14E7F99B23B8AEDFFF8573F9B41FB375FD4A8FC6C6CAF12129D54C280B596A87;PATH=/;MAX-AGE=300
82
+ X-Powered-By:
83
+ - Express
84
+ Content-Length:
85
+ - '599'
86
+ Connection:
87
+ - keep-alive
88
+ body:
89
+ encoding: US-ASCII
90
+ string: ! '{"data":{"name":"Demo District","id":"4fd43cc56d11340000000005"},"links":[{"rel":"self","uri":"/v1.1/districts/4fd43cc56d11340000000005"},{"rel":"schools","uri":"/v1.1/districts/4fd43cc56d11340000000005/schools"},{"rel":"teachers","uri":"/v1.1/districts/4fd43cc56d11340000000005/teachers"},{"rel":"students","uri":"/v1.1/districts/4fd43cc56d11340000000005/students"},{"rel":"sections","uri":"/v1.1/districts/4fd43cc56d11340000000005/sections"},{"rel":"properties","uri":"/v1.1/districts/4fd43cc56d11340000000005/properties"},{"rel":"events","uri":"/v1.1/districts/4fd43cc56d11340000000005/events"}]}'
91
+ http_version:
92
+ recorded_at: Tue, 26 Mar 2013 17:09:36 GMT
93
+ - request:
94
+ method: get
95
+ uri: https://DEMO_KEY:@api.getclever.com/v1.1/districts/4fd43cc56d11340000000005
96
+ body:
97
+ encoding: US-ASCII
98
+ string: ''
99
+ headers:
100
+ Accept:
101
+ - ! '*/*; q=0.5, application/xml'
102
+ Accept-Encoding:
103
+ - gzip, deflate
104
+ User-Agent:
105
+ - Ruby
106
+ response:
107
+ status:
108
+ code: 200
109
+ message: OK
110
+ headers:
111
+ Access-Control-Allow-Headers:
112
+ - Content-Type,Authorization,X-Requested-With,Accept,Origin,Referer,User-Agent
113
+ Access-Control-Allow-Methods:
114
+ - GET,PUT,POST,DELETE
115
+ Access-Control-Allow-Origin:
116
+ - ! '*'
117
+ Cache-Control:
118
+ - no-cache="set-cookie"
119
+ Content-Type:
120
+ - application/json; charset=utf-8
121
+ Date:
122
+ - Tue, 26 Mar 2013 17:09:46 GMT
123
+ Server:
124
+ - nginx/1.2.7
125
+ Set-Cookie:
126
+ - AWSELB=A91137730E0ED0C3FE64858C01B7DE99906AE563A8CD7BD1CCF9B10870E96BC42024E91EFF14E7F99B23B8AEDFFF8573F9B41FB375FD4A8FC6C6CAF12129D54C280B596A87;PATH=/;MAX-AGE=300
127
+ X-Powered-By:
128
+ - Express
129
+ Content-Length:
130
+ - '599'
131
+ Connection:
132
+ - keep-alive
133
+ body:
134
+ encoding: US-ASCII
135
+ string: ! '{"data":{"name":"Demo District","id":"4fd43cc56d11340000000005"},"links":[{"rel":"self","uri":"/v1.1/districts/4fd43cc56d11340000000005"},{"rel":"schools","uri":"/v1.1/districts/4fd43cc56d11340000000005/schools"},{"rel":"teachers","uri":"/v1.1/districts/4fd43cc56d11340000000005/teachers"},{"rel":"students","uri":"/v1.1/districts/4fd43cc56d11340000000005/students"},{"rel":"sections","uri":"/v1.1/districts/4fd43cc56d11340000000005/sections"},{"rel":"properties","uri":"/v1.1/districts/4fd43cc56d11340000000005/properties"},{"rel":"events","uri":"/v1.1/districts/4fd43cc56d11340000000005/events"}]}'
136
+ http_version:
137
+ recorded_at: Tue, 26 Mar 2013 17:09:36 GMT
138
+ - request:
139
+ method: get
140
+ uri: https://DEMO_KEY:@api.getclever.com//v1.1/districts/4fd43cc56d11340000000005/events?created_since=2013-02-15T%202:30:42%200000
141
+ body:
142
+ encoding: US-ASCII
143
+ string: ''
144
+ headers:
145
+ Accept:
146
+ - ! '*/*; q=0.5, application/xml'
147
+ Accept-Encoding:
148
+ - gzip, deflate
149
+ User-Agent:
150
+ - Ruby
151
+ response:
152
+ status:
153
+ code: 400
154
+ message: Bad Request
155
+ headers:
156
+ Access-Control-Allow-Headers:
157
+ - Content-Type,Authorization,X-Requested-With,Accept,Origin,Referer,User-Agent
158
+ Access-Control-Allow-Methods:
159
+ - GET,PUT,POST,DELETE
160
+ Access-Control-Allow-Origin:
161
+ - ! '*'
162
+ Cache-Control:
163
+ - no-cache="set-cookie"
164
+ Content-Type:
165
+ - application/json; charset=utf-8
166
+ Date:
167
+ - Tue, 26 Mar 2013 17:09:47 GMT
168
+ Server:
169
+ - nginx/1.2.7
170
+ Set-Cookie:
171
+ - AWSELB=A91137730E0ED0C3FE64858C01B7DE99906AE563A8CD7BD1CCF9B10870E96BC42024E91EFF14E7F99B23B8AEDFFF8573F9B41FB375FD4A8FC6C6CAF12129D54C280B596A87;PATH=/;MAX-AGE=300
172
+ X-Powered-By:
173
+ - Express
174
+ Content-Length:
175
+ - '174'
176
+ Connection:
177
+ - keep-alive
178
+ body:
179
+ encoding: US-ASCII
180
+ string: ! '{"error":"Could not parse created_since ''2013-02-15T 2:30:42 0000''.
181
+ Please ensure it is either a valid ObjectID or a valid W3C datetime: http://www.w3.org/TR/NOTE-datetime."}'
182
+ http_version:
183
+ recorded_at: Tue, 26 Mar 2013 17:09:36 GMT
184
+ recorded_with: VCR 2.4.0
@@ -0,0 +1,18 @@
1
+ require 'test_helper'
2
+
3
+ class ErrorHandlingTest < Test::Unit::TestCase
4
+ def setup
5
+ Clever.configure do |config|
6
+ config.api_key = "DEMO_KEY"
7
+ end
8
+ end
9
+
10
+ should "raise an InvalidRequestError when given a bad created_since" do
11
+ VCR.use_cassette("error_handling") do
12
+ @district = Clever::District.all.first
13
+ lambda {
14
+ @district.events(created_since: '2013-02-15T 2:30:42 0000')
15
+ }.must_raise Clever::InvalidRequestError
16
+ end
17
+ end
18
+ end
@@ -14,4 +14,11 @@ class CleverTest < Test::Unit::TestCase
14
14
  assert_equal("https://api.getclever.com/v1.1/sections", Clever.resource_url("sections"))
15
15
  assert_equal("https://api.getclever.com/v1.1/teachers", Clever.resource_url("teachers"))
16
16
  end
17
+
18
+ should "uri-encode params" do
19
+ query_string = Clever.convert_to_query_string({
20
+ created_at: '2013-02-15T 2:30:42Z'
21
+ })
22
+ query_string.must_equal "?created_at=2013-02-15T%202:30:42Z"
23
+ end
17
24
  end
@@ -11,6 +11,20 @@ class EventTest < Test::Unit::TestCase
11
11
  },
12
12
  id: "512bb9f2ca5e6fa775061340"
13
13
  })
14
+
15
+ @updated_event = Clever::Event.construct_from({
16
+ type: "sections.updated",
17
+ data: {
18
+ object: {
19
+ id: "510980c2923bcbba1f0ce5dd"
20
+ },
21
+ previous_attributes: {
22
+ teacher: "510980a6923bcbba1f0cb500",
23
+ last_modified: "2013-03-11T15:38:58.558Z"
24
+ }
25
+ },
26
+ id: "514767bf80833fb55b1c2dd7"
27
+ })
14
28
  end
15
29
 
16
30
  should "create a clever object for the object the event is about" do
@@ -20,4 +34,12 @@ class EventTest < Test::Unit::TestCase
20
34
  should "know what action the event is about (created/updated/deleted)" do
21
35
  @event.action.must_equal "created"
22
36
  end
37
+
38
+ should "have an empty hash if there aren't previous attributes" do
39
+ @event.previous_attributes.must_equal {}
40
+ end
41
+
42
+ should "have an event's previous attributes" do
43
+ @updated_event.previous_attributes[:teacher].must_equal "510980a6923bcbba1f0cb500"
44
+ end
23
45
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clever-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-03-13 00:00:00.000000000 Z
13
+ date: 2013-03-28 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: multi_json
@@ -181,6 +181,7 @@ files:
181
181
  - test/data/vcr_cassettes/districts_students.yml
182
182
  - test/data/vcr_cassettes/districts_students_filtered.yml
183
183
  - test/data/vcr_cassettes/districts_teachers.yml
184
+ - test/data/vcr_cassettes/error_handling.yml
184
185
  - test/data/vcr_cassettes/schools.yml
185
186
  - test/data/vcr_cassettes/schools_optional_attributes.yml
186
187
  - test/data/vcr_cassettes/sections.yml
@@ -188,6 +189,7 @@ files:
188
189
  - test/data/vcr_cassettes/teachers.yml
189
190
  - test/integration/api_operations/list_test.rb
190
191
  - test/integration/district_test.rb
192
+ - test/integration/error_handling_test.rb
191
193
  - test/test_helper.rb
192
194
  - test/unit/clever_test.rb
193
195
  - test/unit/configuration_test.rb
@@ -225,6 +227,7 @@ test_files:
225
227
  - test/data/vcr_cassettes/districts_students.yml
226
228
  - test/data/vcr_cassettes/districts_students_filtered.yml
227
229
  - test/data/vcr_cassettes/districts_teachers.yml
230
+ - test/data/vcr_cassettes/error_handling.yml
228
231
  - test/data/vcr_cassettes/schools.yml
229
232
  - test/data/vcr_cassettes/schools_optional_attributes.yml
230
233
  - test/data/vcr_cassettes/sections.yml
@@ -232,6 +235,7 @@ test_files:
232
235
  - test/data/vcr_cassettes/teachers.yml
233
236
  - test/integration/api_operations/list_test.rb
234
237
  - test/integration/district_test.rb
238
+ - test/integration/error_handling_test.rb
235
239
  - test/test_helper.rb
236
240
  - test/unit/clever_test.rb
237
241
  - test/unit/configuration_test.rb