cronofy 0.25.1 → 0.26.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/lib/cronofy.rb +1 -0
- data/lib/cronofy/client.rb +71 -29
- data/lib/cronofy/time_encoding.rb +31 -0
- data/lib/cronofy/types.rb +33 -0
- data/lib/cronofy/version.rb +1 -1
- data/spec/lib/cronofy/client_spec.rb +212 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62d037f0b84f5f60661b7875c8bf2645df8a5b94
|
4
|
+
data.tar.gz: fbbb34833ed05e6ad74375dff707a73ae0138458
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 923d240d65bb915cd34560f41c0752ec39e3bed611b000c5fea4c9648afe31eccce96b5e19a16a9b5e28b9b3b135a56b621df916c7c8100fc00cbe2e6d12869d
|
7
|
+
data.tar.gz: 4d5bfa47913f8439892f10c458dec0464701ccaeb3f0561e2d6bf01c9b479ce7b01d5411464f06a9d02583163d5b31e23f31e186384773c223d9046998c99f12
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## [0.26.0]
|
2
|
+
|
3
|
+
* Support for batch endpoint [#53]
|
4
|
+
|
1
5
|
## [0.25.1]
|
2
6
|
|
3
7
|
* Support for Cancelling Smart Invites [#55]
|
@@ -91,6 +95,7 @@
|
|
91
95
|
[0.24.1]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.24.1
|
92
96
|
[0.25.0]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.25.0
|
93
97
|
[0.25.1]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.25.1
|
98
|
+
[0.26.0]: https://github.com/cronofy/cronofy-ruby/releases/tag/v0.26.0
|
94
99
|
|
95
100
|
[#13]: https://github.com/cronofy/cronofy-ruby/pull/13
|
96
101
|
[#16]: https://github.com/cronofy/cronofy-ruby/pull/16
|
@@ -115,4 +120,5 @@
|
|
115
120
|
[#49]: https://github.com/cronofy/cronofy-ruby/pull/49
|
116
121
|
[#50]: https://github.com/cronofy/cronofy-ruby/pull/50
|
117
122
|
[#52]: https://github.com/cronofy/cronofy-ruby/pull/52
|
123
|
+
[#53]: https://github.com/cronofy/cronofy-ruby/pull/53
|
118
124
|
[#55]: https://github.com/cronofy/cronofy-ruby/pull/55
|
data/lib/cronofy.rb
CHANGED
data/lib/cronofy/client.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Cronofy
|
2
2
|
# Public: Primary class for interacting with the Cronofy API.
|
3
3
|
class Client
|
4
|
+
include TimeEncoding
|
5
|
+
|
4
6
|
# Public: The scope to request if none is explicitly specified by the
|
5
7
|
# caller.
|
6
8
|
DEFAULT_OAUTH_SCOPE = %w{
|
@@ -308,6 +310,75 @@ module Cronofy
|
|
308
310
|
nil
|
309
311
|
end
|
310
312
|
|
313
|
+
class BatchBuilder
|
314
|
+
include TimeEncoding
|
315
|
+
|
316
|
+
def initialize
|
317
|
+
@entries = []
|
318
|
+
end
|
319
|
+
|
320
|
+
def upsert_event(calendar_id, event)
|
321
|
+
data = event.dup
|
322
|
+
|
323
|
+
data[:start] = encode_event_time(data[:start])
|
324
|
+
data[:end] = encode_event_time(data[:end])
|
325
|
+
|
326
|
+
post "/v1/calendars/#{calendar_id}/events", data
|
327
|
+
end
|
328
|
+
|
329
|
+
alias_method :create_or_update_event, :upsert_event
|
330
|
+
|
331
|
+
def delete_event(calendar_id, event_id)
|
332
|
+
delete "/v1/calendars/#{calendar_id}/events", event_id: event_id
|
333
|
+
end
|
334
|
+
|
335
|
+
def delete_external_event(calendar_id, event_uid)
|
336
|
+
delete "/v1/calendars/#{calendar_id}/events", event_uid: event_uid
|
337
|
+
end
|
338
|
+
|
339
|
+
def add_entry(args)
|
340
|
+
@entries << BatchEntryRequest.new(args)
|
341
|
+
nil
|
342
|
+
end
|
343
|
+
|
344
|
+
def build
|
345
|
+
@entries.dup
|
346
|
+
end
|
347
|
+
|
348
|
+
private
|
349
|
+
|
350
|
+
def delete(relative_url, data)
|
351
|
+
add_entry(method: "DELETE", relative_url: relative_url, data: data)
|
352
|
+
end
|
353
|
+
|
354
|
+
def post(relative_url, data)
|
355
|
+
add_entry(method: "POST", relative_url: relative_url, data: data)
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
def batch
|
360
|
+
yield builder = BatchBuilder.new
|
361
|
+
|
362
|
+
requests = builder.build
|
363
|
+
|
364
|
+
response = post("/v1/batch", batch: requests)
|
365
|
+
responses = parse_collection(BatchEntryResponse, "batch", response)
|
366
|
+
|
367
|
+
entries = requests.zip(responses).map do |request, response|
|
368
|
+
response.request = request
|
369
|
+
response
|
370
|
+
end
|
371
|
+
|
372
|
+
result = BatchResponse.new(entries)
|
373
|
+
|
374
|
+
if result.errors?
|
375
|
+
msg = "Batch contains #{result.errors.count} errors"
|
376
|
+
raise BatchResponse::PartialSuccessError.new(msg, result)
|
377
|
+
end
|
378
|
+
|
379
|
+
result
|
380
|
+
end
|
381
|
+
|
311
382
|
# Public: Deletes an external event from the specified calendar
|
312
383
|
#
|
313
384
|
# calendar_id - The String Cronofy ID for the calendar to delete the event
|
@@ -1231,35 +1302,6 @@ module Cronofy
|
|
1231
1302
|
end
|
1232
1303
|
end
|
1233
1304
|
|
1234
|
-
def to_iso8601(value)
|
1235
|
-
case value
|
1236
|
-
when NilClass
|
1237
|
-
nil
|
1238
|
-
when Time
|
1239
|
-
value.getutc.iso8601
|
1240
|
-
else
|
1241
|
-
value.iso8601
|
1242
|
-
end
|
1243
|
-
end
|
1244
|
-
|
1245
|
-
def encode_event_time(time)
|
1246
|
-
result = time
|
1247
|
-
|
1248
|
-
case time
|
1249
|
-
when String
|
1250
|
-
time
|
1251
|
-
when Hash
|
1252
|
-
if time[:time]
|
1253
|
-
encoded_time = encode_event_time(time[:time])
|
1254
|
-
time.merge(time: encoded_time)
|
1255
|
-
else
|
1256
|
-
time
|
1257
|
-
end
|
1258
|
-
else
|
1259
|
-
to_iso8601(time)
|
1260
|
-
end
|
1261
|
-
end
|
1262
|
-
|
1263
1305
|
class PagedResultIterator
|
1264
1306
|
include Enumerable
|
1265
1307
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Cronofy
|
2
|
+
module TimeEncoding
|
3
|
+
def encode_event_time(value)
|
4
|
+
case value
|
5
|
+
when String
|
6
|
+
value
|
7
|
+
when Hash
|
8
|
+
if value[:time]
|
9
|
+
encoded_time = encode_event_time(value[:time])
|
10
|
+
value.merge(time: encoded_time)
|
11
|
+
else
|
12
|
+
value
|
13
|
+
end
|
14
|
+
else
|
15
|
+
to_iso8601(value)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_iso8601(value)
|
20
|
+
case value
|
21
|
+
when NilClass
|
22
|
+
nil
|
23
|
+
when Time
|
24
|
+
value.getutc.iso8601
|
25
|
+
else
|
26
|
+
value.iso8601
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
data/lib/cronofy/types.rb
CHANGED
@@ -193,6 +193,39 @@ module Cronofy
|
|
193
193
|
class Account < CronofyMash
|
194
194
|
end
|
195
195
|
|
196
|
+
BatchEntry = Struct.new(:request, :response)
|
197
|
+
|
198
|
+
class BatchEntryRequest < CronofyMash
|
199
|
+
end
|
200
|
+
|
201
|
+
class BatchEntryResponse < CronofyMash
|
202
|
+
end
|
203
|
+
|
204
|
+
class BatchResponse
|
205
|
+
class PartialSuccessError < CronofyError
|
206
|
+
attr_reader :batch_response
|
207
|
+
|
208
|
+
def initialize(message, batch_response)
|
209
|
+
super(message)
|
210
|
+
@batch_response = batch_response
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
attr_reader :entries
|
215
|
+
|
216
|
+
def initialize(entries)
|
217
|
+
@entries = entries
|
218
|
+
end
|
219
|
+
|
220
|
+
def errors
|
221
|
+
entries.select { |entry| (entry.status % 100) != 2 }
|
222
|
+
end
|
223
|
+
|
224
|
+
def errors?
|
225
|
+
errors.any?
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
196
229
|
class UserInfo < CronofyMash
|
197
230
|
end
|
198
231
|
|
data/lib/cronofy/version.rb
CHANGED
@@ -1885,4 +1885,216 @@ describe Cronofy::Client do
|
|
1885
1885
|
it_behaves_like 'a Cronofy request'
|
1886
1886
|
|
1887
1887
|
end
|
1888
|
+
|
1889
|
+
describe "Batch requests" do
|
1890
|
+
context "upserting an event" do
|
1891
|
+
let(:calendar_id) { 'calendar_id_123'}
|
1892
|
+
let(:request_url) { "https://api.cronofy.com/v1/batch" }
|
1893
|
+
let(:url) { URI("https://example.com") }
|
1894
|
+
let(:method) { :post }
|
1895
|
+
let(:request_headers) { json_request_headers }
|
1896
|
+
|
1897
|
+
let(:start_datetime) { Time.utc(2014, 8, 5, 15, 30, 0) }
|
1898
|
+
let(:end_datetime) { Time.utc(2014, 8, 5, 17, 0, 0) }
|
1899
|
+
let(:encoded_start_datetime) { "2014-08-05T15:30:00Z" }
|
1900
|
+
let(:encoded_end_datetime) { "2014-08-05T17:00:00Z" }
|
1901
|
+
let(:location) { { :description => "Board room" } }
|
1902
|
+
|
1903
|
+
let(:event) do
|
1904
|
+
{
|
1905
|
+
:event_id => "qTtZdczOccgaPncGJaCiLg",
|
1906
|
+
:summary => "Board meeting",
|
1907
|
+
:description => "Discuss plans for the next quarter.",
|
1908
|
+
:start => start_datetime,
|
1909
|
+
:end => end_datetime,
|
1910
|
+
:url => url,
|
1911
|
+
:location => location,
|
1912
|
+
:reminders => [
|
1913
|
+
{ :minutes => 60 },
|
1914
|
+
{ :minutes => 0 },
|
1915
|
+
{ :minutes => 10 },
|
1916
|
+
],
|
1917
|
+
}
|
1918
|
+
end
|
1919
|
+
|
1920
|
+
let(:request_body) do
|
1921
|
+
{
|
1922
|
+
:batch => [
|
1923
|
+
{
|
1924
|
+
:method => "POST",
|
1925
|
+
:relative_url => "/v1/calendars/#{calendar_id}/events",
|
1926
|
+
:data => {
|
1927
|
+
:event_id => "qTtZdczOccgaPncGJaCiLg",
|
1928
|
+
:summary => "Board meeting",
|
1929
|
+
:description => "Discuss plans for the next quarter.",
|
1930
|
+
:start => encoded_start_datetime,
|
1931
|
+
:end => encoded_end_datetime,
|
1932
|
+
:url => url.to_s,
|
1933
|
+
:location => location,
|
1934
|
+
:reminders => [
|
1935
|
+
{ :minutes => 60 },
|
1936
|
+
{ :minutes => 0 },
|
1937
|
+
{ :minutes => 10 },
|
1938
|
+
],
|
1939
|
+
}
|
1940
|
+
}
|
1941
|
+
]
|
1942
|
+
}
|
1943
|
+
end
|
1944
|
+
|
1945
|
+
let(:correct_response_code) { 207 }
|
1946
|
+
let(:correct_response_body) do
|
1947
|
+
{
|
1948
|
+
"batch" => [
|
1949
|
+
{ "status" => 202 }
|
1950
|
+
]
|
1951
|
+
}
|
1952
|
+
end
|
1953
|
+
|
1954
|
+
subject do
|
1955
|
+
client.batch do |batch|
|
1956
|
+
batch.upsert_event(calendar_id, event)
|
1957
|
+
end
|
1958
|
+
end
|
1959
|
+
|
1960
|
+
it_behaves_like "a Cronofy request"
|
1961
|
+
end
|
1962
|
+
|
1963
|
+
context "deleting an event" do
|
1964
|
+
let(:calendar_id) { 'calendar_id_123'}
|
1965
|
+
let(:method) { :post }
|
1966
|
+
let(:request_url) { "https://api.cronofy.com/v1/batch" }
|
1967
|
+
let(:request_headers) { json_request_headers }
|
1968
|
+
|
1969
|
+
let(:event_id) { "asd1knkjsndk123123" }
|
1970
|
+
|
1971
|
+
let(:request_body) do
|
1972
|
+
{
|
1973
|
+
:batch => [
|
1974
|
+
{
|
1975
|
+
:method => "DELETE",
|
1976
|
+
:relative_url => "/v1/calendars/#{calendar_id}/events",
|
1977
|
+
:data => {
|
1978
|
+
:event_id => event_id,
|
1979
|
+
}
|
1980
|
+
}
|
1981
|
+
]
|
1982
|
+
}
|
1983
|
+
end
|
1984
|
+
|
1985
|
+
let(:correct_response_code) { 207 }
|
1986
|
+
let(:correct_response_body) do
|
1987
|
+
{
|
1988
|
+
"batch" => [
|
1989
|
+
{ "status" => 202 }
|
1990
|
+
]
|
1991
|
+
}
|
1992
|
+
end
|
1993
|
+
|
1994
|
+
subject do
|
1995
|
+
client.batch do |batch|
|
1996
|
+
batch.delete_event(calendar_id, event_id)
|
1997
|
+
end
|
1998
|
+
end
|
1999
|
+
|
2000
|
+
it_behaves_like "a Cronofy request"
|
2001
|
+
end
|
2002
|
+
|
2003
|
+
context "deleting an external event" do
|
2004
|
+
let(:calendar_id) { 'calendar_id_123'}
|
2005
|
+
let(:method) { :post }
|
2006
|
+
let(:request_url) { "https://api.cronofy.com/v1/batch" }
|
2007
|
+
let(:request_headers) { json_request_headers }
|
2008
|
+
|
2009
|
+
let(:event_uid) { "evt_external_12345abcde" }
|
2010
|
+
|
2011
|
+
let(:request_body) do
|
2012
|
+
{
|
2013
|
+
:batch => [
|
2014
|
+
{
|
2015
|
+
:method => "DELETE",
|
2016
|
+
:relative_url => "/v1/calendars/#{calendar_id}/events",
|
2017
|
+
:data => {
|
2018
|
+
:event_uid => event_uid,
|
2019
|
+
}
|
2020
|
+
}
|
2021
|
+
]
|
2022
|
+
}
|
2023
|
+
end
|
2024
|
+
|
2025
|
+
let(:correct_response_code) { 207 }
|
2026
|
+
let(:correct_response_body) do
|
2027
|
+
{
|
2028
|
+
"batch" => [
|
2029
|
+
{ "status" => 202 }
|
2030
|
+
]
|
2031
|
+
}
|
2032
|
+
end
|
2033
|
+
|
2034
|
+
subject do
|
2035
|
+
client.batch do |batch|
|
2036
|
+
batch.delete_external_event(calendar_id, event_uid)
|
2037
|
+
end
|
2038
|
+
end
|
2039
|
+
|
2040
|
+
it_behaves_like "a Cronofy request"
|
2041
|
+
end
|
2042
|
+
|
2043
|
+
context "partial success" do
|
2044
|
+
let(:method) { :post }
|
2045
|
+
let(:request_url) { "https://api.cronofy.com/v1/batch" }
|
2046
|
+
let(:request_headers) { json_request_headers }
|
2047
|
+
|
2048
|
+
let(:request_body) do
|
2049
|
+
{
|
2050
|
+
:batch => [
|
2051
|
+
{
|
2052
|
+
:method => "DELETE",
|
2053
|
+
:relative_url => "/v1/calendars/cal_123_abc/events",
|
2054
|
+
:data => {
|
2055
|
+
:event_id => "123",
|
2056
|
+
}
|
2057
|
+
},
|
2058
|
+
{
|
2059
|
+
:method => "DELETE",
|
2060
|
+
:relative_url => "/v1/calendars/cal_123_def/events",
|
2061
|
+
:data => {
|
2062
|
+
:event_id => "456",
|
2063
|
+
}
|
2064
|
+
}
|
2065
|
+
]
|
2066
|
+
}
|
2067
|
+
end
|
2068
|
+
|
2069
|
+
let(:correct_response_code) { 207 }
|
2070
|
+
let(:correct_response_body) do
|
2071
|
+
{
|
2072
|
+
"batch" => [
|
2073
|
+
{ "status" => 202 },
|
2074
|
+
{ "status" => 404 },
|
2075
|
+
]
|
2076
|
+
}
|
2077
|
+
end
|
2078
|
+
|
2079
|
+
subject do
|
2080
|
+
client.batch do |batch|
|
2081
|
+
batch.delete_event("cal_123_abc", "123")
|
2082
|
+
batch.delete_event("cal_123_def", "456")
|
2083
|
+
end
|
2084
|
+
end
|
2085
|
+
|
2086
|
+
it "raises an error" do
|
2087
|
+
stub_request(method, request_url)
|
2088
|
+
.with(headers: request_headers,
|
2089
|
+
body: request_body)
|
2090
|
+
.to_return(status: correct_response_code,
|
2091
|
+
headers: correct_response_headers,
|
2092
|
+
body: correct_response_body.to_json)
|
2093
|
+
|
2094
|
+
expect { subject }.to raise_error(Cronofy::BatchResponse::PartialSuccessError) do |error|
|
2095
|
+
expect(error.batch_response.errors?).to be true
|
2096
|
+
end
|
2097
|
+
end
|
2098
|
+
end
|
2099
|
+
end
|
1888
2100
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cronofy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.26.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergii Paryzhskyi
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-12-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: oauth2
|
@@ -121,6 +121,7 @@ files:
|
|
121
121
|
- lib/cronofy/client.rb
|
122
122
|
- lib/cronofy/errors.rb
|
123
123
|
- lib/cronofy/response_parser.rb
|
124
|
+
- lib/cronofy/time_encoding.rb
|
124
125
|
- lib/cronofy/types.rb
|
125
126
|
- lib/cronofy/version.rb
|
126
127
|
- spec/lib/cronofy/auth_spec.rb
|
@@ -150,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
151
|
version: '0'
|
151
152
|
requirements: []
|
152
153
|
rubyforge_project:
|
153
|
-
rubygems_version: 2.6.
|
154
|
+
rubygems_version: 2.6.6
|
154
155
|
signing_key:
|
155
156
|
specification_version: 4
|
156
157
|
summary: Cronofy - one API for all the calendars
|