tilia-vobject 4.0.0.pre.alpha2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rubocop.yml +32 -0
  4. data/.simplecov +4 -0
  5. data/.travis.yml +3 -0
  6. data/CHANGELOG.sabre.md +626 -0
  7. data/CONTRIBUTING.md +25 -0
  8. data/Gemfile +17 -0
  9. data/Gemfile.lock +68 -0
  10. data/LICENSE +27 -0
  11. data/LICENSE.sabre +27 -0
  12. data/README.md +63 -0
  13. data/Rakefile +17 -0
  14. data/bin/vobject +7 -0
  15. data/lib/tilia/v_object/birthday_calendar_generator.rb +142 -0
  16. data/lib/tilia/v_object/cli.rb +582 -0
  17. data/lib/tilia/v_object/component/available.rb +107 -0
  18. data/lib/tilia/v_object/component/v_alarm.rb +114 -0
  19. data/lib/tilia/v_object/component/v_availability.rb +128 -0
  20. data/lib/tilia/v_object/component/v_calendar.rb +468 -0
  21. data/lib/tilia/v_object/component/v_card.rb +457 -0
  22. data/lib/tilia/v_object/component/v_event.rb +127 -0
  23. data/lib/tilia/v_object/component/v_free_busy.rb +81 -0
  24. data/lib/tilia/v_object/component/v_journal.rb +75 -0
  25. data/lib/tilia/v_object/component/v_time_zone.rb +51 -0
  26. data/lib/tilia/v_object/component/v_todo.rb +147 -0
  27. data/lib/tilia/v_object/component.rb +591 -0
  28. data/lib/tilia/v_object/date_time_parser.rb +486 -0
  29. data/lib/tilia/v_object/document.rb +218 -0
  30. data/lib/tilia/v_object/element_list.rb +18 -0
  31. data/lib/tilia/v_object/eof_exception.rb +8 -0
  32. data/lib/tilia/v_object/free_busy_data.rb +149 -0
  33. data/lib/tilia/v_object/free_busy_generator.rb +465 -0
  34. data/lib/tilia/v_object/i_tip/broker.rb +909 -0
  35. data/lib/tilia/v_object/i_tip/i_tip_exception.rb +9 -0
  36. data/lib/tilia/v_object/i_tip/message.rb +109 -0
  37. data/lib/tilia/v_object/i_tip/same_organizer_for_all_components_exception.rb +13 -0
  38. data/lib/tilia/v_object/i_tip.rb +10 -0
  39. data/lib/tilia/v_object/node.rb +192 -0
  40. data/lib/tilia/v_object/parameter.rb +327 -0
  41. data/lib/tilia/v_object/parse_exception.rb +7 -0
  42. data/lib/tilia/v_object/parser/json.rb +149 -0
  43. data/lib/tilia/v_object/parser/mime_dir.rb +543 -0
  44. data/lib/tilia/v_object/parser/parser.rb +61 -0
  45. data/lib/tilia/v_object/parser/xml/element/key_value.rb +60 -0
  46. data/lib/tilia/v_object/parser/xml/element.rb +11 -0
  47. data/lib/tilia/v_object/parser/xml.rb +322 -0
  48. data/lib/tilia/v_object/parser.rb +10 -0
  49. data/lib/tilia/v_object/property/binary.rb +96 -0
  50. data/lib/tilia/v_object/property/boolean.rb +57 -0
  51. data/lib/tilia/v_object/property/flat_text.rb +52 -0
  52. data/lib/tilia/v_object/property/float_value.rb +107 -0
  53. data/lib/tilia/v_object/property/i_calendar/cal_address.rb +49 -0
  54. data/lib/tilia/v_object/property/i_calendar/date.rb +15 -0
  55. data/lib/tilia/v_object/property/i_calendar/date_time.rb +330 -0
  56. data/lib/tilia/v_object/property/i_calendar/duration.rb +65 -0
  57. data/lib/tilia/v_object/property/i_calendar/period.rb +124 -0
  58. data/lib/tilia/v_object/property/i_calendar/recur.rb +173 -0
  59. data/lib/tilia/v_object/property/i_calendar.rb +14 -0
  60. data/lib/tilia/v_object/property/integer_value.rb +60 -0
  61. data/lib/tilia/v_object/property/text.rb +352 -0
  62. data/lib/tilia/v_object/property/time.rb +85 -0
  63. data/lib/tilia/v_object/property/unknown.rb +30 -0
  64. data/lib/tilia/v_object/property/uri.rb +78 -0
  65. data/lib/tilia/v_object/property/utc_offset.rb +56 -0
  66. data/lib/tilia/v_object/property/v_card/date.rb +31 -0
  67. data/lib/tilia/v_object/property/v_card/date_and_or_time.rb +343 -0
  68. data/lib/tilia/v_object/property/v_card/date_time.rb +22 -0
  69. data/lib/tilia/v_object/property/v_card/language_tag.rb +41 -0
  70. data/lib/tilia/v_object/property/v_card/time_stamp.rb +74 -0
  71. data/lib/tilia/v_object/property/v_card.rb +13 -0
  72. data/lib/tilia/v_object/property.rb +532 -0
  73. data/lib/tilia/v_object/reader.rb +73 -0
  74. data/lib/tilia/v_object/recur/event_iterator.rb +417 -0
  75. data/lib/tilia/v_object/recur/no_instances_exception.rb +11 -0
  76. data/lib/tilia/v_object/recur/r_date_iterator.rb +138 -0
  77. data/lib/tilia/v_object/recur/r_rule_iterator.rb +717 -0
  78. data/lib/tilia/v_object/recur.rb +10 -0
  79. data/lib/tilia/v_object/settings.rb +32 -0
  80. data/lib/tilia/v_object/splitter/i_calendar.rb +95 -0
  81. data/lib/tilia/v_object/splitter/splitter_interface.rb +31 -0
  82. data/lib/tilia/v_object/splitter/v_card.rb +56 -0
  83. data/lib/tilia/v_object/splitter.rb +9 -0
  84. data/lib/tilia/v_object/string_util.rb +58 -0
  85. data/lib/tilia/v_object/time_zone_data/exchange_zones.rb +96 -0
  86. data/lib/tilia/v_object/time_zone_data/lotus_zones.rb +104 -0
  87. data/lib/tilia/v_object/time_zone_data/php_zones.rb +49 -0
  88. data/lib/tilia/v_object/time_zone_data/windows_zones.rb +121 -0
  89. data/lib/tilia/v_object/time_zone_data.rb +10 -0
  90. data/lib/tilia/v_object/time_zone_util.rb +213 -0
  91. data/lib/tilia/v_object/uuid_util.rb +51 -0
  92. data/lib/tilia/v_object/v_card_converter.rb +354 -0
  93. data/lib/tilia/v_object/version.rb +9 -0
  94. data/lib/tilia/v_object/writer.rb +56 -0
  95. data/lib/tilia/v_object.rb +45 -0
  96. data/lib/tilia/vobject.rb +1 -0
  97. data/resources/schema/xcal.rng +1192 -0
  98. data/resources/schema/xcard.rng +388 -0
  99. data/test/test_helper.rb +56 -0
  100. data/test/v_object/attach_issue_test.rb +19 -0
  101. data/test/v_object/birthday_calendar_generator_test.rb +463 -0
  102. data/test/v_object/cli_mock.rb +19 -0
  103. data/test/v_object/cli_test.rb +460 -0
  104. data/test/v_object/component/available_test.rb +59 -0
  105. data/test/v_object/component/v_alarm_test.rb +160 -0
  106. data/test/v_object/component/v_availability_test.rb +388 -0
  107. data/test/v_object/component/v_calendar_test.rb +646 -0
  108. data/test/v_object/component/v_card_test.rb +258 -0
  109. data/test/v_object/component/v_event_test.rb +85 -0
  110. data/test/v_object/component/v_free_busy_test.rb +59 -0
  111. data/test/v_object/component/v_journal_test.rb +85 -0
  112. data/test/v_object/component/v_time_zone_test.rb +47 -0
  113. data/test/v_object/component/v_todo_test.rb +172 -0
  114. data/test/v_object/component_test.rb +419 -0
  115. data/test/v_object/date_time_parser_test.rb +526 -0
  116. data/test/v_object/document_test.rb +71 -0
  117. data/test/v_object/element_list_test.rb +27 -0
  118. data/test/v_object/em_client_test.rb +53 -0
  119. data/test/v_object/empty_parameter_test.rb +65 -0
  120. data/test/v_object/empty_value_issue_test.rb +25 -0
  121. data/test/v_object/fake_component.rb +21 -0
  122. data/test/v_object/free_busy_data_test.rb +285 -0
  123. data/test/v_object/free_busy_generator_test.rb +637 -0
  124. data/test/v_object/google_colon_escaping_test.rb +27 -0
  125. data/test/v_object/i_calendar/attach_parse_test.rb +24 -0
  126. data/test/v_object/i_tip/broker_attendee_reply_test.rb +1042 -0
  127. data/test/v_object/i_tip/broker_delete_event_test.rb +175 -0
  128. data/test/v_object/i_tip/broker_new_event_test.rb +440 -0
  129. data/test/v_object/i_tip/broker_process_message_test.rb +153 -0
  130. data/test/v_object/i_tip/broker_process_reply_test.rb +402 -0
  131. data/test/v_object/i_tip/broker_tester.rb +71 -0
  132. data/test/v_object/i_tip/broker_update_event_test.rb +763 -0
  133. data/test/v_object/i_tip/evolution_test.rb +2644 -0
  134. data/test/v_object/i_tip/message_test.rb +25 -0
  135. data/test/v_object/issue153.vcf +352 -0
  136. data/test/v_object/issue153_test.rb +12 -0
  137. data/test/v_object/issue26_test.rb +25 -0
  138. data/test/v_object/issue36_work_around_test.rb +37 -0
  139. data/test/v_object/issue40_test.rb +26 -0
  140. data/test/v_object/issue64.vcf +351 -0
  141. data/test/v_object/issue64_test.rb +17 -0
  142. data/test/v_object/issue96_test.rb +22 -0
  143. data/test/v_object/issue_undefined_index_test.rb +24 -0
  144. data/test/v_object/j_cal_test.rb +150 -0
  145. data/test/v_object/j_card_test.rb +192 -0
  146. data/test/v_object/line_folding_issue_test.rb +19 -0
  147. data/test/v_object/mock_document.rb +6 -0
  148. data/test/v_object/parameter_test.rb +109 -0
  149. data/test/v_object/parser/json_test.rb +370 -0
  150. data/test/v_object/parser/mime_dir_test.rb +14 -0
  151. data/test/v_object/parser/quoted_printable_test.rb +78 -0
  152. data/test/v_object/parser/xml_test.rb +2563 -0
  153. data/test/v_object/property/binary_test.rb +12 -0
  154. data/test/v_object/property/boolean_test.rb +18 -0
  155. data/test/v_object/property/compound_test.rb +43 -0
  156. data/test/v_object/property/float_test.rb +20 -0
  157. data/test/v_object/property/i_calendar/cal_address_test.rb +26 -0
  158. data/test/v_object/property/i_calendar/date_time_test.rb +303 -0
  159. data/test/v_object/property/i_calendar/duration_test.rb +14 -0
  160. data/test/v_object/property/i_calendar/recur_test.rb +39 -0
  161. data/test/v_object/property/text_test.rb +81 -0
  162. data/test/v_object/property/v_card/date_and_or_time_test.rb +205 -0
  163. data/test/v_object/property/v_card/language_tag_test.rb +35 -0
  164. data/test/v_object/property_test.rb +338 -0
  165. data/test/v_object/reader_test.rb +403 -0
  166. data/test/v_object/recur/event_iterator/by_month_in_daily_test.rb +52 -0
  167. data/test/v_object/recur/event_iterator/by_set_pos_hang_test.rb +55 -0
  168. data/test/v_object/recur/event_iterator/expand_floating_times_test.rb +109 -0
  169. data/test/v_object/recur/event_iterator/fifth_tuesday_problem_test.rb +45 -0
  170. data/test/v_object/recur/event_iterator/incorrect_expand_test.rb +53 -0
  171. data/test/v_object/recur/event_iterator/infinite_loop_problem_test.rb +75 -0
  172. data/test/v_object/recur/event_iterator/issue48_test.rb +43 -0
  173. data/test/v_object/recur/event_iterator/issue50_test.rb +123 -0
  174. data/test/v_object/recur/event_iterator/main_test.rb +1222 -0
  175. data/test/v_object/recur/event_iterator/missing_overridden_test.rb +55 -0
  176. data/test/v_object/recur/event_iterator/no_instances_test.rb +32 -0
  177. data/test/v_object/recur/event_iterator/override_first_event_test.rb +106 -0
  178. data/test/v_object/recur/r_date_iterator_test.rb +44 -0
  179. data/test/v_object/recur/r_rule_iterator_test.rb +608 -0
  180. data/test/v_object/recurrence_iterator/UntilRespectsTimezoneTest.ics +39 -0
  181. data/test/v_object/slash_r_test.rb +15 -0
  182. data/test/v_object/splitter/i_calendar_test.rb +299 -0
  183. data/test/v_object/splitter/v_card_test.rb +173 -0
  184. data/test/v_object/string_util_test.rb +37 -0
  185. data/test/v_object/test_case.rb +42 -0
  186. data/test/v_object/time_zone_util_test.rb +271 -0
  187. data/test/v_object/uuid_util_test.rb +18 -0
  188. data/test/v_object/v_card21_test.rb +43 -0
  189. data/test/v_object/v_card_converter_test.rb +419 -0
  190. data/test/v_object/version_test.rb +15 -0
  191. data/test/v_object/writer_test.rb +33 -0
  192. data/tilia-vobject.gemspec +17 -0
  193. metadata +308 -0
