pg_rails 7.5.2 → 7.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/pg_associable/app/helpers/pg_associable/helpers.rb +19 -2
  3. data/pg_associable/app/javascript/asociable_controller.tsx +1 -1
  4. data/pg_associable/spec/pg_associable/helpers_spec.rb +54 -2
  5. data/pg_engine/app/controllers/admin/user_accounts_controller.rb +5 -1
  6. data/pg_engine/app/controllers/concerns/pg_engine/require_tenant_set.rb +1 -1
  7. data/pg_engine/app/controllers/concerns/pg_engine/resource.rb +1 -3
  8. data/pg_engine/app/controllers/pg_engine/base_controller.rb +7 -4
  9. data/pg_engine/app/controllers/pg_engine/base_public_controller.rb +4 -0
  10. data/pg_engine/app/controllers/pg_engine/health_controller.rb +0 -1
  11. data/pg_engine/app/controllers/users/account_switcher_controller.rb +2 -0
  12. data/pg_engine/app/controllers/users/accounts_controller.rb +35 -0
  13. data/pg_engine/app/helpers/pg_engine/flash_helper.rb +1 -2
  14. data/pg_engine/app/models/account.rb +5 -0
  15. data/pg_engine/app/models/email.rb +0 -1
  16. data/pg_engine/app/models/pg_engine/base_record.rb +3 -1
  17. data/pg_engine/app/models/user.rb +21 -0
  18. data/pg_engine/app/models/user_account.rb +7 -3
  19. data/pg_engine/app/policies/account_policy.rb +4 -0
  20. data/pg_engine/app/views/admin/user_accounts/_form.html.slim +2 -2
  21. data/pg_engine/app/views/users/account_switcher/list.html.slim +23 -5
  22. data/pg_engine/app/views/users/accounts/show.html.slim +13 -0
  23. data/pg_engine/config/initializers/acts_as_tenant.rb +3 -12
  24. data/pg_engine/config/routes.rb +3 -0
  25. data/pg_engine/db/seeds.rb +12 -11
  26. data/pg_engine/lib/pg_engine/utils/pg_logger.rb +5 -0
  27. data/pg_engine/spec/controllers/admin/accounts_controller_spec.rb +1 -1
  28. data/pg_engine/spec/controllers/admin/users_controller_spec.rb +1 -1
  29. data/pg_engine/spec/controllers/devise/sessions_controller_spec.rb +1 -0
  30. data/pg_engine/spec/controllers/users/registrations_controller_spec.rb +1 -1
  31. data/pg_engine/spec/factories/users.rb +5 -1
  32. data/pg_engine/spec/lib/pg_engine/mailgun/log_sync_spec.rb +4 -0
  33. data/pg_engine/spec/models/email_spec.rb +5 -0
  34. data/pg_engine/spec/models/user_spec.rb +7 -0
  35. data/pg_engine/spec/requests/current_attributes_spec.rb +22 -0
  36. data/pg_engine/spec/requests/devise_spec.rb +24 -0
  37. data/pg_engine/spec/requests/users/accounts_spec.rb +22 -0
  38. data/pg_engine/spec/requests/users/switcher_spec.rb +20 -2
  39. data/pg_engine/spec/system/tenants_spec.rb +1 -1
  40. data/pg_layout/app/views/devise/sessions/new.html.erb +1 -1
  41. data/pg_layout/app/views/pg_layout/_sidebar.html.erb +12 -5
  42. data/pg_rails/lib/pg_rails/current_attributes_support.rb +6 -0
  43. data/pg_rails/lib/pg_rails/rspec_logger_matchers.rb +13 -1
  44. data/pg_rails/lib/version.rb +1 -1
  45. data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/controller_spec.rb +1 -0
  46. data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/edit_spec.rb +1 -1
  47. data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/index_spec.rb +1 -1
  48. data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/new_spec.rb +1 -1
  49. data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/show_spec.rb +1 -1
  50. metadata +7 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cbc9c1b9067850c9f99c3a28d9252248c8657cacbd7cade188c50bced6d4559d
4
- data.tar.gz: 4a9b8e39d04fa9837a488262f679c93f946461140229d7da84c124ade30bd120
3
+ metadata.gz: 0f12846cd393967f0aac07acebf37b6799a9e67983da3ee892311aac4fd8a93b
4
+ data.tar.gz: dc6a9d65a1454b891de4bcd751f5f74f1b51a27d2fdc46c0baaf216db28a9306
5
5
  SHA512:
6
- metadata.gz: dec0fda9ea266e4a8b57d186f70bf3395bb4ee2220cbc302556048d600014c7fee086e6dbec2fbfa3189cfe381221b06966e2a5d0afd2fe5d2754044067aee6d
7
- data.tar.gz: a6dd1b4a963542a169fd2a3e67ef9003e4f37b0c549ddf59118f4b402f373c64708d92bca3a257342b75c9b83af74d39edbff162a4e91f9dcbd01bc98ebb5ddb
6
+ metadata.gz: a832616bb110d3662bc1b2f07991f4dc9015ba95a0e17584b749c36058cea9d87928ca7403cc3c46a62789f13abdaff3c827be6bce8d3468420861380bddff3b
7
+ data.tar.gz: 3c103db1aa747b5fd09757c680505d203d06afad591b46ee1903d36037a35de5b2b02ef0475f15f4f8e222accfafb21a8f75a2932b83e93f7fa6c2a82eb763b7
@@ -3,7 +3,7 @@ module PgAssociable
3
3
  MAX_RESULTS = 8
