minitel 0.3.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 65b9eb7da885c09645279a948daa4a61dfe74d7b
4
- data.tar.gz: f9f45910ae96e042306d4d900ecb6a849802c3b3
3
+ metadata.gz: 1a746a71bce4fb28ed51a555f0669724e7bfd133
4
+ data.tar.gz: 2981f18e075b1d60d55cc82cf9ca46eb07e3c60b
5
5
  SHA512:
6
- metadata.gz: 874a4d581a8c49727c1f54fd480d609d8af262c643eac4883c3ddeba794ec3188e3887614db1c54993b6ecd7658a37e0514a6fd1d672bd4b4a0aa3dfa3ab22b6
7
- data.tar.gz: bc4f9e8a874b86b7ca4199267ce1eaaad762d3d5c172b61e55ba80bb12055887bfc309f21b2bfbc313bddeac1458b00403625dd4be4ba9a76672053ad246cba4
6
+ metadata.gz: 056e50f9fe5f3793f9eb9833051c6aa9a50f9cfe10e8effb6ff07da42410513e6fecc4ec01928595c0307c128f64ae592338a793c54a5e5e98e95e93137572c2
7
+ data.tar.gz: b9b491b75dee0c22f75d96ebc5d808bd4716b3aefc332d73440378f07a371603c8ab2ed8defa2a958d1a2a2b937b83828810357b6d081143ca709b03835d91d4
checksums.yaml.gz.sig CHANGED
@@ -1,2 +1 @@
1
- D�(���D}TN}w�B'.Cb��i��U��_�K���6��a[/7��ؽKG��=� f9����:`�7��
2
- '�g�k���]�L<�Y��vR��ӵ��=Q"?�s�E�;���:^�Q��o�)��#ͣ����hޏ#;���g&sy��_��<�us�Y�3�VX(o*�g�8Q�� Ao5�p�cNGkGK��t)�[�׊��}ȃ=�T�j��e.�L�\�FZ?Lh��8m��|�����Z\BTWr�
1
+ ��C“�Q��AfV<3��!(����81/�'_�ag͒�HQ�]�Y�~��Ӝ�]��c��с��p�C�;��|\�k���Y�����E��Xӊ�U:S�&iJaR(>��#+:�)�k�\��5&q+�i�B��Q~��jΎ�.� �O�ֿK]���͕3|����V���tOcۧ����J��GiiY���� �\�%�=���/��mM*H��r�8b'q5mbS��|�\�@?v
data.tar.gz.sig CHANGED
Binary file
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+
data/.travis.yml CHANGED
@@ -1,14 +1,13 @@
1
1
  cache: bundler
2
2
  language: ruby
3
3
  rvm:
4
- - 2.1.3
5
- - 2.1.2
6
- - 2.1.1
7
- - 2.1.0
4
+ - 2.2.0
5
+ - 2.1.5
8
6
  - 2.0.0
9
7
  - 1.9.3
10
8
  - ruby-head
11
9
  script: bundle exec rspec
12
10
  notifications:
13
11
  email: false
12
+ sudo: false
14
13
 
data/Readme.md CHANGED
@@ -11,14 +11,21 @@ require 'minitel'
11
11
  # create a client
12
12
  client = Minitel::Client.new("https://user:pass@telex.heroku.com")
13
13
 
14
- # send a notifcation to the owner and collaborators of an app
15
- client.notify_app(app_uuid: '...', title: 'Something happened', body: 'here are the details')
14
+ # send a notification to the owner and collaborators of an app
15
+ client.notify_app(app_uuid: '...', title: 'Your database is on fire!', body: 'Sorry.')
16
16
  # => {"id"=>"uuid of message"}
17
17
 
18
- # send a notifcation to a user
19
- client.notify_user(user_uuid: '...', title: 'Something happened', body: 'here are the details')
18
+ # send a notification to a user
19
+ client.notify_user(user_uuid: '...', title: 'Here is your invoice', body: 'You owe us 65k.')
20
20
  # => {"id"=>"uuid of message"}
21
21
 
22
- # add folloup to a previous notificaiton
23
- client.notify_user(message_uuid: '...', body: 'here are even more details')
22
+ # send a notification with an email action
23
+ # see: https://developers.google.com/gmail/markup/reference/go-to-action
24
+ client.notify_user(user_uuid: '...',
25
+ title: 'Here is your invoice',
26
+ body: 'You owe us 65k.',
27
+ action: { label: 'View Invoice', url: 'https://heroku.com/invoices/12345-12-98765'})
28
+
29
+ # add folloup to a previous notification
30
+ client.add_followup(message_uuid: '...', body: 'here are even more details')
24
31
  ```
@@ -17,31 +17,40 @@ module Minitel
17
17
  end
18
18
 
19
19
  def notify_app(args)
20
- StrictArgs.enforce(args, [:app_uuid, :body, :title], :app_uuid)
21
- post_message('app', args[:app_uuid], args[:title], args[:body])
20
+ StrictArgs.enforce(args, [:app_uuid, :body, :title], [:action], :app_uuid)
21
+ if action = args[:action]
22
+ StrictArgs.enforce(action, [:label, :url])
23
+ end
24
+ post_message('app', args[:app_uuid], args[:title], args[:body], action)
22
25
  end
23
26
 
24
27
  def notify_user(args)
25
- StrictArgs.enforce(args, [:user_uuid, :body, :title], :user_uuid)
26
- post_message('user', args[:user_uuid], args[:title], args[:body])
28
+ StrictArgs.enforce(args, [:user_uuid, :body, :title], [:action], :user_uuid)
29
+ if action = args[:action]
30
+ StrictArgs.enforce(action, [:label, :url])
31
+ end
32
+ post_message('user', args[:user_uuid], args[:title], args[:body], action)
27
33
  end
28
34
 
29
35
  def add_followup(args)
30
- StrictArgs.enforce(args, [:message_uuid, :body], :message_uuid)
36
+ StrictArgs.enforce(args, [:message_uuid, :body], [], :message_uuid)
31
37
  followup = { body: args[:body] }
32
-
33
38
  post("/producer/messages/#{args[:message_uuid]}/followups", followup)
34
39
  end
35
40
 
36
41
  private
37
42
 
38
- def post_message(type, id, title, body)
43
+ def post_message(type, id, title, body, action)
39
44
  message = {
40
45
  title: title,
41
46
  body: body,
42
47
  target: {type: type, id: id}
43
48
  }
44
49
 
50
+ if action
51
+ message.merge!(action: action)
52
+ end
53
+
45
54
  post("/producer/messages", message)
46
55
  end
47
56
 
@@ -1,17 +1,21 @@
1
1
  module Minitel
2
2
  module StrictArgs
3
3
  extend self
4
- def enforce(args, keywords, uuid_field)
5
- ensure_strict_args(args.keys, keywords)
6
- ensure_no_nils(args, keywords)
7
- ensure_is_uuid(args[uuid_field])
4
+ def enforce(args, required, allowed=[], uuid_field=nil)
5
+ ensure_strict_args(args.keys, required, allowed)
6
+ ensure_no_nils(args, required)
7
+ ensure_is_uuid(args[uuid_field]) if uuid_field
8
8
  end
9
9
 
10
10
  # A Ruby 2.1 required keyword argument sorta backport
11
- def ensure_strict_args(keys, accept_keys)
12
- if keys.sort != accept_keys.sort
13
- delta = accept_keys - keys
14
- raise ArgumentError, "missing or extra keywords: #{delta.join(', ')}"
11
+ def ensure_strict_args(keys, required, allowed)
12
+ missing = required - keys
13
+ unless missing.empty?
14
+ raise ArgumentError, "missing keywords: #{missing.join(', ')}"
15
+ end
16
+ unknown = keys - (required + allowed)
17
+ unless unknown.empty?
18
+ raise ArgumentError, "extra keywords: #{unknown.join(', ')}"
15
19
  end
16
20
  end
17
21
 
@@ -1,3 +1,3 @@
1
1
  module Minitel
2
- VERSION = '0.3.0'
2
+ VERSION = '0.4.0'
3
3
  end
data/minitel.gemspec CHANGED
@@ -23,4 +23,5 @@ Gem::Specification.new do |gem|
23
23
  gem.add_development_dependency 'guard', '~> 2.6'
24
24
  gem.add_development_dependency 'guard-rspec', '~> 4.3'
25
25
  gem.add_development_dependency 'rspec', '~> 3.0'
26
+ gem.add_development_dependency 'webmock', '~> 1.20'
26
27
  end
@@ -30,25 +30,30 @@ end
30
30
  describe Minitel::Client, '#notify_app' do
31
31
  describe 'action' do
32
32
  let(:defaults) { {title: 'a title', body: 'a body', app_uuid: SecureRandom.uuid} }
33
- let(:client) { Minitel::Client.new('https://u:p@h.com') }
33
+ let(:client) { Minitel::Client.new('https://telex.com') }
34
34
 
35
35
  before do
36
- request = {path: '/producer/messages', method: :post}
37
- response = {status: 201, body: MultiJson.dump({'success' => true})}
38
- body = MultiJson.dump({
39
- title: 'a title',
40
- body: 'a body',
41
- target: {type: 'app', id: defaults[:app_uuid]}
42
- })
43
-
44
- Excon.stub(request.merge(body: body), response)
36
+ @stub = stub_request(:post, 'https://telex.com/producer/messages').
37
+ to_return(status: 201, body: MultiJson.encode(success: true))
45
38
  end
46
39
 
47
40
  it 'posts a proper json body to the producer messages endpoint' do
48
- expect{ client.notify_app(defaults) }.to_not raise_error
41
+ client.notify_app(defaults)
42
+ body = MultiJson.encode(
43
+ title: 'a title',
44
+ body: 'a body',
45
+ target: {type: 'app', id: defaults[:app_uuid]})
46
+ expect(@stub.with(body: body)).to have_been_requested
47
+ end
49
48
 
50
- unstubbed_body = defaults.merge({title: 'bad title'})
51
- expect{ client.notify_app(unstubbed_body) }.to raise_error(Excon::Errors::StubNotFound)
49
+ it 'supports actions' do
50
+ action = { label: 'omg', url: 'https://foo' }
51
+ client.notify_app(defaults.merge(action: action))
52
+ post_with_action = @stub.with do |req|
53
+ body = MultiJson.decode(req.body, symbolize_keys: true)
54
+ body[:action] == action
55
+ end
56
+ expect(post_with_action).to have_been_requested
52
57
  end
53
58
 
54
59
  it 'returns a parsed json response' do
@@ -61,25 +66,30 @@ end
61
66
 
62
67
  describe Minitel::Client, '#notify_user' do
63
68
  let(:defaults) { {title: 'a title', body: 'a body', user_uuid: SecureRandom.uuid} }
64
- let(:client) { Minitel::Client.new('https://u:p@h.com') }
69
+ let(:client) { Minitel::Client.new('https://telex.com') }
65
70
 
66
71
  before do
67
- request = {path: '/producer/messages', method: :post}
68
- response = {status: 201, body: MultiJson.dump({'success' => true})}
69
- body = MultiJson.dump({
70
- title: 'a title',
71
- body: 'a body',
72
- target: {type: 'user', id: defaults[:user_uuid]}
73
- })
74
-
75
- Excon.stub(request.merge(body: body), response)
72
+ @stub = stub_request(:post, 'https://telex.com/producer/messages').
73
+ to_return(status: 201, body: MultiJson.encode(success: true))
76
74
  end
77
75
 
78
76
  it 'posts a proper json body to the producer messages endpoint' do
79
- expect{ client.notify_user(defaults) }.to_not raise_error
77
+ client.notify_user(defaults)
78
+ body = MultiJson.encode(
79
+ title: 'a title',
80
+ body: 'a body',
81
+ target: {type: 'user', id: defaults[:user_uuid]})
82
+ expect(@stub.with(body: body)).to have_been_requested
83
+ end
80
84
 
81
- unstubbed_body = defaults.merge({title: 'bad title'})
82
- expect{ client.notify_user(unstubbed_body) }.to raise_error(Excon::Errors::StubNotFound)
85
+ it 'supports actions' do
86
+ action = { label: 'omg', url: 'https://foo' }
87
+ client.notify_user(defaults.merge(action: action))
88
+ post_with_action = @stub.with do |req|
89
+ body = MultiJson.decode(req.body, symbolize_keys: true)
90
+ body[:action] == action
91
+ end
92
+ expect(post_with_action).to have_been_requested
83
93
  end
84
94
 
85
95
  it 'returns a parsed json response' do
@@ -90,23 +100,17 @@ end
90
100
 
91
101
  describe Minitel::Client, '#add_followup' do
92
102
  let(:defaults) { {body: 'a body', message_uuid: SecureRandom.uuid} }
93
- let(:client) { Minitel::Client.new('https://u:p@h.com') }
103
+ let(:client) { Minitel::Client.new('https://telex.com') }
94
104
 
95
105
  before do
96
- request = {path: "/producer/messages/#{defaults[:message_uuid]}/followups", method: :post}
97
- response = {status: 201, body: MultiJson.dump({'success' => true})}
98
- body = MultiJson.dump({
99
- body: 'a body',
100
- })
101
-
102
- Excon.stub(request.merge(body: body), response)
106
+ @stub = stub_request(:post, "https://telex.com/producer/messages/#{defaults[:message_uuid]}/followups").
107
+ to_return(status: 201, body: MultiJson.encode(success: true))
103
108
  end
104
109
 
105
110
  it 'posts a proper json body to the producer messages endpoint' do
106
- expect{ client.add_followup(defaults) }.to_not raise_error
107
-
108
- unstubbed_body = defaults.merge({message_uuid: SecureRandom.uuid})
109
- expect{ client.add_followup(unstubbed_body) }.to raise_error(Excon::Errors::StubNotFound)
111
+ client.add_followup(defaults)
112
+ body = MultiJson.encode(body: 'a body')
113
+ expect(@stub.with(body: body)).to have_been_requested
110
114
  end
111
115
 
112
116
  it 'returns a parsed json response' do
@@ -4,31 +4,37 @@ describe Minitel::StrictArgs, '.enforce' do
4
4
  describe 'arguments' do
5
5
  before do
6
6
  @hash = {one: 1, two: 2, uuid: SecureRandom.uuid}
7
- @keys = @hash.keys
7
+ @required = [:one, :uuid]
8
+ @optional = [:two]
8
9
  end
9
10
 
10
11
  it 'works when all listed args are present' do
11
- expect { Minitel::StrictArgs.enforce(@hash, @keys, :uuid) }.to_not raise_error
12
+ expect { Minitel::StrictArgs.enforce(@hash, @required, @optional, :uuid) }.to_not raise_error
13
+ end
14
+
15
+ it 'works when optional args are omitted' do
16
+ @hash.delete(:two)
17
+ expect { Minitel::StrictArgs.enforce(@hash, @required, @optional, :uuid) }.to_not raise_error
12
18
  end
13
19
 
14
20
  it "fails when a key is missing from the arg hash" do
15
21
  @hash.delete(:one)
16
- expect { Minitel::StrictArgs.enforce(@hash, @keys, :uuid) }.to raise_error(ArgumentError)
22
+ expect { Minitel::StrictArgs.enforce(@hash, @required, @optional, :uuid) }.to raise_error(ArgumentError)
17
23
  end
18
24
 
19
25
  it "fails when a key is nil" do
20
26
  @hash[:one] = nil
21
- expect { Minitel::StrictArgs.enforce(@hash, @keys, :uuid) }.to raise_error(ArgumentError)
27
+ expect { Minitel::StrictArgs.enforce(@hash, @required, @optional, :uuid) }.to raise_error(ArgumentError)
22
28
  end
23
29
 
24
30
  it 'fails if the uuid column uuid is not a uuid' do
25
31
  @hash[:uuid] = "not a uuid"
26
- expect { Minitel::StrictArgs.enforce(@hash, @keys, :uuid) }.to raise_error(ArgumentError)
32
+ expect { Minitel::StrictArgs.enforce(@hash, @required, @optional, :uuid) }.to raise_error(ArgumentError)
27
33
  end
28
34
 
29
35
  it 'fails if there is an extra key' do
30
36
  @hash.merge!( {foo: 3} )
31
- expect { Minitel::StrictArgs.enforce(@hash, @keys, :uuid) }.to raise_error(ArgumentError)
37
+ expect { Minitel::StrictArgs.enforce(@hash, @required, @optional, :uuid) }.to raise_error(ArgumentError)
32
38
  end
33
39
  end
34
40
  end
data/spec/spec_helper.rb CHANGED
@@ -1,13 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'rspec'
3
+ require 'webmock/rspec'
3
4
  require 'minitel'
4
5
 
5
6
  RSpec.configure do |config|
6
- config.before(:all) do
7
- Excon.defaults[:mock] = true
8
- end
9
-
10
- config.after(:each) do
11
- Excon.stubs.clear
12
- end
13
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minitel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Will Leinweber
@@ -28,7 +28,7 @@ cert_chain:
28
28
  5bkhRfJHSD/uX/cHbjmopLRbPlHrGbZTDIP4VEC5l0QLPiZ1nhKQnf3+U0+FSy2o
29
29
  CCngcLCR6q+mLf+A4L54VxmyrtFpcBfmkU72QYyf3vJ9QipL3XbvJvbpPkWSn1DX
30
30
  -----END CERTIFICATE-----
31
- date: 2014-10-21 00:00:00.000000000 Z
31
+ date: 2015-02-13 00:00:00.000000000 Z
32
32
  dependencies:
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: excon
@@ -100,6 +100,20 @@ dependencies:
100
100
  - - "~>"
101
101
  - !ruby/object:Gem::Version
102
102
  version: '3.0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: webmock
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '1.20'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '1.20'
103
117
  description: "\U0001D54B\U0001D53C\U0001D543\U0001D53C\U0001D54F client"
104
118
  email:
105
119
  - will@bitfission.com
@@ -108,6 +122,7 @@ extensions: []
108
122
  extra_rdoc_files: []
109
123
  files:
110
124
  - ".gitignore"
125
+ - ".rspec"
111
126
  - ".travis.yml"
112
127
  - Gemfile
113
128
  - Guardfile
@@ -143,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
143
158
  version: '0'
144
159
  requirements: []
145
160
  rubyforge_project:
146
- rubygems_version: 2.2.2
161
+ rubygems_version: 2.4.5
147
162
  signing_key:
148
163
  specification_version: 4
149
164
  summary: "\U0001D54B\U0001D53C\U0001D543\U0001D53C\U0001D54F client: see https://github.com/heroku/telex"
metadata.gz.sig CHANGED
Binary file