eventifier 0.0.14 → 0.1.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 +4 -4
- data/Gemfile +1 -1
- data/README.textile +32 -4
- data/app/assets/javascripts/eventifier/notifications.coffee +29 -5
- data/app/assets/javascripts/eventifier/templates/dropdown.hamlc +1 -1
- data/app/assets/stylesheets/eventifier/notifications.scss +1 -1
- data/app/controllers/eventifier/preferences_controller.rb +7 -9
- data/app/helpers/eventifier/notification_helper.rb +1 -1
- data/app/helpers/eventifier/path_helper.rb +2 -2
- data/app/models/eventifier/event.rb +1 -3
- data/app/models/eventifier/notification.rb +0 -2
- data/app/models/eventifier/notification_setting.rb +0 -2
- data/app/views/eventifier/notifications/index.jbuilder +2 -2
- data/db/migrate/5_system_events.rb +9 -0
- data/eventifier.gemspec +7 -5
- data/lib/eventifier.rb +2 -0
- data/lib/eventifier/event_builder.rb +4 -1
- data/lib/eventifier/notification_translator.rb +27 -5
- data/lib/eventifier/notifier/notification_subscriber.rb +6 -6
- data/lib/eventifier/notifier/notifier.rb +5 -5
- data/lib/eventifier/preferences.rb +14 -0
- data/lib/eventifier/tracker.rb +7 -0
- data/lib/generators/eventifier/install/install_generator.rb +1 -1
- data/lib/generators/eventifier/install/templates/{events.en.yaml → events.en.yml} +3 -0
- data/spec/controllers/eventifier/notifications_controller_spec.rb +3 -1
- data/spec/controllers/eventifier/preferences_controller_spec.rb +5 -23
- data/spec/event_tracking_spec.rb +2 -2
- data/spec/eventifier/notification_translator_spec.rb +118 -0
- data/spec/eventifier/preferences_spec.rb +47 -10
- data/spec/eventifier/relationship_spec.rb +8 -8
- data/spec/eventifier_spec.rb +14 -10
- data/spec/helpers/eventifier/notification_helper_spec.rb +13 -13
- data/spec/helpers/eventifier/path_helper_spec.rb +3 -3
- data/spec/integration/eventifier_spec.rb +11 -11
- data/spec/integration/internationalisation_spec.rb +4 -4
- data/spec/integration/system_events_spec.rb +40 -0
- data/spec/models/eventifier/event_spec.rb +1 -1
- data/spec/models/eventifier/ghost_spec.rb +3 -4
- data/spec/models/eventifier/notification_spec.rb +3 -3
- data/spec/notifier/notification_mapping_spec.rb +3 -3
- metadata +61 -41
@@ -13,10 +13,24 @@ class Eventifier::Preferences
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
+
def update(preferences)
|
17
|
+
settings.preferences['email'] ||= {}
|
18
|
+
to_hashes.each do |hash|
|
19
|
+
settings.preferences['email'][hash[:key]] = boolean(
|
20
|
+
preferences[hash[:key]]
|
21
|
+
)
|
22
|
+
end
|
23
|
+
settings.save
|
24
|
+
end
|
25
|
+
|
16
26
|
private
|
17
27
|
|
18
28
|
attr_reader :user
|
19
29
|
|
30
|
+
def boolean(value)
|
31
|
+
!(value.nil? || value == '0')
|
32
|
+
end
|
33
|
+
|
20
34
|
def keys
|
21
35
|
@keys ||= begin
|
22
36
|
hash = Eventifier::NotificationMapping.notification_mappings
|
data/lib/eventifier/tracker.rb
CHANGED
@@ -8,6 +8,13 @@ module Eventifier
|
|
8
8
|
User.class_eval {
|
9
9
|
has_many :notifications, class_name: 'Eventifier::Notification'
|
10
10
|
} unless User.respond_to?(:notifications)
|
11
|
+
User.class_eval {
|
12
|
+
has_one :notification_setting,
|
13
|
+
class_name: 'Eventifier::NotificationSetting',
|
14
|
+
dependent: :destroy
|
15
|
+
} unless User.respond_to?(:notification_setting)
|
16
|
+
|
17
|
+
|
11
18
|
|
12
19
|
# set up each class with an observer and relationships
|
13
20
|
@klasses.each do |target_klass|
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Eventifier::NotificationsController do
|
4
|
+
routes { Eventifier::Engine.routes }
|
5
|
+
|
4
6
|
describe '#touch' do
|
5
7
|
let(:user) { double 'User', :update_attribute => true }
|
6
8
|
|
@@ -18,7 +20,7 @@ describe Eventifier::NotificationsController do
|
|
18
20
|
it "responds with JSON OK status" do
|
19
21
|
post :touch
|
20
22
|
|
21
|
-
response.body.
|
23
|
+
expect(response.body).to eq ({'status' => 'OK'}.to_json)
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Eventifier::PreferencesController do
|
4
|
+
routes { Eventifier::Engine.routes }
|
4
5
|
let(:user) { double 'User' }
|
5
6
|
|
6
7
|
before :each do
|
@@ -15,34 +16,15 @@ describe Eventifier::PreferencesController do
|
|
15
16
|
it "returns the settings hashes" do
|
16
17
|
get :show
|
17
18
|
|
18
|
-
response.body.
|
19
|
+
expect(response.body).to eq ([{'foo' => 'bar'}].to_json)
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
22
23
|
describe '#update' do
|
23
|
-
let(:preferences) { double
|
24
|
-
let(:settings) { double 'Settings', :preferences => {}, :save => true }
|
25
|
-
|
26
|
-
before :each do
|
27
|
-
Eventifier::NotificationSetting.stub :for_user => settings
|
28
|
-
end
|
29
|
-
|
30
|
-
it "updates the user's email preferences" do
|
31
|
-
put :update, :preferences => {'foo' => ''}
|
32
|
-
|
33
|
-
settings.preferences['email']['foo'].should be_true
|
34
|
-
settings.preferences['email']['bar'].should be_false
|
35
|
-
end
|
36
|
-
|
37
|
-
it "sets everything to false if no preferences are supplied" do
|
38
|
-
put :update
|
39
|
-
|
40
|
-
settings.preferences['email']['foo'].should be_false
|
41
|
-
settings.preferences['email']['bar'].should be_false
|
42
|
-
end
|
24
|
+
let(:preferences) { double update: true }
|
43
25
|
|
44
26
|
it 'saves the settings changes' do
|
45
|
-
|
27
|
+
preferences.should_receive(:update).with('foo' => '')
|
46
28
|
|
47
29
|
put :update, :preferences => {'foo' => ''}
|
48
30
|
end
|
@@ -50,7 +32,7 @@ describe Eventifier::PreferencesController do
|
|
50
32
|
it "renders a JSON OK status" do
|
51
33
|
put :update, :preferences => {'foo' => ''}
|
52
34
|
|
53
|
-
response.body.
|
35
|
+
expect(response.body).to eq ({'status' => 'OK'}.to_json)
|
54
36
|
end
|
55
37
|
end
|
56
38
|
end
|
data/spec/event_tracking_spec.rb
CHANGED
@@ -12,9 +12,9 @@ describe Eventifier::EventTracking do
|
|
12
12
|
|
13
13
|
event_tracker.url url_proc
|
14
14
|
|
15
|
-
Eventifier::EventTracking.url_mappings[:activity].
|
15
|
+
expect(Eventifier::EventTracking.url_mappings[:activity]).to eq url_proc
|
16
16
|
end
|
17
17
|
|
18
18
|
end
|
19
19
|
|
20
|
-
end
|
20
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Eventifier::NotificationTranslator do
|
4
|
+
let(:translator) {
|
5
|
+
Eventifier::NotificationTranslator.new 'foo', options, :bar
|
6
|
+
}
|
7
|
+
let(:options) { {} }
|
8
|
+
let(:object) { double 'EventableObject'}
|
9
|
+
let(:event) { double 'Event', user: double, eventable: object }
|
10
|
+
let(:user_a) { double 'User' }
|
11
|
+
let(:user_b) { double 'User' }
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
stub_const 'ActiveSupport::Notifications::Event',
|
15
|
+
double(new: double(payload: {event: event}))
|
16
|
+
stub_const 'Eventifier::NotificationMapping', double
|
17
|
+
stub_const 'Eventifier::Notification', double(create: double)
|
18
|
+
stub_const 'Eventifier::Delivery', double(deliver_for: true)
|
19
|
+
|
20
|
+
Eventifier::NotificationMapping.stub(:users_and_relations).
|
21
|
+
and_yield(user_a, [:a]).and_yield(user_b, [:b])
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#translate' do
|
25
|
+
it "creates a notification for each affected user" do
|
26
|
+
Eventifier::Notification.should_receive(:create).
|
27
|
+
with(event: event, user: user_a, relations: [:a])
|
28
|
+
Eventifier::Notification.should_receive(:create).
|
29
|
+
with(event: event, user: user_b, relations: [:b])
|
30
|
+
|
31
|
+
translator.translate
|
32
|
+
end
|
33
|
+
|
34
|
+
it "does not create an event for the originator's user" do
|
35
|
+
event.stub user: user_a
|
36
|
+
|
37
|
+
Eventifier::Notification.should_not_receive(:create).
|
38
|
+
with(event: event, user: user_a, relations: [:a])
|
39
|
+
Eventifier::Notification.should_receive(:create).
|
40
|
+
with(event: event, user: user_b, relations: [:b])
|
41
|
+
|
42
|
+
translator.translate
|
43
|
+
end
|
44
|
+
|
45
|
+
it "creates a notification for the originating user if allowed" do
|
46
|
+
options[:notify_self] = true
|
47
|
+
|
48
|
+
event.stub user: user_a
|
49
|
+
|
50
|
+
Eventifier::Notification.should_receive(:create).
|
51
|
+
with(event: event, user: user_a, relations: [:a])
|
52
|
+
Eventifier::Notification.should_receive(:create).
|
53
|
+
with(event: event, user: user_b, relations: [:b])
|
54
|
+
|
55
|
+
translator.translate
|
56
|
+
end
|
57
|
+
|
58
|
+
it "creates an event when :if is set and returns true" do
|
59
|
+
options[:if] = Proc.new { |event, user| true }
|
60
|
+
|
61
|
+
Eventifier::Notification.should_receive(:create).
|
62
|
+
with(event: event, user: user_a, relations: [:a])
|
63
|
+
Eventifier::Notification.should_receive(:create).
|
64
|
+
with(event: event, user: user_b, relations: [:b])
|
65
|
+
|
66
|
+
translator.translate
|
67
|
+
end
|
68
|
+
|
69
|
+
it "does not create an event when :if is set and returns false" do
|
70
|
+
options[:if] = Proc.new { |event, user| false }
|
71
|
+
|
72
|
+
Eventifier::Notification.should_not_receive(:create).
|
73
|
+
with(event: event, user: user_a, relations: [:a])
|
74
|
+
Eventifier::Notification.should_not_receive(:create).
|
75
|
+
with(event: event, user: user_b, relations: [:b])
|
76
|
+
|
77
|
+
translator.translate
|
78
|
+
end
|
79
|
+
|
80
|
+
it "creates an event when :unless is set and returns false" do
|
81
|
+
options[:unless] = Proc.new { |event, user| false }
|
82
|
+
|
83
|
+
Eventifier::Notification.should_receive(:create).
|
84
|
+
with(event: event, user: user_a, relations: [:a])
|
85
|
+
Eventifier::Notification.should_receive(:create).
|
86
|
+
with(event: event, user: user_b, relations: [:b])
|
87
|
+
|
88
|
+
translator.translate
|
89
|
+
end
|
90
|
+
|
91
|
+
it "does not create an event when :unless is set and returns true" do
|
92
|
+
options[:unless] = Proc.new { |event, user| true }
|
93
|
+
|
94
|
+
Eventifier::Notification.should_not_receive(:create).
|
95
|
+
with(event: event, user: user_a, relations: [:a])
|
96
|
+
Eventifier::Notification.should_not_receive(:create).
|
97
|
+
with(event: event, user: user_b, relations: [:b])
|
98
|
+
|
99
|
+
translator.translate
|
100
|
+
end
|
101
|
+
|
102
|
+
it "does not deliver an email by default" do
|
103
|
+
Eventifier::Delivery.should_not_receive(:deliver_for).with(user_a)
|
104
|
+
Eventifier::Delivery.should_not_receive(:deliver_for).with(user_b)
|
105
|
+
|
106
|
+
translator.translate
|
107
|
+
end
|
108
|
+
|
109
|
+
it "delivers email when :email is set to :immediate" do
|
110
|
+
options[:email] = :immediate
|
111
|
+
|
112
|
+
Eventifier::Delivery.should_receive(:deliver_for).with(user_a)
|
113
|
+
Eventifier::Delivery.should_receive(:deliver_for).with(user_b)
|
114
|
+
|
115
|
+
translator.translate
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -14,7 +14,7 @@ describe Eventifier::Preferences do
|
|
14
14
|
|
15
15
|
describe '#to_hashes' do
|
16
16
|
it "interprets each key" do
|
17
|
-
preferences.to_hashes.collect { |hash| hash[:key] }.
|
17
|
+
expect(preferences.to_hashes.collect { |hash| hash[:key] }).to eq [
|
18
18
|
'default',
|
19
19
|
'create_posts_notify_readers',
|
20
20
|
'create_comments_notify_post_readers'
|
@@ -22,28 +22,28 @@ describe Eventifier::Preferences do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
it "sets values to true if unknown" do
|
25
|
-
preferences.to_hashes.collect { |hash| hash[:value] }.
|
26
|
-
|
25
|
+
expect(preferences.to_hashes.collect { |hash| hash[:value] }).
|
26
|
+
to eq [true, true, true]
|
27
27
|
end
|
28
28
|
|
29
29
|
it "sets values to true if known and true" do
|
30
30
|
settings.preferences['email'] = {}
|
31
31
|
settings.preferences['email']['create_posts_notify_readers'] = true
|
32
32
|
|
33
|
-
preferences.to_hashes.collect { |hash| hash[:value] }.
|
34
|
-
|
33
|
+
expect(preferences.to_hashes.collect { |hash| hash[:value] }).
|
34
|
+
to eq [true, true, true]
|
35
35
|
end
|
36
36
|
|
37
37
|
it "sets values to false if known and false" do
|
38
38
|
settings.preferences['email'] = {}
|
39
39
|
settings.preferences['email']['create_posts_notify_readers'] = false
|
40
40
|
|
41
|
-
preferences.to_hashes.collect { |hash| hash[:value] }.
|
42
|
-
|
41
|
+
expect(preferences.to_hashes.collect { |hash| hash[:value] }).
|
42
|
+
to eq [true, false, true]
|
43
43
|
end
|
44
44
|
|
45
45
|
it "returns keys if no translations available for labels" do
|
46
|
-
preferences.to_hashes.collect { |hash| hash[:label] }.
|
46
|
+
expect(preferences.to_hashes.collect { |hash| hash[:label] }).to eq [
|
47
47
|
'default',
|
48
48
|
'create_posts_notify_readers',
|
49
49
|
'create_comments_notify_post_readers'
|
@@ -62,8 +62,45 @@ describe Eventifier::Preferences do
|
|
62
62
|
}
|
63
63
|
}
|
64
64
|
|
65
|
-
preferences.to_hashes.collect { |hash| hash[:label] }.
|
66
|
-
|
65
|
+
expect(preferences.to_hashes.collect { |hash| hash[:label] }).
|
66
|
+
to eq ['All Events', 'New Posts', 'New Comments']
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '#update' do
|
71
|
+
before :each do
|
72
|
+
settings.stub save: true
|
73
|
+
end
|
74
|
+
|
75
|
+
it "updates the user's email preferences" do
|
76
|
+
preferences.update(
|
77
|
+
'create_posts_notify_readers' => '',
|
78
|
+
'create_comments_notify_post_readers' => '0'
|
79
|
+
)
|
80
|
+
|
81
|
+
expect(
|
82
|
+
settings.preferences['email']['create_posts_notify_readers']
|
83
|
+
).to be_truthy
|
84
|
+
expect(
|
85
|
+
settings.preferences['email']['create_comments_notify_post_readers']
|
86
|
+
).to be_falsey
|
87
|
+
end
|
88
|
+
|
89
|
+
it "sets everything to false if no preferences are supplied" do
|
90
|
+
preferences.update({})
|
91
|
+
|
92
|
+
expect(
|
93
|
+
settings.preferences['email']['create_posts_notify_readers']
|
94
|
+
).to be_falsey
|
95
|
+
expect(
|
96
|
+
settings.preferences['email']['create_comments_notify_post_readers']
|
97
|
+
).to be_falsey
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'saves the settings changes' do
|
101
|
+
settings.should_receive(:save)
|
102
|
+
|
103
|
+
preferences.update('create_posts_notify_readers' => '')
|
67
104
|
end
|
68
105
|
end
|
69
106
|
end
|
@@ -3,17 +3,17 @@ require 'spec_helper'
|
|
3
3
|
describe Eventifier::Relationship do
|
4
4
|
describe '#key' do
|
5
5
|
it "translates symbol relations to strings" do
|
6
|
-
Eventifier::Relationship.new(double, :mouse).key.
|
6
|
+
expect(Eventifier::Relationship.new(double, :mouse).key).to eq 'mouse'
|
7
7
|
end
|
8
8
|
|
9
9
|
it "translates hash relations to period-separated strings" do
|
10
|
-
Eventifier::Relationship.new(double, :cat => :mouse).key.
|
11
|
-
|
10
|
+
expect(Eventifier::Relationship.new(double, :cat => :mouse).key).
|
11
|
+
to eq 'cat_mouse'
|
12
12
|
end
|
13
13
|
|
14
14
|
it "translates array relations to hyphen-separated strings" do
|
15
|
-
Eventifier::Relationship.new(double, [:cat, :mouse]).key.
|
16
|
-
|
15
|
+
expect(Eventifier::Relationship.new(double, [:cat, :mouse]).key).
|
16
|
+
to eq 'cat-mouse'
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -21,13 +21,13 @@ describe Eventifier::Relationship do
|
|
21
21
|
it "should call the string as a method when passed a string" do
|
22
22
|
object = double('object', :mouse => 5)
|
23
23
|
|
24
|
-
Eventifier::Relationship.new(object, :mouse).users.
|
24
|
+
expect(Eventifier::Relationship.new(object, :mouse).users).to eq [5]
|
25
25
|
end
|
26
26
|
|
27
27
|
it "should string the methods when passed a hash" do
|
28
28
|
object = double('object', :cat => (cat = double('cat', :mouse => 5)))
|
29
29
|
|
30
|
-
Eventifier::Relationship.new(object, :cat => :mouse).users.
|
30
|
+
expect(Eventifier::Relationship.new(object, :cat => :mouse).users).to eq [5]
|
31
31
|
end
|
32
32
|
end
|
33
|
-
end
|
33
|
+
end
|
data/spec/eventifier_spec.rb
CHANGED
@@ -13,7 +13,7 @@ describe Eventifier::EventTracking do
|
|
13
13
|
:track_on => [:create, :update, :destroy],
|
14
14
|
:attributes => { :except => %w(updated_at) }
|
15
15
|
|
16
|
-
user.
|
16
|
+
expect(user).to respond_to(:notifications)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -32,7 +32,7 @@ describe Eventifier::EventTracking do
|
|
32
32
|
changes = { :foo => 'bar', :bar => 'baz' }
|
33
33
|
object.stub(:changes).and_return(changes)
|
34
34
|
|
35
|
-
Eventifier::Event.should_receive(:create).with(:user => user, :eventable => object, :verb => :create, :change_data => changes, :groupable => object).and_return(event)
|
35
|
+
Eventifier::Event.should_receive(:create).with(:user => user, :eventable => object, :verb => :create, :change_data => changes, :groupable => object, :system => nil).and_return(event)
|
36
36
|
|
37
37
|
subject
|
38
38
|
end
|
@@ -55,7 +55,7 @@ describe Eventifier::EventTracking do
|
|
55
55
|
track_on :update, :attributes => { :except => %w(updated_at) }
|
56
56
|
end
|
57
57
|
|
58
|
-
Eventifier::Event.should_receive(:create).with(:user => user, :eventable => object, :verb => :create, :change_data => changes, :groupable => object).and_return(event)
|
58
|
+
Eventifier::Event.should_receive(:create).with(:user => user, :eventable => object, :verb => :create, :change_data => changes, :groupable => object, :system => nil).and_return(event)
|
59
59
|
|
60
60
|
subject
|
61
61
|
end
|
@@ -84,16 +84,20 @@ describe Eventifier::EventTracking do
|
|
84
84
|
object.stub :category => double('category', :subscribers => [subscriber])
|
85
85
|
|
86
86
|
Eventifier::Notification.should_receive(:create) do |args|
|
87
|
-
args[:user].
|
88
|
-
args[:event].eventable.
|
89
|
-
end
|
87
|
+
expect(args[:user]).to == subscriber
|
88
|
+
expect(args[:event].eventable).to == object
|
89
|
+
end.and_return(nil)
|
90
90
|
|
91
|
-
event_tracker.events_for test_class do
|
92
|
-
|
93
|
-
|
94
|
-
end
|
91
|
+
# event_tracker.events_for test_class do
|
92
|
+
# track_on :create, :attributes => { :except => %w(updated_at) }
|
93
|
+
# notify :category => :subscribers, :on => :create
|
94
|
+
# end
|
95
95
|
|
96
96
|
object.save
|
97
|
+
|
98
|
+
ActiveSupport::Notifications.notifier.listeners_for('create.posts.notification.eventifier').each do |listener|
|
99
|
+
ActiveSupport::Notifications.unsubscribe(listener)
|
100
|
+
end
|
97
101
|
end
|
98
102
|
|
99
103
|
|