eventifier 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.travis.yml +7 -8
  4. data/Gemfile +1 -1
  5. data/README.textile +44 -3
  6. data/app/assets/images/eventifier/notifications-bell.png +0 -0
  7. data/app/assets/images/eventifier/notifications-tower.png +0 -0
  8. data/app/assets/javascripts/eventifier/notifications.coffee +196 -0
  9. data/app/assets/javascripts/eventifier/templates/dropdown.hamlc +10 -0
  10. data/app/assets/javascripts/eventifier/templates/settings.hamlc +11 -0
  11. data/app/assets/stylesheets/eventifier/notifications.scss +167 -0
  12. data/app/controllers/eventifier/application_controller.rb +4 -0
  13. data/app/controllers/eventifier/notifications_controller.rb +36 -0
  14. data/app/controllers/eventifier/preferences_controller.rb +19 -0
  15. data/app/helpers/eventifier/notification_helper.rb +87 -0
  16. data/app/helpers/eventifier/path_helper.rb +15 -0
  17. data/app/mailers/eventifier/mailer.rb +12 -0
  18. data/app/models/event_tracking.rb +3 -0
  19. data/app/models/eventifier/event.rb +22 -0
  20. data/app/models/eventifier/ghost.rb +21 -0
  21. data/app/models/eventifier/notification.rb +38 -0
  22. data/app/models/eventifier/notification_setting.rb +14 -0
  23. data/app/views/eventifier/_notification.haml +1 -0
  24. data/app/views/eventifier/email/_notification.haml +2 -0
  25. data/app/views/eventifier/mailer/notifications.haml +5 -0
  26. data/app/views/eventifier/notifications/index.jbuilder +6 -0
  27. data/config/routes.rb +7 -0
  28. data/config.ru +7 -0
  29. data/{lib/generators/eventifier/install/templates/migration.rb → db/migrate/1_eventifier_setup.rb} +2 -3
  30. data/db/migrate/2_eventifier_notification_settings.rb +11 -0
  31. data/db/migrate/3_notification_sent_status.rb +15 -0
  32. data/db/migrate/4_event_groupable.rb +19 -0
  33. data/eventifier.gemspec +12 -15
  34. data/lib/eventifier/delivery.rb +59 -0
  35. data/lib/eventifier/{railtie.rb → engine.rb} +4 -2
  36. data/lib/eventifier/event_subscriber.rb +44 -0
  37. data/lib/eventifier/event_tracking.rb +5 -58
  38. data/lib/eventifier/mailers/helpers.rb +70 -0
  39. data/lib/eventifier/notifier/notification_mapping.rb +34 -0
  40. data/lib/eventifier/notifier/notification_subscriber.rb +23 -0
  41. data/lib/eventifier/notifier/notifier.rb +21 -0
  42. data/lib/eventifier/preferences.rb +44 -0
  43. data/lib/eventifier/relationship.rb +36 -0
  44. data/lib/eventifier/trackable_class.rb +74 -0
  45. data/lib/eventifier/tracker.rb +18 -0
  46. data/lib/eventifier.rb +35 -11
  47. data/lib/generators/eventifier/install/install_generator.rb +2 -5
  48. data/lib/generators/eventifier/install/templates/events.en.yaml +1 -0
  49. data/lib/tasks/email.rake +8 -0
  50. data/spec/controllers/eventifier/notifications_controller_spec.rb +24 -0
  51. data/spec/controllers/eventifier/preferences_controller_spec.rb +56 -0
  52. data/spec/eventifier/delivery_spec.rb +110 -0
  53. data/spec/eventifier/preferences_spec.rb +69 -0
  54. data/spec/eventifier/relationship_spec.rb +33 -0
  55. data/spec/eventifier_spec.rb +6 -48
  56. data/spec/fabricators/fabricator.rb +11 -11
  57. data/spec/helpers/eventifier/notification_helper_spec.rb +169 -0
  58. data/spec/helpers/eventifier/path_helper_spec.rb +19 -0
  59. data/spec/integration/eventifier_spec.rb +113 -70
  60. data/spec/integration/internationalisation_spec.rb +39 -0
  61. data/spec/internal/app/controllers/application_controller.rb +3 -0
  62. data/spec/internal/app/lib/event_tracking.rb +12 -0
  63. data/spec/internal/app/models/category.rb +3 -0
  64. data/spec/internal/app/models/post.rb +8 -0
  65. data/spec/internal/app/models/subscription.rb +4 -0
  66. data/spec/internal/app/models/user.rb +4 -0
  67. data/spec/internal/app/views/eventifier/dropdown/_awesome_object.haml +0 -0
  68. data/spec/internal/config/database.yml +4 -0
  69. data/spec/internal/config/initializers/eventifier.rb +1 -0
  70. data/spec/internal/config/locales/events.en.yml +20 -0
  71. data/spec/internal/config/routes.rb +5 -0
  72. data/spec/internal/db/schema.rb +31 -0
  73. data/spec/internal/log/.gitignore +1 -0
  74. data/spec/internal/public/favicon.ico +0 -0
  75. data/spec/models/eventifier/event_spec.rb +23 -0
  76. data/spec/{ghost_spec.rb → models/eventifier/ghost_spec.rb} +3 -3
  77. data/spec/{notification_spec.rb → models/eventifier/notification_spec.rb} +1 -9
  78. data/spec/notification_mailer_spec.rb +8 -4
  79. data/spec/notifier/notification_mapping_spec.rb +28 -0
  80. data/spec/spec_helper.rb +14 -8
  81. data/spec/support/controller_helpers.rb +14 -0
  82. metadata +205 -128
  83. data/Gemfile.lock +0 -97
  84. data/lib/eventifier/active_record/event.rb +0 -10
  85. data/lib/eventifier/active_record/event_observer.rb +0 -8
  86. data/lib/eventifier/active_record/event_tracking.rb +0 -11
  87. data/lib/eventifier/active_record/ghost.rb +0 -9
  88. data/lib/eventifier/active_record/notification.rb +0 -13
  89. data/lib/eventifier/active_record_support.rb +0 -5
  90. data/lib/eventifier/event_helper.rb +0 -40
  91. data/lib/eventifier/event_mixin.rb +0 -45
  92. data/lib/eventifier/event_observer_mixin.rb +0 -44
  93. data/lib/eventifier/ghost_mixin.rb +0 -27
  94. data/lib/eventifier/helper_methods.rb +0 -36
  95. data/lib/eventifier/mongoid/event.rb +0 -16
  96. data/lib/eventifier/mongoid/event_observer.rb +0 -7
  97. data/lib/eventifier/mongoid/event_tracking.rb +0 -13
  98. data/lib/eventifier/mongoid/ghost.rb +0 -15
  99. data/lib/eventifier/mongoid/notification.rb +0 -19
  100. data/lib/eventifier/mongoid/user_patch.rb +0 -3
  101. data/lib/eventifier/mongoid_support.rb +0 -6
  102. data/lib/eventifier/notification_helper.rb +0 -42
  103. data/lib/eventifier/notification_mailer.rb +0 -18
  104. data/lib/eventifier/notification_mixin.rb +0 -50
  105. data/lib/eventifier/version.rb +0 -3
  106. data/spec/event_helper_spec.rb +0 -67
  107. data/spec/event_observer_spec.rb +0 -20
  108. data/spec/event_spec.rb +0 -39
  109. data/spec/helper_methods_spec.rb +0 -36
  110. data/spec/notification_helper_spec.rb +0 -65
  111. data/spec/support/action_mailer.rb +0 -3
  112. data/spec/support/database_cleaner.rb +0 -3
  113. data/spec/test_classes/active_record_support.rb +0 -72
  114. data/spec/test_classes/mongoid_support.rb +0 -34