@@ -0,0 +1,763 @@
1
+ require 'test_helper'
2
+ require 'v_object/i_tip/broker_tester'
3
+
4
+ module Tilia
5
+ module VObject
6
+ class BrokerUpdateEventTest < ITip::BrokerTester
7
+ def test_invite_change
8
+ old_message = <<ICS
9
+ BEGIN:VCALENDAR
10
+ VERSION:2.0
11
+ BEGIN:VEVENT
12
+ UID:foobar
13
+ SEQUENCE:1
14
+ SUMMARY:foo
15
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
16
+ ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
17
+ ATTENDEE;CN=One:mailto:one@example.org
18
+ ATTENDEE;CN=Two:mailto:two@example.org
19
+ DTSTART:20140716T120000Z
20
+ END:VEVENT
21
+ END:VCALENDAR
22
+ ICS
23
+
24
+ new_message = <<ICS
25
+ BEGIN:VCALENDAR
26
+ VERSION:2.0
27
+ BEGIN:VEVENT
28
+ UID:foobar
29
+ SEQUENCE:2
30
+ SUMMARY:foo
31
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
32
+ ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
33
+ ATTENDEE;CN=Two:mailto:two@example.org
34
+ ATTENDEE;CN=Three:mailto:three@example.org
35
+ DTSTART:20140716T120000Z
36
+ END:VEVENT
37
+ END:VCALENDAR
38
+ ICS
39
+
40
+ version = Tilia::VObject::Version::VERSION
41
+
42
+ expected = [
43
+ {
44
+ 'uid' => 'foobar',
45
+ 'method' => 'CANCEL',
46
+ 'component' => 'VEVENT',
47
+ 'sender' => 'mailto:strunk@example.org',
48
+ 'sender_name' => 'Strunk',
49
+ 'recipient' => 'mailto:one@example.org',
50
+ 'recipient_name' => 'One',
51
+ 'significant_change' => true,
52
+ 'message' => <<ICS
53
+ BEGIN:VCALENDAR
54
+ VERSION:2.0
55
+ PRODID:-//Tilia//Tilia VObject #{version}//EN
56
+ CALSCALE:GREGORIAN
57
+ METHOD:CANCEL
58
+ BEGIN:VEVENT
59
+ UID:foobar
60
+ SEQUENCE:2
61
+ SUMMARY:foo
62
+ DTSTART:20140716T120000Z
63
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
64
+ ATTENDEE;CN=One:mailto:one@example.org
65
+ END:VEVENT
66
+ END:VCALENDAR
67
+ ICS
68
+ },
69
+ {
70
+ 'uid' => 'foobar',
71
+ 'method' => 'REQUEST',
72
+ 'component' => 'VEVENT',
73
+ 'sender' => 'mailto:strunk@example.org',
74
+ 'sender_name' => 'Strunk',
75
+ 'recipient' => 'mailto:two@example.org',
76
+ 'recipient_name' => 'Two',
77
+ 'significant_change' => false,
78
+ 'message' => <<ICS
79
+ BEGIN:VCALENDAR
80
+ VERSION:2.0
81
+ PRODID:-//Tilia//Tilia VObject #{version}//EN
82
+ CALSCALE:GREGORIAN
83
+ METHOD:REQUEST
84
+ BEGIN:VEVENT
85
+ UID:foobar
86
+ SEQUENCE:2
87
+ SUMMARY:foo
88
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
89
+ ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
90
+ ATTENDEE;CN=Two;PARTSTAT=NEEDS-ACTION:mailto:two@example.org
91
+ ATTENDEE;CN=Three;PARTSTAT=NEEDS-ACTION:mailto:three@example.org
92
+ DTSTART:20140716T120000Z
93
+ END:VEVENT
94
+ END:VCALENDAR
95
+ ICS
96
+
97
+ },
98
+ {
99
+ 'uid' => 'foobar',
100
+ 'method' => 'REQUEST',
101
+ 'component' => 'VEVENT',
102
+ 'sender' => 'mailto:strunk@example.org',
103
+ 'sender_name' => 'Strunk',
104
+ 'recipient' => 'mailto:three@example.org',
105
+ 'recipient_name' => 'Three',
106
+ 'significant_change' => true,
107
+ 'message' => <<ICS
108
+ BEGIN:VCALENDAR
109
+ VERSION:2.0
110
+ PRODID:-//Tilia//Tilia VObject #{version}//EN
111
+ CALSCALE:GREGORIAN
112
+ METHOD:REQUEST
113
+ BEGIN:VEVENT
114
+ UID:foobar
115
+ SEQUENCE:2
116
+ SUMMARY:foo
117
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
118
+ ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
119
+ ATTENDEE;CN=Two;PARTSTAT=NEEDS-ACTION:mailto:two@example.org
120
+ ATTENDEE;CN=Three;PARTSTAT=NEEDS-ACTION:mailto:three@example.org
121
+ DTSTART:20140716T120000Z
122
+ END:VEVENT
123
+ END:VCALENDAR
124
+ ICS
125
+
126
+ }
127
+ ]
128
+
129
+ parse(old_message, new_message, expected, 'mailto:strunk@example.org')
130
+ end
131
+
132
+ def test_invite_change_from_non_scheduling_to_scheduling_object
133
+ old_message = <<ICS
134
+ BEGIN:VCALENDAR
135
+ VERSION:2.0
136
+ BEGIN:VEVENT
137
+ UID:foobar
138
+ SEQUENCE:1
139
+ DTSTART:20140716T120000Z
140
+ END:VEVENT
141
+ END:VCALENDAR
142
+ ICS
143
+
144
+ new_message = <<ICS
145
+ BEGIN:VCALENDAR
146
+ VERSION:2.0
147
+ BEGIN:VEVENT
148
+ UID:foobar
149
+ SEQUENCE:2
150
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
151
+ ATTENDEE;CN=One:mailto:one@example.org
152
+ DTSTART:20140716T120000Z
153
+ END:VEVENT
154
+ END:VCALENDAR
155
+ ICS
156
+
157
+ version = Tilia::VObject::Version::VERSION
158
+
159
+ expected = [
160
+ {
161
+ 'uid' => 'foobar',
162
+ 'method' => 'REQUEST',
163
+ 'component' => 'VEVENT',
164
+ 'sender' => 'mailto:strunk@example.org',
165
+ 'sender_name' => 'Strunk',
166
+ 'recipient' => 'mailto:one@example.org',
167
+ 'recipient_name' => 'One',
168
+ 'message' => <<ICS
169
+ BEGIN:VCALENDAR
170
+ VERSION:2.0
171
+ PRODID:-//Tilia//Tilia VObject #{version}//EN
172
+ CALSCALE:GREGORIAN
173
+ METHOD:REQUEST
174
+ BEGIN:VEVENT
175
+ UID:foobar
176
+ SEQUENCE:2
177
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
178
+ ATTENDEE;CN=One;PARTSTAT=NEEDS-ACTION:mailto:one@example.org
179
+ DTSTART:20140716T120000Z
180
+ END:VEVENT
181
+ END:VCALENDAR
182
+ ICS
183
+ }
184
+ ]
185
+
186
+ parse(old_message, new_message, expected, 'mailto:strunk@example.org')
187
+ end
188
+
189
+ def test_invite_change_from_scheduling_to_non_scheduling_object
190
+ old_message = <<ICS
191
+ BEGIN:VCALENDAR
192
+ VERSION:2.0
193
+ BEGIN:VEVENT
194
+ UID:foobar
195
+ SEQUENCE:2
196
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
197
+ ATTENDEE;CN=One:mailto:one@example.org
198
+ DTSTART:20140716T120000Z
199
+ END:VEVENT
200
+ END:VCALENDAR
201
+ ICS
202
+
203
+ new_message = <<ICS
204
+ BEGIN:VCALENDAR
205
+ VERSION:2.0
206
+ BEGIN:VEVENT
207
+ UID:foobar
208
+ SEQUENCE:1
209
+ DTSTART:20140716T120000Z
210
+ END:VEVENT
211
+ END:VCALENDAR
212
+ ICS
213
+
214
+ version = Tilia::VObject::Version::VERSION
215
+
216
+ expected = [
217
+ {
218
+ 'uid' => 'foobar',
219
+ 'method' => 'CANCEL',
220
+ 'component' => 'VEVENT',
221
+ 'message' => <<ICS
222
+ BEGIN:VCALENDAR
223
+ VERSION:2.0
224
+ PRODID:-//Tilia//Tilia VObject #{version}//EN
225
+ CALSCALE:GREGORIAN
226
+ METHOD:CANCEL
227
+ BEGIN:VEVENT
228
+ UID:foobar
229
+ SEQUENCE:1
230
+ DTSTART:20140716T120000Z
231
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
232
+ ATTENDEE;CN=One:mailto:one@example.org
233
+ END:VEVENT
234
+ END:VCALENDAR
235
+ ICS
236
+ }
237
+ ]
238
+
239
+ parse(old_message, new_message, expected, 'mailto:strunk@example.org')
240
+ end
241
+
242
+ def test_no_attendees
243
+ old_message = <<ICS
244
+ BEGIN:VCALENDAR
245
+ VERSION:2.0
246
+ BEGIN:VEVENT
247
+ UID:foobar
248
+ SEQUENCE:1
249
+ DTSTART:20140716T120000Z
250
+ END:VEVENT
251
+ END:VCALENDAR
252
+ ICS
253
+
254
+ new_message = <<ICS
255
+ BEGIN:VCALENDAR
256
+ VERSION:2.0
257
+ BEGIN:VEVENT
258
+ UID:foobar
259
+ SEQUENCE:2
260
+ DTSTART:20140716T120000Z
261
+ END:VEVENT
262
+ END:VCALENDAR
263
+ ICS
264
+
265
+ expected = []
266
+ parse(old_message, new_message, expected, 'mailto:strunk@example.org')
267
+ end
268
+
269
+ def test_remove_instance
270
+ old_message = <<ICS
271
+ BEGIN:VCALENDAR
272
+ VERSION:2.0
273
+ BEGIN:VEVENT
274
+ UID:foobar
275
+ SEQUENCE:1
276
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
277
+ ATTENDEE;CN=One:mailto:one@example.org
278
+ DTSTART;TZID=America/Toronto:20140716T120000
279
+ RRULE:FREQ=WEEKLY
280
+ END:VEVENT
281
+ END:VCALENDAR
282
+ ICS
283
+
284
+ new_message = <<ICS
285
+ BEGIN:VCALENDAR
286
+ VERSION:2.0
287
+ BEGIN:VEVENT
288
+ UID:foobar
289
+ SEQUENCE:2
290
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
291
+ ATTENDEE;CN=One:mailto:one@example.org
292
+ DTSTART;TZID=America/Toronto:20140716T120000
293
+ RRULE:FREQ=WEEKLY
294
+ EXDATE;TZID=America/Toronto:20140724T120000
295
+ END:VEVENT
296
+ END:VCALENDAR
297
+ ICS
298
+
299
+ version = Tilia::VObject::Version::VERSION
300
+
301
+ expected = [
302
+ {
303
+ 'uid' => 'foobar',
304
+ 'method' => 'REQUEST',
305
+ 'component' => 'VEVENT',
306
+ 'sender' => 'mailto:strunk@example.org',
307
+ 'sender_name' => 'Strunk',
308
+ 'recipient' => 'mailto:one@example.org',
309
+ 'recipient_name' => 'One',
310
+ 'message' => <<ICS
311
+ BEGIN:VCALENDAR
312
+ VERSION:2.0
313
+ PRODID:-//Tilia//Tilia VObject #{version}//EN
314
+ CALSCALE:GREGORIAN
315
+ METHOD:REQUEST
316
+ BEGIN:VEVENT
317
+ UID:foobar
318
+ SEQUENCE:2
319
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
320
+ ATTENDEE;CN=One;PARTSTAT=NEEDS-ACTION:mailto:one@example.org
321
+ DTSTART;TZID=America/Toronto:20140716T120000
322
+ RRULE:FREQ=WEEKLY
323
+ EXDATE;TZID=America/Toronto:20140724T120000
324
+ END:VEVENT
325
+ END:VCALENDAR
326
+ ICS
327
+ }
328
+ ]
329
+
330
+ parse(old_message, new_message, expected, 'mailto:strunk@example.org')
331
+ end
332
+
333
+ # This test is identical to the first test, except this time we change the
334
+ # DURATION property.
335
+ #
336
+ # This should ensure that the message is significant for every attendee,
337
+ def test_invite_change_significant_change
338
+ old_message = <<ICS
339
+ BEGIN:VCALENDAR
340
+ VERSION:2.0
341
+ BEGIN:VEVENT
342
+ UID:foobar
343
+ DURATION:PT1H
344
+ SEQUENCE:1
345
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
346
+ ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
347
+ ATTENDEE;CN=One:mailto:one@example.org
348
+ ATTENDEE;CN=Two:mailto:two@example.org
349
+ DTSTART:20140716T120000Z
350
+ END:VEVENT
351
+ END:VCALENDAR
352
+ ICS
353
+
354
+ new_message = <<ICS
355
+ BEGIN:VCALENDAR
356
+ VERSION:2.0
357
+ BEGIN:VEVENT
358
+ UID:foobar
359
+ DURATION:PT2H
360
+ SEQUENCE:2
361
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
362
+ ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
363
+ ATTENDEE;CN=Two:mailto:two@example.org
364
+ ATTENDEE;CN=Three:mailto:three@example.org
365
+ DTSTART:20140716T120000Z
366
+ END:VEVENT
367
+ END:VCALENDAR
368
+ ICS
369
+
370
+ version = Tilia::VObject::Version::VERSION
371
+
372
+ expected = [
373
+ {
374
+ 'uid' => 'foobar',
375
+ 'method' => 'CANCEL',
376
+ 'component' => 'VEVENT',
377
+ 'sender' => 'mailto:strunk@example.org',
378
+ 'sender_name' => 'Strunk',
379
+ 'recipient' => 'mailto:one@example.org',
380
+ 'recipient_name' => 'One',
381
+ 'significant_change' => true,
382
+ 'message' => <<ICS
383
+ BEGIN:VCALENDAR
384
+ VERSION:2.0
385
+ PRODID:-//Tilia//Tilia VObject #{version}//EN
386
+ CALSCALE:GREGORIAN
387
+ METHOD:CANCEL
388
+ BEGIN:VEVENT
389
+ UID:foobar
390
+ SEQUENCE:2
391
+ DTSTART:20140716T120000Z
392
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
393
+ ATTENDEE;CN=One:mailto:one@example.org
394
+ END:VEVENT
395
+ END:VCALENDAR
396
+ ICS
397
+ },
398
+ {
399
+ 'uid' => 'foobar',
400
+ 'method' => 'REQUEST',
401
+ 'component' => 'VEVENT',
402
+ 'sender' => 'mailto:strunk@example.org',
403
+ 'sender_name' => 'Strunk',
404
+ 'recipient' => 'mailto:two@example.org',
405
+ 'recipient_name' => 'Two',
406
+ 'significant_change' => true,
407
+ 'message' => <<ICS
408
+ BEGIN:VCALENDAR
409
+ VERSION:2.0
410
+ PRODID:-//Tilia//Tilia VObject #{version}//EN
411
+ CALSCALE:GREGORIAN
412
+ METHOD:REQUEST
413
+ BEGIN:VEVENT
414
+ UID:foobar
415
+ DURATION:PT2H
416
+ SEQUENCE:2
417
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
418
+ ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
419
+ ATTENDEE;CN=Two;PARTSTAT=NEEDS-ACTION:mailto:two@example.org
420
+ ATTENDEE;CN=Three;PARTSTAT=NEEDS-ACTION:mailto:three@example.org
421
+ DTSTART:20140716T120000Z
422
+ END:VEVENT
423
+ END:VCALENDAR
424
+ ICS
425
+ },
426
+ {
427
+ 'uid' => 'foobar',
428
+ 'method' => 'REQUEST',
429
+ 'component' => 'VEVENT',
430
+ 'sender' => 'mailto:strunk@example.org',
431
+ 'sender_name' => 'Strunk',
432
+ 'recipient' => 'mailto:three@example.org',
433
+ 'recipient_name' => 'Three',
434
+ 'significant_change' => true,
435
+ 'message' => <<ICS
436
+ BEGIN:VCALENDAR
437
+ VERSION:2.0
438
+ PRODID:-//Tilia//Tilia VObject #{version}//EN
439
+ CALSCALE:GREGORIAN
440
+ METHOD:REQUEST
441
+ BEGIN:VEVENT
442
+ UID:foobar
443
+ DURATION:PT2H
444
+ SEQUENCE:2
445
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
446
+ ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
447
+ ATTENDEE;CN=Two;PARTSTAT=NEEDS-ACTION:mailto:two@example.org
448
+ ATTENDEE;CN=Three;PARTSTAT=NEEDS-ACTION:mailto:three@example.org
449
+ DTSTART:20140716T120000Z
450
+ END:VEVENT
451
+ END:VCALENDAR
452
+ ICS
453
+ }
454
+ ]
455
+
456
+ parse(old_message, new_message, expected, 'mailto:strunk@example.org')
457
+ end
458
+
459
+ def test_invite_no_change
460
+ old_message = <<ICS
461
+ BEGIN:VCALENDAR
462
+ VERSION:2.0
463
+ BEGIN:VEVENT
464
+ UID:foobar
465
+ SEQUENCE:1
466
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
467
+ ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
468
+ ATTENDEE;CN=One:mailto:one@example.org
469
+ DTSTART:20140716T120000Z
470
+ END:VEVENT
471
+ END:VCALENDAR
472
+ ICS
473
+
474
+ new_message = <<ICS
475
+ BEGIN:VCALENDAR
476
+ VERSION:2.0
477
+ BEGIN:VEVENT
478
+ UID:foobar
479
+ SEQUENCE:2
480
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
481
+ ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
482
+ ATTENDEE;CN=One:mailto:one@example.org
483
+ DTSTART:20140716T120000Z
484
+ END:VEVENT
485
+ END:VCALENDAR
486
+ ICS
487
+
488
+ version = Tilia::VObject::Version::VERSION
489
+
490
+ expected = [
491
+ {
492
+ 'uid' => 'foobar',
493
+ 'method' => 'REQUEST',
494
+ 'component' => 'VEVENT',
495
+ 'sender' => 'mailto:strunk@example.org',
496
+ 'sender_name' => 'Strunk',
497
+ 'recipient' => 'mailto:one@example.org',
498
+ 'recipient_name' => 'One',
499
+ 'significant_change' => false,
500
+ 'message' => <<ICS
501
+ BEGIN:VCALENDAR
502
+ VERSION:2.0
503
+ PRODID:-//Tilia//Tilia VObject #{version}//EN
504
+ CALSCALE:GREGORIAN
505
+ METHOD:REQUEST
506
+ BEGIN:VEVENT
507
+ UID:foobar
508
+ SEQUENCE:2
509
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
510
+ ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
511
+ ATTENDEE;CN=One;PARTSTAT=NEEDS-ACTION:mailto:one@example.org
512
+ DTSTART:20140716T120000Z
513
+ END:VEVENT
514
+ END:VCALENDAR
515
+ ICS
516
+ }
517
+ ]
518
+
519
+ parse(old_message, new_message, expected, 'mailto:strunk@example.org')
520
+ end
521
+
522
+ def test_invite_no_change_force_send
523
+ old_message = <<ICS
524
+ BEGIN:VCALENDAR
525
+ VERSION:2.0
526
+ BEGIN:VEVENT
527
+ UID:foobar
528
+ SEQUENCE:1
529
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
530
+ ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
531
+ ATTENDEE;CN=One:mailto:one@example.org
532
+ DTSTART:20140716T120000Z
533
+ END:VEVENT
534
+ END:VCALENDAR
535
+ ICS
536
+
537
+ new_message = <<ICS
538
+ BEGIN:VCALENDAR
539
+ VERSION:2.0
540
+ BEGIN:VEVENT
541
+ UID:foobar
542
+ SEQUENCE:2
543
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
544
+ ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
545
+ ATTENDEE;SCHEDULE-FORCE-SEND=REQUEST;CN=One:mailto:one@example.org
546
+ DTSTART:20140716T120000Z
547
+ END:VEVENT
548
+ END:VCALENDAR
549
+ ICS
550
+
551
+ version = Tilia::VObject::Version::VERSION
552
+
553
+ expected = [
554
+ {
555
+ 'uid' => 'foobar',
556
+ 'method' => 'REQUEST',
557
+ 'component' => 'VEVENT',
558
+ 'sender' => 'mailto:strunk@example.org',
559
+ 'sender_name' => 'Strunk',
560
+ 'recipient' => 'mailto:one@example.org',
561
+ 'recipient_name' => 'One',
562
+ 'significant_change' => true,
563
+ 'message' => <<ICS
564
+ BEGIN:VCALENDAR
565
+ VERSION:2.0
566
+ PRODID:-//Tilia//Tilia VObject #{version}//EN
567
+ CALSCALE:GREGORIAN
568
+ METHOD:REQUEST
569
+ BEGIN:VEVENT
570
+ UID:foobar
571
+ SEQUENCE:2
572
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
573
+ ATTENDEE;CN=Strunk;PARTSTAT=ACCEPTED:mailto:strunk@example.org
574
+ ATTENDEE;CN=One;PARTSTAT=NEEDS-ACTION:mailto:one@example.org
575
+ DTSTART:20140716T120000Z
576
+ END:VEVENT
577
+ END:VCALENDAR
578
+ ICS
579
+ }
580
+ ]
581
+
582
+ parse(old_message, new_message, expected, 'mailto:strunk@example.org')
583
+ end
584
+
585
+ def test_invite_remove_attendees
586
+ old_message = <<ICS
587
+ BEGIN:VCALENDAR
588
+ VERSION:2.0
589
+ BEGIN:VEVENT
590
+ UID:foobar
591
+ SEQUENCE:1
592
+ SUMMARY:foo
593
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
594
+ ATTENDEE;CN=Strunk:mailto:strunk@example.org
595
+ ATTENDEE;CN=One:mailto:one@example.org
596
+ ATTENDEE;CN=Two:mailto:two@example.org
597
+ DTSTART:20140716T120000Z
598
+ END:VEVENT
599
+ END:VCALENDAR
600
+ ICS
601
+
602
+ new_message = <<ICS
603
+ BEGIN:VCALENDAR
604
+ VERSION:2.0
605
+ BEGIN:VEVENT
606
+ UID:foobar
607
+ SEQUENCE:2
608
+ SUMMARY:foo
609
+ DTSTART:20140716T120000Z
610
+ END:VEVENT
611
+ END:VCALENDAR
612
+ ICS
613
+
614
+ version = Tilia::VObject::Version::VERSION
615
+
616
+ expected = [
617
+ {
618
+ 'uid' => 'foobar',
619
+ 'method' => 'CANCEL',
620
+ 'component' => 'VEVENT',
621
+ 'sender' => 'mailto:strunk@example.org',
622
+ 'sender_name' => 'Strunk',
623
+ 'recipient' => 'mailto:one@example.org',
624
+ 'recipient_name' => 'One',
625
+ 'significant_change' => true,
626
+ 'message' => <<ICS
627
+ BEGIN:VCALENDAR
628
+ VERSION:2.0
629
+ PRODID:-//Tilia//Tilia VObject #{version}//EN
630
+ CALSCALE:GREGORIAN
631
+ METHOD:CANCEL
632
+ BEGIN:VEVENT
633
+ UID:foobar
634
+ SEQUENCE:2
635
+ SUMMARY:foo
636
+ DTSTART:20140716T120000Z
637
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
638
+ ATTENDEE;CN=One:mailto:one@example.org
639
+ END:VEVENT
640
+ END:VCALENDAR
641
+ ICS
642
+
643
+ },
644
+ {
645
+ 'uid' => 'foobar',
646
+ 'method' => 'CANCEL',
647
+ 'component' => 'VEVENT',
648
+ 'sender' => 'mailto:strunk@example.org',
649
+ 'sender_name' => 'Strunk',
650
+ 'recipient' => 'mailto:two@example.org',
651
+ 'recipient_name' => 'Two',
652
+ 'significant_change' => true,
653
+ 'message' => <<ICS
654
+ BEGIN:VCALENDAR
655
+ VERSION:2.0
656
+ PRODID:-//Tilia//Tilia VObject #{version}//EN
657
+ CALSCALE:GREGORIAN
658
+ METHOD:CANCEL
659
+ BEGIN:VEVENT
660
+ UID:foobar
661
+ SEQUENCE:2
662
+ SUMMARY:foo
663
+ DTSTART:20140716T120000Z
664
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
665
+ ATTENDEE;CN=Two:mailto:two@example.org
666
+ END:VEVENT
667
+ END:VCALENDAR
668
+ ICS
669
+ }
670
+ ]
671
+
672
+ parse(old_message, new_message, expected, 'mailto:strunk@example.org')
673
+ end
674
+
675
+ def test_invite_change_exdate_order
676
+ old_message = <<ICS
677
+ BEGIN:VCALENDAR
678
+ VERSION:2.0
679
+ PRODID:-//Apple Inc.//Mac OS X 10.10.1//EN
680
+ CALSCALE:GREGORIAN
681
+ BEGIN:VEVENT
682
+ UID:foobar
683
+ SEQUENCE:0
684
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
685
+ ATTENDEE;CN=Strunk;CUTYPE=INDIVIDUAL;EMAIL=strunk@example.org;PARTSTAT=ACCE
686
+ PTED:mailto:strunk@example.org
687
+ ATTENDEE;CN=One;CUTYPE=INDIVIDUAL;EMAIL=one@example.org;PARTSTAT=ACCEPTED;R
688
+ OLE=REQ-PARTICIPANT;SCHEDULE-STATUS="1.2;Message delivered locally":mailto
689
+ :one@example.org
690
+ SUMMARY:foo
691
+ DTSTART:20141211T160000Z
692
+ DTEND:20141211T170000Z
693
+ RRULE:FREQ=WEEKLY
694
+ EXDATE:20141225T160000Z,20150101T160000Z
695
+ EXDATE:20150108T160000Z
696
+ END:VEVENT
697
+ END:VCALENDAR
698
+ ICS
699
+
700
+ new_message = <<ICS
701
+ BEGIN:VCALENDAR
702
+ VERSION:2.0
703
+ PRODID:-//Apple Inc.//Mac OS X 10.10.1//EN
704
+ CALSCALE:GREGORIAN
705
+ BEGIN:VEVENT
706
+ UID:foobar
707
+ SEQUENCE:1
708
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
709
+ ATTENDEE;CN=Strunk;CUTYPE=INDIVIDUAL;EMAIL=strunk@example.org;PARTSTAT=ACCE
710
+ PTED:mailto:strunk@example.org
711
+ ATTENDEE;CN=One;CUTYPE=INDIVIDUAL;EMAIL=one@example.org;PARTSTAT=ACCEPTED;R
712
+ OLE=REQ-PARTICIPANT;SCHEDULE-STATUS=1.2:mailto:one@example.org
713
+ DTSTART:20141211T160000Z
714
+ DTEND:20141211T170000Z
715
+ RRULE:FREQ=WEEKLY
716
+ EXDATE:20150101T160000Z
717
+ EXDATE:20150108T160000Z,20141225T160000Z
718
+ END:VEVENT
719
+ END:VCALENDAR
720
+ ICS
721
+
722
+ version = Tilia::VObject::Version::VERSION
723
+
724
+ expected = [
725
+ {
726
+ 'uid' => 'foobar',
727
+ 'method' => 'REQUEST',
728
+ 'component' => 'VEVENT',
729
+ 'sender' => 'mailto:strunk@example.org',
730
+ 'sender_name' => 'Strunk',
731
+ 'recipient' => 'mailto:one@example.org',
732
+ 'recipient_name' => 'One',
733
+ 'significant_change' => false,
734
+ 'message' => <<ICS
735
+ BEGIN:VCALENDAR
736
+ VERSION:2.0
737
+ PRODID:-//Tilia//Tilia VObject #{version}//EN
738
+ CALSCALE:GREGORIAN
739
+ METHOD:REQUEST
740
+ BEGIN:VEVENT
741
+ UID:foobar
742
+ SEQUENCE:1
743
+ ORGANIZER;CN=Strunk:mailto:strunk@example.org
744
+ ATTENDEE;CN=Strunk;CUTYPE=INDIVIDUAL;EMAIL=strunk@example.org;PARTSTAT=ACCE
745
+ PTED:mailto:strunk@example.org
746
+ ATTENDEE;CN=One;CUTYPE=INDIVIDUAL;EMAIL=one@example.org;PARTSTAT=ACCEPTED;R
747
+ OLE=REQ-PARTICIPANT:mailto:one@example.org
748
+ DTSTART:20141211T160000Z
749
+ DTEND:20141211T170000Z
750
+ RRULE:FREQ=WEEKLY
751
+ EXDATE:20150101T160000Z
752
+ EXDATE:20150108T160000Z,20141225T160000Z
753
+ END:VEVENT
754
+ END:VCALENDAR
755
+ ICS
756
+ }
757
+ ]
758
+
759
+ parse(old_message, new_message, expected, 'mailto:strunk@example.org')
760
+ end
761
+ end
762
+ end
763
+ end