message_train 0.1.7 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/.simplecov +8 -0
  3. data/.travis.yml +7 -2
  4. data/Gemfile +3 -0
  5. data/README.rdoc +37 -1
  6. data/Rakefile +5 -6
  7. data/VERSION +1 -1
  8. data/app/assets/javascripts/message_train.js +33 -0
  9. data/app/assets/stylesheets/message_train.scss +26 -0
  10. data/app/controllers/concerns/message_train_support.rb +127 -0
  11. data/app/controllers/message_train/application_controller.rb +1 -60
  12. data/app/controllers/message_train/boxes_controller.rb +0 -4
  13. data/app/controllers/message_train/messages_controller.rb +12 -6
  14. data/app/controllers/message_train/participants_controller.rb +1 -1
  15. data/app/controllers/message_train/unsubscribes_controller.rb +59 -0
  16. data/app/helpers/message_train/application_helper.rb +26 -0
  17. data/app/helpers/message_train/attachments_helper.rb +19 -0
  18. data/app/helpers/message_train/boxes_helper.rb +16 -11
  19. data/app/helpers/message_train/collectives_helper.rb +48 -0
  20. data/app/helpers/message_train/conversations_helper.rb +24 -16
  21. data/app/helpers/message_train/messages_helper.rb +14 -12
  22. data/app/mailers/message_train/application_mailer.rb +8 -0
  23. data/app/mailers/message_train/previews/receipt_mailer_preview.rb +10 -0
  24. data/app/mailers/message_train/receipt_mailer.rb +17 -0
  25. data/app/models/message_train/attachment.rb +28 -10
  26. data/app/models/message_train/box.rb +114 -83
  27. data/app/models/message_train/conversation.rb +48 -39
  28. data/app/models/message_train/ignore.rb +2 -6
  29. data/app/models/message_train/message.rb +40 -24
  30. data/app/models/message_train/receipt.rb +20 -10
  31. data/app/models/message_train/unsubscribe.rb +7 -0
  32. data/app/views/layouts/mailer.html.haml +6 -0
  33. data/app/views/message_train/application/_attachment_fields.html.haml +7 -0
  34. data/app/views/message_train/application/_attachment_link.html.haml +4 -0
  35. data/app/views/message_train/application/_widget.html.haml +6 -0
  36. data/app/views/message_train/boxes/_dropdown_list.html.haml +1 -2
  37. data/app/views/message_train/boxes/_list_item.html.haml +2 -2
  38. data/app/views/message_train/boxes/_widget.html.haml +4 -1
  39. data/app/views/message_train/boxes/show.html.haml +12 -4
  40. data/app/views/message_train/collectives/_dropdown_list.html.haml +6 -0
  41. data/app/views/message_train/collectives/_list_item.html.haml +5 -0
  42. data/app/views/message_train/collectives/_widget.html.haml +7 -0
  43. data/app/views/message_train/conversations/_conversation.html.haml +22 -7
  44. data/app/views/message_train/conversations/_deleted_toggle.html.haml +1 -1
  45. data/app/views/message_train/conversations/_ignored_toggle.html.haml +3 -3
  46. data/app/views/message_train/conversations/_read_toggle.html.haml +3 -3
  47. data/app/views/message_train/conversations/_toggle.html.haml +4 -1
  48. data/app/views/message_train/conversations/_trashed_toggle.html.haml +3 -3
  49. data/app/views/message_train/conversations/show.html.haml +4 -3
  50. data/app/views/message_train/messages/_deleted_toggle.html.haml +1 -1
  51. data/app/views/message_train/messages/_form.html.haml +22 -7
  52. data/app/views/message_train/messages/_message.html.haml +14 -4
  53. data/app/views/message_train/messages/_read_toggle.html.haml +1 -1
  54. data/app/views/message_train/messages/_trashed_toggle.html.haml +1 -1
  55. data/app/views/message_train/messages/edit.html.haml +1 -1
  56. data/app/views/message_train/messages/new.html.haml +4 -1
  57. data/app/views/message_train/participants/_field.html.haml +1 -1
  58. data/app/views/message_train/participants/_prefilled_field.html.haml +4 -0
  59. data/app/views/message_train/receipt_mailer/notification_email.html.haml +13 -0
  60. data/app/views/message_train/unsubscribes/index.html.haml +10 -0
  61. data/config/environment.rb +1 -0
  62. data/config/locales/en.yml +49 -7
  63. data/config/routes.rb +10 -2
  64. data/db/migrate/20150901183458_add_received_through_to_message_train_receipts.rb +6 -0
  65. data/db/migrate/20151004184347_add_unique_index_to_receipts.rb +5 -0
  66. data/db/migrate/20151124000820_create_message_train_unsubscribes.rb +14 -0
  67. data/lib/generators/message_train/install/install_generator.rb +8 -2
  68. data/lib/generators/message_train/install/templates/initializer.rb +5 -1
  69. data/lib/message_train/configuration.rb +11 -1
  70. data/lib/message_train/engine.rb +1 -0
  71. data/lib/message_train/mixin.rb +206 -21
  72. data/message_train.gemspec +66 -13
  73. data/spec/controllers/message_train/boxes_controller_spec.rb +10 -3
  74. data/spec/controllers/message_train/concerns_spec.rb +40 -0
  75. data/spec/controllers/message_train/conversations_controller_spec.rb +3 -3
  76. data/spec/controllers/message_train/messages_controller_spec.rb +60 -27
  77. data/spec/controllers/message_train/participants_controller_spec.rb +41 -6
  78. data/spec/controllers/message_train/unsubscribes_controller_spec.rb +56 -0
  79. data/spec/dummy/app/assets/files/message_train/attachments/{1917-Boys_Race_Above-Wiki.jpg → image-sample.jpg} +0 -0
  80. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  81. data/spec/dummy/app/models/group.rb +16 -1
  82. data/spec/dummy/app/models/role.rb +22 -0
  83. data/spec/dummy/app/models/user.rb +1 -1
  84. data/spec/dummy/app/views/layouts/_top_navigation.html.haml +4 -2
  85. data/spec/dummy/app/views/layouts/application.html.haml +2 -3
  86. data/spec/dummy/app/views/pages/index.html.haml +4 -0
  87. data/spec/dummy/config/application.rb +6 -0
  88. data/spec/dummy/config/environments/development.rb +1 -0
  89. data/spec/dummy/config/environments/test.rb +1 -0
  90. data/spec/dummy/config/initializers/high_voltage.rb +3 -0
  91. data/spec/dummy/config/initializers/message_train.rb +6 -1
  92. data/spec/dummy/config/initializers/paperclip.rb +2 -2
  93. data/spec/dummy/config/routes.rb +2 -2
  94. data/spec/dummy/config/settings.yml +9 -0
  95. data/spec/dummy/db/migrate/{20150724142846_create_message_train_conversations.night_train.rb → 20150901183629_create_message_train_conversations.message_train.rb} +0 -0
  96. data/spec/dummy/db/migrate/{20150724142847_create_message_train_messages.night_train.rb → 20150901183630_create_message_train_messages.message_train.rb} +0 -0
  97. data/spec/dummy/db/migrate/{20150724142848_create_message_train_attachments.night_train.rb → 20150901183631_create_message_train_attachments.message_train.rb} +0 -0
  98. data/spec/dummy/db/migrate/{20150724142849_create_message_train_receipts.night_train.rb → 20150901183632_create_message_train_receipts.message_train.rb} +0 -0
  99. data/spec/dummy/db/migrate/{20150724142850_create_message_train_ignores.night_train.rb → 20150901183633_create_message_train_ignores.message_train.rb} +0 -0
  100. data/spec/dummy/db/migrate/20150901183634_add_received_through_to_message_train_receipts.message_train.rb +7 -0
  101. data/spec/dummy/db/migrate/20151004184519_add_unique_index_to_receipts.message_train.rb +6 -0
  102. data/spec/dummy/db/migrate/20151124001417_create_message_train_unsubscribes.message_train.rb +15 -0
  103. data/spec/dummy/db/schema.rb +24 -7
  104. data/spec/dummy/db/seeds/conversations.seeds.rb +92 -3
  105. data/spec/dummy/db/seeds/groups.seeds.rb +27 -0
  106. data/spec/dummy/db/seeds/test/attachments.seeds.rb +4 -0
  107. data/spec/dummy/db/seeds/unsubscribes.seeds.rb +12 -0
  108. data/spec/dummy/db/seeds/users.seeds.rb +27 -0
  109. data/spec/dummy/db/test.sqlite3 +0 -0
  110. data/spec/factories/group.rb +4 -4
  111. data/spec/factories/message.rb +10 -3
  112. data/spec/features/boxes_spec.rb +160 -33
  113. data/spec/features/conversations_spec.rb +11 -4
  114. data/spec/features/messages_spec.rb +20 -6
  115. data/spec/features/unsubscribes_spec.rb +38 -0
  116. data/spec/helpers/message_train/application_helper_spec.rb +60 -0
  117. data/spec/helpers/message_train/attachment_helper_spec.rb +35 -0
  118. data/spec/helpers/message_train/boxes_helper_spec.rb +11 -5
  119. data/spec/helpers/message_train/collectives_helper_spec.rb +76 -0
  120. data/spec/helpers/message_train/conversations_helper_spec.rb +295 -0
  121. data/spec/helpers/message_train/messages_helper_spec.rb +217 -0
  122. data/spec/models/group_spec.rb +112 -2
  123. data/spec/models/message_train/attachment_spec.rb +44 -1
  124. data/spec/models/message_train/box_spec.rb +306 -51
  125. data/spec/models/message_train/conversation_spec.rb +84 -6
  126. data/spec/models/message_train/ignore_spec.rb +0 -4
  127. data/spec/models/message_train/message_spec.rb +49 -12
  128. data/spec/models/message_train/receipt_spec.rb +44 -8
  129. data/spec/models/message_train/unsubscribe_spec.rb +16 -0
  130. data/spec/models/role_spec.rb +125 -0
  131. data/spec/models/user_spec.rb +155 -26
  132. data/spec/rails_helper.rb +8 -1
  133. data/spec/support/attachments.rb +4 -0
  134. data/spec/support/controller_behaviors.rb +28 -0
  135. data/spec/support/conversations.rb +13 -0
  136. data/spec/support/groups.rb +3 -0
  137. data/spec/support/loaded_site.rb +3 -0
  138. data/spec/support/messages.rb +23 -0
  139. data/spec/support/roles.rb +4 -0
  140. data/spec/support/users.rb +6 -0
  141. data/spec/support/wysihtml5_helper.rb +8 -0
  142. metadata +99 -12
  143. data/spec/dummy/app/assets/files/message_train/attachments/Haie_rci.svg +0 -1714
  144. data/spec/dummy/public/capybara.html +0 -193
