acts_as_chattable 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +4 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +122 -0
- data/MIT-LICENSE +20 -0
- data/README.md +327 -0
- data/Rakefile +32 -0
- data/VERSION +1 -0
- data/acts_as_chattable.gemspec +88 -0
- data/coverage/.last_run.json +5 -0
- data/coverage/.resultset.json +338 -0
- data/gemfiles/Gemfile-3.0 +6 -0
- data/gemfiles/Gemfile-3.1 +6 -0
- data/gemfiles/Gemfile-3.2 +6 -0
- data/gemfiles/Gemfile-4.0 +6 -0
- data/lib/acts_as_chattable.rb +17 -0
- data/lib/acts_as_chattable/message.rb +75 -0
- data/lib/acts_as_chattable/model.rb +159 -0
- data/lib/acts_as_chattable/rails3.rb +15 -0
- data/lib/acts_as_chattable/rails4.rb +19 -0
- data/lib/acts_as_chattable/railtie.rb +14 -0
- data/lib/acts_as_chattable/relation.rb +17 -0
- data/lib/generators/acts_as_chattable/migration/migration_generator.rb +21 -0
- data/lib/generators/acts_as_chattable/migration/templates/migration.rb +20 -0
- data/lib/generators/acts_as_chattable/migration/templates/migration_permanent.rb +11 -0
- data/spec/acts_as_chattable_spec.rb +253 -0
- data/spec/spec_helper.rb +67 -0
- data/spec/support/admin.rb +3 -0
- data/spec/support/send_message.rb +3 -0
- data/spec/support/user.rb +6 -0
- metadata +186 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
module ActsAsChattable
|
2
|
+
autoload :Model, 'acts_as_chattable/model'
|
3
|
+
autoload :Message, 'acts_as_chattable/message'
|
4
|
+
autoload :Relation, 'acts_as_chattable/relation'
|
5
|
+
autoload :Rails3, 'acts_as_chattable/rails3'
|
6
|
+
autoload :Rails4, 'acts_as_chattable/rails4'
|
7
|
+
|
8
|
+
def self.rails_api
|
9
|
+
if Rails::VERSION::MAJOR >= 4
|
10
|
+
Rails4
|
11
|
+
else
|
12
|
+
Rails3
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'acts_as_chattable/railtie'
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module ActsAsChattable
|
2
|
+
class Message < ::ActiveRecord::Base
|
3
|
+
belongs_to :received_messageable, :polymorphic => true
|
4
|
+
belongs_to :sent_messageable, :polymorphic => true
|
5
|
+
|
6
|
+
attr_accessor :removed, :restored
|
7
|
+
cattr_accessor :required
|
8
|
+
|
9
|
+
ActsAsChattable.rails_api.new(self).default_scope("created_at desc")
|
10
|
+
|
11
|
+
scope :are_from, lambda { |*args| where(:sent_messageable_id => args.first, :sent_messageable_type => args.first.class.name) }
|
12
|
+
scope :are_to, lambda { |*args| where(:received_messageable_id => args.first, :received_messageable_type => args.first.class.name) }
|
13
|
+
scope :connected_with, lambda { |*args| where("(sent_messageable_type = :sent_type and
|
14
|
+
sent_messageable_id = :sent_id and
|
15
|
+
sender_delete = :s_delete and sender_permanent_delete = :s_perm_delete) or
|
16
|
+
(received_messageable_type = :received_type and
|
17
|
+
received_messageable_id = :received_id and
|
18
|
+
recipient_delete = :r_delete and recipient_permanent_delete = :r_perm_delete)",
|
19
|
+
:sent_type => args.first.class.resolve_active_record_ancestor.to_s,
|
20
|
+
:sent_id => args.first.id,
|
21
|
+
:received_type => args.first.class.resolve_active_record_ancestor.to_s,
|
22
|
+
:received_id => args.first.id,
|
23
|
+
:r_delete => args.last,
|
24
|
+
:s_delete => args.last,
|
25
|
+
:r_perm_delete => false,
|
26
|
+
:s_perm_delete => false)
|
27
|
+
}
|
28
|
+
scope :readed, lambda { where(:opened => true) }
|
29
|
+
scope :unreaded, lambda { where(:opened => false) }
|
30
|
+
scope :deleted, lambda { where(:recipient_delete => true, :sender_delete => true) }
|
31
|
+
|
32
|
+
def open?
|
33
|
+
self.opened?
|
34
|
+
end
|
35
|
+
|
36
|
+
def open
|
37
|
+
update_attributes!(:opened => true)
|
38
|
+
end
|
39
|
+
alias :mark_as_read :open
|
40
|
+
alias :read :open
|
41
|
+
|
42
|
+
def close
|
43
|
+
update_attributes!(:opened => false)
|
44
|
+
end
|
45
|
+
alias :mark_as_unread :close
|
46
|
+
alias :unread :close
|
47
|
+
|
48
|
+
alias :from :sent_messageable
|
49
|
+
alias :to :received_messageable
|
50
|
+
|
51
|
+
def real_receiver(user)
|
52
|
+
user == from ? to : from
|
53
|
+
end
|
54
|
+
|
55
|
+
def participant?(user)
|
56
|
+
(to == user) || (from == user)
|
57
|
+
end
|
58
|
+
|
59
|
+
def conversation
|
60
|
+
root.subtree
|
61
|
+
end
|
62
|
+
|
63
|
+
def delete
|
64
|
+
self.removed = true
|
65
|
+
end
|
66
|
+
|
67
|
+
def restore
|
68
|
+
self.restored = true
|
69
|
+
end
|
70
|
+
|
71
|
+
def people
|
72
|
+
conversation.map{ |x| x.from }.uniq!
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
module ActsAsChattable
|
2
|
+
module Model
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
mattr_accessor :messages_class_name
|
10
|
+
|
11
|
+
# Method make ActiveRecord::Base object chattable
|
12
|
+
# @param [Symbol] :table_name - table name for messages
|
13
|
+
# @param [String] :class_name - message class name
|
14
|
+
# @param [Array, Symbol] :required - required fields in message
|
15
|
+
# @param [Symbol] :dependent - dependent option from ActiveRecord has_many method
|
16
|
+
def acts_as_chattable(options = {})
|
17
|
+
default_options = {
|
18
|
+
:table_name => "messages",
|
19
|
+
:class_name => "ActsAsChattable::Message",
|
20
|
+
:required => [:body],
|
21
|
+
:dependent => :nullify
|
22
|
+
}
|
23
|
+
options = default_options.merge(options)
|
24
|
+
|
25
|
+
has_many :received_messages_relation,
|
26
|
+
:as => :received_messageable,
|
27
|
+
:class_name => options[:class_name],
|
28
|
+
:dependent => options[:dependent]
|
29
|
+
has_many :sent_messages_relation,
|
30
|
+
:as => :sent_messageable,
|
31
|
+
:class_name => options[:class_name],
|
32
|
+
:dependent => options[:dependent]
|
33
|
+
|
34
|
+
self.messages_class_name = options[:class_name].constantize
|
35
|
+
|
36
|
+
if self.messages_class_name.respond_to?(:table_name=)
|
37
|
+
self.messages_class_name.table_name = options[:table_name]
|
38
|
+
else
|
39
|
+
self.messages_class_name.set_table_name(options[:table_name])
|
40
|
+
ActiveSupport::Deprecation.warn("Calling set_table_name is deprecated. Please use `self.table_name = 'the_name'` instead.")
|
41
|
+
end
|
42
|
+
|
43
|
+
self.messages_class_name.required = Array.wrap(options[:required])
|
44
|
+
self.messages_class_name.validates_presence_of self.messages_class_name.required
|
45
|
+
|
46
|
+
include ActsAsChattable::Model::InstanceMethods
|
47
|
+
end
|
48
|
+
|
49
|
+
# Method recognize real object class
|
50
|
+
# @return [ActiveRecord::Base] class or relation object
|
51
|
+
def resolve_active_record_ancestor
|
52
|
+
self.reflect_on_association(:received_messages_relation).active_record
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
module InstanceMethods
|
58
|
+
# @return [ActiveRecord::Relation] all messages connected with user
|
59
|
+
def messages(trash = false)
|
60
|
+
result = self.class.messages_class_name.connected_with(self, trash)
|
61
|
+
result.relation_context = self
|
62
|
+
|
63
|
+
result
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [ActiveRecord::Relation] returns all messages from inbox
|
67
|
+
def received_messages
|
68
|
+
result = ActsAsChattable.rails_api.new(received_messages_relation)
|
69
|
+
result = result.scoped.where(:recipient_delete => false)
|
70
|
+
result.relation_context = self
|
71
|
+
|
72
|
+
result
|
73
|
+
end
|
74
|
+
|
75
|
+
# @return [ActiveRecord::Relation] returns all messages from outbox
|
76
|
+
def sent_messages
|
77
|
+
result = ActsAsChattable.rails_api.new(sent_messages_relation)
|
78
|
+
result = result.scoped.where(:sender_delete => false)
|
79
|
+
result.relation_context = self
|
80
|
+
|
81
|
+
result
|
82
|
+
end
|
83
|
+
|
84
|
+
# @return [ActiveRecord::Relation] returns all messages from trash
|
85
|
+
def deleted_messages
|
86
|
+
messages true
|
87
|
+
end
|
88
|
+
|
89
|
+
# Method sens message to another user
|
90
|
+
# @param [ActiveRecord::Base] to
|
91
|
+
# @param [String] topic
|
92
|
+
# @param [String] body
|
93
|
+
#
|
94
|
+
# @return [ActsAsChattable::Message] the message object
|
95
|
+
def send_message(to, *args)
|
96
|
+
message_attributes = {}
|
97
|
+
|
98
|
+
case args.first
|
99
|
+
when String
|
100
|
+
self.class.messages_class_name.required.each_with_index do |attribute, index|
|
101
|
+
message_attributes[attribute] = args[index]
|
102
|
+
end
|
103
|
+
when Hash
|
104
|
+
message_attributes = args.first
|
105
|
+
end
|
106
|
+
|
107
|
+
message = self.class.messages_class_name.new message_attributes
|
108
|
+
message.received_messageable = to
|
109
|
+
message.sent_messageable = self
|
110
|
+
message.save
|
111
|
+
|
112
|
+
message
|
113
|
+
end
|
114
|
+
|
115
|
+
# Method send message to another user
|
116
|
+
# and raise exception in case of validation errors
|
117
|
+
# @param [ActiveRecord::Base] to
|
118
|
+
# @param [String] topic
|
119
|
+
# @param [String] body
|
120
|
+
#
|
121
|
+
# @return [ActsAsChattable::Message] the message object
|
122
|
+
def send_message!(to, *args)
|
123
|
+
send_message(to, *args).save!
|
124
|
+
end
|
125
|
+
|
126
|
+
# Mark message as deleted
|
127
|
+
def delete_message(message)
|
128
|
+
current_user = self
|
129
|
+
|
130
|
+
case current_user
|
131
|
+
when message.to
|
132
|
+
attribute = message.recipient_delete ? :recipient_permanent_delete : :recipient_delete
|
133
|
+
when message.from
|
134
|
+
attribute = message.sender_delete ? :sender_permanent_delete : :sender_delete
|
135
|
+
else
|
136
|
+
raise "#{current_user} can't delete this message"
|
137
|
+
end
|
138
|
+
|
139
|
+
message.update_attributes!(attribute => true)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Mark message as restored
|
143
|
+
def restore_message(message)
|
144
|
+
current_user = self
|
145
|
+
|
146
|
+
case current_user
|
147
|
+
when message.to
|
148
|
+
attribute = :recipient_delete
|
149
|
+
when message.from
|
150
|
+
attribute = :sender_delete
|
151
|
+
else
|
152
|
+
raise "#{current_user} can't restore this message"
|
153
|
+
end
|
154
|
+
|
155
|
+
message.update_attributes!(attribute => false)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module ActsAsChattable
|
2
|
+
class Rails3
|
3
|
+
def initialize(subject)
|
4
|
+
@subject = subject
|
5
|
+
end
|
6
|
+
|
7
|
+
def default_scope(order_by)
|
8
|
+
@subject.send(:default_scope, order(order_by))
|
9
|
+
end
|
10
|
+
|
11
|
+
def method_missing(name, *args)
|
12
|
+
@subject.send(name, *args)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActsAsChattable
|
2
|
+
class Rails4
|
3
|
+
def initialize(subject)
|
4
|
+
@subject = subject
|
5
|
+
end
|
6
|
+
|
7
|
+
def default_scope(order_by)
|
8
|
+
@subject.default_scope { order(order_by) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def scoped
|
12
|
+
@subject.scope
|
13
|
+
end
|
14
|
+
|
15
|
+
def method_missing(name, *args)
|
16
|
+
@subject.send(name, *args)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'active_record/railtie'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
|
4
|
+
module ActsAsChattable
|
5
|
+
class Railtie < Rails::Railtie
|
6
|
+
if defined?(ActiveRecord::Base)
|
7
|
+
ActiveRecord::Base.send :include, ActsAsChattable::Model
|
8
|
+
end
|
9
|
+
|
10
|
+
if defined?(ActiveRecord::Relation)
|
11
|
+
ActiveRecord::Relation.send :include, ActsAsChattable::Relation
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ActsAsChattable
|
2
|
+
module Relation
|
3
|
+
attr_accessor :relation_context
|
4
|
+
|
5
|
+
def process(context = self.relation_context, &block)
|
6
|
+
self.each do |message|
|
7
|
+
block.call(message) if block_given?
|
8
|
+
context.delete_message(message) if message.removed
|
9
|
+
context.restore_message(message) if message.restored
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def conversations
|
14
|
+
map { |r| r.root.subtree.order("id desc").first }.uniq
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rails/generators/migration'
|
2
|
+
require 'rails/generators/active_record'
|
3
|
+
|
4
|
+
module ActsAsChattable
|
5
|
+
class MigrationGenerator < Rails::Generators::Base
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
|
8
|
+
namespace "acts_as_chattable:migration"
|
9
|
+
|
10
|
+
source_root File.join(File.dirname(__FILE__), 'templates')
|
11
|
+
|
12
|
+
def self.next_migration_number(dirname)
|
13
|
+
ActiveRecord::Generators::Base.next_migration_number(dirname)
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_migration_file
|
17
|
+
migration_template 'migration.rb', 'db/migrate/create_messages_table.rb' rescue nil
|
18
|
+
migration_template 'migration_permanent.rb', 'db/migrate/add_recipient_permanent_delete_and_sender_permanent_delete_to_messages.rb' rescue nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class CreateMessagesTable < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :messages do |t|
|
4
|
+
t.text :body
|
5
|
+
t.string :attachment
|
6
|
+
t.references :received_messageable, :polymorphic => true
|
7
|
+
t.references :sent_messageable, :polymorphic => true
|
8
|
+
t.boolean :opened, :default => false
|
9
|
+
t.boolean :recipient_delete, :default => false
|
10
|
+
t.boolean :sender_delete, :default => false
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
|
14
|
+
add_index :messages, [:sent_messageable_id, :received_messageable_id], :name => "acts_as_chattable_ids"
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.down
|
18
|
+
drop_table :messages
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class AddRecipientPermanentDeleteAndSenderPermanentDeleteToMessages < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :messages, :recipient_permanent_delete, :boolean, :default => false
|
4
|
+
add_column :messages, :sender_permanent_delete, :boolean, :default => false
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.down
|
8
|
+
remove_column :messages, :recipient_permanent_delete
|
9
|
+
remove_column :messages, :sender_permanent_delete
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,253 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "ActsAsChattable" do
|
4
|
+
before do
|
5
|
+
User.acts_as_chattable
|
6
|
+
@message = send_message
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "send messages" do
|
10
|
+
it "alice should have one message" do
|
11
|
+
@alice.messages.count.should == 1
|
12
|
+
end
|
13
|
+
|
14
|
+
it "alice should have one message from bob" do
|
15
|
+
@alice.messages.are_from(@bob).count.should == 1
|
16
|
+
end
|
17
|
+
|
18
|
+
it "bob should have one message" do
|
19
|
+
@bob.messages.count.should == 1
|
20
|
+
end
|
21
|
+
|
22
|
+
it "bob should have one message to alice in outbox" do
|
23
|
+
@bob.sent_messages.are_to(@alice).count.should == 1
|
24
|
+
end
|
25
|
+
|
26
|
+
it "bob should have one open message from alice" do
|
27
|
+
@alice.messages.are_from(@bob).process { |m| m.open }
|
28
|
+
@alice.messages.readed.count.should == 1
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "send messages with bang" do
|
33
|
+
it "should return message object" do
|
34
|
+
@alice.send_message!(@bob, :body => "body", :attachment => "test").should
|
35
|
+
be_kind_of ActsAsChattable::Message
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "inheritance models" do
|
40
|
+
it "men send message to alice" do
|
41
|
+
send_message(@men, @alice)
|
42
|
+
@men.sent_messages.size.should be_equal(1)
|
43
|
+
@alice.received_messages.size.should be_equal(2)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "messages method should receive all messages connected with user" do
|
47
|
+
send_message(@men, @alice)
|
48
|
+
@men.messages.size.should be_equal(1)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "men send message and receive from alice" do
|
52
|
+
send_message(@men, @alice)
|
53
|
+
send_message(@alice, @men)
|
54
|
+
|
55
|
+
@men.messages.size.should be_equal(2)
|
56
|
+
@men.sent_messages.size.should be_equal(1)
|
57
|
+
@men.received_messages.size.should be_equal(1)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "delete messages" do
|
62
|
+
|
63
|
+
it "bob should have one deleted message from alice" do
|
64
|
+
@bob.messages.process do |m|
|
65
|
+
m.delete
|
66
|
+
end
|
67
|
+
|
68
|
+
@bob.messages.each do |m|
|
69
|
+
m.recipient_delete.should == true
|
70
|
+
m.sender_delete.should == false
|
71
|
+
end
|
72
|
+
|
73
|
+
@bob.deleted_messages.count.should == 1
|
74
|
+
@bob.messages.count.should == 0
|
75
|
+
end
|
76
|
+
|
77
|
+
it "received_messages and sent_messages should work with .process method" do
|
78
|
+
@bob.sent_messages.count.should == 1
|
79
|
+
@alice.received_messages.count.should == 1
|
80
|
+
|
81
|
+
@bob.sent_messages.process { |m| m.delete }
|
82
|
+
@bob.sent_messages.count.should == 0
|
83
|
+
@alice.received_messages.count.should == 1
|
84
|
+
|
85
|
+
@alice.received_messages.process { |m| m.delete }
|
86
|
+
@alice.received_messages.count.should == 0
|
87
|
+
end
|
88
|
+
|
89
|
+
it "message should permanent delete" do
|
90
|
+
@alice.messages.process { |m| m.delete }
|
91
|
+
@alice.messages.count.should == 0
|
92
|
+
|
93
|
+
@alice.deleted_messages.count.should == 1
|
94
|
+
@alice.deleted_messages.process { |m| m.delete }
|
95
|
+
@alice.deleted_messages.count.should == 0
|
96
|
+
|
97
|
+
@message.reload
|
98
|
+
@message.recipient_permanent_delete.should == true
|
99
|
+
|
100
|
+
@bob.sent_messages.count.should == 1
|
101
|
+
end
|
102
|
+
|
103
|
+
it "pat should not able to delete message" do
|
104
|
+
lambda { @pat.delete_message(@message) }.should raise_error
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "restore message" do
|
109
|
+
it "alice should restore message" do
|
110
|
+
@alice.received_messages.process { |m| m.delete }
|
111
|
+
@alice.restore_message(@message.reload)
|
112
|
+
@alice.received_messages.count.should == 1
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should works with relation" do
|
116
|
+
@alice.received_messages.process { |m| m.delete }
|
117
|
+
@alice.received_messages.count.should == 0
|
118
|
+
@alice.deleted_messages.process { |m| m.restore }
|
119
|
+
@alice.received_messages.count.should == 1
|
120
|
+
end
|
121
|
+
|
122
|
+
it "pat should not able to restore message" do
|
123
|
+
lambda { @pat.restore_message(@message) }.should raise_error
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "read/unread feature" do
|
128
|
+
it "alice should have one unread message from bob" do
|
129
|
+
@alice.messages.are_from(@bob).unreaded.count.should == 1
|
130
|
+
@alice.messages.are_from(@bob).readed.count.should == 0
|
131
|
+
end
|
132
|
+
|
133
|
+
it "alice should able to read message from bob" do
|
134
|
+
@alice.messages.are_from(@bob).first.read
|
135
|
+
@alice.messages.are_from(@bob).unreaded.count.should == 0
|
136
|
+
end
|
137
|
+
|
138
|
+
it "alice should able to unread message from bob" do
|
139
|
+
@alice.messages.are_from(@bob).first.read
|
140
|
+
@alice.messages.are_from(@bob).first.unread
|
141
|
+
@alice.messages.are_from(@bob).unreaded.count.should == 1
|
142
|
+
end
|
143
|
+
|
144
|
+
it "alice should able to get datetime when he read bob message" do
|
145
|
+
@alice.messages.are_from(@bob).first.read
|
146
|
+
read_datetime = @alice.messages.are_from(@bob).first.updated_at
|
147
|
+
@alice.messages.are_from(@bob).reorder("updated_at asc").first.updated_at.should == read_datetime
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
it "finds proper message" do
|
152
|
+
@bob.messages.find(@message.id) == @message
|
153
|
+
end
|
154
|
+
|
155
|
+
it "message should have proper body" do
|
156
|
+
@bob.messages.count.should == 1
|
157
|
+
@bob.messages.first.body == "Body"
|
158
|
+
end
|
159
|
+
|
160
|
+
# describe "conversation" do
|
161
|
+
# it "bob send message to alice, and alice reply to bob message and show proper tree" do
|
162
|
+
# @reply_message = @alice.reply_to(@message, "Re: Topic", "Body")
|
163
|
+
|
164
|
+
# @reply_message.conversation.size.should == 2
|
165
|
+
# @reply_message.conversation.last.topic.should == "Topic"
|
166
|
+
# @reply_message.conversation.first.topic.should == "Re: Topic"
|
167
|
+
# end
|
168
|
+
|
169
|
+
# it "bob send message to alice, alice answer, and bob answer for alice answer" do
|
170
|
+
# @reply_message = @alice.reply_to(@message, "Re: Topic", "Body")
|
171
|
+
# @reply_reply_message = @bob.reply_to(@reply_message, "Re: Re: Topic", "Body")
|
172
|
+
|
173
|
+
# [@message, @reply_message, @reply_reply_message].each do |m|
|
174
|
+
# m.conversation.size.should == 3
|
175
|
+
# end
|
176
|
+
|
177
|
+
# @message.conversation.first.should == @reply_reply_message
|
178
|
+
# @reply_reply_message.conversation.first.should == @reply_reply_message
|
179
|
+
# end
|
180
|
+
# end
|
181
|
+
|
182
|
+
# describe "conversations" do
|
183
|
+
# before do
|
184
|
+
# @reply_message = @message.reply("Re: Topic", "Body")
|
185
|
+
# @reply_reply_message = @reply_message.reply("Re: Re: Topic", "Body")
|
186
|
+
# end
|
187
|
+
|
188
|
+
# it "bob send message to alice and alice reply" do
|
189
|
+
# @bob.messages.conversations.should == [@reply_reply_message]
|
190
|
+
# @reply_message.conversation.should == [@reply_reply_message, @reply_message, @message]
|
191
|
+
# end
|
192
|
+
|
193
|
+
# it "show conversations in proper order" do
|
194
|
+
# @sec_message = @bob.send_message(@alice, "Hi", "Alice!")
|
195
|
+
# @sec_reply = @sec_message.reply("Re: Hi", "Fine!")
|
196
|
+
# @bob.received_messages.conversations.map(&:id).should == [@sec_reply.id, @reply_reply_message.id]
|
197
|
+
# @sec_reply.conversation.to_a.should == [@sec_reply, @sec_message]
|
198
|
+
# end
|
199
|
+
# end
|
200
|
+
|
201
|
+
# describe "search text from messages" do
|
202
|
+
# before do
|
203
|
+
# @reply_message = @message.reply("Re: Topic", "Body : I am fine")
|
204
|
+
# @reply_reply_message = @reply_message.reply("Re: Re: Topic", "Fine too")
|
205
|
+
# end
|
206
|
+
|
207
|
+
# it "bob should be able to search text from messages" do
|
208
|
+
# recordset = @bob.messages.search("I am fine")
|
209
|
+
# recordset.count.should == 1
|
210
|
+
# recordset.should_not be_nil
|
211
|
+
# end
|
212
|
+
# end
|
213
|
+
|
214
|
+
# describe "send messages with hash" do
|
215
|
+
# it "send message with hash" do
|
216
|
+
# @message = @bob.send_message(@alice, {:body => "Body", :topic => "Topic"})
|
217
|
+
# @message.topic.should == "Topic"
|
218
|
+
# @message.body.should == "Body"
|
219
|
+
# end
|
220
|
+
# end
|
221
|
+
|
222
|
+
it "messages should return in right order :created_at" do
|
223
|
+
@message = send_message(@bob, @alice, "Example", "Example Body")
|
224
|
+
@alice.messages.last.body.should == "Body"
|
225
|
+
end
|
226
|
+
|
227
|
+
it "received_messages should return unloaded messages" do
|
228
|
+
@alice.received_messages.loaded?.should be_false
|
229
|
+
end
|
230
|
+
|
231
|
+
it "sent_messages should return unloaded messages" do
|
232
|
+
@bob.sent_messages.loaded?.should be_false
|
233
|
+
end
|
234
|
+
|
235
|
+
describe "send messages between two different models (the same id)" do
|
236
|
+
it "should have the same id" do
|
237
|
+
@alice.id.should be_equal(@admin.id)
|
238
|
+
end
|
239
|
+
|
240
|
+
it "bob send message to admin (different model) with the same id" do
|
241
|
+
@bob.send_message(@alice, "hello", "alice")
|
242
|
+
@alice.messages.are_to(@alice).size.should be_equal(2)
|
243
|
+
@alice.messages.are_to(@admin).size.should be_equal(0)
|
244
|
+
end
|
245
|
+
|
246
|
+
it "admin send message to bob" do
|
247
|
+
@admin.send_message(@bob, "hello", "bob")
|
248
|
+
@bob.messages.are_from(@admin).size.should be_equal(1)
|
249
|
+
@bob.messages.are_from(@alice).size.should be_equal(0)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
end
|