4
4
 
5
5
  def pg_respond_abrir_modal
6
- src = @clase_modelo.new.decorate.new_object_url
6
+ src = clase_modelo.new.decorate.new_object_url
7
7
  content = ModalContentComponent.new(src:).render_in(view_context)
8
8
  modal = AsociableModalComponent.new(modal_id: params[:id]).with_content(content)
9
9
  render turbo_stream: turbo_stream.append_all('body', modal)
@@ -14,10 +14,27 @@ module PgAssociable
14
14
  resultados_prefix = 'resultados-inline'
15
15
  query = params[:query]
16
16
  timeout_id = params[:timeout_id]
17
- @collection = policy_scope(@clase_modelo).kept.query(query).limit(MAX_RESULTS)
17
+ @collection = search_in_scope(query)
18
18
  render turbo_stream:
19
19
  turbo_stream.update("#{resultados_prefix}-#{params[:id]}",
20
20
  partial:, locals: { collection: @collection, query:, timeout_id: })
21
21
  end
22
+
23
+ def search_in_scope(query)
24
+ scope = policy_scope(clase_modelo).kept
25
+
26
+ if clase_modelo.ransackable_attributes.include?('search')
27
+ scope.ransack(search_cont: query).result
28
+ else
29
+ Rails.logger.warn("WARNING: #{clase_modelo} should implement a 'search' ransacker")
30
+
31
+ if scope.respond_to?(:query)
32
+ Rails.logger.warn("DEPRECATED WARNING: #{clase_modelo}#query is deprecated in favor of 'search' ransacker")
33
+ scope.query(query)
34
+ else
35
+ scope.where(id: query)
36
+ end
37
+ end
38
+ end
22
39
  end
23
40
  end
@@ -66,7 +66,7 @@ export default class extends Controller {
66
66
  }
67
67
  const doSearchBounce = debounce((force) => {
68
68
  this.doSearch(force)
69
- }, 900)
69
+ }, 200)
70
70
 
