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
@@ -0,0 +1,295 @@
1
+ require 'rails_helper'
2
+
3
+ describe MessageTrain::ConversationsHelper do
4
+ include_context 'loaded site'
5
+ include ControllerMacros
6
+ helper MessageTrain::BoxesHelper
7
+
8
+ before do
9
+ login_user first_user
10
+ assign(:box_user, first_user)
11
+ end
12
+
13
+ describe '#conversation_senders' do
14
+ context 'when there is one sender' do
15
+ subject { helper.conversation_senders(sent_conversation) }
16
+ it { should eq 'First User' }
17
+ end
18
+ context 'when there is more than one sender' do
19
+ subject { helper.conversation_senders(long_conversation) }
20
+ it { should eq 'First User and Second User' }
21
+ end
22
+ end
23
+
24
+ describe '#conversation_class' do
25
+ context 'when it is unread' do
26
+ context 'in the inbox' do
27
+ subject { helper.conversation_class(first_user.box(:in), unread_conversation) }
28
+ it { should match /unread/ }
29
+ end
30
+ context 'in the ignored box' do
31
+ subject { helper.conversation_class(first_user.box(:ignored), unread_conversation) }
32
+ it { should match /hide/ }
33
+ end
34
+ end
35
+ context 'when it is read' do
36
+ subject { helper.conversation_class(first_user.box(:in), read_conversation) }
37
+ it { should match /read/ }
38
+ it { should_not match /unread/ }
39
+ end
40
+ context 'when it is a draft' do
41
+ subject { helper.conversation_class(first_user.box(:in), draft_conversation) }
42
+ it { should match /draft/ }
43
+ end
44
+ context 'when it is deleted' do
45
+ subject { helper.conversation_class(first_user.box(:in), deleted_conversation) }
46
+ it { should match /hide/ }
47
+ end
48
+ context 'when it is trashed' do
49
+ context 'in the inbox' do
50
+ subject { helper.conversation_class(first_user.box(:in), trashed_conversation) }
51
+ it { should match /hide/ }
52
+ end
53
+ context 'in the trash box' do
54
+ subject { helper.conversation_class(first_user.box(:trash), trashed_conversation) }
55
+ it { should_not match /hide/ }
56
+ end
57
+ end
58
+ context 'when it is not trashed' do
59
+ context 'in the inbox' do
60
+ subject { helper.conversation_class(first_user.box(:in), unread_conversation) }
61
+ it { should_not match /hide/ }
62
+ end
63
+ context 'in the trash box' do
64
+ subject { helper.conversation_class(first_user.box(:trash), unread_conversation) }
65
+ it { should match /hide/ }
66
+ end
67
+ end
68
+ context 'when it is ignored' do
69
+ context 'in the ignored box' do
70
+ subject { helper.conversation_class(first_user.box(:ignored), ignored_conversation) }
71
+ it { should_not match /hide/ }
72
+ end
73
+ context 'in the trash box' do
74
+ subject { helper.conversation_class(first_user.box(:trash), ignored_conversation) }
75
+ it { should match /hide/ }
76
+ end
77
+ end
78
+ end
79
+
80
+ describe '#conversation_trashed_toggle' do
81
+ describe 'in a user box' do
82
+ context 'when the conversation has untrashed messages' do
83
+ before do
84
+ assign(:box, first_user.box(:in))
85
+ end
86
+ subject { helper.conversation_trashed_toggle(unread_conversation) }
87
+ it { should have_tag(:a, with: {
88
+ 'rel' => 'nofollow',
89
+ 'title' => 'Mark as Trashed',
90
+ 'data-confirm' => 'Are you sure?',
91
+ 'data-method' => 'put',
92
+ 'data-remote' => 'true'
93
+ }) }
94
+ it { should have_tag(:span, with: { class: 'glyphicon-trash' }) }
95
+ end
96
+ context 'when the conversation is all trashed' do
97
+ before do
98
+ assign(:box, first_user.box(:trash))
99
+ end
100
+ subject { helper.conversation_trashed_toggle(trashed_conversation) }
101
+ it { should have_tag(:a, with: {
102
+ 'rel' => 'nofollow',
103
+ 'title' => 'Mark as Untrashed',
104
+ 'data-method' => 'put',
105
+ 'data-remote' => 'true'
106
+ }) }
107
+ it { should have_tag(:span, with: { class: 'glyphicon-inbox' }) }
108
+ end
109
+ end
110
+ describe 'in a collective box' do
111
+ context 'when the conversation has untrashed messages' do
112
+ before do
113
+ assign(:box, membered_group.box(:in, first_user))
114
+ end
115
+ subject { helper.conversation_trashed_toggle(membered_group_conversation) }
116
+ it { should have_tag(:a, with: {
117
+ 'rel' => 'nofollow',
118
+ 'title' => 'Mark as Trashed',
119
+ 'data-confirm' => 'Are you sure?',
120
+ 'data-method' => 'put',
121
+ 'data-remote' => 'true'
122
+ }) }
123
+ it { should have_tag(:span, with: { class: 'glyphicon-trash' }) }
124
+ end
125
+ context 'when the conversation is all trashed' do
126
+ before do
127
+ assign(:box, membered_group.box(:trash, first_user))
128
+ end
129
+ subject { helper.conversation_trashed_toggle(membered_group_trashed_conversation) }
130
+ it { should have_tag(:a, with: {
131
+ 'rel' => 'nofollow',
132
+ 'title' => 'Mark as Untrashed',
133
+ 'data-method' => 'put',
134
+ 'data-remote' => 'true'
135
+ }) }
136
+ it { should have_tag(:span, with: { class: 'glyphicon-inbox' }) }
137
+ end
138
+ end
139
+ end
140
+
141
+ describe '#conversation_read_toggle' do
142
+ describe 'in a user box' do
143
+ context 'when the conversation has unread messages' do
144
+ before do
145
+ assign(:box, first_user.box(:in))
146
+ end
147
+ subject { helper.conversation_read_toggle(unread_conversation) }
148
+ it { should have_tag(:a, with: {
149
+ 'rel' => 'nofollow',
150
+ 'title' => 'Mark as Read',
151
+ 'data-method' => 'put',
152
+ 'data-remote' => 'true'
153
+ }) }
154
+ it { should have_tag(:span, with: { class: 'glyphicon-eye-open' }) }
155
+ end
156
+ context 'when the conversation is all read' do
157
+ before do
158
+ assign(:box, first_user.box(:trash))
159
+ end
160
+ subject { helper.conversation_read_toggle(read_conversation) }
161
+ it { should have_tag(:a, with: {
162
+ 'rel' => 'nofollow',
163
+ 'title' => 'Mark as Unread',
164
+ 'data-method' => 'put',
165
+ 'data-remote' => 'true'
166
+ }) }
167
+ it { should have_tag(:span, with: { class: 'glyphicon-eye-close' }) }
168
+ end
169
+ end
170
+ describe 'in a collective box' do
171
+ context 'when the conversation has unread messages' do
172
+ before do
173
+ assign(:box, membered_group.box(:in, first_user))
174
+ end
175
+ subject { helper.conversation_read_toggle(membered_group_conversation) }
176
+ it { should have_tag(:a, with: {
177
+ 'rel' => 'nofollow',
178
+ 'title' => 'Mark as Read',
179
+ 'data-method' => 'put',
180
+ 'data-remote' => 'true'
181
+ }) }
182
+ it { should have_tag(:span, with: { class: 'glyphicon-eye-open' }) }
183
+ end
184
+ context 'when the conversation is all read' do
185
+ before do
186
+ assign(:box, membered_group.box(:trash, first_user))
187
+ end
188
+ subject { helper.conversation_read_toggle(membered_group_read_conversation) }
189
+ it { should have_tag(:a, with: {
190
+ 'rel' => 'nofollow',
191
+ 'title' => 'Mark as Unread',
192
+ 'data-method' => 'put',
193
+ 'data-remote' => 'true'
194
+ }) }
195
+ it { should have_tag(:span, with: { class: 'glyphicon-eye-close' }) }
196
+ end
197
+ end
198
+ end
199
+
200
+ describe '#conversation_ignored_toggle' do
201
+ describe 'in a user box' do
202
+ context 'when the conversation has unignored messages' do
203
+ before do
204
+ assign(:box, first_user.box(:in))
205
+ end
206
+ subject { helper.conversation_ignored_toggle(unread_conversation) }
207
+ it { should have_tag(:a, with: {
208
+ 'rel' => 'nofollow',
209
+ 'title' => 'Mark as Ignored',
210
+ 'data-confirm' => 'Are you sure?',
211
+ 'data-method' => 'delete',
212
+ 'data-remote' => 'true'
213
+ }) }
214
+ it { should have_tag(:span, with: { class: 'glyphicon-volume-off' }) }
215
+ end
216
+ context 'when the conversation is all ignored' do
217
+ before do
218
+ assign(:box, first_user.box(:trash))
219
+ end
220
+ subject { helper.conversation_ignored_toggle(ignored_conversation) }
221
+ it { should have_tag(:a, with: {
222
+ 'rel' => 'nofollow',
223
+ 'title' => 'Mark as Unignored',
224
+ 'data-method' => 'delete',
225
+ 'data-remote' => 'true'
226
+ }) }
227
+ it { should have_tag(:span, with: { class: 'glyphicon-volume-up' }) }
228
+ end
229
+ end
230
+ describe 'in a collective box' do
231
+ context 'when the conversation has unignored messages' do
232
+ before do
233
+ assign(:box, membered_group.box(:in, first_user))
234
+ end
235
+ subject { helper.conversation_ignored_toggle(membered_group_conversation) }
236
+ it { should have_tag(:a, with: {
237
+ 'rel' => 'nofollow',
238
+ 'title' => 'Mark as Ignored',
239
+ 'data-confirm' => 'Are you sure?',
240
+ 'data-method' => 'delete',
241
+ 'data-remote' => 'true'
242
+ }) }
243
+ it { should have_tag(:span, with: { class: 'glyphicon-volume-off' }) }
244
+ end
245
+ context 'when the conversation is all ignored' do
246
+ before do
247
+ assign(:box, membered_group.box(:trash, first_user))
248
+ end
249
+ subject { helper.conversation_ignored_toggle(membered_group_ignored_conversation) }
250
+ it { should have_tag(:a, with: {
251
+ 'rel' => 'nofollow',
252
+ 'title' => 'Mark as Unignored',
253
+ 'data-method' => 'delete',
254
+ 'data-remote' => 'true'
255
+ }) }
256
+ it { should have_tag(:span, with: { class: 'glyphicon-volume-up' }) }
257
+ end
258
+ end
259
+ end
260
+
261
+ describe '#conversation_deleted_toggle' do
262
+ describe 'in a user box' do
263
+ context 'when the conversation has undeleted messages' do
264
+ before do
265
+ assign(:box, first_user.box(:trash))
266
+ end
267
+ subject { helper.conversation_deleted_toggle(unread_conversation) }
268
+ it { should have_tag(:a, with: {
269
+ 'rel' => 'nofollow',
270
+ 'title' => 'Mark as Deleted',
271
+ 'data-confirm' => 'Delete forever? This cannot be undone.',
272
+ 'data-method' => 'put',
273
+ 'data-remote' => 'true'
274
+ }) }
275
+ it { should have_tag(:span, with: { class: 'glyphicon-remove' }) }
276
+ end
277
+ end
278
+ describe 'in a collective box' do
279
+ context 'when the conversation has undeleted messages' do
280
+ before do
281
+ assign(:box, membered_group.box(:trash, first_user))
282
+ end
283
+ subject { helper.conversation_deleted_toggle(membered_group_conversation) }
284
+ it { should have_tag(:a, with: {
285
+ 'rel' => 'nofollow',
286
+ 'title' => 'Mark as Deleted',
287
+ 'data-confirm' => 'Delete forever? This cannot be undone.',
288
+ 'data-method' => 'put',
289
+ 'data-remote' => 'true'
290
+ }) }
291
+ it { should have_tag(:span, with: { class: 'glyphicon-remove' }) }
292
+ end
293
+ end
294
+ end
295
+ end
@@ -0,0 +1,217 @@
1
+ require 'rails_helper'
2
+
3
+ describe MessageTrain::MessagesHelper do
4
+ include_context 'loaded site'
5
+ include ControllerMacros
6
+ helper MessageTrain::BoxesHelper
7
+
8
+ before do
9
+ login_user first_user
10
+ assign(:box_user, first_user)
11
+ end
12
+
13
+ describe '#messages_class' do
14
+ context 'when it is unread' do
15
+ subject { helper.message_class(first_user.box(:in), unread_message) }
16
+ it { should match /unread/ }
17
+ end
18
+ context 'when it is read' do
19
+ subject { helper.message_class(first_user.box(:in), read_message) }
20
+ it { should match /read/ }
21
+ it { should_not match /unread/ }
22
+ end
23
+ context 'when it is a draft' do
24
+ subject { helper.message_class(first_user.box(:in), draft_message) }
25
+ it { should match /draft/ }
26
+ end
27
+ context 'when it is trashed' do
28
+ context 'in the inbox' do
29
+ subject { helper.message_class(first_user.box(:in), trashed_message) }
30
+ it { should match /hide/ }
31
+ end
32
+ context 'in the trash box' do
33
+ subject { helper.message_class(first_user.box(:trash), trashed_message) }
34
+ it { should_not match /hide/ }
35
+ end
36
+ end
37
+ context 'when it is not trashed' do
38
+ context 'in the inbox' do
39
+ subject { helper.message_class(first_user.box(:in), unread_message) }
40
+ it { should_not match /hide/ }
41
+ end
42
+ context 'in the trash box' do
43
+ subject { helper.message_class(first_user.box(:trash), unread_message) }
44
+ it { should match /hide/ }
45
+ end
46
+ end
47
+ context 'when it is ignored' do
48
+ context 'in the trash box' do
49
+ subject { helper.message_class(first_user.box(:trash), ignored_message) }
50
+ it { should match /hide/ }
51
+ end
52
+ end
53
+ end
54
+
55
+ describe '#message_trashed_toggle' do
56
+ describe 'in a user box' do
57
+ context 'when the message is untrashed' do
58
+ before do
59
+ assign(:box, first_user.box(:in))
60
+ end
61
+ subject { helper.message_trashed_toggle(unread_message) }
62
+ it { should have_tag(:a, with: {
63
+ 'rel' => 'nofollow',
64
+ 'title' => 'Mark as Trashed',
65
+ 'data-confirm' => 'Are you sure?',
66
+ 'data-method' => 'put',
67
+ 'data-remote' => 'true'
68
+ }) }
69
+ it { should have_tag(:span, with: { class: 'glyphicon-trash' }) }
70
+ end
71
+ context 'when the message is trashed' do
72
+ before do
73
+ assign(:box, first_user.box(:trash))
74
+ end
75
+ subject { helper.message_trashed_toggle(trashed_message) }
76
+ it { should have_tag(:a, with: {
77
+ 'rel' => 'nofollow',
78
+ 'title' => 'Mark as Untrashed',
79
+ 'data-method' => 'put',
80
+ 'data-remote' => 'true'
81
+ }) }
82
+ it { should have_tag(:span, with: { class: 'glyphicon-inbox' }) }
83
+ end
84
+ end
85
+ describe 'in a collective box' do
86
+ context 'when the message is untrashed' do
87
+ before do
88
+ assign(:box, membered_group.box(:in, first_user))
89
+ end
90
+ subject { helper.message_trashed_toggle(membered_group_message) }
91
+ it { should have_tag(:a, with: {
92
+ 'rel' => 'nofollow',
93
+ 'title' => 'Mark as Trashed',
94
+ 'data-confirm' => 'Are you sure?',
95
+ 'data-method' => 'put',
96
+ 'data-remote' => 'true'
97
+ }) }
98
+ it { should have_tag(:span, with: { class: 'glyphicon-trash' }) }
99
+ end
100
+ context 'when the message is trashed' do
101
+ before do
102
+ assign(:box, membered_group.box(:trash, first_user))
103
+ end
104
+ subject { helper.message_trashed_toggle(membered_group_trashed_message) }
105
+ it { should have_tag(:a, with: {
106
+ 'rel' => 'nofollow',
107
+ 'title' => 'Mark as Untrashed',
108
+ 'data-method' => 'put',
109
+ 'data-remote' => 'true'
110
+ }) }
111
+ it { should have_tag(:span, with: { class: 'glyphicon-inbox' }) }
112
+ end
113
+ end
114
+ end
115
+
116
+ describe '#message_read_toggle' do
117
+ describe 'in a user box' do
118
+ context 'when the message is unread' do
119
+ before do
120
+ assign(:box, first_user.box(:in))
121
+ end
122
+ subject { helper.message_read_toggle(unread_message) }
123
+ it { should have_tag(:a, with: {
124
+ 'rel' => 'nofollow',
125
+ 'title' => 'Mark as Read',
126
+ 'data-method' => 'put',
127
+ 'data-remote' => 'true'
128
+ }) }
129
+ it { should have_tag(:span, with: { class: 'glyphicon-eye-open' }) }
130
+ end
131
+ context 'when the message is read' do
132
+ before do
133
+ assign(:box, first_user.box(:trash))
134
+ end
135
+ subject { helper.message_read_toggle(read_message) }
136
+ it { should have_tag(:a, with: {
137
+ 'rel' => 'nofollow',
138
+ 'title' => 'Mark as Unread',
139
+ 'data-method' => 'put',
140
+ 'data-remote' => 'true'
141
+ }) }
142
+ it { should have_tag(:span, with: { class: 'glyphicon-eye-close' }) }
143
+ end
144
+ end
145
+ describe 'in a collective box' do
146
+ context 'when the message is unread' do
147
+ before do
148
+ assign(:box, membered_group.box(:in, first_user))
149
+ end
150
+ subject { helper.message_read_toggle(membered_group_message) }
151
+ it { should have_tag(:a, with: {
152
+ 'rel' => 'nofollow',
153
+ 'title' => 'Mark as Read',
154
+ 'data-method' => 'put',
155
+ 'data-remote' => 'true'
156
+ }) }
157
+ it { should have_tag(:span, with: { class: 'glyphicon-eye-open' }) }
158
+ end
159
+ context 'when the message is read' do
160
+ before do
161
+ assign(:box, membered_group.box(:trash, first_user))
162
+ end
163
+ subject { helper.message_read_toggle(membered_group_read_message) }
164
+ it { should have_tag(:a, with: {
165
+ 'rel' => 'nofollow',
166
+ 'title' => 'Mark as Unread',
167
+ 'data-method' => 'put',
168
+ 'data-remote' => 'true'
169
+ }) }
170
+ it { should have_tag(:span, with: { class: 'glyphicon-eye-close' }) }
171
+ end
172
+ end
173
+ end
174
+
175
+ describe '#message_deleted_toggle' do
176
+ describe 'in a user box' do
177
+ context 'when the message is undeleted' do
178
+ before do
179
+ assign(:box, first_user.box(:trash))
180
+ end
181
+ subject { helper.message_deleted_toggle(unread_message) }
182
+ it { should have_tag(:a, with: {
183
+ 'rel' => 'nofollow',
184
+ 'title' => 'Mark as Deleted',
185
+ 'data-confirm' => 'Delete forever? This cannot be undone.',
186
+ 'data-method' => 'put',
187
+ 'data-remote' => 'true'
188
+ }) }
189
+ it { should have_tag(:span, with: { class: 'glyphicon-remove' }) }
190
+ end
191
+ end
192
+ describe 'in a collective box' do
193
+ context 'when the message is undeleted' do
194
+ before do
195
+ assign(:box, membered_group.box(:trash, first_user))
196
+ end
197
+ subject { helper.message_deleted_toggle(membered_group_message) }
198
+ it { should have_tag(:a, with: {
199
+ 'rel' => 'nofollow',
200
+ 'title' => 'Mark as Deleted',
201
+ 'data-confirm' => 'Delete forever? This cannot be undone.',
202
+ 'data-method' => 'put',
203
+ 'data-remote' => 'true'
204
+ }) }
205
+ it { should have_tag(:span, with: { class: 'glyphicon-remove' }) }
206
+ end
207
+ end
208
+ end
209
+
210
+ describe '#message_recipients' do
211
+ subject { helper.message_recipients(to_many_message) }
212
+ it { should match /^([^\,]+\,){2} and ([^\,]+)$/ }
213
+ it { should match /Second User/ }
214
+ it { should match /Third User/ }
215
+ it { should match /Fourth User/ }
216
+ end
217
+ end
@@ -12,10 +12,120 @@ RSpec.describe Group do
12
12
  describe 'Scopes and Methods from Message Train' do
