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,153 @@
1
+ require 'test_helper'
2
+ require 'v_object/i_tip/broker_tester'
3
+
4
+ module Tilia
5
+ module VObject
6
+ class BrokerProcessMessageTest < ITip::BrokerTester
7
+ def test_request_new
8
+ itip = <<ICS
9
+ BEGIN:VCALENDAR
10
+ VERSION:2.0
11
+ METHOD:REQUEST
12
+ BEGIN:VEVENT
13
+ SEQUENCE:1
14
+ UID:foobar
15
+ END:VEVENT
16
+ END:VCALENDAR
17
+ ICS
18
+
19
+ expected = <<ICS
20
+ BEGIN:VCALENDAR
21
+ VERSION:2.0
22
+ BEGIN:VEVENT
23
+ SEQUENCE:1
24
+ UID:foobar
25
+ END:VEVENT
26
+ END:VCALENDAR
27
+ ICS
28
+
29
+ process(itip, nil, expected)
30
+ end
31
+
32
+ def test_request_update
33
+ itip = <<ICS
34
+ BEGIN:VCALENDAR
35
+ VERSION:2.0
36
+ METHOD:REQUEST
37
+ BEGIN:VEVENT
38
+ SEQUENCE:2
39
+ UID:foobar
40
+ END:VEVENT
41
+ END:VCALENDAR
42
+ ICS
43
+
44
+ old = <<ICS
45
+ BEGIN:VCALENDAR
46
+ BEGIN:VEVENT
47
+ SEQUENCE:1
48
+ UID:foobar
49
+ END:VEVENT
50
+ END:VCALENDAR
51
+ ICS
52
+
53
+ expected = <<ICS
54
+ BEGIN:VCALENDAR
55
+ BEGIN:VEVENT
56
+ SEQUENCE:2
57
+ UID:foobar
58
+ END:VEVENT
59
+ END:VCALENDAR
60
+ ICS
61
+
62
+ process(itip, old, expected)
63
+ end
64
+
65
+ def test_cancel
66
+ itip = <<ICS
67
+ BEGIN:VCALENDAR
68
+ VERSION:2.0
69
+ METHOD:CANCEL
70
+ BEGIN:VEVENT
71
+ SEQUENCE:2
72
+ UID:foobar
73
+ END:VEVENT
74
+ END:VCALENDAR
75
+ ICS
76
+
77
+ old = <<ICS
78
+ BEGIN:VCALENDAR
79
+ BEGIN:VEVENT
80
+ SEQUENCE:1
81
+ UID:foobar
82
+ END:VEVENT
83
+ END:VCALENDAR
84
+ ICS
85
+
86
+ expected = <<ICS
87
+ BEGIN:VCALENDAR
88
+ BEGIN:VEVENT
89
+ UID:foobar
90
+ STATUS:CANCELLED
91
+ SEQUENCE:2
92
+ END:VEVENT
93
+ END:VCALENDAR
94
+ ICS
95
+
96
+ process(itip, old, expected)
97
+ end
98
+
99
+ def test_cancel_no_existing_event
100
+ itip = <<ICS
101
+ BEGIN:VCALENDAR
102
+ VERSION:2.0
103
+ METHOD:CANCEL
104
+ BEGIN:VEVENT
105
+ SEQUENCE:2
106
+ UID:foobar
107
+ END:VEVENT
108
+ END:VCALENDAR
109
+ ICS
110
+
111
+ old = nil
112
+ expected = nil
113
+
114
+ process(itip, old, expected)
115
+ end
116
+
117
+ def test_unsupported_component
118
+ itip = <<ICS
119
+ BEGIN:VCALENDAR
120
+ VERSION:2.0
121
+ BEGIN:VTODO
122
+ SEQUENCE:2
123
+ UID:foobar
124
+ END:VTODO
125
+ END:VCALENDAR
126
+ ICS
127
+
128
+ old = nil
129
+ expected = nil
130
+
131
+ process(itip, old, expected)
132
+ end
133
+
134
+ def test_unsupported_method
135
+ itip = <<ICS
136
+ BEGIN:VCALENDAR
137
+ VERSION:2.0
138
+ METHOD:PUBLISH
139
+ BEGIN:VEVENT
140
+ SEQUENCE:2
141
+ UID:foobar
142
+ END:VEVENT
143
+ END:VCALENDAR
144
+ ICS
145
+
146
+ old = nil
147
+ expected = nil
148
+
149
+ process(itip, old, expected)
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,402 @@
1
+ require 'test_helper'
2
+ require 'v_object/i_tip/broker_tester'
3
+
4
+ module Tilia
5
+ module VObject
6
+ class BrokerProcessReplyTest < ITip::BrokerTester
7
+ def test_reply_no_original
8
+ itip = <<ICS
9
+ BEGIN:VCALENDAR
10
+ VERSION:2.0
11
+ METHOD:REPLY
12
+ BEGIN:VEVENT
13
+ SEQUENCE:2
14
+ UID:foobar
15
+ ATTENDEE;PARTSTAT=ACCEPTED:mailto:foo@example.org
16
+ ORGANIZER:mailto:bar@example.org
17
+ END:VEVENT
18
+ END:VCALENDAR
19
+ ICS
20
+
21
+ old = nil
22
+ expected = nil
23
+
24
+ process(itip, old, expected)
25
+ end
26
+
27
+ def test_reply_accept
28
+ itip = <<ICS
29
+ BEGIN:VCALENDAR
30
+ VERSION:2.0
31
+ METHOD:REPLY
32
+ BEGIN:VEVENT
33
+ ATTENDEE;PARTSTAT=ACCEPTED:mailto:foo@example.org
34
+ ORGANIZER:mailto:bar@example.org
35
+ SEQUENCE:2
36
+ UID:foobar
37
+ END:VEVENT
38
+ END:VCALENDAR
39
+ ICS
40
+
41
+ old = <<ICS
42
+ BEGIN:VCALENDAR
43
+ VERSION:2.0
44
+ BEGIN:VEVENT
45
+ SEQUENCE:2
46
+ UID:foobar
47
+ ATTENDEE:mailto:foo@example.org
48
+ ORGANIZER:mailto:bar@example.org
49
+ END:VEVENT
50
+ END:VCALENDAR
51
+ ICS
52
+
53
+ expected = <<ICS
54
+ BEGIN:VCALENDAR
55
+ VERSION:2.0
56
+ BEGIN:VEVENT
57
+ SEQUENCE:2
58
+ UID:foobar
59
+ ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:mailto:foo@example.org
60
+ ORGANIZER:mailto:bar@example.org
61
+ END:VEVENT
62
+ END:VCALENDAR
63
+ ICS
64
+
65
+ process(itip, old, expected)
66
+ end
67
+
68
+ def test_reply_request_status
69
+ itip = <<ICS
70
+ BEGIN:VCALENDAR
71
+ VERSION:2.0
72
+ METHOD:REPLY
73
+ BEGIN:VEVENT
74
+ UID:foobar
75
+ REQUEST-STATUS:2.3;foo-bar!
76
+ ATTENDEE;PARTSTAT=ACCEPTED:mailto:foo@example.org
77
+ ORGANIZER:mailto:bar@example.org
78
+ SEQUENCE:2
79
+ UID:foobar
80
+ END:VEVENT
81
+ END:VCALENDAR
82
+ ICS
83
+
84
+ old = <<ICS
85
+ BEGIN:VCALENDAR
86
+ VERSION:2.0
87
+ BEGIN:VEVENT
88
+ UID:foobar
89
+ SEQUENCE:2
90
+ ATTENDEE:mailto:foo@example.org
91
+ ORGANIZER:mailto:bar@example.org
92
+ END:VEVENT
93
+ END:VCALENDAR
94
+ ICS
95
+
96
+ expected = <<ICS
97
+ BEGIN:VCALENDAR
98
+ VERSION:2.0
99
+ BEGIN:VEVENT
100
+ UID:foobar
101
+ SEQUENCE:2
102
+ ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.3:mailto:foo@example.org
103
+ ORGANIZER:mailto:bar@example.org
104
+ END:VEVENT
105
+ END:VCALENDAR
106
+ ICS
107
+
108
+ process(itip, old, expected)
109
+ end
110
+
111
+ def test_reply_party_crasher
112
+ itip = <<ICS
113
+ BEGIN:VCALENDAR
114
+ VERSION:2.0
115
+ METHOD:REPLY
116
+ BEGIN:VEVENT
117
+ ATTENDEE;PARTSTAT=ACCEPTED:mailto:crasher@example.org
118
+ ORGANIZER:mailto:bar@example.org
119
+ SEQUENCE:2
120
+ UID:foobar
121
+ END:VEVENT
122
+ END:VCALENDAR
123
+ ICS
124
+
125
+ old = <<ICS
126
+ BEGIN:VCALENDAR
127
+ VERSION:2.0
128
+ BEGIN:VEVENT
129
+ SEQUENCE:2
130
+ UID:foobar
131
+ ATTENDEE:mailto:foo@example.org
132
+ ORGANIZER:mailto:bar@example.org
133
+ END:VEVENT
134
+ END:VCALENDAR
135
+ ICS
136
+
137
+ expected = <<ICS
138
+ BEGIN:VCALENDAR
139
+ VERSION:2.0
140
+ BEGIN:VEVENT
141
+ SEQUENCE:2
142
+ UID:foobar
143
+ ATTENDEE:mailto:foo@example.org
144
+ ORGANIZER:mailto:bar@example.org
145
+ ATTENDEE;PARTSTAT=ACCEPTED:mailto:crasher@example.org
146
+ END:VEVENT
147
+ END:VCALENDAR
148
+ ICS
149
+
150
+ process(itip, old, expected)
151
+ end
152
+
153
+ def test_reply_new_exception
154
+ # This is a reply to 1 instance of a recurring event. This should
155
+ # automatically create an exception.
156
+ itip = <<ICS
157
+ BEGIN:VCALENDAR
158
+ VERSION:2.0
159
+ METHOD:REPLY
160
+ BEGIN:VEVENT
161
+ ATTENDEE;PARTSTAT=ACCEPTED:mailto:foo@example.org
162
+ ORGANIZER:mailto:bar@example.org
163
+ SEQUENCE:2
164
+ RECURRENCE-ID:20140725T000000Z
165
+ UID:foobar
166
+ END:VEVENT
167
+ END:VCALENDAR
168
+ ICS
169
+
170
+ old = <<ICS
171
+ BEGIN:VCALENDAR
172
+ VERSION:2.0
173
+ BEGIN:VEVENT
174
+ SEQUENCE:2
175
+ UID:foobar
176
+ RRULE:FREQ=DAILY
177
+ DTSTART:20140724T000000Z
178
+ ATTENDEE:mailto:foo@example.org
179
+ ORGANIZER:mailto:bar@example.org
180
+ END:VEVENT
181
+ END:VCALENDAR
182
+ ICS
183
+
184
+ expected = <<ICS
185
+ BEGIN:VCALENDAR
186
+ VERSION:2.0
187
+ BEGIN:VEVENT
188
+ SEQUENCE:2
189
+ UID:foobar
190
+ RRULE:FREQ=DAILY
191
+ DTSTART:20140724T000000Z
192
+ ATTENDEE:mailto:foo@example.org
193
+ ORGANIZER:mailto:bar@example.org
194
+ END:VEVENT
195
+ BEGIN:VEVENT
196
+ SEQUENCE:2
197
+ UID:foobar
198
+ DTSTART:20140725T000000Z
199
+ ATTENDEE;PARTSTAT=ACCEPTED:mailto:foo@example.org
200
+ ORGANIZER:mailto:bar@example.org
201
+ RECURRENCE-ID:20140725T000000Z
202
+ END:VEVENT
203
+ END:VCALENDAR
204
+ ICS
205
+
206
+ process(itip, old, expected)
207
+ end
208
+
209
+ def test_reply_new_exception_tz
210
+ # This is a reply to 1 instance of a recurring event. This should
211
+ # automatically create an exception.
212
+ itip = <<ICS
213
+ BEGIN:VCALENDAR
214
+ VERSION:2.0
215
+ METHOD:REPLY
216
+ BEGIN:VEVENT
217
+ ATTENDEE;PARTSTAT=ACCEPTED:mailto:foo@example.org
218
+ ORGANIZER:mailto:bar@example.org
219
+ SEQUENCE:2
220
+ RECURRENCE-ID;TZID=America/Toronto:20140725T000000
221
+ UID:foobar
222
+ END:VEVENT
223
+ END:VCALENDAR
224
+ ICS
225
+
226
+ old = <<ICS
227
+ BEGIN:VCALENDAR
228
+ VERSION:2.0
229
+ BEGIN:VEVENT
230
+ SEQUENCE:2
231
+ UID:foobar
232
+ RRULE:FREQ=DAILY
233
+ DTSTART;TZID=America/Toronto:20140724T000000
234
+ ATTENDEE:mailto:foo@example.org
235
+ ORGANIZER:mailto:bar@example.org
236
+ END:VEVENT
237
+ END:VCALENDAR
238
+ ICS
239
+
240
+ expected = <<ICS
241
+ BEGIN:VCALENDAR
242
+ VERSION:2.0
243
+ BEGIN:VEVENT
244
+ SEQUENCE:2
245
+ UID:foobar
246
+ RRULE:FREQ=DAILY
247
+ DTSTART;TZID=America/Toronto:20140724T000000
248
+ ATTENDEE:mailto:foo@example.org
249
+ ORGANIZER:mailto:bar@example.org
250
+ END:VEVENT
251
+ BEGIN:VEVENT
252
+ SEQUENCE:2
253
+ UID:foobar
254
+ DTSTART;TZID=America/Toronto:20140725T000000
255
+ ATTENDEE;PARTSTAT=ACCEPTED:mailto:foo@example.org
256
+ ORGANIZER:mailto:bar@example.org
257
+ RECURRENCE-ID;TZID=America/Toronto:20140725T000000
258
+ END:VEVENT
259
+ END:VCALENDAR
260
+ ICS
261
+
262
+ process(itip, old, expected)
263
+ end
264
+
265
+ def test_reply_party_crash_create_excepton
266
+ # IN this test there's a recurring event that has an exception. The
267
+ # exception is missing the attendee.
268
+ #
269
+ # The attendee party crashes the instance, so it should show up in the
270
+ # resulting object.
271
+ itip = <<ICS
272
+ BEGIN:VCALENDAR
273
+ VERSION:2.0
274
+ METHOD:REPLY
275
+ BEGIN:VEVENT
276
+ ATTENDEE;PARTSTAT=ACCEPTED;CN=Crasher!:mailto:crasher@example.org
277
+ ORGANIZER:mailto:bar@example.org
278
+ SEQUENCE:2
279
+ RECURRENCE-ID:20140725T000000Z
280
+ UID:foobar
281
+ END:VEVENT
282
+ END:VCALENDAR
283
+ ICS
284
+
285
+ old = <<ICS
286
+ BEGIN:VCALENDAR
287
+ VERSION:2.0
288
+ BEGIN:VEVENT
289
+ SEQUENCE:2
290
+ UID:foobar
291
+ RRULE:FREQ=DAILY
292
+ DTSTART:20140724T000000Z
293
+ ORGANIZER:mailto:bar@example.org
294
+ END:VEVENT
295
+ END:VCALENDAR
296
+ ICS
297
+
298
+ expected = <<ICS
299
+ BEGIN:VCALENDAR
300
+ VERSION:2.0
301
+ BEGIN:VEVENT
302
+ SEQUENCE:2
303
+ UID:foobar
304
+ RRULE:FREQ=DAILY
305
+ DTSTART:20140724T000000Z
306
+ ORGANIZER:mailto:bar@example.org
307
+ END:VEVENT
308
+ BEGIN:VEVENT
309
+ SEQUENCE:2
310
+ UID:foobar
311
+ DTSTART:20140725T000000Z
312
+ ORGANIZER:mailto:bar@example.org
313
+ RECURRENCE-ID:20140725T000000Z
314
+ ATTENDEE;PARTSTAT=ACCEPTED;CN=Crasher!:mailto:crasher@example.org
315
+ END:VEVENT
316
+ END:VCALENDAR
317
+ ICS
318
+
319
+ process(itip, old, expected)
320
+ end
321
+
322
+ def test_reply_new_exception_no_master_event
323
+ # This iTip message would normally create a new exception, but the
324
+ # server is not able to create this new instance, because there's no
325
+ # master event to clone from.
326
+ #
327
+ # This test checks if the message is ignored.
328
+ itip = <<ICS
329
+ BEGIN:VCALENDAR
330
+ VERSION:2.0
331
+ METHOD:REPLY
332
+ BEGIN:VEVENT
333
+ ATTENDEE;PARTSTAT=ACCEPTED;CN=Crasher!:mailto:crasher@example.org
334
+ ORGANIZER:mailto:bar@example.org
335
+ SEQUENCE:2
336
+ RECURRENCE-ID:20140725T000000Z
337
+ UID:foobar
338
+ END:VEVENT
339
+ END:VCALENDAR
340
+ ICS
341
+
342
+ old = <<ICS
343
+ BEGIN:VCALENDAR
344
+ VERSION:2.0
345
+ BEGIN:VEVENT
346
+ SEQUENCE:2
347
+ UID:foobar
348
+ RRULE:FREQ=DAILY
349
+ DTSTART:20140724T000000Z
350
+ RECURRENCE-ID:20140724T000000Z
351
+ ORGANIZER:mailto:bar@example.org
352
+ END:VEVENT
353
+ END:VCALENDAR
354
+ ICS
355
+
356
+ expected = nil
357
+ process(itip, old, expected)
358
+ end
359
+
360
+ def test_reply_accept_update_rsvp
361
+ itip = <<ICS
362
+ BEGIN:VCALENDAR
363
+ VERSION:2.0
364
+ METHOD:REPLY
365
+ BEGIN:VEVENT
366
+ ATTENDEE;PARTSTAT=ACCEPTED:mailto:foo@example.org
367
+ ORGANIZER:mailto:bar@example.org
368
+ SEQUENCE:2
369
+ UID:foobar
370
+ END:VEVENT
371
+ END:VCALENDAR
372
+ ICS
373
+
374
+ old = <<ICS
375
+ BEGIN:VCALENDAR
376
+ VERSION:2.0
377
+ BEGIN:VEVENT
378
+ SEQUENCE:2
379
+ UID:foobar
380
+ ATTENDEE;RSVP=TRUE:mailto:foo@example.org
381
+ ORGANIZER:mailto:bar@example.org
382
+ END:VEVENT
383
+ END:VCALENDAR
384
+ ICS
385
+
386
+ expected = <<ICS
387
+ BEGIN:VCALENDAR
388
+ VERSION:2.0
389
+ BEGIN:VEVENT
390
+ SEQUENCE:2
391
+ UID:foobar
392
+ ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:mailto:foo@example.org
393
+ ORGANIZER:mailto:bar@example.org
394
+ END:VEVENT
395
+ END:VCALENDAR
396
+ ICS
397
+
398
+ process(itip, old, expected)
399
+ end
400
+ end
401
+ end
402
+ end
@@ -0,0 +1,71 @@
1
+ require 'v_object/test_case'
2
+
3
+ module Tilia
4
+ module VObject
5
+ module ITip
6
+ # Utilities for testing the broker
7
+ class BrokerTester < TestCase
8
+ def parse(old_message, new_message, expected = [], current_user = 'mailto:one@example.org')
9
+ broker = Tilia::VObject::ITip::Broker.new
10
+ result = broker.parse_event(new_message, current_user, old_message)
11
+
12
+ assert_equal(expected.size, result.size)
13
+
14
+ expected.each_with_index do |ex, index|
15
+ message = result[index]
16
+
17
+ ex.each do |key, val|
18
+ if key == 'message'
19
+ assert_v_obj_equals(val, message.message.serialize)
20
+ else
21
+ actual = message.send(key)
22
+ assert_equal(val, val.is_a?(String) ? actual.to_s : actual)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def process(input, existing_object = nil, expected = false)
29
+ version = Tilia::VObject::Version::VERSION
30
+
31
+ vcal = Tilia::VObject::Reader.read(input)
32
+
33
+ main_component = vcal.components.first
34
+
35
+ message = Tilia::VObject::ITip::Message.new
36
+ message.message = vcal
37
+ message.method = vcal.key?('METHOD') ? vcal['METHOD'].value : nil
38
+ message.component = main_component.name
39
+ message.uid = main_component['UID'].value
40
+ message.sequence = vcal['VEVENT'] ? vcal['VEVENT'][0]['SEQUENCE'] : nil
41
+
42
+ if message.method == 'REPLY'
43
+ message.sender = main_component['ATTENDEE'].value
44
+ message.sender_name = main_component['ATTENDEE'].key?('CN') ? main_component['ATTENDEE']['CN'].value : nil
45
+ message.recipient = main_component['ORGANIZER'].value
46
+ message.recipient_name = main_component['ORGANIZER'].key?('CN') ? main_component['ORGANIZER']['CN'] : nil
47
+ end
48
+
49
+ broker = Tilia::VObject::ITip::Broker.new
50
+
51
+ if existing_object.is_a?(String)
52
+ existing_object = existing_object.gsub(
53
+ '%foo%',
54
+ "VERSION:2.0\nPRODID:-//Tilia//Tilia VObject #{version}//EN\nCALSCALE:GREGORIAN"
55
+ )
56
+ existing_object = Tilia::VObject::Reader.read(existing_object)
57
+ end
58
+
59
+ result = broker.process_message(message, existing_object)
60
+
61
+ if expected.nil?
62
+ assert(!result)
63
+ return nil
64
+ end
65
+
66
+ assert_v_obj_equals(expected, result)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end