@@ -0,0 +1,169 @@
1
+ require 'spec_helper'
2
+
3
+ describe Eventifier::NotificationHelper do
4
+ before do
5
+ I18n.backend.store_translations :en, :notifications => {
6
+ :post => {
7
+ :create => "{{user.name}} just created an Post - you should check it out",
8
+ :destroy => "{{user.name}} just deleted an Post",
9
+ :update => {
10
+ :single => "{{user.name}} made a change to their Post",
11
+ :multiple => "{{user.name}} made some changes to their Post",
12
+ :attributes => {
13
+ :deleted_at => "{{user.name}} deleted their Post"
14
+ }
15
+ }
16
+ }
17
+ }
18
+ end
19
+
20
+ describe "#notification_message" do
21
+ it "should return the I18n message for that event" do
22
+ event = Fabricate(:event, :eventable => Fabricate(:post), :verb => :create)
23
+ helper.notification_message(event).should == "<strong class='user'>#{event.user.name}</strong> just created an Post - you should check it out"
24
+ end
25
+
26
+ it "should return a message specific to a single change if only 1 change has been made" do
27
+ event = Fabricate(:event, :eventable => Fabricate(:post), :verb => :update, :change_data => { :name => ["Fred", "Mike"] })
28
+ helper.notification_message(event).should == "<strong class='user'>#{event.user.name}</strong> made a change to their Post"
29
+ end
30
+ it "should return a message specific to a particular field change if configuration is present" do
31
+ event = Fabricate(:event, :eventable => Fabricate(:post), :verb => :update, :change_data => { :deleted_at => [nil, Time.now] })
32
+ helper.notification_message(event).should == "<strong class='user'>#{event.user.name}</strong> deleted their Post"
33
+ end
34
+
35
+ it "should return a message specific to multiple changes if more than 1 change has been made" do
36
+ event = Fabricate(:event, :eventable => Fabricate(:post), :verb => :update, :change_data => { :name => ["Fred", "Mike"], :age => [55, 65] })
37
+ helper.notification_message(event).should == "<strong class='user'>#{event.user.name}</strong> made some changes to their Post"
38
+ end
39
+
40
+ it "should return the default I18n message if one doesn't exist" do
41
+ I18n.backend.reload!
42
+ @notification_strings = {
43
+ :default => {
44
+ :create => "{{user.name}} created a {{eventable_type}}",
45
+ :update => "{{user.name}} updated a {{eventable_type}}"
46
+ }
47
+ }
48
+ I18n.backend.store_translations :test, :notifications => @notification_strings
49
+ I18n.with_locale("test") do
50
+ event = Fabricate(:event, :eventable => Fabricate(:post), :verb => :create)
51
+ helper.notification_message(event).should == "<strong class='user'>#{event.user.name}</strong> created a <strong>Post</strong>"
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "replacing vars" do
57
+
58
+ class TestClass
59
+ def self.helper_method(*args); end
60
+ include Eventifier::NotificationHelper
61
+ end
62
+
63
+ let!(:helper) { TestClass.new }
64
+
65
+ describe ".replace_vars" do
66
+ let(:event) { Fabricate.build(:event)}
67
+
68
+ it "should replace {{stuff}} with awesome" do
69
+ message = "I'm really loving {{eventable.title}}"
70
+ helper.replace_vars(message, event).should == "I'm really loving <strong>#{event.eventable.title}</strong>"
71
+ end
72
+
73
+ it "should replace multiple {{stuff}} with multiple awesome" do
74
+ message = "I'm really loving {{eventable.title}} and all {{eventable.class.name}}s"
75
+ helper.replace_vars(message, event).should == "I'm really loving <strong>#{event.eventable.title}</strong> and all <strong>Post</strong>s"
76
+ end
77
+ end
78
+
79
+ describe ".load_event_for_template" do
80
+
81
+ it "should add some handy methods to an event instance" do
82
+ event = Fabricate(:event)
83
+ event = helper.load_event_for_template event
84
+ event.object.should == event.eventable
85
+ event.object_type.should == event.eventable_type
86
+ end
87
+
88
+ end
89
+ end
90
+
91
+ describe ".event_message" do
92
+ let(:verb) { "update" }
93
+ let(:change_data) { { } }
94
+ let(:event) { double("Event", :verb => verb, :eventable_type => "Object", :change_data => change_data, :user => double("user", :name => "Willy")) }
95
+ let!(:helper) { TestClass.new }
96
+
97
+ before do
98
+ helper.stub :replace_vars => double("String", :html_safe => true)
99
+ end
100
+
101
+ subject { helper.event_message event }
102
+
103
+ context "with event verb create" do
104
+ let(:verb) { "create" }
105
+
106
+ it "should hit the I18n verb definition for create & destroy" do
107
+ I18n.should_receive(:translate).with("events.object.create", :default => :"events.default.create", "user.name" => "Willy", :"event.type" => "Object")
108
+
109
+ subject
110
+ end
111
+
112
+ it "should pass the I18n translation to the replace_vars method" do
113
+ I18n.should_receive(:translate).with("events.object.create", :default => :"events.default.create", "user.name" => "Willy", :"event.type" => "Object").and_return("A message")
114
+ helper.should_receive(:replace_vars).with "A message", event
115
+
116
+ subject
117
+ end
118
+ end
119
+
120
+ context "with event verb update" do
121
+ let(:verb) { "update" }
122
+
123
+ context "multiple updates" do
124
+ let(:change_data) { { :name => ["Lol", "Omg Lol"] } }
125
+
126
+ it "should specify single on the verb for the I18n definition on update when there are just a single change" do
127
+ I18n.should_receive(:translate).with("events.object.update.single", :default => :"events.default.update", "user.name" => "Willy", :"event.type" => "Object")
128
+
129
+ subject
130
+ end
131
+ end
132
+
133
+ context "multiple updates" do
134
+ let(:change_data) { { :name => ["Lol", "Omg Lol"], :address => ["old", "new"] } }
135
+
136
+ it "should specify single on the verb for the I18n definition on update when there are just a single change" do
137
+ I18n.should_receive(:translate).with("events.object.update.multiple", :default => :"events.default.update", "user.name" => "Willy", :"event.type" => "Object")
138
+
139
+ subject
140
+ end
141
+ end
142
+ end
143
+ end
144
+
145
+ describe "replacing vars" do
146
+ describe ".replace_vars" do
147
+ let(:event) { Fabricate.build(:event)}
148
+
149
+ it "should replace {{stuff}} with awesome" do
150
+ message = "I'm really loving {{eventable.title}}"
151
+ helper.replace_vars(message, event).should == "I'm really loving <strong>#{event.eventable.title}</strong>"
152
+ end
153
+
154
+ it "should replace multiple {{stuff}} with multiple awesome" do
155
+ message = "I'm really loving {{eventable.title}} and all {{eventable.class.name}}s"
156
+ helper.replace_vars(message, event).should == "I'm really loving <strong>#{event.eventable.title}</strong> and all <strong>Post</strong>s"
157
+ end
158
+ end
159
+
160
+ describe ".load_event_for_template" do
161
+ it "should add some handy methods to an event instance" do
162
+ event = Fabricate(:event)
163
+ event = helper.load_event_for_template event
164
+ event.object.should == event.eventable
165
+ event.object_type.should == event.eventable_type
166
+ end
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Eventifier::PathHelper do
4
+ let(:notification) { double(Eventifier::Notification, event: double(Eventifier::Event, eventable_type: 'AwesomeObject')) }
5
+
6
+ describe "partial_path" do
7
+ it "returns an app view path with context in the path" do
8
+ helper.partial_path(notification, :donkey).should == 'eventifier/donkey/notification'
9
+ end
10
+
11
+ it "returns an app view if it's defined" do
12
+ helper.partial_path(notification, :dropdown).should == 'eventifier/dropdown/awesome_object'
13
+ end
14
+
15
+ it "returns the default view if not defined" do
16
+ helper.partial_path(notification).should == 'eventifier/notification'
17
+ end
18
+ end
19
+ end
@@ -1,108 +1,151 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Eventifier do
4
- let(:post) { Fabricate(:post, :author => owner) }
5
- let(:owner) { Fabricate(:user) }
6
- let(:reader1) { Fabricate(:user) }
7
- let(:reader2) { Fabricate(:user) }
8
-
4
+ it "can list tracked classes" do
5
+ Object.new.extend(Eventifier::EventTracking).events_for Post do
6
+ track_on [:create, :update], :attributes => { :except => %w(updated_at) }
7
+ notify :readers, :on => [:create, :update]
8
+ end
9
9
 
