govdelivery-tms 0.8.0

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 (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