google_calendar 0.6.2 → 0.7.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.
@@ -13,38 +13,69 @@ class TestGoogleCalendar < Minitest::Test
13
13
  @refresh_token = ENV['REFRESH_TOKEN']
14
14
  @calendar_id = ENV['CALENDAR_ID']
15
15
  @access_token = ENV['ACCESS_TOKEN']
16
+ @redirect_url = ENV['REDIRECT_URL']
16
17
 
17
- @calendar = Calendar.new(:client_id => @client_id, :client_secret => @client_secret, :redirect_url => ENV['REDIRECT_URL'], :refresh_token => @refresh_token, :calendar => @calendar_id)
18
+ @calendar = Calendar.new(:client_id => @client_id, :client_secret => @client_secret, :redirect_url => @redirect_url, :refresh_token => @refresh_token, :calendar => @calendar_id)
18
19
 
19
20
  end
20
21
 
21
22
  context "a calendar" do
22
23
 
23
24
  should "generate auth url" do
24
- 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'
25
+ 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=https://mytesturl.com/&response_type=code&scope=https://www.googleapis.com/auth/calendar'
25
26
  end
26
27
 
27
28
  should "login with auth code" do
28
29
  @client_mock.stubs(:body).returns( get_mock_body("login_with_auth_code_success.json") )
29
30
  @calendar.login_with_auth_code('4/QzBU-n6GXnHUkorG0fiu6AhoZtIjW53qKLOREiJWFpQ.wn0UfiyaDlEfEnp6UAPFm0EazsV1kwI')
30
- assert_equal @calendar.auth_code, nil # the auth_code is discarded after it is used.
31
+ assert_nil @calendar.auth_code # the auth_code is discarded after it is used.
31
32
  assert_equal @calendar.access_token, @access_token
32
33
  assert_equal @calendar.refresh_token, '1/aJUy7pQzc4fUMX89BMMLeAfKcYteBKRMpQvf4fQFX0'
33
34
  end
34
35
 
35
36
  should "login with refresh token" do
36
37
  # no refresh_token specified
37
- cal = Calendar.new(:client_id => @client_id, :client_secret => @client_secret, :redirect_url => "urn:ietf:wg:oauth:2.0:oob", :calendar => @calendar_id)
38
+ cal = Calendar.new(:client_id => @client_id, :client_secret => @client_secret, :redirect_url => @redirect_url, :calendar => @calendar_id)
38
39
  @client_mock.stubs(:body).returns( get_mock_body("login_with_refresh_token_success.json") )
39
40
  cal.login_with_refresh_token(@refresh_token)
40
41
  assert_equal @calendar.access_token, @access_token
41
42
  end
42
43
 
44
+ should "login with get method" do
45
+ cal = Calendar.get(:client_id => @client_id, :client_secret => @client_secret, :redirect_url => @redirect_url,
46
+ :calendar => @calendar_id, :refresh_token => @refresh_token)
47
+ @client_mock.stubs(:body).returns( get_mock_body("get_calendar.json") )
48
+ assert_equal cal.id, @calendar_id
49
+ end
50
+
51
+ should "update calendar" do
52
+ cal = Calendar.get(:client_id => @client_id, :client_secret => @client_secret, :redirect_url => @redirect_url,
53
+ :calendar => @calendar_id, :refresh_token => @refresh_token)
54
+ @client_mock.stubs(:body).returns( get_mock_body("update_calendar.json") )
55
+ cal.update(:summary => 'Our Company', :description => "Work event list")
56
+ assert_equal @calendar.id, @calendar_id
57
+ end
58
+
59
+ should "create calendar" do
60
+ cal = Calendar.create(:client_id => @client_id, :client_secret => @client_secret, :redirect_url => @redirect_url,
61
+ :refresh_token => @refresh_token, :summary => 'A New Calendar', :description => 'Our new calendar')
62
+ assert_equal cal.summary, 'A New Calendar'
63
+ end
64
+
65
+ should "destroy a calendar" do
66
+ reusable_connection = mock('Google::Connection')
67
+ reusable_connection.expects(:send).with("/calendars/#{@calendar_id}", :delete, '').returns(@client_mock)
68
+
69
+ calendar = Calendar.new({:calendar => @calendar_id}, reusable_connection)
70
+ calendar.destroy
71
+ end
72
+
43
73
  should "catch login with invalid credentials" do
