pg_rails 7.5.2 → 7.5.4

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.
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