symphonia 4.1.1 → 4.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 37c5df664c5d4a4e23242972efcb37a44a97b0000c943aba8ff68ac7ebd4d2ec
4
- data.tar.gz: 1636c08f1a1aa674319a19172cf0291d5fa910a9930056f8598ac96b7bf65937
3
+ metadata.gz: 8b1926adf23dfcc6193affda2c0eaf6edcf7729eba7ee21fde5d65d7ffe6fa64
4
+ data.tar.gz: 16cd15eb367b3f597e6fc67f60d8d8de7941010d08ec42b5b02baecf3fddf623
5
5
  SHA512:
6
- metadata.gz: f2716c183798fd2acc14702ac79d44f4f210e4d4b770c6670ff78267c2ada056d3c331229371f02a66ca32d7496618a65972b1405860aace5fd7fc433161b94b
7
- data.tar.gz: dbeff2e27c22f063183e6eecd395ba895cf8c6986841281d1914f2e3997ee4a833fd3e78c7a38dca24e49041083f3398a876ea8a4bd476b11ec57cf9830c1734
6
+ metadata.gz: c3b96b59bd3014de2cd86cbf53a5c4bfe1c30f4f1ee6d1b9a60a71c98784c33c1a8b270471dfe8a5db35f80c00f02c931e3d54c98e712000737828e805226480
7
+ data.tar.gz: 31b3f194941fb8661419af1f52a1ab9c4423f40da86443846876f9996505127903002473ec7c1923f91891858851201bb134420feb1210f7ecf061f182ae11bb
data/.rubocop.yml CHANGED
@@ -19,6 +19,8 @@ Metrics/BlockLength:
19
19
  Enabled: false
20
20
  Metrics/MethodLength:
21
21
  Enabled: false
22
+ Naming/VariableNumber:
23
+ Enabled: false
22
24
 
23
25
  Style/Documentation:
24
26
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -5,6 +5,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
+ ## [4.2.0] - 2022-04-07
9
+ ### Removed
10
+ - awesome_nested_set dependency
11
+ ### Changed
12
+ - start with Ruby3 support
13
+
14
+ ## [4.1.3] - 2022-03-02
15
+ ### Changed
16
+ - update sidekiq
17
+ ## [4.1.2] - 2022-01-20
18
+ ### Removed
19
+ - Recaptcha conditions
20
+ ### Changed
21
+ - registration/login autocomplete
22
+ - cleanup controller extensions
23
+
8
24
  ## [4.1.1] - 2021-12-26
9
25
  ### Fixed
10
26
  - user activation
@@ -1,42 +1,42 @@
1
1
  /**
2
2
  * Symphonia modal dialog pop-up.
3
3
  * @param {String} id
4
- * @param {Object} options
5
- * @param {String} options.title - Title of dialog window.
6
- * @param {Boolean} options.force - If dialog element exists, will remove and replace new one.
7
- * @param {String} options.text - Text for body of dialog window.
8
- * @param {String} options.html - Content (html) for body of dialog window.
9
- * @param {String} options.submit - Text of submit button. If provided generate submit button.
10
- * @param {Boolean} options.large - Use Large modal
4
+ * @param {Object} opts
5
+ * @param {String} opts.title - Title of dialog window.
6
+ * @param {Boolean} opts.force - If dialog element exists, will remove and replace new one.
7
+ * @param {String} opts.text - Text for body of dialog window.
8
+ * @param {String} opts.html - Content (html) for body of dialog window.
9
+ * @param {String} opts.submit - Text of submit button. If provided generate submit button.
10
+ * @param {Boolean} opts.large - Use Large modal
11
11
  */
