tb_core 1.3.5 → 1.3.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 06f0ab03560e57efe477e7fb0f9ae6f72a8a042c
4
- data.tar.gz: e8d702fe0332d78ae18bc9d0605db1d89ec3cb26
3
+ metadata.gz: f6bf453f0beae57a1071c09c8d17bb2af451d8f1
4
+ data.tar.gz: 24fcc7c6774cf0957886dd28675a5fa9fd8cdc6f
5
5
  SHA512:
6
- metadata.gz: 6b6d73ea8d50f6930b71df507147e5644128cd2a04024522984aed28fe1832dcc1e9e37059945c34e22a31b41747d9a914868af5eead68d5a466917bdd3b0a46
7
- data.tar.gz: 778f7e4d4a48508249c54cff93cdda5334a0beddf158e4a5b68eaab544e9cc6539a53b18fc8aa64480267b549a436cf2713f4d7b7344380a6a232ae815071a40
6
+ metadata.gz: 6e82de4ddd86404ab8a03bce734b7bc6a5f57e63e1528d9b9c4e58b687cb0eee48bb41f6921997463e68d7062bc09f76f52cd4b3bdfebb544ba75e3db32b33e5
7
+ data.tar.gz: ed7a6ac11107b0602eb0d21a50af16662657aa0462e7a288acb5f00c9dda9c78e364478d45e9d0b6a93438f2629fb7bb92a401df7a57da0978ddeca17586defe
@@ -1,5 +1,4 @@
1
1
  //= require jquery
2
- //= require jquery_ujs
3
2
  //= require tinymce-jquery
4
3
  //= require bootstrap-sprockets
5
4
  //= require ../../tb_core
