eventifier 0.0.14 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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