acts_as_messenger 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +65 -0
- data/Rakefile +46 -0
- data/VERSION +1 -0
- data/acts_as_messenger.gemspec +72 -0
- data/generators/acts_as_messenger/acts_as_messenger_generator.rb +17 -0
- data/generators/acts_as_messenger/templates/migrations/create_comments.rb +19 -0
- data/generators/acts_as_messenger/templates/migrations/create_message_threads.rb +19 -0
- data/generators/acts_as_messenger/templates/migrations/create_recipients.rb +20 -0
- data/generators/acts_as_messenger/templates/models/comment.rb +8 -0
- data/generators/acts_as_messenger/templates/models/message_thread.rb +21 -0
- data/generators/acts_as_messenger/templates/models/recipient.rb +22 -0
- data/lib/acts_as_messenger/thread.rb +36 -0
- data/lib/acts_as_messenger.rb +50 -0
- data/spec/acts_as_messenger_spec.rb +101 -0
- data/spec/database.yml +7 -0
- data/spec/debug.log +2519 -0
- data/spec/models/user.rb +5 -0
- data/spec/schema.rb +29 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +24 -0
- metadata +100 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Mike Nelson
|
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.rdoc
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
= acts_as_messenger
|
2
|
+
|
3
|
+
Standard facebook-style messaging system. Not bound to any friendship structure. Integrates directly into your User model. Allows for users to comment on a thread, leave a thread, and be updated when a thread is commented on.
|
4
|
+
|
5
|
+
|
6
|
+
== Installation
|
7
|
+
|
8
|
+
Install the gem
|
9
|
+
|
10
|
+
gem install acts_as_messenger
|
11
|
+
|
12
|
+
Generate the necessary classes and migrations
|
13
|
+
|
14
|
+
script/generate acts_as_messenger
|
15
|
+
|
16
|
+
Migrate the DB
|
17
|
+
|
18
|
+
rake db:migrate
|
19
|
+
|
20
|
+
Add acts_as_messenger to your user model
|
21
|
+
|
22
|
+
class User < ActiveRecord::Base
|
23
|
+
...
|
24
|
+
acts_as_messenger
|
25
|
+
...
|
26
|
+
end
|
27
|
+
|
28
|
+
== Usage
|
29
|
+
|
30
|
+
With acts_as_messenger now incorporated into your User model, you have access to helper methods for creating messages and recipients. It's as simple as calling the send_message(title, body, recipients) method:
|
31
|
+
|
32
|
+
mike = User.find 4
|
33
|
+
john = User.find 3
|
34
|
+
sky = User.find 2
|
35
|
+
|
36
|
+
thread = mike.send_message('Message Title', 'Message Body', [john, sky])
|
37
|
+
# OR
|
38
|
+
thread = mike.send_message('Message Title', 'Message Body', [3, 2])
|
39
|
+
|
40
|
+
The recipients of the message can be an array of AR objects or can be Fixnum's (or any combination). In the case of a Fixnum, the class type is assumed to be the same as the sending class.
|
41
|
+
---
|
42
|
+
From the thread object you can access the participants of the message directly. Participants are considered as the author of the message and anyone who's commented on the thread.
|
43
|
+
|
44
|
+
thread.participants
|
45
|
+
=> [mike]
|
46
|
+
|
47
|
+
john.comment_on(thread, 'Some comment')
|
48
|
+
|
49
|
+
thread.participants
|
50
|
+
=> [mike, john]
|
51
|
+
|
52
|
+
=== Privacy
|
53
|
+
|
54
|
+
All threads have a private_thread field. This allows the can_be_viewed_by? method to be utilized. The can_be_viewed_by? method checks to see if the object is either the author or one of the recipient objects:
|
55
|
+
|
56
|
+
random_user = User.find 490
|
57
|
+
thread.can_be_viewed_by?(random_user)
|
58
|
+
=> false
|
59
|
+
|
60
|
+
thread.can_be_viewed_by?(john)
|
61
|
+
=> true
|
62
|
+
|
63
|
+
== Copyright
|
64
|
+
|
65
|
+
Copyright (c) 2010 Mike Nelson. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "acts_as_messenger"
|
8
|
+
gem.summary = "Standard facebook-style messaging system. Not bound to any friendship structure. Integrates directly into your User model."
|
9
|
+
gem.description = "Standard facebook-style messaging system. Not bound to any friendship structure. Integrates directly into your User model. Allows for users to comment on a thread, leave a thread, and be updated when a thread is commented on."
|
10
|
+
gem.email = "mdnelson30@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/mnelson/acts_as_messenger"
|
12
|
+
gem.authors = ["Mike Nelson"]
|
13
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
14
|
+
gem.add_development_dependency "active_record"
|
15
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
|
+
end
|
17
|
+
Jeweler::GemcutterTasks.new
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'spec/rake/spectask'
|
23
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
24
|
+
spec.libs << 'lib' << 'spec'
|
25
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
26
|
+
end
|
27
|
+
|
28
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
29
|
+
spec.libs << 'lib' << 'spec'
|
30
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
31
|
+
spec.rcov = true
|
32
|
+
end
|
33
|
+
|
34
|
+
task :spec => :check_dependencies
|
35
|
+
|
36
|
+
task :default => :spec
|
37
|
+
|
38
|
+
require 'rake/rdoctask'
|
39
|
+
Rake::RDocTask.new do |rdoc|
|
40
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
41
|
+
|
42
|
+
rdoc.rdoc_dir = 'rdoc'
|
43
|
+
rdoc.title = "acts_as_messenger #{version}"
|
44
|
+
rdoc.rdoc_files.include('README*')
|
45
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
46
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{acts_as_messenger}
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Mike Nelson"]
|
12
|
+
s.date = %q{2010-02-02}
|
13
|
+
s.description = %q{Standard facebook-style messaging system. Not bound to any friendship structure. Integrates directly into your User model. Allows for users to comment on a thread, leave a thread, and be updated when a thread is commented on.}
|
14
|
+
s.email = %q{mdnelson30@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"acts_as_messenger.gemspec",
|
27
|
+
"generators/acts_as_messenger/acts_as_messenger_generator.rb",
|
28
|
+
"generators/acts_as_messenger/templates/migrations/create_comments.rb",
|
29
|
+
"generators/acts_as_messenger/templates/migrations/create_message_threads.rb",
|
30
|
+
"generators/acts_as_messenger/templates/migrations/create_recipients.rb",
|
31
|
+
"generators/acts_as_messenger/templates/models/comment.rb",
|
32
|
+
"generators/acts_as_messenger/templates/models/message_thread.rb",
|
33
|
+
"generators/acts_as_messenger/templates/models/recipient.rb",
|
34
|
+
"lib/acts_as_messenger.rb",
|
35
|
+
"lib/acts_as_messenger/thread.rb",
|
36
|
+
"spec/acts_as_messenger_spec.rb",
|
37
|
+
"spec/database.yml",
|
38
|
+
"spec/debug.log",
|
39
|
+
"spec/models/user.rb",
|
40
|
+
"spec/schema.rb",
|
41
|
+
"spec/spec.opts",
|
42
|
+
"spec/spec_helper.rb"
|
43
|
+
]
|
44
|
+
s.homepage = %q{http://github.com/mnelson/acts_as_messenger}
|
45
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
46
|
+
s.require_paths = ["lib"]
|
47
|
+
s.rubygems_version = %q{1.3.5}
|
48
|
+
s.summary = %q{Standard facebook-style messaging system. Not bound to any friendship structure. Integrates directly into your User model.}
|
49
|
+
s.test_files = [
|
50
|
+
"spec/acts_as_messenger_spec.rb",
|
51
|
+
"spec/models/user.rb",
|
52
|
+
"spec/schema.rb",
|
53
|
+
"spec/spec_helper.rb"
|
54
|
+
]
|
55
|
+
|
56
|
+
if s.respond_to? :specification_version then
|
57
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
58
|
+
s.specification_version = 3
|
59
|
+
|
60
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
61
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
62
|
+
s.add_development_dependency(%q<active_record>, [">= 0"])
|
63
|
+
else
|
64
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
65
|
+
s.add_dependency(%q<active_record>, [">= 0"])
|
66
|
+
end
|
67
|
+
else
|
68
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
69
|
+
s.add_dependency(%q<active_record>, [">= 0"])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class ActsAsMessengerGenerator < Rails::Generator::Base
|
2
|
+
|
3
|
+
def manifest
|
4
|
+
record do |m|
|
5
|
+
|
6
|
+
%w(comment message_thread recipient).each do |model|
|
7
|
+
m.file "models/#{model}.rb", "app/models/#{model}.rb"
|
8
|
+
m.migration_template "migrations/create_#{model.pluralize}.rb", "db/migrate"
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def file_name
|
15
|
+
"acts_as_messenger"
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class CreateComments < ActiveRecord::Migration
|
2
|
+
|
3
|
+
def self.up
|
4
|
+
create_table :comments do |t|
|
5
|
+
t.references :commentable, :polymorphic => true
|
6
|
+
t.integer :author_id
|
7
|
+
t.text :body
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
add_index :comments, :author_id
|
12
|
+
add_index :comments, [:commentable_id, :commentable_type]
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.down
|
16
|
+
drop_table :comments
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class CreateMessageThreads < ActiveRecord::Migration
|
2
|
+
|
3
|
+
def self.up
|
4
|
+
create_table :message_threads do |t|
|
5
|
+
t.integer :author_id
|
6
|
+
t.string :title
|
7
|
+
t.text :body
|
8
|
+
t.boolean :private_thread, :default => true
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
|
12
|
+
add_index :message_threads, :author_id
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.down
|
16
|
+
drop_table :message_threads
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class CreateRecipients < ActiveRecord::Migration
|
2
|
+
|
3
|
+
def self.up
|
4
|
+
create_table :recipients do |t|
|
5
|
+
t.references :receiver, :polymorphic => true
|
6
|
+
t.references :message_thread
|
7
|
+
t.boolean :has_read
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
add_index :recipients, :message_thread_id
|
12
|
+
add_index :recipients, [:receiver_id, :receiver_type]
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.down
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class MessageThread < ActiveRecord::Base
|
2
|
+
include SocialButterfly::Thread
|
3
|
+
|
4
|
+
acts_as_thread
|
5
|
+
has_many :recipients, :dependent => :destroy
|
6
|
+
|
7
|
+
def recipient_by_user(u)
|
8
|
+
self.recipients.by_user(u).first
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
def can_be_viewed_by?(user)
|
13
|
+
!!(user && (!self.private_thread || self.author == user || self.recipient_objects.include?(user)))
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
def recipient_objects
|
19
|
+
self.recipients.find(:all, :include => :receiver).collect{|r| r.receiver}
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Recipient < ActiveRecord::Base
|
2
|
+
|
3
|
+
|
4
|
+
belongs_to :receiver, :polymorphic => true
|
5
|
+
belongs_to :message_thread
|
6
|
+
|
7
|
+
default_scope :order => 'has_read ASC, created_at DESC'
|
8
|
+
|
9
|
+
named_scope :by_user, lambda {|u| {:conditions => ['receiver_type = ? and receiver_id = ?', 'User', u.id]}}
|
10
|
+
named_scope :read, :conditions => ['has_read = ?', true]
|
11
|
+
named_scope :unread, :conditions => ['has_read = ?', false]
|
12
|
+
|
13
|
+
|
14
|
+
def read!
|
15
|
+
self.update_attribute(:has_read, true)
|
16
|
+
end
|
17
|
+
|
18
|
+
def unread!
|
19
|
+
self.update_attribute(:has_read, false)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module SocialButterfly
|
2
|
+
module Thread
|
3
|
+
|
4
|
+
def self.included(model)
|
5
|
+
model.extend(SocialButterfly::Thread::ClassMethods)
|
6
|
+
|
7
|
+
model.send(:include, SocialButterfly::Thread::InstanceMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def acts_as_thread
|
12
|
+
|
13
|
+
validates_presence_of :author
|
14
|
+
validates_inclusion_of :private_thread, :in => [true, false]
|
15
|
+
|
16
|
+
belongs_to :author, :class_name => 'User'
|
17
|
+
has_many :comments, :as => :commentable, :dependent => :destroy
|
18
|
+
has_many :comment_participants, :through => :comments, :source => :author, :uniq => true
|
19
|
+
|
20
|
+
named_scope :by_user, lambda {|u| u && {:conditions => ['author_id = ?', u.id]} || {}}
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module InstanceMethods
|
26
|
+
def last_post
|
27
|
+
self.comments.last || self
|
28
|
+
end
|
29
|
+
|
30
|
+
def participants
|
31
|
+
(self.comment_participants + [self.author].compact).uniq
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module SocialButterfly
|
2
|
+
module Message
|
3
|
+
def self.included(model)
|
4
|
+
model.extend(SocialButterfly::Message::ClassMethods)
|
5
|
+
model.send(:include, SocialButterfly::Message::InstanceMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def acts_as_messenger
|
10
|
+
has_many :recipients, :as => :receiver
|
11
|
+
has_many :unread_recipients, :source => :recipients, :class_name => 'Recipient', :as => :receiver, :conditions => {:read => false}
|
12
|
+
has_many :read_recipients, :source => :recipients, :class_name => 'Recipient', :as => :receiver, :conditions => {:read => true}
|
13
|
+
|
14
|
+
has_many :sent_messages, :class_name => 'MessageThread', :foreign_key => :author_id
|
15
|
+
has_many :unread_messages, :through => :unread_recipients, :source => :message_thread
|
16
|
+
has_many :read_messages, :through => :read_recipients, :source => :message_thread
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module InstanceMethods
|
21
|
+
def send_message(title, body, recips)
|
22
|
+
thread = ::MessageThread.create(:author => self, :title => title, :body => body, :private_thread => true)
|
23
|
+
thread.recipients = [recips].flatten.uniq.collect{|r| rdata = recipient_data(r); thread.recipients.create(:receiver_id => rdata[0], :receiver_type => rdata[1])}
|
24
|
+
thread
|
25
|
+
end
|
26
|
+
def recipient_for(message)
|
27
|
+
self.recipients.find(:first, :conditions => ['message_thread_id = ?', message.id])
|
28
|
+
end
|
29
|
+
|
30
|
+
def comment_on(message, body)
|
31
|
+
if message && body
|
32
|
+
message.comments.create(:author => self, :body => body)
|
33
|
+
recip = recipient_for(message)
|
34
|
+
(message.recipients - [recip].compact).each{|r| r.unread!}
|
35
|
+
true
|
36
|
+
else
|
37
|
+
false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def recipient_data(given)
|
44
|
+
given.is_a?(Fixnum) && [given, self.class.name] || [given.id, given.class.name]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
::ActiveRecord::Base.send :include, SocialButterfly::Message
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "ActsAsMessenger" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@mike = User.create(:name => 'Mike')
|
7
|
+
@john = User.create(:name => 'John')
|
8
|
+
@sky = User.create(:name => 'Sky')
|
9
|
+
end
|
10
|
+
|
11
|
+
it "Should integrate flawlessly" do
|
12
|
+
@mike.methods.include?('send_message').should be_true
|
13
|
+
m = @mike.method('send_message')
|
14
|
+
m.arity.should eql(3)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "Should generate a valid thread" do
|
18
|
+
thread = @mike.send_message('Title', 'Body', @john)
|
19
|
+
thread.valid?.should be_true
|
20
|
+
end
|
21
|
+
|
22
|
+
it "Should generate recipients correctly" do
|
23
|
+
thread = @mike.send_message('Title 1', 'Body 1', @john)
|
24
|
+
|
25
|
+
thread.recipients.size.should eql(1)
|
26
|
+
@john.recipients.size.should eql(1)
|
27
|
+
@mike.recipients.size.should eql(0)
|
28
|
+
|
29
|
+
thread = @john.send_message('Title 2', 'Body 2', [@mike.id, @sky.id])
|
30
|
+
|
31
|
+
thread.recipients.size.should eql(2)
|
32
|
+
|
33
|
+
@mike.reload
|
34
|
+
@john.reload
|
35
|
+
@sky.reload
|
36
|
+
|
37
|
+
@mike.recipients.size.should eql(1)
|
38
|
+
@john.recipients.size.should eql(1)
|
39
|
+
@sky.recipients.size.should eql(1)
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
it "Should allow for removal of recipient from thread" do
|
44
|
+
thread = @mike.send_message('Title 3', 'Body 3', [@john, @sky])
|
45
|
+
|
46
|
+
@john.recipients.first.read!
|
47
|
+
@john.recipients.read.size.should eql(1)
|
48
|
+
@john.recipients.unread.size.should eql(0)
|
49
|
+
|
50
|
+
@sky.comment_on(thread, 'This is totally awesome')
|
51
|
+
|
52
|
+
@john.recipients.unread.size.should eql(1)
|
53
|
+
@john.recipients.read.size.should eql(0)
|
54
|
+
|
55
|
+
@john.recipients.first.destroy
|
56
|
+
|
57
|
+
@sky.comment_on(thread, 'Seriously, i love this')
|
58
|
+
|
59
|
+
@john.recipients.size.should eql(0)
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
it "Should allow destroy all recipients on thread destruction" do
|
64
|
+
thread = @mike.send_message('Title 4', 'Body 4', [@john, @sky, @john, @sky])
|
65
|
+
|
66
|
+
@john.recipients.size.should eql(1)
|
67
|
+
|
68
|
+
thread.destroy
|
69
|
+
|
70
|
+
@john.recipients.size.should eql(0)
|
71
|
+
@sky.recipients.size.should eql(0)
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
it "Should access participants properly" do
|
76
|
+
thread = @mike.send_message('Title 5', 'Body 5', [@john, @sky])
|
77
|
+
|
78
|
+
thread.participants.sort{|a,b| a.id <=> b.id}.should eql([@mike])
|
79
|
+
|
80
|
+
@john.comment_on(thread, 'Test')
|
81
|
+
|
82
|
+
thread.reload
|
83
|
+
thread.participants.sort{|a,b| a.id <=> b.id}.should eql([@mike, @john])
|
84
|
+
|
85
|
+
@sky.comment_on(thread, 'Tester')
|
86
|
+
|
87
|
+
thread.reload
|
88
|
+
thread.participants.sort{|a,b| a.id <=> b.id}.should eql([@mike, @john, @sky])
|
89
|
+
end
|
90
|
+
|
91
|
+
it "Should restrict access to the right objects" do
|
92
|
+
thread = @mike.send_message('Title 6', 'Body 6', [@john, @sky])
|
93
|
+
|
94
|
+
frank = User.create
|
95
|
+
thread.can_be_viewed_by?(frank).should be_false
|
96
|
+
|
97
|
+
thread.can_be_viewed_by?(@sky).should be_true
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|