google_calendar 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,48 @@
1
+ {
2
+ "kind": "calendar#events",
3
+ "defaultReminders": [],
4
+ "description": "My Personal Events Calendar",
5
+ "items": [
6
+ {
7
+ "status": "confirmed",
8
+ "kind": "calendar#event",
9
+ "end": {
10
+ "timeZone": "America/Los_Angeles",
11
+ "dateTime": "2014-11-15T18:00:00-08:00"
12
+ },
13
+ "created": "2014-11-17T00:45:30.000Z",
14
+ "iCalUID": "fhru34kt6ikmr20knd2456l08n@google.com",
15
+ "reminders": {
16
+ "useDefault": true
17
+ },
18
+ "htmlLink": "https://www.google.com/calendar/event?eid=MjRmNHZhY2pzY3A1YjB0NHE2OThoMGs2YXNfMjAxNDExMTZUMDEwMDAwWiBncWViMGk2djczN2tmdTVtZDBmM2V1a2psZ0Bn",
19
+ "sequence": 0,
20
+ "updated": "2014-11-17T00:45:30.431Z",
21
+ "summary": "Test Repeating Events",
22
+ "recurrence": [
23
+ "RRULE:FREQ=DAILY;COUNT=3"
24
+ ],
25
+ "start": {
26
+ "timeZone": "America/Los_Angeles",
27
+ "dateTime": "2014-11-15T17:00:00-08:00"
28
+ },
29
+ "etag": "\"2832370260862000\"",
30
+ "organizer": {
31
+ "self": true,
32
+ "displayName": "Some Person",
33
+ "email": "some.person@gmail.com"
34
+ },
35
+ "creator": {
36
+ "displayName": "Some Person",
37
+ "email": "some.person@gmail.com"
38
+ },
39
+ "id": "fhru34kt6ikmr20knd2456l08n"
40
+ }
41
+ ],
42
+ "updated": "2014-11-17T00:45:30.522Z",
43
+ "summary": "My Events Calendar",
44
+ "etag": "\"1416185130522000\"",
45
+ "nextSyncToken": "AKi8uge987ECEIjyiZnV_cECGAU=",
46
+ "timeZone": "America/Los_Angeles",
47
+ "accessRole": "owner"
48
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "access_token": "ya29.hYjPO0uHt63uWr5qmQtMEReZEvILcdGlPCOHDy6quKPyEQaQQvqaVAlLAVASaRm_O0a7vkZ91T8xyQ",
3
+ "token_type": "Bearer",
4
+ "expires_in": 3600,
5
+ "refresh_token": "1/aJUy7pQzc4fUMX89BMMLeAfKcYteBKRMpQvf4fQFX0"
6
+ }
@@ -1,199 +1,183 @@
1
1
  require 'helper'
2
2
 
3
- class TestGoogleCalendar < Test::Unit::TestCase
3
+ class TestGoogleCalendar < Minitest::Test
4
4
  include Google
5
5
 
6
- context "Connected" do
6
+ context "When connected" do
7
7
 
8
8
  setup do
9
- @http_mock = mock('Net::HTTPResponse')
10
- @http_mock.stubs(:code => '200', :kind_of? => false, :message => "OK")
11
- @http_mock.stubs(:kind_of?).with(Net::HTTPSuccess).returns(true)
12
- @http_mock.stubs(:body).returns(get_mock_body('successful_login.txt'))
13
- @http_request_mock = mock('Net::HTTPS')
14
- @http_request_mock.stubs(:set_form_data => '', :request => @http_mock)
15
-
16
- Net::HTTPS.stubs(:new).returns(@http_request_mock)
17
- end
9
+ @client_mock = mock('Faraday::Response')
10
+ @client_mock.stubs(:body).returns(get_mock_body('successful_login.json'))
11
+ @client_mock.stubs(:finish).returns('')
12
+ @client_mock.stubs(:status).returns(200)
13
+ Faraday::Response.stubs(:new).returns(@client_mock)
18
14
 