@@ -2,11 +2,54 @@ require 'rails_helper'
2
2
 
3
3
  module MessageTrain
4
4
  RSpec.describe Attachment do
5
+ include_context 'loaded site'
6
+
5
7
  describe 'Model' do
6
8
  it { should belong_to :message }
9
+ it { should have_attached_file :attachment }
10
+ it { should validate_attachment_presence :attachment }
11
+ it { should validate_attachment_content_type(:attachment).allowing(
12
+ 'application/pdf',
13
+ 'application/vnd.ms-excel',
14
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
15
+ 'application/msword',
16
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
17
+ 'application/rtf',
18
+ 'text/plain',
19
+ 'image/bmp',
20
+ 'image/gif',
21
+ 'image/jpeg',
22
+ 'image/pjpeg',
23
+ 'image/png',
24
+ 'image/x-png',
25
+ 'application/bmp',
26
+ 'application/gif',
27
+ 'application/jpeg',
28
+ 'application/pjpeg',
29
+ 'application/png',
30
+ 'application/x-png',
31
+ 'x-application/bmp',
32
+ 'x-application/gif',
33
+ 'x-application/jpeg',
34
+ 'x-application/pjpeg',
35
+ 'x-application/png',
36
+ 'x-application/x-png'
37
+ ).rejecting(
38
+ 'image/tiff',
39
+ 'image/svg'
40
+ ) }
7
41
  end