13
13
  include_context 'loaded site'
14
14
 
15
+ describe '#slug_part' do
16
+ subject { membered_group.slug_part }
17
+ it { should eq 'membered-group' }
18
+ end
19
+
20
+ describe '#path_part' do
21
+ subject { membered_group.path_part }
22
+ it { should eq 'groups:membered-group' }
23
+ end
24
+
25
+ describe '#valid_senders' do
26
+ subject { membered_group.valid_senders }
27
+ it { should include second_user }
28
+ it { should_not include first_user }
29
+ end
30
+
31
+ describe '#allows_sending_by?' do
32
+ context 'when user is an owner' do
33
+ subject { membered_group.allows_sending_by?(second_user) }
34
+ it { should be true }
35
+ end
36
+ context 'when user is not an owner' do
37
+ subject { membered_group.allows_sending_by?(first_user) }
38
+ it { should be false }
39
+ end
40
+ end
41
+
42
+ describe '#valid_recipients' do
43
+ subject { membered_group.valid_recipients }
44
+ it { should_not include second_user }
45
+ it { should include first_user }
46
+ end
47
+
48
+ describe '#allows_receiving_by?' do
49
+ context 'when user is a member' do
50
+ subject { membered_group.allows_receiving_by?(first_user) }
51
+ it { should be true }
52
+ end
53
+ context 'when user is not a member' do
54
+ subject { membered_group.allows_receiving_by?(second_user) }
55
+ it { should be false }
56
+ end
57
+ context 'when no users exist' do
58
+ subject { empty_group.allows_receiving_by?(second_user) }
59
+ it { should be false }
60
+ end
61
+ end
62
+
63
+ describe '#self_collection' do
64
+ subject { membered_group.self_collection }
65
+ it { should be_a ActiveRecord::Relation }
66
+ it { should include membered_group }
67
+ it { should have_exactly(1).item }
68
+ end
69
+
15
70
  describe '#conversations' do