71
71
  this.input.addEventListener('blur', () => {
72
72
  this.input.placeholder = this.originalPlaceholder
@@ -1,7 +1,41 @@
1
1
  require 'rails_helper'
2
2
 
3
3
  describe PgAssociable::Helpers do
4
- describe '#pg_respond_buscar' do
4
+ include ActiveSupport::CurrentAttributes::TestHelper
5
+
6
+ describe 'current attributes gets reset' do
7
+ it 'sets a current attribute' do
8
+ Current.user = 1
9
+ expect(Current.namespace).to be_nil
10
+ end
11
+
12
+ it 'the attribute gets reset' do
13
+ Current.namespace = 2
14
+ expect(Current.user).to be_nil
15
+ end
16
+ end
17
+
18
+ # DEPRECATED
19
+ describe '#pg_respond_buscar with query scope' do
20
+ let(:ctrl) do
21
+ Admin::CategoriaDeCosasController.new
22
+ end
23
+ let!(:categoria_de_cosa) { create :categoria_de_cosa }
24
+
25
+ before do
26
+ Current.user = create :user, :developer
27
+ allow(ctrl).to receive_messages(params: { id: 123, query: categoria_de_cosa.nombre })
28
+ allow(ctrl).to receive(:render)
29
+ end
30
+
31
+ it do
32
+ ctrl.pg_respond_buscar
33
+ categoria_de_cosas = ctrl.instance_variable_get(:@collection)
34
+ expect(categoria_de_cosas).to eq [categoria_de_cosa]
35
+ end
36
+ end
37
+
38
+ describe '#pg_respond_buscar with id' do
5
39
  let(:ctrl) do
6
40
  Admin::CosasController.new
7
41
  end
@@ -11,7 +45,6 @@ describe PgAssociable::Helpers do
11
45
  Current.user = create :user, :developer
12
46
  allow(ctrl).to receive_messages(params: { id: 123, query: cosa.id })
13
47
  allow(ctrl).to receive(:render)
14
- ctrl.instance_variable_set(:@clase_modelo, Cosa)
15
48
  end
16
49
 
17
50
  it do
@@ -20,4 +53,23 @@ describe PgAssociable::Helpers do
20
53
  expect(cosas).to eq [cosa]
21
54
  end
22
55
  end
56
+
57
+ describe '#pg_respond_buscar with ransack' do
58
+ let(:ctrl) do
59
+ Admin::AccountsController.new
60
+ end
61
+ let!(:account) { create :account }
62
+
63
+ before do
64
+ Current.user = create :user, :developer
65
+ allow(ctrl).to receive_messages(params: { id: 123, query: account.nombre })
66
+ allow(ctrl).to receive(:render)
67
+ end
68
+
69
+ it do
70
+ ctrl.pg_respond_buscar
71
+ accounts = ctrl.instance_variable_get(:@collection)
72
+ expect(accounts).to eq [account]
73
+ end
74
+ end
23
75
  end
@@ -15,7 +15,11 @@ module Admin
15
15
  private
16
16
 
17
17
  def atributos_permitidos
18
- %i[user_id account_id profiles]
18
+ [
19
+ :user_id,
20
+ :account_id,
21
+ { profiles: [] }
22
+ ]
19
23
  end
20
24
 
21
25
  def atributos_para_buscar
@@ -9,7 +9,7 @@ module PgEngine
9
9
  def require_tenant_set
10
10
  return if ActsAsTenant.current_tenant.present?
11
11
 
12
- redirect_to users_account_switcher_path
12
+ raise ActsAsTenant::Errors::NoTenantSet
13
13
  end
14
14
  end
15
15
  end
@@ -418,9 +418,7 @@ module PgEngine
418
418
  instancia_modelo.assign_attributes(modelo_params) if action_name.in? %w[update]
419
419
  end
420
420
 
421
- # FIXME: estaría bueno delegar directamente a pundit, pero habría que
422
- # arreglar tema policies
423
- Current.user&.developer? || authorize(instancia_modelo)
421
+ authorize(instancia_modelo)
424
422
 
425
423
  # TODO: problema en create y update cuando falla la validacion
426
424
  # Reproducir el error antes de arreglarlo
@@ -17,19 +17,22 @@ module PgEngine
17
17
  # if ActsAsTenant.current_tenant.blank? && !global_domain?
18
18
  # raise ActsAsTenant::Errors::NoTenantSet
19
19
  # end
20
+ # FIXME: if current_tenant.present? check it's not discarded
20
21
 
21
22
  if Current.user.present?
23
+ user_accounts = Current.user.user_accounts.kept
22
24
  if ActsAsTenant.current_tenant.present?
23
- unless Current.user.user_accounts.exists?(account: ActsAsTenant.current_tenant)
25
+ unless user_accounts.exists?(account: ActsAsTenant.current_tenant)
24
26
  sign_out(Current.user)
25
27
  throw :warden, scope: :user, message: :invalid
26
28
  end
27
29
 
30
+ @current_tenant_set_by_domain_or_subdomain = true
28
31
  else
29
- account = if session['current_user_account'].present?
32
+ account = if user_accounts.count == 1
33
+ user_accounts.first.account
34
+ elsif session['current_user_account'].present?
30
35
  UserAccount.where(id: session['current_user_account']).first&.account
31
- elsif Current.user.user_accounts.count == 1
32
- Current.user.user_accounts.first.account
33
36
  end
34
37
  set_current_tenant(account)
35
38
  end
@@ -1,5 +1,9 @@
1
1
  module PgEngine
2
2
  class BasePublicController < ApplicationController
3
+ before_action do
4
+ Current.namespace = :public
5
+ end
6
+
3
7
  # :nocov:
4
8
  def login_as
5
9
  return head :bad_request unless dev_user_or_env?
@@ -35,7 +35,6 @@ module PgEngine
35
35
 
36
36
  def html_status(color:)
37
37
  %(<!DOCTYPE html><html><body style="background-color: #{color}"></body></html>).html_safe
38
- # rubocop:enable Rails/OutputSafety
39
38
  end
40
39
  end
41
40
  end
@@ -7,6 +7,8 @@ module Users
7
7
  @no_main_frame = true
8
8
  end
9
9
 
10
+ layout 'pg_layout/centered'
11
+
10
12
  def list
11
13
  @user_accounts = Current.user.user_accounts
12
14
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ # generado con pg_rails
4
+
5
+ module Users
6
+ class AccountsController < UsersController
7
+ include PgEngine::Resource
8
+
9
+ self.clase_modelo = Account
10
+ add_breadcrumb 'Cuentas'
11
+ self.skip_default_breadcrumb = true
12
+
13
+ before_action(only: :index) { authorize Account }
14
+
15
+ before_action :set_instancia_modelo, only: %i[new create show edit update destroy]
16
+
17
+ # private
18
+
19
+ # def atributos_permitidos
20
+ # %i[plan nombre domain subdomain]
21
+ # end
22
+
23
+ # def atributos_para_buscar
24
+ # atributos_permitidos
25
+ # end
26
+
27
+ # def atributos_para_listar
28
+ # atributos_permitidos
29
+ # end
30
+
31
+ # def atributos_para_mostrar
32
+ # atributos_permitidos
33
+ # end
34
+ end
35
+ end
@@ -9,9 +9,8 @@ module PgEngine
9
9
  end
10
10
 
11
11
  def render_turbo_stream_title
12
- title = [breadcrumbs.last&.name, I18n.t('app_name')].compact.join(' - ')
12
+ title = [breadcrumbs.last&.name, ActsAsTenant.current_tenant, I18n.t('app_name')].compact.join(' - ')
13
13
  turbo_stream.update_all 'title', title
14
- # rubocop:enable Rails/SkipsModelValidations
15
14
  end
16
15
  end
17
16
  end
@@ -22,6 +22,7 @@
22
22
  class Account < ApplicationRecord
23
23
  audited
24
24
  include Discard::Model
25
+ include Hashid::Rails
25
26
 
26
27
  has_many :user_accounts
27
28
  has_many :users, through: :user_accounts
@@ -33,6 +34,10 @@ class Account < ApplicationRecord
33
34
 
34
35
  validates :plan, :nombre, presence: true
35
36
 
37
+ ransacker :search do |parent|
38
+ parent.table[:nombre]
39
+ end
40
+
36
41
  def to_s
37
42
  nombre
38
43
  end
@@ -47,7 +47,6 @@ class Email < ApplicationRecord
47
47
  has_one_attached :encoded_eml
48
48
 
49
49
  acts_as_tenant :account, optional: true
50
-
51
50
  tenantable_belongs_to :associated, polymorphic: true, optional: true,
52
51
  assign_tenant_from_associated: true
53
52
 
@@ -19,7 +19,9 @@ module PgEngine
19
19
  attr_accessor :default_modal
20
20
  end
21
21
 
22
- scope :query, ->(param) { param.present? ? where(id: param) : all }
22
+ # ransacker :search do |parent|
23
+ # parent.table[:nombre]
24
+ # end
23
25
 
24
26
  def self.ransackable_associations(_auth_object = nil)
25
27
  authorizable_ransackable_associations
@@ -71,6 +71,15 @@ class User < ApplicationRecord
71
71
 
72
72
  attr_accessor :orphan
73
73
 
74
+ def active_for_authentication?
75
+ super && kept?
76
+ end
77
+
78
+ # TODO: test
79
+ def inactive_message
80
+ kept? ? super : :locked
81
+ end
82
+
74
83
  after_create do
75
84
  create_account unless orphan
76
85
  end
@@ -99,8 +108,20 @@ class User < ApplicationRecord
99
108
  # true
100
109
  # end
101
110
 
111
+ # DEPRECATED
102
112
  scope :query, ->(param) { where('email ILIKE ?', "%#{param}%") }
103
113
 
114
+ ransacker :search do |parent|
115
+ Arel::Nodes::InfixOperation.new(
116
+ '||',
117
+ Arel::Nodes::InfixOperation.new(
118
+ '||',
119
+ parent.table[:nombre], parent.table[:apellido]
120
+ ),
121
+ parent.table[:email]
122
+ )
123
+ end
124
+
104
125
  def to_s
105
126
  nombre_completo
106
127
  end
@@ -21,6 +21,7 @@
21
21
  # fk_rails_... (user_id => users.id)
22
22
  #
23
23
 
24
+ # FIXME: add column active?
24
25
  class UserAccount < ApplicationRecord
25
26
  audited
26
27
  include Hashid::Rails
@@ -31,9 +32,12 @@ class UserAccount < ApplicationRecord
31
32
  belongs_to :creado_por, optional: true, class_name: 'User'
32
33
  belongs_to :actualizado_por, optional: true, class_name: 'User'
33
34
 
35
+ # scope :kept, -> { undiscarded.joins(:account).merge(Account.kept) }
36
+ scope :kept, -> { joins(:account).merge(Account.kept) }
37
+
34
38
  enumerize :profiles, in: {
35
- admin: 1,
36
- dueño: 2,
37
- invitado: 3
39
+ administracion: 1,
40
+ operacion: 2,
41
+ lectura: 3
38
42
  }, multiple: true
39
43
  end
@@ -28,4 +28,8 @@ class AccountPolicy < ApplicationPolicy
28
28
  # def acceso_total?
29
29
  # user.developer?
30
30
  # end
31
+ def base_access_to_record?
32
+ ActsAsTenant.unscoped? ||
33
+ record.user_accounts.pluck(:user_id).include?(user.id)
34
+ end
31
35
  end
@@ -2,8 +2,8 @@
2
2
 
3
3
  div style="max-width: 22em"
4
4
  = pg_form_for(@user_account || object) do |f|
5
- = f.pg_associable :user
6
- = f.pg_associable :account
5
+ = f.pg_associable :user, preload: 10
6
+ = f.pg_associable :account, preload: 5
7
7
  = f.input :profiles
8
8
  .mt-2
9
9
  = f.button :submit
@@ -1,6 +1,24 @@
1
- h1 Switcher
1
+ h1 Cambiar a otra cuenta
2
2
 
3
- ul
4
- - @user_accounts.each do |user_account|
5
- li = link_to user_account.account, users_account_switch_path(user_account),
6
- 'data-turbo-method': :post
3
+ / FIXME!: user_accounts add active column
4
+ - if @user_accounts.empty?
5
+ p No tenés ninguna cuenta disponible
6
+ - else
7
+ - if @current_tenant_set_by_domain_or_subdomain
8
+ p Estás en el dominio de #{ActsAsTenant.current_tenant} (#{request.host})
9
+ p
10
+ | Para cambiar de cuenta vas a tener que iniciar sesión en el dominio
11
+ |< de Bien o de la cuenta específica a la que quieras cambiar
12
+
13
+ ul.m-auto.list-group style="max-width: 20em"
14
+ - @user_accounts.each do |user_account|
15
+ li.list-group-item
16
+ - if @current_tenant_set_by_domain_or_subdomain
17
+ = user_account.account
18
+ - elsif user_account.account == ActsAsTenant.current_tenant
19
+ b
20
+ = user_account.account
21
+ | (Actual)
22
+ - else
23
+ = link_to user_account.account, users_account_switch_path(user_account),
24
+ 'data-turbo-method': :post
@@ -0,0 +1,13 @@
1
+ h1
2
+ |> Usuarios de la cuenta:
3
+ = @account
4
+
5
+ div style="max-width: 30em"
6
+ table.table.table-sm
7
+ tr
8
+ th Nombre
9
+ th Roles
10
+ - @account.user_accounts.each do |user_account|
11
+ tr
12
+ td = user_account.user
13
+ td = user_account.profiles.texts.join(', ')
@@ -1,16 +1,7 @@
1
1
  ActsAsTenant.configure do |config|
2
- config.require_tenant = true
3
- # config.require_tenant = lambda do |options|
4
- # # if options[:scope] == User && true # global_domain?
5
- # # # tal vez en algunos casos de devise sí requeriría el tenant?
6
- # # # creería que no, el único lugar en donde se debería queriar
7
- # # # User es en devise y es para obtener el current_user
8
- # # # hay que ver luego qué pasa con invitable
9
- # # false
10
- # # else
11
- # # true
12
- # # end
13
- # end
2
+ config.require_tenant = lambda do
3
+ Current.namespace == :users
4
+ end
14
5
 
15
6
  # Customize the query for loading the tenant in background jobs
16
7
  # config.job_scope = ->{ all }
@@ -28,6 +28,9 @@ Rails.application.routes.draw do
28
28
  get '', action: 'list', as: 'account_switcher'
29
29
  post ':user_account_id', action: 'switch', as: 'account_switch'
30
30
  end
31
+
32
+ pg_resource(:accounts, path: 'cuentas', only: [:show])
33
+ # get 'account', to: 'accounts#show'
31
34
  end
32
35
 
33
36
  get '/u', to: 'users#home', as: :users_root
@@ -1,15 +1,16 @@
1
- ActsAsTenant.without_tenant do
2
- DatabaseCleaner.clean_with(:truncation, except: %w(ar_internal_metadata))
1
+ DatabaseCleaner.clean_with(:truncation, except: %w(ar_internal_metadata))
3
2
 
3
+ bien = FactoryBot.create(:account, nombre: 'Bien', subdomain: 'bien')
4
+ rosso = FactoryBot.create(:user, email: 'mrosso10@gmail.com', nombre: 'Martín', apellido: 'Rosso', password: 'admin123',
5
+ confirmed_at: Time.now, developer: true, orphan: true)
4
6
 
5
- bien = FactoryBot.create :account, nombre: 'Bien', subdomain: 'bien'
6
- uno = FactoryBot.create :user, email: 'mrosso10@gmail.com', nombre: 'Martín', apellido: 'Rosso', password: 'admin123',
7
- confirmed_at: Time.now, developer: true, orphan: true
8
- bien.users << uno
7
+ bien.user_accounts.create(user: rosso, profiles: [:administracion])
9
8
 
10
- mal = FactoryBot.create :account, nombre: 'Mal', subdomain: 'mal'
11
- otro = FactoryBot.create :user, email: 'mal@gmail.com', nombre: 'Mal', apellido: 'Mal', password: 'admin123',
12
- confirmed_at: Time.now, developer: true, orphan: true
9
+ racionalismo = FactoryBot.create(:account, nombre: 'Racionalismo', subdomain: 'racionalismo')
10
+ baruch = FactoryBot.create(:user, email: 'baruch@bien.com', nombre: 'Baruch', apellido: 'Spinoza', password: 'admin123',
11
+ confirmed_at: Time.now, orphan: true)
12
+ rené = FactoryBot.create(:user, email: 'rene@bien.com', nombre: 'René', apellido: 'Descartes', password: 'admin123',
13
+ confirmed_at: Time.now, orphan: true)
13
14
 
14
- mal.users << otro
15
- end
15
+ racionalismo.user_accounts.create(user: baruch, profiles: [:administracion])
16
+ racionalismo.user_accounts.create(user: rené, profiles: [:operacion])
@@ -36,6 +36,11 @@ def pg_log(*)
36
36
  PgEngine::PgLogger.log(*)
37
37
  end
38
38
 
39
+ # To be called inside a method or block that is deprecated
40
+ def pg_deprecation(method, message = nil, deprecator:)
41
+ deprecator.warn(deprecator.deprecation_warning(method, message), caller_locations(3))
42
+ end
43
+
39
44
  module PgEngine
40
45
  class PgLogger
41
46
  def self.test_logged_messages
@@ -42,7 +42,7 @@ RSpec.describe Admin::AccountsController do
42
42
  }
43
43
  end
44
44
 
45
- let(:user) { create :user, :admin }
45
+ let(:user) { create :user, :developer }
46
46
 
47
47
  before do
48
48
  sign_in user if user.present?
@@ -43,7 +43,7 @@ RSpec.describe Admin::UsersController do
43
43
  }
