govdelivery-tms 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +15 -0
  2. data/Gemfile +14 -0
  3. data/README.md +324 -0
  4. data/Rakefile +20 -0
  5. data/govdelivery-tms.gemspec +30 -0
  6. data/lib/govdelivery-tms.rb +43 -0
  7. data/lib/govdelivery-tms/base.rb +37 -0
  8. data/lib/govdelivery-tms/client.rb +97 -0
  9. data/lib/govdelivery-tms/collection_resource.rb +54 -0
  10. data/lib/govdelivery-tms/connection.rb +34 -0
  11. data/lib/govdelivery-tms/errors.rb +58 -0
  12. data/lib/govdelivery-tms/instance_resource.rb +219 -0
  13. data/lib/govdelivery-tms/link_header.rb +223 -0
  14. data/lib/govdelivery-tms/logger.rb +36 -0
  15. data/lib/govdelivery-tms/mail/delivery_method.rb +63 -0
  16. data/lib/govdelivery-tms/resource/collections.rb +98 -0
  17. data/lib/govdelivery-tms/resource/command.rb +25 -0
  18. data/lib/govdelivery-tms/resource/command_action.rb +17 -0
  19. data/lib/govdelivery-tms/resource/command_type.rb +20 -0
  20. data/lib/govdelivery-tms/resource/email_message.rb +81 -0
  21. data/lib/govdelivery-tms/resource/email_recipient.rb +31 -0
  22. data/lib/govdelivery-tms/resource/email_recipient_click.rb +8 -0
  23. data/lib/govdelivery-tms/resource/email_recipient_open.rb +8 -0
  24. data/lib/govdelivery-tms/resource/email_template.rb +15 -0
  25. data/lib/govdelivery-tms/resource/from_address.rb +10 -0
  26. data/lib/govdelivery-tms/resource/inbound_sms_message.rb +8 -0
  27. data/lib/govdelivery-tms/resource/ipaws_acknowledgement.rb +9 -0
  28. data/lib/govdelivery-tms/resource/ipaws_alert.rb +38 -0
  29. data/lib/govdelivery-tms/resource/ipaws_category.rb +7 -0
  30. data/lib/govdelivery-tms/resource/ipaws_cog_profile.rb +29 -0
  31. data/lib/govdelivery-tms/resource/ipaws_event_code.rb +7 -0
  32. data/lib/govdelivery-tms/resource/ipaws_nwem_area.rb +18 -0
  33. data/lib/govdelivery-tms/resource/ipaws_nwem_authorization.rb +9 -0
  34. data/lib/govdelivery-tms/resource/ipaws_nwem_auxilary_data.rb +8 -0
  35. data/lib/govdelivery-tms/resource/ipaws_response_type.rb +7 -0
  36. data/lib/govdelivery-tms/resource/ipaws_static_resource.rb +8 -0
  37. data/lib/govdelivery-tms/resource/keyword.rb +30 -0
  38. data/lib/govdelivery-tms/resource/recipient.rb +10 -0
  39. data/lib/govdelivery-tms/resource/sms_message.rb +35 -0
  40. data/lib/govdelivery-tms/resource/webhook.rb +20 -0
  41. data/lib/govdelivery-tms/util/core_ext.rb +27 -0
  42. data/lib/govdelivery-tms/util/hal_link_parser.rb +50 -0
  43. data/lib/govdelivery-tms/version.rb +3 -0
  44. data/spec/client_spec.rb +41 -0
  45. data/spec/command_types_spec.rb +29 -0
  46. data/spec/email_message_spec.rb +102 -0
  47. data/spec/email_template_spec.rb +149 -0
  48. data/spec/errors_spec.rb +13 -0
  49. data/spec/from_address_spec.rb +86 -0
  50. data/spec/inbound_sms_messages_spec.rb +19 -0
  51. data/spec/instance_resource_spec.rb +61 -0
  52. data/spec/ipaws_acknowledgement_spec.rb +16 -0
  53. data/spec/ipaws_alerts_spec.rb +192 -0
  54. data/spec/ipaws_cog_profile_spec.rb +75 -0
  55. data/spec/ipaws_event_codes_spec.rb +35 -0
  56. data/spec/ipaws_nwem_areas_spec.rb +58 -0
  57. data/spec/ipaws_nwem_authorization_spec.rb +16 -0
  58. data/spec/keyword_spec.rb +62 -0
  59. data/spec/keywords_spec.rb +21 -0
  60. data/spec/mail/delivery_method_spec.rb +52 -0
  61. data/spec/sms_message_spec.rb +63 -0
  62. data/spec/sms_messages_spec.rb +21 -0
  63. data/spec/spec_helper.rb +31 -0
  64. data/spec/tms_spec.rb +7 -0
  65. metadata +172 -0
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe TMS::FromAddress do
4
+ context "creating a list of from addresses" do
5
+ let(:client) do
6
+ double('client')
7
+ end
8
+ before do
9
+ @fromaddresses = TMS::FromAddress.new(client, '/from_addresses')
10
+ end
11
+
12
+ it 'should be able to get a list of email templates' do
13
+ response = [{
14
+ 'from_email' => "something@evotest.govdelivery.com",
15
+ 'reply_to_email' => "something@evotest.govdelivery.com",
16
+ 'bounce_email' => "something@evotest.govdelivery.com",
17
+ 'is_default' => true,
18
+ 'created_at' => "sometime",
19
+ '_links' => {"self" => "/from_addresses/1"}
20
+ }]
21
+
22
+ @fromaddresses.client.should_receive('get').with('/from_addresses').and_return(double('/from_addresses', :status => 200, :body => @from_addresses))
23
+ @fromaddresses.get
24
+ @fromaddresses.should == @fromaddresses
25
+ end
26
+ end
27
+
28
+ context "creating a from address" do
29
+ let(:client) do
30
+ double('client')
31
+ end
32
+
33
+ before do
34
+ @fromaddress = TMS::FromAddress.new(client, '/from_addresses', {
35
+ :from_email => "something@evotest.govdelivery.com",
36
+ :reply_to_email => "something@evotest.govdelivery.com",
37
+ :bounce_email => "something@evotest.govdelivery.com",
38
+ :is_default => true})
39
+ end
40
+
41
+ it 'should post successfully' do
42
+ response = {
43
+ 'from_email' => "something@evotest.govdelivery.com",
44
+ 'reply_to_email' => "something@evotest.govdelivery.com",
45
+ 'bounce_email' => "something@evotest.govdelivery.com",
46
+ 'is_default' => true,
47
+ 'created_at' => "sometime",
48
+ '_links' => {"self" => "/from_addresses/1"}
49
+ }
50
+ @fromaddress.client.should_receive('post').with(@fromaddress).and_return(double('response', :status => 201, :body => response ))
51
+ @fromaddress.post
52
+ @fromaddress.from_email.should == "something@evotest.govdelivery.com"
53
+ @fromaddress.reply_to_email.should == "something@evotest.govdelivery.com"
54
+ @fromaddress.bounce_email.should == "something@evotest.govdelivery.com"
55
+ @fromaddress.is_default.should == true
56
+ @fromaddress.created_at.should == "sometime"
57
+ @fromaddress.href.should == "/from_addresses/1"
58
+ end
59
+ end
60
+
61
+ context "handling errors" do
62
+ let(:client) do
63
+ double('client')
64
+ end
65
+ before do
66
+ @fromaddress = TMS::FromAddress.new(client, '/from_addresses/1')
67
+ end
68
+
69
+ it 'should handle errors' do
70
+ response = {'errors' => {:from_email => "can't be nil"}}
71
+ @fromaddress.client.should_receive('post').with(@fromaddress).and_return(double('response', :status => 422, :body => response))
72
+ @fromaddress.post
73
+ @fromaddress.errors.should == {:from_email => "can't be nil"}
74
+ end
75
+
76
+ it 'should handle 401 errors' do
77
+ @fromaddress.client.should_receive('post').with(@fromaddress).and_return(double('response', :status => 401))
78
+ expect {@fromaddress.post}.to raise_error("401 Not Authorized")
79
+ end
80
+
81
+ it 'should handle 404 errors' do
82
+ @fromaddress.client.should_receive('post').with(@fromaddress).and_return(double('response', :status => 404))
83
+ expect {@fromaddress.post}.to raise_error("Can't POST to /from_addresses/1")
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe TMS::InboundSmsMessages do
4
+ context "creating a new inbound messages list" do
5
+ let(:client) do
6
+ double('client')
7
+ end
8
+ before do
9
+ @messages = TMS::InboundSmsMessages.new(client, '/inbound_messages')
10
+ end
11
+ it 'should GET itself' do
12
+ body = [{:body=>"HELP", :from=>"+16125551212", :created_at=>"a while ago", :to=>"(651) 433-6258"}, {:body=>"STOP", :from=>"+16125551212", :created_at=>"a while ago", :to=>"(651) 433-6258"}]
13
+ @messages.client.should_receive(:get).and_return(double('response', :body => body, :status => 200, :headers => {}))
14
+
15
+ @messages.get
16
+ @messages.collection.length.should == 2
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+ class Foo
3
+ include TMS::InstanceResource
4
+ writeable_attributes :bar
5
+ collection_attribute :blah, 'EmailMessage'
6
+ readonly_collection_attribute :shah, 'EmailMessage'
7
+ end
8
+
9
+ describe TMS::InstanceResource do
10
+ context "creating a new inbound messages list" do
11
+ let(:happy_response) do
12
+ double(:status => 201, :body => {})
13
+ end
14
+
15
+ let(:client) do
16
+ double('client', :post => happy_response, :get => happy_response)
17
+ end
18
+
19
+
20
+ before do
21
+ @instance_resource = Foo.new(client)
22
+ end
23
+
24
+ it 'should POST' do
25
+ @instance_resource.bar = "OMG"
26
+ @instance_resource.post.should be_truthy
27
+ end
28
+
29
+ it 'should correctly reflect on collection resources' do
30
+ @instance_resource.blah.class.should == TMS::EmailMessage
31
+ @instance_resource.shah.class.should == TMS::EmailMessage
32
+ end
33
+
34
+ it 'should not GET on initialization' do
35
+ client.should_not receive(:get)
36
+ Foo.new(client, 'https://example.com/foos/1')
37
+ end
38
+
39
+ it 'should return self on successful get' do
40
+ client.should receive(:get)
41
+ foo = Foo.new(client, 'https://example.com/foos/1')
42
+ foo.should_not be_new_record
43
+ foo.get.should == foo
44
+ end
45
+
46
+ %w{get post put delete}.each do |verb|
47
+ it "should blow up on invalid #{verb}!" do
48
+ client.should(receive(verb)).and_return(double('response', status: 404, body: "{}"))
49
+ foo = Foo.new(client, 'https://example.com/foos/1')
50
+ expect do
51
+ foo.send("#{verb}!")
52
+ end.to raise_error("TMS::Errors::Invalid#{verb.capitalize}".constantize)
53
+ end
54
+ end
55
+
56
+ it 'it exposes its attributes hash' do
57
+ @instance_resource.attributes.should == {}
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe TMS::IpawsAcknowledgement do
4
+
5
+ it 'gets IPAWS acknowledgement from client' do
6
+ client = double(:client)
7
+ response_body = { "ACK" => "PONG" }
8
+ ipaws_acknowledgement = TMS::IpawsAcknowledgement.new(client, '/ipaws/acknowledgement', {})
9
+ ipaws_acknowledgement.client.should_receive('get').with(ipaws_acknowledgement.href).and_return(
10
+ double('response', :status => 200, :body => response_body)
11
+ )
12
+ ipaws_acknowledgement.get.should == ipaws_acknowledgement
13
+ ipaws_acknowledgement.ACK.should == "PONG"
14
+ end
15
+
16
+ end
@@ -0,0 +1,192 @@
1
+ require 'spec_helper'
2
+
3
+ describe TMS::IpawsAlert do
4
+
5
+ it 'post new IPAWS alerts to client, and capture status response from IPAWS' do
6
+ client = double(:client)
7
+
8
+ response_body = {
9
+ "identifier"=>"CAP12-TEST-1397743203",
10
+ "statuses"=> [
11
+ {
12
+ "CHANNELNAME"=>"CAPEXCH",
13
+ "STATUSITEMID"=>"200",
14
+ "ERROR"=>"N",
15
+ "STATUS"=>"Ack"
16
+ },
17
+ {
18
+ "CHANNELNAME"=>"CAPEXCH",
19
+ "STATUSITEMID"=>"202",
20
+ "ERROR"=>"N",
21
+ "STATUS"=>"alert-signature-is-valid"
22
+ },
23
+ {
24
+ "CHANNELNAME"=>"IPAWS",
25
+ "STATUSITEMID"=>"300",
26
+ "ERROR"=>"N",
27
+ "STATUS"=>"Ack"
28
+ },
29
+ {
30
+ "CHANNELNAME"=>"NWEM",
31
+ "STATUSITEMID"=>"401",
32
+ "ERROR"=>"N",
33
+ "STATUS"=>"message-not-disseminated-as-NWEM"
34
+ },
35
+ {
36
+ "CHANNELNAME"=>"EAS",
37
+ "STATUSITEMID"=>"501",
38
+ "ERROR"=>"N",
39
+ "STATUS"=>"message-not-disseminated-as-EAS"
40
+ },
41
+ {
42
+ "CHANNELNAME"=>"CMAS",
43
+ "STATUSITEMID"=>"600",
44
+ "ERROR"=>"N",
45
+ "STATUS"=>"Ack"
46
+ },
47
+ {
48
+ "CHANNELNAME"=>"PUBLIC",
49
+ "STATUSITEMID"=>"800",
50
+ "ERROR"=>"N",
51
+ "STATUS"=>"Ack"
52
+ }
53
+ ]
54
+ }
55
+
56
+ alert_attributes = {
57
+ identifier: "CAP12-TEST-123",
58
+ sender: 'test@open.com',
59
+ sent: "2014-04-18T15:02:26-05:00",
60
+ status: 'Actual',
61
+ msgType: 'Alert',
62
+ source: 'IPAWS-TEST',
63
+ scope: 'Public',
64
+ addresses: '999',
65
+ code: ['IPAWSv1.0'],
66
+ note: 'test',
67
+ incidents: 'IPAWS-9999',
68
+ info: [
69
+ {
70
+ language: 'en-US',
71
+ category: ['Safety'],
72
+ event: 'CIVIL EMERGENCY MESSAGE',
73
+ responseType: ['Shelter'],
74
+ urgency: 'Immediate',
75
+ severity: 'Extreme',
76
+ certainty: 'Observed',
77
+ audience: 'Public',
78
+ eventCode: [
79
+ { valueName: 'SAME', value: 'SVR'}
80
+ ],
81
+ effective: "2014-04-18T15:02:26-05:00",
82
+ expires: "2014-04-18T15:02:26-05:00",
83
+ senderName: 'IPAWS-Test',
84
+ headline: 'FLash Flood Warning',
85
+ description: 'Severe Weather Warning - Flooding',
86
+ instruction: 'Take Shelter',
87
+ parameter: [
88
+ { valueName: 'timezone', value: 'CST' }
89
+ ],
90
+ area: [
91
+ {
92
+ areaDesc: 'Fairfax County',
93
+ geocode: { valueName: 'SAME', value: '039035' }
94
+ }
95
+ ]
96
+ }
97
+ ]
98
+ }
99
+
100
+ alerts = TMS::IpawsAlerts.new(client, '/ipaws/alerts')
101
+ alert = alerts.build(alert_attributes)
102
+
103
+ alert.identifier.should == "CAP12-TEST-123"
104
+ alert.sender.should == 'test@open.com'
105
+ alert.sent.should == "2014-04-18T15:02:26-05:00"
106
+ alert.status.should == 'Actual'
107
+ alert.msgType.should == 'Alert'
108
+ alert.source.should == 'IPAWS-TEST'
109
+ alert.scope.should == 'Public'
110
+ alert.addresses.should == '999'
111
+ alert.code.should == ['IPAWSv1.0']
112
+ alert.note.should == 'test'
113
+ alert.incidents.should == 'IPAWS-9999'
114
+ alert.info.should == [
115
+ {
116
+ language: 'en-US',
117
+ category: ['Safety'],
118
+ event: 'CIVIL EMERGENCY MESSAGE',
119
+ responseType: ['Shelter'],
120
+ urgency: 'Immediate',
121
+ severity: 'Extreme',
122
+ certainty: 'Observed',
123
+ audience: 'Public',
124
+ eventCode: [
125
+ { valueName: 'SAME', value: 'SVR'}
126
+ ],
127
+ effective: "2014-04-18T15:02:26-05:00",
128
+ expires: "2014-04-18T15:02:26-05:00",
129
+ senderName: 'IPAWS-Test',
130
+ headline: 'FLash Flood Warning',
131
+ description: 'Severe Weather Warning - Flooding',
132
+ instruction: 'Take Shelter',
133
+ parameter: [
134
+ { valueName: 'timezone', value: 'CST' }
135
+ ],
136
+ area: [
137
+ {
138
+ areaDesc: 'Fairfax County',
139
+ geocode: { valueName: 'SAME', value: '039035' }
140
+ }
141
+ ]
142
+ }
143
+ ]
144
+
145
+ alert.client.should_receive('post').with(alert).and_return(double('response', :status => 200, :body => response_body))
146
+ alert.post.should == true
147
+ alert.ipaws_response.should == response_body
148
+
149
+ alert.identifier.should == "CAP12-TEST-123"
150
+ alert.sender.should == 'test@open.com'
151
+ alert.sent.should == "2014-04-18T15:02:26-05:00"
152
+ alert.status.should == 'Actual'
153
+ alert.msgType.should == 'Alert'
154
+ alert.source.should == 'IPAWS-TEST'
155
+ alert.scope.should == 'Public'
156
+ alert.addresses.should == '999'
157
+ alert.code.should == ['IPAWSv1.0']
158
+ alert.note.should == 'test'
159
+ alert.incidents.should == 'IPAWS-9999'
160
+ alert.info.should == [
161
+ {
162
+ language: 'en-US',
163
+ category: ['Safety'],
164
+ event: 'CIVIL EMERGENCY MESSAGE',
165
+ responseType: ['Shelter'],
166
+ urgency: 'Immediate',
167
+ severity: 'Extreme',
168
+ certainty: 'Observed',
169
+ audience: 'Public',
170
+ eventCode: [
171
+ { valueName: 'SAME', value: 'SVR'}
172
+ ],
173
+ effective: "2014-04-18T15:02:26-05:00",
174
+ expires: "2014-04-18T15:02:26-05:00",
175
+ senderName: 'IPAWS-Test',
176
+ headline: 'FLash Flood Warning',
177
+ description: 'Severe Weather Warning - Flooding',
178
+ instruction: 'Take Shelter',
179
+ parameter: [
180
+ { valueName: 'timezone', value: 'CST' }
181
+ ],
182
+ area: [
183
+ {
184
+ areaDesc: 'Fairfax County',
185
+ geocode: { valueName: 'SAME', value: '039035' }
186
+ }
187
+ ]
188
+ }
189
+ ]
190
+ end
191
+
192
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe TMS::IpawsCogProfile do
4
+
5
+ it 'gets IPAWS cog profile from client' do
6
+ client = double(:client)
7
+ response_body = {
8
+ "cogid"=>"120082",
9
+ "name"=>"GovDelivery",
10
+ "description"=>"GovDelivery",
11
+ "categoryName"=>"IPAWS-OPEN",
12
+ "organizationName"=>"CIV",
13
+ "cogEnabled"=>"Y",
14
+ "caeAuthorized"=>"Y",
15
+ "caeCmasAuthorized"=>"Y",
16
+ "eanAuthorized"=>"N",
17
+ "allEventCode"=>"N",
18
+ "allGeoCode"=>"N",
19
+ "easAuthorized"=>"Y",
20
+ "cmasAlertAuthorized"=>"Y",
21
+ "cmamTextAuthorized"=>"Y",
22
+ "publicAlertAuthorized"=>"Y",
23
+ "broadcastAuthorized"=>"N",
24
+ "email"=>"joe.bloom@govdelivery.com",
25
+ "eventCodes" => [
26
+ {"ALL"=>"FRW"},
27
+ {"ALL"=>"SVR"},
28
+ {"ALL"=>"SPW"},
29
+ {"ALL"=>"LAE"},
30
+ {"ALL"=>"CAE"},
31
+ {"ALL"=>"WSW"},
32
+ {"ALL"=>"CEM"}
33
+ ],
34
+ "geoCodes" => [
35
+ {"SAME"=>"039035"}
36
+ ]
37
+ }
38
+ cog_profile = TMS::IpawsCogProfile.new(client, '/ipaws/cog_profile', {})
39
+ cog_profile.client.should_receive('get').with(cog_profile.href).and_return(
40
+ double('response', :status => 200, :body => response_body)
41
+ )
42
+ cog_profile.get.should == cog_profile
43
+ cog_profile.cogid.should == "120082"
44
+
45
+ cog_profile.name.should == "GovDelivery"
46
+ cog_profile.description.should == "GovDelivery"
47
+ cog_profile.categoryName.should == "IPAWS-OPEN"
48
+ cog_profile.organizationName.should == "CIV"
49
+ cog_profile.cogEnabled.should == "Y"
50
+ cog_profile.caeAuthorized.should == "Y"
51
+ cog_profile.caeCmasAuthorized.should == "Y"
52
+ cog_profile.eanAuthorized.should == "N"
53
+ cog_profile.allEventCode.should == "N"
54
+ cog_profile.allGeoCode.should == "N"
55
+ cog_profile.easAuthorized.should == "Y"
56
+ cog_profile.cmasAlertAuthorized.should == "Y"
57
+ cog_profile.cmamTextAuthorized.should == "Y"
58
+ cog_profile.publicAlertAuthorized.should == "Y"
59
+ cog_profile.broadcastAuthorized.should == "N"
60
+ cog_profile.email.should == "joe.bloom@govdelivery.com"
61
+ cog_profile.eventCodes.should == [
62
+ {"ALL"=>"FRW"},
63
+ {"ALL"=>"SVR"},
64
+ {"ALL"=>"SPW"},
65
+ {"ALL"=>"LAE"},
66
+ {"ALL"=>"CAE"},
67
+ {"ALL"=>"WSW"},
68
+ {"ALL"=>"CEM"}
69
+ ]
70
+ cog_profile.geoCodes.should == [
71
+ {"SAME"=>"039035"}
72
+ ]
73
+ end
74
+
75
+ end