message_train 0.7.6 → 1.0.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.
- checksums.yaml +5 -5
- data/.gitattributes +1 -0
- data/.github/workflows/ci.yml +86 -0
- data/.gitignore +64 -0
- data/.rubocop.yml +9 -0
- data/.rubocop_todo.yml +854 -2
- data/.ruby-version +1 -1
- data/.simplecov +2 -4
- data/CHANGELOG.md +128 -0
- data/CLAUDE.md +5 -0
- data/Gemfile +29 -31
- data/LICENSE.txt +1 -1
- data/README.md +106 -35
- data/Rakefile +4 -18
- data/app/assets/stylesheets/message_train.scss +405 -67
- data/app/controllers/concerns/message_train_support.rb +2 -2
- data/app/controllers/message_train/boxes_controller.rb +4 -2
- data/app/controllers/message_train/conversations_controller.rb +1 -0
- data/app/helpers/message_train/application_helper.rb +68 -0
- data/app/helpers/message_train/attachments_helper.rb +7 -4
- data/app/helpers/message_train/conversations_helper.rb +16 -16
- data/app/helpers/message_train/messages_helper.rb +23 -10
- data/app/javascript/controllers/message_train/bulk_actions_controller.js +36 -0
- data/app/javascript/controllers/message_train/lightbox_controller.js +25 -0
- data/app/javascript/controllers/message_train/nested_form_controller.js +36 -0
- data/app/javascript/controllers/message_train/recipient_autocomplete_controller.js +31 -0
- data/app/mailers/message_train/previews/receipt_mailer_preview.rb +7 -5
- data/app/models/message_train/attachment.rb +54 -42
- data/app/models/message_train/box.rb +2 -2
- data/app/models/message_train/conversation.rb +28 -2
- data/app/models/message_train/ignore.rb +2 -2
- data/app/models/message_train/message.rb +10 -4
- data/app/models/message_train/receipt.rb +27 -4
- data/app/models/message_train/unsubscribe.rb +1 -1
- data/app/views/application/404.html.haml +1 -3
- data/app/views/kaminari/_first_page.html.haml +1 -1
- data/app/views/kaminari/_last_page.html.haml +1 -1
- data/app/views/kaminari/_next_page.html.haml +1 -1
- data/app/views/kaminari/_page.html.haml +3 -3
- data/app/views/kaminari/_paginator.html.haml +12 -11
- data/app/views/kaminari/_prev_page.html.haml +1 -1
- data/app/views/message_train/application/_attachment_fields.html.haml +10 -7
- data/app/views/message_train/application/_attachment_link.html.haml +2 -2
- data/app/views/message_train/application/_widget.html.haml +2 -4
- data/app/views/message_train/boxes/_widget.html.haml +5 -5
- data/app/views/message_train/boxes/show.html.haml +28 -45
- data/app/views/message_train/collectives/_widget.html.haml +4 -4
- data/app/views/message_train/conversations/_conversation.html.haml +11 -11
- data/app/views/message_train/conversations/_deleted_toggle.html.haml +1 -1
- data/app/views/message_train/conversations/_ignored_toggle.html.haml +2 -2
- data/app/views/message_train/conversations/_read_toggle.html.haml +2 -2
- data/app/views/message_train/conversations/_toggle.html.haml +6 -4
- data/app/views/message_train/conversations/_trashed_toggle.html.haml +2 -2
- data/app/views/message_train/conversations/show.html.haml +8 -6
- data/app/views/message_train/messages/_deleted_toggle.html.haml +1 -1
- data/app/views/message_train/messages/_form.html.haml +22 -30
- data/app/views/message_train/messages/_message.html.haml +27 -45
- data/app/views/message_train/messages/_read_toggle.html.haml +2 -2
- data/app/views/message_train/messages/_toggle.html.haml +5 -1
- data/app/views/message_train/messages/_trashed_toggle.html.haml +2 -2
- data/app/views/message_train/unsubscribes/index.html.haml +12 -15
- data/badges/coverage.json +1 -0
- data/config/importmap.rb +2 -0
- data/config/locales/en.yml +6 -3
- data/db/migrate/20150721145319_create_message_train_conversations.rb +1 -1
- data/db/migrate/20150721160322_create_message_train_messages.rb +1 -1
- data/db/migrate/20150721161144_create_message_train_attachments.rb +5 -2
- data/db/migrate/20150721161940_create_message_train_receipts.rb +1 -1
- data/db/migrate/20150721163838_create_message_train_ignores.rb +1 -1
- data/db/migrate/20150901183458_add_received_through_to_message_train_receipts.rb +1 -1
- data/db/migrate/20151004184347_add_unique_index_to_receipts.rb +1 -1
- data/db/migrate/20151124000820_create_message_train_unsubscribes.rb +1 -1
- data/db/migrate/20260827095938_remove_paperclip_columns_from_message_train_attachments.rb +8 -0
- data/db/migrate/20260827171549_remove_body_from_message_train_messages.rb +5 -0
- data/db/migrate/20260827180000_add_marking_indexes.rb +9 -0
- data/db/migrate/20260827200000_add_body_back_to_message_train_messages.rb +5 -0
- data/docs/screenshots/inbox-desktop.png +0 -0
- data/docs/screenshots/inbox-mobile.png +0 -0
- data/lib/generators/message_train/install/install_generator.rb +1 -1
- data/lib/message_train/engine.rb +11 -0
- data/lib/message_train/instance_methods.rb +13 -7
- data/lib/message_train/localization.rb +4 -3
- data/lib/message_train/version.rb +1 -1
- data/lib/message_train.rb +0 -2
- data/message_train.gemspec +57 -389
- data/spec/controllers/message_train/boxes_controller_spec.rb +13 -8
- data/spec/controllers/message_train/concerns_spec.rb +2 -2
- data/spec/controllers/message_train/conversations_controller_spec.rb +36 -7
- data/spec/controllers/message_train/messages_controller_spec.rb +4 -4
- data/spec/dummy/app/assets/stylesheets/application.scss +141 -12
- data/spec/dummy/app/controllers/application_controller.rb +1 -1
- data/spec/dummy/app/javascript/application.js +4 -0
- data/spec/dummy/app/javascript/controllers/application.js +9 -0
- data/spec/dummy/app/javascript/controllers/index.js +4 -0
- data/spec/dummy/app/models/role.rb +1 -1
- data/spec/dummy/app/views/active_storage/blobs/_blob.html.erb +14 -0
- data/spec/dummy/app/views/layouts/_top_navigation.html.haml +18 -7
- data/spec/dummy/app/views/layouts/application.html.haml +22 -26
- data/spec/dummy/bin/importmap +4 -0
- data/spec/dummy/config/application.rb +7 -20
- data/spec/dummy/config/environments/development.rb +17 -21
- data/spec/dummy/config/environments/production.rb +11 -63
- data/spec/dummy/config/environments/test.rb +21 -16
- data/spec/dummy/config/importmap.rb +7 -0
- data/spec/dummy/config/initializers/assets.rb +1 -6
- data/spec/dummy/config/routes.rb +1 -1
- data/spec/dummy/config/storage.yml +7 -0
- data/spec/dummy/db/migrate/20150721140013_devise_create_users.rb +1 -1
- data/spec/dummy/db/migrate/20150721141009_rolify_create_roles.rb +1 -1
- data/spec/dummy/db/migrate/20150721141128_create_groups.rb +1 -1
- data/spec/dummy/db/migrate/20150721150307_add_display_name_column_to_users.rb +1 -1
- data/spec/dummy/db/migrate/20160207190402_create_message_train_conversations.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190403_create_message_train_messages.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190404_create_message_train_attachments.message_train.rb +5 -2
- data/spec/dummy/db/migrate/20160207190405_create_message_train_receipts.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190406_create_message_train_ignores.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190407_add_received_through_to_message_train_receipts.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190408_add_unique_index_to_receipts.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20160207190409_create_message_train_unsubscribes.message_train.rb +1 -1
- data/spec/dummy/db/migrate/20260827095939_remove_paperclip_columns_from_message_train_attachments.message_train.rb +9 -0
- data/spec/dummy/db/migrate/20260827161141_create_active_storage_tables.active_storage.rb +57 -0
- data/spec/dummy/db/migrate/20260827171550_remove_body_from_message_train_messages.message_train.rb +6 -0
- data/spec/dummy/db/migrate/20260827225116_add_marking_indexes.message_train.rb +10 -0
- data/spec/dummy/db/migrate/20260828034830_add_body_back_to_message_train_messages.message_train.rb +6 -0
- data/spec/dummy/db/migrate/20260828040000_drop_action_text_tables.rb +5 -0
- data/spec/dummy/db/schema.rb +106 -72
- data/spec/dummy/db/seeds/conversations.seeds.rb +22 -22
- data/spec/dummy/db/seeds/development/conversations.seeds.rb +2 -2
- data/spec/dummy/db/seeds/groups.seeds.rb +4 -4
- data/spec/dummy/db/seeds/test/attachments.seeds.rb +4 -4
- data/spec/dummy/db/seeds/test/conversations.seeds.rb +2 -2
- data/spec/dummy/db/seeds/users.seeds.rb +8 -8
- data/spec/dummy/vendor/javascript/.keep +0 -0
- data/spec/factories/attachment.rb +5 -6
- data/spec/factories/group.rb +2 -2
- data/spec/factories/message.rb +7 -7
- data/spec/factories/user.rb +3 -3
- data/spec/features/boxes_spec.rb +38 -34
- data/spec/features/conversations_spec.rb +13 -6
- data/spec/features/messages_spec.rb +20 -20
- data/spec/features/unsubscribes_spec.rb +9 -9
- data/spec/helpers/message_train/application_helper_spec.rb +16 -18
- data/spec/helpers/message_train/attachment_helper_spec.rb +8 -18
- data/spec/helpers/message_train/boxes_helper_spec.rb +6 -6
- data/spec/helpers/message_train/collectives_helper_spec.rb +10 -10
- data/spec/helpers/message_train/conversations_helper_spec.rb +43 -85
- data/spec/helpers/message_train/messages_helper_spec.rb +41 -61
- data/spec/models/message_train/attachment_spec.rb +26 -36
- data/spec/models/message_train/box_spec.rb +2 -2
- data/spec/models/message_train/conversation_spec.rb +15 -0
- data/spec/models/message_train/message_spec.rb +5 -1
- data/spec/models/message_train/receipt_spec.rb +1 -1
- data/spec/models/message_train/unsubscribe_spec.rb +1 -1
- data/spec/rails_helper.rb +14 -13
- data/spec/support/controller_behaviors.rb +13 -13
- data/spec/support/factory_bot.rb +3 -0
- data/spec/support/feature_behaviors.rb +14 -14
- data/spec/support/loaded_site/attachments.rb +6 -2
- data/spec/support/utilities.rb +49 -20
- metadata +260 -213
- data/.travis.yml +0 -12
- data/VERSION +0 -1
- data/app/assets/javascripts/ckeditor/config.js +0 -49
- data/app/assets/javascripts/message_train.js +0 -149
- data/spec/dummy/app/assets/javascripts/application.js +0 -17
- data/spec/dummy/app/assets/stylesheets/bootstrap-everything.scss +0 -54
- data/spec/dummy/config/initializers/bootstrap_leather.rb +0 -7
- data/spec/dummy/config/initializers/paperclip.rb +0 -5
- data/spec/dummy/config/secrets.yml +0 -22
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/support/factory_girl.rb +0 -3
|
@@ -6,7 +6,7 @@ describe MessageTrain::ConversationsHelper do
|
|
|
6
6
|
|
|
7
7
|
before do
|
|
8
8
|
view.extend MessageTrain::BoxesHelper
|
|
9
|
-
view.extend
|
|
9
|
+
view.extend MessageTrain::ApplicationHelper
|
|
10
10
|
login_user first_user
|
|
11
11
|
assign(:box_user, first_user)
|
|
12
12
|
end
|
|
@@ -120,17 +120,14 @@ describe MessageTrain::ConversationsHelper do
|
|
|
120
120
|
subject { helper.conversation_trashed_toggle(unread_conversation) }
|
|
121
121
|
it do
|
|
122
122
|
should have_tag(
|
|
123
|
-
:
|
|
123
|
+
:button,
|
|
124
124
|
with: {
|
|
125
|
-
'rel' => 'nofollow',
|
|
126
125
|
'title' => 'Mark as Trashed',
|
|
127
|
-
'data-confirm' => 'Are you sure?'
|
|
128
|
-
'data-method' => 'put',
|
|
129
|
-
'data-remote' => 'true'
|
|
126
|
+
'data-turbo-confirm' => 'Are you sure?'
|
|
130
127
|
}
|
|
131
128
|
)
|
|
132
129
|
end
|
|
133
|
-
it { should have_tag(:span, with: { class: '
|
|
130
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
134
131
|
end
|
|
135
132
|
context 'when the conversation is all trashed' do
|
|
136
133
|
before do
|
|
@@ -139,16 +136,13 @@ describe MessageTrain::ConversationsHelper do
|
|
|
139
136
|
subject { helper.conversation_trashed_toggle(trashed_conversation) }
|
|
140
137
|
it do
|
|
141
138
|
should have_tag(
|
|
142
|
-
:
|
|
139
|
+
:button,
|
|
143
140
|
with: {
|
|
144
|
-
'
|
|
145
|
-
'title' => 'Mark as Untrashed',
|
|
146
|
-
'data-method' => 'put',
|
|
147
|
-
'data-remote' => 'true'
|
|
141
|
+
'title' => 'Mark as Untrashed'
|
|
148
142
|
}
|
|
149
143
|
)
|
|
150
144
|
end
|
|
151
|
-
it { should have_tag(:span, with: { class: '
|
|
145
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
152
146
|
end
|
|
153
147
|
end
|
|
154
148
|
describe 'in a collective box' do
|
|
@@ -161,17 +155,14 @@ describe MessageTrain::ConversationsHelper do
|
|
|
161
155
|
end
|
|
162
156
|
it do
|
|
163
157
|
should have_tag(
|
|
164
|
-
:
|
|
158
|
+
:button,
|
|
165
159
|
with: {
|
|
166
|
-
'rel' => 'nofollow',
|
|
167
160
|
'title' => 'Mark as Trashed',
|
|
168
|
-
'data-confirm' => 'Are you sure?'
|
|
169
|
-
'data-method' => 'put',
|
|
170
|
-
'data-remote' => 'true'
|
|
161
|
+
'data-turbo-confirm' => 'Are you sure?'
|
|
171
162
|
}
|
|
172
163
|
)
|
|
173
164
|
end
|
|
174
|
-
it { should have_tag(:span, with: { class: '
|
|
165
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
175
166
|
end
|
|
176
167
|
context 'when the conversation is all trashed' do
|
|
177
168
|
before do
|
|
@@ -184,16 +175,13 @@ describe MessageTrain::ConversationsHelper do
|
|
|
184
175
|
end
|
|
185
176
|
it do
|
|
186
177
|
should have_tag(
|
|
187
|
-
:
|
|
178
|
+
:button,
|
|
188
179
|
with: {
|
|
189
|
-
'
|
|
190
|
-
'title' => 'Mark as Untrashed',
|
|
191
|
-
'data-method' => 'put',
|
|
192
|
-
'data-remote' => 'true'
|
|
180
|
+
'title' => 'Mark as Untrashed'
|
|
193
181
|
}
|
|
194
182
|
)
|
|
195
183
|
end
|
|
196
|
-
it { should have_tag(:span, with: { class: '
|
|
184
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
197
185
|
end
|
|
198
186
|
end
|
|
199
187
|
end
|
|
@@ -207,16 +195,13 @@ describe MessageTrain::ConversationsHelper do
|
|
|
207
195
|
subject { helper.conversation_read_toggle(unread_conversation) }
|
|
208
196
|
it do
|
|
209
197
|
should have_tag(
|
|
210
|
-
:
|
|
198
|
+
:button,
|
|
211
199
|
with: {
|
|
212
|
-
'
|
|
213
|
-
'title' => 'Mark as Read',
|
|
214
|
-
'data-method' => 'put',
|
|
215
|
-
'data-remote' => 'true'
|
|
200
|
+
'title' => 'Mark as Read'
|
|
216
201
|
}
|
|
217
202
|
)
|
|
218
203
|
end
|
|
219
|
-
it { should have_tag(:span, with: { class: '
|
|
204
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
220
205
|
end
|
|
221
206
|
context 'when the conversation is all read' do
|
|
222
207
|
before do
|
|
@@ -225,16 +210,13 @@ describe MessageTrain::ConversationsHelper do
|
|
|
225
210
|
subject { helper.conversation_read_toggle(read_conversation) }
|
|
226
211
|
it do
|
|
227
212
|
should have_tag(
|
|
228
|
-
:
|
|
213
|
+
:button,
|
|
229
214
|
with: {
|
|
230
|
-
'
|
|
231
|
-
'title' => 'Mark as Unread',
|
|
232
|
-
'data-method' => 'put',
|
|
233
|
-
'data-remote' => 'true'
|
|
215
|
+
'title' => 'Mark as Unread'
|
|
234
216
|
}
|
|
235
217
|
)
|
|
236
218
|
end
|
|
237
|
-
it { should have_tag(:span, with: { class: '
|
|
219
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
238
220
|
end
|
|
239
221
|
end
|
|
240
222
|
describe 'in a collective box' do
|
|
@@ -245,16 +227,13 @@ describe MessageTrain::ConversationsHelper do
|
|
|
245
227
|
subject { helper.conversation_read_toggle(membered_group_conversation) }
|
|
246
228
|
it do
|
|
247
229
|
should have_tag(
|
|
248
|
-
:
|
|
230
|
+
:button,
|
|
249
231
|
with: {
|
|
250
|
-
'
|
|
251
|
-
'title' => 'Mark as Read',
|
|
252
|
-
'data-method' => 'put',
|
|
253
|
-
'data-remote' => 'true'
|
|
232
|
+
'title' => 'Mark as Read'
|
|
254
233
|
}
|
|
255
234
|
)
|
|
256
235
|
end
|
|
257
|
-
it { should have_tag(:span, with: { class: '
|
|
236
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
258
237
|
end
|
|
259
238
|
context 'when the conversation is all read' do
|
|
260
239
|
before do
|
|
@@ -265,16 +244,13 @@ describe MessageTrain::ConversationsHelper do
|
|
|
265
244
|
end
|
|
266
245
|
it do
|
|
267
246
|
should have_tag(
|
|
268
|
-
:
|
|
247
|
+
:button,
|
|
269
248
|
with: {
|
|
270
|
-
'
|
|
271
|
-
'title' => 'Mark as Unread',
|
|
272
|
-
'data-method' => 'put',
|
|
273
|
-
'data-remote' => 'true'
|
|
249
|
+
'title' => 'Mark as Unread'
|
|
274
250
|
}
|
|
275
251
|
)
|
|
276
252
|
end
|
|
277
|
-
it { should have_tag(:span, with: { class: '
|
|
253
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
278
254
|
end
|
|
279
255
|
end
|
|
280
256
|
end
|
|
@@ -288,17 +264,14 @@ describe MessageTrain::ConversationsHelper do
|
|
|
288
264
|
subject { helper.conversation_ignored_toggle(unread_conversation) }
|
|
289
265
|
it do
|
|
290
266
|
should have_tag(
|
|
291
|
-
:
|
|
267
|
+
:button,
|
|
292
268
|
with: {
|
|
293
|
-
'rel' => 'nofollow',
|
|
294
269
|
'title' => 'Mark as Ignored',
|
|
295
|
-
'data-confirm' => 'Are you sure?'
|
|
296
|
-
'data-method' => 'delete',
|
|
297
|
-
'data-remote' => 'true'
|
|
270
|
+
'data-turbo-confirm' => 'Are you sure?'
|
|
298
271
|
}
|
|
299
272
|
)
|
|
300
273
|
end
|
|
301
|
-
it { should have_tag(:span, with: { class: '
|
|
274
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
302
275
|
end
|
|
303
276
|
context 'when the conversation is all ignored' do
|
|
304
277
|
before do
|
|
@@ -307,16 +280,13 @@ describe MessageTrain::ConversationsHelper do
|
|
|
307
280
|
subject { helper.conversation_ignored_toggle(ignored_conversation) }
|
|
308
281
|
it do
|
|
309
282
|
should have_tag(
|
|
310
|
-
:
|
|
283
|
+
:button,
|
|
311
284
|
with: {
|
|
312
|
-
'
|
|
313
|
-
'title' => 'Mark as Unignored',
|
|
314
|
-
'data-method' => 'delete',
|
|
315
|
-
'data-remote' => 'true'
|
|
285
|
+
'title' => 'Mark as Unignored'
|
|
316
286
|
}
|
|
317
287
|
)
|
|
318
288
|
end
|
|
319
|
-
it { should have_tag(:span, with: { class: '
|
|
289
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
320
290
|
end
|
|
321
291
|
end
|
|
322
292
|
describe 'in a collective box' do
|
|
@@ -329,17 +299,14 @@ describe MessageTrain::ConversationsHelper do
|
|
|
329
299
|
end
|
|
330
300
|
it do
|
|
331
301
|
should have_tag(
|
|
332
|
-
:
|
|
302
|
+
:button,
|
|
333
303
|
with: {
|
|
334
|
-
'rel' => 'nofollow',
|
|
335
304
|
'title' => 'Mark as Ignored',
|
|
336
|
-
'data-confirm' => 'Are you sure?'
|
|
337
|
-
'data-method' => 'delete',
|
|
338
|
-
'data-remote' => 'true'
|
|
305
|
+
'data-turbo-confirm' => 'Are you sure?'
|
|
339
306
|
}
|
|
340
307
|
)
|
|
341
308
|
end
|
|
342
|
-
it { should have_tag(:span, with: { class: '
|
|
309
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
343
310
|
end
|
|
344
311
|
context 'when the conversation is all ignored' do
|
|
345
312
|
before do
|
|
@@ -352,16 +319,13 @@ describe MessageTrain::ConversationsHelper do
|
|
|
352
319
|
end
|
|
353
320
|
it do
|
|
354
321
|
should have_tag(
|
|
355
|
-
:
|
|
322
|
+
:button,
|
|
356
323
|
with: {
|
|
357
|
-
'
|
|
358
|
-
'title' => 'Mark as Unignored',
|
|
359
|
-
'data-method' => 'delete',
|
|
360
|
-
'data-remote' => 'true'
|
|
324
|
+
'title' => 'Mark as Unignored'
|
|
361
325
|
}
|
|
362
326
|
)
|
|
363
327
|
end
|
|
364
|
-
it { should have_tag(:span, with: { class: '
|
|
328
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
365
329
|
end
|
|
366
330
|
end
|
|
367
331
|
end
|
|
@@ -375,17 +339,14 @@ describe MessageTrain::ConversationsHelper do
|
|
|
375
339
|
subject { helper.conversation_deleted_toggle(unread_conversation) }
|
|
376
340
|
it do
|
|
377
341
|
should have_tag(
|
|
378
|
-
:
|
|
342
|
+
:button,
|
|
379
343
|
with: {
|
|
380
|
-
'rel' => 'nofollow',
|
|
381
344
|
'title' => 'Mark as Deleted',
|
|
382
|
-
'data-confirm' => 'Delete forever? This cannot be undone.'
|
|
383
|
-
'data-method' => 'put',
|
|
384
|
-
'data-remote' => 'true'
|
|
345
|
+
'data-turbo-confirm' => 'Delete forever? This cannot be undone.'
|
|
385
346
|
}
|
|
386
347
|
)
|
|
387
348
|
end
|
|
388
|
-
it { should have_tag(:span, with: { class: '
|
|
349
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
389
350
|
end
|
|
390
351
|
end
|
|
391
352
|
describe 'in a collective box' do
|
|
@@ -398,17 +359,14 @@ describe MessageTrain::ConversationsHelper do
|
|
|
398
359
|
end
|
|
399
360
|
it do
|
|
400
361
|
should have_tag(
|
|
401
|
-
:
|
|
362
|
+
:button,
|
|
402
363
|
with: {
|
|
403
|
-
'rel' => 'nofollow',
|
|
404
364
|
'title' => 'Mark as Deleted',
|
|
405
|
-
'data-confirm' => 'Delete forever? This cannot be undone.'
|
|
406
|
-
'data-method' => 'put',
|
|
407
|
-
'data-remote' => 'true'
|
|
365
|
+
'data-turbo-confirm' => 'Delete forever? This cannot be undone.'
|
|
408
366
|
}
|
|
409
367
|
)
|
|
410
368
|
end
|
|
411
|
-
it { should have_tag(:span, with: { class: '
|
|
369
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
412
370
|
end
|
|
413
371
|
end
|
|
414
372
|
end
|
|
@@ -6,7 +6,7 @@ describe MessageTrain::MessagesHelper do
|
|
|
6
6
|
|
|
7
7
|
before do
|
|
8
8
|
view.extend MessageTrain::BoxesHelper
|
|
9
|
-
view.extend
|
|
9
|
+
view.extend MessageTrain::ApplicationHelper
|
|
10
10
|
login_user first_user
|
|
11
11
|
assign(:box_user, first_user)
|
|
12
12
|
end
|
|
@@ -64,37 +64,33 @@ describe MessageTrain::MessagesHelper do
|
|
|
64
64
|
assign(:box, first_user.box(:in))
|
|
65
65
|
end
|
|
66
66
|
subject { helper.message_trashed_toggle(unread_message) }
|
|
67
|
+
before { assign(:conversation, unread_message.conversation) }
|
|
67
68
|
it do
|
|
68
69
|
should have_tag(
|
|
69
|
-
:
|
|
70
|
+
:button,
|
|
70
71
|
with: {
|
|
71
|
-
'rel' => 'nofollow',
|
|
72
72
|
'title' => 'Mark as Trashed',
|
|
73
|
-
'data-confirm' => 'Are you sure?'
|
|
74
|
-
'data-method' => 'put',
|
|
75
|
-
'data-remote' => 'true'
|
|
73
|
+
'data-turbo-confirm' => 'Are you sure?'
|
|
76
74
|
}
|
|
77
75
|
)
|
|
78
76
|
end
|
|
79
|
-
it { should have_tag(:span, with: { class: '
|
|
77
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
80
78
|
end
|
|
81
79
|
context 'when the message is trashed' do
|
|
82
80
|
before do
|
|
83
81
|
assign(:box, first_user.box(:trash))
|
|
84
82
|
end
|
|
85
83
|
subject { helper.message_trashed_toggle(trashed_message) }
|
|
84
|
+
before { assign(:conversation, trashed_message.conversation) }
|
|
86
85
|
it do
|
|
87
86
|
should have_tag(
|
|
88
|
-
:
|
|
87
|
+
:button,
|
|
89
88
|
with: {
|
|
90
|
-
'
|
|
91
|
-
'title' => 'Mark as Untrashed',
|
|
92
|
-
'data-method' => 'put',
|
|
93
|
-
'data-remote' => 'true'
|
|
89
|
+
'title' => 'Mark as Untrashed'
|
|
94
90
|
}
|
|
95
91
|
)
|
|
96
92
|
end
|
|
97
|
-
it { should have_tag(:span, with: { class: '
|
|
93
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
98
94
|
end
|
|
99
95
|
end
|
|
100
96
|
describe 'in a collective box' do
|
|
@@ -103,19 +99,17 @@ describe MessageTrain::MessagesHelper do
|
|
|
103
99
|
assign(:box, membered_group.box(:in, first_user))
|
|
104
100
|
end
|
|
105
101
|
subject { helper.message_trashed_toggle(membered_group_message) }
|
|
102
|
+
before { assign(:conversation, membered_group_message.conversation) }
|
|
106
103
|
it do
|
|
107
104
|
should have_tag(
|
|
108
|
-
:
|
|
105
|
+
:button,
|
|
109
106
|
with: {
|
|
110
|
-
'rel' => 'nofollow',
|
|
111
107
|
'title' => 'Mark as Trashed',
|
|
112
|
-
'data-confirm' => 'Are you sure?'
|
|
113
|
-
'data-method' => 'put',
|
|
114
|
-
'data-remote' => 'true'
|
|
108
|
+
'data-turbo-confirm' => 'Are you sure?'
|
|
115
109
|
}
|
|
116
110
|
)
|
|
117
111
|
end
|
|
118
|
-
it { should have_tag(:span, with: { class: '
|
|
112
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
119
113
|
end
|
|
120
114
|
context 'when the message is trashed' do
|
|
121
115
|
before do
|
|
@@ -124,18 +118,16 @@ describe MessageTrain::MessagesHelper do
|
|
|
124
118
|
subject do
|
|
125
119
|
helper.message_trashed_toggle(membered_group_trashed_message)
|
|
126
120
|
end
|
|
121
|
+
before { assign(:conversation, membered_group_trashed_message.conversation) }
|
|
127
122
|
it do
|
|
128
123
|
should have_tag(
|
|
129
|
-
:
|
|
124
|
+
:button,
|
|
130
125
|
with: {
|
|
131
|
-
'
|
|
132
|
-
'title' => 'Mark as Untrashed',
|
|
133
|
-
'data-method' => 'put',
|
|
134
|
-
'data-remote' => 'true'
|
|
126
|
+
'title' => 'Mark as Untrashed'
|
|
135
127
|
}
|
|
136
128
|
)
|
|
137
129
|
end
|
|
138
|
-
it { should have_tag(:span, with: { class: '
|
|
130
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
139
131
|
end
|
|
140
132
|
end
|
|
141
133
|
end
|
|
@@ -147,36 +139,32 @@ describe MessageTrain::MessagesHelper do
|
|
|
147
139
|
assign(:box, first_user.box(:in))
|
|
148
140
|
end
|
|
149
141
|
subject { helper.message_read_toggle(unread_message) }
|
|
142
|
+
before { assign(:conversation, unread_message.conversation) }
|
|
150
143
|
it do
|
|
151
144
|
should have_tag(
|
|
152
|
-
:
|
|
145
|
+
:button,
|
|
153
146
|
with: {
|
|
154
|
-
'
|
|
155
|
-
'title' => 'Mark as Read',
|
|
156
|
-
'data-method' => 'put',
|
|
157
|
-
'data-remote' => 'true'
|
|
147
|
+
'title' => 'Mark as Read'
|
|
158
148
|
}
|
|
159
149
|
)
|
|
160
150
|
end
|
|
161
|
-
it { should have_tag(:span, with: { class: '
|
|
151
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
162
152
|
end
|
|
163
153
|
context 'when the message is read' do
|
|
164
154
|
before do
|
|
165
155
|
assign(:box, first_user.box(:trash))
|
|
166
156
|
end
|
|
167
157
|
subject { helper.message_read_toggle(read_message) }
|
|
158
|
+
before { assign(:conversation, read_message.conversation) }
|
|
168
159
|
it do
|
|
169
160
|
should have_tag(
|
|
170
|
-
:
|
|
161
|
+
:button,
|
|
171
162
|
with: {
|
|
172
|
-
'
|
|
173
|
-
'title' => 'Mark as Unread',
|
|
174
|
-
'data-method' => 'put',
|
|
175
|
-
'data-remote' => 'true'
|
|
163
|
+
'title' => 'Mark as Unread'
|
|
176
164
|
}
|
|
177
165
|
)
|
|
178
166
|
end
|
|
179
|
-
it { should have_tag(:span, with: { class: '
|
|
167
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
180
168
|
end
|
|
181
169
|
end
|
|
182
170
|
describe 'in a collective box' do
|
|
@@ -185,36 +173,32 @@ describe MessageTrain::MessagesHelper do
|
|
|
185
173
|
assign(:box, membered_group.box(:in, first_user))
|
|
186
174
|
end
|
|
187
175
|
subject { helper.message_read_toggle(membered_group_message) }
|
|
176
|
+
before { assign(:conversation, membered_group_message.conversation) }
|
|
188
177
|
it do
|
|
189
178
|
should have_tag(
|
|
190
|
-
:
|
|
179
|
+
:button,
|
|
191
180
|
with: {
|
|
192
|
-
'
|
|
193
|
-
'title' => 'Mark as Read',
|
|
194
|
-
'data-method' => 'put',
|
|
195
|
-
'data-remote' => 'true'
|
|
181
|
+
'title' => 'Mark as Read'
|
|
196
182
|
}
|
|
197
183
|
)
|
|
198
184
|
end
|
|
199
|
-
it { should have_tag(:span, with: { class: '
|
|
185
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
200
186
|
end
|
|
201
187
|
context 'when the message is read' do
|
|
202
188
|
before do
|
|
203
189
|
assign(:box, membered_group.box(:trash, first_user))
|
|
204
190
|
end
|
|
205
191
|
subject { helper.message_read_toggle(membered_group_read_message) }
|
|
192
|
+
before { assign(:conversation, membered_group_read_message.conversation) }
|
|
206
193
|
it do
|
|
207
194
|
should have_tag(
|
|
208
|
-
:
|
|
195
|
+
:button,
|
|
209
196
|
with: {
|
|
210
|
-
'
|
|
211
|
-
'title' => 'Mark as Unread',
|
|
212
|
-
'data-method' => 'put',
|
|
213
|
-
'data-remote' => 'true'
|
|
197
|
+
'title' => 'Mark as Unread'
|
|
214
198
|
}
|
|
215
199
|
)
|
|
216
200
|
end
|
|
217
|
-
it { should have_tag(:span, with: { class: '
|
|
201
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
218
202
|
end
|
|
219
203
|
end
|
|
220
204
|
end
|
|
@@ -226,19 +210,17 @@ describe MessageTrain::MessagesHelper do
|
|
|
226
210
|
assign(:box, first_user.box(:trash))
|
|
227
211
|
end
|
|
228
212
|
subject { helper.message_deleted_toggle(unread_message) }
|
|
213
|
+
before { assign(:conversation, unread_message.conversation) }
|
|
229
214
|
it do
|
|
230
215
|
should have_tag(
|
|
231
|
-
:
|
|
216
|
+
:button,
|
|
232
217
|
with: {
|
|
233
|
-
'rel' => 'nofollow',
|
|
234
218
|
'title' => 'Mark as Deleted',
|
|
235
|
-
'data-confirm' => 'Delete forever? This cannot be undone.'
|
|
236
|
-
'data-method' => 'put',
|
|
237
|
-
'data-remote' => 'true'
|
|
219
|
+
'data-turbo-confirm' => 'Delete forever? This cannot be undone.'
|
|
238
220
|
}
|
|
239
221
|
)
|
|
240
222
|
end
|
|
241
|
-
it { should have_tag(:span, with: { class: '
|
|
223
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
242
224
|
end
|
|
243
225
|
end
|
|
244
226
|
describe 'in a collective box' do
|
|
@@ -247,19 +229,17 @@ describe MessageTrain::MessagesHelper do
|
|
|
247
229
|
assign(:box, membered_group.box(:trash, first_user))
|
|
248
230
|
end
|
|
249
231
|
subject { helper.message_deleted_toggle(membered_group_message) }
|
|
232
|
+
before { assign(:conversation, membered_group_message.conversation) }
|
|
250
233
|
it do
|
|
251
234
|
should have_tag(
|
|
252
|
-
:
|
|
235
|
+
:button,
|
|
253
236
|
with: {
|
|
254
|
-
'rel' => 'nofollow',
|
|
255
237
|
'title' => 'Mark as Deleted',
|
|
256
|
-
'data-confirm' => 'Delete forever? This cannot be undone.'
|
|
257
|
-
'data-method' => 'put',
|
|
258
|
-
'data-remote' => 'true'
|
|
238
|
+
'data-turbo-confirm' => 'Delete forever? This cannot be undone.'
|
|
259
239
|
}
|
|
260
240
|
)
|
|
261
241
|
end
|
|
262
|
-
it { should have_tag(:span, with: { class: '
|
|
242
|
+
it { should have_tag(:span, with: { class: 'message-train-icon' }) }
|
|
263
243
|
end
|
|
264
244
|
end
|
|
265
245
|
end
|
|
@@ -5,52 +5,42 @@ module MessageTrain
|
|
|
5
5
|
include_context 'loaded site'
|
|
6
6
|
|
|
7
7
|
describe 'Model' do
|
|
8
|
-
it {
|
|
9
|
-
|
|
10
|
-
it
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
'
|
|
28
|
-
'
|
|
29
|
-
'
|
|
30
|
-
'application/pjpeg',
|
|
31
|
-
'application/png',
|
|
32
|
-
'application/x-png',
|
|
33
|
-
'x-application/bmp',
|
|
34
|
-
'x-application/gif',
|
|
35
|
-
'x-application/jpeg',
|
|
36
|
-
'x-application/pjpeg',
|
|
37
|
-
'x-application/png',
|
|
38
|
-
'x-application/x-png'
|
|
39
|
-
).rejecting(
|
|
40
|
-
'image/tiff',
|
|
41
|
-
'image/svg'
|
|
8
|
+
it { is_expected.to belong_to :message }
|
|
9
|
+
|
|
10
|
+
it 'has an attached file' do
|
|
11
|
+
expect(image_attachment.attachment).to be_attached
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'is invalid without an attached file' do
|
|
15
|
+
attachment = build(:attachment, message: build(:message), attachment: nil)
|
|
16
|
+
expect(attachment).not_to be_valid
|
|
17
|
+
expect(attachment.errors[:attachment]).to be_present
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'is valid for an allowed content type' do
|
|
21
|
+
expect(image_attachment).to be_valid
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'is invalid for a disallowed content type' do
|
|
25
|
+
attachment = build(:attachment, message: build(:message))
|
|
26
|
+
attachment.attachment.attach(
|
|
27
|
+
io: StringIO.new('bogus'),
|
|
28
|
+
filename: 'bogus.svg',
|
|
29
|
+
content_type: 'image/svg'
|
|
42
30
|
)
|
|
31
|
+
expect(attachment).not_to be_valid
|
|
32
|
+
expect(attachment.errors[:attachment]).to be_present
|
|
43
33
|
end
|
|
44
34
|
end
|
|
45
35
|
describe 'Scopes and Methods' do
|
|
46
36
|
describe '#image?' do
|
|
47
37
|
context 'when it is an image' do
|
|
48
38
|
subject { image_attachment.image? }
|
|
49
|
-
it {
|
|
39
|
+
it { is_expected.to eq true }
|
|
50
40
|
end
|
|
51
41
|
context 'when it is not an image' do
|
|
52
42
|
subject { pdf_attachment.image? }
|
|
53
|
-
it {
|
|
43
|
+
it { is_expected.to eq false }
|
|
54
44
|
end
|
|
55
45
|
end
|
|
56
46
|
end
|
|
@@ -290,7 +290,7 @@ module MessageTrain
|
|
|
290
290
|
should eq [
|
|
291
291
|
{
|
|
292
292
|
css_id: 'box',
|
|
293
|
-
path: '/collectives/groups:first-group/box/in',
|
|
293
|
+
path: '/messages/collectives/groups:first-group/box/in',
|
|
294
294
|
message: 'Cannot mark with Time'
|
|
295
295
|
}
|
|
296
296
|
]
|
|
@@ -512,7 +512,7 @@ module MessageTrain
|
|
|
512
512
|
{
|
|
513
513
|
css_id: 'message_train_message_'\
|
|
514
514
|
"#{membered_group_message.id}",
|
|
515
|
-
path: '/collectives/groups:membered-group/box/in/'\
|
|
515
|
+
path: '/messages/collectives/groups:membered-group/box/in/'\
|
|
516
516
|
"messages/#{membered_group_message.id}",
|
|
517
517
|
message: 'Access to Message '\
|
|
518
518
|
"#{membered_group_message.id} denied"
|
|
@@ -53,6 +53,21 @@ module MessageTrain
|
|
|
53
53
|
it { should_not include third_user }
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
+
describe '#new_reply' do
|
|
57
|
+
subject(:reply) { sent_conversation.new_reply(box: first_user.box(:in)) }
|
|
58
|
+
|
|
59
|
+
it 'prefixes the subject with Re:' do
|
|
60
|
+
expect(reply.subject).to eq("Re: #{sent_conversation.subject}")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'quotes the previous message as a markdown blockquote' do
|
|
64
|
+
quoted = sent_conversation.messages.last.body.each_line.map do |line|
|
|
65
|
+
"> #{line.chomp}"
|
|
66
|
+
end.join("\n")
|
|
67
|
+
expect(reply.body).to eq("#{quoted}\n\n")
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
56
71
|
describe '#participant_ignore and #participant_ignored?' do
|
|
57
72
|
subject { ignored_conversation.participant_ignored?(first_user) }
|
|
58
73
|
it { should be true }
|
|
@@ -6,7 +6,11 @@ module MessageTrain
|
|
|
6
6
|
let(:user_in_box) { first_user.box(:in) }
|
|
7
7
|
describe 'Model' do
|
|
8
8
|
# Relationships
|
|
9
|
-
|
|
9
|
+
# `conversation` has no association-level `required`/presence
|
|
10
|
+
# validation because `create_conversation_if_blank` (a
|
|
11
|
+
# before_validation callback) always fills it in before validation
|
|
12
|
+
# runs, so it's never actually blank at that point.
|
|
13
|
+
it { should belong_to(:conversation).optional }
|
|
10
14
|
it { should belong_to :sender }
|
|
11
15
|
it { should have_many :attachments }
|
|
12
16
|
it { should have_many :receipts }
|