44
44
  end
45
45
 
46
- let(:logged_user) { create :user, :admin }
46
+ let(:logged_user) { create :user, :developer }
47
47
 
48
48
  before do
49
49
  sign_in logged_user
@@ -2,6 +2,7 @@ require 'rails_helper'
2
2
 
3
3
  describe Devise::SessionsController do
4
4
  before do
5
+ ActsAsTenant.current_tenant = nil
5
6
  # rubocop:disable RSpec/InstanceVariable
6
7
  @request.env['devise.mapping'] = Devise.mappings[:user]
7
8
  # rubocop:enable RSpec/InstanceVariable
@@ -51,7 +51,7 @@ describe Users::RegistrationsController do
51
51
  describe '#edit' do
52
52
  subject { get :edit }
53
53
 
54
- let(:logger_user) { create :user, :admin }
54
+ let(:logger_user) { create :user, :developer }
55
55
 
56
56
  before do
57
57
  sign_in logger_user
@@ -58,7 +58,11 @@ FactoryBot.define do
58
58
  end
59
59
 
60
60
  trait :admin do
61
- developer { true }
61
+ developer do
62
+ pg_deprecation 'trait "admin"', 'use trait "developer" instead',
63
+ deprecator: PgEngine.deprecator
64
+ true
65
+ end
62
66
  end