44
74
  @client_mock.stubs(:status).returns(403)
45
75
  @client_mock.stubs(:body).returns( get_mock_body("403.json") )
46
76
  assert_raises(HTTPAuthorizationFailed) do
47
- Calendar.new(:client_id => 'abadid', :client_secret => 'abadsecret', :redirect_url => "urn:ietf:wg:oauth:2.0:oob", :refresh_token => @refresh_token, :calendar => @calendar_id)
77
+ Calendar.new(:client_id => 'abadid', :client_secret => 'abadsecret', :redirect_url => @redirect_url,
78
+ :refresh_token => @refresh_token, :calendar => @calendar_id)
48
79
  end
49
80
  end
50
81
 
@@ -65,11 +96,29 @@ class TestGoogleCalendar < Minitest::Test
65
96
  calendar.events
66
97
  end
67
98
 
99
+ should "throw ForbiddenError if not logged in" do
100
+ @client_mock.stubs(:status).returns(403)
101
+ @client_mock.stubs(:body).returns( get_mock_body("403_forbidden.json") )
102
+
103
+ assert_raises(ForbiddenError) do
104
+ @calendar.find_event_by_id('1234')
105
+ end
106
+ end
107
+
108
+ should "throw ForbiddenError if unknown 403 response" do
109
+ @client_mock.stubs(:status).returns(403)
110
+ @client_mock.stubs(:body).returns( get_mock_body("403_unknown.json") )
111
+
112
+ assert_raises(ForbiddenError) do
113
+ @calendar.find_event_by_id('1234')
114
+ end
115
+ end
116
+
68
117
  end # login context
69
118
 
70
119
  context "and logged in" do
71
120
  setup do
72
- @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)
121
+ @calendar = Calendar.new(:client_id => @client_id, :client_secret => @client_secret, :redirect_url => @redirect_url, :refresh_token => @refresh_token, :calendar => @calendar_id)
73
122
  end
74
123
 
75
124
  should "find all events" do
@@ -159,6 +208,96 @@ class TestGoogleCalendar < Minitest::Test
159
208
  assert_equal @calendar.find_event_by_id('1234'), []
160
209
  end
161
210
 
