cronofy 0.25.1 → 0.26.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 +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
|