63
67
 
64
68
  trait :developer do
@@ -5,6 +5,10 @@ describe PgEngine::Mailgun::LogSync, vcr: { cassette_name: 'mailgun/log_sync_dow
5
5
  match_requests_on: %i[method host] } do
6
6
  let(:instancia) { described_class }
7
7
 
8
+ before do
9
+ ActsAsTenant.current_tenant = nil
10
+ end
11
+
8
12
  describe '#download' do
9
13
  subject do
10
14
  instancia.download
@@ -11,6 +11,11 @@ RSpec.describe Email do
11
11
  expect(email).to be_persisted
12
12
  end
13
13
 
14
+ it 'se persiste cuando no hay tenant' do
15
+ ActsAsTenant.current_tenant = nil
16
+ expect(email).to be_persisted
17
+ end
18
+
14
19
  describe 'update_status!' do
15
20
  context 'cuando hay accepted y delivered' do
16
21
  subject do
@@ -56,4 +56,11 @@ RSpec.describe User do
56
56
  expect(user).not_to be_persisted
57
57
  end
58
58
  end
59
+
60
+ describe 'search ransacker' do
61
+ it 'searchs' do
62
+ results = described_class.ransack(search_cont: user.nombre).result.to_a
63
+ expect(results).to eq [user]
64
+ end
65
+ end
59
66
  end