211
+ should "throw Request Failed with 400 error" do
212
+ @client_mock.stubs(:status).returns(400)
213
+ @client_mock.stubs(:body).returns( get_mock_body("400.json") )
214
+
215
+ assert_raises(HTTPRequestFailed) do
216
+ @calendar.create_event do |e|
217
+ e.title = 'New Event with no time'
218
+ e.description = "A new event with &"
219
+ e.location = "Joe's House & Backyard"
220
+ end
221
+ end
222
+ end
223
+
224
+ should "throw DailyLimitExceededError when limit exceeded" do
225
+ @client_mock.stubs(:status).returns(403)
226
+ @client_mock.stubs(:body).returns( get_mock_body("403_daily_limit.json") )
227
+
228
+ assert_raises(DailyLimitExceededError) do
229
+ @calendar.find_event_by_id('1234')
230
+ end
231
+ end
232
+
233
+ should "throw RateLimitExceededError when rate limit exceeded" do
234
+ @client_mock.stubs(:status).returns(403)
235
+ @client_mock.stubs(:body).returns( get_mock_body("403_rate_limit.json") )
236
+
237
+ assert_raises(RateLimitExceededError) do
238
+ @calendar.find_event_by_id('1234')
239
+ end
240
+ end
241
+
242
+ should "throw UserRateLimitExceededError when user rate limit exceeded" do
243
+ @client_mock.stubs(:status).returns(403)
244
+ @client_mock.stubs(:body).returns( get_mock_body("403_user_rate_limit.json") )
245
+
246
+ assert_raises(UserRateLimitExceededError) do
247
+ @calendar.find_event_by_id('1234')
248
+ end
249
+ end
250
+
251
+ should "throw CalendarUsageLimitExceededError when calendar rate limit exceeded" do
252
+ @client_mock.stubs(:status).returns(403)
253
+ @client_mock.stubs(:body).returns( get_mock_body("403_calendar_rate_limit.json") )
254
+
255
+ assert_raises(CalendarUsageLimitExceededError) do
256
+ @calendar.find_event_by_id('1234')
257
+ end
258
+ end
259
+
260
+ should "throw RequestedIdentifierAlreadyExistsError if bad eTag" do
261
+ @client_mock.stubs(:status).returns(409)
262
+ @client_mock.stubs(:body).returns( get_mock_body("409.json") )
263
+
264
+ assert_raises(RequestedIdentifierAlreadyExistsError) do
265
+ @calendar.create_event do |e|
266
+ e.id = 'duplicate'
267
+ e.title = 'New Event'
268
+ e.start_time = Time.now + (60 * 60)
269
+ e.end_time = Time.now + (60 * 60 * 2)
270
+ end
271
+ end
272
+ end
273
+
274
+ should "throw GoneError if bad eTag" do
275
+ @client_mock.stubs(:status).returns(410)
276
+ @client_mock.stubs(:body).returns( get_mock_body("410.json") )
277
+
278
+ assert_raises(GoneError) do
279
+ @calendar.find_event_by_id('deleted')
280
+ end
281
+ end
282
+
283
+ should "throw PreconditionFailedError if bad eTag" do
284
+ @client_mock.stubs(:status).returns(412)
285
+ @client_mock.stubs(:body).returns( get_mock_body("412.json") )
286
+
287
+ assert_raises(PreconditionFailedError) do
288
+ @calendar.find_event_by_id('1234')
289
+ end
290
+ end
291
+
292
+ should "throw BackendError if Google is having issues" do
293
+ @client_mock.stubs(:status).returns(500)
294
+ @client_mock.stubs(:body).returns( get_mock_body("500.json") )
295
+
296
+ assert_raises(BackendError) do
297
+ @calendar.find_event_by_id('1234')
298
+ end
299
+ end
300
+
162
301
  should "create an event with block" do
163
302
  @client_mock.stubs(:body).returns( get_mock_body("create_event.json") )
164
303
 
@@ -248,7 +387,7 @@ class TestGoogleCalendar < Minitest::Test
248
387
 
249
388
  @client_mock.stubs(:body).returns('')
250
389
  event.delete
251
- assert_equal event.id, nil
390
+ assert_nil event.id
252
391
  end
253
392
 
254
393
  should "throw exception on bad request" do
@@ -258,14 +397,25 @@ class TestGoogleCalendar < Minitest::Test
258
397
  end
259
398
  end
260
399
 
261
- should "create event when id is NIL" do
400
+ should "create event when id is nil" do
262
401
  @client_mock.stubs(:body).returns( get_mock_body("find_event_by_id.json") )
263
402
 
264
- event = @calendar.find_or_create_event_by_id(NIL) do |e|
265
- e.title = 'New Event Update when id is NIL'
403
+ event = @calendar.find_or_create_event_by_id(nil) do |e|
404
+ e.title = 'New Event Update when id is nil'
405
+ end
406
+
407
+ assert_equal event.title, 'New Event Update when id is nil'
408
+ end
409
+
410
+ should "create an event with a specified id when none is found on the server" do
411
+ @client_mock.stubs(:body).returns( get_mock_body("empty_events.json") )
412
+
413
+ event = @calendar.find_or_create_event_by_id('fhru34kt6ikmr20knd2456l08n') do |e|
414
+ e.title = 'New Event With Predefined Id'
266
415
  end
267
416
 
268
- assert_equal event.title, 'New Event Update when id is NIL'
417
+ assert_equal event.title, 'New Event With Predefined Id'
418
+ assert_equal event.id, 'fhru34kt6ikmr20knd2456l08n'
269
419
  end
270
420
 
271
421
  should "provide the calendar summary" do
@@ -285,10 +435,10 @@ class TestGoogleCalendar < Minitest::Test
285
435
  event.id = '8os94knodtv84h0jh4pqq4ut35'
