acts_as_chattable 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.
- 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
|