@@ -0,0 +1,22 @@
1
+ require 'rails_helper'
2
+
3
+ describe 'current attributes' do
4
+ it 'Current gets reset between requests' do
5
+ allow(Current).to receive(:namespace=)
6
+ allow(Current.instance).to receive(:reset)
7
+ get '/contacto/new'
8
+ expect(Current).to have_received(:namespace=).with(:public)
9
+ expect(Current.instance).to have_received(:reset).at_least(:twice)
10
+ expect(Current.namespace).to be_nil
11
+ end
12
+
13
+ it 'sets a current attribute' do
14
+ Current.user = 1
15
+ expect(Current.namespace).to be_nil
16
+ end
17
+
18
+ it 'the attribute gets reset' do
19
+ Current.namespace = 2
20
+ expect(Current.user).to be_nil
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ require 'rails_helper'
2
+
3
+ describe 'devise flows' do
4
+ describe 'resend confirmation' do
5
+ subject do
6
+ post '/users/confirmation', params: { user: { email: user.email } }
7
+ end
8
+
9
+ let!(:user) { create :user, confirmed_at: nil }
10
+
11
+ it do
12
+ expect { subject }.to change(ActionMailer::Base.deliveries, :length).by(1)
13
+ end
14
+
15
+ it do
16
+ subject
17
+ expect(response).to redirect_to(new_user_session_path)
18
+ end
19
+
20
+ it do
21
+ expect { subject }.not_to have_errored
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,22 @@
1
+ require 'rails_helper'
2
+
3
+ describe 'Users::AccountsController' do
4
+ let(:account) { ActsAsTenant.current_tenant }
5
+ let(:user) { create :user }
6
+
7
+ before do
8
+ sign_in user
9
+ end
10
+
11
+ it 'shows the owned account' do
12
+ get "/u/cuentas/#{account.to_param}"
13
+ expect(response).to have_http_status(:ok)
14
+ end
15
+
16
+ it 'denies foreign account' do
17
+ other_account = create :account
18
+ get "/u/cuentas/#{other_account.to_param}"
19
+ expect(response).to have_http_status(:redirect)
20
+ expect(flash[:alert]).to eq 'Acceso no autorizado'
21
+ end
22
+ end
@@ -26,21 +26,39 @@ describe 'redirection' do
26
26
  expect(response).to have_http_status(:ok)
