eventifier 0.0.1

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 (35) hide show
  1. data/Gemfile +4 -0
  2. data/Gemfile.lock +83 -0
  3. data/README.textile +43 -0
  4. data/Rakefile +13 -0
  5. data/eventifier.gemspec +29 -0
  6. data/lib/eventifier.rb +42 -0
  7. data/lib/eventifier/event.rb +35 -0
  8. data/lib/eventifier/event_helper.rb +40 -0
  9. data/lib/eventifier/event_observer.rb +35 -0
  10. data/lib/eventifier/event_tracking.rb +81 -0
  11. data/lib/eventifier/helper_methods.rb +34 -0
  12. data/lib/eventifier/matchers.rb +34 -0
  13. data/lib/eventifier/notification.rb +40 -0
  14. data/lib/eventifier/notification_helper.rb +51 -0
  15. data/lib/eventifier/notification_mailer.rb +20 -0
  16. data/lib/eventifier/version.rb +3 -0
  17. data/lib/generators/active_record/eventifier_generator.rb +11 -0
  18. data/lib/generators/eventifier/install/install_generator.rb +25 -0
  19. data/lib/generators/eventifier/install/templates/event_tracking.rb +12 -0
  20. data/lib/generators/eventifier/install/templates/events.en.yaml +13 -0
  21. data/lib/generators/eventifier/install/templates/migration.rb +30 -0
  22. data/spec/event_helper_spec.rb +57 -0
  23. data/spec/event_observer_spec.rb +25 -0
  24. data/spec/event_spec.rb +28 -0
  25. data/spec/eventifier_spec.rb +179 -0
  26. data/spec/helper_methods_spec.rb +36 -0
  27. data/spec/integration/eventifier_spec.rb +67 -0
  28. data/spec/notification_helper_spec.rb +58 -0
  29. data/spec/notification_mailer_spec.rb +12 -0
  30. data/spec/notification_spec.rb +83 -0
  31. data/spec/spec_helper.rb +8 -0
  32. data/spec/support/action_mailer.rb +3 -0
  33. data/spec/support/active_record_support.rb +63 -0
  34. data/spec/support/blueprints.rb +24 -0
  35. metadata +170 -0
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Eventifier::EventHelper do
4
+
5
+ class TestClass
6
+ def self.helper_method(*args); end
7
+ include Eventifier::HelperMethods
8
+ end
9
+
10
+ let!(:helper) { TestClass.new }
11
+
12
+ describe ".replace_vars" do
13
+ let(:event) { Eventifier::Event.make }
14
+
15
+ it "should replace {{stuff}} with awesome" do
16
+ message = "I'm really loving {{eventable.title}}"
17
+ helper.replace_vars(message, event).should == "I'm really loving <strong>#{event.eventable.title}</strong>"
18
+ end
19
+
20
+ it "should replace multiple {{stuff}} with multiple awesome" do
21
+ message = "I'm really loving {{eventable.title}} and all {{eventable.class.name}}s"
22
+ helper.replace_vars(message, event).should == "I'm really loving <strong>#{event.eventable.title}</strong> and all <strong>Post</strong>s"
23
+ end
24
+ end
25
+
26
+ describe ".load_event_for_template" do
27
+
28
+ it "should add some handy methods to an event instance" do
29
+ event = Eventifier::Event.make!
30
+ event = helper.load_event_for_template event
31
+ event.object.should == event.eventable
32
+ event.object_type.should == event.eventable_type
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,67 @@
1
+
2
+ describe Eventifier do
3
+ let(:post) { mock_model('Post', :group => group) }
4
+ let(:group) { double('group', :user => owner,
5
+ :members => [owner, member]) }
6
+ let(:owner) { User.make! }
7
+ let(:member) { double('member') }
8
+
9
+ before :each do
10
+ Eventifier::Notification.stub :create => true
11
+ end
12
+
13
+ context 'a new post' do
14
+ let(:event) { Eventifier::Event.new :eventable => post, :verb => :create,
15
+ :user => owner }
16
+
17
+ it "notifies the members of the group" do
18
+ Eventifier::Notification.should_receive(:create).
19
+ with(:user => member, :event => event)
20
+ ActiveRecord::Observer.with_observers(Eventifier::EventObserver) do
21
+ event.save
22
+ end
23
+ end
24
+
25
+ it "does not notify the person initiating the event" do
26
+ Eventifier::Notification.should_not_receive(:create).
27
+ with(:user => owner, :event => event)
28
+
29
+ event.save
30
+ end
31
+ end
32
+
33
+ context 'an existing post' do
34
+ let(:event) { Eventifier::Event.new :eventable => post, :verb => :update,
35
+ :user => owner }
36
+ let(:guest) { double('guest') }
37
+
38
+ before :each do
39
+ post.group.stub :members => [owner, guest]
40
+ end
41
+
42
+ it "notifies the members of the post" do
43
+ Eventifier::Notification.should_receive(:create).
44
+ with(:user => guest, :event => event)
45
+ ActiveRecord::Observer.with_observers(Eventifier::EventObserver) do
46
+ event.save
47
+ end
48
+ end
49
+
50
+ it "does not notify the person initiating the event" do
51
+ Eventifier::Notification.should_not_receive(:create).
52
+ with(:user => owner, :event => event)
53
+
54
+ ActiveRecord::Observer.with_observers(Eventifier::EventObserver) do
55
+ event.save
56
+ end
57
+ end
58
+ end
59
+
60
+ it "should create a notification for users of a post when it's changed" do
61
+ post = event.eventable
62
+ user = User.make!
63
+
64
+ lambda { post.update_attribute :date, 5.days.from_now }.should change(user.notifications, :count).by(1)
65
+ end
66
+
67
+ end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+
3
+ describe Eventifier::NotificationHelper do
4
+
5
+ class TestClass
6
+ def self.helper_method(*args); end
7
+ include Eventifier::NotificationHelper
8
+ end
9
+
10
+ let!(:helper) {TestClass.new}
11
+
12
+ before do
13
+ @notification_strings = {
14
+ :post => {
15
+ :create => "{{user.name}} just created an Post - you should check it out",
16
+ :destroy => "{{user.name}} just deleted an Post",
17
+ :update => {
18
+ :single => "{{user.name}} made a change to their Post",
19
+ :multiple => "{{user.name}} made some changes to their Post"
20
+ }
21
+ }
22
+ }
23
+ I18n.backend.store_translations :en, :notifications => @notification_strings
24
+ end
25
+
26
+ describe ".notification_message" do
27
+ it "should return the I18n message for that event" do
28
+
29
+ event = Eventifier::Event.make! :eventable => Post.make!, :verb => :create
30
+ helper.notification_message(event).should == "<strong>#{event.user.name}</strong> just created an Post - you should check it out"
31
+ end
32
+
33
+ it "should return a message specific to a single change if only 1 change has been made" do
34
+ event = Eventifier::Event.make! :eventable => Post.make!, :verb => :update, :change_data => { :name => ["Fred", "Mike"] }
35
+ helper.notification_message(event).should == "<strong>#{event.user.name}</strong> made a change to their Post"
36
+ end
37
+
38
+ it "should return a message specific to multiple changes if more than 1 change has been made" do
39
+ event = Eventifier::Event.make! :eventable => Post.make!, :verb => :update, :change_data => { :name => ["Fred", "Mike"], :age => [55, 65] }
40
+ helper.notification_message(event).should == "<strong>#{event.user.name}</strong> made some changes to their Post"
41
+ end
42
+
43
+ it "should return the default I18n message if one doesn't exist" do
44
+ I18n.backend.reload!
45
+ @notification_strings = {
46
+ :default => {
47
+ :create => "{{user.name}} created a {{eventable_type}}",
48
+ :update => "{{user.name}} updated a {{eventable_type}}"
49
+ }
50
+ }
51
+ I18n.backend.store_translations :test, :notifications => @notification_strings
52
+ I18n.with_locale("test") do
53
+ event = Eventifier::Event.make! :eventable => Post.make!, :verb => :create
54
+ helper.notification_message(event).should == "<strong>#{event.user.name}</strong> created a <strong>Post</strong>"
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Eventifier::NotificationMailer do
4
+ describe "#notification_email" do
5
+ it "should response to notification emails" do
6
+ Eventifier::NotificationMailer.should respond_to(:notification_email)
7
+ end
8
+ it "should be able to send a 'notification' email" do
9
+ proc { Eventifier::NotificationMailer.notification_email(Eventifier::Notification.make!).deliver }.should change(ActionMailer::Base.deliveries, :count)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe Eventifier::Notification do
4
+ let(:notification) { Eventifier::Notification.make! }
5
+
6
+ describe '.expire_for_past_events!' do
7
+ let(:notification) { double('notification', :expire! => true) }
8
+ let(:expired_event_ids) { [1, 3, 5, 7] }
9
+
10
+ before :each do
11
+ Eventifier::Event.stub :expired_ids => expired_event_ids
12
+ Eventifier::Notification.stub :for_events => [notification]
13
+ end
14
+
15
+ it "finds all notifications belonging to past activities" do
16
+ Eventifier::Notification.should_receive(:for_events).with(expired_event_ids).
17
+ and_return([notification])
18
+
19
+ Eventifier::Notification.expire_for_past_events!
20
+ end
21
+
22
+ it "expires each notification" do
23
+ notification.should_receive(:expire!)
24
+
25
+ Eventifier::Notification.expire_for_past_events!
26
+ end
27
+ end
28
+
29
+ describe ".unread_for" do
30
+ it "should return unread notifications for a user" do
31
+ user = notification.user
32
+
33
+ Eventifier::Notification.unread_for(user).should include notification
34
+ end
35
+
36
+ it "should return unread notifications for a user" do
37
+ user = notification.user
38
+
39
+ user.notifications_last_read_at = Time.now
40
+ second_notification = Eventifier::Notification.make!
41
+
42
+ Eventifier::Notification.unread_for(user).should_not include notification
43
+ Eventifier::Notification.unread_for(user).should_not include second_notification
44
+ end
45
+ end
46
+
47
+ describe "#create" do
48
+ it "sends an email to the user" do
49
+ ActionMailer::Base.deliveries.clear
50
+ notification = Eventifier::Notification.make!
51
+ ActionMailer::Base.deliveries.count.should > 0
52
+ end
53
+ end
54
+
55
+ # describe "#valid?" do
56
+ # it_requires_a :user
57
+ # it_requires_an :event
58
+ # end
59
+
60
+ describe "#unread_for?" do
61
+ let(:user) { double(User, :notifications_last_read_at => last_read) }
62
+ subject { Eventifier::Notification.make(:created_at => Time.now).unread_for?(user) }
63
+ context 'when the user has never read notifications' do
64
+ let(:last_read) { nil }
65
+ it 'should return true' do
66
+ subject.should be_true
67
+ end
68
+ end
69
+ context 'when the user has read notifications before' do
70
+
71
+ describe 'notificication newer than that time' do
72
+ let(:last_read) { Time.now - 1.day }
73
+
74
+ it { should be_true }
75
+ end
76
+ describe 'notificication older than that time' do
77
+ let(:last_read) { Time.now + 1.day }
78
+
79
+ it { should be_false }
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ $LOAD_PATH.unshift File.dirname(__FILE__)
3
+
4
+ Dir["./spec/support/**/*.rb"].each {|f| require f}
5
+
6
+ require 'rubygems'
7
+ require 'rspec'
8
+ require 'eventifier'
@@ -0,0 +1,3 @@
1
+ require 'action_mailer'
2
+
3
+ ActionMailer::Base.delivery_method = :test
@@ -0,0 +1,63 @@
1
+ require 'active_record'
2
+
3
+ ActiveRecord::Base.establish_connection(
4
+ :adapter => "postgresql",
5
+ :database => "eventifier"
6
+ )
7
+
8
+ ActiveRecord::Schema.define(:version => 0) do
9
+
10
+ create_table :events, :force => true do |t|
11
+ t.integer :user_id
12
+ t.string :eventable_type
13
+ t.integer :eventable_id
14
+ t.string :verb
15
+ t.text :change_data
16
+
17
+ t.timestamps
18
+ end
19
+
20
+ create_table :notifications, :force => true do |t|
21
+ t.integer :event_id
22
+ t.integer :user_id
23
+ t.integer :parent_id
24
+
25
+ t.timestamps
26
+ end
27
+
28
+ create_table :users, :force => true do |t|
29
+ t.column :name, :string
30
+ t.column :email, :string
31
+ t.column :notifications_last_read_at, :datetime
32
+ end
33
+
34
+ create_table :posts, :force => true do |t|
35
+ t.column :title, :string
36
+ t.column :author_id, :integer
37
+ t.column :body, :text
38
+ end
39
+
40
+ create_table :subscriptions, :force => true do |t|
41
+ t.column :user_id, :integer
42
+ t.column :post_id, :integer
43
+ end
44
+
45
+ end
46
+
47
+ class User < ActiveRecord::Base
48
+ has_many :subscriptions
49
+ validates :name, :presence => true, :uniqueness => true
50
+ end
51
+
52
+ class Subscription < ActiveRecord::Base
53
+ belongs_to :user
54
+ belongs_to :post
55
+ end
56
+
57
+ class Post < ActiveRecord::Base
58
+ belongs_to :author, :class_name => "User"
59
+ has_many :subscriptions
60
+ has_many :readers, :through => :subscriptions, :source => :user
61
+
62
+ alias_method :user, :author
63
+ end
@@ -0,0 +1,24 @@
1
+ require 'machinist/active_record'
2
+ require 'eventifier'
3
+
4
+ Eventifier::Event.blueprint do
5
+ user { object.user || User.make! }
6
+ eventable { object.eventable || Post.make! }
7
+ verb { :update }
8
+ change_data { { :date => [ 5.days.ago, 3.days.ago ] } }
9
+ end
10
+
11
+ Eventifier::Notification.blueprint do
12
+ event { object.event || Eventifier::Event.make! }
13
+ user { object.user || User.make! }
14
+ end
15
+
16
+ Post.blueprint do
17
+ title { "My amazing blog post" }
18
+ body { "A deep and profound analysis of life" }
19
+ end
20
+
21
+ User.blueprint do
22
+ name { "Billy #{sn}" }
23
+ email { "billy#{sn}@email.com" }
24
+ end
metadata ADDED
@@ -0,0 +1,170 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eventifier
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nathan Sampimon
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: &70095162476700 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70095162476700
25
+ - !ruby/object:Gem::Dependency
26
+ name: actionmailer
27
+ requirement: &70095162475660 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70095162475660
36
+ - !ruby/object:Gem::Dependency
37
+ name: machinist
38
+ requirement: &70095162474080 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70095162474080
47
+ - !ruby/object:Gem::Dependency
48
+ name: pg
49
+ requirement: &70095162472540 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70095162472540
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: &70095162470940 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70095162470940
69
+ - !ruby/object:Gem::Dependency
70
+ name: activerecord
71
+ requirement: &70095162470020 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: *70095162470020
80
+ - !ruby/object:Gem::Dependency
81
+ name: actionmailer
82
+ requirement: &70095162469140 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :runtime
89
+ prerelease: false
90
+ version_requirements: *70095162469140
91
+ description: Tracks and logs events and sends notifications of events on Active Record
92
+ models.
93
+ email:
94
+ - nathan@inspire9.com
95
+ executables: []
96
+ extensions: []
97
+ extra_rdoc_files: []
98
+ files:
99
+ - Gemfile
100
+ - Gemfile.lock
101
+ - README.textile
102
+ - Rakefile
103
+ - eventifier.gemspec
104
+ - lib/eventifier.rb
105
+ - lib/eventifier/event.rb
106
+ - lib/eventifier/event_helper.rb
107
+ - lib/eventifier/event_observer.rb
108
+ - lib/eventifier/event_tracking.rb
109
+ - lib/eventifier/helper_methods.rb
110
+ - lib/eventifier/matchers.rb
111
+ - lib/eventifier/notification.rb
112
+ - lib/eventifier/notification_helper.rb
113
+ - lib/eventifier/notification_mailer.rb
114
+ - lib/eventifier/version.rb
115
+ - lib/generators/active_record/eventifier_generator.rb
116
+ - lib/generators/eventifier/install/install_generator.rb
117
+ - lib/generators/eventifier/install/templates/event_tracking.rb
118
+ - lib/generators/eventifier/install/templates/events.en.yaml
119
+ - lib/generators/eventifier/install/templates/migration.rb
120
+ - spec/event_helper_spec.rb
121
+ - spec/event_observer_spec.rb
122
+ - spec/event_spec.rb
123
+ - spec/eventifier_spec.rb
124
+ - spec/helper_methods_spec.rb
125
+ - spec/integration/eventifier_spec.rb
126
+ - spec/notification_helper_spec.rb
127
+ - spec/notification_mailer_spec.rb
128
+ - spec/notification_spec.rb
129
+ - spec/spec_helper.rb
130
+ - spec/support/action_mailer.rb
131
+ - spec/support/active_record_support.rb
132
+ - spec/support/blueprints.rb
133
+ homepage: http://github.com/inspire9/eventifier
134
+ licenses: []
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ! '>='
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ none: false
147
+ requirements:
148
+ - - ! '>='
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ requirements: []
152
+ rubyforge_project: eventifier
153
+ rubygems_version: 1.8.11
154
+ signing_key:
155
+ specification_version: 3
156
+ summary: Event tracking and notifying for active record models
157
+ test_files:
158
+ - spec/event_helper_spec.rb
159
+ - spec/event_observer_spec.rb
160
+ - spec/event_spec.rb
161
+ - spec/eventifier_spec.rb
162
+ - spec/helper_methods_spec.rb
163
+ - spec/integration/eventifier_spec.rb
164
+ - spec/notification_helper_spec.rb
165
+ - spec/notification_mailer_spec.rb
166
+ - spec/notification_spec.rb
167
+ - spec/spec_helper.rb
168
+ - spec/support/action_mailer.rb
169
+ - spec/support/active_record_support.rb
170
+ - spec/support/blueprints.rb