19
- context "Login" do
15
+ @client_id = "671053090364-ntifn8rauvhib9h3vnsegi6dhfglk9ue.apps.googleusercontent.com"
16
+ @client_secret = "roBgdbfEmJwPgrgi2mRbbO-f"
17
+ @refresh_token = "1/eiqBWx8aj-BsdhwvlzDMFOUN1IN_HyThvYTujyksO4c"
18
+ @calendar_id = "klei8jnelo09nflqehnvfzipgs@group.calendar.google.com"
19
+ @access_token = 'ya29.hYjPO0uHt63uWr5qmQtMEReZEvILcdGlPCOHDy6quKPyEQaQQvqaVAlLAVASaRm_O0a7vkZ91T8xyQ'
20
20
 
21
- should "login properly" do
22
- assert_nothing_thrown do
23
- Calendar.new(:username => 'some.one@gmail.com', :password => 'super-secret')
24
- end
25
- end
21
+ @calendar = Calendar.new(:client_id => @client_id, :client_secret => @client_secret, :redirect_url => "urn:ietf:wg:oauth:2.0:oob", :refresh_token => @refresh_token, :calendar => @calendar_id)
26
22
 
27
- should "catch login with invalid credentials" do
28
- @http_mock.stubs(:kind_of?).with(Net::HTTPForbidden).returns(true)
29
- @http_mock.stubs(:body).returns('Error=BadAuthentication')
30
- assert_raise(HTTPAuthorizationFailed) do
31
- Calendar.new(:username => 'some.one@gmail.com', :password => 'wrong-password')
32
- end
33
- end
23
+ end
34
24
 
35
- should "login properly with an app_name" do
36
- assert_nothing_thrown do
37
- Calendar.new(:username => 'some.one@gmail.com', :password => 'super-secret',
38
- :app_name => 'northworld.com-googlecalendar-integration'
39
- )
40
- end
41
- end
25
+ context "a calendar" do
42
26
 
43
- should "catch login with invalid app_name" do
44
- @http_mock.stubs(:kind_of?).with(Net::HTTPForbidden).returns(true)
45
- @http_mock.stubs(:body).returns('Error=BadAuthentication')
46
- assert_raise(HTTPAuthorizationFailed) do
47
- Calendar.new(:username => 'some.one@gmail.com', :password => 'super-secret',
48
- :app_name => 'northworld.com-silly-cal'
49
- )
50
- end
27
+ should "generate auth url" do
28
+ assert_equal @calendar.authorize_url.to_s, 'https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=671053090364-ntifn8rauvhib9h3vnsegi6dhfglk9ue.apps.googleusercontent.com&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&scope=https://www.googleapis.com/auth/calendar'
51
29
  end
52
30
 
53
- should "login properly with an auth_url" do
54
- assert_nothing_thrown do
55
- Calendar.new(:username => 'some.one@gmail.com', :password => 'super-secret',
56
- :auth_url => "https://www.google.com/accounts/ClientLogin"
57
- )
58
- end
31
+ should "login with auth code" do
32
+ @client_mock.stubs(:body).returns( get_mock_body("login_with_auth_code_success.json") )
33
+ @calendar.login_with_auth_code('4/QzBU-n6GXnHUkorG0fiu6AhoZtIjW53qKLOREiJWFpQ.wn0UfiyaDlEfEnp6UAPFm0EazsV1kwI')
34
+ assert_equal @calendar.auth_code, nil # the auth_code is discarded after it is used.
35
+ assert_equal @calendar.access_token, @access_token
36
+ assert_equal @calendar.refresh_token, '1/aJUy7pQzc4fUMX89BMMLeAfKcYteBKRMpQvf4fQFX0'
59
37
  end
60
38
 
61
- should "catch login with invalid auth_url" do
62
- @http_mock.stubs(:kind_of?).with(Net::HTTPForbidden).returns(true)
63
- @http_mock.stubs(:body).returns('Error=BadAuthentication')
64
- assert_raise(HTTPAuthorizationFailed) do
65
- Calendar.new(:username => 'some.one@gmail.com', :password => 'super-secret',
66
- :auth_url => "https://www.google.com/accounts/ClientLogin/waffles"
67
- )
68
- end
39
+ should "login with refresh token" do
40
+ # no refresh_token specified
41
+ cal = Calendar.new(:client_id => @client_id, :client_secret => @client_secret, :redirect_url => "urn:ietf:wg:oauth:2.0:oob", :calendar => @calendar_id)
42
+ @client_mock.stubs(:body).returns( get_mock_body("login_with_refresh_token_success.json") )
43
+ cal.login_with_refresh_token(@refresh_token)
44
+ assert_equal @calendar.access_token, @access_token
69
45
  end