8
42
  describe 'Scopes and Methods' do
9
-
43
+ describe '#image?' do
44
+ context 'when it is an image' do
45
+ subject { image_attachment.image? }
46
+ it { should eq true }
47
+ end
48
+ context 'when it is not an image' do
49
+ subject { pdf_attachment.image? }
50
+ it { should eq false }
51
+ end
52
+ end
10
53
  end
11
54
  end
12
55
  end
@@ -2,19 +2,26 @@ require 'rails_helper'
2
2
 
3
3
  module MessageTrain
4
4
  RSpec.describe Box do
5
- describe 'Model' do
5
+ include_context 'loaded site'
6
+ let(:user_in_box) { first_user.box(:in) }
7
+ let(:user_sent_box) { first_user.box(:sent) }
8
+ let(:user_trash_box) { first_user.box(:trash) }
9
+ let(:user_all_box) { first_user.box(:all) }
10
+ let(:user_drafts_box) { first_user.box(:drafts) }
11
+ let(:user_ignored_box) { first_user.box(:ignored) }
12
+ let(:owned_group_box) { first_user.collective_boxes[:groups].find{ |x| x.parent.slug == 'first-group' } }
13
+ let(:membered_group_box) { first_user.collective_boxes[:groups].find{ |x| x.parent.slug == 'membered-group' } }
6
14
 