27
27
  end
28
28
 
29
+ context 'when account is discarded' do
30
+ it do
31
+ get '/u/cosas'
32
+ expect(response.body).to include 'No hay cosos que mostrar'
33
+ logged_user.user_accounts.first.account.discard!
34
+ get '/u/cosas'
35
+ expect(response).to redirect_to users_account_switcher_path
36
+ end
37
+ end
38
+
29
39
  context 'when has been removed from account' do
30
40
  let!(:other_account) { create :account }
31
41
  let!(:other_user_account) { logged_user.user_accounts.create(account: other_account) }
32
42
 
43
+ before do
44
+ third_account = create :account
45
+ logged_user.user_accounts.create(account: third_account)
46
+ end
47
+
33
48
  it 'redirects to switcher' do
34
49
  get '/u/cosas'
35
50
  expect(response).to redirect_to users_account_switcher_path
36
51
  follow_redirect!
37
- expect(response.body).to include 'Switcher'
52
+ expect(response.body).to include 'Cambiar a otra cuenta'
38
53
  post "/u/switcher/#{other_user_account.to_param}"
39
54
  expect(response).to redirect_to(root_path)
40
55
  follow_redirect!
56
+ get '/u/cosas'
57
+ expect(response).to have_http_status(:ok)
41
58
  expect(response.body).to include other_account.to_s
59
+ expect(response.body).to include 'No hay cosos que mostrar'
42
60
  other_user_account.destroy!
43
- get '/'
61
+ get '/u/cosas'
44
62
  expect(response).to redirect_to users_account_switcher_path
45
63
  end
46
64
  end
@@ -35,7 +35,7 @@ describe 'Tenants' do
35
35
  it 'shows the switcher' do
36
36
  visitar
37
37
 
38
- expect(page).to have_text 'Switcher'
38
+ expect(page).to have_text 'Cambiar a otra cuenta'
39
39
  end
40
40
 
41
41
  it 'switches to account' do
@@ -32,7 +32,7 @@
32
32
  <br>
33
33
  <br>
34
34
  <ul style="max-width: 500px">
35
- <% User.order(:id).each do |user| %>
35
+ <% User.kept.order(:id).each do |user| %>
36
36
  <li><%= link_to user, login_as_path(id: user.id) %></li>
37
37
  <% end %>
38
38
  </ul>
@@ -5,13 +5,20 @@
5
5
  </div>
6
6
  <% if user_signed_in? %>
7
7
  <span class="d-inline-block px-3 text-end text-light"><%= Current.user %></span>
8
- <%= link_to users_account_switcher_path do %>
9
- <% if Rails.env.development? %>
10
- <span class="d-block px-3 text-secondary">Tenant: <%= ActsAsTenant.current_tenant || 'Global' %></span>
8
+ <span class="d-block px-3 text-secondary">
9
+ <% if Current.user.user_accounts.count > 1 %>
10
+ <%= link_to ActsAsTenant.current_tenant, [:users, ActsAsTenant.current_tenant] if ActsAsTenant.current_tenant.present? %>
11
+ <%= link_to users_account_switcher_path do %>
12
+ <% if ActsAsTenant.current_tenant.present? %>
13
+ (Cambiar)
14
+ <% else %>
15
+ Elegir cuenta
16
+ <% end %>
17
+ <% end %>
11
18
  <% else %>
12
- <span class="d-block px-3 text-secondary"><%= ActsAsTenant.current_tenant %></span>
19
+ <%= link_to ActsAsTenant.current_tenant, [:users, ActsAsTenant.current_tenant] if ActsAsTenant.current_tenant.present? %>
13
20
  <% end %>
14
- <% end %>
21
+ </span>
15
22
  <hr>
16
23
  <% end %>
17
24
  <ul class="list-unstyled ps-0">
@@ -1,3 +1,9 @@
1
+ pg_deprecation(
2
+ 'requiring current_attributes_support',
3
+ 'instead use "include ActiveSupport::CurrentAttributes::TestHelper" when necessary',
4
+ deprecator: PgEngine.deprecator
5
+ )
6
+
1
7
  RSpec.configure do |config|
2
8
  config.before(:each) do
3
9
  Current.user = nil
@@ -33,6 +33,18 @@ module PgEngine
33
33
  end
34
34
  end
35
35
 
