message_train 0.6.17 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +16 -13
  3. data/.rubocop_todo.yml +12 -0
  4. data/.ruby-version +1 -1
  5. data/.travis.yml +1 -1
  6. data/Gemfile +28 -30
  7. data/README.md +284 -0
  8. data/Rakefile +6 -7
  9. data/VERSION +1 -1
  10. data/app/assets/javascripts/ckeditor/{config.js.coffee → config.js} +7 -6
  11. data/app/assets/stylesheets/message_train.scss +0 -8
  12. data/app/controllers/concerns/message_train_authorization.rb +37 -0
  13. data/app/controllers/concerns/message_train_support.rb +41 -69
  14. data/app/controllers/message_train/application_controller.rb +1 -0
  15. data/app/controllers/message_train/boxes_controller.rb +5 -4
  16. data/app/controllers/message_train/conversations_controller.rb +7 -5
  17. data/app/controllers/message_train/messages_controller.rb +43 -27
  18. data/app/controllers/message_train/participants_controller.rb +14 -25
  19. data/app/controllers/message_train/unsubscribes_controller.rb +96 -61
  20. data/app/helpers/message_train/application_helper.rb +13 -7
  21. data/app/helpers/message_train/attachments_helper.rb +4 -12
  22. data/app/helpers/message_train/boxes_helper.rb +4 -14
  23. data/app/helpers/message_train/collectives_helper.rb +23 -29
  24. data/app/helpers/message_train/conversations_helper.rb +52 -30
  25. data/app/helpers/message_train/messages_helper.rb +33 -20
  26. data/app/mailers/message_train/receipt_mailer.rb +22 -12
  27. data/app/models/message_train/attachment.rb +2 -2
  28. data/app/models/message_train/box.rb +182 -228
  29. data/app/models/message_train/conversation.rb +100 -103
  30. data/app/models/message_train/ignore.rb +83 -4
  31. data/app/models/message_train/message.rb +66 -117
  32. data/app/models/message_train/receipt.rb +73 -49
  33. data/app/views/message_train/boxes/show.html.haml +11 -7
  34. data/config/locales/en.yml +1 -0
  35. data/config/routes.rb +6 -12
  36. data/lib/message_train.rb +3 -1
  37. data/lib/message_train/class_methods.rb +51 -0
  38. data/lib/message_train/configuration.rb +28 -3
  39. data/lib/message_train/instance_methods.rb +209 -0
  40. data/lib/message_train/mixin.rb +25 -320
  41. data/message_train.gemspec +83 -83
  42. data/spec/controllers/message_train/boxes_controller_spec.rb +37 -19
  43. data/spec/controllers/message_train/concerns_spec.rb +21 -3
  44. data/spec/controllers/message_train/conversations_controller_spec.rb +41 -18
  45. data/spec/controllers/message_train/messages_controller_spec.rb +112 -31
  46. data/spec/controllers/message_train/participants_controller_spec.rb +33 -7
  47. data/spec/controllers/message_train/unsubscribes_controller_spec.rb +10 -8
  48. data/spec/dummy/app/assets/stylesheets/{application.css.scss → application.scss} +2 -1
  49. data/spec/dummy/app/assets/stylesheets/bootstrap-everything.scss +54 -0
  50. data/spec/dummy/app/models/group.rb +1 -1
  51. data/spec/dummy/app/views/layouts/application.html.haml +9 -8
  52. data/spec/dummy/bin/setup +8 -8
  53. data/spec/dummy/config/application.rb +0 -3
  54. data/spec/dummy/config/environments/test.rb +4 -2
  55. data/spec/dummy/db/schema.rb +94 -103
  56. data/spec/dummy/db/test.sqlite3 +0 -0
  57. data/spec/factories/attachment.rb +3 -1
  58. data/spec/factories/message.rb +2 -3
  59. data/spec/features/boxes_spec.rb +0 -3
  60. data/spec/helpers/message_train/application_helper_spec.rb +3 -2
  61. data/spec/helpers/message_train/attachment_helper_spec.rb +4 -0
  62. data/spec/helpers/message_train/boxes_helper_spec.rb +1 -0
  63. data/spec/helpers/message_train/collectives_helper_spec.rb +1 -0
  64. data/spec/helpers/message_train/conversations_helper_spec.rb +3 -2
  65. data/spec/helpers/message_train/messages_helper_spec.rb +2 -1
  66. data/spec/models/group_spec.rb +6 -4
  67. data/spec/models/message_train/box_spec.rb +0 -88
  68. data/spec/models/message_train/ignore_spec.rb +65 -0
  69. data/spec/models/message_train/message_spec.rb +6 -5
  70. data/spec/models/message_train/receipt_spec.rb +6 -8
  71. data/spec/models/role_spec.rb +2 -2
  72. data/spec/models/user_spec.rb +29 -101
  73. data/spec/rails_helper.rb +16 -30
  74. data/spec/support/feature_behaviors.rb +2 -1
  75. data/spec/support/shared_connection.rb +5 -0
  76. data/spec/support/utilities.rb +7 -8
  77. metadata +145 -120
  78. data/README.rdoc +0 -175
  79. data/spec/dummy/app/models/.keep +0 -0
  80. data/spec/dummy/log/.keep +0 -0