7
- end
8
15
  describe 'Scopes and Methods' do
9
- include_context 'loaded site'
10
16
 
11
17
  describe '#unread_count' do
12
- subject { first_user.box.unread_count }
18
+ subject { user_in_box.unread_count }
13
19
  it { should be >= 2 }
14
20
  end
21
+
15
22
  describe '#conversations' do
16
23
  context 'with division as :in' do
17
- subject { first_user.box.conversations }
24
+ subject { user_in_box.conversations }
18
25
  it { should_not include sent_conversation }
19
26
  it { should include unread_conversation }
20
27
  it { should include read_conversation }
@@ -24,7 +31,7 @@ module MessageTrain
24
31
  it { should_not include draft_conversation }
25
32
  end
26
33
  context 'with division as :sent' do
27
- subject { first_user.box(:sent).conversations }
34
+ subject { user_sent_box.conversations }
28
35
  it { should include sent_conversation }
29
36
  it { should_not include unread_conversation }
30
37
  it { should_not include read_conversation }
@@ -34,7 +41,7 @@ module MessageTrain
34
41
  it { should_not include draft_conversation }
35
42
  end
36
43
  context 'with division as :trash' do
37
- subject { first_user.box(:trash).conversations }
44
+ subject { user_trash_box.conversations }
38
45
  it { should_not include sent_conversation }
39
46
  it { should_not include unread_conversation }
40
47
  it { should_not include read_conversation }
@@ -44,7 +51,7 @@ module MessageTrain
44
51
  it { should_not include draft_conversation }
45
52
  end
46
53
  context 'with division as :drafts' do
47
- subject { first_user.box(:drafts).conversations }
54
+ subject { user_drafts_box.conversations }
48
55
  it { should_not include sent_conversation }
49
56
  it { should_not include trashed_conversation }
50
57
  it { should_not include read_conversation }
@@ -54,7 +61,7 @@ module MessageTrain
54
61
  it { should include draft_conversation }
55
62
  end
56
63
  context 'with unread set to true' do
57
- subject { first_user.box.conversations(unread: true) }
64
+ subject { user_in_box.conversations(unread: true) }
58
65
  it { should_not include sent_conversation }
59
66
  it { should include unread_conversation }
60
67
  it { should_not include read_conversation }
@@ -64,13 +71,105 @@ module MessageTrain
64
71
  it { should_not include draft_conversation }
65
72
  end
66
73
  end