286
436
  assert_equal event.id, '8os94knodtv84h0jh4pqq4ut35'
287
437
  end
288
- should "work with a passed-in NIL id" do
438
+ should "work with a passed-in nil id" do
289
439
  event = Event.new
290
440
  event.id = nil
291
- assert_equal event.id, nil
441
+ assert_nil event.id
292
442
  end
293
443
  should "raise an error with an invalid ID" do
294
444
  event = Event.new
@@ -371,15 +521,30 @@ class TestGoogleCalendar < Minitest::Test
371
521
  end
372
522
 
373
523
  context "transparency" do
374
- should "be transparent" do
375
- @event = Event.new(:transparency => true)
376
- assert @event.transparent?
524
+ should "be opaque when nil" do
525
+ @event = Event.new
526
+ assert @event.opaque?
527
+ end
528
+
529
+ should "be opaque when transparency = opaque" do
530
+ @event = Event.new(:transparency => 'opaque')
531
+ assert @event.opaque?
377
532
  end
378
533
 
379
534
  should "be opaque?" do
380
535
  @event = Event.new(:transparency => false)
381
536
  assert @event.opaque?
382
537
  end
538
+
539
+ should "be transparent" do
540
+ @event = Event.new(:transparency => true)
541
+ assert @event.transparent?
542
+ end
543
+
544
+ should "be transparent when transparency = transparent" do
545
+ @event = Event.new(:transparency => 'transparent')
546
+ assert @event.transparent?
547
+ end
383
548
  end
384
549
 
385
550
  context "event json" do
@@ -509,6 +674,67 @@ class TestGoogleCalendar < Minitest::Test
509
674
  assert_equal correct_hash.inspect, Event.parse_recurrence_rule(rrule).inspect
510
675
  end
511
676
  end
677
+
678
+ context "visibility" do
679
+ should "default to 'default' when not specified" do
680
+ assert_equal Event.new.visibility, "default"
681
+ end
682
+
683
+ should "accept a valid visibility" do
684
+ assert_equal Event.new(:visibility => "private").visibility, "private"
685
+ end
686
+
687
+ should "raise an error on an invalid visibility" do
688
+ assert_raises(ArgumentError) { Event.new(:visibility => "bogus") }
689
+ end
690
+ end
691
+
692
+ context "default hashes" do
693
+ should "return an empty hash for recurrence when unset" do
694
+ assert_equal Event.new.recurrence, {}
695
+ end
696
+
697
+ should "return an empty hash for extended_properties when unset" do
698
+ assert_equal Event.new.extended_properties, {}
699
+ end
700
+ end
701
+
702
+ context "attribute JSON helpers" do
703
+ setup do
704
+ @event = Event.new(
705
+ :color_id => 5,
706
+ :attendees => [{'email' => 'a@example.com', 'displayName' => 'A', 'responseStatus' => 'accepted'}],
707
+ :reminders => { 'useDefault' => false, 'overrides' => [{'minutes' => 10, 'method' => 'popup'}] },
708
+ :recurrence => { freq: 'weekly' },
709
+ :extended_properties => { 'shared' => { 'key' => 'value' } }
710
+ )
711
+ end
712
+
713
+ should "expose colorId as a hash and as json" do
714
+ assert_equal @event.color_attributes, { "colorId" => "5" }
715
+ assert_equal JSON.parse(@event.color_json), { "colorId" => "5" }
716
+ end
717
+
718
+ should "expose attendees as json" do
719
+ assert_equal JSON.parse(@event.attendees_json)["attendees"].first["email"], 'a@example.com'
720
+ end
721
+
722
+ should "expose reminders as json" do
723
+ assert_equal JSON.parse(@event.reminders_json)["useDefault"], false
724
+ end
725
+
726
+ should "expose recurrence as json" do
727
+ assert_equal JSON.parse(@event.recurrence_json)["recurrence"], ["RRULE:FREQ=WEEKLY"]
728
+ end
729
+
730
+ should "expose extended properties as json" do
731
+ assert_equal JSON.parse(@event.extended_properties_json)["extendedProperties"]["shared"]["key"], 'value'
732
+ end
733
+
734
+ should "expose the local timezone as json" do
735
+ assert_equal JSON.parse(@event.local_timezone_json)["timeZone"], TimezoneParser::getTimezones(Time.now.getlocal.zone).last
736
+ end
737
+ end
512
738
  end