10
- let(:event_tracker) { Object.new.extend(Eventifier::EventTracking) }
10
+ Eventifier.tracked_classes.should == [Post]
11
+ end
12
+ end
11
13
 
14
+ describe 'event tracking' do
15
+ let(:owner) { Fabricate(:user) }
16
+ let(:reader1) { Fabricate(:user) }
17
+ let(:reader2) { Fabricate(:user) }
12
18
 
13
19
  before do
14
- Eventifier::NotificationMailer.any_instance.stub main_app: double('app', url_for: true)
15
- post.stub(:readers => [owner, reader1, reader2])
20
+ ActionMailer::Base.deliveries.clear
21
+
22
+ post.readers = [owner, reader1, reader2]
16
23
 
17
- event_tracker.events_for Post do
24
+ Object.new.extend(Eventifier::EventTracking).events_for Post do
18
25
  track_on [:create, :update], :attributes => { :except => %w(updated_at) }
19
26
  notify :readers, :on => [:create, :update]
20
27
  end
21
28
  end
22
29
 
23
30
  context 'a new post' do
24
- let(:post) { Fabricate.build(:post, :author => owner) }
31
+ let(:post) { Fabricate.build(:post, :author => owner) }
32
+ let(:event) {
33
+ Eventifier::Event.where(
34
+ :verb => :create, :user_id => owner.id,
35
+ :eventable_type => 'Post', :eventable_id => post.id
36
+ ).first
37
+ }
38
+
39
+ it "logs an event" do
40
+ post.save
25
41
 