data/Rakefile CHANGED
@@ -10,21 +10,20 @@ rescue Bundler::BundlerError => e
10
10
  end
11
11
  require 'rake'
12
12
 
13
- require 'jeweler'
14
- Jeweler::Tasks.new do |gem|
13
+ require 'juwelier'
14
+ Juwelier::Tasks.new do |gem|
15
15
  # gem is a Gem::Specification...
16
16
  # see http://guides.rubygems.org/specification-reference/ for more options
17
17
  gem.name = 'message_train'
18
18
  gem.homepage = 'http://www.gemvein.com/museum/cases/message_train'
19
19
  gem.license = 'MIT'
20
- gem.summary = 'Rails 4 Engine providing messaging for any object'
21
- gem.description = 'Rails 4 Engine providing private/public messaging for '\
22
- 'any object, such as Users or Groups'
20
+ gem.summary = 'Rails 4 & 5 Engine providing messaging for any object'
21
+ gem.description = 'Rails 4 & 5 Engine providing private and public messaging'\
22
+ ' for any object, such as Users or Groups'
23
23
  gem.email = 'karen.e.lundgren@gmail.com'
24
24
  gem.authors = ['Karen Lundgren']
25
- # dependencies defined in Gemfile
26
25
  end
27
- Jeweler::RubygemsDotOrgTasks.new
26
+ Juwelier::RubygemsDotOrgTasks.new
28
27
 
29
28
  require 'rspec/core'
30
29
  require 'rspec/core/rake_task'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.17