12
- SymphoniaDialog = function (id, options) {
13
- var options = $.extend(options, {});
12
+ SymphoniaDialog = function (id, opts) {
13
+ const options = $.extend(opts, {});
14
14
  if (options["force"] === undefined)
15
15
  options["force"] = true;
16
16
 
17
17
  this.id = id || 'ajax_modal';
18
- var m = document.getElementById(this.id);
18
+ const m = document.getElementById(this.id);
19
19
 
20
20
  // var currentDialog = document.getElementById(this.id + "__symphonia_dialog");
21
21
  // if (currentDialog) {
22
22
  // currentDialog.remove();
23
23
  // }
24
24
 
25
- var dialog = document.createElement("div");
26
- var modalDialog = document.createElement("div");
25
+ const dialog = document.createElement("div");
26
+ const modalDialog = document.createElement("div");
27
27
  modalDialog.className = "modal-dialog";
28
28
  if (options["large"]) {
29
29
  modalDialog.classList.add("modal-lg")
30
30
  }
31
31
  dialog.setAttribute("role", "document");
32
32
 
33
- var content = document.createElement("div");
33
+ const content = document.createElement("div");
34
34
  content.className = "modal-content";
35
- var heading = document.createElement("div");
35
+ const heading = document.createElement("div");
36
36
  heading.className = "modal-header";
37
- var modalTitle = document.createElement("h5");
37
+ const modalTitle = document.createElement("h5");
38
38
  modalTitle.className = "modal-title";
39
- var body = document.createElement("div");
39
+ const body = document.createElement("div");
40
40
 
41
41
  body.className = "modal-body";
42
42
  dialog.id = this.id;
@@ -46,7 +46,7 @@ SymphoniaDialog = function (id, options) {
46
46
  // =-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-
47
47
 
48
48
  this.appendSubmitButton = function (label) {
49
- var submitButton = document.createElement('button');
49
+ const submitButton = document.createElement('button');
50
50
  submitButton.onclick = this.submit;
51
51
  submitButton.innerText = (label === true) && 'Submit' || label;
52
52
  submitButton.className = "btn btn-primary";
@@ -54,14 +54,14 @@ SymphoniaDialog = function (id, options) {
54
54
  return submitButton;
55
55
  };
56
56
  this.submit = function () {
57
- var form = dialog.querySelector("form");
57
+ const form = dialog.querySelector("form");
58
58
  if (form)
59
59
  form.submit();
60
60
  };
61
61
  this.show = function () {
62
62
  // dialog.find(".modal-body > .modal-content-inner-container").css({'max-height': window.innerHeight - 200});
63
63
  // dialog.find(".modal-body > .modal-content-inner-container").css({'max-height': window.innerHeight - 200});
64
- var t = dialog.querySelector(".title");
64
+ const t = dialog.querySelector(".title");
65
65
  if (t && t.innerHTML === '') {
66
66
  this.title = modalTitle.innerHTML;
67
67
  t.remove();
@@ -83,7 +83,7 @@ SymphoniaDialog = function (id, options) {
83
83
 
84
84
  modalTitle.innerText = options.title || '';
85
85
 
86
- var closeButton = document.createElement("button");
86
+ const closeButton = document.createElement("button");
87
87
  closeButton.className = "close fa fa-times";
88
88
  closeButton.dataset['dismiss'] = "modal";
89
89
  heading.appendChild(modalTitle);
@@ -114,7 +114,7 @@ SymphoniaDialog = function (id, options) {
114
114
  dialog.appendChild(modalDialog);
115
115
 
116
116
  if (options.force) {
117
- var currentDialog = document.getElementById(dialog.id);
117
+ const currentDialog = document.getElementById(dialog.id);
118
118
  if (currentDialog)
119
119
  currentDialog.remove();
120
120
  }
@@ -130,7 +130,7 @@ SymphoniaDialog.prototype.close = function () {
130
130
  };
131
131
  window.Symphonia.dialog = {
132
132
  show: function(IDcontainer, options) {
133
- var modal = new SymphoniaDialog(IDcontainer, options);
133
+ const modal = new SymphoniaDialog(IDcontainer, options);
134
134
  modal.show();
135
135
  }
136
- }
136
+ }
@@ -43,9 +43,7 @@
43
43
  content: "\f05d"
44
44
  }
45
45
  }
46
- flash.recaptcha_error {
47
- display: none;
48
- }
46
+
49
47
  .nodata, .no-data {
50
48
  @extend .flash;
51
49
  @extend .info;
@@ -5,8 +5,6 @@ module Symphonia
5
5
  before_action -> { menu_item(:my_account) }, only: [:show, :edit, :update]
6
6
  before_action :prepare_user, only: [:register, :create]
7
7
 
8
- helper Recaptcha::ClientHelper if defined? Recaptcha
9
-
10
8
  def show
11
9
  @user = current_account
12
10
 
@@ -159,11 +157,7 @@ module Symphonia
159
157
 
160
158
  # @return [Boolean]
161
159
  def verify_registration
162
- if defined?(Recaptcha)
163
- verify_recaptcha(model: @user)
164
- else
165
- true
166
- end
160
+ true
167
161
  end
168
162
 
169
163
  end
@@ -9,11 +9,9 @@
9
9
  </div>
10
10
  <div class="col-lg-8">
11
11
  <%= f.text_field :first_name, required: true %>
12
-
13
12
  </div>
14
13
  <div class="col-lg-8">
15
14
  <%= f.text_field :last_name, required: true %>
16
-
17
15
  </div>
18
16
  <div class="col-lg-8">
19
17
  <% if f.object.external_id.blank? %>
@@ -21,5 +19,3 @@
21
19
  <% end %>
22
20
  </div>
23
21
  </div>
24
-
25
-
@@ -8,20 +8,10 @@
8
8
  <%= symphonia_form_for(@user, url: account_register_path) do |f| %>
9
9
  <div style="width:1px;height: 1px;visibility: hidden"><%= check_box_tag :terms, true %></div>
10
10
  <%= f.error_messages %>
11
- <%= f.email_field :mail, required: true, prepend: "@" %>
12
- <%= f.text_field :name, required: true, prepend: icon("user") %>
13
- <%= f.password_field :password, required: true, prepend: icon('key') %>
14
- <% if defined? Recaptcha %>
15
- <fieldset>
16
- <%= content_tag(:legend, t(:text_explanation_recaptcha)) %>
17
- <div class="form-group">
18
- <div class="col-sm-offset-4 col-sm-5">
19
- <%#= invisible_recaptcha_tags %>
20
- <%= recaptcha_tags(:display => { :theme => 'white' }) %>
21
- </div>
22
- </div>
23
- </fieldset>
24
- <% end %>
11
+ <%= f.text_field :name, required: true, autocomplete: "off", prepend: icon("user") %>
12
+ <%= f.email_field :mail, required: true, autocomplete: "username", prepend: "@" %>
13
+ <%= f.password_field :password, autocomplete: "new-password", required: true, prepend: icon('key') %>
14
+
25
15
  <%= f.primary t(:button_register), class: 'btn btn-primary btn-block' %>
26
16
  <% end %>
27
17
  </div>
@@ -1,8 +1,8 @@
1
1
  <%= f.error_messages %>
2
- <%= hidden_field_tag(:back_url, params[:back_url].presence || request.env['HTTP_REFERER'].presence || session[:back_url]) %>
3
- <%= f.text_field :login, required: true, autofocus: true %>
2
+ <%= hidden_field_tag(:back_url, back_url || session[:back_url]) %>
3
+ <%= f.text_field :login, required: true, autofocus: true, autocomplete: "username" %>
4
4
 
5
- <%= f.password_field :password, required: true %>
5
+ <%= f.password_field :password, required: true, autocomplete: "current-password" %>
6
6
 
7
7
  <%= f.form_group :remember_me do %>
8
8
  <%= f.check_box :remember_me %>
@@ -79,10 +79,6 @@ cs:
79
79
  role_id: 'Role'
80
80
  ssl: Používat SSL?
81
81
 
82
- recaptcha:
83
- errors:
84
- verification_failed: 'Nesprávný text z obrázku'
85
-
86
82
  helpers:
87
83
  submit:
88
84
  create: Vytvořit
@@ -144,7 +140,6 @@ cs:
144
140
  text_user_not_found: Účet nenalezen
145
141
  text_activation_resend: Aktivační odkaz odeslán
146
142
  text_reset_password_resend: Informace o změně hesla odeslány
147
- text_explanation_recaptcha: 'Opište prosím tato dvě slova:'
148
143
  text_or: nebo
149
144
  text_confirm_send_unlock_mail: Po aktivaci účtu bude uživateli zaslán email.
150
145
  text_error_no_data_file_input: Nebyl vybrán žádný soubor
@@ -14,5 +14,4 @@ end
14
14
 
15
15
  # gem 'bootswatch-rails'
16
16
  # gem 'jquery-colorbox-rails'
17
- # gem 'recaptacha'
18
- # gem 'ckeditor-rails'
17
+ # gem 'ckeditor-rails'
@@ -1,10 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
- # Recaptcha.configure do |config|
4
- # config.site_key = '6LejxOESAAAAALC3ohQCddKilokhYnTNXfYVItZe'
5
- # config.secret_key = '6LejxOESAAAAANf-9T4nyHCDGW6Ok78Zo7GaG2GK'
6
- # end
7
-
8
3
  WillPaginate.per_page = 20
9
4
  # Rails.application.config.i18n.available_locales = %i[en cs ru pl]
10
5
 
@@ -3,69 +3,39 @@ module Symphonia
3
3
 
4
4
  extend ActiveSupport::Concern
5
5
 
6
+ class Unauthorized < RuntimeError
7
+ end
6
8
 
7
9
  included do
8
- class Unauthorized < Exception;
9
- end
10
10
 
11
11
  before_action :current_user, :menu_item
12
12
  before_action :set_default_locale
13
13
 
14
- # force_ssl if: -> {Rails.env.production? && User.current.ssl?}
15
-
16
14
  add_flash_types :notice
17
15
  add_flash_types :info
18
16
  add_flash_types :warning
19
17
  add_flash_types :error
20
18
 
21
- rescue_from ::ActiveRecord::RecordNotFound do
22
- render_404
23
- end
24
-
25
- rescue_from Unauthorized do
26
- render_403
27
- end
28
-
29
- helper_method :current_user
19
+ rescue_from ::ActiveRecord::RecordNotFound, with: :render_404
20
+ rescue_from Unauthorized, with: :render_403
30
21
 
22
+ helper_method :current_user, :back_url
31
23
  end
32
24
 
33
25
  def back_url
34
- url = params[:back_url]
35
- if url.nil? && (referer = request.env['HTTP_REFERER'])
26
+ url = params[:back_url].presence
27
+ if url.nil? && (referer = request.env['HTTP_REFERER'].presence)
36
28
  url = CGI.unescape(referer.to_s)
37
29
  end
38
30
  url
39
31
  end
40
32
 
41
- # def redirect_back_or_default(default, options={})
42
- # back_url = params[:back_url].to_s
43
- # if back_url.present?
44
- # begin
45
- # uri = URI.parse(back_url)
46
- # # do not redirect user to another host or to the login or register page
47
- # if (uri.relative? || (uri.host == request.host)) && !uri.path.match(%r{/(login|account/register)})
48
- # redirect_to(back_url)
49
- # return
50
- # end
51
- # rescue URI::InvalidURIError
52
- # logger.warn("Could not redirect to invalid URL #{back_url}")
53
- # # redirect to default
54
- # end
55
- # elsif options[:referer]
56
- # redirect_to_referer_or default
57
- # return
58
- # end
59
- # redirect_to default, options
60
- # false
61
- # end
62
-
63
33
  # Redirects to the request referer if present, redirects to args or call block otherwise.
64
34
  def redirect_to_referer_or(*args, &block)
65
35
  redirect_to :back
66
36
  rescue ::ActionController::RedirectBackError
67
37
  if args.any?
68
- redirect_to *args
38
+ redirect_to(*args)
69
39
  elsif block_given?
70
40
  block.call
71
41
  else
@@ -76,7 +46,10 @@ module Symphonia
76
46
  # private
77
47
 
78
48
  def set_locale
79
- client_lang = Array(params.fetch(:locale, nil).presence || session[:locale].presence || request.env['HTTP_ACCEPT_LANGUAGE'].to_s.split(',').collect { |l| l.scan(/^[a-z]{2}/) }.flatten)
49
+ params_locale = params.fetch(:locale, nil).presence
50
+ params_locale ||= session[:locale].presence
51
+ params_locale ||= request.env['HTTP_ACCEPT_LANGUAGE'].to_s.split(',').collect { |l| l.scan(/^[a-z]{2}/) }.flatten
52
+ client_lang = Array(params_locale).compact
80
53
  client_lang.unshift current_user.language if current_user.language
81
54
  @client_lang = client_lang.detect { |l| I18n.available_locales.include?(l.to_sym) }
82
55
 
@@ -87,53 +60,57 @@ module Symphonia
87
60
  end
88
61
 
89
62
  def set_default_locale
90
- if (enforce_default = Symphonia.config.default_locale)
91
- I18n.locale = enforce_default
92
- end
63
+ return unless (enforce_default = Symphonia.config.default_locale)
64
+
65
+ I18n.locale = enforce_default
93
66
  end
94
67
 
95
68
  # protected
96
69
 
97
- def login_require(format = nil)
70
+ def login_require(_format = nil)
98
71
  if current_user.nil? || !current_user.logged_in?
99
72
  respond_to do |format|
100
73
  format.html do
101
74
  store_location
102
75
  redirect_to symphonia.login_path, flash: { error: t(:text_login_require) }
103
76
  end
104
- format.json { render json: { errors: 'You must be logged in to access this endpoint' }, status: 401 }
105
- format.any { head 401 }
77
+ format.json do
78
+ render json: { errors: 'You must be logged in to access this endpoint' }, status: :unauthorized
79
+ end
80
+ format.any { head :unauthorized }
106
81
  end
107
82
  return false
108
83
  end
109
84
  true
110
85
  end
111
86
 
112
- alias_method :require_login, :login_require
113
- alias_method :require_user, :login_require
87
+ alias require_login login_require
88
+ alias require_user login_require
114
89
 
115
90
  def admin_require
116
91
  return unless login_require
117
92
 
118
93
  unless current_user.admin?
119
94
  render_403
120
- return false
95
+ false
121
96
  end
122
97
  end
123
98
 
124
- alias_method :require_admin, :admin_require
99
+ alias require_admin admin_require
125
100
 
126
101
  def render_403
127
102
  respond_to do |format|
128
- format.html { render template: 'common/403', message: :notice_not_authorized, status: 403 }
129
- format.js { render plain: "alert('#{t :text_access_deny}')", message: :notice_not_authorized, status: 403 }
103
+ format.html { render template: 'common/403', message: :notice_not_authorized, status: :forbidden }
104
+ format.js do
105
+ render plain: "alert('#{t :text_access_deny}')", message: :notice_not_authorized, status: :forbidden
106
+ end
130
107
  format.any { head 403, message: :notice_not_authorized }
131
108
  end
132
109
  end
133
110
 
134
111
  def render_404
135
112
  respond_to do |format|
136
- format.html { render template: 'common/404', message: :notice_page_not_found, status: 404 }
113
+ format.html { render template: 'common/404', message: :notice_page_not_found, status: :not_found }
137
114
  format.any { head 404, message: :not_found }
138
115
  end
139
116
  end
@@ -161,35 +138,32 @@ module Symphonia
161
138
  def current_user
162
139
  return (Symphonia::User.current ||= @current_user) if defined?(@current_user)
163
140
 
164
- @current_user = current_user_session && current_user_session.user
141
+ @current_user = current_user_session&.user
165
142
  Symphonia::User.current = @current_user || Symphonia::User::Anonymous.new
166
143
  end
167
144
 
168
145
  def authorize
169
146
  if Symphonia::User.current.authorize?(controller_name, action_name)
170
147
  return true
148
+ elsif Symphonia::User.current.logged_in?
149
+ raise Unauthorized
171
150
  else
172
- if Symphonia::User.current.logged_in?
173
- raise Unauthorized
174
- else
175
- respond_to do |format|
176
- format.html do
177
- return redirect_to(symphonia.login_path(back_url: request.path), error: t(:text_error_login_required))
178
- end
179
- format.any { return head 401 }
151
+ respond_to do |format|
152
+ format.html do
153
+ return redirect_to(symphonia.login_path(back_url: request.path), error: t(:text_error_login_required))
180
154
  end
155
+ format.any { return head 401 }
181
156
  end
182
157
  end
158
+
183
159
  raise Unauthorized
184
160
  end
185
161
 
186
162
  def handle_unverified_request
187
163
  # raise an exception
188
- fail ActionController::InvalidAuthenticityToken
164
+ raise ActionController::InvalidAuthenticityToken
189
165
  # or destroy session, redirect
190
- if current_user_session
191
- current_user_session.destroy
192
- end
166
+ current_user_session&.destroy
193
167
  redirect_to main_app.root_url
194
168
  end
195
169
 
@@ -16,9 +16,6 @@ require 'jquery-rails'
16
16
  require 'jquery-ui-rails'
17
17
  require 'rdiscount'
18
18
  require 'sortable-table'
19
- # require 'paperclip'
20
- require 'awesome_nested_set'
21
- # require 'acts_as_list'
22
19
  require 'bootstrap_form'
23
20
  require 'bootstrap-datepicker-rails'
24
21
  # require 'wicked_pdf'
@@ -106,7 +106,7 @@ module Symphonia
106
106
 
107
107
  # TODO: @klass.name || @klass.base_class.name || entity.class.name
108
108
  def format_value(view, value, _entity)
109
- view.t("#{@klass.name.underscore}.#{name.to_s.pluralize}.#{value}", format_options)
109
+ view.t("#{@klass.name.underscore}.#{name.to_s.pluralize}.#{value}", **format_options)
110
110
  end
111
111
 
112
112
  def input_field
@@ -179,7 +179,7 @@ module Symphonia
179
179
  class DateAttribute < Attribute
180
180
 
181
181
  def format_value(view, value, _entity)
182
- value && view.l(value.to_date, format_options)
182
+ value && view.l(value.to_date, **format_options)
183
183
  end
184
184
 
185
185
  end
@@ -187,7 +187,7 @@ module Symphonia
187
187
  class DateTimeAttribute < Attribute
188
188
 
189
189
  def format_value(view, value, _entity)
190
- value && view.l(value.localtime, format_options)
190
+ value && view.l(value.localtime, **format_options)
191
191
  end
192
192
 
193
193
  end
@@ -1,5 +1,5 @@
1
1
  module Symphonia
2
2
 
3
- VERSION = '4.1.1'
3
+ VERSION = '4.2.0'
4
4
 
5
5
  end
@@ -6,8 +6,8 @@ RSpec.describe Symphonia::AccountsController do
6
6
 
7
7
  let(:regular_user) { FactoryBot.create(:user) }
8
8
 
9
- context 'logged', logged: true do
10
- context '#update' do
9
+ context 'with logged', logged: true do
10
+ describe '#update' do
11
11
 
12
12
  it 'valid' do
13
13
  put :update, params: { user: { login: Faker::Internet.user_name } }
@@ -22,53 +22,52 @@ RSpec.describe Symphonia::AccountsController do
22
22
  end
23
23
  end
24
24
 
25
- context '#resend_activation' do
25
+ describe '#resend_activation' do
26
26
 
27
27
  let(:email) { Faker::Internet.email }
28
28
  subject { get :resend_activation, params: { email: email } }
29
29
 
30
30
  it 'non exist user' do
31
- is_expected.to redirect_to :root
31
+ is_expected.to redirect_to :login
32
32
  expect(flash[:error]).not_to be :blank
33
33
  end
34
34
 
35
35
  it 'active user' do
36
36
  _user = FactoryBot.create(:user, email: email, status: 'active')
37
- is_expected.to redirect_to :root
37
+ is_expected.to redirect_to :login
38
38
  expect(flash[:error]).not_to be :blank
39
39
  end
40
40
 
41
+ let(:pending_user) { FactoryBot.create(:user, email: email, status: 'pending') }
41
42
  it 'pending user' do
42
- user = FactoryBot.create(:user, email: email, status: 'pending')
43
- token = user.perishable_token.dup
43
+ token = pending_user.perishable_token.dup
44
44
 
45
45
  expect { get :resend_activation, params: { email: email } }.to have_enqueued_job.on_queue('mailers')
46
- expect(response).to have_http_status :redirect
47
46
 
48
- expect(user.reload.perishable_token).not_to eq token
47
+ expect { pending_user.reload }.to change(pending_user, :perishable_token)
49
48
  expect(flash[:error]).to be_nil
50
49
  expect(flash[:notice]).not_to be :blank
51
50
  end
52
51
  end
53
52
 
54
- context '#activation' do
55
- let(:token) { SecureRandom.hex(3) }
53
+ describe '#activation' do
56
54
  subject { get :activation, params: { activation_code: token } }
55
+ let(:token) { SecureRandom.hex(3) }
56
+ let(:pending_user) { FactoryBot.create(:user, status: 'pending') }
57
57
 
58
58
  it 'valid token' do
59
- user = FactoryBot.create(:user, status: 'pending')
60
- user.update_columns(perishable_token: token)
59
+ pending_user.update_columns(perishable_token: token)
61
60
  is_expected.to redirect_to :login
62
- expect(user.reload.status).to eq 'active'
61
+ expect { pending_user.reload }.to change(pending_user, :status).to "active"
63
62
  end
64
63
 
65
64
  it 'invalid token' do
66
- is_expected.to redirect_to :root
65
+ is_expected.to redirect_to :login
67
66
  expect(flash[:error]).not_to be :blank
68
67
  end
69
68
  end
70
69
 
71
- context '#lost_password' do
70
+ describe '#lost_password' do
72
71
 
73
72
  it 'with mail' do
74
73
  user = FactoryBot.create(:user, status: 'active')
@@ -84,8 +83,9 @@ RSpec.describe Symphonia::AccountsController do
84
83
  end
85
84
  end
86
85
 
87
- context "#reset_password" do
86
+ describe "#reset_password" do
88
87
  subject { FactoryBot.create :user }
88
+
89
89
  it "reset" do
90
90
  put :reset_password, params: { id: subject.perishable_token, password: "secret-pass-1" }
91
91
  expect(response).to redirect_to /login/
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: symphonia
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.1
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lukas Pokorny
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-25 00:00:00.000000000 Z
11
+ date: 2022-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: api-pagination
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 6.4.0
41
- - !ruby/object:Gem::Dependency
42
- name: awesome_nested_set
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: 3.2.1
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: 3.2.1
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: bootstrap
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -226,28 +212,28 @@ dependencies:
226
212
  requirements:
227
213
  - - "~>"
228
214
  - !ruby/object:Gem::Version
229
- version: 6.2.1
215
+ version: 6.4.1
230
216
  type: :runtime
231
217
  prerelease: false
232
218
  version_requirements: !ruby/object:Gem::Requirement
233
219
  requirements:
234
220
  - - "~>"
235
221
  - !ruby/object:Gem::Version
236
- version: 6.2.1
222
+ version: 6.4.1
237
223
  - !ruby/object:Gem::Dependency
238
224
  name: sidekiq-cron
239
225
  requirement: !ruby/object:Gem::Requirement
240
226
  requirements:
241
227
  - - "~>"
242
228
  - !ruby/object:Gem::Version
243
- version: '1.2'
229
+ version: '1.3'
244
230
  type: :runtime
245
231
  prerelease: false
246
232
  version_requirements: !ruby/object:Gem::Requirement
247
233
  requirements:
248
234
  - - "~>"
249
235
  - !ruby/object:Gem::Version
250
- version: '1.2'
236
+ version: '1.3'
251
237
  - !ruby/object:Gem::Dependency
252
238
  name: sortable-table
253
239
  requirement: !ruby/object:Gem::Requirement
@@ -498,7 +484,7 @@ require_paths:
498
484
  - lib
499
485
  required_ruby_version: !ruby/object:Gem::Requirement
500
486
  requirements:
501
- - - "~>"
487
+ - - ">="
502
488
  - !ruby/object:Gem::Version
503
489
  version: '2.5'
504
490
  required_rubygems_version: !ruby/object:Gem::Requirement
@@ -507,7 +493,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
507
493
  - !ruby/object:Gem::Version
508
494
  version: '0'
509
495
  requirements: []
510
- rubygems_version: 3.1.4
496
+ rubygems_version: 3.3.9
511
497
  signing_key:
512
498
  specification_version: 4
513
499
  summary: My administration