26
- it "notifies only the readers of the post" do
27
- Eventifier::Notification.should_receive(:create).twice do |args|
28
- args[:event].verb.should == :create
29
- [reader1, reader2].should include(args[:user])
30
- end
42
+ event.should be_present
43
+ end
44
+
45
+ it "does not store a notification for the post creator" do
31
46
  post.save
47
+
48
+ Eventifier::Notification.where(
49
+ :event_id => event.id, :user_id => owner.id
50
+ ).count.should == 0
32
51
  end
33
- end
34
52
 
35
- context 'an existing post' do
36
- let(:post) { Fabricate(:post, :author => owner) }
37
- let(:event) { Eventifier::Event.new :eventable => post, :verb => :update,
38
- :user => owner }
39
-
40
- it "notifies the readers of the post" do
41
- Eventifier::Notification.should_receive(:create).twice do |args|
42
- args[:event].verb.should == :update
43
- [reader1, reader2].should include(args[:user])
53
+ it "stores notifications for the reader" do
54
+ post.save
55
+
56
+ [reader1, reader2].each do |reader|
57
+ Eventifier::Notification.where(
58
+ :event_id => event.id, :user_id => reader.id
59
+ ).count.should == 1
44
60
  end
45
- post.update_attribute(:title, 'something else')
46
61
  end