70
46
 
71
- should "login properly with a calendar" do
72
- assert_nothing_thrown do
73
- cal = Calendar.new(:username => 'some.one@gmail.com', :password => 'super-secret',
74
- :calendar => "Little Giants")
75
-
76
- #mock calendar list request
77
- calendar_uri = mock("get calendar uri")
78
- Addressable::URI.expects(:parse).with("https://www.google.com/calendar/feeds/default/allcalendars/full").once.returns(calendar_uri)
79
- Connection.any_instance.expects(:send).with(calendar_uri, :get).once.returns(mock("response", :body => get_mock_body('list_calendars.xml')))
80
-
81
- #mock events list request
82
- events_uri = mock("get events uri")
83
- Addressable::URI.expects(:parse).with("https://www.google.com/calendar/feeds/rf1c66uld6dgk2t5lh43svev6g%40group.calendar.google.com/private/full").once.returns(events_uri)
84
- Connection.any_instance.expects(:send).with(events_uri, :get).once.returns(mock("response", :body => get_mock_body('events.xml')))
85
-
86
- cal.events
47
+ should "catch login with invalid credentials" do
48
+ @client_mock.stubs(:status).returns(403)
49
+ @client_mock.stubs(:body).returns( get_mock_body("403.json") )
50
+ assert_raises(HTTPAuthorizationFailed) do
51
+ Calendar.new(:client_id => 'abadid', :client_secret => 'abadsecret', :redirect_url => "urn:ietf:wg:oauth:2.0:oob", :refresh_token => @refresh_token, :calendar => @calendar_id)
87
52
  end
88
53
  end
89
54
 
90
- should "catch login with invalid calendar" do
91
-
92
- assert_raise(InvalidCalendar) do
93
- cal = Calendar.new(:username => 'some.one@gmail.com', :password => 'super-secret',
94
- :calendar => "invalid calendar")
95
-
96
- #mock calendar list request
97
- calendar_uri = mock("get calendar uri")
98
- Addressable::URI.expects(:parse).with("https://www.google.com/calendar/feeds/default/allcalendars/full").once.returns(calendar_uri)
99
- Connection.any_instance.expects(:send).with(calendar_uri, :get).once.returns(mock("response", :body => get_mock_body('list_calendars.xml')))
100
-
101
- cal.events
55
+ should "catch login with missing credentials" do
56
+ assert_raises(ArgumentError) do
57
+ @client_mock.stubs(:status).returns(401)
58
+ @client_mock.stubs(:body).returns( get_mock_body("401.json") )
59
+ Calendar.new()
102
60
  end
103
61
  end
104
62
 
105
63
  end # login context
106
64
 
107
- context "Logged on" do
65
+ context "and logged in" do
108
66
  setup do
109
- @calendar = Calendar.new(:username => 'some.one@gmail.com', :password => 'super-secret')
110
- end
111
-
112
- should "reload connection" do
113
- old_connection = @calendar.connection
114
- assert_not_equal old_connection, @calendar.reload.connection
67
+ @calendar = Calendar.new(:client_id => @client_id, :client_secret => @client_secret, :redirect_url => "urn:ietf:wg:oauth:2.0:oob", :refresh_token => @refresh_token, :calendar => @calendar_id)
115
68
  end
116
69
 
117
70
  should "find all events" do
118
- @http_mock.stubs(:body).returns( get_mock_body("events.xml") )
71
+ @client_mock.stubs(:body).returns( get_mock_body("events.json") )
119
72
  assert_equal @calendar.events.length, 3
120
73
  end
121
74
 
122
75
  should "query events" do
123
- @http_mock.stubs(:body).returns( get_mock_body("query_events.xml") )
76
+ @client_mock.stubs(:body).returns( get_mock_body("query_events.json") )
124
77
  event = @calendar.find_events('Test&gsessionid=12345')
125
- assert_equal event.title, 'Test'
78
+ assert_equal event[0].title, 'Test Event'
126
79
  end
127
80
 
128
81
  should "find events in range" do
129
82
  start_min = DateTime.new(2011, 2, 1, 11, 1, 1)
130
83
  start_max = DateTime.new(2011, 2, 28, 23, 59, 59)
