rcap 0.4 → 1.0.0.rc.1

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.
Files changed (63) hide show
  1. data/.gitignore +7 -0
  2. data/CHANGELOG.rdoc +6 -0
  3. data/Gemfile +4 -0
  4. data/README.rdoc +104 -85
  5. data/Rakefile +35 -0
  6. data/lib/rcap.rb +21 -14
  7. data/lib/rcap/alert.rb +26 -325
  8. data/lib/rcap/cap_1_1/alert.rb +363 -0
  9. data/lib/rcap/cap_1_1/area.rb +180 -0
  10. data/lib/rcap/cap_1_1/circle.rb +81 -0
  11. data/lib/rcap/cap_1_1/event_code.rb +22 -0
  12. data/lib/rcap/cap_1_1/geocode.rb +22 -0
  13. data/lib/rcap/cap_1_1/info.rb +470 -0
  14. data/lib/rcap/cap_1_1/parameter.rb +68 -0
  15. data/lib/rcap/cap_1_1/point.rb +55 -0
  16. data/lib/rcap/cap_1_1/polygon.rb +89 -0
  17. data/lib/rcap/cap_1_1/resource.rb +145 -0
  18. data/lib/rcap/cap_1_2/alert.rb +363 -0
  19. data/lib/rcap/cap_1_2/area.rb +180 -0
  20. data/lib/rcap/cap_1_2/circle.rb +81 -0
  21. data/lib/rcap/cap_1_2/event_code.rb +22 -0
  22. data/lib/rcap/cap_1_2/geocode.rb +22 -0
  23. data/lib/rcap/cap_1_2/info.rb +472 -0
  24. data/lib/rcap/cap_1_2/parameter.rb +68 -0
  25. data/lib/rcap/cap_1_2/point.rb +55 -0
  26. data/lib/rcap/cap_1_2/polygon.rb +90 -0
  27. data/lib/rcap/cap_1_2/resource.rb +147 -0
  28. data/lib/rcap/utilities.rb +14 -9
  29. data/lib/rcap/validations.rb +39 -7
  30. data/lib/rcap/version.rb +3 -0
  31. data/rcap.gemspec +30 -0
  32. data/spec/alert_spec.rb +109 -172
  33. data/spec/cap_1_1/alert_spec.rb +222 -0
  34. data/spec/cap_1_1/area_spec.rb +247 -0
  35. data/spec/cap_1_1/circle_spec.rb +88 -0
  36. data/spec/{geocode_spec.rb → cap_1_1/geocode_spec.rb} +8 -8
  37. data/spec/{info_spec.rb → cap_1_1/info_spec.rb} +143 -75
  38. data/spec/{point_spec.rb → cap_1_1/point_spec.rb} +8 -8
  39. data/spec/cap_1_1/polygon_spec.rb +97 -0
  40. data/spec/{resource_spec.rb → cap_1_1/resource_spec.rb} +24 -24
  41. data/spec/cap_1_2/alert_spec.rb +233 -0
  42. data/spec/cap_1_2/area_spec.rb +248 -0
  43. data/spec/cap_1_2/circle_spec.rb +95 -0
  44. data/spec/cap_1_2/geocode_spec.rb +38 -0
  45. data/spec/cap_1_2/info_spec.rb +338 -0
  46. data/spec/cap_1_2/point_spec.rb +46 -0
  47. data/spec/cap_1_2/polygon_spec.rb +102 -0
  48. data/spec/cap_1_2/resource_spec.rb +161 -0
  49. data/spec/spec.opts +2 -0
  50. data/spec/validations_spec.rb +80 -7
  51. metadata +122 -37
  52. data/lib/rcap/area.rb +0 -156
  53. data/lib/rcap/circle.rb +0 -78
  54. data/lib/rcap/event_code.rb +0 -20
  55. data/lib/rcap/geocode.rb +0 -20
  56. data/lib/rcap/info.rb +0 -437
  57. data/lib/rcap/parameter.rb +0 -66
  58. data/lib/rcap/point.rb +0 -53
  59. data/lib/rcap/polygon.rb +0 -77
  60. data/lib/rcap/resource.rb +0 -143
  61. data/spec/area_spec.rb +0 -179
  62. data/spec/circle_spec.rb +0 -88
  63. data/spec/polygon_spec.rb +0 -68