47
62
 
48
- it "should create a notification for readers of a post when it's changed" do
49
- lambda { post.update_attribute(:title, 'somethang') }.should change(reader1.notifications, :count).by(1)
50
- end
51
- end
63
+ it "emails the readers with a notification" do
64
+ post.save
52
65
 
53
- context "helper method" do
66
+ Eventifier::Delivery.deliver
54
67
 
55
- class TestClass
56
- def self.helper_method(*args)
68
+ [reader1, reader2].each do |reader|
69
+ ActionMailer::Base.deliveries.detect { |email|
70
+ email.to == [reader.email] &&
71
+ email.subject == 'You have received notifications'
72
+ }.should be_present
57
73
  end
74
+ end
75
+
76
+ it "stores the post as the groupable object" do
77
+ post.save
58
78
 
59
- include Eventifier::EventHelper
79
+ event.groupable.should == post
60
80
  end
61
81
 
62
- let!(:helper) { TestClass.new }
63
- before do
64
- @event_strings = {
65
- :post => {
66
- :create => "{{user.name}} just created a new post - you should check it out",
67
- :destroy => "{{user.name}} just deleted a post",
68
- :update => {
69
- :single => "{{user.name}} made a change to their post",
70
- :multiple => "{{user.name}} made some changes to their post"
71
- }
72
- }
73
- }
74
- I18n.backend.store_translations :en, :events => @event_strings
82
+ it "deletes the event when the post is destroyed" do
83
+ post.save
84
+ post.destroy
85
+
86
+ Eventifier::Event.count.should be_zero
75
87
  end