131
- @calendar.expects(:event_lookup).with('?start-min=2011-02-01T11:01:01&start-max=2011-02-28T23:59:59&recurrence-expansion-start=2011-02-01T11:01:01&recurrence-expansion-end=2011-02-28T23:59:59&orderby=lastmodified&max-results=25')
84
+ @calendar.expects(:event_lookup).with('?timeMin=2011-02-01T11%3A01%3A01%2B00%3A00&timeMax=2011-02-28T23%3A59%3A59%2B00%3A00&orderBy=startTime&maxResults=25&singleEvents=true')
132
85
  events = @calendar.find_events_in_range(start_min, start_max)
133
86
  end
134
87
 
88
+ should "find future events" do
89
+ now = DateTime.now
90
+ DateTime.stubs(:now).returns(now)
91
+ formatted_time = Addressable::URI.encode_component(now.strftime("%FT%T%:z"), Addressable::URI::CharacterClasses::UNRESERVED)
92
+ @calendar.expects(:event_lookup).with("?timeMin=#{formatted_time}&orderBy=startTime&maxResults=25&singleEvents=true")
93
+ events = @calendar.find_future_events()
94
+ end
95
+
96
+ should "return multiple events in range as array" do
97
+ @client_mock.stubs(:body).returns( get_mock_body("events.json") )
98
+ events = @calendar.events
99
+ assert_equal events.class.to_s, "Array"
100
+ end
101
+
102
+ should "return one event in range as array" do
103
+ @client_mock.stubs(:body).returns( get_mock_body("query_events.json") )
104
+ events = @calendar.events
105
+ assert_equal events.class.to_s, "Array"
106
+ end
107
+
108
+ should "return response of no events in range as array" do
109
+ @client_mock.stubs(:body).returns( get_mock_body("empty_events.json") )
110
+ events = @calendar.events
111
+ assert_equal events.class.to_s, "Array"
112
+ assert_equal events, []
113
+ end
114
+
135
115
  should "find an event by id" do
136
- @http_mock.stubs(:body).returns( get_mock_body("find_event_by_id.xml") )
137
- event = @calendar.find_event_by_id('oj6fmpaulbvk9ouoj0lj4v6hio')
138
- assert_equal event.id, 'oj6fmpaulbvk9ouoj0lj4v6hio'
116
+ @client_mock.stubs(:body).returns( get_mock_body("find_event_by_id.json") )
117
+ event = @calendar.find_event_by_id('fhru34kt6ikmr20knd2456l08n')
118
+ assert_equal event[0].id, 'fhru34kt6ikmr20knd2456l08n'
139
119
  end
140
120
 
141
121
  should "throw NotFound with invalid event id" do
142
- @http_mock.stubs(:kind_of?).with(Net::HTTPNotFound).returns(true)
122
+ @client_mock.stubs(:status).returns(404)
123
+ @client_mock.stubs(:body).returns( get_mock_body("404.json") )
143
124
  assert_equal @calendar.find_event_by_id('1234'), nil
144
125
  end
145
126
 
146
127
  should "create an event with block" do
147
- @http_mock.stubs(:body).returns( get_mock_body("create_event.xml") )
128
+ @client_mock.stubs(:body).returns( get_mock_body("create_event.json") )
148
129
 
149
130
  event = @calendar.create_event do |e|
150
131
  e.title = 'New Event'
151
132
  e.start_time = Time.now + (60 * 60)
152
133
  e.end_time = Time.now + (60 * 60 * 2)
153
- e.content = "A new event"
154
- e.where = "Joe's House"
134
+ e.description = "A new event"
135
+ e.location = "Joe's House"
155
136
  end
156
137
 
157
138
  assert_equal event.title, 'New Event'
139
+ assert_equal event.id, "fhru34kt6ikmr20knd2456l08n"
158
140
  end
159
141
 
160
142
  should "create a quickadd event" do
161
- @http_mock.stubs(:body).returns( get_mock_body("create_quickadd_event.xml") )
143
+ @client_mock.stubs(:body).returns( get_mock_body("create_quickadd_event.json") )
162
144
 
163
145
  event = @calendar.create_event do |e|
164
- e.content = "movie tomorrow 23:00 at AMC Van Ness"
146
+ e.title = "movie tomorrow 23:00 at AMC Van Ness"
165
147
  e.quickadd = true
166
148
  end
167
149
 
