hertz 1.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +27 -42
- data/Rakefile +5 -3
- data/app/models/hertz/delivery.rb +1 -0
- data/app/models/hertz/notification.rb +2 -0
- data/db/migrate/20160415174901_create_hertz_notifications.rb +1 -1
- data/db/migrate/20160627084018_create_hertz_notification_deliveries.rb +1 -1
- data/db/migrate/20160628084342_rename_notification_deliveries_to_deliveries.rb +1 -1
- data/lib/generators/hertz/install_generator.rb +2 -1
- data/lib/generators/hertz/templates/initializer.rb +1 -0
- data/lib/hertz.rb +1 -0
- data/lib/hertz/engine.rb +1 -0
- data/lib/hertz/notifiable.rb +1 -0
- data/lib/hertz/notification_deliverer.rb +2 -1
- data/lib/hertz/version.rb +2 -1
- data/spec/dummy/config/database.travis.yml +4 -0
- data/spec/factories/hertz/deliveries.rb +3 -2
- data/spec/factories/hertz/notifications.rb +3 -2
- data/spec/factories/users.rb +2 -1
- data/spec/hertz/hertz_spec.rb +2 -1
- data/spec/hertz/notifiable_spec.rb +25 -26
- data/spec/hertz/notification_deliverer_spec.rb +40 -47
- data/spec/models/hertz/notification_spec.rb +67 -57
- data/spec/spec_helper.rb +3 -0
- data/spec/support/factory_bot.rb +5 -0
- metadata +57 -72
- data/app/assets/javascripts/hertz/application.js +0 -13
- data/app/assets/stylesheets/hertz/application.css +0 -15
- data/app/controllers/hertz/application_controller.rb +0 -6
- data/app/helpers/hertz/application_helper.rb +0 -5
- data/app/views/layouts/hertz/application.html.erb +0 -14
- data/spec/dummy/config/database.yml +0 -19
- data/spec/dummy/log/development.log +0 -61
- data/spec/dummy/log/test.log +0 -217
- data/spec/examples.txt +0 -20
- data/spec/models/hertz/delivery_spec.rb +0 -12
- data/spec/support/factory_girl.rb +0 -5
- data/spec/support/shoulda.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6d6cb83749f5c26265f7c4e034bc4d7b4a860ff9e976bd9749ece869d04b0312
|
4
|
+
data.tar.gz: dbbf0fe3c453b17d7178849aa50114ee38dfe319b4b1a41ae26ad29009f7d743
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f27a28147d6d505617f383480afd38161c3bc2ab86dd5bcc1c2554ca3bd511f0a3e89303bdef31692d2bd9633e5df81c265980570f322037ab364c8ce197f71
|
7
|
+
data.tar.gz: 8b7e1d023865f0f17a83a5e56ad891c62b6d6a1fd4e23a2efb201b1356a58cfdbce8468c5a4ef6d388d0f41af5b4d079c20306125e9b42fe1c3ee8bb58f826bf
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# Hertz
|
2
2
|
|
3
|
-
[![
|
4
|
-
[![
|
5
|
-
[![
|
3
|
+
[![Build Status](https://travis-ci.org/aldesantis/hertz.svg?branch=master)](https://travis-ci.org/aldesantis/hertz)
|
4
|
+
[![Coverage Status](https://coveralls.io/repos/github/aldesantis/hertz/badge.svg?branch=master)](https://coveralls.io/github/aldesantis/hertz?branch=master)
|
5
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/84d43f19a0ec0bf62ede/maintainability)](https://codeclimate.com/github/aldesantis/hertz/maintainability)
|
6
6
|
|
7
7
|
Hertz is a Ruby on Rails engine for sending in-app notifications to your users.
|
8
8
|
|
@@ -33,8 +33,7 @@ $ rails g hertz:install
|
|
33
33
|
$ rake db:migrate
|
34
34
|
```
|
35
35
|
|
36
|
-
Finally, add the following to the model that will receive the notifications
|
37
|
-
(e.g. `User`):
|
36
|
+
Finally, add the following to the model that will receive the notifications (e.g. `User`):
|
38
37
|
|
39
38
|
```ruby
|
40
39
|
class User < ActiveRecord::Base
|
@@ -46,39 +45,32 @@ end
|
|
46
45
|
|
47
46
|
### Using couriers
|
48
47
|
|
49
|
-
Couriers are what Hertz uses to deliver notifications to your users. For
|
50
|
-
|
51
|
-
another one for delivering them by email.
|
48
|
+
Couriers are what Hertz uses to deliver notifications to your users. For instance, you might have a courier for
|
49
|
+
delivering notifications by SMS and another one for delivering them by email.
|
52
50
|
|
53
51
|
Creating a new courier in Hertz is easy:
|
54
52
|
|
55
53
|
```ruby
|
56
54
|
module Hertz
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
# ...
|
61
|
-
end
|
55
|
+
class Sms
|
56
|
+
def self.deliver_notification(notification)
|
57
|
+
# ...
|
62
58
|
end
|
63
59
|
end
|
64
60
|
end
|
65
61
|
```
|
66
62
|
|
67
|
-
Again, you don't have to use couriers if you only display notifications on your
|
68
|
-
website using standard AR methods.
|
69
|
-
|
70
63
|
### Creating new notification types
|
71
64
|
|
72
|
-
In Hertz, every notification is a model. If you want to create a new
|
73
|
-
|
74
|
-
`Hertz::Notification`:
|
65
|
+
In Hertz, every notification is a model. If you want to create a new notification type, just create a new model
|
66
|
+
inheriting from `Hertz::Notification`:
|
75
67
|
|
76
68
|
```ruby
|
77
69
|
class CommentNotification < Hertz::Notification
|
78
70
|
end
|
79
71
|
```
|
80
|
-
Since not all notifications might implement interfaces for all couriers, you
|
81
|
-
|
72
|
+
Since not all notifications might implement interfaces for all couriers, you have to manually specify which couriers
|
73
|
+
they implement via `deliver_by`:
|
82
74
|
|
83
75
|
```ruby
|
84
76
|
class CommentNotification < Hertz::Notification
|
@@ -88,8 +80,8 @@ end
|
|
88
80
|
|
89
81
|
Notifications are not required to implement any couriers.
|
90
82
|
|
91
|
-
You can set common couriers (i.e. couriers that will be used for all
|
92
|
-
|
83
|
+
You can set common couriers (i.e. couriers that will be used for all notifications) by putting the following into an
|
84
|
+
initializer:
|
93
85
|
|
94
86
|
```ruby
|
95
87
|
Hertz.configure do |config|
|
@@ -99,8 +91,7 @@ end
|
|
99
91
|
|
100
92
|
### Attaching metadata to a notification
|
101
93
|
|
102
|
-
You can attach custom metadata to a notification, but make sure it can be
|
103
|
-
cleanly stored in an hstore:
|
94
|
+
You can attach custom metadata to a notification, but make sure it can be cleanly stored in an hstore:
|
104
95
|
|
105
96
|
```ruby
|
106
97
|
notification = CommentNotification.new(meta: { comment_id: comment.id })
|
@@ -117,8 +108,7 @@ class CommentNotification < Hertz::Notification
|
|
117
108
|
end
|
118
109
|
```
|
119
110
|
|
120
|
-
Note that you should always access your metadata with string keys, regardless of
|
121
|
-
the type you use when attaching it.
|
111
|
+
Note that you should always access your metadata with string keys, regardless of the type you use when attaching it.
|
122
112
|
|
123
113
|
### Notifying users
|
124
114
|
|
@@ -134,6 +124,7 @@ You can access a user's notifications with `#notifications`:
|
|
134
124
|
|
135
125
|
```ruby
|
136
126
|
current_user.notifications
|
127
|
+
current_user.notifications.read
|
137
128
|
current_user.notifications.unread
|
138
129
|
```
|
139
130
|
|
@@ -146,9 +137,8 @@ notification.mark_as_unread
|
|
146
137
|
|
147
138
|
### Tracking delivery status
|
148
139
|
|
149
|
-
Hertz provides an API couriers can use to mark the notification as delivered.
|
150
|
-
|
151
|
-
notifications and helps prevent double deliveries:
|
140
|
+
Hertz provides an API couriers can use to mark the notification as delivered. This allows you to know which couriers
|
141
|
+
have successfully delivered your notifications and helps prevent double deliveries:
|
152
142
|
|
153
143
|
```ruby
|
154
144
|
notification.delivered_with?(:email) # => false
|
@@ -156,24 +146,19 @@ notification.mark_delivered_with(:email) # => Hertz::Delivery
|
|
156
146
|
notification.delivered_with?(:email) # => true
|
157
147
|
```
|
158
148
|
|
159
|
-
Hertz does not enforce usage of the delivery API in any way, so some couriers
|
160
|
-
might not take advantage of it.
|
149
|
+
Hertz does not enforce usage of the delivery API in any way, so some couriers might not take advantage of it.
|
161
150
|
|
162
151
|
## Available couriers
|
163
152
|
|
164
|
-
- [hertz-
|
165
|
-
|
166
|
-
- [hertz-
|
167
|
-
|
168
|
-
- [hertz-courier-intercom](https://github.com/alessandro1997/hertz-courier-intercom):
|
169
|
-
delivers notifications as Intercom conversations.
|
153
|
+
- [hertz-twilio](https://github.com/aldesantis/hertz-twilio): delivers notifications by SMS with the
|
154
|
+
Twilio API.
|
155
|
+
- [hertz-email](https://github.com/aldesantis/hertz-email): delivers notifications by email with
|
156
|
+
ActionMailer.
|
170
157
|
|
171
158
|
## Contributing
|
172
159
|
|
173
|
-
Bug reports and pull requests are welcome on GitHub at
|
174
|
-
https://github.com/alessandro1997/hertz.
|
160
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/aldesantis/hertz.
|
175
161
|
|
176
162
|
## License
|
177
163
|
|
178
|
-
The gem is available as open source under the terms of the
|
179
|
-
[MIT License](http://opensource.org/licenses/MIT).
|
164
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Hertz
|
3
4
|
class Notification < ActiveRecord::Base
|
4
5
|
@couriers = []
|
5
6
|
|
7
|
+
scope :read, -> { where 'read_at IS NOT NULL' }
|
6
8
|
scope :unread, -> { where 'read_at IS NULL' }
|
7
9
|
|
8
10
|
belongs_to :receiver, inverse_of: :notifications, polymorphic: true
|
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Hertz
|
3
4
|
class InstallGenerator < Rails::Generators::Base
|
4
|
-
source_root File.expand_path('
|
5
|
+
source_root File.expand_path('templates', __dir__)
|
5
6
|
|
6
7
|
def copy_initializer_file
|
7
8
|
copy_file 'initializer.rb', 'config/initializers/hertz.rb'
|
data/lib/hertz.rb
CHANGED
data/lib/hertz/engine.rb
CHANGED
data/lib/hertz/notifiable.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Hertz
|
3
4
|
class NotificationDeliverer
|
4
5
|
class << self
|
@@ -15,7 +16,7 @@ module Hertz
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def build_courier(courier)
|
18
|
-
"Hertz
|
19
|
+
"Hertz::#{courier.to_s.camelcase}".constantize
|
19
20
|
end
|
20
21
|
end
|
21
22
|
end
|
data/lib/hertz/version.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
FactoryBot.define do
|
3
4
|
factory :notification, class: 'Hertz::Notification' do
|
4
|
-
type 'Hertz::Notification'
|
5
|
+
type { 'Hertz::Notification' }
|
5
6
|
association :receiver, factory: :user, strategy: :build
|
6
7
|
|
7
8
|
trait :read do
|
data/spec/factories/users.rb
CHANGED
data/spec/hertz/hertz_spec.rb
CHANGED
@@ -1,40 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
module Hertz
|
3
|
-
RSpec.describe Notifiable do
|
4
|
-
let(:user) { create(:user) }
|
5
2
|
|
6
|
-
|
7
|
-
|
3
|
+
RSpec.describe Hertz::Notifiable do
|
4
|
+
let(:user) { create(:user) }
|
8
5
|
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
describe '.notifications' do
|
7
|
+
let!(:notification) { create(:notification, receiver: user) }
|
8
|
+
|
9
|
+
it "returns the receiver's notifications" do
|
10
|
+
expect(user.notifications).to eq([notification])
|
12
11
|
end
|
12
|
+
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
describe '#notify' do
|
15
|
+
before do
|
16
|
+
class TestNotification < Hertz::Notification; end
|
17
|
+
end
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
context 'with a notification object' do
|
20
|
+
subject { -> { user.notify(TestNotification.new) } }
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
end
|
22
|
+
it 'notifies the receiver' do
|
23
|
+
expect(subject).to change(user.notifications, :count).by(1)
|
25
24
|
end
|
25
|
+
end
|
26
26
|
|
27
|
-
|
28
|
-
|
27
|
+
context 'with a notification class' do
|
28
|
+
subject { -> { user.notify(TestNotification, foo: 'bar') } }
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
it 'notifies the receiver' do
|
31
|
+
expect(subject).to change(user.notifications, :count).by(1)
|
32
|
+
end
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
34
|
+
it 'sets the provided meta' do
|
35
|
+
subject.call
|
36
|
+
expect(user.notifications.last.meta).to eq('foo' => 'bar')
|
38
37
|
end
|
39
38
|
end
|
40
39
|
end
|
@@ -1,65 +1,58 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
module Hertz
|
3
|
-
RSpec.describe NotificationDeliverer do
|
4
|
-
subject { described_class }
|
5
2
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
3
|
+
RSpec.describe Hertz::NotificationDeliverer do
|
4
|
+
subject { described_class }
|
5
|
+
|
6
|
+
before do
|
7
|
+
module Hertz
|
8
|
+
class Test
|
9
|
+
def self.deliver_notification(_notification); end
|
12
10
|
end
|
13
11
|
end
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
14
|
+
describe '#deliver' do
|
15
|
+
let(:notification) do
|
16
|
+
Class.new(TestNotification) do
|
17
|
+
deliver_by :test
|
18
|
+
end.new
|
19
|
+
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
it 'delivers the notification through the couriers' do
|
22
|
+
expect(Hertz::Test).to receive(:deliver_notification)
|
23
|
+
.once
|
24
|
+
.with(notification)
|
26
25
|
|
27
|
-
|
28
|
-
|
26
|
+
subject.deliver(notification)
|
27
|
+
end
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
29
|
+
context 'when common couriers are defined' do
|
30
|
+
before do
|
31
|
+
module Hertz
|
32
|
+
class Common
|
33
|
+
def self.deliver_notification(_notification); end
|
37
34
|
end
|
38
35
|
end
|
39
36
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
allow(Hertz::Courier::Test).to receive(:deliver_notification)
|
45
|
-
allow(Hertz::Courier::Common).to receive(:deliver_notification)
|
46
|
-
end
|
37
|
+
allow(Hertz).to receive(:common_couriers).and_return([:common])
|
38
|
+
allow(Hertz::Test).to receive(:deliver_notification)
|
39
|
+
allow(Hertz::Common).to receive(:deliver_notification)
|
40
|
+
end
|
47
41
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
42
|
+
it 'uses common couriers' do
|
43
|
+
expect(Hertz::Test).to receive(:deliver_notification)
|
44
|
+
.once
|
45
|
+
.with(notification)
|
52
46
|
|
53
|
-
|
54
|
-
|
47
|
+
subject.deliver(notification)
|
48
|
+
end
|
55
49
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
50
|
+
it 'uses model-specific couriers' do
|
51
|
+
expect(Hertz::Common).to receive(:deliver_notification)
|
52
|
+
.once
|
53
|
+
.with(notification)
|
60
54
|
|
61
|
-
|
62
|
-
end
|
55
|
+
subject.deliver(notification)
|
63
56
|
end
|
64
57
|
end
|
65
58
|
end
|