513
739
 
514
740
  context "a calendar list" do
@@ -519,11 +745,12 @@ class TestGoogleCalendar < Minitest::Test
519
745
  @client_id = "671053090364-ntifn8rauvhib9h3vnsegi6dhfglk9ue.apps.googleusercontent.com"
520
746
  @client_secret = "roBgdbfEmJwPgrgi2mRbbO-f"
521
747
  @refresh_token = "1/eiqBWx8aj-BsdhwvlzDMFOUN1IN_HyThvYTujyksO4c"
748
+ @redirect_url = "https://mytesturl.com/"
522
749
 
523
750
  @calendar_list = Google::CalendarList.new(
524
751
  :client_id => @client_id,
525
752
  :client_secret => @client_secret,
526
- :redirect_url => "urn:ietf:wg:oauth:2.0:oob",
753
+ :redirect_url => @redirect_url,
527
754
  :refresh_token => @refresh_token
528
755
  )
529
756
 
@@ -566,18 +793,18 @@ class TestGoogleCalendar < Minitest::Test
566
793
  end
567
794
 
568
795
  context "a freebusy query" do
569
-
570
796
  setup do
571
797
  @client_mock = setup_mock_client
572
798
 
573
799
  @client_id = "671053090364-ntifn8rauvhib9h3vnsegi6dhfglk9ue.apps.googleusercontent.com"
574
800
  @client_secret = "roBgdbfEmJwPgrgi2mRbbO-f"
575
801
  @refresh_token = "1/eiqBWx8aj-BsdhwvlzDMFOUN1IN_HyThvYTujyksO4c"
802
+ @redirect_url = "https://mytesturl.com/"
576
803
 
577
804
  @freebusy = Google::Freebusy.new(
578
805
  :client_id => @client_id,
579
806
  :client_secret => @client_secret,
580
- :redirect_url => "urn:ietf:wg:oauth:2.0:oob",
807
+ :redirect_url => @redirect_url,
581
808
  :refresh_token => @refresh_token
582
809
  )
583
810
 
@@ -595,12 +822,28 @@ class TestGoogleCalendar < Minitest::Test
595
822
  should "returns the busy times for each calendar supplied" do
596
823
  freebusy_result = @freebusy.query(@calendar_ids, @start_time, @end_time)
597
824
 
598
- assert_equal ({'start' => '2015-03-06T10:00:00Z', 'end' => '2015-03-06T11:00:00Z' }), freebusy_result['busy-calendar-id'].first
599
- assert_equal ({'start' => '2015-03-06T11:30:00Z', 'end' => '2015-03-06T11:30:00Z' }), freebusy_result['busy-calendar-id'].last
825
+ assert_equal ({'start' => DateTime.new(2015, 3, 6, 10, 0, 0, 0), 'end' => DateTime.new(2015, 3, 6, 11, 0, 0, 0) }), freebusy_result['busy-calendar-id'].first
826
+ assert_equal ({'start' => DateTime.new(2015, 3, 6, 11, 30, 0, 0), 'end' => DateTime.new(2015, 3, 6, 11, 30, 0, 0) }), freebusy_result['busy-calendar-id'].last
600
827
  assert_equal [], freebusy_result['not-busy-calendar-id']
601
828
  end
602
829
  end
603
830
 
831
+ context "with a service account" do
832
+ setup do
833
+ @client_mock = setup_mock_client
834
+ end
835
+
836
+ should "connect and obtain an access token" do
837
+ connection = Google::Connection.new_with_service_account(
838
+ :client_id => "the-issuer@example.iam.gserviceaccount.com",
839
+ :signing_key => OpenSSL::PKey::RSA.new(2048),
840
+ :person => "user@example.com"
841
+ )
842
+
843
+ assert_equal connection.access_token, ENV['ACCESS_TOKEN']
844
+ end
845
+ end
846
+
604
847
  protected
605
848
 
606
849
  def get_mock_body(name)