1
+ 0.7.1
@@ -1,6 +1,6 @@
1
- CKEDITOR.editorConfig = (config) ->
2
- config.allowedContent = true
3
- config.width = '100%'
1
+ CKEDITOR.editorConfig = function(config) {
2
+ config.allowedContent = true;
3
+ config.width = '100%';
4
4
  config.toolbar_full = [
5
5
  {
6
6
  name: 'links',
@@ -43,6 +43,7 @@ CKEDITOR.editorConfig = (config) ->
43
43
  'RemoveFormat'
44
44
  ]
45
45
  }
46
- ]
47
- config.toolbar = 'full'
48
- true
46
+ ];
47
+ config.toolbar = 'full';
48
+ return true;
49
+ };
@@ -82,20 +82,12 @@ div.conversation-actions {
82
82
 
83
83
  td.conversation-actions {
84
84
  white-space: nowrap;
85
-
86
- a {
87
- visibility: hidden;
88
- }
89
85
  }
90
86
 
91
87
  .date-column {
92
88
  white-space: nowrap;
93
89
  }
94
90
 
95
- tr:hover .conversation-actions a {
96
- visibility: visible;
97
- }
98
-
99
91
  .glyphicon-thumbnail {
100
92
  font-size: 170px;
101
93
  }
@@ -0,0 +1,37 @@
1
+ # MessageTrain authorization
2
+ module MessageTrainAuthorization
3
+ extend ActiveSupport::Concern
4
+
5
+ protected
6
+
7
+ def authorize_collective(collective, division)
8
+ return false unless authorize_collective_access(collective)
9
+ case division
10
+ when :in, :ignored
11
+ authorize_collective_receiving(collective)
12
+ when :sent, :drafts
13
+ authorize_collective_sending(collective)
14
+ end
15
+ end
16
+
17
+ def authorize_collective_access(collective)
18
+ return true if collective.allows_access_by? @box_user
19
+ flash[:error] = :access_to_that_box_denied.l
20
+ redirect_to main_app.root_url
21
+ false
22
+ end
23
+
24
+ def authorize_collective_receiving(collective)
25
+ return true if collective.allows_receiving_by? @box_user
26
+ flash[:error] = :access_to_that_box_denied.l
27
+ redirect_to message_train.collective_box_url(collective.path_part, :sent)
28
+ false
29
+ end
30
+
31
+ def authorize_collective_sending(collective)
32
+ return true if collective.allows_sending_by? @box_user
33
+ flash[:error] = :access_to_that_box_denied.l
34
+ redirect_to message_train.collective_box_url(collective.path_part, :in)
35
+ false
36
+ end
37
+ end
@@ -3,13 +3,13 @@ module MessageTrainSupport
3
3
  extend ActiveSupport::Concern
4
4
  included do
5
5
  # Last in first out
6
- prepend_before_filter :load_collective_boxes,
6
+ prepend_before_action :load_collective_boxes,
7
7
  :load_box,
8
8
  :load_collective,
9
9
  :load_division,
10
10
  :load_box_user,
11
11
  unless: :devise_controller?
12
- before_filter :load_objects
12
+ before_action :load_objects
13
13
  before_action :set_locale
14
14
 
15
15
  helper MessageTrain::ApplicationHelper
@@ -24,6 +24,11 @@ module MessageTrainSupport
24
24
  end
25
25
  end
26
26
 
27
+ def redirect_to_sign_in
28
+ flash[:error] = :you_must_sign_in_or_sign_up_to_continue.l
29
+ redirect_to MessageTrain.configuration.user_sign_in_path
30
+ end
31
+
27
32
  protected
28
33
 
29
34
  def anonymous
@@ -36,9 +41,8 @@ module MessageTrainSupport
36
41
  end
37
42
 
38
43
  def load_box_user
39
- @box_user = send(
40
- MessageTrain.configuration.current_user_method
41
- ) || anonymous
44
+ @box_user = send(MessageTrain.configuration.current_user_method)
45
+ @box_user ||= anonymous
42
46
  end
43
47
 
44
48
  def load_division
@@ -46,45 +50,15 @@ module MessageTrainSupport
46
50
  end
47
51
 
48
52
  def load_collective
49
- if params[:collective_id].present?
50
- collective_table, collective_id = params[:collective_id].split(':')
51
- collective_class_name = MessageTrain.configuration.recipient_tables[
52
- collective_table.to_sym
53
- ]
54
- collective_model = collective_class_name.constantize
55
- slug_column = MessageTrain.configuration
56
- .slug_columns[collective_table.to_sym] || :slug
57
- @collective = collective_model.find_by!(slug_column => collective_id)
58
-
59
- unless @collective.allows_receiving_by?(
60
- @box_user
61
- ) || @collective.allows_sending_by?(
62
- @box_user
63
- )
64
- flash[:error] = :access_to_that_box_denied.l
65
- redirect_to main_app.root_url
66
- return
67
- end
53
+ return unless params[:collective_id].present?
54
+ collective_table, collective_id = params[:collective_id].split(':')
55
+ model = get_collective_model(collective_table)
56
+ @collective = model.find_by!(model.slug_column => collective_id)
57
+ authorize_collective(@collective, @division)
58
+ end
68
59
 
69
- case @division
70
- when :in, :ignored
71
- unless @collective.allows_receiving_by? @box_user
72
- flash[:error] = :access_to_that_box_denied.l
73
- redirect_to message_train.collective_box_url(
74
- @collective.path_part,
75
- :sent
76
- )
77
- end
78
- when :sent, :drafts
79
- unless @collective.allows_sending_by? @box_user
80
- flash[:error] = :access_to_that_box_denied.l
81
- redirect_to message_train.collective_box_url(
82
- @collective.path_part,
83
- :in
84
- )
85
- end
86
- end
87
- end
60
+ def get_collective_model(table)
61
+ MessageTrain.configuration.recipient_tables[table.to_sym].constantize
88
62
  end
89
63
 
90
64
  def load_box
@@ -100,39 +74,37 @@ module MessageTrainSupport
100
74
  end
101
75
 
102
76
  def load_objects
103
- @objects = {}
104
- @objects['conversations'] = {}
105
- @objects['messages'] = {}
106
- if params[:objects].present?
107
- params[:objects].each do |type, list|
108
- list.each do |key, list_item|
109
- @objects[type][key.to_s] = list_item.to_i
110
- end
77
+ @objects = { 'conversations' => {}, 'messages' => {} }
78
+ return unless params[:objects].present?
79
+ params[:objects].each do |type, list|
80
+ list.each do |key, list_item|
81
+ @objects[type][key.to_s] = list_item.to_i
111
82
  end
112
83
  end
113
84
  end
114
85
 
115
86
  def respond_to_marking
116
- if !@box.errors.all.empty?
117
- respond_to do |format|
118
- format.html do
119
- flash[:error] = @box.message
120
- show
121
- end
122
- format.json { render :results, status: :unprocessable_entity }
87
+ @box.errors.any? ? marking_error : marking_success
88
+ end
89
+
90
+ def marking_error
91
+ respond_to do |format|
92
+ format.html do
93
+ flash[:error] = @box.message
94
+ show
123
95
  end
124
- else
125
- respond_to do |format|
126
- format.html do
127
- if @box.results.all.empty?
128
- flash[:alert] = @box.message
129
- else
130
- flash[:notice] = @box.message
131
- end
132
- show
133
- end
134
- format.json { render :results, status: :accepted }
96
+ format.json { render :results, status: :unprocessable_entity }
97
+ end
98
+ end
99
+
100
+ def marking_success
101
+ respond_to do |format|
102
+ format.html do
103
+ flash_type = @box.results.any? ? :notice : :alert
104
+ flash[flash_type] = @box.message
105
+ show
135
106
  end
107
+ format.json { render :results, status: :accepted }
136
108
  end
137
109
  end
138
110
  end
@@ -2,5 +2,6 @@ module MessageTrain
2
2
  # Application controller
3
3
  class ApplicationController < ::ApplicationController
4
4
  include MessageTrainSupport
5
+ include MessageTrainAuthorization
5
6
  end
6
7
  end
@@ -1,11 +1,12 @@
1
1
  module MessageTrain
2
2
  # Boxes controller
3
3
  class BoxesController < MessageTrain::ApplicationController
4
- before_filter :load_conversations
4
+ before_action :load_conversations
5
5
 
6
6
  # GET /box/:division
7
7
  def show
8
- @conversations = @conversations.page(params[:page])
8
+ @conversations = @conversations.order(updated_at: :desc)
9
+ .page(params[:page])
9
10
  render :show
10
11
  end
11
12
 
@@ -19,8 +20,8 @@ module MessageTrain
19
20
 
20
21
  # DELETE /box/:division
21
22
  def destroy
22
- if %w( ignore unignore ).include? params[:mark_to_set]
23
- @box.send(params[:mark_to_set], @objects)
23
+ if %w(ignore unignore).include? params[:mark_to_set]
24
+ MessageTrain::Ignore.send(params[:mark_to_set], @objects, @box)
24
25
  end
25
26
  respond_to_marking
26
27
  end
@@ -1,12 +1,14 @@
1
1
  module MessageTrain
2
2
  # Conversations controller
3
3
  class ConversationsController < MessageTrain::ApplicationController
4
- before_filter :load_conversation
5
- after_filter :mark_as_read
4
+ before_action :load_conversation
5
+ after_action :mark_as_read
6
6
 
7
7
  # GET /box/:division/conversations/:id
8
8
  def show
9
- @messages = @conversation.messages.page(params[:page])
9
+ @messages = @conversation.messages
10
+ .order(updated_at: :desc)
11
+ .page(params[:page])
10
12
  render :show
11
13
  @box.mark :read, @messages
12
14
  end
@@ -21,8 +23,8 @@ module MessageTrain
21
23
 
22
24
  # DELETE /box/:division/conversations/:id
23
25
  def destroy
24
- if %w( ignore unignore ).include? params[:mark_to_set]
25
- @box.send(params[:mark_to_set], @conversation)
26
+ if %w(ignore unignore).include? params[:mark_to_set]
27
+ MessageTrain::Ignore.send(params[:mark_to_set], @conversation, @box)
26
28
  end
27
29
  respond_to_marking
28
30
  end
@@ -1,7 +1,7 @@
1
1
  module MessageTrain
2
2
  # Messages controller
3
3
  class MessagesController < MessageTrain::ApplicationController
4
- before_filter :load_message, only: [:show, :edit, :update]
4
+ before_action :load_message, only: [:show, :edit, :update]
5
5
 
6
6
  # GET /box/in/messages/1
7
7
  def show
@@ -12,9 +12,12 @@ module MessageTrain
12
12
 
13
13
  # GET /box/:division/messages/new
14
14
  def new
15
- @message = @box.new_message(
16
- message_train_conversation_id: params[:conversation_id]
17
- )
15
+ if params[:conversation_id]
16
+ @conversation = @box.find_conversation params[:conversation_id]
17
+ @message = @conversation.new_reply(box: @box)
18
+ else
19
+ @message = MessageTrain::Message.new(box: @box)
20
+ end
18
21
  end
19
22
 
20
23
  # GET /box/:division/messages/:id/edit
@@ -25,42 +28,55 @@ module MessageTrain
25
28
  # POST /box/:division/messages
26
29
  def create
27
30
  @message = @box.send_message(message_params)
28
- if @box.errors.all.empty?
29
- if @message.draft
30
- redirect_to message_train.box_path(:drafts), alert: @box.message
31
- else
32
- redirect_to message_train.box_path(:sent), notice: @box.message
33
- end
31
+ return create_error if @box.errors.any?
32
+ if @message.draft
33
+ redirect_to message_train.box_path(:drafts), alert: @box.message
34
34
  else
35
- flash[:error] = @box.message
36
- render :new
35
+ redirect_to message_train.box_path(:sent), notice: @box.message
37
36
  end
38
37
  end
39
38
 
40
39
  # PATCH/PUT /box/:division/messages/:id
41
40
  def update
42
- !@message.draft && raise(ActiveRecord::RecordNotFound)
43
41
  @box.update_message(@message, message_params)
44
- if @box.errors.all.empty?
45
- if @message.draft
46
- redirect_to(
47
- message_train.box_conversation_url(@box, @message.conversation),
48
- alert: @box.message
49
- )
50
- else
51
- redirect_to(
52
- message_train.box_path(:sent),
53
- notice: @box.message
54
- )
55
- end
42
+
43
+ return update_error if @box.errors.any?
44
+
45
+ if @message.draft
46
+ redirect_draft
56
47
  else
57
- flash[:error] = @box.message
58
- render :edit
48
+ redirect_ready
59
49
  end
60
50
  end
61
51
 
62
52
  private
63
53
 
54
+ def redirect_draft
55
+ redirect_to(
56
+ message_train.box_conversation_url(@box, @message.conversation),
57
+ alert: @box.message
58
+ )
59
+ end
60
+
61
+ def redirect_ready
62
+ redirect_to(
63
+ message_train.box_path(:sent),
64
+ notice: @box.message
65
+ )
66
+ end
67
+
68
+ def update_error
69
+ flash[:error] = @box.message
70
+ render :edit
71
+ false
72
+ end
73
+
74
+ def create_error
75
+ flash[:error] = @box.message
76
+ render :new
77
+ false
78
+ end
79
+
64
80
  def load_message
65
81
  @message = @box.find_message(params[:id])
66
82
  end
@@ -1,17 +1,18 @@
1
1
  module MessageTrain
2
2
  # Participants controller
3
3
  class ParticipantsController < MessageTrain::ApplicationController
4
- before_filter :load_participants
5
- before_filter :load_participant, only: :show
4
+ before_action :load_model
5
+ before_action :load_participants
6
+ before_action :load_participant, only: :show
6
7
 
7
- # GET /box/:division/participants/:model
8
+ # GET /box/:division/participants/:model.json
8
9
  def index
9
10
  respond_to do |format|
10
11
  format.json { render :index }
11
12
  end
12
13
  end
13
14
 
14
- # GET /box/:division/participants/:model/:id
15
+ # GET /box/:division/participants/:model/:id.json
15
16
  def show
16
17
  respond_to do |format|
17
18
  format.json { render :show }
@@ -20,29 +21,17 @@ module MessageTrain
20
21
 
21
22
  private
22
23
 
23
- def load_participants
24
+ def load_model
24
25
  params[:model].empty? && raise(ActiveRecord::RecordNotFound)
25
- model_sym = params[:model].to_sym
26
- model = MessageTrain.configuration.recipient_tables[model_sym].constantize
27
- method = MessageTrain.configuration.address_book_methods[model_sym]
28
- fallback_method = MessageTrain.configuration.address_book_method
26
+ @model = MessageTrain.configuration
27
+ .recipient_tables[params[:model].to_sym]
28
+ .constantize
29
+ end
30
+
31
+ def load_participants
29
32
  current_participant = send(MessageTrain.configuration.current_user_method)
30
- if !method.nil? && model.respond_to?(method)
31
- @participants = model.send(method, current_participant)
32
- elsif !fallback_method.nil? && model.respond_to?(fallback_method)
33
- @participants = model.send(fallback_method, current_participant)
34
- else
35
- @participants = model.all
36
- end
37
- if params[:query].present?
38
- field_name = MessageTrain.configuration.slug_columns[model_sym]
39
- pattern = Regexp.union('\\', '%', '_')
40
- query = params[:query].gsub(pattern) { |x| ['\\', x].join }
41
- @participants = @participants.where(
42
- "#{field_name} LIKE ?",
43
- "#{query}%"
44
- )
45
- end
33
+ @participants = @model.message_train_address_book(current_participant)
34
+ @participants = @participants.where_slug_starts_with(params[:query])
46
35
  end
47
36
 
48
37
  def load_participant