social_feed 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/INSTALL +22 -0
- data/MIT-LICENSE +20 -0
- data/README +96 -0
- data/Rakefile +24 -0
- data/VERSION +1 -0
- data/generators/feed_event/feed_event_generator.rb +19 -0
- data/generators/feed_event/templates/event_hint.html.erb +4 -0
- data/generators/feed_event/templates/event_model.rb.erb +5 -0
- data/generators/social_feed_migration/social_feed_migration_generator.rb +13 -0
- data/generators/social_feed_migration/templates/migration.rb +24 -0
- data/init.rb +10 -0
- data/install.rb +35 -0
- data/lib/feed_event.rb +81 -0
- data/lib/feed_event_mailer.rb.template +6 -0
- data/lib/feed_events_controller.rb.template +6 -0
- data/lib/object_extensions.rb +27 -0
- data/lib/social_feed/feed_event_mailer_extension.rb +14 -0
- data/lib/social_feed/feed_events_controller_extension.rb +48 -0
- data/lib/social_feed/routing.rb +15 -0
- data/lib/social_feed/social_feed_helper.rb +7 -0
- data/lib/social_feed/user_extension.rb +59 -0
- data/routes.rb +2 -0
- data/social_feed.yml +1 -0
- data/spec/controllers/feed_events_controller_spec.rb +103 -0
- data/spec/helpers/social_feed_helper_spec.rb +17 -0
- data/spec/models/feed_event_spec.rb +202 -0
- data/spec/models/user_spec.rb +148 -0
- data/spec/spec_helper.rb +86 -0
- data/views/_user_feed.html.erb +12 -0
- data/views/destroy.rjs +1 -0
- data/views/index.html.erb +2 -0
- data/views/settings.html.erb +36 -0
- metadata +92 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.sqlite3
|
data/INSTALL
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Plugin setup
|
2
|
+
|
3
|
+
* to create the necessary migration run:
|
4
|
+
|
5
|
+
script/generate social_feed_migration
|
6
|
+
rake db:migrate
|
7
|
+
|
8
|
+
* add the following line to the top of your config/routes.rb:
|
9
|
+
|
10
|
+
map.from_plugin 'social_feed'
|
11
|
+
|
12
|
+
* add the following line to the Rails::Initializer block in your environment.rb
|
13
|
+
|
14
|
+
config.load_paths << RAILS_ROOT + '/app/models/events'
|
15
|
+
|
16
|
+
* add the following line to your User class
|
17
|
+
|
18
|
+
include SocialFeed::UserExtension
|
19
|
+
|
20
|
+
* make sure you have the prototype javascript library loaded in your views, e.g. with the following line in your views/layouts/application.html.erb
|
21
|
+
|
22
|
+
<%= javascript_include_tag :defaults %>
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 [name of plugin creator]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
SocialFeed
|
2
|
+
==========
|
3
|
+
|
4
|
+
This plugin adds a social feed to your rails application. Users can decide what kinds of events they want to see on their social feed and also wether they want to be sent an email when an event occurs. They can also decide wether others will receive a notification on their social feed concerning their own actions.
|
5
|
+
|
6
|
+
How it works
|
7
|
+
============
|
8
|
+
|
9
|
+
The plugins adds the following things to your application
|
10
|
+
* a FeedEvent model - this represents an event on the social feed - you will subclass the SocialFeed to create your own custom events
|
11
|
+
* a SocialFeedsController - this controller has actions for:
|
12
|
+
* displaying the social feed for a user (index)
|
13
|
+
* destroying a SocialFeed
|
14
|
+
* displaying a settings page where users can
|
15
|
+
* subscribe to and unsubscribe from events
|
16
|
+
* subscirbe to and unsubscribe from receiving emails for events
|
17
|
+
* enable/disable the creation of events concerning their own actions in the application
|
18
|
+
* a migration that adds 3 fields to your users table to store the event subscriptions
|
19
|
+
|
20
|
+
|
21
|
+
Installation
|
22
|
+
============
|
23
|
+
|
24
|
+
If you are on rails >= 2.1 (which supports git) you can simply do a
|
25
|
+
script/plugin install git://github.com/langalex/social_feed.git
|
26
|
+
|
27
|
+
If not you need to do this from your rails root:
|
28
|
+
|
29
|
+
cd vendor/plugins
|
30
|
+
git clone git://github.com/langalex/social_feed.git --depth 1
|
31
|
+
cd social_feed
|
32
|
+
ruby install.rb
|
33
|
+
cd ../../..
|
34
|
+
|
35
|
+
for the rest see the INSTALL file
|
36
|
+
|
37
|
+
Assumptions
|
38
|
+
===========
|
39
|
+
|
40
|
+
the socialfeed plugin assumes that:
|
41
|
+
|
42
|
+
* your users are represented via the User model
|
43
|
+
* your users have an email attribute (used by the feed event mailer)
|
44
|
+
* the controllers in your application have access to the currently logged in user via the current_user method
|
45
|
+
|
46
|
+
Basic User Experience
|
47
|
+
=====================
|
48
|
+
|
49
|
+
After the plugin is installed you can direct your users to the /feed_events url which will show them their personal social feed. To customize their events the users should go to /feed_events/settings
|
50
|
+
|
51
|
+
How to create custom events types
|
52
|
+
=================================
|
53
|
+
|
54
|
+
To create a custom event you should use the built-in feed_event generator:
|
55
|
+
|
56
|
+
e.g.: script/generate feed_event new_friend
|
57
|
+
|
58
|
+
This creates a new class NewFriendEvent in the app/models/events directory (the class representing the event) as well as a new_friend_hint.html.erb file in the app/views/feed_events directory (this gets rendered on people's social feed page). First thing you probably want to do is to customize the hint file.
|
59
|
+
|
60
|
+
Secondly you should also customize the two description lines in the model, which will be used on the setting page. By commenting out either line, you can remove the corresponding line from the setings page.
|
61
|
+
|
62
|
+
If you want your users to be able to receive emails for your new event, add a method deliver_new_friend(event) to the FeedEventMailer found in app/models/feed_events. You can call the convenience method create_event_message(subject, event) to send your mails. After adding the method a checkbox for this event will automatically appear on the settings page.
|
63
|
+
|
64
|
+
Creating actual events
|
65
|
+
======================
|
66
|
+
|
67
|
+
In order for the social feeds of your users to get filled with events you have to create instances of your custom event classes. You have a number of choices here. I would recommend to use the rails observers, so for a NewFriendEvent you would probably create a FriendShipObserver with an after_create hook that creates the event after a new friendship has been created. As soon as you start creating lots of events for a single action (e.g. tell every user that user X and user Y are now friends) I would highly recommend using something asynchronous like the workling plugin and starling.
|
68
|
+
|
69
|
+
An event requires two attributes, a user and a source. The user is the user who sees the event on her social feed, the source is the object that sort of caused the event, which in this example would be the friendship, e.g.
|
70
|
+
|
71
|
+
NewFriendEvent.create :user => some_user_interested_in_the_event, :source => new_friendship
|
72
|
+
|
73
|
+
If you want the enable/disable event feature to work (a.k.a. privacy settings), the source must implement a user method which returns the user who caused the event. That user's privacy settings are then check before creating the actual FeedEvent instance.
|
74
|
+
|
75
|
+
Warning: Do not create events using create! but use the create method (without the bang) - when a user has not subscribed to an event, a validation in the FeedEvent class will fail so that the event won't be created. If you use the create! method you will get an exception instead.
|
76
|
+
|
77
|
+
Configuration
|
78
|
+
=============
|
79
|
+
|
80
|
+
You can setup the from address used by the FeedEventMailers create_event_message method in the social_feed.yml in your config folder.
|
81
|
+
|
82
|
+
Gotchas
|
83
|
+
=======
|
84
|
+
|
85
|
+
For all models of you application you use as a source for a FeedEvent, add a
|
86
|
+
:has_many :feed_events, :dependent => :destroy
|
87
|
+
so that the feed events are destroyed when objects are destroyed. Otherwise the social feeds of you users will get into trouble with sources of events missing.
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
Contact
|
92
|
+
=======
|
93
|
+
|
94
|
+
Copyright (c) 2008 Alexander Lang, released under the MIT license
|
95
|
+
|
96
|
+
Contact: email: alex[at]upstream-berlin.com, twitter: langalex, blog: http://upstream-berlin.com/blog, skype: langalex
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'spec/rake/spectask'
|
3
|
+
|
4
|
+
desc 'Default: run specs.'
|
5
|
+
task :default => :spec
|
6
|
+
|
7
|
+
desc "Run all specs"
|
8
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
9
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
10
|
+
end
|
11
|
+
|
12
|
+
begin
|
13
|
+
require 'jeweler'
|
14
|
+
Jeweler::Tasks.new do |gemspec|
|
15
|
+
gemspec.name = "social_feed"
|
16
|
+
gemspec.summary = "a ruby on rails plugin to create and display a social feed"
|
17
|
+
gemspec.email = "alex@upstream-berlin.com"
|
18
|
+
gemspec.homepage = "http://github.com/langalex/social_feed"
|
19
|
+
gemspec.description = ""
|
20
|
+
gemspec.authors = ["Alexander Lang", "Thilo Utke"]
|
21
|
+
end
|
22
|
+
rescue LoadError
|
23
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
24
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class FeedEventGenerator < Rails::Generator::Base
|
2
|
+
|
3
|
+
attr_accessor :event_name
|
4
|
+
|
5
|
+
def initialize(runtime_args, runtime_options = {})
|
6
|
+
super
|
7
|
+
self.event_name = runtime_args[0]
|
8
|
+
raise "Usage: script/generate feed_event <event_name>\ne.g. script/generate feed_event user_signed_up\n" unless event_name
|
9
|
+
end
|
10
|
+
|
11
|
+
def manifest
|
12
|
+
record do |r|
|
13
|
+
r.template 'event_model.rb.erb', "app/models/events/#{event_name.underscore}_event.rb"
|
14
|
+
r.template 'event_hint.html.erb', "app/views/feed_events/_#{event_name.underscore}_hint.html.erb"
|
15
|
+
# email template and mailer method
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class AddSocialFeed < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :users, :feed_event_subscriptions, :text
|
4
|
+
add_column :users, :email_subscriptions, :text
|
5
|
+
add_column :users, :enabled_feed_events, :text
|
6
|
+
|
7
|
+
create_table :feed_events do |t|
|
8
|
+
t.column :type, :string
|
9
|
+
t.column :user_id, :integer
|
10
|
+
t.column :created_at, :datetime
|
11
|
+
t.column :source_id, :integer
|
12
|
+
t.column :source_type, :string
|
13
|
+
t.column :hint_body, :text
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.down
|
18
|
+
remove_column :users, :feed_event_subscriptions
|
19
|
+
remove_column :users, :email_subscriptions
|
20
|
+
remove_column :users, :enabled_feed_events
|
21
|
+
|
22
|
+
drop_table :feed_events
|
23
|
+
end
|
24
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'object_extensions'
|
2
|
+
|
3
|
+
# configuration
|
4
|
+
require 'ostruct'
|
5
|
+
SocialFeed::Conf = OpenStruct.new YAML::load(File.read(RAILS_ROOT + '/config/social_feed.yml'))
|
6
|
+
|
7
|
+
|
8
|
+
ActionController::Base.helper(SocialFeed::SocialFeedHelper)
|
9
|
+
|
10
|
+
ActionController::Routing::RouteSet::Mapper.send(:include, SocialFeed::Routing)
|
data/install.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
__DIR__ = File.dirname(__FILE__)
|
4
|
+
RAILS_ROOT = __DIR__ + '/../../..'
|
5
|
+
|
6
|
+
# generate migration
|
7
|
+
# done by user
|
8
|
+
|
9
|
+
# add events directory to load path
|
10
|
+
# done by user
|
11
|
+
|
12
|
+
# create events directory
|
13
|
+
FileUtils.mkdir RAILS_ROOT + '/app/models/events'
|
14
|
+
|
15
|
+
# copy mailer template
|
16
|
+
FileUtils.cp __DIR__ + '/lib/feed_event_mailer.rb.template', RAILS_ROOT + '/app/models/feed_event_mailer.rb'
|
17
|
+
|
18
|
+
# create mailer views directory
|
19
|
+
FileUtils.mkdir RAILS_ROOT + '/app/views/feed_event_mailer'
|
20
|
+
|
21
|
+
# copy controller views, partials
|
22
|
+
FileUtils.mkdir RAILS_ROOT + '/app/views/feed_events'
|
23
|
+
FileUtils.cp __DIR__ + '/lib/feed_events_controller.rb.template', RAILS_ROOT + '/app/controllers/feed_events_controller.rb'
|
24
|
+
FileUtils.cp __DIR__ + '/views/index.html.erb', RAILS_ROOT + '/app/views/feed_events'
|
25
|
+
FileUtils.cp __DIR__ + '/views/settings.html.erb', RAILS_ROOT + '/app/views/feed_events'
|
26
|
+
FileUtils.cp __DIR__ + '/views/destroy.rjs', RAILS_ROOT + '/app/views/feed_events'
|
27
|
+
FileUtils.cp __DIR__ + '/views/_user_feed.html.erb', RAILS_ROOT + '/app/views/feed_events'
|
28
|
+
|
29
|
+
# copy config file
|
30
|
+
FileUtils.cp __DIR__ + '/social_feed.yml', RAILS_ROOT + '/config'
|
31
|
+
|
32
|
+
# add routes
|
33
|
+
# done by user
|
34
|
+
|
35
|
+
puts File.read(__DIR__ + '/INSTALL')
|
data/lib/feed_event.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
class FeedEvent < ActiveRecord::Base
|
2
|
+
def before_validation_on_create
|
3
|
+
send_email
|
4
|
+
end
|
5
|
+
|
6
|
+
belongs_to :source, :polymorphic => true
|
7
|
+
validates_presence_of :user_id #receiver
|
8
|
+
validate :source_user_has_event_enabled
|
9
|
+
validate :user_has_subscribed_to_event
|
10
|
+
|
11
|
+
@@event_types = []
|
12
|
+
|
13
|
+
belongs_to :user
|
14
|
+
|
15
|
+
def allowed_to_destroy?(_user_id)
|
16
|
+
(user_id == _user_id)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.event_types
|
20
|
+
load_subclasses if @@event_types.empty?
|
21
|
+
@@event_types
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.subscribable_feed_event_types
|
25
|
+
event_types.reject{|type| type.user_cannot_subscribe_to_event?}
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.enabable_feed_event_types
|
29
|
+
event_types.select{|type| type.user_can_enable_event?}
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.subscribe_description(desc = nil)
|
33
|
+
@@subscribe_descriptions ||= {}
|
34
|
+
@@subscribe_descriptions[name] = desc if desc
|
35
|
+
@@subscribe_descriptions[name]
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.privacy_description(desc = nil)
|
39
|
+
@@privacy_descriptions ||= {}
|
40
|
+
@@privacy_descriptions[name] = desc if desc
|
41
|
+
@@privacy_descriptions[name]
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.can_send_email?
|
45
|
+
FeedEventMailer.send(:new).respond_to?(name.underscore[0..-7])
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.user_cannot_subscribe_to_event?
|
49
|
+
subscribe_description.blank?
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.user_can_enable_event?
|
53
|
+
privacy_description
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def source_disabled_event?
|
59
|
+
self.class.user_can_enable_event? && source.respond_to?(:user) && source.user && !source.user.feed_event_enabled?(self.class)
|
60
|
+
end
|
61
|
+
def send_email
|
62
|
+
FeedEventMailer.send "deliver_#{self.class.name.underscore[0..-7]}", self if self.class.can_send_email? &&
|
63
|
+
(user.subscribed_to_email?(self.class) || self.class.user_cannot_subscribe_to_event?) && !user.try(:online?) && !source_disabled_event?
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.load_subclasses
|
67
|
+
Dir[RAILS_ROOT+'/app/models/events/*_event.rb'].each do |file|
|
68
|
+
@@event_types << File.basename(file, '.rb').camelize.constantize
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def user_has_subscribed_to_event
|
73
|
+
errors.add :user, "has not subscribed to event #{self.class}" unless user.if_not_nil?{|u| u.subscribed_to_feed_event?(self.class)} ||
|
74
|
+
self.class.user_cannot_subscribe_to_event?
|
75
|
+
end
|
76
|
+
|
77
|
+
def source_user_has_event_enabled
|
78
|
+
errors.add :source, "this event is disabled by the user of #{self.source.class}" if source_disabled_event?
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Object
|
2
|
+
def try(method, *params)
|
3
|
+
send method, *params if respond_to? method
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
class Object
|
8
|
+
def if_nil?
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def if_not_nil?
|
13
|
+
yield self
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class NilClass
|
18
|
+
def if_nil?
|
19
|
+
yield self
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def if_not_nil?
|
24
|
+
self
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module SocialFeed
|
2
|
+
module FeedEventMailerExtension
|
3
|
+
|
4
|
+
private
|
5
|
+
def create_event_message(subject, event)
|
6
|
+
@subject = subject
|
7
|
+
@body = {:event => event}
|
8
|
+
@recipients = event.user.email
|
9
|
+
@from = SocialFeed::Conf.sender_email
|
10
|
+
@sent_on = Time.now
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module SocialFeed
|
2
|
+
module FeedEventsControllerExtension
|
3
|
+
|
4
|
+
def destroy
|
5
|
+
@event = current_user.feed_events.find params[:id]
|
6
|
+
@event.destroy
|
7
|
+
end
|
8
|
+
|
9
|
+
def index
|
10
|
+
@feed_events = current_user.feed_events.find :all, :limit => 20, :order => 'created_at DESC'
|
11
|
+
end
|
12
|
+
|
13
|
+
def settings
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
def toggle_subscription
|
18
|
+
if current_user.subscribed_to_feed_event?(params[:event])
|
19
|
+
current_user.unsubscribe_from_feed_event(params[:event])
|
20
|
+
else
|
21
|
+
current_user.subscribe_to_feed_event(params[:event])
|
22
|
+
end
|
23
|
+
current_user.save
|
24
|
+
render :nothing => true
|
25
|
+
end
|
26
|
+
|
27
|
+
def toggle_email_subscription
|
28
|
+
if current_user.subscribed_to_email?(params[:event])
|
29
|
+
current_user.unsubscribe_from_email(params[:event])
|
30
|
+
else
|
31
|
+
current_user.subscribe_to_email(params[:event])
|
32
|
+
end
|
33
|
+
current_user.save
|
34
|
+
render :nothing => true
|
35
|
+
end
|
36
|
+
|
37
|
+
def toggle_enabled
|
38
|
+
if current_user.feed_event_enabled? params[:event]
|
39
|
+
current_user.disable_feed_event params[:event]
|
40
|
+
else
|
41
|
+
current_user.enable_feed_event params[:event]
|
42
|
+
end
|
43
|
+
current_user.save
|
44
|
+
render :nothing => true
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module SocialFeed
|
2
|
+
module Routing
|
3
|
+
def from_plugin(name)
|
4
|
+
plugin_root = File.join(RAILS_ROOT,
|
5
|
+
'vendor',
|
6
|
+
'plugins')
|
7
|
+
routes_path = File.join(plugin_root,
|
8
|
+
name.to_s,
|
9
|
+
'routes.rb')
|
10
|
+
if File.file?(routes_path)
|
11
|
+
eval(IO.read(routes_path), binding, routes_path)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module SocialFeed
|
2
|
+
module UserExtension
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
serialize :feed_event_subscriptions
|
7
|
+
serialize :email_subscriptions
|
8
|
+
serialize :enabled_feed_events
|
9
|
+
|
10
|
+
has_many :feed_events, :dependent => :destroy, :order => "id DESC"
|
11
|
+
has_many :feed_events_as_source, :dependent => :destroy, :as => :source, :class_name => 'FeedEvent'
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
def subscribe_to_feed_event(event_class)
|
17
|
+
self.feed_event_subscriptions ||= []
|
18
|
+
self.feed_event_subscriptions |= [event_class.to_s]
|
19
|
+
end
|
20
|
+
|
21
|
+
def subscribed_to_feed_event?(event_class)
|
22
|
+
self.feed_event_subscriptions.if_not_nil?{|s| s.include?(event_class.to_s)}
|
23
|
+
end
|
24
|
+
|
25
|
+
def unsubscribe_from_feed_event(event_class)
|
26
|
+
self.feed_event_subscriptions_will_change!
|
27
|
+
self.feed_event_subscriptions.delete event_class.to_s
|
28
|
+
end
|
29
|
+
|
30
|
+
def subscribe_to_email(event_class)
|
31
|
+
self.email_subscriptions ||= []
|
32
|
+
self.email_subscriptions |= [event_class.to_s]
|
33
|
+
end
|
34
|
+
|
35
|
+
def subscribed_to_email?(event_class)
|
36
|
+
self.email_subscriptions.if_not_nil?{|s| s.include?(event_class.to_s)}
|
37
|
+
end
|
38
|
+
|
39
|
+
def unsubscribe_from_email(event_class)
|
40
|
+
self.email_subscriptions_will_change!
|
41
|
+
self.email_subscriptions.delete event_class.to_s
|
42
|
+
end
|
43
|
+
|
44
|
+
def enable_feed_event(event_class)
|
45
|
+
self.enabled_feed_events ||= []
|
46
|
+
self.enabled_feed_events |= [event_class.to_s]
|
47
|
+
end
|
48
|
+
|
49
|
+
def disable_feed_event(event_class)
|
50
|
+
self.enabled_feed_events_will_change!
|
51
|
+
self.enabled_feed_events.delete event_class.to_s
|
52
|
+
end
|
53
|
+
|
54
|
+
def feed_event_enabled?(event_class)
|
55
|
+
self.enabled_feed_events.if_not_nil?{|e| e.include? event_class.to_s}
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
data/routes.rb
ADDED
data/social_feed.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
sender_email: "<no-reply@mydomain.com>"
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require PLUGIN_ROOT + '/lib/social_feed/feed_events_controller_extension'
|
3
|
+
|
4
|
+
class FeedEventsController
|
5
|
+
attr_accessor :params
|
6
|
+
include SocialFeed::FeedEventsControllerExtension
|
7
|
+
|
8
|
+
def render(options); end
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
describe FeedEventsController do
|
13
|
+
|
14
|
+
before(:each) do
|
15
|
+
@controller = FeedEventsController.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def set_current_user(user)
|
19
|
+
@controller.stub!(:current_user).and_return(user)
|
20
|
+
end
|
21
|
+
|
22
|
+
def post(method, options)
|
23
|
+
@controller.params = options
|
24
|
+
@controller.send method
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
describe FeedEventsController, 'toggle enabled feed events' do
|
29
|
+
before(:each) do
|
30
|
+
@user = stub 'user', :feed_event_enabled? => false, :enable_feed_event => true, :save => true
|
31
|
+
set_current_user @user
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should enable the event" do
|
35
|
+
@user.should_receive(:enable_feed_event).with('TestEvent')
|
36
|
+
post :toggle_enabled, :event => 'TestEvent'
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should disable an enabled event" do
|
40
|
+
@user.stub!(:feed_event_enabled?).with('TestEvent').and_return(true)
|
41
|
+
@user.should_receive(:disable_feed_event).with('TestEvent')
|
42
|
+
post :toggle_enabled, :event => 'TestEvent'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should save the user" do
|
46
|
+
@user.should_receive(:save)
|
47
|
+
post :toggle_enabled, :event => 'TestEvent'
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
describe FeedEventsController, 'toggle subscribe to feed event' do
|
53
|
+
before(:each) do
|
54
|
+
@user = stub 'user', :subscribed_to_feed_event? => true, :unsubscribe_from_feed_event => false, :save => true
|
55
|
+
set_current_user @user
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should subscribe on the event" do
|
59
|
+
@user.stub!(:subscribed_to_feed_event?).with('TestEvent').and_return(false)
|
60
|
+
@user.should_receive(:subscribe_to_feed_event).with('TestEvent')
|
61
|
+
post :toggle_subscription, :event => 'TestEvent'
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should unsubscribe from a subscribed event" do
|
65
|
+
@user.stub!(:subscribed_to_feed_event?).with('TestEvent').and_return(true)
|
66
|
+
@user.should_receive(:unsubscribe_from_feed_event).with('TestEvent')
|
67
|
+
post :toggle_subscription, :event => 'TestEvent'
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should save the user" do
|
71
|
+
@user.should_receive(:save)
|
72
|
+
post :toggle_subscription, :event => 'TestEvent'
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
describe FeedEventsController, 'toggle subscribe to email event' do
|
78
|
+
before(:each) do
|
79
|
+
@user = stub 'user', :subscribed_to_email? => true, :unsubscribe_from_email => nil, :save => true
|
80
|
+
set_current_user @user
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
it "should subscribe on the event" do
|
85
|
+
@user.stub!(:subscribed_to_email?).with('TestEvent').and_return(false)
|
86
|
+
@user.should_receive(:subscribe_to_email).with('TestEvent')
|
87
|
+
post :toggle_email_subscription, :event => 'TestEvent'
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should unsubscribe from a subscribed event" do
|
91
|
+
@user.stub!(:subscribed_to_email?).with('TestEvent').and_return(true)
|
92
|
+
@user.should_receive(:unsubscribe_from_email).with('TestEvent')
|
93
|
+
post :toggle_email_subscription, :event => 'TestEvent'
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should save the user" do
|
97
|
+
@user.should_receive(:save)
|
98
|
+
post :toggle_email_subscription, :event => 'TestEvent'
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require PLUGIN_ROOT + '/lib/social_feed/social_feed_helper'
|
3
|
+
include SocialFeed::SocialFeedHelper
|
4
|
+
class TestEvent; end
|
5
|
+
class TestEventCreatedEvent; end
|
6
|
+
|
7
|
+
describe SocialFeed::SocialFeedHelper do
|
8
|
+
|
9
|
+
it "should derive the hint partial from the feed class" do
|
10
|
+
feed_event_partial_name(TestEvent.new).should == 'test_hint'
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should only replace event with hint at the end" do
|
14
|
+
feed_event_partial_name(TestEventCreatedEvent.new).should == 'test_event_created_hint'
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,202 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require PLUGIN_ROOT + '/lib/feed_event'
|
3
|
+
|
4
|
+
describe FeedEvent, 'send emails' do
|
5
|
+
class TestFeedEvent < FeedEvent; end
|
6
|
+
|
7
|
+
it "should send no email if mailer does not support it" do
|
8
|
+
user = mock_model(User, :subscribed_to_feed_event? => true)
|
9
|
+
event = TestFeedEvent.new :source => user, :user => user
|
10
|
+
FeedEventMailer.should_receive(:deliver_test_feed_event).never
|
11
|
+
event.save!
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should derive mailer method from class name" do
|
15
|
+
FeedEventMailer.stub!(:send).with(:new).and_return(stub('mailer', :test_feed => true))
|
16
|
+
user = mock_model User, :subscribed_to_feed_event? => true, :subscribed_to_email? => true, :online? => false
|
17
|
+
event = TestFeedEvent.new :source => user, :user => user
|
18
|
+
FeedEventMailer.should_receive(:send).with('deliver_test_feed', event)
|
19
|
+
event.save!
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should not be able to send mail if mailer has no mailer method" do
|
23
|
+
TestFeedEvent.can_send_email?.should be_false
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should be able to send mail if mailer has mailer method" do
|
27
|
+
FeedEventMailer.stub!(:new).and_return(nil) # actionmailer.new really returns nil, you have to use send(:new)
|
28
|
+
FeedEventMailer.stub!(:send).with(:new).and_return(stub('mailer', :test_feed => true))
|
29
|
+
TestFeedEvent.can_send_email?.should be_true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe FeedEvent, 'check event enabled when creating' do
|
34
|
+
|
35
|
+
class TestFeedEvent < FeedEvent
|
36
|
+
privacy_description 'desc'
|
37
|
+
end
|
38
|
+
class NotDisabableEvent < FeedEvent; end
|
39
|
+
|
40
|
+
before(:each) do
|
41
|
+
@user = mock_model User, :feed_event_enabled? => true
|
42
|
+
@event = TestFeedEvent.new :source => mock_model(FeedEvent, :user => @user)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should be valid if source user has event enabled" do
|
46
|
+
@event.valid?
|
47
|
+
@event.should have(:no).errors_on(:source)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should be invalid if soure user has event disabled" do
|
51
|
+
@user.stub!(:feed_event_enabled?).and_return(false)
|
52
|
+
@event.valid?
|
53
|
+
@event.should have(1).error_on(:source)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should check wether the event is enabled" do
|
57
|
+
@user.should_receive(:feed_event_enabled?).with(TestFeedEvent)
|
58
|
+
@event.valid?
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should be valid if source has no user" do
|
62
|
+
@event.source = mock_model(FeedEvent)
|
63
|
+
@event.valid?
|
64
|
+
@event.should have(:no).errors_on(:source)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should be valid if source user is nil" do
|
68
|
+
@event.source = mock_model(FeedEvent, :user => nil)
|
69
|
+
@event.valid?
|
70
|
+
@event.should have(:no).errors_on(:source)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should be valid if source user has event disabled but event has no privacy description (user can not disabled the event)" do
|
74
|
+
@user.stub!(:feed_event_enabled?).and_return(false)
|
75
|
+
event = NotDisabableEvent.new :source => mock_model(FeedEvent, :user => @user)
|
76
|
+
event.valid?
|
77
|
+
event.should have(:no).errors_on(:source)
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'check event enabled when sending email' do
|
83
|
+
class TestFeedEvent < FeedEvent
|
84
|
+
privacy_description 'desc'
|
85
|
+
end
|
86
|
+
|
87
|
+
class NotDisabableEvent < FeedEvent;end
|
88
|
+
|
89
|
+
class Source; end
|
90
|
+
|
91
|
+
before(:each) do
|
92
|
+
TestFeedEvent.connection.stub!(:insert)
|
93
|
+
FeedEventMailer.stub!(:send).with(:new).and_return(stub('mailer', :test_feed => true, :not_disabable => true))
|
94
|
+
@user = mock_model(User, :subscribed_to_feed_event? => true, :subscribed_to_email? => true)
|
95
|
+
Source.stub!(:base_class).and_return(Source)
|
96
|
+
@source = mock_model(Source, :user => @user)
|
97
|
+
@event = TestFeedEvent.new :source => @source, :user => @user
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should send no email if event disabled" do
|
101
|
+
@user.stub!(:feed_event_enabled?).and_return(false)
|
102
|
+
FeedEventMailer.should_receive(:send).with('deliver_test_feed', @event).never
|
103
|
+
@event.save
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should send email if event enabled" do
|
107
|
+
@user.stub!(:feed_event_enabled?).and_return(true)
|
108
|
+
FeedEventMailer.should_receive(:send).with('deliver_test_feed', @event)
|
109
|
+
@event.save
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should send email if user can't disable event" do
|
113
|
+
event = NotDisabableEvent.new :source => @source, :user => @user
|
114
|
+
FeedEventMailer.should_receive(:send).with('deliver_not_disabable', event)
|
115
|
+
event.save
|
116
|
+
end
|
117
|
+
end
|
118
|
+
describe FeedEvent, 'check subscriptions when creating' do
|
119
|
+
class TestFeedEvent < FeedEvent
|
120
|
+
subscribe_description 'desc'
|
121
|
+
end
|
122
|
+
class NotSubscribableEvent < FeedEvent; end
|
123
|
+
|
124
|
+
before(:each) do
|
125
|
+
@user = mock_model User
|
126
|
+
@event = TestFeedEvent.new :user => @user
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should be invalid if user not subscribed to event" do
|
130
|
+
@user.stub!(:subscribed_to_feed_event?).and_return(false)
|
131
|
+
@event.valid?
|
132
|
+
@event.should have(1).errors_on(:user)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should be valid if user not subscribed to event but event has no description (user could not unsubscribe from this event)" do
|
136
|
+
@user.stub!(:subscribed_to_feed_event?).and_return(false)
|
137
|
+
@event = NotSubscribableEvent.new :user => @user
|
138
|
+
@event.should have(:no).errors_on(:user)
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should check the subscription of the user" do
|
142
|
+
@user.should_receive(:subscribed_to_feed_event?).with(TestFeedEvent).and_return(true)
|
143
|
+
@event.valid?
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should be valid if user subscribed to event" do
|
147
|
+
@user.stub!(:subscribed_to_feed_event?).and_return(true)
|
148
|
+
@event.valid?
|
149
|
+
@event.should have(:no).errors_on(:user)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe FeedEvent, 'check subscription before sending emails' do
|
154
|
+
class TestFeedEvent < FeedEvent
|
155
|
+
subscribe_description 'desc'
|
156
|
+
end
|
157
|
+
class NotSubscribableEvent < FeedEvent; end
|
158
|
+
|
159
|
+
before(:each) do
|
160
|
+
@user = mock_model User, :subscribed_to_email? => true, :subscribed_to_feed_event? => true, :online? => false
|
161
|
+
FeedEventMailer.stub!(:send).with(:new).and_return(stub('mailer', :respond_to? => true))
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should send an email if user subscribed to email" do
|
165
|
+
FeedEventMailer.should_receive(:send).with('deliver_test_feed', anything)
|
166
|
+
TestFeedEvent.create :user => @user
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should send no email if user subscribed to email but is online" do
|
170
|
+
@user.stub!(:online?).and_return(true)
|
171
|
+
FeedEventMailer.should_receive(:send).with('deliver_test_feed', anything).never
|
172
|
+
TestFeedEvent.create :user => @user
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should send an email user user subscribed to email and has no online method" do
|
176
|
+
FeedEventMailer.should_receive(:send).with('deliver_test_feed', anything)
|
177
|
+
TestFeedEvent.create :user => mock_model(User, :subscribed_to_email? => true, :subscribed_to_feed_event? => false)
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should check the subscription of the user" do
|
181
|
+
@user.should_receive(:subscribed_to_email?).with(TestFeedEvent).and_return(false)
|
182
|
+
TestFeedEvent.create :user => @user
|
183
|
+
end
|
184
|
+
|
185
|
+
it "should send no email if user has not subscribed to email" do
|
186
|
+
@user.stub!(:subscribed_to_email?).and_return(false)
|
187
|
+
FeedEventMailer.should_receive(:send).with('deliver_test_feed', anything).never
|
188
|
+
TestFeedEvent.create :user => @user
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should send a email if user can't unsubscribe from email (event has no email description)" do
|
192
|
+
@user.stub!(:subscribed_to_email?).and_return(false)
|
193
|
+
FeedEventMailer.should_receive(:send).with('deliver_not_subscribable', anything)
|
194
|
+
NotSubscribableEvent.create :user => @user
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should send an email if user subscribed to email but not to feed event" do
|
198
|
+
@user.stub!(:subscribed_to_feed_event?).and_return(false)
|
199
|
+
FeedEventMailer.should_receive(:send).with('deliver_test_feed', anything)
|
200
|
+
TestFeedEvent.create :user => @user
|
201
|
+
end
|
202
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe User, 'enable feed events' do
|
4
|
+
|
5
|
+
class TestEvent; end
|
6
|
+
before(:each) do
|
7
|
+
@user = User.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should enable an event" do
|
11
|
+
@user.enable_feed_event TestEvent
|
12
|
+
@user.enabled_feed_events.should include('TestEvent')
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should enable an event only once" do
|
16
|
+
@user.enable_feed_event TestEvent
|
17
|
+
@user.enable_feed_event TestEvent
|
18
|
+
@user.enabled_feed_events.should == ['TestEvent']
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should disable and event" do
|
22
|
+
@user.enabled_feed_events = ['TestEvent']
|
23
|
+
@user.disable_feed_event TestEvent
|
24
|
+
@user.enabled_feed_events.should_not include('TestEvent')
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should return true if an event is enabled" do
|
28
|
+
@user.enabled_feed_events = ['TestEvent']
|
29
|
+
@user.should be_feed_event_enabled(TestEvent)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should return false if an event is disabled" do
|
33
|
+
@user.should_not be_feed_event_enabled(TestEvent)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should mark the attibute dirty when disabling" do
|
37
|
+
@user.enabled_feed_events = ['TestEvent']
|
38
|
+
@user.save!
|
39
|
+
@user.disable_feed_event TestEvent
|
40
|
+
@user.should be_enabled_feed_events_changed
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should mark the attibute dirty when enabling" do
|
44
|
+
@user.enabled_feed_events = ['TestEvent1']
|
45
|
+
@user.save!
|
46
|
+
@user.enable_feed_event TestEvent
|
47
|
+
@user.should be_enabled_feed_events_changed
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe User, 'subscribe to feed events' do
|
52
|
+
class TestEvent; end
|
53
|
+
before(:each) do
|
54
|
+
@user = User.new
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should subscribe to an event" do
|
58
|
+
@user.subscribe_to_feed_event TestEvent
|
59
|
+
@user.feed_event_subscriptions.should include('TestEvent')
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should subscribe to an event only once" do
|
63
|
+
@user.subscribe_to_feed_event TestEvent
|
64
|
+
@user.subscribe_to_feed_event TestEvent
|
65
|
+
@user.feed_event_subscriptions.should == ['TestEvent']
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should unsubscribe from an event" do
|
69
|
+
@user.feed_event_subscriptions = ['TestEvent']
|
70
|
+
@user.unsubscribe_from_feed_event TestEvent
|
71
|
+
@user.feed_event_subscriptions.should be_empty
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should return true if user is subscribed" do
|
75
|
+
@user.feed_event_subscriptions = ['TestEvent']
|
76
|
+
@user.should be_subscribed_to_feed_event(TestEvent)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should return false if user is not subscribed" do
|
80
|
+
@user.should_not be_subscribed_to_feed_event(TestEvent)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should mark the attibute dirty when subscribing" do
|
84
|
+
@user.feed_event_subscriptions = ['TestEvent1']
|
85
|
+
@user.save!
|
86
|
+
@user.subscribe_to_feed_event TestEvent
|
87
|
+
@user.should be_feed_event_subscriptions_changed
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should mark the attibute dirty when unsubscribing" do
|
91
|
+
@user.feed_event_subscriptions = ['TestEvent']
|
92
|
+
@user.save!
|
93
|
+
@user.unsubscribe_from_feed_event TestEvent
|
94
|
+
@user.should be_feed_event_subscriptions_changed
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
describe User, 'subscribe to emails' do
|
100
|
+
class TestEvent; end
|
101
|
+
before(:each) do
|
102
|
+
@user = User.new
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should subscribe to an email" do
|
106
|
+
@user.subscribe_to_email TestEvent
|
107
|
+
@user.email_subscriptions.should include('TestEvent')
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should subscribe to an email only once" do
|
111
|
+
@user.subscribe_to_email TestEvent
|
112
|
+
@user.subscribe_to_email TestEvent
|
113
|
+
@user.email_subscriptions.should == ['TestEvent']
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should unsubscribe from an email" do
|
117
|
+
@user.email_subscriptions = ['TestEvent']
|
118
|
+
@user.unsubscribe_from_email TestEvent
|
119
|
+
@user.email_subscriptions.should be_empty
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should return true if user is subscribed" do
|
123
|
+
@user.email_subscriptions = ['TestEvent']
|
124
|
+
@user.should be_subscribed_to_email(TestEvent)
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should return false if user is not subscribed" do
|
128
|
+
@user.should_not be_subscribed_to_email(TestEvent)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should mark the attibute dirty when subscribing" do
|
132
|
+
@user.email_subscriptions = ['TestEvent1']
|
133
|
+
@user.save!
|
134
|
+
@user.subscribe_to_email TestEvent
|
135
|
+
@user.should be_email_subscriptions_changed
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should mark the attibute dirty when unsubscribing" do
|
139
|
+
@user.email_subscriptions = ['TestEvent']
|
140
|
+
@user.save!
|
141
|
+
@user.unsubscribe_from_email TestEvent
|
142
|
+
@user.should be_email_subscriptions_changed
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
describe User, 'subscribed to email notification' do
|
148
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
PLUGIN_ROOT = File.dirname(__FILE__) + '/..'
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
gem 'activerecord'
|
5
|
+
require 'activerecord'
|
6
|
+
|
7
|
+
__DIR__ = File.dirname __FILE__
|
8
|
+
|
9
|
+
FileUtils.rm_rf __DIR__ + '/../test.sqlite3'
|
10
|
+
ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => File.join(File.dirname(__FILE__), '..', 'test.sqlite3')
|
11
|
+
|
12
|
+
# migrate
|
13
|
+
|
14
|
+
class CreateUsers < ActiveRecord::Migration
|
15
|
+
def self.up
|
16
|
+
create_table :users do |t|
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
CreateUsers.up
|
22
|
+
|
23
|
+
require PLUGIN_ROOT + '/lib/social_feed/user_extension'
|
24
|
+
class User < ActiveRecord::Base
|
25
|
+
include SocialFeed::UserExtension
|
26
|
+
end
|
27
|
+
class FeedEventMailer; end
|
28
|
+
|
29
|
+
require File.dirname(__FILE__) + '/../generators/social_feed_migration/templates/migration'
|
30
|
+
AddSocialFeed.up
|
31
|
+
|
32
|
+
require PLUGIN_ROOT + '/lib/object_extensions'
|
33
|
+
|
34
|
+
|
35
|
+
# rspec rails stuff
|
36
|
+
|
37
|
+
module Spec
|
38
|
+
module Example
|
39
|
+
class ExampleGroup
|
40
|
+
|
41
|
+
@@model_id = 1000
|
42
|
+
|
43
|
+
def mock_model(model_class, options_and_stubs = {})
|
44
|
+
# null = options_and_stubs.delete(:null_object)
|
45
|
+
# stubs = options_and_stubs
|
46
|
+
id = @@model_id
|
47
|
+
@@model_id += 1
|
48
|
+
options_and_stubs = {
|
49
|
+
:id => id,
|
50
|
+
:to_param => id.to_s,
|
51
|
+
:new_record? => false,
|
52
|
+
:errors => stub("errors", :count => 0)
|
53
|
+
}.merge(options_and_stubs)
|
54
|
+
m = mock("#{model_class.name}_#{id}", options_and_stubs)
|
55
|
+
m.send(:__mock_proxy).instance_eval <<-CODE
|
56
|
+
def @target.is_a?(other)
|
57
|
+
#{model_class}.ancestors.include?(other)
|
58
|
+
end
|
59
|
+
def @target.kind_of?(other)
|
60
|
+
#{model_class}.ancestors.include?(other)
|
61
|
+
end
|
62
|
+
def @target.instance_of?(other)
|
63
|
+
other == #{model_class}
|
64
|
+
end
|
65
|
+
def @target.class
|
66
|
+
#{model_class}
|
67
|
+
end
|
68
|
+
CODE
|
69
|
+
yield m if block_given?
|
70
|
+
m
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
module ActiveRecord #:nodoc:
|
77
|
+
class Base
|
78
|
+
|
79
|
+
def errors_on(attribute)
|
80
|
+
self.valid?
|
81
|
+
[self.errors.on(attribute)].flatten.compact
|
82
|
+
end
|
83
|
+
alias :error_on :errors_on
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div id="user_feed">
|
2
|
+
<%- user_feed.each do |event| -%>
|
3
|
+
<%- if event.hint_body? -%>
|
4
|
+
<%= event.hint_body %>
|
5
|
+
<%- else -%>
|
6
|
+
<%= hint = render :partial => feed_event_partial_name(event), :locals => {:event => event}
|
7
|
+
event.update_attribute :hint_body, hint
|
8
|
+
hint
|
9
|
+
%>
|
10
|
+
<%- end -%>
|
11
|
+
<% end %>
|
12
|
+
</div>
|
data/views/destroy.rjs
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
page.visual_effect :fade, dom_id(@event)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<h2>Subscriptions</h2>
|
2
|
+
<table>
|
3
|
+
<tr>
|
4
|
+
<th>Feed</th>
|
5
|
+
<th>Email</th>
|
6
|
+
<th>Event</th>
|
7
|
+
</tr>
|
8
|
+
<%- FeedEvent.subscribable_feed_event_types.each do |clazz| -%>
|
9
|
+
<tr id="<%= clazz.name + '_row' %>">
|
10
|
+
<td>
|
11
|
+
<%= check_box_tag clazz.name + '_feed', '1', current_user.subscribed_to_feed_event?(clazz) %>
|
12
|
+
<%= observe_field clazz.name + '_feed', :url => toggle_subscription_feed_events_path(:event => clazz.name), :success => "new Effect.Highlight('#{clazz.name + '_row'}')" %>
|
13
|
+
</td>
|
14
|
+
<td>
|
15
|
+
<%- if clazz.can_send_email? -%>
|
16
|
+
<%= check_box_tag clazz.name + '_mail', '1', current_user.subscribed_to_email?(clazz) %>
|
17
|
+
<%= observe_field clazz.name + '_mail', :url => toggle_email_subscription_feed_events_path(:event => clazz.name), :success => "new Effect.Highlight('#{clazz.name + '_row'}')" %>
|
18
|
+
<%- end -%>
|
19
|
+
</td>
|
20
|
+
<td class="blue_font"><%= clazz.subscribe_description %></td>
|
21
|
+
</tr>
|
22
|
+
<%- end -%>
|
23
|
+
</table>
|
24
|
+
|
25
|
+
<h2>Privacy Settings</h2>
|
26
|
+
<table>
|
27
|
+
<%- FeedEvent.enabable_feed_event_types.each do |clazz| -%>
|
28
|
+
<tr id="<%= "#{clazz.name + '_privacy_row'}" %>">
|
29
|
+
<td>
|
30
|
+
<%= check_box_tag clazz.name + '_privacy', '1', current_user.feed_event_enabled?(clazz) %>
|
31
|
+
<%= observe_field clazz.name + '_privacy', :url => toggle_enabled_feed_events_path(:event => clazz.name), :success => "new Effect.Highlight('#{clazz.name + '_privacy_row'}')" %>
|
32
|
+
</td>
|
33
|
+
<td><%= clazz.privacy_description %></td>
|
34
|
+
</tr>
|
35
|
+
<%- end -%>
|
36
|
+
</table>
|
metadata
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: social_feed
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alexander Lang
|
8
|
+
- Thilo Utke
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2009-05-07 00:00:00 +02:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: ""
|
18
|
+
email: alex@upstream-berlin.com
|
19
|
+
executables: []
|
20
|
+
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files:
|
24
|
+
- README
|
25
|
+
files:
|
26
|
+
- .gitignore
|
27
|
+
- INSTALL
|
28
|
+
- MIT-LICENSE
|
29
|
+
- README
|
30
|
+
- Rakefile
|
31
|
+
- VERSION
|
32
|
+
- generators/feed_event/feed_event_generator.rb
|
33
|
+
- generators/feed_event/templates/event_hint.html.erb
|
34
|
+
- generators/feed_event/templates/event_model.rb.erb
|
35
|
+
- generators/social_feed_migration/social_feed_migration_generator.rb
|
36
|
+
- generators/social_feed_migration/templates/migration.rb
|
37
|
+
- init.rb
|
38
|
+
- install.rb
|
39
|
+
- lib/feed_event.rb
|
40
|
+
- lib/feed_event_mailer.rb.template
|
41
|
+
- lib/feed_events_controller.rb.template
|
42
|
+
- lib/object_extensions.rb
|
43
|
+
- lib/social_feed/feed_event_mailer_extension.rb
|
44
|
+
- lib/social_feed/feed_events_controller_extension.rb
|
45
|
+
- lib/social_feed/routing.rb
|
46
|
+
- lib/social_feed/social_feed_helper.rb
|
47
|
+
- lib/social_feed/user_extension.rb
|
48
|
+
- routes.rb
|
49
|
+
- social_feed.yml
|
50
|
+
- spec/controllers/feed_events_controller_spec.rb
|
51
|
+
- spec/helpers/social_feed_helper_spec.rb
|
52
|
+
- spec/models/feed_event_spec.rb
|
53
|
+
- spec/models/user_spec.rb
|
54
|
+
- spec/spec_helper.rb
|
55
|
+
- views/_user_feed.html.erb
|
56
|
+
- views/destroy.rjs
|
57
|
+
- views/index.html.erb
|
58
|
+
- views/settings.html.erb
|
59
|
+
has_rdoc: true
|
60
|
+
homepage: http://github.com/langalex/social_feed
|
61
|
+
licenses: []
|
62
|
+
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options:
|
65
|
+
- --charset=UTF-8
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: "0"
|
79
|
+
version:
|
80
|
+
requirements: []
|
81
|
+
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 1.3.5
|
84
|
+
signing_key:
|
85
|
+
specification_version: 2
|
86
|
+
summary: a ruby on rails plugin to create and display a social feed
|
87
|
+
test_files:
|
88
|
+
- spec/controllers/feed_events_controller_spec.rb
|
89
|
+
- spec/helpers/social_feed_helper_spec.rb
|
90
|
+
- spec/models/feed_event_spec.rb
|
91
|
+
- spec/models/user_spec.rb
|
92
|
+
- spec/spec_helper.rb
|