74
+
75
+ describe '#find_conversation' do
76
+ subject { user_in_box.find_conversation(unread_conversation.id) }
77
+ it { should eq unread_conversation }
78
+ end
79
+
80
+ describe '#find_message' do
81
+ subject { user_in_box.find_message(unread_message.id) }
82
+ it { should eq unread_message }
83
+ end
84
+
85
+ describe '#new_message' do
86
+ describe 'when no conversation id is set' do
87
+ subject { user_in_box.new_message }
88
+ it { should be_a_new MessageTrain::Message }
89
+ end
90
+ describe 'when a conversation id is set' do
91
+ let(:user_hash) { { 'users' => 'second-user' } }
92
+ subject { user_in_box.new_message(conversation_id: unread_conversation.id) }
93
+ it { should be_a_new MessageTrain::Message }
94
+ its(:recipients_to_save) { should eq user_hash }
95
+ its(:subject) { should eq 'Re: Unread Conversation' }
96
+ its(:body) { should match /<blockquote>.*<\/blockquote>.*<p>&nbsp;<\/p>/ }
97
+ end
98
+ end
99
+
100
+ describe '#send_message' do
101
+ describe 'to a singular recipient' do
102
+ let(:message) { {recipients_to_save: {'users' => 'second-user'}, subject: 'Message to send', body: '...'} }
103
+ subject { user_in_box.send_message(message) }
104
+ it { should be_a MessageTrain::Message }
105
+ end
106
+ describe 'to a collective recipient' do
107
+ describe 'when recipient does not accept from sender' do
108
+ context 'message status' do
109
+ let(:message) { {recipients_to_save: {'groups' => 'membered-group'}, subject: 'Message to send', body: '...'} }
110
+ subject { membered_group_box.send_message(message) }
111
+ it { should be false }
112
+ end
113
+ context 'box status' do
114
+ let(:message) { {recipients_to_save: {'groups' => 'membered-group'}, subject: 'Message to send', body: '...'} }
115
+ before do
116
+ membered_group_box.send_message(message)
117
+ end
118
+ subject { membered_group_box.errors.all.find { |x| x[:css_id] == 'message_train_message' } }
119
+ its([:message]) { should eq 'Invalid sender for Group 2' }
120
+ end
121
+ end
122
+ describe 'when recipient accepts from sender' do
123
+ let(:message) { {recipients_to_save: {'groups' => 'first-group'}, subject: 'Message to send', body: '...'} }
124
+ subject { owned_group_box.send_message(message) }
125
+ it { should be_a MessageTrain::Message }
126
+ end
127
+ end
128
+ end
129
+
130
+ describe '#update_message' do
131
+ describe 'to a singular recipient' do
132
+ let(:message) { {recipients_to_save: {'users' => 'second-user'}, subject: 'Message to send', body: '...', draft: false } }
133
+ subject { user_in_box.update_message(draft_message, message) }
134
+ it { should be_a MessageTrain::Message }
135
+ end
136
+ describe 'to a collective recipient' do
137
+ describe 'when recipient does not accept from sender' do
138
+ context 'message status' do
139
+ let(:message) { {recipients_to_save: {'groups' => 'membered-group'}, subject: 'Message to send', body: '...', draft: false } }
140
+ subject { membered_group_box.update_message(owned_group_draft.messages.first, message) }
141
+ it { should be false }
142
+ end
143
+ context 'box status' do
144
+ let(:message) { {recipients_to_save: {'groups' => 'membered-group'}, subject: 'Message to send', body: '...', draft: false } }
145
+ let(:owned_group_draft_id) { owned_group_draft.messages.first.id }
146
+ before do
147
+ membered_group_box.update_message(owned_group_draft.messages.first, message)
148
+ end
149
+ subject { membered_group_box.errors.all.find { |x| x[:css_id] == "message_train_message_#{owned_group_draft_id}" } }
150
+ its([:message]) { should eq "Access to Message #{owned_group_draft_id} denied" }
151
+ end
152
+ end
153
+ describe 'when recipient accepts from sender' do
154
+ let(:message) { {recipients_to_save: {'groups' => 'first-group'}, subject: 'Message to send', body: '...', draft: false } }
155
+ subject { owned_group_box.update_message(owned_group_draft.messages.first, message) }
156
+ it { should be_a MessageTrain::Message }
157
+ end
158
+ end
159
+ end
160
+
67
161
  describe '#ignore' do