76
88
 
77
- it "should return the I18n message for that event" do
78
- event = Fabricate(:event, :eventable => Fabricate(:post), :verb => :create)
79
- helper.event_message(event).should == "<strong class='user'>#{event.user.name}</strong> just created a new post - you should check it out"
89
+ it "deletes notifications belonging to an event" do
90
+ post.save
91
+ post.destroy
92
+
93
+ Eventifier::Notification.count.should be_zero
80
94
  end
95
+ end
81
96
 
82
- it "should return a message specific to a single change if only 1 change has been made" do
83
- event = Fabricate(:event, :eventable => Fabricate(:post), :verb => :update, :change_data => { :name => ["Fred", "Mike"] })
84
- helper.event_message(event).should == "<strong class='user'>#{event.user.name}</strong> made a change to their post"
97
+ context 'an existing post' do
98
+ let(:post) { Fabricate(:post, :author => owner) }
99
+ let(:event) {
100
+ Eventifier::Event.where(
101
+ :verb => :update, :user_id => owner.id,
102
+ :eventable_type => 'Post', :eventable_id => post.id
103
+ ).first
104
+ }
105
+
106
+ it "logs an event" do
107
+ post.update_attribute :title, 'somethang'
108
+
109
+ event.should be_present
85
110
  end
86
111
 
87
- it "should return a message specific to multiple changes if more than 1 change has been made" do
88
- event = Fabricate(:event, :eventable => Fabricate(:post), :verb => :update, :change_data => { :name => ["Fred", "Mike"], :age => [55, 65] })
89
- helper.event_message(event).should == "<strong class='user'>#{event.user.name}</strong> made some changes to their post"
112
+ it "does not store a notification for the post creator" do
113
+ post.update_attribute(:title, 'something else')
114
+
115
+ Eventifier::Notification.where(
116
+ :event_id => event.id, :user_id => owner.id
117
+ ).count.should == 0
90
118
  end
91
119
 
92
- it "should return the default I18n message if one doesn't exist" do
93
- I18n.backend.reload!
94
- @event_strings = {
95
- :default => {
96
- :create => "{{user.name}} created a {{eventable_type}}",
97
- :update => "{{user.name}} updated a {{eventable_type}}"
98
- }
99
- }
100
- I18n.backend.store_translations :test, :events => @event_strings
101
- I18n.with_locale("test") do
102
- event = Fabricate(:event, :eventable => Fabricate(:post), :verb => :create)
103
- helper.event_message(event).should == "<strong class='user'>#{event.user.name}</strong> created a <strong>Post</strong>"
120
+ it "stores notifications for the reader" do
121
+ post.update_attribute(:title, 'something else')
122
+
123
+ [reader1, reader2].each do |reader|
124
+ Eventifier::Notification.where(
125
+ :event_id => event.id, :user_id => reader.id
126
+ ).count.should == 1
127
+ end
128
+ end
129
+
130
+ it "should create a notification for the reader when it's changed" do
131
+ post.update_attribute(:title, 'somethang')
132
+
133
+ [reader1, reader2].each do |reader|
134
+ reader.notifications.count.should == 1
104
135
  end
105
136
  end
106
- end
107
137
 