@@ -0,0 +1,248 @@
1
+ require 'spec_helper'
2
+
3
+ describe( RCAP::CAP_1_2::Area ) do
4
+ context( 'on initialisation' ) do
5
+ before( :each ) do
6
+ @area = RCAP::CAP_1_2::Area.new
7
+ end
8
+
9
+ # Atomic
10
+ it( 'should not have a area_desc' ){ @area.area_desc.should( be_nil )}
11
+ it( 'should not have a altitude' ){ @area.altitude.should( be_nil )}
12
+ it( 'should not have a ceiling' ){ @area.ceiling.should( be_nil )}
13
+
14
+ # Group
15
+ it( 'should have an empty polygons' ){ @area.polygons.should( be_empty )}
16
+ it( 'should have an empty circles' ){ @area.circles.should( be_empty )}
17
+ it( 'should have an empty geocodes' ){ @area.geocodes.should( be_empty )}
18
+
19
+ shared_examples_for( "it can parse into a CAP 1.2 Area object" ) do
20
+ it( 'should parse the area_desc correctly' ) do
21
+ @area.area_desc.should == @original_area.area_desc
22
+ end
23
+
24
+ it( 'should parse the altitude correctly' ) do
25
+ @area.altitude.should == @original_area.altitude
26
+ end
27
+
28
+ it( 'should parse the ceiling correctly' ) do
29
+ @area.ceiling.should == @original_area.ceiling
30
+ end
31
+
32
+ it( 'should parse the circles correctly' ) do
33
+ @area.circles.should == @original_area.circles
34
+ end
35
+
36
+ it( 'should parse the geocodes correctly' ) do
37
+ @area.geocodes.should == @original_area.geocodes
38
+ end
39
+
40
+ it( 'should parse the polygons correctly' ) do
41
+ @area.polygons.should == @original_area.polygons
42
+ end
43
+ end
44
+
45
+ context( 'from XML' ) do
46
+ before( :each ) do
47
+ @original_area = RCAP::CAP_1_2::Area.new( :area_desc => 'Area Description',
48
+ :altitude => 100,
49
+ :ceiling => 200,
50
+ :circles => RCAP::CAP_1_2::Circle.new( :lattitude => 0, :longitude => 0 , :radius => 100 ),
51
+ :geocodes => RCAP::CAP_1_2::Geocode.new( :name => 'name', :value => 'value' ),
52
+ :polygons => RCAP::CAP_1_2::Polygon.new( :points => RCAP::CAP_1_2::Point.new( :lattitude =>1, :longitude => 1 )))
53
+
54
+ @alert = RCAP::CAP_1_2::Alert.new( :infos => RCAP::CAP_1_2::Info.new( :areas => @original_area ))
55
+ @xml_string = @alert.to_xml
56
+ @xml_document = REXML::Document.new( @xml_string )
57
+ @info_xml_element = RCAP.xpath_first( @xml_document.root, RCAP::CAP_1_2::Info::XPATH, RCAP::CAP_1_2::Alert::XMLNS )
58
+ @area_xml_element = RCAP.xpath_first( @info_xml_element, RCAP::CAP_1_2::Area::XPATH, RCAP::CAP_1_2::Alert::XMLNS )
59
+ @area = RCAP::CAP_1_2::Area.from_xml_element( @area_xml_element )
60
+ end
61
+
62
+ it_should_behave_like( "it can parse into a CAP 1.2 Area object" )
63
+ end
64
+
65
+ context( 'from YAML Data' ) do
66
+ before( :each ) do
67
+ @original_area = RCAP::CAP_1_2::Area.new( :area_desc => 'Area Description',
68
+ :altitude => 100,
69
+ :ceiling => 200,
70
+ :circles => RCAP::CAP_1_2::Circle.new( :lattitude => 0, :longitude => 0 , :radius => 100 ),
71
+ :geocodes => RCAP::CAP_1_2::Geocode.new( :name => 'name', :value => 'value' ),
72
+ :polygons => RCAP::CAP_1_2::Polygon.new( :points => RCAP::CAP_1_2::Point.new( :lattitude =>1, :longitude => 1 )))
73
+
74
+ @area = RCAP::CAP_1_2::Area.from_yaml_data( YAML.load( @original_area.to_yaml ))
75
+ end
76
+
77
+ it_should_behave_like( "it can parse into a CAP 1.2 Area object" )
78
+ end
79
+
80
+ context( 'from a hash' ) do
81
+ before( :each ) do
82
+ @original_area = RCAP::CAP_1_2::Area.new( :area_desc => 'Area Description',
83
+ :altitude => 100,
84
+ :ceiling => 200,
85
+ :circles => RCAP::CAP_1_2::Circle.new( :lattitude => 0, :longitude => 0 , :radius => 100 ),
86
+ :geocodes => RCAP::CAP_1_2::Geocode.new( :name => 'name', :value => 'value' ),
87
+ :polygons => RCAP::CAP_1_2::Polygon.new( :points => RCAP::CAP_1_2::Point.new( :lattitude =>1, :longitude => 1 )))
88
+
89
+ @area = RCAP::CAP_1_2::Area.from_h( @original_area.to_h )
90
+ end
91
+
92
+ it_should_behave_like( "it can parse into a CAP 1.2 Area object" )
93
+ end
94
+ end
95
+
96
+ context( 'when exported' ) do
97
+ before( :each ) do
98
+ @area = RCAP::CAP_1_2::Area.new( :area_desc => 'Area Description',
99
+ :altitude => 100,
100
+ :ceiling => 200,
101
+ :circles => RCAP::CAP_1_2::Circle.new( :lattitude => 0, :longitude => 0 , :radius => 100 ),
102
+ :geocodes => RCAP::CAP_1_2::Geocode.new( :name => 'name', :value => 'value' ),
103
+ :polygons => RCAP::CAP_1_2::Polygon.new( :points => RCAP::CAP_1_2::Point.new( :lattitude =>1, :longitude => 1 )))
104
+ end
105
+ context( 'to a hash' ) do
106
+ before( :each ) do
107
+ @area_hash = @area.to_h
108
+ end
109
+
110
+ it( 'should export the area description correctly' ) do
111
+ @area_hash[ RCAP::CAP_1_2::Area::AREA_DESC_KEY ].should == @area.area_desc
112
+ end
113
+
114
+ it( 'should export the altitude correctly' ) do
115
+ @area_hash[ RCAP::CAP_1_2::Area::ALTITUDE_KEY ].should == @area.altitude
116
+ end
117
+
118
+ it( 'should set the ceiling correctly' ) do
119
+ @area_hash[ RCAP::CAP_1_2::Area::CEILING_KEY ].should == @area.ceiling
120
+ end
121
+
122
+ it( 'should export the circles correctly' ) do
123
+ @area_hash[ RCAP::CAP_1_2::Area::CIRCLES_KEY ].should == @area.circles.map{ |circle| circle.to_h }
124
+ end
125
+
126
+ it( 'should export the geocodes correctly' ) do
127
+ @area_hash[ RCAP::CAP_1_2::Area::GEOCODES_KEY ].should == @area.geocodes.map{ |geocode| geocode.to_h }
128
+ end
129
+
130
+ it( 'should export the polygons correctly' ) do
131
+ @area_hash[ RCAP::CAP_1_2::Area::POLYGONS_KEY ].should == @area.polygons.map{ |polygon| polygon.to_h }
132
+ end
133
+ end
134
+ end
135
+
136
+ context( 'is not valid if' ) do
137
+ before( :each ) do
138
+ @area = RCAP::CAP_1_2::Area.new( :area_desc => "Cape Town Metropole" )
139
+ @area.should( be_valid )
140
+ end
141
+
142
+ it( 'does not have an area descrtiption (area_desc)') do
143
+ @area.area_desc = nil
144
+ @area.should_not( be_valid )
145
+ end
146
+
147
+ it( 'has a ceiling defined but no altitude' ) do
148
+ @area.ceiling = 1
149
+ @area.altitude = nil
150
+ @area.should_not( be_valid )
151
+ end
152
+
153
+ context( 'it contains circles and it' ) do
154
+ before( :each ) do
155
+ @area.circles << RCAP::CAP_1_2::Circle.new( :lattitude => 0, :longitude => 0, :radius => 1)
156
+ @area.should( be_valid )
157
+ end
158
+
159
+ it( 'has an invalid circle' ) do
160
+ @area.circles.first.lattitude = nil
161
+ @area.should_not( be_valid )
162
+ end
163
+ end
164
+
165
+ context( 'it contains polygons and it' ) do
166
+ before( :each ) do
167
+ @polygon = RCAP::CAP_1_2::Polygon.new
168
+ @polygon.points.push( RCAP::CAP_1_2::Point.new( :lattitude => 0, :longitude => 0 ),
169
+ RCAP::CAP_1_2::Point.new( :lattitude => 0, :longitude => 1 ),
170
+ RCAP::CAP_1_2::Point.new( :lattitude => 1, :longitude => 0 ),
171
+ RCAP::CAP_1_2::Point.new( :lattitude => 0, :longitude => 0 ))
172
+ @area.polygons << @polygon
173
+ @area.should( be_valid )
174
+ end
175
+
176
+ it( 'has an invalid polygon' ) do
177
+ @polygon.points.first.lattitude = nil
178
+ @area.should_not( be_valid )
179
+ end
180
+ end
181
+
182
+ context( 'it contains geocodes and it' ) do
183
+ before( :each ) do
184
+ @geocode = RCAP::CAP_1_2::Geocode.new( :name => 'foo', :value => 'bar' )
185
+ @area.geocodes << @geocode
186
+ @area.should( be_valid )
187
+ end
188
+
189
+ it( 'has an invalid geocode' ) do
190
+ @geocode.value = nil
191
+ @area.should_not( be_valid )
192
+ end
193
+ end
194
+ end
195
+
196
+ describe( 'instance methods' ) do
197
+ before( :each ) do
198
+ @area = RCAP::CAP_1_2::Area.new
199
+ end
200
+
201
+ describe( '#add_polygon' ) do
202
+ before( :each ) do
203
+ @polygon = @area.add_polygon
204
+ end
205
+
206
+ it( 'should return a CAP 1.1 Polygon' ) do
207
+ @polygon.class.should == RCAP::CAP_1_2::Polygon
208
+ end
209
+
210
+ it( 'should add a Polygon to the polygons attribute' ) do
211
+ @area.polygons.size.should == 1
212
+ end
213
+ end
214
+
215
+ describe( '#add_circle' ) do
216
+ before( :each ) do
217
+ @circle = @area.add_circle( lattitude: 1, longitude: 1, radius: 1 )
218
+ end
219
+
220
+ it( 'should return a CAP 1.1 Circle' ) do
221
+ @circle.class.should == RCAP::CAP_1_2::Circle
222
+ @circle.lattitude.should == 1
223
+ @circle.longitude.should == 1
224
+ @circle.radius.should == 1
225
+ end
226
+
227
+ it( 'should add a circle to the circles attribute' ) do
228
+ @area.circles.size.should == 1
229
+ end
230
+ end
231
+
232
+ describe( '#add_geocode' ) do
233
+ before( :each ) do
234
+ @geocode = @area.add_geocode( name: 'Geocode', value: '123' )
235
+ end
236
+
237
+ it( 'should return a CAP 1.1 Geocode' ) do
238
+ @geocode.class.should == RCAP::CAP_1_2::Geocode
239
+ @geocode.name.should == 'Geocode'
240
+ @geocode.value.should == '123'
241
+ end
242
+
243
+ it( 'should add a geocode to the geocodes attribute' ) do
244
+ @area.geocodes.size.should == 1
245
+ end
246
+ end
247
+ end
248
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ describe( RCAP::CAP_1_2::Circle ) do
4
+ describe( '#to_s' ) do
5
+ it( 'should return a correct string' ) do
6
+ @circle = RCAP::CAP_1_2::Circle.new( :lattitude => 0, :longitude => 0 , :radius => 1 )
7
+ @circle.to_s.should == '0,0 1'
8
+ end
9
+ end
10
+
11
+ context( 'should not be valid if' ) do
12
+ before( :each ) do
13
+ @circle = RCAP::CAP_1_2::Circle.new( :lattitude => 0, :longitude => 0 , :radius => 1 )
14
+ @circle.should( be_valid )
15
+ end
16
+
17
+ it( 'does not have a lattitude defined' ) do
18
+ @circle.lattitude = nil
19
+ @circle.should_not( be_valid )
20
+ end
21
+
22
+ it( 'does not have a longitude defined' ) do
23
+ @circle.longitude = nil
24
+ @circle.should_not( be_valid )
25
+ end
26
+
27
+ it( 'does not have a radius defined' ) do
28
+ @circle.radius = nil
29
+ @circle.should_not( be_valid )
30
+ end
31
+
32
+ it( 'does not have a numeric radius' ) do
33
+ @circle.radius = "not a number"
34
+ @circle.should_not( be_valid )
35
+ end
36
+
37
+ it( 'does not have a positive radius' ) do
38
+ @circle.radius = -1
39
+ @circle.should_not( be_valid )
40
+ end
41
+ end
42
+
43
+ context( 'on initialisation' ) do
44
+ context( 'from XML' ) do
45
+ before( :each ) do
46
+ @original_circle = RCAP::CAP_1_2::Circle.new( :radius => 10.5,
47
+ :lattitude => 30, :longitude => 60 )
48
+ @alert = RCAP::CAP_1_2::Alert.new( :infos => RCAP::CAP_1_2::Info.new( :areas => RCAP::CAP_1_2::Area.new( :circles => @original_circle )))
49
+ @xml_string = @alert.to_xml
50
+ @xml_document = REXML::Document.new( @xml_string )
51
+ @info_element = RCAP.xpath_first( @xml_document.root, RCAP::CAP_1_2::Info::XPATH, RCAP::CAP_1_2::Alert::XMLNS )
52
+ @area_element = RCAP.xpath_first( @info_element, RCAP::CAP_1_2::Area::XPATH, RCAP::CAP_1_2::Alert::XMLNS )
53
+ @circle_element = RCAP.xpath_first( @area_element, RCAP::CAP_1_2::Circle::XPATH, RCAP::CAP_1_2::Alert::XMLNS )
54
+ @circle = RCAP::CAP_1_2::Circle.from_xml_element( @circle_element )
55
+ end
56
+
57
+ it( 'should parse the radius correctly' ) do
58
+ @circle.radius.should == @original_circle.radius
59
+ end
60
+
61
+ it( 'should parse the lattitude and longitude correctly' ) do
62
+ @circle.lattitude.should == @original_circle.lattitude
63
+ @circle.longitude.should == @original_circle.longitude
64
+ end
65
+ end
66
+
67
+ context( 'from a hash' ) do
68
+ before( :each ) do
69
+ @original_circle = RCAP::CAP_1_2::Circle.new( :radius => 10.5, :lattitude => 30, :longitude => 60 )
70
+ @circle = RCAP::CAP_1_2::Circle.from_h( @original_circle.to_h )
71
+ end
72
+
73
+ it( 'should set the radius correctly' ) do
74
+ @circle.radius.should == @original_circle.radius
75
+ end
76
+
77
+ it( 'should parse the lattitude and longitude correctly' ) do
78
+ @circle.lattitude.should == @original_circle.lattitude
79
+ @circle.longitude.should == @original_circle.longitude
80
+ end
81
+ end
82
+ end
83
+
84
+ context( 'when exported' ) do
85
+ before( :each ) do
86
+ @circle = RCAP::CAP_1_2::Circle.new( :radius => 10.5, :lattitude => 30, :longitude => 60 )
87
+ end
88
+
89
+ context( 'to hash' ) do
90
+ it( 'should be correct' ) do
91
+ @circle.to_h.should == { 'radius' => 10.5, 'lattitude' => 30, 'longitude' => 60 }
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe( RCAP::CAP_1_2::Geocode ) do
4
+ context( 'when initialised' ) do
5
+ context( 'from XML' ) do
6
+ before( :each ) do
7
+ @original_geocode = RCAP::CAP_1_2::Geocode.new( :name => 'name', :value => 'value' )
8
+ @alert = RCAP::CAP_1_2::Alert.new( :infos => RCAP::CAP_1_2::Info.new( :areas => RCAP::CAP_1_2::Area.new( :geocodes => @original_geocode )))
9
+ @xml_string = @alert.to_xml
10
+ @xml_document = REXML::Document.new( @xml_string )
11
+ @info_xml_element = RCAP.xpath_first( @xml_document.root, RCAP::CAP_1_2::Info::XPATH, RCAP::CAP_1_2::Alert::XMLNS )
12
+ @area_xml_element = RCAP.xpath_first( @info_xml_element, RCAP::CAP_1_2::Area::XPATH, RCAP::CAP_1_2::Alert::XMLNS )
13
+ @geocode_xml_element = RCAP.xpath_first( @area_xml_element, RCAP::CAP_1_2::Geocode::XPATH, RCAP::CAP_1_2::Alert::XMLNS )
14
+ @geocode = RCAP::CAP_1_2::Geocode.from_xml_element( @geocode_xml_element )
15
+ end
16
+
17
+ it( 'should parse the name correctly' ) do
18
+ @geocode.name.should == @original_geocode.name
19
+ end
20
+
21
+ it( 'should parse the value correctly' ) do
22
+ @geocode.value.should == @original_geocode.value
23
+ end
24
+ end
25
+ end
26
+
27
+ context( 'when exported' ) do
28
+ before( :each ) do
29
+ @geocode = RCAP::CAP_1_2::Geocode.new( :name => 'name', :value => 'value' )
30
+ end
31
+
32
+ context( 'to a hash' ) do
33
+ it( 'should export correctly' ) do
34
+ @geocode.to_h.should == { 'name' => 'value' }
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,338 @@
1
+ require 'spec_helper'
2
+
3
+ describe( RCAP::CAP_1_2::Info ) do
4
+ context( 'on initialisation' ) do
5
+ before( :each ) do
6
+ @info = RCAP::CAP_1_2::Info.new
7
+ end
8
+
9
+ it( 'should have a default language of en-US' ) { @info.language.should == 'en-US' }
10
+ it( 'should have no categories' ) { @info.categories.should( be_empty )}
11
+ it( 'should have no event' ) { @info.event.should( be_nil )}
12
+ it( 'should have no response types' ) { @info.response_types.should( be_empty )}
13
+ it( 'should have no urgency' ) { @info.urgency.should( be_nil )}
14
+ it( 'should have no severity' ) { @info.severity.should( be_nil )}
15
+ it( 'should have no certainty' ) { @info.certainty.should( be_nil )}
16
+ it( 'should have no audience' ) { @info.audience.should( be_nil )}
17
+ it( 'should have no event_codes' ) { @info.event_codes.should( be_empty )}
18
+ it( 'should have no effective datetime' ) { @info.effective.should( be_nil )}
19
+ it( 'should have no onset datetime' ) { @info.onset.should( be_nil )}
20
+ it( 'should have no expires datetime' ) { @info.expires.should( be_nil )}
21
+ it( 'should have no sender name ' ) { @info.sender_name.should( be_nil )}
22
+ it( 'should have no headline' ) { @info.headline.should( be_nil )}
23
+ it( 'should have no description' ) { @info.description.should( be_nil )}
24
+ it( 'should have no instruction' ) { @info.instruction.should( be_nil )}
25
+ it( 'should have no web' ) { @info.web.should( be_nil )}
26
+ it( 'should have no contact' ) { @info.contact.should( be_nil )}
27
+ it( 'should have no parameters' ) { @info.parameters.should( be_empty )}
28
+
29
+ shared_examples_for( 'it can parse into a CAP 1.2 Info object' ) do
30
+ it( 'should parse categories correctly' ){ @info .categories.should == @original_info.categories }
31
+ it( 'should parse event correctly' ){ @info .event.should == @original_info.event }
32
+ it( 'should parse response_types correctly' ){ @info .response_types.should == @original_info.response_types }
33
+ it( 'should parse urgency correctly' ){ @info .urgency.should == @original_info.urgency }
34
+ it( 'should parse severity correctly' ){ @info .severity.should == @original_info.severity }
35
+ it( 'should parse certainty correctly' ){ @info .certainty.should == @original_info.certainty }
36
+ it( 'should parse audience correctly' ){ @info .audience.should == @original_info.audience }
37
+ it( 'should parse effective correctly' ){ @info .effective.should( be_within(Rational( 1, 86400 )).of( @original_info.effective ))}
38
+ it( 'should parse onset correctly' ){ @info .onset.should( be_within( Rational( 1, 86400 )).of( @original_info.onset ))}
39
+ it( 'should parse expires correctly' ){ @info .expires.should( be_within( Rational( 1, 86400 )).of( @original_info.expires ))}
40
+ it( 'should parse sender_name correctly' ){ @info .sender_name.should == @original_info.sender_name }
41
+ it( 'should parse headline correctly' ){ @info .headline.should == @original_info.headline }
42
+ it( 'should parse description correctly' ){ @info .description.should == @original_info.description }
43
+ it( 'should parse instruction correctly' ){ @info .instruction.should == @original_info.instruction }
44
+ it( 'should parse web correctly' ){ @info .web.should == @original_info.web }
45
+ it( 'should parse contact correctly' ){ @info .contact.should == @original_info.contact }
46
+ it( 'should parse event_codes correctly' ){ @info .event_codes.should == @original_info.event_codes }
47
+ it( 'should parse parameters correctly' ){ @info .parameters.should == @original_info.parameters }
48
+ it( 'should parse resources correctly' ){ @info .resources.should == @original_info.resources }
49
+ it( 'should parse areas correctly' ){ @info .areas.should == @original_info.areas }
50
+ end
51
+
52
+ context( 'from XML' ) do
53
+ before( :each ) do
54
+ @original_info = RCAP::CAP_1_2::Info.new( :categories => [ RCAP::CAP_1_2::Info::CATEGORY_GEO, RCAP::CAP_1_2::Info::CATEGORY_FIRE ],
55
+ :event => 'Event Description',
56
+ :response_types => [ RCAP::CAP_1_2::Info::RESPONSE_TYPE_MONITOR, RCAP::CAP_1_2::Info::RESPONSE_TYPE_ASSESS ],
57
+ :urgency => RCAP::CAP_1_2::Info::URGENCY_IMMEDIATE,
58
+ :severity => RCAP::CAP_1_2::Info::SEVERITY_EXTREME,
59
+ :certainty => RCAP::CAP_1_2::Info::CERTAINTY_OBSERVED,
60
+ :audience => 'Audience',
61
+ :effective => DateTime.now,
62
+ :onset => DateTime.now + 1,
63
+ :expires => DateTime.now + 2,
64
+ :sender_name => 'Sender Name',
65
+ :headline => 'Headline',
66
+ :description => 'Description',
67
+ :instruction => 'Instruction',
68
+ :web => 'http://website',
69
+ :contact => 'contact@address',
70
+ :event_codes => [ RCAP::CAP_1_2::EventCode.new( :name => 'name1', :value => 'value1' ),
71
+ RCAP::CAP_1_2::EventCode.new( :name => 'name2', :value => 'value2' )],
72
+ :parameters => [ RCAP::CAP_1_2::Parameter.new( :name => 'name1', :value => 'value1' ),
73
+ RCAP::CAP_1_2::Parameter.new( :name => 'name2', :value => 'value2' )],
74
+ :areas => [ RCAP::CAP_1_2::Area.new( :area_desc => 'Area1' ),
75
+ RCAP::CAP_1_2::Area.new( :area_desc => 'Area2' )]
76
+ )
77
+ @alert = RCAP::CAP_1_2::Alert.new( :infos => @original_info )
78
+ @xml_string = @alert.to_xml
79
+ @xml_document = REXML::Document.new( @xml_string )
80
+ @info = RCAP::CAP_1_2::Info.from_xml_element( RCAP.xpath_first( @xml_document.root, RCAP::CAP_1_2::Info::XPATH, RCAP::CAP_1_2::Alert::XMLNS ))
81
+ end
82
+
83
+ it_should_behave_like( "it can parse into a CAP 1.2 Info object" )
84
+ end
85
+
86
+ context( 'from a hash' ) do
87
+ before( :each ) do
88
+ @original_info = RCAP::CAP_1_2::Info.new( :categories => [ RCAP::CAP_1_2::Info::CATEGORY_GEO, RCAP::CAP_1_2::Info::CATEGORY_FIRE ],
89
+ :event => 'Event Description',
90
+ :response_types => [ RCAP::CAP_1_2::Info::RESPONSE_TYPE_MONITOR, RCAP::CAP_1_2::Info::RESPONSE_TYPE_ASSESS ],
91
+ :urgency => RCAP::CAP_1_2::Info::URGENCY_IMMEDIATE,
92
+ :severity => RCAP::CAP_1_2::Info::SEVERITY_EXTREME,
93
+ :certainty => RCAP::CAP_1_2::Info::CERTAINTY_OBSERVED,
94
+ :audience => 'Audience',
95
+ :effective => DateTime.now,
96
+ :onset => DateTime.now + 1,
97
+ :expires => DateTime.now + 2,
98
+ :sender_name => 'Sender Name',
99
+ :headline => 'Headline',
100
+ :description => 'Description',
101
+ :instruction => 'Instruction',
102
+ :web => 'http://website',
103
+ :contact => 'contact@address',
104
+ :event_codes => [ RCAP::CAP_1_2::EventCode.new( :name => 'name1', :value => 'value1' ),
105
+ RCAP::CAP_1_2::EventCode.new( :name => 'name2', :value => 'value2' )],
106
+ :parameters => [ RCAP::CAP_1_2::Parameter.new( :name => 'name1', :value => 'value1' ),
107
+ RCAP::CAP_1_2::Parameter.new( :name => 'name2', :value => 'value2' )],
108
+ :areas => [ RCAP::CAP_1_2::Area.new( :area_desc => 'Area1' ),
109
+ RCAP::CAP_1_2::Area.new( :area_desc => 'Area2' )]
110
+ )
111
+ @info = RCAP::CAP_1_2::Info.from_h( @original_info.to_h )
112
+ end
113
+ it_should_behave_like( "it can parse into a CAP 1.2 Info object" )
114
+ end
115
+ end
116
+
117
+ context( 'is not valid if it' ) do
118
+ before( :each ) do
119
+ @info = RCAP::CAP_1_2::Info.new( :event => 'Info Event',
120
+ :categories => RCAP::CAP_1_2::Info::CATEGORY_GEO,
121
+ :urgency => RCAP::CAP_1_2::Info::URGENCY_IMMEDIATE,
122
+ :severity => RCAP::CAP_1_2::Info::SEVERITY_EXTREME,
123
+ :certainty => RCAP::CAP_1_2::Info::CERTAINTY_OBSERVED )
124
+ @info.valid?
125
+ puts @info.errors.full_messages
126
+ @info.should( be_valid )
127
+ end
128
+
129
+ it( 'does not have an event' ) do
130
+ @info.event = nil
131
+ @info.should_not( be_valid )
132
+ end
133
+
134
+ it( 'does not have categories' ) do
135
+ @info.categories.clear
136
+ @info.should_not( be_valid )
137
+ end
138
+
139
+ it( 'does not have an urgency' ) do
140
+ @info.urgency = nil
141
+ @info.should_not( be_valid )
142
+ end
143
+
144
+ it( 'does not have an severity' ) do
145
+ @info.severity = nil
146
+ @info.should_not( be_valid )
147
+ end
148
+
149
+ it( 'does not have an certainty' ) do
150
+ @info.certainty = nil
151
+ @info.should_not( be_valid )
152
+ end
153
+ end
154
+
155
+
156
+ describe( 'when exported' ) do
157
+ context( 'to hash' ) do
158
+ before( :each ) do
159
+ @info = RCAP::CAP_1_2::Info.new( :categories => [ RCAP::CAP_1_2::Info::CATEGORY_GEO, RCAP::CAP_1_2::Info::CATEGORY_FIRE ],
160
+ :event => 'Event Description',
161
+ :response_types => [ RCAP::CAP_1_2::Info::RESPONSE_TYPE_MONITOR, RCAP::CAP_1_2::Info::RESPONSE_TYPE_ASSESS ],
162
+ :urgency => RCAP::CAP_1_2::Info::URGENCY_IMMEDIATE,
163
+ :severity => RCAP::CAP_1_2::Info::SEVERITY_EXTREME,
164
+ :certainty => RCAP::CAP_1_2::Info::CERTAINTY_OBSERVED,
165
+ :audience => 'Audience',
166
+ :effective => DateTime.now,
167
+ :onset => DateTime.now + 1,
168
+ :expires => DateTime.now + 2,
169
+ :sender_name => 'Sender Name',
170
+ :headline => 'Headline',
171
+ :description => 'Description',
172
+ :instruction => 'Instruction',
173
+ :web => 'http://website',
174
+ :contact => 'contact@address',
175
+ :resources => [ RCAP::CAP_1_2::Resource.new( :resource_desc => 'Resource Description', :uri => 'http://tempuri.org/resource' )],
176
+ :event_codes => [ RCAP::CAP_1_2::EventCode.new( :name => 'name1', :value => 'value1' ),
177
+ RCAP::CAP_1_2::EventCode.new( :name => 'name2', :value => 'value2' )],
178
+ :parameters => [ RCAP::CAP_1_2::Parameter.new( :name => 'name1', :value => 'value1' ),
179
+ RCAP::CAP_1_2::Parameter.new( :name => 'name2', :value => 'value2' )],
180
+ :areas => [ RCAP::CAP_1_2::Area.new( :area_desc => 'Area1' ),
181
+ RCAP::CAP_1_2::Area.new( :area_desc => 'Area2' )])
182
+ @info_hash = @info.to_h
183
+ end
184
+
185
+ it( 'should export the language correctly' ) do
186
+ @info_hash[ RCAP::CAP_1_2::Info::LANGUAGE_KEY ].should == @info.language
187
+ end
188
+
189
+ it( 'should export the categories' ) do
190
+ @info_hash[ RCAP::CAP_1_2::Info::CATEGORIES_KEY ].should == @info.categories
191
+ end
192
+
193
+ it( 'should export the event' ) do
194
+ @info_hash[ RCAP::CAP_1_2::Info::EVENT_KEY ].should == @info.event
195
+ end
196
+
197
+ it( 'should export the response types' ) do
198
+ @info_hash[ RCAP::CAP_1_2::Info::RESPONSE_TYPES_KEY ].should == @info.response_types
199
+ end
200
+
201
+ it( 'should export the urgency' ) do
202
+ @info_hash[ RCAP::CAP_1_2::Info:: URGENCY_KEY ].should == @info.urgency
203
+ end
204
+
205
+ it( 'should export the severity' ) do
206
+ @info_hash[ RCAP::CAP_1_2::Info:: SEVERITY_KEY ].should == @info.severity
207
+ end
208
+
209
+ it( 'should export the certainty' ) do
210
+ @info_hash[ RCAP::CAP_1_2::Info:: CERTAINTY_KEY ].should == @info.certainty
211
+ end
212
+
213
+ it( 'should export the audience' ) do
214
+ @info_hash[ RCAP::CAP_1_2::Info:: AUDIENCE_KEY ].should == @info.audience
215
+ end
216
+
217
+ it( 'should export the effective date' ) do
218
+ @info_hash[ RCAP::CAP_1_2::Info::EFFECTIVE_KEY ].should == @info.effective.to_s_for_cap
219
+ end
220
+
221
+ it( 'should export the onset date' ) do
222
+ @info_hash[ RCAP::CAP_1_2::Info::ONSET_KEY ].should == @info.onset.to_s_for_cap
223
+ end
224
+
225
+ it( 'should export the expires date' ) do
226
+ @info_hash[ RCAP::CAP_1_2::Info::EXPIRES_KEY ].should == @info.expires.to_s_for_cap
227
+ end
228
+
229
+ it( 'should export the sender name' ) do
230
+ @info_hash[ RCAP::CAP_1_2::Info::SENDER_NAME_KEY ].should == @info.sender_name
231
+ end
232
+
233
+ it( 'should export the headline' ) do
234
+ @info_hash[ RCAP::CAP_1_2::Info::HEADLINE_KEY ].should == @info.headline
235
+ end
236
+
237
+ it( 'should export the description' ) do
238
+ @info_hash[ RCAP::CAP_1_2::Info::DESCRIPTION_KEY ].should == @info.description
239
+ end
240
+
241
+ it( 'should export the instruction' ) do
242
+ @info_hash[ RCAP::CAP_1_2::Info::INSTRUCTION_KEY ].should == @info.instruction
243
+ end
244
+
245
+ it( 'should export the web address ' ) do
246
+ @info_hash[ RCAP::CAP_1_2::Info::WEB_KEY ].should == @info.web
247
+ end
248
+
249
+ it( 'should export the contact' ) do
250
+ @info_hash[ RCAP::CAP_1_2::Info::CONTACT_KEY ].should == @info.contact
251
+ end
252
+
253
+ it( 'should export the event codes' ) do
254
+ @info_hash[ RCAP::CAP_1_2::Info::EVENT_CODES_KEY ].should == @info.event_codes.map{ |event_code| event_code.to_h }
255
+ end
256
+
257
+ it( 'should export the parameters ' ) do
258
+ @info_hash[ RCAP::CAP_1_2::Info::PARAMETERS_KEY ].should == @info.parameters.map{ |parameter| parameter.to_h }
259
+ end
260
+
261
+ it( 'should export the resources ' ) do
262
+ @info_hash[ RCAP::CAP_1_2::Info::RESOURCES_KEY ].should == @info.resources.map{ |resource| resource.to_h }
263
+ end
264
+
265
+ it( 'should export the areas' ) do
266
+ @info_hash[ RCAP::CAP_1_2::Info::AREAS_KEY ].should == @info.areas.map{ |area| area.to_h }
267
+ end
268
+ end
269
+ end
270
+
271
+ describe( 'instance methods' ) do
272
+ before( :each ) do
273
+ @info = RCAP::CAP_1_2::Info.new
274
+ end
275
+
276
+ describe( '#add_event_code' ) do
277
+ before( :each ) do
278
+ @event_code = @info.add_event_code( name: 'Event Code', value: '1234' )
279
+ end
280
+
281
+ it( 'should return a 1.2 EventCode' ) do
282
+ @event_code.class.should == RCAP::CAP_1_2::EventCode
283
+ @event_code.name.should == 'Event Code'
284
+ @event_code.value.should == '1234'
285
+ end
286
+
287
+ it( 'should add an EventCode to the event_codes attribute' ) do
288
+ @info.event_codes.size.should == 1
289
+ end
290
+ end
291
+
292
+ describe( '#add_parameter' ) do
293
+ before( :each ) do
294
+ @parameter = @info.add_parameter( name: 'Parameter', value: '1234' )
295
+ end
296
+
297
+ it( 'should return a 1.2 Parameter' ) do
298
+ @parameter.class.should == RCAP::CAP_1_2::Parameter
299
+ @parameter.name.should == 'Parameter'
300
+ @parameter.value.should == '1234'
301
+ end
302
+
303
+ it( 'should add a Parameter to the parameters attribute' ) do
304
+ @info.parameters.size.should == 1
305
+ end
306
+ end
307
+
308
+ describe( '#add_resource' ) do
309
+ before( :each ) do
310
+ @resource = @info.add_resource( resource_desc: 'Resource' )
311
+ end
312
+
313
+ it( 'should return a 1.2 Resource' ) do
314
+ @resource.class.should == RCAP::CAP_1_2::Resource
315
+ @resource.resource_desc.should == 'Resource'
316
+ end
317
+
318
+ it( 'should add a Resource to the resources attribute' ) do
319
+ @info.resources.size.should == 1
320
+ end
321
+ end
322
+
323
+ describe( '#add_area' ) do
324
+ before( :each ) do
325
+ @area = @info.add_area( area_desc: 'Area' )
326
+ end
327
+
328
+ it( 'should return a 1.2 area' ) do
329
+ @area.class.should == RCAP::CAP_1_2::Area
330
+ @area.area_desc.should == 'Area'
331
+ end
332
+
333
+ it( 'should add a Area to the areas attribute' ) do
334
+ @info.areas.size.should == 1
335
+ end
336
+ end
337
+ end
338
+ end