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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/README.textile +32 -4
  4. data/app/assets/javascripts/eventifier/notifications.coffee +29 -5
  5. data/app/assets/javascripts/eventifier/templates/dropdown.hamlc +1 -1
  6. data/app/assets/stylesheets/eventifier/notifications.scss +1 -1
  7. data/app/controllers/eventifier/preferences_controller.rb +7 -9
  8. data/app/helpers/eventifier/notification_helper.rb +1 -1
  9. data/app/helpers/eventifier/path_helper.rb +2 -2
  10. data/app/models/eventifier/event.rb +1 -3
  11. data/app/models/eventifier/notification.rb +0 -2
  12. data/app/models/eventifier/notification_setting.rb +0 -2
  13. data/app/views/eventifier/notifications/index.jbuilder +2 -2
  14. data/db/migrate/5_system_events.rb +9 -0
  15. data/eventifier.gemspec +7 -5
  16. data/lib/eventifier.rb +2 -0
  17. data/lib/eventifier/event_builder.rb +4 -1
  18. data/lib/eventifier/notification_translator.rb +27 -5
  19. data/lib/eventifier/notifier/notification_subscriber.rb +6 -6
  20. data/lib/eventifier/notifier/notifier.rb +5 -5
  21. data/lib/eventifier/preferences.rb +14 -0
  22. data/lib/eventifier/tracker.rb +7 -0
  23. data/lib/generators/eventifier/install/install_generator.rb +1 -1
  24. data/lib/generators/eventifier/install/templates/{events.en.yaml → events.en.yml} +3 -0
  25. data/spec/controllers/eventifier/notifications_controller_spec.rb +3 -1
  26. data/spec/controllers/eventifier/preferences_controller_spec.rb +5 -23
  27. data/spec/event_tracking_spec.rb +2 -2
  28. data/spec/eventifier/notification_translator_spec.rb +118 -0
  29. data/spec/eventifier/preferences_spec.rb +47 -10
  30. data/spec/eventifier/relationship_spec.rb +8 -8
  31. data/spec/eventifier_spec.rb +14 -10
  32. data/spec/helpers/eventifier/notification_helper_spec.rb +13 -13
  33. data/spec/helpers/eventifier/path_helper_spec.rb +3 -3
  34. data/spec/integration/eventifier_spec.rb +11 -11
  35. data/spec/integration/internationalisation_spec.rb +4 -4
  36. data/spec/integration/system_events_spec.rb +40 -0
  37. data/spec/models/eventifier/event_spec.rb +1 -1
  38. data/spec/models/eventifier/ghost_spec.rb +3 -4
  39. data/spec/models/eventifier/notification_spec.rb +3 -3
  40. data/spec/notifier/notification_mapping_spec.rb +3 -3
  41. 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
@@ -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|
@@ -10,7 +10,7 @@ module Eventifier
10
10
  end
11
11
 
12
12
  def copy_language
13
- copy_file "events.en.yaml", "config/locales/events.en.yaml"
13
+ copy_file "events.en.yaml", "config/locales/events.en.yml"
14
14
  end
15
15
 
16
16
  def add_routes
@@ -1,5 +1,8 @@
1
1
  en:
2
2
  events:
3
+ labels:
4
+ preferences:
5
+ default: "All notifications"
3
6
  default:
4
7
  create: "{{user.name}} created a <strong>{{object_type}}</strong>"
5
8
  update:
@@ -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.should == {'status' => 'OK'}.to_json
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.should == [{'foo' => 'bar'}].to_json
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 to_hashes: [{:key => 'foo'}, {:key => 'bar'}] }
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
- settings.should_receive(:save)
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.should == {'status' => 'OK'}.to_json
35
+ expect(response.body).to eq ({'status' => 'OK'}.to_json)
54
36
  end
55
37
  end
56
38
  end
@@ -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].should == url_proc
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] }.should == [
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
- should == [true, true, true]
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
- should == [true, true, true]
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
- should == [true, false, true]
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] }.should == [
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
- should == ['All Events', 'New Posts', 'New Comments']
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.should == 'mouse'
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
- should == 'cat_mouse'
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
- should == 'cat-mouse'
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.should == [5]
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.should == [5]
30
+ expect(Eventifier::Relationship.new(object, :cat => :mouse).users).to eq [5]
31
31
  end
32
32
  end
33
- end
33
+ end
@@ -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.should respond_to(:notifications)
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].should == subscriber
88
- args[:event].eventable.should == object
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
- track_on :create, :attributes => { :except => %w(updated_at) }
93
- notify :category => :subscribers, :on => :create
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