message_train 0.1.7 → 0.2.0

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