symphonia 4.1.1 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  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