16
- subject { first_group.conversations(:in) }
71
+ subject { membered_group.conversations(:in, first_user) }
17
72
  its(:first) { should be_a MessageTrain::Conversation }
18
- its(:count) { should eq 1 }
73
+ its(:count) { should eq 4 }
74
+ end
75
+
76
+ describe '#boxes_for_participant' do
77
+ context 'when participant is a valid sender' do
78
+ subject { membered_group.boxes_for_participant(second_user).collect { |x| x.division } }
79
+ it { should_not include :in }
80
+ it { should include :sent }
81
+ it { should include :drafts }
82
+ it { should include :all }
83
+ it { should include :trash }
84
+ it { should_not include :ignored }
85
+ end
86
+ context 'when participant is a valid recipient' do
87
+ subject { membered_group.boxes_for_participant(first_user).collect { |x| x.division } }
88
+ it { should include :in }
89
+ it { should_not include :sent }
90
+ it { should_not include :drafts }
91
+ it { should include :all }
92
+ it { should include :trash }
93
+ it { should include :ignored }
94
+ end
95
+ end
96
+
97
+ describe '#all_conversations' do
98
+ context 'when participant is a valid sender' do
99
+ subject { membered_group.all_conversations(second_user) }
100
+ its(:first) { should be_a MessageTrain::Conversation }
101
+ it { should_not include unread_conversation }
102
+ it { should include membered_group_conversation }
103
+ it { should_not include membered_group_draft } # Because received_through not set on sender receipts
104
+ end
105
+ context 'when participant is a valid recipient' do
106
+ subject { membered_group.all_conversations(first_user) }
107
+ its(:first) { should be_a MessageTrain::Conversation }
108
+ it { should_not include unread_conversation }
109
+ it { should include membered_group_conversation }
110
+ it { should_not include membered_group_draft }
111
+ end
112
+ end
113
+
114
+ describe '#all_messages' do
115
+ context 'when participant is a valid sender' do
116
+ subject { membered_group.all_messages(second_user) }
117
+ its(:first) { should be_a MessageTrain::Message }
118
+ it { should_not include unread_message }
119
+ it { should include membered_group_message }
120
+ it { should_not include membered_group_draft.messages.first } # Because received_through not set on sender receipts
121
+ end
122
+ context 'when participant is a valid recipient' do
123
+ subject { membered_group.all_messages(first_user) }
124
+ its(:first) { should be_a MessageTrain::Message }
125
+ it { should_not include unread_message }
126
+ it { should include membered_group_message }
127
+ it { should_not include membered_group_draft.messages.first }
128
+ end
19
129
  end
20
130
 
21
131
  end