pg_rails 7.6.19 → 7.6.21.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/pg_associable/app/javascript/modal_controller.js +8 -4
- data/pg_associable/spec/pg_associable/helpers_spec.rb +8 -13
- data/pg_engine/app/components/inline_edit/inline_edit_component.html.slim +1 -1
- data/pg_engine/app/components/inline_edit/inline_show_component.html.slim +2 -2
- data/pg_engine/app/components/notifications_bell_component.rb +1 -1
- data/pg_engine/app/controllers/admin/accounts_controller.rb +2 -2
- data/pg_engine/app/controllers/admin/user_accounts_controller.rb +3 -3
- data/pg_engine/app/controllers/admin/users_controller.rb +4 -1
- data/pg_engine/app/controllers/concerns/pg_engine/resource.rb +12 -7
- data/pg_engine/app/controllers/concerns/pg_engine/tenant_helper.rb +33 -0
- data/pg_engine/app/controllers/pg_engine/base_admin_controller.rb +0 -1
- data/pg_engine/app/controllers/pg_engine/base_controller.rb +18 -21
- data/pg_engine/app/controllers/pg_engine/base_public_controller.rb +1 -1
- data/pg_engine/app/controllers/pg_engine/base_users_controller.rb +5 -3
- data/pg_engine/app/controllers/pg_engine/devise_controller.rb +4 -1
- data/pg_engine/app/controllers/pg_engine/tenant_controller.rb +22 -0
- data/pg_engine/app/controllers/{users → tenant}/dashboard_controller.rb +2 -2
- data/pg_engine/app/controllers/tenant/inline_edit_controller.rb +22 -0
- data/pg_engine/app/controllers/tenant/user_accounts_controller.rb +56 -0
- data/pg_engine/app/controllers/users/accounts_controller.rb +46 -15
- data/pg_engine/app/controllers/users/invitations_controller.rb +78 -0
- data/pg_engine/app/controllers/users/notifications_controller.rb +1 -0
- data/pg_engine/app/controllers/users/registrations_controller.rb +3 -2
- data/pg_engine/app/decorators/account_decorator.rb +18 -0
- data/pg_engine/app/decorators/pg_engine/base_record_decorator.rb +9 -1
- data/pg_engine/app/decorators/user_account_decorator.rb +76 -11
- data/pg_engine/app/helpers/pg_engine/accounts_helper.rb +9 -0
- data/pg_engine/app/helpers/pg_engine/frame_helper.rb +12 -0
- data/pg_engine/app/lib/pg_engine/default_url_options.rb +21 -0
- data/pg_engine/app/lib/pg_engine/filtros_builder.rb +2 -0
- data/pg_engine/app/models/account.rb +28 -1
- data/pg_engine/app/models/concerns/pg_engine/child_record.rb +55 -0
- data/pg_engine/app/models/current.rb +21 -3
- data/pg_engine/app/models/pg_engine/base_record.rb +5 -0
- data/pg_engine/app/models/user.rb +51 -9
- data/pg_engine/app/models/user_account.rb +74 -9
- data/pg_engine/app/policies/account_policy.rb +35 -16
- data/pg_engine/app/policies/email_log_policy.rb +0 -4
- data/pg_engine/app/policies/email_policy.rb +0 -4
- data/pg_engine/app/policies/pg_engine/base_policy.rb +31 -10
- data/pg_engine/app/policies/user_account_policy.rb +59 -25
- data/pg_engine/app/policies/user_policy.rb +14 -1
- data/pg_engine/app/views/admin/user_accounts/_form.html.slim +1 -1
- data/pg_engine/app/views/admin/user_accounts/show.html.slim +15 -0
- data/pg_engine/app/views/admin/users/show.html.slim +0 -3
- data/pg_engine/app/views/pg_engine/base/index.html.slim +2 -2
- data/pg_engine/app/views/tenant/dashboard/dashboard.html.slim +2 -0
- data/pg_engine/app/views/tenant/user_accounts/_fields.html.slim +13 -0
- data/pg_engine/app/views/tenant/user_accounts/_form.html.slim +9 -0
- data/pg_engine/app/views/tenant/user_accounts/show.html.slim +20 -0
- data/pg_engine/app/views/users/accounts/_form.html.slim +7 -0
- data/pg_engine/app/views/users/accounts/show.html.slim +23 -15
- data/pg_engine/config/initializers/acts_as_tenant.rb +7 -2
- data/pg_engine/config/initializers/devise.rb +10 -0
- data/pg_engine/config/initializers/ransack.rb +2 -0
- data/pg_engine/config/locales/es.yml +60 -0
- data/pg_engine/config/routes.rb +21 -11
- data/pg_engine/config/simple_form/simple_form_bootstrap.rb +2 -2
- data/pg_engine/db/migrate/20241023203849_devise_invitable.rb +14 -0
- data/pg_engine/db/migrate/20241027225618_add_membership_status_to_user_accounts.rb +6 -0
- data/pg_engine/db/seeds.rb +6 -6
- data/pg_engine/lib/pg_engine/configuracion.rb +36 -1
- data/pg_engine/lib/pg_engine/navigator.rb +2 -25
- data/pg_engine/lib/pg_engine/utils/{check_invalid_records.rb → resource_reports.rb} +22 -3
- data/pg_engine/lib/pg_engine.rb +1 -0
- data/pg_engine/spec/controllers/admin/accounts_controller_spec.rb +3 -2
- data/pg_engine/spec/controllers/admin/user_accounts_controller_spec.rb +11 -9
- data/pg_engine/spec/factories/accounts.rb +8 -0
- data/pg_engine/spec/factories/user_accounts.rb +1 -1
- data/pg_engine/spec/factories/users.rb +6 -0
- data/pg_engine/spec/models/concerns/pg_engine/child_record_spec.rb +27 -0
- data/pg_engine/spec/models/user_account_spec.rb +5 -1
- data/pg_engine/spec/models/user_spec.rb +3 -25
- data/pg_engine/spec/policies/account_policy_spec.rb +19 -0
- data/pg_engine/spec/requests/devise/invitations_spec.rb +196 -0
- data/pg_engine/spec/requests/resource_spec.rb +14 -15
- data/pg_engine/spec/requests/users/accounts_spec.rb +117 -8
- data/pg_engine/spec/requests/users/base_controller_spec.rb +31 -0
- data/pg_engine/spec/requests/users/dashboard_spec.rb +4 -9
- data/pg_engine/spec/requests/users/date_jumper_spec.rb +2 -1
- data/pg_engine/spec/requests/users/inline_edit_spec.rb +6 -5
- data/pg_engine/spec/requests/users/registrations_spec.rb +2 -2
- data/pg_engine/spec/requests/users/user_accounts_spec.rb +54 -0
- data/pg_engine/spec/system/login_spec.rb +2 -2
- data/pg_engine/spec/system/noticed_spec.rb +0 -2
- data/pg_engine/spec/system/signup_spec.rb +4 -3
- data/pg_engine/spec/system/tenants_spec.rb +10 -9
- data/pg_layout/app/javascript/application.js +1 -1
- data/pg_layout/app/javascript/config/turbo_rails/index.js +1 -1
- data/pg_layout/app/lib/navbar.rb +15 -1
- data/pg_layout/app/views/devise/invitations/edit.html.erb +34 -0
- data/pg_layout/app/views/devise/invitations/new.html.erb +15 -0
- data/pg_layout/app/views/devise/mailer/invitation_instructions.html.erb +11 -0
- data/pg_layout/app/views/devise/mailer/invitation_instructions.text.erb +11 -0
- data/pg_layout/app/views/devise/registrations/edit.html.erb +1 -0
- data/pg_layout/app/views/layouts/pg_layout/base.html.slim +6 -5
- data/pg_layout/app/views/pg_layout/_navbar.html.erb +7 -6
- data/pg_layout/app/views/pg_layout/_sidebar.html.erb +2 -20
- data/pg_layout/app/views/pg_layout/_signed_in_links.html.slim +52 -0
- data/pg_layout/lib/pg_layout.rb +0 -5
- data/pg_rails/lib/pg_rails/pundit_matchers.rb +21 -0
- data/pg_rails/lib/pg_rails/tpath_support.rb +73 -0
- data/pg_rails/lib/pg_rails.rb +6 -0
- data/pg_rails/lib/version.rb +1 -1
- data/pg_rails/scss/pg_rails.scss +1 -1
- data/pg_scaffold/lib/generators/pg_rspec/scaffold/templates/controller_spec.rb +1 -1
- data/pg_scaffold/lib/generators/pg_slim/templates/index.html.slim +1 -1
- metadata +44 -10
- data/pg_engine/app/controllers/concerns/pg_engine/require_tenant_set.rb +0 -15
- data/pg_engine/app/controllers/users/account_switcher_controller.rb +0 -30
- data/pg_engine/app/controllers/users/inline_edit_controller.rb +0 -21
- data/pg_engine/app/views/users/account_switcher/list.html.slim +0 -24
- data/pg_engine/app/views/users/dashboard/dashboard.html.slim +0 -1
- data/pg_engine/spec/requests/users/switcher_spec.rb +0 -84
@@ -4,11 +4,46 @@
|
|
4
4
|
|
5
5
|
module PgEngine
|
6
6
|
class Configuracion
|
7
|
-
attr_accessor :users_controller, :global_domains, :navigators
|
7
|
+
attr_accessor :users_controller, :global_domains, :navigators, :user_profiles
|
8
|
+
|
9
|
+
# attr_accessor :profile_groups
|
8
10
|
|
9
11
|
def initialize
|
10
12
|
@global_domains = ['app.localhost.com', 'test.host', 'localhost']
|
11
13
|
@navigators = [PgEngine::Navigator.new]
|
14
|
+
# @profile_groups = [:account]
|
15
|
+
@user_profiles = {
|
16
|
+
account__owner: 0
|
17
|
+
}
|
18
|
+
user_profiles.merge!(
|
19
|
+
user_accounts__read: 1000 + 1
|
20
|
+
)
|
21
|
+
# add_profiles(:user_accounts, 1000)
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_profiles(key, base)
|
25
|
+
# profile_groups.push(key)
|
26
|
+
user_profiles.merge!(
|
27
|
+
"#{key}__read": base + 1,
|
28
|
+
"#{key}__update": base + 10,
|
29
|
+
"#{key}__create": base + 30,
|
30
|
+
"#{key}__archive": base + 50,
|
31
|
+
"#{key}__export": base + 80,
|
32
|
+
"#{key}__destroy": base + 100
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
def profile_groups_options
|
37
|
+
groups = user_profiles.keys.map { |v| v.to_s.split('__').first }.uniq
|
38
|
+
|
39
|
+
groups = groups.excluding('account') unless Current.namespace == :admin
|
40
|
+
|
41
|
+
groups.map do |group|
|
42
|
+
options = user_profiles.keys.select { |va| va.starts_with?(group) }.map do |va|
|
43
|
+
[va, I18n.t(va.to_s.split('__').last, scope: 'profile_member')]
|
44
|
+
end
|
45
|
+
{ name: group, options: }
|
46
|
+
end
|
12
47
|
end
|
13
48
|
end
|
14
49
|
end
|
@@ -2,40 +2,17 @@ module PgEngine
|
|
2
2
|
class Navigator
|
3
3
|
# rubocop:disable Metrics/MethodLength
|
4
4
|
def configure(navbar)
|
5
|
-
navbar.add_item('sidebar.not_signed_in', {
|
6
|
-
name: 'Crear una cuenta',
|
7
|
-
path: 'new_user_registration_path'
|
8
|
-
})
|
9
|
-
navbar.add_item('sidebar.not_signed_in', {
|
10
|
-
name: 'Iniciar sesión',
|
11
|
-
path: 'new_user_session_path'
|
12
|
-
})
|
13
|
-
navbar.add_item('sidebar.not_signed_in', {
|
14
|
-
name: 'Contacto',
|
15
|
-
path: 'new_public_mensaje_contacto_path'
|
16
|
-
})
|
17
|
-
|
18
5
|
# *****************************************************
|
19
6
|
|
20
7
|
navbar.add_item('sidebar.signed_in', {
|
21
8
|
name: 'Inicio',
|
22
|
-
path: '
|
9
|
+
path: 'tenant_root_path',
|
23
10
|
priority: 0
|
24
11
|
})
|
25
|
-
navbar.add_item('sidebar.signed_in', {
|
26
|
-
name: 'Mi perfil',
|
27
|
-
path: 'edit_user_registration_path',
|
28
|
-
policy: 'policy(Current.user).edit?'
|
29
|
-
})
|
30
|
-
navbar.add_item('sidebar.signed_in', {
|
31
|
-
name: 'Cerrar sesión',
|
32
|
-
path: 'destroy_user_session_path',
|
33
|
-
attributes: 'data-turbo-method="delete"'
|
34
|
-
})
|
35
12
|
|
36
13
|
# *****************************************************
|
37
14
|
|
38
|
-
return unless Current.
|
15
|
+
return unless Current.namespace == :admin
|
39
16
|
|
40
17
|
navbar.add_item('sidebar.signed_in', {
|
41
18
|
name: 'Eventos',
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# :nocov:
|
2
2
|
module PgEngine
|
3
3
|
module Utils
|
4
|
-
class
|
5
|
-
def
|
4
|
+
class ResourceReports
|
5
|
+
def check_invalid_records
|
6
6
|
invalids = []
|
7
7
|
classes.each do |klass|
|
8
8
|
klass.find_each do |record|
|
@@ -19,6 +19,26 @@ module PgEngine
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
def report(klass)
|
23
|
+
if klass.respond_to?(:discarded)
|
24
|
+
<<~STRING
|
25
|
+
#{klass}.unscoped.count: #{klass.unscoped.count}
|
26
|
+
#{klass}.unscoped.kept.count: #{klass.unscoped.kept.count}
|
27
|
+
#{klass}.unscoped.unkept.count: #{klass.unscoped.unkept.count}
|
28
|
+
#{klass}.unscoped.discarded.count: #{klass.unscoped.discarded.count}
|
29
|
+
#{klass}.unscoped.undiscarded.count: #{klass.unscoped.undiscarded.count}
|
30
|
+
STRING
|
31
|
+
else
|
32
|
+
<<~STRING
|
33
|
+
#{klass}.unscoped.count: #{klass.unscoped.count}
|
34
|
+
STRING
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def report_all
|
39
|
+
classes.map { |klass| report(klass).to_s }.join("\n")
|
40
|
+
end
|
41
|
+
|
22
42
|
def classes
|
23
43
|
all = ActiveRecord::Base.descendants.select { |m| m.table_name.present? }
|
24
44
|
all - ignored_classes
|
@@ -28,7 +48,6 @@ module PgEngine
|
|
28
48
|
[
|
29
49
|
ActionText::Record,
|
30
50
|
ActionMailbox::Record,
|
31
|
-
ActiveAdmin::Comment,
|
32
51
|
ActiveStorage::Record,
|
33
52
|
PgEngine::BaseRecord,
|
34
53
|
Audited::Audit,
|
data/pg_engine/lib/pg_engine.rb
CHANGED
@@ -45,6 +45,7 @@ RSpec.describe Admin::AccountsController do
|
|
45
45
|
let(:user) { create :user, :developer }
|
46
46
|
|
47
47
|
before do
|
48
|
+
create :user, :owner
|
48
49
|
sign_in user if user.present?
|
49
50
|
end
|
50
51
|
|
@@ -60,7 +61,7 @@ RSpec.describe Admin::AccountsController do
|
|
60
61
|
get :index, params: {}
|
61
62
|
end
|
62
63
|
|
63
|
-
let!(:account) { create :account }
|
64
|
+
let!(:account) { create :account, :with_owner }
|
64
65
|
|
65
66
|
it 'returns a success response' do
|
66
67
|
subject
|
@@ -99,7 +100,7 @@ RSpec.describe Admin::AccountsController do
|
|
99
100
|
|
100
101
|
describe 'GET #show' do
|
101
102
|
it 'returns a success response' do
|
102
|
-
account = create(:account)
|
103
|
+
account = create(:account, :with_owner)
|
103
104
|
get :show, params: { id: account.to_param }
|
104
105
|
expect(response).to be_successful
|
105
106
|
end
|
@@ -29,7 +29,12 @@ require 'rails_helper'
|
|
29
29
|
|
30
30
|
RSpec.describe Admin::UserAccountsController do
|
31
31
|
render_views
|
32
|
-
let!(:user)
|
32
|
+
let!(:user) do
|
33
|
+
create :user
|
34
|
+
end
|
35
|
+
let(:user_account) do
|
36
|
+
create :user_account, user:, account:
|
37
|
+
end
|
33
38
|
|
34
39
|
let!(:account) { ActsAsTenant.current_tenant }
|
35
40
|
|
@@ -64,7 +69,9 @@ RSpec.describe Admin::UserAccountsController do
|
|
64
69
|
get :index, params: {}
|
65
70
|
end
|
66
71
|
|
67
|
-
before
|
72
|
+
before do
|
73
|
+
create :user
|
74
|
+
end
|
68
75
|
|
69
76
|
it 'returns a success response' do
|
70
77
|
subject
|
@@ -94,7 +101,6 @@ RSpec.describe Admin::UserAccountsController do
|
|
94
101
|
|
95
102
|
describe 'GET #show' do
|
96
103
|
it 'returns a success response' do
|
97
|
-
user_account = create(:user_account)
|
98
104
|
get :show, params: { id: user_account.to_param }
|
99
105
|
expect(response).to be_successful
|
100
106
|
end
|
@@ -109,7 +115,6 @@ RSpec.describe Admin::UserAccountsController do
|
|
109
115
|
|
110
116
|
describe 'GET #edit' do
|
111
117
|
it 'returns a success response' do
|
112
|
-
user_account = create(:user_account)
|
113
118
|
get :edit, params: { id: user_account.to_param }
|
114
119
|
expect(response).to be_successful
|
115
120
|
end
|
@@ -149,7 +154,6 @@ RSpec.describe Admin::UserAccountsController do
|
|
149
154
|
end
|
150
155
|
|
151
156
|
it 'redirects to the user_account' do
|
152
|
-
user_account = create(:user_account)
|
153
157
|
put :update, params: { id: user_account.to_param, user_account: valid_attributes }
|
154
158
|
|
155
159
|
expect(response).to redirect_to([:admin, UserAccount.last])
|
@@ -158,13 +162,11 @@ RSpec.describe Admin::UserAccountsController do
|
|
158
162
|
|
159
163
|
context 'with invalid params' do
|
160
164
|
it 'returns a unprocessable_entity response' do
|
161
|
-
user_account = create(:user_account)
|
162
165
|
put :update, params: { id: user_account.to_param, user_account: invalid_attributes }
|
163
166
|
expect(response).to have_http_status(:unprocessable_entity)
|
164
167
|
end
|
165
168
|
|
166
169
|
it 'renders the edit template' do
|
167
|
-
user_account = create(:user_account)
|
168
170
|
put :update, params: { id: user_account.to_param, user_account: invalid_attributes }
|
169
171
|
expect(response).to render_template(:edit)
|
170
172
|
end
|
@@ -177,11 +179,11 @@ RSpec.describe Admin::UserAccountsController do
|
|
177
179
|
delete :destroy, params: { id: user_account.to_param, land_on: }
|
178
180
|
end
|
179
181
|
|
180
|
-
let!(:user_account) { create :user_account }
|
181
182
|
let(:land_on) { nil }
|
182
183
|
|
183
184
|
it 'destroys the requested user_account' do
|
184
|
-
|
185
|
+
user_account
|
186
|
+
expect { subject }.to change(UserAccount.unscoped, :count).by(-1)
|
185
187
|
end
|
186
188
|
|
187
189
|
it 'envía el pg-event' do
|
@@ -6,5 +6,13 @@ FactoryBot.define do
|
|
6
6
|
factory :account do
|
7
7
|
plan { Account.plan.values.sample }
|
8
8
|
nombre { Faker::Lorem.sentence }
|
9
|
+
|
10
|
+
trait :with_owner do
|
11
|
+
after(:create) do |model|
|
12
|
+
ActsAsTenant.with_tenant(model) do
|
13
|
+
create :user, :owner
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
9
17
|
end
|
10
18
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe PgEngine::ChildRecord do
|
4
|
+
describe '#parent_accessor' do
|
5
|
+
it 'the values are independent from each class' do
|
6
|
+
model_class = Class.new(PgEngine::BaseRecord)
|
7
|
+
another_model_class = Class.new(PgEngine::BaseRecord)
|
8
|
+
model_class.include described_class
|
9
|
+
another_model_class.include described_class
|
10
|
+
model_class.parent_accessor = :one
|
11
|
+
another_model_class.parent_accessor = :two
|
12
|
+
expect(model_class.parent_accessor).to be :one
|
13
|
+
expect(another_model_class.parent_accessor).to be :two
|
14
|
+
expect { described_class.parent_accessor }.to raise_error(NoMethodError)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#parent?' do
|
19
|
+
it do
|
20
|
+
expect(create(:cosa)).to be_parent
|
21
|
+
end
|
22
|
+
|
23
|
+
it do
|
24
|
+
expect(create(:categoria_de_cosa)).not_to be_parent
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -8,6 +8,10 @@ RSpec.describe UserAccount do
|
|
8
8
|
let(:user_account) { create(:user_account) }
|
9
9
|
|
10
10
|
it 'se persiste' do
|
11
|
-
|
11
|
+
ActsAsTenant.without_tenant do
|
12
|
+
expect(user_account).to be_persisted
|
13
|
+
expect(User.count).to eq 1
|
14
|
+
expect(described_class.count).to eq 1
|
15
|
+
end
|
12
16
|
end
|
13
17
|
end
|
@@ -5,10 +5,12 @@
|
|
5
5
|
require 'rails_helper'
|
6
6
|
|
7
7
|
RSpec.describe User do
|
8
|
-
let(:user) { create(:user) }
|
8
|
+
let(:user) { create(:user, :owner) }
|
9
9
|
|
10
10
|
it 'se persiste' do
|
11
11
|
expect(user).to be_persisted
|
12
|
+
expect(UserAccount.unscoped.count).to eq 1
|
13
|
+
expect(UserAccount.first.profiles).to include(:account__owner)
|
12
14
|
end
|
13
15
|
|
14
16
|
it do
|
@@ -21,28 +23,4 @@ RSpec.describe User do
|
|
21
23
|
expect(results).to eq [user]
|
22
24
|
end
|
23
25
|
end
|
24
|
-
|
25
|
-
describe 'default scope' do
|
26
|
-
before do
|
27
|
-
ActsAsTenant.current_tenant = nil
|
28
|
-
ActsAsTenant.test_tenant = nil
|
29
|
-
Current.reset
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'scopes according to tenant' do
|
33
|
-
account = create(:account)
|
34
|
-
other_account = create(:account)
|
35
|
-
usr1 = usr2 = usr3 = usr4 = nil
|
36
|
-
ActsAsTenant.with_tenant(other_account) do
|
37
|
-
usr3 = create(:user)
|
38
|
-
usr4 = create(:user)
|
39
|
-
end
|
40
|
-
ActsAsTenant.with_tenant(account) do
|
41
|
-
usr1 = create(:user)
|
42
|
-
usr2 = create(:user)
|
43
|
-
expect(described_class.all).to contain_exactly(usr1, usr2)
|
44
|
-
end
|
45
|
-
expect(described_class.all).to contain_exactly(usr1, usr2, usr3, usr4)
|
46
|
-
end
|
47
|
-
end
|
48
26
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe AccountPolicy do
|
4
|
+
subject do
|
5
|
+
described_class.new(user, account)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:account) { ActsAsTenant.current_tenant }
|
9
|
+
let(:user) { create :user, account: }
|
10
|
+
|
11
|
+
it do
|
12
|
+
expect(subject).to permit(:show)
|
13
|
+
end
|
14
|
+
|
15
|
+
it do
|
16
|
+
user.user_accounts.first.update(membership_status: :disabled)
|
17
|
+
expect(subject).to permit(:show)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
RSpec::Matchers.define_negated_matcher :not_change, :change
|
4
|
+
|
5
|
+
describe 'invite users to the platform and to an account' do
|
6
|
+
let(:account) { ActsAsTenant.current_tenant }
|
7
|
+
|
8
|
+
describe 'send an invitation to the platform', :tpath_req do
|
9
|
+
let(:logged_user) { create :user, :owner }
|
10
|
+
|
11
|
+
before do
|
12
|
+
sign_in logged_user
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'new' do
|
16
|
+
it 'shows the form' do
|
17
|
+
get '/users/invitation/new'
|
18
|
+
expect(response).to have_http_status(:ok)
|
19
|
+
expect(response.body).to have_text('Agregar usuario')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'create' do
|
24
|
+
subject do
|
25
|
+
post '/users/invitation', params:
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:email) { Faker::Internet.email }
|
29
|
+
let(:params) do
|
30
|
+
{
|
31
|
+
user: {
|
32
|
+
email:,
|
33
|
+
user_accounts_attributes: [{
|
34
|
+
profiles: ['cosas__read']
|
35
|
+
}]
|
36
|
+
}
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'creates the User and the UserAccount' do
|
41
|
+
expect { subject }.to change(User.unscoped, :count).by(1).and(change(UserAccount.unscoped, :count).by(1))
|
42
|
+
expect(UserAccount.last.profiles).to contain_exactly('cosas__read')
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when the user exists but not the user account' do
|
46
|
+
let!(:other_user) do
|
47
|
+
ActsAsTenant.without_tenant do
|
48
|
+
create :user
|
49
|
+
end
|
50
|
+
end
|
51
|
+
let(:email) { other_user.email }
|
52
|
+
|
53
|
+
it 'creates the UserAccount but not the User' do
|
54
|
+
expect { subject }.to not_change(User.unscoped, :count).and(change(UserAccount.unscoped, :count).by(1))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when the user exists but is discarded' do
|
59
|
+
let!(:other_user) do
|
60
|
+
ActsAsTenant.without_tenant do
|
61
|
+
create :user, discarded_at: Time.current
|
62
|
+
end
|
63
|
+
end
|
64
|
+
let(:email) { other_user.email }
|
65
|
+
|
66
|
+
it 'doesnt create any' do
|
67
|
+
expect { subject }.to not_change(User.unscoped, :count).and(not_change(UserAccount.unscoped, :count))
|
68
|
+
expect(response).to have_http_status(:unprocessable_entity)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'when the user belongs to the account' do
|
73
|
+
let(:email) { logged_user.email }
|
74
|
+
|
75
|
+
it 'doesnt create any' do
|
76
|
+
expect { subject }.to not_change(User.unscoped, :count).and(not_change(UserAccount.unscoped, :count))
|
77
|
+
expect(response).to have_http_status(:unprocessable_entity)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe 'accept an invitation to the platform and to the account' do
|
84
|
+
subject do
|
85
|
+
put '/users/invitation', params: {
|
86
|
+
user: {
|
87
|
+
nombre: Faker::Name.first_name,
|
88
|
+
apellido: Faker::Name.last_name,
|
89
|
+
password: 'asd12345',
|
90
|
+
password_confirmation: 'asd12345',
|
91
|
+
accept_terms: '1',
|
92
|
+
invitation_token: user.raw_invitation_token
|
93
|
+
}
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
let(:user) do
|
98
|
+
User.invite!({ email: Faker::Internet.email, user_accounts_attributes: [{ profiles: [] }] })
|
99
|
+
end
|
100
|
+
|
101
|
+
it do
|
102
|
+
expect(user.user_accounts.length).to eq 1
|
103
|
+
user_account = user.user_accounts.first
|
104
|
+
expect(user_account.invitation_status).to eq 'ist_invited'
|
105
|
+
expect { subject }.to change { user.reload.invitation_accepted_at }.to(be_present)
|
106
|
+
put "/u/espacios/#{account.to_param}/update_invitation", params: { accept: 1 }
|
107
|
+
expect(user_account.reload.invitation_status).to eq 'ist_accepted'
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe 'update an invitation' do
|
112
|
+
let(:logged_user) { create :user, account: }
|
113
|
+
let(:user_account) do
|
114
|
+
logged_user.user_accounts.first
|
115
|
+
end
|
116
|
+
|
117
|
+
before do
|
118
|
+
sign_in logged_user
|
119
|
+
user_account.update(membership_status:, invitation_status: :ist_invited)
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'when accepting an invite' do
|
123
|
+
subject do
|
124
|
+
put "/u/espacios/#{account.to_param}/update_invitation", params: { accept: 1 }
|
125
|
+
end
|
126
|
+
|
127
|
+
let(:membership_status) { :ms_active }
|
128
|
+
|
129
|
+
it do
|
130
|
+
expect { subject }.to change { user_account.reload.invitation_status }.to('ist_accepted')
|
131
|
+
end
|
132
|
+
|
133
|
+
pending 'and doesnt belong to the account'
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'when rejecting an invite' do
|
137
|
+
subject do
|
138
|
+
put "/u/espacios/#{account.to_param}/update_invitation", params: { reject: 1 }
|
139
|
+
end
|
140
|
+
|
141
|
+
let(:membership_status) { :ms_active }
|
142
|
+
|
143
|
+
it do
|
144
|
+
expect { subject }.to change { user_account.reload.invitation_status }.to('ist_rejected')
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'when signing off the account' do
|
149
|
+
subject do
|
150
|
+
put "/u/espacios/#{account.to_param}/update_invitation", params: { sign_off: 1 }
|
151
|
+
end
|
152
|
+
|
153
|
+
let(:membership_status) { %i[ms_active ms_disabled].sample }
|
154
|
+
|
155
|
+
it do
|
156
|
+
expect { subject }.to change { user_account.reload.invitation_status }.to('ist_signed_off')
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe 'remove an invitation', :tpath_req do
|
162
|
+
subject do
|
163
|
+
delete "/u/t/user_accounts/#{user_account.to_param}"
|
164
|
+
end
|
165
|
+
|
166
|
+
let(:logged_user) { create :user, :owner }
|
167
|
+
let(:user_account) do
|
168
|
+
user.user_accounts.first
|
169
|
+
end
|
170
|
+
let!(:user) do
|
171
|
+
User.invite!({ email: Faker::Internet.email, user_accounts_attributes: [{ profiles: [] }] })
|
172
|
+
end
|
173
|
+
|
174
|
+
before do
|
175
|
+
sign_in logged_user
|
176
|
+
end
|
177
|
+
|
178
|
+
context 'when the user is confirmed' do
|
179
|
+
before do
|
180
|
+
user.nombre = Faker::Name.first_name
|
181
|
+
user.apellido = Faker::Name.last_name
|
182
|
+
user.accept_invitation!
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'removes the UserAccount but not the User' do
|
186
|
+
expect { subject }.to change { UserAccount.unscoped.count }.by(-1).and(not_change(User.unscoped, :count))
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context 'when the user is not confirmed' do
|
191
|
+
it 'removes both the UserAccount and the User' do
|
192
|
+
expect { subject }.to change { UserAccount.unscoped.count }.by(-1).and(change(User.unscoped, :count).by(-1))
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'rails_helper'
|
2
2
|
|
3
|
-
describe 'Resources' do
|
4
|
-
let(:user) { create :user }
|
3
|
+
describe 'Resources', :tpath_req do
|
4
|
+
let(:user) { create :user, :owner }
|
5
5
|
let(:cosa) { create :cosa }
|
6
6
|
|
7
7
|
before do
|
@@ -10,34 +10,33 @@ describe 'Resources' do
|
|
10
10
|
|
11
11
|
describe 'action links' do
|
12
12
|
it 'shows the archive link' do
|
13
|
-
get '/u/cosas/' + cosa.to_param
|
13
|
+
get '/u/t/cosas/' + cosa.to_param
|
14
14
|
expect(response).to have_http_status(:ok)
|
15
|
-
|
16
|
-
expect(response.body).to match regex
|
15
|
+
expect(response.body).to have_css('span[title="Archivar"] a')
|
17
16
|
end
|
18
17
|
|
19
18
|
it 'shows the unarchive link' do
|
20
19
|
cosa.update(discarded_at: Time.current)
|
21
|
-
get '/u/cosas/' + cosa.to_param
|
22
|
-
expect(response.body).to have_link(href: %r{/u/cosas/[\d]+/restore})
|
20
|
+
get '/u/t/cosas/' + cosa.to_param
|
21
|
+
expect(response.body).to have_link(href: %r{/u/t/.*/cosas/[\d]+/restore})
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
25
|
describe 'set breadcrumbs for all actions' do
|
27
26
|
it 'when flat archived index' do
|
28
|
-
get '/u/cosas/archived'
|
29
|
-
expect(response.body).to have_css('.breadcrumb a[href
|
27
|
+
get '/u/t/cosas/archived'
|
28
|
+
expect(response.body).to have_css('.breadcrumb a[href*="/cosas"]')
|
30
29
|
end
|
31
30
|
|
32
31
|
it 'when nested archived index' do
|
33
|
-
get "/u/categoria_de_cosas/#{cosa.categoria_de_cosa.to_param}/cosas/archived"
|
32
|
+
get "/u/t/categoria_de_cosas/#{cosa.categoria_de_cosa.to_param}/cosas/archived"
|
34
33
|
expect(response.body).to \
|
35
|
-
have_css ".breadcrumb a[href
|
34
|
+
have_css ".breadcrumb a[href*=\"/categoria_de_cosas/#{cosa.categoria_de_cosa.to_param}/cosas\"]"
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
39
38
|
describe '#archive' do
|
40
|
-
let(:url) { "/u/cosas/#{cosa.to_param}/archive" }
|
39
|
+
let(:url) { "/u/t/cosas/#{cosa.to_param}/archive" }
|
41
40
|
|
42
41
|
it 'when accepts turbo stream' do
|
43
42
|
headers = { 'ACCEPT' => 'text/vnd.turbo-stream.html' }
|
@@ -47,7 +46,7 @@ describe 'Resources' do
|
|
47
46
|
|
48
47
|
it 'when accepts only html' do
|
49
48
|
expect { post url }.to change { cosa.reload.discarded_at }.to(be_present)
|
50
|
-
expect(response).to redirect_to([:
|
49
|
+
expect(response).to redirect_to([:tenant, cosa])
|
51
50
|
end
|
52
51
|
|
53
52
|
context 'when fails' do
|
@@ -64,7 +63,7 @@ describe 'Resources' do
|
|
64
63
|
|
65
64
|
it 'when accepts only html' do
|
66
65
|
post url
|
67
|
-
expect(response).to redirect_to([:
|
66
|
+
expect(response).to redirect_to([:tenant, cosa])
|
68
67
|
expect(flash[:alert]).to eq 'Hubo un error al intentar actualizar el coso'
|
69
68
|
end
|
70
69
|
end
|
@@ -72,7 +71,7 @@ describe 'Resources' do
|
|
72
71
|
|
73
72
|
describe '#restore' do
|
74
73
|
subject do
|
75
|
-
post "/u/cosas/#{cosa.to_param}/restore"
|
74
|
+
post "/u/t/cosas/#{cosa.to_param}/restore"
|
76
75
|
end
|
77
76
|
|
78
77
|
let(:cosa) { create :cosa, discarded_at: Time.zone.now }
|