68
- context 'when authorized' do
162
+ context 'when not present' do
163
+ it 'raises an ActiveRecord::RecordNotFound error' do
164
+ expect {last_user.box.ignore(99999999)}.to raise_error(ActiveRecord::RecordNotFound, /Couldn't find MessageTrain::Conversation with 'id'=99999999/)
165
+ end
166
+ end
167
+ context 'when bad type' do
69
168
  before do
70
- first_user.box.ignore(read_conversation)
169
+ last_user.box.ignore(first_user)
71
170
  end
72
- subject { read_conversation.is_ignored?(first_user) }
73
- it { should be true}
171
+ subject { last_user.box.errors.all.first[:message] }
172
+ it { should match /Cannot ignore User/ }
74
173
  end
75
174
  context 'when not authorized' do
76
175
  before do
@@ -79,14 +178,26 @@ module MessageTrain
79
178
  subject { last_user.box.errors.all.first[:message] }
80
179
  it { should match /Access to Conversation ([0-9]+) denied/ }
81
180
  end
181
+ context 'when authorized' do
182
+ before do
183
+ user_in_box.ignore(read_conversation)
184
+ end
185
+ subject { read_conversation.is_ignored?(first_user) }
186
+ it { should be true}
187
+ end
82
188
  end
83
189
  describe '#unignore' do
84
- context 'when authorized' do
190
+ context 'when not present' do
191
+ it 'raises an ActiveRecord::RecordNotFound error' do
192
+ expect {last_user.box.unignore(99999999)}.to raise_error(ActiveRecord::RecordNotFound, /Couldn't find MessageTrain::Conversation with 'id'=99999999/)
193
+ end
194
+ end
195
+ context 'when bad type' do
85
196
  before do
86
- first_user.box.unignore(ignored_conversation)
197
+ last_user.box.unignore(first_user)
87
198
  end
88
- subject { ignored_conversation.is_ignored?(first_user) }
89
- it { should be false }
199
+ subject { last_user.box.errors.all.first[:message] }
200
+ it { should match /Cannot unignore User/ }
90
201
  end
91
202
  context 'when not authorized' do
92
203
  before do
@@ -95,40 +206,114 @@ module MessageTrain
95
206
  subject { last_user.box.errors.all.first[:message] }
96
207
  it { should match /Access to Conversation ([0-9]+) denied/ }
97
208
  end
209
+ context 'when authorized' do
210
+ before do
211
+ user_in_box.unignore(ignored_conversation)
212
+ end
213
+ subject { ignored_conversation.is_ignored?(first_user) }
214
+ it { should be false }
215
+ end
98
216
  end
99
217
  describe '#title' do
100
218
  context 'with division set to :in' do
101
- subject { first_user.box.title }
219
+ subject { user_in_box.title }
102
220
  it { should eq 'Inbox' }
103
221
  end
104
222
  context 'with division set to :sent' do
105
- subject { first_user.box(:sent).title }
106
- it { should eq 'Sent Messages' }
223
+ subject { user_sent_box.title }
224
+ it { should eq 'Sent' }
107
225
  end
108
226
  context 'with division set to :all' do
109
- subject { first_user.box(:all).title }
110
- it { should eq 'All Messages' }
227
+ subject { user_all_box.title }
228
+ it { should eq 'All' }
111
229
  end
112
230
  context 'with division set to :drafts' do
113
- subject { first_user.box(:drafts).title }
231
+ subject { user_drafts_box.title }
114
232
  it { should eq 'Drafts' }
115
233
  end
116
234
  context 'with division set to :trash' do
117
- subject { first_user.box(:trash).title }
235
+ subject { user_trash_box.title }
118
236
  it { should eq 'Trash' }
119
237
  end
238
+ context 'with division set to :ignored' do
239
+ subject { user_ignored_box.title }
240
+ it { should eq 'Ignored' }
241
+ end
120
242
  end
243
+
121
244
  describe '#mark' do
122
- before do
123
- first_user.box.mark('unread', conversations: [read_conversation.id.to_s])
245
+ context 'when not present' do
246
+ it 'raises an ActiveRecord::RecordNotFound error' do
247
+ expect {last_user.box.mark('read', conversations: ['99999999'])}.to raise_error(ActiveRecord::RecordNotFound, /Couldn't find MessageTrain::Conversation/)
248
+ end
249
+ end
250
+ context 'when bad type' do
251
+ before do
252
+ last_user.box.mark('read', users: [first_user.id.to_s])
253
+ end
254
+ subject { last_user.box.errors.all.first[:message] }
255
+ it { should match /Cannot mark users/ }
256
+ end
257
+ context 'when bad object' do
258
+ describe 'given singular box' do
259
+ before do
260
+ last_user.box.mark('read', conversations: Time.now)
261
+ end
262
+ subject { last_user.box.errors.all.first[:message] }
263
+ it { should match /Cannot mark with Time/ }
264
+ end
265
+ describe 'given collective box' do
266
+ # This test is mostly here to test the error handling for collective boxes, not so much the mark method
267
+ before do
268
+ first_group.box(:in, first_user).mark('read', conversations: Time.now)
269
+ end
270
+ subject { first_group.box(:in, first_user).errors.all }
271
+ it { should eq [{ css_id: "box", path: "/collectives/groups:first-group/box/in", message: "Cannot mark with Time"}] }
272
+ end
273
+ end
274
+ context 'when not authorized' do
275
+ before do
276
+ last_user.box.mark('unread', conversations: read_conversation)
277
+ end
278
+ subject { last_user.box.errors.all.first[:message] }
279
+ it { should match /Access to Conversation ([0-9]+) denied/ }
280
+ end
281
+ context 'when authorized' do
282
+ before do
283
+ user_in_box.mark('unread', conversations: [read_conversation.id.to_s])
284
+ end
285
+ subject { read_conversation.includes_read_for?(first_user) }
286
+ it { should be false }
287
+ end
288
+ end
289
+
290
+ describe '#message' do
291
+ describe 'when there are errors' do
292
+ let(:message) { {recipients_to_save: {'users' => 'second-user'}, subject: ''} }
293
+ before do
294
+ first_user.box.send_message(message)
295
+ end
296
+ subject { first_user.box.message }
297
+ it { should eq "Subject can't be blank" }
298
+ end
299
+ describe 'when there are results' do
300
+ let(:message) { {recipients_to_save: {'users' => 'second-user'}, subject: 'Valid'} }
301
+ before do
302
+ first_user.box.send_message(message)
303
+ end
304
+ subject { first_user.box.message }
305
+ it { should eq "Message sent." }
306
+ end
307
+ describe 'when there is nothing to do' do
308
+ subject { first_user.box.message }
309
+ it { should eq 'Nothing to do'}
124
310
  end
125
- subject { read_conversation.includes_read_for?(first_user) }
126
- it { should be false }
127
311
  end
128
- describe '.send_message' do
312
+
313
+ describe '#send_message' do
129
314
  context 'when message is valid' do
130
315
  let(:valid_attributes) { { recipients_to_save: {'users' => 'second-user, third-user'}, subject: 'Test Message', body: 'This is the content.' } }
131
- subject { first_user.box.send_message(valid_attributes) }
316
+ subject { user_in_box.send_message(valid_attributes) }
132
317
  it { should be_a MessageTrain::Message }
133
318
  its(:new_record?) { should be false }
134
319
  its('errors.full_messages.to_sentence') { should eq '' }
@@ -138,28 +323,44 @@ module MessageTrain
138
323
  end
139
324
  context 'when message is invalid' do
140
325
  let(:invalid_attributes) { { recipients_to_save: {'users' => 'second-user, third-user'}, subject: nil, body: 'This is the content.' } }
141
- subject { first_user.box.send_message(invalid_attributes) }
326
+ subject { user_in_box.send_message(invalid_attributes) }
142
327
  it { should be_a_new MessageTrain::Message }
143
328
  its('errors.full_messages.to_sentence') { should eq "Subject can't be blank" }
144
329
  its(:recipients) { should be_empty }
145
330
  end
146
331
  end
147
- describe '.update_message' do
148
- let(:draft_message) { draft_conversation.messages.first }
149
- context 'when message is valid' do
150
- let(:valid_attributes) { {
151
- recipients_to_save: {'users' => 'second-user, third-user'},
152
- subject: 'Test Message',
153
- body: 'This is the content.',
154
- draft: false
155
- } }
156
- subject { first_user.box.update_message(draft_message, valid_attributes) }
157
- it { should be_a MessageTrain::Message }
158
- its('errors.full_messages.to_sentence') { should eq '' }
159
- its(:recipients) { should include second_user }
160
- its(:recipients) { should include third_user }
161
- its(:subject) { should eq 'Test Message' }
162
- its(:draft) { should be false }
332
+
333
+ describe '#update_message' do
334
+ describe 'when message is valid' do
335
+ context 'and still a draft' do
336
+ let(:valid_attributes) { {
337
+ recipients_to_save: {'users' => 'second-user, third-user'},
338
+ subject: 'Test Message',
339
+ body: 'This is the content.',
340
+ draft: true
341
+ } }
342
+ subject { user_in_box.update_message(draft_message, valid_attributes) }
343
+ it { should be_a MessageTrain::Message }
344
+ its('errors.full_messages.to_sentence') { should eq '' }
345
+ its(:recipients) { should be_empty }
346
+ its(:subject) { should eq 'Test Message' }
347
+ its(:draft) { should be true }
348
+ end
349
+ context 'and no longer a draft' do
350
+ let(:valid_attributes) { {
351
+ recipients_to_save: {'users' => 'second-user, third-user'},
352
+ subject: 'Test Message',
353
+ body: 'This is the content.',
354
+ draft: false
355
+ } }
356
+ subject { user_in_box.update_message(draft_message, valid_attributes) }
357
+ it { should be_a MessageTrain::Message }
358
+ its('errors.full_messages.to_sentence') { should eq '' }
359
+ its(:recipients) { should include second_user }
360
+ its(:recipients) { should include third_user }
361
+ its(:subject) { should eq 'Test Message' }
362
+ its(:draft) { should be false }
363
+ end
163
364
  end
164
365
  context 'when message is invalid' do
165
366
  let(:invalid_attributes) { {
@@ -168,28 +369,82 @@ module MessageTrain
168
369
  body: 'This is the content.',
169
370
  draft: false
170
371
  } }
171
- subject { first_user.box.update_message(draft_message, invalid_attributes) }
372
+ subject { user_in_box.update_message(draft_message, invalid_attributes) }
172
373
  it { should be_a MessageTrain::Message }
173
374
  its('errors.full_messages.to_sentence') { should eq "Subject can't be blank" }
174
375
  its(:recipients) { should be_empty }
175
376
  end
176
377
  end
177
378
 
178
- describe '.new_message' do
379
+ describe '#new_message' do
179
380
  context 'when conversation is set' do
180
381
  let(:expected_recipients) { { 'users' => 'second-user' } }
181
- subject { first_user.box.new_message(conversation_id: unread_conversation.id) }
382
+ subject { user_in_box.new_message(conversation_id: unread_conversation.id) }
182
383
  it { should be_a_new MessageTrain::Message }
183
384
  its(:subject) { should eq 'Re: Unread Conversation' }
184
385
  its(:recipients_to_save) { should eq expected_recipients }
185
386
  end
186
387
  context 'when conversation is not set' do
187
- subject { first_user.box.new_message }
388
+ subject { user_in_box.new_message }
188
389
  it { should be_a_new MessageTrain::Message }
189
390
  its(:subject) { should eq nil }
190
391
  its(:recipients_to_save) { should be_empty }
191
392
  end
192
393
  end
394
+
395
+ describe '#authorize' do
396
+ describe 'given participant is the same as parent' do
397
+ describe 'when bad type' do
398
+ before do
399
+ first_user.box.authorize(second_user)
400
+ end
401
+ subject { first_user.box.errors.all }
402
+ it { should eq [{ css_id: 'user', path: nil, message: 'Cannot authorize User'}] }
403
+ end
404
+ describe 'when conversation' do
405
+ describe 'is authorized' do
406
+ subject { first_user.box.authorize(unread_conversation) }
407
+ it { should be true }
408
+ end
409
+ describe 'is not authorized' do
410
+ subject { first_user.box.authorize(someone_elses_conversation) }
411
+ it { should be false }
412
+ end
413
+ end
414
+ describe 'when message' do
415
+ describe 'is authorized' do
416
+ subject { first_user.box.authorize(unread_message) }
417
+ it { should be true }
418
+ end
419
+ describe 'is not authorized' do
420
+ subject { first_user.box.authorize(someone_elses_message) }
421
+ it { should be false }
422
+ end
423
+ end
424
+ end
425
+ describe 'given parent differs from participant' do
426
+ # This is really here to test the error handling for this case.
427
+ describe 'when message' do
428
+ describe 'is authorized' do
429
+ subject { first_group.box(:in, first_user).authorize(group_message) }
430
+ it { should be true }
431
+ end
432
+ describe 'is not authorized' do
433
+ describe 'result' do
434
+ subject { membered_group.box(:in, third_user).authorize(membered_group_message) }
435
+ it { should be false }
436
+ end
437
+ describe 'box status' do
438
+ before do
439
+ membered_group.box(:in, third_user).authorize(membered_group_message)
440
+ end
441
+ subject { membered_group.box(:in, third_user).errors.all }
442
+ it { should eq [{ css_id: "message_train_message_#{membered_group_message.id}", path: "/collectives/groups:membered-group/box/in/messages/#{membered_group_message.id}", message: "Access to Message #{membered_group_message.id} denied"}] }
443
+ end
444
+ end
445
+ end
446
+ end
447
+ end
193
448
  end
194
449
  end
195
450
  end