108
- end
138
+ it "emails the readers with a notification" do
139
+ post.update_attribute(:title, 'somethang')
140
+
141
+ Eventifier::Delivery.deliver
142
+
143
+ [reader1, reader2].each do |reader|
144
+ ActionMailer::Base.deliveries.detect { |email|
145
+ email.to == [reader.email] &&
146
+ email.subject == 'You have received notifications'
147
+ }.should be_present
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Internationalisation" do
4
+ class TestClass
5
+ include Eventifier::NotificationHelper
6
+ end
7
+
8
+ let!(:helper) { TestClass.new }
9
+
10
+ it "should return the I18n message for that event" do
11
+ event = Fabricate(:event, :eventable => Fabricate(:post), :verb => :create)
12
+ helper.event_message(event).should == "<strong class='user'>#{event.user.name}</strong> just created a new post - you should check it out"
13
+ end
14
+
15
+ it "should return a message specific to a single change if only 1 change has been made" do
16
+ event = Fabricate(:event, :eventable => Fabricate(:post), :verb => :update, :change_data => { :name => ["Fred", "Mike"] })
17
+ helper.event_message(event).should == "<strong class='user'>#{event.user.name}</strong> made a change to their post"
18
+ end
19
+
20
+ it "should return a message specific to multiple changes if more than 1 change has been made" do
21
+ event = Fabricate(:event, :eventable => Fabricate(:post), :verb => :update, :change_data => { :name => ["Fred", "Mike"], :age => [55, 65] })
22
+ helper.event_message(event).should == "<strong class='user'>#{event.user.name}</strong> made some changes to their post"
23
+ end
24
+
25
+ it "should return the default I18n message if one doesn't exist" do
26
+ I18n.backend.reload!
27
+ I18n.backend.store_translations :test, :events => {
28
+ :default => {
29
+ :create => "{{user.name}} created a {{eventable_type}}",
30
+ :update => "{{user.name}} updated a {{eventable_type}}"
31
+ }
32
+ }
33
+
34
+ I18n.with_locale("test") do
35
+ event = Fabricate(:event, :eventable => Fabricate(:post), :verb => :create)
36
+ helper.event_message(event).should == "<strong class='user'>#{event.user.name}</strong> created a <strong>Post</strong>"
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationController < ActionController::Base
2
+ #
3
+ end
@@ -0,0 +1,12 @@
1
+ class EventTracking
2
+ include Eventifier::EventTracking
3
+
4
+ def initialize
5
+ # events_for Group do
6
+ # track_on [:create, :update, :destroy], :attributes => { :except => %w(updated_at) }
7
+ # notify :group => :members, :on => [:create, :update]
8
+ # end
9
+ end
10
+ end
11
+
12
+ EventTracking.new
@@ -0,0 +1,3 @@
1
+ class Category < ActiveRecord::Base
2
+ has_many :posts
3
+ end
@@ -0,0 +1,8 @@
1
+ class Post < ActiveRecord::Base
2
+ belongs_to :author, :class_name => "User"
3
+ belongs_to :category
4
+ has_many :subscriptions
5
+ has_many :readers, :through => :subscriptions, :source => :user
6
+
7
+ alias_method :user, :author
8
+ end
@@ -0,0 +1,4 @@
1
+ class Subscription < ActiveRecord::Base
2
+ belongs_to :user
3
+ belongs_to :post
4
+ end
@@ -0,0 +1,4 @@
1
+ class User < ActiveRecord::Base
2
+ has_many :subscriptions
3
+ validates :name, :presence => true, :uniqueness => true
4
+ end
@@ -0,0 +1,4 @@
1
+ test:
2
+ adapter: postgresql
3
+ database: eventifier
4
+ min_messages: warning
@@ -0,0 +1 @@
1
+ Eventifier.mailer_sender = 'me@test.com'
@@ -0,0 +1,20 @@
1
+ en:
2
+ events:
3
+ default:
4
+ create: "{{user.name}} created a <strong>{{object_type}}</strong>"
5
+ update:
6
+ single: "{{user.name}} updated a {{object_type}}"
7
+ multiple: "{{user.name}} made some changes to a {{object_type}}"
8
+ post:
9
+ create: "{{user.name}} just created a new post - you should check it out"
10
+ destroy: "{{user.name}} just deleted a post"
11
+ update:
12
+ single: "{{user.name}} made a change to their post"
13
+ multiple: "{{user.name}} made some changes to their post"
14
+ notifications:
15
+ email_subject: "You have received notifications"
16
+ default:
17
+ create: "{{user.name}} created a <strong>{{object_type}}</strong>"
18
+ update:
19
+ single: "{{user.name}} updated a {{object_type}}"
20
+ multiple: "{{user.name}} made some changes to a {{object_type}}"
@@ -0,0 +1,5 @@
1
+ Rails.application.routes.draw do
2
+ root to: 'application#index'
3
+
4
+ mount Eventifier::Engine => '/'
5
+ end
@@ -0,0 +1,31 @@
1
+ ActiveRecord::Schema.define do
2
+ create_table :categories, :force => true do |t|
3
+ t.string :name
4
+ t.timestamps
5
+ end
6
+
7
+ create_table :ghosts, :force => true do |t|
8
+ t.string :ghost_class
9
+ t.integer :ghost_id
10
+ t.text :data_hash
11
+
12
+ t.timestamps
13
+ end
14
+
15
+ create_table :users, :force => true do |t|
16
+ t.column :name, :string
17
+ t.column :email, :string
18
+ end
19
+
20
+ create_table :posts, :force => true do |t|
21
+ t.column :title, :string
22
+ t.column :author_id, :integer
23
+ t.column :body, :text
24
+ t.column :category_id, :integer
25
+ end
26
+
27
+ create_table :subscriptions, :force => true do |t|
28
+ t.column :user_id, :integer
29
+ t.column :post_id, :integer
30
+ end
31
+ end
@@ -0,0 +1 @@
1
+ *.log
File without changes
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Eventifier::Event do
4
+ let(:event) { Fabricate(:event) }
5
+
6
+ describe "#valid?" do
7
+ it_requires_a :user
8
+ it_requires_an :eventable
9
+ it_requires_a :verb
10
+ end
11
+
12
+ describe ".find_all_by_eventable" do
13
+ let(:eventable) { Fabricate(:user) }
14
+ let(:event) { Fabricate(:event, :eventable => eventable) }
15
+
16
+ it "should find the associated polymorphic eventable object" do
17
+ alpha = Fabricate :event, :eventable => eventable
18
+ beta = Fabricate :event, :eventable => Fabricate(:user)
19
+
20
+ Eventifier::Event.find_all_by_eventable(eventable).should == [alpha]
21
+ end
22
+ end
23
+ end
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Eventifier::Ghost do
4
-
5
4
  it_requires_a :ghost_class
