hertz 1.0.2 → 2.0.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 +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
|
-
[](https://travis-ci.org/aldesantis/hertz)
|
4
|
+
[](https://coveralls.io/github/aldesantis/hertz?branch=master)
|
5
|
+
[](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
|