rcap 0.4 → 1.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
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