6
5
  it_requires_a :ghost_id
7
6
  it_requires_a :data_hash
@@ -22,9 +21,10 @@ describe Eventifier::Ghost do
22
21
  subject { Fabricate.build(:ghost, :data_hash => post.serializable_hash) }
23
22
 
24
23
  it "should be an object with the attributes of the undeleted object" do
24
+ pending
25
+
25
26
  subject.ghost.class.should == Post
26
27
  subject.ghost.attributes.except("_type").should == post.serializable_hash
27
28
  end
28
29
  end
29
-
30
- end
30
+ end
@@ -4,7 +4,7 @@ describe Eventifier::Notification do
4
4
  let(:notification) { Fabricate(:notification) }
5
5
 
6
6
  before do
7
- Eventifier::NotificationMailer.any_instance.stub main_app: double('app', url_for: true)
7
+ Eventifier::Mailer.any_instance.stub main_app: double('app', url_for: true)
8
8
  end
9
9
 
10
10
  describe '.expire_for_past_events!' do
@@ -47,14 +47,6 @@ describe Eventifier::Notification do
47
47
  end
48
48
  end
49
49
 
50
- describe "#create" do
51
- it "sends an email to the user" do
52
- ActionMailer::Base.deliveries.clear
53
- notification = Fabricate(:notification)
54
- ActionMailer::Base.deliveries.count.should > 0
55
- end
56
- end
57
-
58
50
  describe "#unread_for?" do
59
51
  let(:user) { double(User, :notifications_last_read_at => last_read) }
60
52
  subject { Fabricate.build(:notification, :created_at => Time.now).unread_for?(user) }