36
+ def failure_message_when_negated
37
+ msg = "expected not to #{@level || log}"
38
+ msg << "with text: #{@text}" if @text.present?
39
+ return msg unless @new_messages.any?
40
+
41
+ msg << "\nLogged messages:"
42
+ @new_messages.each do |level, message|
43
+ msg << "\n #{level}: #{message[0..500]}"
44
+ end
45
+ msg
46
+ end
47
+
36
48
  def failure_message
37
49
  msg = "expected to #{@level || log}"
38
50
  msg << "with text: #{@text}" if @text.present?
@@ -40,7 +52,7 @@ module PgEngine
40
52
 
41
53
  msg << "\nLogged messages:"
42
54
  @new_messages.each do |level, message|
43
- msg << "\n #{level}: #{message[0..200]}"
55
+ msg << "\n #{level}: #{message[0..500]}"
44
56
  end
45
57
  msg
46
58
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgRails
4
- VERSION = '7.5.2'
4
+ VERSION = '7.5.4'
5
5
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # FIXME: reemplazar por requests spec
3
4
  # generado con pg_rails
4
5
 
5
6
  require 'rails_helper'
@@ -9,7 +9,7 @@ RSpec.describe "<%= ruta_vistas %>/edit", <%= type_metatag(:view) %> do
9
9
  helper <%= mountable_engine? %>::Engine.routes.url_helpers
10
10
  <% end -%>
11
11
 
12
- let(:user) { create(:user, :admin) }
12
+ let(:user) { create(:user, :developer) }
13
13
 
14
14
  before(:each) do
15
15
  sign_in user
@@ -9,7 +9,7 @@ RSpec.describe "<%= ruta_vistas %>/index", <%= type_metatag(:view) %> do
9
9
  helper <%= mountable_engine? %>::Engine.routes.url_helpers
10
10
  <% end -%>
11
11
 
12
- let(:user) { create(:user, :admin) }
12
+ let(:user) { create(:user, :developer) }
13
13
  let!(:<%= plural_name %>) { create_list(:<%= nombre_tabla_completo_singular %>, rand(10..20))}
14
14
 
15
15
  before(:each) do
@@ -9,7 +9,7 @@ RSpec.describe "<%= ruta_vistas %>/new", <%= type_metatag(:view) %> do
9
9
  helper <%= mountable_engine? %>::Engine.routes.url_helpers
10
10
  <% end -%>
11
11
 
12
- let(:user) { create(:user, :admin) }
12
+ let(:user) { create(:user, :developer) }
13
13
 
14
14
  before(:each) do
15
15
  sign_in user
@@ -9,7 +9,7 @@ RSpec.describe "<%= ruta_vistas %>/show", <%= type_metatag(:view) %> do
9
9
  helper <%= mountable_engine? %>::Engine.routes.url_helpers
10
10
  <% end -%>
11
11
 
12
- let(:user) { create(:user, :admin) }
12
+ let(:user) { create(:user, :developer) }
13
13
 
14
14
  before(:each) do
15
15
  sign_in user
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.5.2
4
+ version: 7.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martín Rosso
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-11 00:00:00.000000000 Z
11
+ date: 2024-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -689,6 +689,7 @@ files:
689
689
  - pg_engine/app/controllers/public/mensaje_contactos_controller.rb
690
690
  - pg_engine/app/controllers/public/webhooks_controller.rb
691
691
  - pg_engine/app/controllers/users/account_switcher_controller.rb
692
+ - pg_engine/app/controllers/users/accounts_controller.rb
692
693
  - pg_engine/app/controllers/users/confirmations_controller.rb
693
694
  - pg_engine/app/controllers/users/date_jumper_controller.rb
694
695
  - pg_engine/app/controllers/users/notifications_controller.rb
@@ -777,6 +778,7 @@ files:
777
778
  - pg_engine/app/views/public/mensaje_contactos/_gracias.html.slim
778
779
  - pg_engine/app/views/public/mensaje_contactos/new.html.slim
779
780
  - pg_engine/app/views/users/account_switcher/list.html.slim
781
+ - pg_engine/app/views/users/accounts/show.html.slim
780
782
  - pg_engine/config/initializers/action_mailer.rb
781
783
  - pg_engine/config/initializers/active_admin.rb
782
784
  - pg_engine/config/initializers/acts_as_tenant.rb
@@ -876,6 +878,9 @@ files:
876
878
  - pg_engine/spec/pg_engine/pdf_preview_generator_spec.rb
877
879
  - pg_engine/spec/requests/admin/eventos_spec.rb
878
880
  - pg_engine/spec/requests/base_controller_requests_spec.rb
881
+ - pg_engine/spec/requests/current_attributes_spec.rb
882
+ - pg_engine/spec/requests/devise_spec.rb
883
+ - pg_engine/spec/requests/users/accounts_spec.rb
879
884
  - pg_engine/spec/requests/users/base_controller_spec.rb
880
885
  - pg_engine/spec/requests/users/date_jumper_spec.rb
881
886
  - pg_engine/spec/requests/users/switcher_spec.rb