@@ -1,3 +1,6 @@
1
+ //= require_self
2
+ //= require jquery_ujs
3
+
1
4
  (function(){
2
5
 
3
6
  /*
@@ -20,15 +23,17 @@ tb.remote = {
20
23
  $document.on('ajax:error', 'form[data-errors]', onRemoteFormErrors);
21
24
  $document.on('ajax:success', 'tr a[data-method=delete][data-remote=true]', onRemoteDeleteTableRow);
22
25
  $document.on('ajax:aborted:file', 'form', onRemoteAbortedFile);
26
+ $document.ready(extendEnableFormElementMethod);
23
27
  }
24
28
  };
25
29
 
26
30
  /*
27
31
  * UJS likes to request application/javascript by default, but Twice Baked prefers JSON.
28
32
  */
29
- var onRemoteFormBefore = function(xhr, settings){
30
- if($(this).data('type') === undefined){
31
- $(this).data('type', 'json');
33
+ var onRemoteFormBefore = function(event){
34
+ var $form = $(this);
35
+ if($form.data('type') === undefined){
36
+ $form.data('type', 'json');
32
37
  }
33
38
  };
34
39
 
@@ -97,7 +102,7 @@ var onRemoteFormErrors = function(event, jqXHR, textStatus, errorThrown){
97
102
  displayErrorsInline($form, jqXHR.responseJSON.errors);
98
103
  }
99
104
  else{
100
- displayErrorsAlert(jqXHR.responseJSON.full_messages);
105
+ displayErrorsAlert(jqXHR.responseJSON);
101
106
  }
102
107
  }
103
108
  else if(jqXHR.status == 401 || jqXHR.status == 403){
@@ -159,11 +164,15 @@ var displayErrorsInline = function($form, errors){
159
164
  /*
160
165
  * Display errors in a standard window.alert dialog
161
166
  */
162
- var displayErrorsAlert = function(errors){
167
+ var displayErrorsAlert = function(json){
163
168
  var text = "Please correct the following errors:\n";
164
- var len = errors.length;
165
- for(var i=0; i<len; i++){
166
- text += " - " + errors[i] + "\n";
169
+ var label, message;
170
+ var index = 0;
171
+ for(var key in json.errors){
172
+ label = json.labels[index];
173
+ message = json.errors[key][0];
174
+ text += " - " + label + ' ' + message + "\n";
175
+ index++;
167
176
  }
168
177
  window.alert(text);
169
178
  };
@@ -208,24 +217,26 @@ var onRemoteAbortedFile = function(event, inputs){
208
217
  * delay and a success text value to the button before returning to
209
218
  * default state.
210
219
  */
211
- var originalEnableFormElement = $.rails.enableFormElement;
212
-
213
- $.rails.enableFormElement = function(element){
214
- var success = $(element).parents('form').data('lastRemoteSuccess');
215
- var message = element.data('enableWith');
216
-
217
- if(success && message){
218
- var method = element.is('button') ? 'html' : 'val';
219
- element[method](message);
220
- setTimeout(function(){
221
- originalEnableFormElement(element);
222
- }, 1000);
223
- }
224
- else{
225
- originalEnableFormElement(element);
226
- }
220
+ var extendEnableFormElementMethod = function(){
221
+ var originalEnableFormElement = $.rails.enableFormElement;
222
+
223
+ $.rails.enableFormElement = function(element){
224
+ var success = $(element).parents('form').data('lastRemoteSuccess');
225
+ var message = element.data('enableWith');
226
+
227
+ if(success && message){
228
+ var method = element.is('button') ? 'html' : 'val';
229
+ element[method](message);
230
+ setTimeout(function(){
231
+ originalEnableFormElement(element);
232
+ }, 1000);
233
+ }
234
+ else{
235
+ originalEnableFormElement(element);
236
+ }
237
+ };
227
238
  };
228
239
 
229
- $(document).ready(tb.remote.init);
240
+ tb.remote.init();
230
241
 
231
242
  })();
@@ -4,7 +4,6 @@ class Admin::ApplicationController < Spud::ApplicationController
4
4
  add_breadcrumb "Dashboard", :admin_root_path
5
5
  layout 'admin/detail'
6
6
  respond_to :html, :json
7
- # self.responder = TbCore::Responder
8
7
 
9
8
  private
10
9
 
@@ -2,7 +2,7 @@ class Admin::RolesController < Admin::ApplicationController
2
2
 
3
3
  before_action :get_record, :only => [:show, :edit, :update, :destroy]
4
4
  respond_to :html, :json, :xml
5
- belongs_to_spud_app :users
5
+ belongs_to_app :users
6
6
  add_breadcrumb "Users", :admin_users_path
7
7
  add_breadcrumb "Roles", :admin_roles_path
8
8
 
@@ -14,14 +14,14 @@ class Admin::SettingsController < Admin::ApplicationController
14
14
  end
15
15
 
16
16
  def update
17
- if @current_user.update_attributes(user_params)
17
+ if check_password && @current_user.update_attributes(user_params)
18
18
  if user_params.include?(:password)
19
- SpudUserSession.create(@current_user)
19
+ SpudUserSession.create(@current_user)
20
20
  end
21
21
  flash[:notice] = "User settings saved successfully."
22
22
  respond_with @current_user, :location => admin_settings_path
23
23
  else
24
- render 'edit'
24
+ render 'edit', :status => 401
25
25
  end
26
26
  end
27
27
 
@@ -31,4 +31,16 @@ private
31
31
  params.require(:spud_user).permit(:login, :first_name, :last_name, :email, :password, :password_confirmation, :time_zone)
32
32
  end
33
33
 
34
+ def check_password
35
+ if params[:spud_user][:password].nil? || params[:spud_user][:password].empty?
36
+ return true
37
+ else
38
+ if !current_user.valid_password?(params[:current_password])
39
+ current_user.errors.add(:current_password, "is not correct. Please enter correct password.")
40
+ return false
41
+ end
42
+ return true
43
+ end
44
+ end
45
+
34
46
  end
@@ -1,7 +1,6 @@
1
1
  class Admin::UsersController < Admin::ApplicationController
2
2
 
3
- self.responder = TbCore::Responder
4
- belongs_to_spud_app :users
3
+ belongs_to_app :users
5
4
  add_breadcrumb "Users", :admin_users_path
6
5
  before_action :load_user, :only => [:edit, :update, :show, :destroy]
7
6
  after_action :send_credentials_email, :only => [:create, :update]
@@ -10,6 +10,8 @@ class Spud::ApplicationController < ActionController::Base
10
10
  include TbCore::ApplicationHelper
11
11
  before_action :set_mailer_default_url
12
12
 
13
+ self.responder = TbCore::Responder
14
+
13
15
  rescue_from Spud::RequestError, :with => :handle_request_error
14
16
  rescue_from ActiveRecord::RecordNotFound, :with => :handle_record_not_found
15
17
  rescue_from ActionController::UnknownFormat, :with => :handle_unknown_format_error
@@ -4,7 +4,6 @@
4
4
  skip_before_action :check_requires_password_change, :only => [:destroy, :change_password, :set_change_password]
5
5
 
6
6
  respond_to :html, :json, :js
7
- self.responder = TbCore::Responder
8
7
  layout 'user_sessions'
9
8
 
10
9
  def new
@@ -38,7 +38,14 @@
38
38
  <h4>Credentials</h4>
39
39
 
40
40
  <div class="form-group">
41
- <%= f.label :password, :class => "col-sm-2 control-label" %>
41
+ <%= f.label :current_password, :class => "col-sm-2 control-label" %>
42
+ <div class="col-sm-10">
43
+ <%= password_field :current_password, nil, class:"form-control" %>
44
+ <p class="help-block">Enter current password to change it.</p>
45
+ </div>
46
+ </div>
47
+ <div class="form-group">
48
+ <%= f.label "New Password", :class => "col-sm-2 control-label" %>
42
49
  <div class="col-sm-10">
43
50
  <%= f.password_field :password, :title => "", :class => 'form-control', :autocomplete => 'new-password' %>
44
51
  <p class="help-block">Password must be at least 8 characters</p>
@@ -1,6 +1,6 @@
1
1
  class Admin::<%= module_name_formatted.camelize%>Controller < Admin::ApplicationController
2
2
 
3
- belongs_to_spud_app :<%= module_name_formatted %>
3
+ belongs_to_app :<%= module_name_formatted %>
4
4
  add_breadcrumb "<%= module_name_formatted.humanize.titlecase %>", :admin_<%= module_name_formatted %>_path
5
5
  before_action :load_<%= module_name_formatted.singularize %>, :only => [:show, :edit, :update, :destroy]
6
6
 
@@ -1,5 +1,4 @@
1
1
  //= require jquery
2
- //= require jquery_ujs
3
2
  //= require tb_core
4
3
  //= require bootstrap_modules
5
4
  //= require_self
@@ -16,7 +16,6 @@ end
16
16
  module Spud
17
17
  module Core
18
18
  class Engine < ::Rails::Engine
19
- require "#{root}/lib/spud_core/belongs_to_app"
20
19
  require "#{root}/lib/spud_core/errors"
21
20
  require "#{root}/lib/spud_core/searchable"
22
21
  require "#{root}/lib/responds_to_parent"
@@ -26,7 +25,7 @@ module Spud
26
25
 
27
26
  initializer 'tb_core.controller_overrides' do |config|
28
27
  ActionController::Base.class_eval do
29
- include Spud::BelongsToApp
28
+ include TbCore::BelongsToApp
30
29
  end
31
30
  end
32
31
 
@@ -78,6 +77,10 @@ module Spud
78
77
  end
79
78
  end
80
79
 
80
+ initializer 'tb_core.assets' do
81
+ Rails.application.config.assets.precompile += ['admin/users_thumb.png', 'admin/module_icon.png']
82
+ end
83
+
81
84
  end
82
85
  end
83
86
  end
@@ -1,5 +1,5 @@
1
1
  module Spud
2
2
  module Core
3
- VERSION = "1.3.5"
3
+ VERSION = "1.3.6"
4
4
  end
5
5
  end
@@ -0,0 +1,55 @@
1
+ module TbCore::BelongsToApp
2
+ extend ActiveSupport::Concern
3
+
4
+ module ClassMethods
5
+ def belongs_to_spud_app(name, options={})
6
+ ActiveSupport::Deprecation.warn 'ApplicationController#belongs_to_spud_app is deprecated. Please use #belongs_to_app instead.', caller
7
+ belongs_to_app(name, page_title: options[:page_title])
8
+ end
9
+
10
+ # Adds a before action to the current controller to act like the specified twice baked app
11
+ #
12
+ # symbol: This should be the :key value for the app you want to use
13
+ # page_title: Override the base name value for the app (optional)
14
+ # only: An array of controller actions you want this to apply to (optional)
15
+ #
16
+ def belongs_to_app(name, page_title: nil, only: nil)
17
+ before_action ->(){
18
+ act_as_app(name, page_title: page_title)
19
+ }, :only => only
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ # Call the make the current controller behave as though it belongs to the specified twice baked app
26
+ #
27
+ # symbol: This should be the :key value for the app you want to use
28
+ # page_title: Override the base name value for the app (optional)
29
+ #
30
+ def act_as_app(symbol, page_title: nil)
31
+ @page_application = Spud::Core.admin_applications.find{ |app| app[:key] == symbol }
32
+ if @page_application.blank?
33
+ raise "Requested application '#{symbol}' could not be found"
34
+ elsif !current_user.can_view_app?(@page_application)
35
+ raise Spud::AccessDeniedError.new(:item => 'module', :template => '/layouts/admin/error_page')
36
+ end
37
+ @page_thumbnail = @page_application[:thumbnail]
38
+ @page_name = determine_page_name(page_title || @page_application[:name], action_name)
39
+ end
40
+
41
+ # Takes a base app name and controller action name and returns an appropriate page title
42
+ #
43
+ def determine_page_name(base_name, action_name)
44
+ if action_name == 'new' || action_name == 'create'
45
+ return "New #{base_name.singularize}"
46
+ elsif action_name == 'edit' || action_name == 'update'
47
+ return "Edit #{base_name.singularize}"
48
+ elsif action_name == 'show'
49
+ return "#{base_name.singularize} Detail"
50
+ else
51
+ return base_name
52
+ end
53
+ end
54
+
55
+ end
@@ -109,12 +109,16 @@ class TbCore::FormBuilder < ActionView::Helpers::FormBuilder
109
109
 
110
110
  # Builds a row of save/cancel buttons
111
111
  #
112
- def tb_save_buttons(model_name, cancel_path)
112
+ def tb_save_buttons(model_name, cancel_path, delete_path=nil)
113
113
  content_tag :div, :class => 'form-group' do
114
114
  content_tag :div, :class => 'col-sm-offset-2 col-sm-10' do
115
115
  concat submit "Save #{model_name}", :class => 'btn btn-primary', :data => {:disable_with => "Saving #{model_name}...", :enable_with => 'Saved!'}
116
116
  concat ' '
117
117
  concat @template.link_to 'Cancel', cancel_path, :class => 'btn btn-default', :data => {:dismiss => :modal}
118
+ if delete_path != nil
119
+ concat ' '
120
+ concat @template.link_to 'Delete', delete_path, :class => 'btn btn-danger', :data => {:confirm => "This action can't be undone. Would you like to delete the #{model_name.downcase}?"}, :method => :delete
121
+ end
118
122
  end
119
123
  end
120
124
  end
@@ -1,5 +1,14 @@
1
1
  module TbCore::Mysql2Extensions
2
- extend ActiveSupport::Concern
2
+
3
+ # Create a new table
4
+ #
5
+ def create_table(table_name, options = {})
6
+ if @connection.query_options[:encoding] == 'utf8mb4'
7
+ super(table_name, options.reverse_merge(:options => 'ROW_FORMAT=DYNAMIC ENGINE=InnoDB'))
8
+ else
9
+ super
10
+ end
11
+ end
3
12
 
4
13
  # Build a hash of length options for a given table and column name
5
14
  #
@@ -23,10 +23,13 @@ class TbCore::Responder < ActionController::Responder
23
23
  end
24
24
 
25
25
  # Default responder only sends the basic errors array
26
- # This override also sends the full messages for convenience
26
+ # This override also sends the translated labels for convenience
27
27
  #
28
28
  def json_resource_errors
29
- return {:errors => resource.errors, :full_messages => resource.errors.full_messages}
29
+ return {
30
+ :errors => resource.errors,
31
+ :labels => resource.errors.keys.collect{ |attribute| resource.class.human_attribute_name(attribute) }
32
+ }
30
33
  end
31
34
 
32
35
  end
@@ -13,6 +13,13 @@ describe Admin::SettingsController, :type => :controller do
13
13
  end
14
14
 
15
15
  describe 'update' do
16
+ it "should give an error if password change does not include a valid current password" do
17
+ u = FactoryGirl.build(:spud_user)
18
+ u.password = "test"
19
+ put :update, :spud_user => {:first_name => "Mike", :password => "Imapassword", :current_password => "ImaTest"}
20
+ is_expected.to respond_with 401
21
+ end
22
+
16
23
  it "should redirect to the settings page with a successful update" do
17
24
  put :update, :spud_user => {:first_name => "Mike"}
18
25
  expect(response).to redirect_to(admin_settings_path)
@@ -1,5 +1,4 @@
1
1
  //= require jquery
2
- //= require jquery_ujs
3
2
  //= require tb_core
4
3
  //= require bootstrap-sprockets
5
4
  //= require_self
@@ -0,0 +1,67 @@
1
+ require 'rails_helper'
2
+
3
+ class DummyController < ActionController::Base
4
+ attr_accessor :current_user
5
+ end
6
+
7
+ describe TbCore::BelongsToApp do
8
+
9
+ let(:controller){
10
+ DummyController.new()
11
+ }
12
+
13
+ before(:each) do
14
+
15
+ end
16
+
17
+ describe '.belongs_to_app' do
18
+ it 'should add a before_action' do
19
+ # Not sure how to test for this...
20
+ DummyController.belongs_to_app(:users)
21
+ end
22
+ end
23
+
24
+ describe '#acts_as_app' do
25
+ it 'should configure the app' do
26
+ controller.current_user = FactoryGirl.create(:spud_user, :super_admin => true)
27
+ controller.send(:act_as_app, :users)
28
+ expect(controller.instance_variable_get('@page_application')).to be_a(Hash)
29
+ end
30
+
31
+ it 'should raise an error if the app cannot be found' do
32
+ expect{
33
+ controller.send(:act_as_app, :fail)
34
+ }.to raise_error
35
+ end
36
+
37
+ it 'should raise an error if the user does not have access' do
38
+ controller.current_user = FactoryGirl.create(:spud_user, :super_admin => false)
39
+ expect{
40
+ controller.send(:act_as_app, :users)
41
+ }.to raise_error(Spud::AccessDeniedError)
42
+ end
43
+ end
44
+
45
+ describe '#determine_page_name' do
46
+ it 'should contain "New"' do
47
+ result = controller.send(:determine_page_name, 'Users', 'new')
48
+ expect(result).to eq('New User')
49
+ end
50
+
51
+ it 'should contain "Edit"' do
52
+ result = controller.send(:determine_page_name, 'Users', 'edit')
53
+ expect(result).to eq('Edit User')
54
+ end
55
+
56
+ it 'should contain "Detail"' do
57
+ result = controller.send(:determine_page_name, 'Users', 'show')
58
+ expect(result).to eq('User Detail')
59
+ end
60
+
61
+ it 'should return the base name' do
62
+ result = controller.send(:determine_page_name, 'Users', 'other')
63
+ expect(result).to eq('Users')
64
+ end
65
+ end
66
+
67
+ end
@@ -6,6 +6,19 @@ describe TbCore::Mysql2Extensions do
6
6
  SpudUser.connection
7
7
  }
8
8
 
9
+ describe '#create_table' do
10
+ before(:each){
11
+ allow_any_instance_of(ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter).to receive(:create_table) do |abstract_adapter, table_name, arguments|
12
+ arguments[:options]
13
+ end
14
+ }
15
+
16
+ it 'should pass the dynamic option' do
17
+ options = adapter.create_table(:tests)
18
+ expect(options).to match('ROW_FORMAT=DYNAMIC')
19
+ end
20
+ end
21
+
9
22
  describe '#length_options_for_utf8mb4_string_index' do
10
23
  it 'should return a hash with a single value' do
11
24
  options = adapter.length_options_for_utf8mb4_string_index(:spud_users, :first_name)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tb_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.5
4
+ version: 1.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg Woods
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-12 00:00:00.000000000 Z
11
+ date: 2016-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -410,7 +410,6 @@ files:
410
410
  - lib/generators/spud/templates/views/layouts/application.html.erb
411
411
  - lib/generators/spud/templates/views/layouts/error_page.html.erb
412
412
  - lib/responds_to_parent.rb
413
- - lib/spud_core/belongs_to_app.rb
414
413
  - lib/spud_core/catch_all_route.rb
415
414
  - lib/spud_core/configuration.rb
416
415
  - lib/spud_core/engine.rb
@@ -420,6 +419,7 @@ files:
420
419
  - lib/spud_core/version.rb
421
420
  - lib/tasks/spud_core_tasks.rake
422
421
  - lib/tb_core.rb
422
+ - lib/tb_core/belongs_to_app.rb
423
423
  - lib/tb_core/form_builder.rb
424
424
  - lib/tb_core/mysql2_extensions.rb
425
425
  - lib/tb_core/responder.rb
@@ -478,6 +478,7 @@ files:
478
478
  - spec/factories/spud_user_factories.rb
479
479
  - spec/helpers/spud/admin/application_helper_spec.rb
480
480
  - spec/lib/spud_core/configuration_spec.rb
481
+ - spec/lib/tb_core/belongs_to_app_spec.rb
481
482
  - spec/lib/tb_core/mysql2_extensions_spec.rb
482
483
  - spec/models/spud_role_spec.rb
483
484
  - spec/models/spud_user_spec.rb
@@ -561,6 +562,7 @@ test_files:
561
562
  - spec/factories/spud_user_factories.rb
562
563
  - spec/helpers/spud/admin/application_helper_spec.rb
563
564
  - spec/lib/spud_core/configuration_spec.rb
565
+ - spec/lib/tb_core/belongs_to_app_spec.rb
564
566
  - spec/lib/tb_core/mysql2_extensions_spec.rb
565
567
  - spec/models/spud_role_spec.rb
566
568
  - spec/models/spud_user_spec.rb
@@ -1,46 +0,0 @@
1
- module Spud::BelongsToApp
2
- extend ActiveSupport::Concern
3
-
4
- included do
5
- extend ClassMethods
6
- end
7
-
8
- module ClassMethods
9
- def belongs_to_spud_app(name=nil,options={})
10
- @page_title = options[:page_title]
11
- Spud::Core.admin_applications.each do |app|
12
- if app[:key] == name
13
- @page_application = app
14
- break
15
- end
16
- end
17
- self.class_eval do
18
- before_action do |controller|
19
- @page_thumbnail = self.class.page_application[:thumbnail]
20
- @application_name = self.class.page_application[:name]
21
- @page_name = self.class.page_title
22
-
23
- if !current_user.can_view_app?(self.class.page_application)
24
- raise Spud::AccessDeniedError.new(:item => 'module', :template => '/layouts/admin/error_page')
25
- end
26
-
27
- if controller.action_name == 'new' || controller.action_name == 'create'
28
- @page_name = "New #{@page_name.singularize}"
29
- elsif controller.action_name == 'edit' || controller.action_name == 'update'
30
- @page_name = "Edit #{@page_name.singularize}"
31
- elsif controller.action_name == 'show'
32
- @page_name = "#{@page_name.singularize} Detail"
33
- end
34
- end
35
- end
36
- end
37
-
38
- def page_application
39
- @page_application || self.superclass.instance_variable_get('@page_application')
40
- end
41
-
42
- def page_title
43
- @page_title || self.superclass.instance_variable_get('@page_title') || page_application[:name]
44
- end
45
- end
46
- end