168
- assert_equal event.content, "movie tomorrow 23:00 at AMC Van Ness"
150
+ assert_equal event.title, "movie tomorrow 23:00 at AMC Van Ness"
151
+ assert_equal event.id, 'fhru34kt6ikmr20knd2456l08n'
169
152
  end
170
153
 
171
154
  should "format create event with ampersand correctly" do
172
- @http_mock.stubs(:body).returns( get_mock_body("create_event.xml") )
173
-
174
- event = @calendar.create_event do |e|
175
- e.title = 'New Event with &'
176
- e.start_time = Time.now + (60 * 60)
177
- e.end_time = Time.now + (60 * 60 * 2)
178
- e.content = "A new event with &"
179
- e.where = "Joe's House & Backyard"
180
- end
181
-
182
- assert_equal event.title, 'New Event with &amp;'
183
- assert_equal event.content, 'A new event with &amp;'
184
- assert_equal event.where, "Joe's House &amp; Backyard"
155
+ @client_mock.stubs(:body).returns( get_mock_body("create_event.json") )
156
+
157
+ event = @calendar.create_event do |e|
158
+ e.title = 'New Event with &'
159
+ e.start_time = Time.now + (60 * 60)
160
+ e.end_time = Time.now + (60 * 60 * 2)
161
+ e.description = "A new event with &"
162
+ e.location = "Joe's House & Backyard"
163
+ end
164
+
165
+ assert_equal event.title, 'New Event with &'
166
+ assert_equal event.description, 'A new event with &'
167
+ assert_equal event.location, "Joe's House & Backyard"
185
168
  end
186
169
 
187
170
  should "format to_s properly" do
188
- @http_mock.stubs(:body).returns( get_mock_body("query_events.xml") )
171
+ @client_mock.stubs(:body).returns( get_mock_body("query_events.json") )
189
172
  event = @calendar.find_events('Test')
190
- assert_equal event.to_s, "Test (oj6fmpaulbvk9ouoj0lj4v6hio)\n\t2010-04-08\n\t2010-04-09\n\tAt School\n\t"
173
+ e = event[0]
174
+ assert_equal e.to_s, "Event Id '#{e.id}'\n\tTitle: #{e.title}\n\tStarts: #{e.start_time}\n\tEnds: #{e.end_time}\n\tLocation: #{e.location}\n\tDescription: #{e.description}\n\n"
191
175
  end
192
176
 
193
177
  should "update an event by id" do
194
- @http_mock.stubs(:body).returns( get_mock_body("find_event_by_id.xml") )
178
+ @client_mock.stubs(:body).returns( get_mock_body("find_event_by_id.json") )
195
179
 
196
- event = @calendar.find_or_create_event_by_id('oj6fmpaulbvk9ouoj0lj4v6hio') do |e|
180
+ event = @calendar.find_or_create_event_by_id('t00jnpqc08rcabi6pa549ttjlk') do |e|
197
181
  e.title = 'New Event Update'
198
182
  end
199
183
 
@@ -201,30 +185,22 @@ class TestGoogleCalendar < Test::Unit::TestCase
201
185
  end
202
186
 
203
187
  should "delete an event" do
204
- @http_mock.stubs(:body).returns( get_mock_body("create_event.xml") )
188
+ @client_mock.stubs(:body).returns( get_mock_body("create_event.json") )
205
189
 
206
190
  event = @calendar.create_event do |e|
207
191
  e.title = 'Delete Me'
208
192
  end
209
193
 
210
- assert_equal event.id, 'b1vq6rj4r4mg85kcickc7iomb0'
194
+ assert_equal event.id, 'fhru34kt6ikmr20knd2456l08n'
211
195
 
212
- @http_mock.stubs(:body).returns("")
196
+ @client_mock.stubs(:body).returns('')
213
197
  event.delete
214
198
  assert_equal event.id, nil
215
199
  end
216
200
 
217
- should "not redirect forever" do
218
- @http_mock.stubs(:kind_of?).with(Net::HTTPRedirection).returns(true)
219
- @http_mock.stubs(:[]).with('location').returns('https://www.google.com')
220
- assert_raise(HTTPTooManyRedirections) do
221
- @calendar.events
222
- end
223
- end
224
-
225
201
  should "throw exception on bad request" do
226
- @http_mock.stubs(:kind_of?).with(Net::HTTPBadRequest).returns(true)
227
- assert_raise(HTTPRequestFailed) do
202
+ @client_mock.stubs(:status).returns(400)
203
+ assert_raises(HTTPRequestFailed) do
228
204
  @calendar.events
229
205
  end
230
206
  end
@@ -232,7 +208,7 @@ class TestGoogleCalendar < Test::Unit::TestCase
232
208
  end # Logged on context
233
209
 
234
210
  end # Connected context
235
-
211
+
236
212
  context "Event instance methods" do
237
213
  context "#all_day?" do
238
214
  context "when the event is marked as All Day in google calendar" do
@@ -260,7 +236,7 @@ class TestGoogleCalendar < Test::Unit::TestCase
260
236
  end
261
237
  end
262
238
  end
263
-
239
+
264
240
  context "#all_day=" do
265
241
  context "sets the start and end time to the appropriate values for an all day event on that day" do
266
242
  should "set the start time" do
@@ -278,12 +254,64 @@ class TestGoogleCalendar < Test::Unit::TestCase
278
254
  end
279
255
  end
280
256
  end
281
- end
282
257
 
283
- def test_https_extension
284
- assert_nothing_thrown do
285
- uri = Addressable::URI.parse('https://www.google.com')
286
- Net::HTTPS.new(uri.host, uri.port)
258
+ context "transparency" do
259
+ should "be transparent" do
260
+ @event = Event.new(:transparency => true)
261
+ assert @event.transparent?
262
+ end
263
+
264
+ should "be opaque?" do
265
+ @event = Event.new(:transparency => false)
266
+ assert @event.opaque?
267
+ end
268
+ end
269
+
270
+ context "event json" do
271
+ should "be correct format" do
272
+ now = Time.now
273
+ @event = Event.new
274
+ @event.start_time = now
275
+ @event.end_time = now + (60 * 60)
276
+ @event.title = "Go Swimming"
277
+ @event.description = "The polar bear plunge"
278
+ @event.location = "In the arctic ocean"
279
+ @event.transparency = "opaque"
280
+ @event.reminders = { 'useDefault' => false, 'overrides' => ['minutes' => 10, 'method' => "popup"]}
281
+ @event.attendees = [
282
+ {'email' => 'some.a.one@gmail.com', 'displayName' => 'Some A One', 'responseStatus' => 'tentative'},
283
+ {'email' => 'some.b.one@gmail.com', 'displayName' => 'Some B One', 'responseStatus' => 'tentative'}
284
+ ]
285
+
286
+ correct_json = "{ \"summary\": \"Go Swimming\", \"description\": \"The polar bear plunge\", \"location\": \"In the arctic ocean\", \"start\": { \"dateTime\": \"#{@event.start_time}\" }, \"end\": { \"dateTime\": \"#{@event.end_time}\" }, \"attendees\": [{ \"displayName\": \"Some A One\", \"email\": \"some.a.one@gmail.com\", \"responseStatus\": \"tentative\" },{ \"displayName\": \"Some B One\", \"email\": \"some.b.one@gmail.com\", \"responseStatus\": \"tentative\" }], \"reminders\": { \"useDefault\": false,\"overrides\": [{ \"method\": \"popup\", \"minutes\": 10 }] } }"
287
+ assert_equal @event.to_json.gsub("\n", "").gsub(/\s+/, ' '), correct_json
288
+ end
289
+ end
290
+
291
+ context "reminders" do
292
+ context "reminders array" do
293
+ should "set reminder time" do
294
+ @event = Event.new :reminders => [minutes: 6]
295
+ assert_equal @event.reminders.first[:minutes], 6
296
+ end
297
+
298
+ should "use different time scales" do
299
+ @event = Event.new :reminders => [hours: 5]
300
+ assert_equal @event.reminders.first[:hours], 5
301
+ end
302
+
303
+ should "set reminder method" do
304
+ @event = Event.new :reminders => [minutes: 6, method: "sms"]
305
+ assert_equal @event.reminders.first[:minutes], 6
306
+ assert_equal @event.reminders.first[:method], "sms"
307
+ end
308
+
309
+ should "default to minutes -> hours -> days" do
310
+ @event = Event.new :reminders => [minutes: 6, hours: 8]
311
+ assert_equal @event.reminders.first[:minutes], 6
312
+ assert_equal @event.reminders.first[:hours], 8
313
+ end
314
+ end
287
315
  end
288
316
  end
289
317