symphonia 3.4.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -4
- data/CHANGELOG.md +12 -0
- data/README.md +16 -0
- data/app/controllers/symphonia/admin_controller.rb +1 -4
- data/app/views/symphonia/admin/index.html.erb +1 -11
- data/db/migrate/20130714140501_create_roles.rb +6 -4
- data/db/migrate/20200428180001_add_uuid_to_users.rb +4 -2
- data/db/migrate/20210509141420_roles_change_permissions_to_json.rb +18 -0
- data/db/migrate/20210509180525_roles_change_permissions_to_native_json.rb +7 -0
- data/lib/generators/symphonia/setup/setup_generator.rb +17 -14
- data/lib/generators/symphonia/setup/templates/{settings.rb → app/config/initializers/settings.rb.tt} +0 -0
- data/lib/generators/symphonia/setup/templates/{404.html → public/404.html.tt} +2 -2
- data/lib/generators/symphonia/setup/templates/{500.html → public/500.html.tt} +2 -2
- data/lib/generators/symphonia/setup/templates/{spec_helper.rb → spec/spec_helper.rb.tt} +3 -2
- data/lib/symphonia.rb +4 -1
- data/lib/symphonia/model_attributes/attribute.rb +30 -14
- data/lib/symphonia/model_filters/base.rb +13 -15
- data/lib/symphonia/model_filters/boolean_filter.rb +10 -11
- data/lib/symphonia/model_filters/date_filter.rb +32 -31
- data/lib/symphonia/model_filters/integer_filter.rb +4 -5
- data/lib/symphonia/model_filters/select_filter.rb +19 -17
- data/lib/symphonia/model_filters/string_filter.rb +4 -5
- data/lib/symphonia/query.rb +10 -34
- data/lib/symphonia/query_columns.rb +1 -2
- data/lib/symphonia/query_columns/attribute_column.rb +59 -5
- data/lib/symphonia/spec_helper.rb +5 -3
- data/lib/symphonia/version.rb +3 -1
- data/spec/controllers/account_controller_spec.rb +66 -69
- data/spec/controllers/admin_controller_spec.rb +24 -25
- data/spec/libs/some_lib_spec.rb +1 -1
- data/spec/rails_helper.rb +4 -3
- data/spec/spec_helper.rb +3 -8
- metadata +71 -158
- data/app/models/symphonia/admin_module.rb +0 -18
- data/app/views/symphonia/filters/table.html.erb +0 -21
- data/db/migrate/20130828175114_create_attachments.rb +0 -20
- data/db/migrate/20141213204351_create_admin_modules.rb +0 -20
- data/lib/symphonia/query_columns/generic_column.rb +0 -165
@@ -2,12 +2,12 @@ module Symphonia
|
|
2
2
|
module ModelFilters
|
3
3
|
class BooleanFilter < Base
|
4
4
|
|
5
|
-
def operator=(
|
6
|
-
if
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
def operator=(to)
|
6
|
+
@operator = if to == '!'
|
7
|
+
'not_eq'
|
8
|
+
else
|
9
|
+
'eq'
|
10
|
+
end
|
11
11
|
end
|
12
12
|
|
13
13
|
def apply(scope)
|
@@ -16,11 +16,10 @@ module Symphonia
|
|
16
16
|
scope.where(t[name].send(operator, true))
|
17
17
|
end
|
18
18
|
|
19
|
-
def form_field(
|
20
|
-
|
19
|
+
def form_field(context)
|
20
|
+
context.text_field_tag(form_field_name, @query.active_filters[name], class: 'form-control')
|
21
21
|
end
|
22
|
-
end
|
23
22
|
|
23
|
+
end
|
24
24
|
end
|
25
|
-
|
26
|
-
end
|
25
|
+
end
|
@@ -1,18 +1,18 @@
|
|
1
1
|
module Symphonia
|
2
2
|
module ModelFilters
|
3
3
|
class DateFilter < Base
|
4
|
-
|
4
|
+
attr_writer :available_values
|
5
5
|
|
6
|
-
def initialize(name, query, options={})
|
6
|
+
def initialize(name, query, options = {})
|
7
7
|
super
|
8
8
|
@operator = 'in'
|
9
9
|
end
|
10
10
|
|
11
|
-
def value=(
|
12
|
-
v = available_values.values.reduce(:merge)[
|
11
|
+
def value=(to)
|
12
|
+
v = available_values.values.reduce(:merge)[to.to_sym]
|
13
13
|
@operator = 'between' unless q == 'today'
|
14
|
-
@value = if
|
15
|
-
data =
|
14
|
+
@value = if to == 'custom'
|
15
|
+
data = query.controller.params.require(:date_from_custom).permit(:from, :to)
|
16
16
|
v.call(data)
|
17
17
|
else
|
18
18
|
v.call
|
@@ -34,48 +34,49 @@ module Symphonia
|
|
34
34
|
def available_values
|
35
35
|
{
|
36
36
|
past: {
|
37
|
-
last_month: -> {d = Date.today.last_month.beginning_of_month; d..d.end_of_month},
|
38
|
-
last_year: -> {d = Date.today.last_year.beginning_of_year; d..d.end_of_year}
|
37
|
+
last_month: -> { d = Date.today.last_month.beginning_of_month; d..d.end_of_month },
|
38
|
+
last_year: -> { d = Date.today.last_year.beginning_of_year; d..d.end_of_year },
|
39
39
|
},
|
40
40
|
present: {
|
41
|
-
today: -> {Date.today},
|
42
|
-
this_month: -> {Date.today.beginning_of_month..Date.today.end_of_month},
|
43
|
-
this_year: -> {Date.today.beginning_of_year..Date.today.end_of_year},
|
44
|
-
custom: ->(data) {data[:from].to_date..data[:to].to_date}
|
41
|
+
today: -> { Date.today },
|
42
|
+
this_month: -> { Date.today.beginning_of_month..Date.today.end_of_month },
|
43
|
+
this_year: -> { Date.today.beginning_of_year..Date.today.end_of_year },
|
44
|
+
custom: ->(data) { data[:from].to_date..data[:to].to_date },
|
45
45
|
},
|
46
46
|
future: {
|
47
|
-
next_month: -> {d = Date.today.next_month.beginning_of_month; d..d.end_of_month},
|
48
|
-
next_year: -> {d = Date.today.next_year.beginning_of_year; d..d.end_of_year}
|
49
|
-
}
|
47
|
+
next_month: -> { d = Date.today.next_month.beginning_of_month; d..d.end_of_month },
|
48
|
+
next_year: -> { d = Date.today.next_year.beginning_of_year; d..d.end_of_year },
|
49
|
+
},
|
50
50
|
}
|
51
51
|
end
|
52
52
|
|
53
|
-
def form_field(
|
54
|
-
groups = available_values.
|
55
|
-
mem[
|
56
|
-
[
|
53
|
+
def form_field(context)
|
54
|
+
groups = available_values.each_with_object({}) do |(time, values), mem|
|
55
|
+
mem[context.t("time.#{time}")] = values.collect do |(k, _val)|
|
56
|
+
[context.t("query_options.filter_date.values.#{k}"), k]
|
57
57
|
end
|
58
|
-
mem
|
59
58
|
end
|
60
59
|
selected = Array(@query.active_filters[name])
|
61
|
-
|
62
|
-
|
60
|
+
context.content_tag(:div, class: 'row') do
|
61
|
+
context.select_tag(form_field_name.to_s, context.grouped_options_for_select(groups, selected), {
|
63
62
|
class: 'form-control',
|
64
63
|
include_blank: true,
|
65
|
-
onchange: 'symphoniaFiltersForm.dateFilterCallback(this)'
|
66
|
-
}) +
|
67
|
-
|
68
|
-
|
69
|
-
|
64
|
+
onchange: 'symphoniaFiltersForm.dateFilterCallback(this)',
|
65
|
+
}) + context.content_tag(:div, class: 'filter-custom-date clearfix input-daterange input-group inline',
|
66
|
+
style: 'display: none') do
|
67
|
+
context.date_field_tag("#{form_field_name}contextustom[to]", '', {
|
68
|
+
placeholder: context.t('query_options.filter_date.to'),
|
69
|
+
class: 'form-control datepicker pull-right',
|
70
70
|
}) +
|
71
|
-
#
|
72
|
-
|
71
|
+
# context.content_tag(:span, context.t('query_options.filter_date.to'), class: 'input-group-addon')+
|
72
|
+
context.date_field_tag("#{form_field_name}_custom[from]", '', {
|
73
73
|
placeholder: _c.t('query_options.filter_date.from'),
|
74
|
-
class: 'form-control datepicker'
|
74
|
+
class: 'form-control datepicker',
|
75
75
|
})
|
76
76
|
end
|
77
77
|
end
|
78
78
|
end
|
79
|
+
|
79
80
|
end
|
80
81
|
end
|
81
|
-
end
|
82
|
+
end
|
@@ -8,11 +8,10 @@ module Symphonia
|
|
8
8
|
scope.where(t[name].send(operator, value.to_f))
|
9
9
|
end
|
10
10
|
|
11
|
-
def form_field(
|
12
|
-
|
11
|
+
def form_field(context)
|
12
|
+
context.number_field_tag(form_field_name, @query.active_filters[name], class: 'form-control')
|
13
13
|
end
|
14
|
-
end
|
15
14
|
|
15
|
+
end
|
16
16
|
end
|
17
|
-
|
18
|
-
end
|
17
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Symphonia
|
2
2
|
module ModelFilters
|
3
3
|
class SelectFilter < StringFilter
|
4
|
-
|
4
|
+
attr_writer :available_values
|
5
5
|
|
6
6
|
def initialize(name, query, options = {})
|
7
7
|
super
|
@@ -9,7 +9,7 @@ module Symphonia
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def available_values
|
12
|
-
return @available_values.call(
|
12
|
+
return @available_values.call(context, self) if @available_values.is_a? Proc
|
13
13
|
|
14
14
|
@available_values || case @attribute
|
15
15
|
when Symphonia::ModelAttributes::EnumAttribute
|
@@ -17,18 +17,16 @@ module Symphonia
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
def value=(
|
21
|
-
@value = if
|
22
|
-
|
20
|
+
def value=(to)
|
21
|
+
@value = if to.is_a?(Array)
|
22
|
+
to
|
23
23
|
else
|
24
|
-
|
24
|
+
to.to_s.split("|")
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
def operator=(
|
29
|
-
if
|
30
|
-
@operator = 'not_in'
|
31
|
-
end
|
28
|
+
def operator=(to)
|
29
|
+
@operator = 'not_in' if to == '!'
|
32
30
|
end
|
33
31
|
|
34
32
|
def apply(scope)
|
@@ -37,16 +35,20 @@ module Symphonia
|
|
37
35
|
scope.where(t[name].send(operator, value))
|
38
36
|
end
|
39
37
|
|
40
|
-
def form_field(
|
38
|
+
def form_field(context)
|
41
39
|
selected = Array(@query.active_filters[name])
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
context.content_tag(:div, class: 'input-group') do
|
41
|
+
context.content_tag(:div, class: 'input-group-prepend') do
|
42
|
+
context.content_tag(:span,
|
43
|
+
context.check_box_tag("o[#{form_field_name}]", '!', operator == 'not_in', title: 'Not In'), class: "input-group-text")
|
45
44
|
end +
|
46
|
-
|
47
|
-
|
45
|
+
context.select_tag("#{form_field_name}[]", context.options_for_select(available_values, selected),
|
46
|
+
class: 'form-control', include_blank: true, multiple: selected.size > 1) +
|
47
|
+
context.content_tag(:div,
|
48
|
+
context.link_to(context.fa_icon('plus-square-o'), 'javascript:void(0)', onclick: "toggleMultiSelect($(this).closest('.input-group').find('select'))", title: I18n.t(:title_toggle_multiselect), class: "input-group-text"), class: 'input-group-append')
|
48
49
|
end
|
49
50
|
end
|
51
|
+
|
50
52
|
end
|
51
53
|
end
|
52
|
-
end
|
54
|
+
end
|
@@ -8,11 +8,10 @@ module Symphonia
|
|
8
8
|
scope.where(t[name].lower.send(operator, value&.downcase))
|
9
9
|
end
|
10
10
|
|
11
|
-
def form_field(
|
12
|
-
|
11
|
+
def form_field(context)
|
12
|
+
context.text_field_tag(form_field_name, @query.active_filters[name], class: 'form-control')
|
13
13
|
end
|
14
|
-
end
|
15
14
|
|
15
|
+
end
|
16
16
|
end
|
17
|
-
|
18
|
-
end
|
17
|
+
end
|
data/lib/symphonia/query.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Symphonia
|
2
2
|
class SymphoniaQueryNotRegistered < StandardError
|
3
3
|
end
|
4
|
+
|
4
5
|
class FilterNotFound < StandardError
|
5
6
|
end
|
6
7
|
|
@@ -108,10 +109,8 @@ module Symphonia
|
|
108
109
|
@columns ||= column_names.map { |c| available_columns[c] }.compact
|
109
110
|
end
|
110
111
|
|
111
|
-
def render_filters
|
112
|
-
(available_filters | filters).each
|
113
|
-
yield filter
|
114
|
-
end
|
112
|
+
def render_filters(&block)
|
113
|
+
(available_filters | filters).each(&block)
|
115
114
|
end
|
116
115
|
|
117
116
|
def entity_scope
|
@@ -161,11 +160,16 @@ module Symphonia
|
|
161
160
|
'symphonia/common/query'
|
162
161
|
end
|
163
162
|
|
164
|
-
|
163
|
+
# Serialize query to params
|
164
|
+
# @param [FalseClass] force use applied filters, even that wasn't before
|
165
|
+
# @return [Hash]
|
166
|
+
def to_params(force: false)
|
165
167
|
if @q
|
166
168
|
{ q: @q }
|
167
169
|
elsif @set_filter || force
|
168
|
-
filters.
|
170
|
+
filters.inject(set_filter: 1) do |(f, v), mem|
|
171
|
+
mem[f.send(:form_field_name).to_sym] = v
|
172
|
+
end
|
169
173
|
else
|
170
174
|
{}
|
171
175
|
end
|
@@ -175,7 +179,6 @@ module Symphonia
|
|
175
179
|
"#<#{self.class.name} set_filter=#{@set_filter} >"
|
176
180
|
end
|
177
181
|
|
178
|
-
|
179
182
|
def available_filters
|
180
183
|
self.active_filters ||= {}
|
181
184
|
self.operators ||= {}
|
@@ -230,33 +233,6 @@ module Symphonia
|
|
230
233
|
@default_column_names
|
231
234
|
end
|
232
235
|
|
233
|
-
def add_column(_type, name, options = {})
|
234
|
-
@available_columns[name] = "Symphonia::QueryColumns::#{_type.to_s.classify}Column".constantize.new(name, self, options)
|
235
|
-
end
|
236
|
-
|
237
|
-
# aliases
|
238
|
-
|
239
|
-
def add_generic_column(name, options = {})
|
240
|
-
add_column(:generic, name, options)
|
241
|
-
end
|
242
|
-
|
243
|
-
def add_text_column(name, options = {})
|
244
|
-
add_column(:text, name, options)
|
245
|
-
end
|
246
|
-
|
247
|
-
def add_price_column(name, options = {})
|
248
|
-
add_column(:price, name, options)
|
249
|
-
end
|
250
|
-
|
251
|
-
def add_date_column(name, options = {})
|
252
|
-
add_column(:date, name, options)
|
253
|
-
end
|
254
|
-
|
255
|
-
def add_boolean_column(name, options = {})
|
256
|
-
add_column(:boolean, name, options)
|
257
|
-
end
|
258
|
-
|
259
|
-
#
|
260
236
|
def add_attribute_column(attribute, options = {})
|
261
237
|
@available_columns[attribute.name] = ::Symphonia::QueryColumns::AttributeColumn.new(attribute, self, options)
|
262
238
|
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
module Symphonia
|
2
2
|
module QueryColumns
|
3
|
-
class AttributeColumn
|
3
|
+
class AttributeColumn
|
4
4
|
|
5
|
-
attr_reader :attribute
|
5
|
+
attr_reader :attribute, :name, :query, :model, :includes, :preload, :joins
|
6
6
|
attr_accessor :no_header, :sort_options
|
7
|
-
attr_writer :header, :sort
|
7
|
+
attr_writer :header, :sort, :sort_column_name, :sort_definition
|
8
8
|
|
9
9
|
delegate :default?, :title, to: :attribute
|
10
10
|
|
11
|
-
def initialize(attribute, query, options={})
|
11
|
+
def initialize(attribute, query, options = {})
|
12
12
|
@attribute = attribute
|
13
13
|
@name = attribute.name
|
14
14
|
@query = query
|
@@ -38,6 +38,60 @@ module Symphonia
|
|
38
38
|
@attribute.format(view, entity)
|
39
39
|
end
|
40
40
|
|
41
|
+
def summarize?
|
42
|
+
false
|
43
|
+
end
|
44
|
+
|
45
|
+
def header?
|
46
|
+
!(@header == false)
|
47
|
+
end
|
48
|
+
|
49
|
+
def sort?
|
50
|
+
!(@sort == false)
|
51
|
+
end
|
52
|
+
|
53
|
+
def sort_definition
|
54
|
+
return nil unless sort?
|
55
|
+
|
56
|
+
@sort_definition ||= SortableTable::SortColumnCustomDefinition.new(@name, { asc: "#{sort_column_name} asc", desc: "#{sort_column_name} desc" })
|
57
|
+
end
|
58
|
+
|
59
|
+
def value(entity)
|
60
|
+
entity.send(name)
|
61
|
+
end
|
62
|
+
|
63
|
+
def sum_value(view)
|
64
|
+
format_value(view, OpenStruct.new(name => sum))
|
65
|
+
end
|
66
|
+
|
67
|
+
def sum
|
68
|
+
return nil unless summarize?
|
69
|
+
|
70
|
+
@sum ||= query.entities.sum(name)
|
71
|
+
end
|
72
|
+
|
73
|
+
def css_classes
|
74
|
+
@name.to_s
|
75
|
+
end
|
76
|
+
|
77
|
+
def inspect
|
78
|
+
"#<#{self.class.name} name='#{name}' options=#{@options.inspect}>"
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def t(*args)
|
84
|
+
I18n.translate(*args)
|
85
|
+
end
|
86
|
+
|
87
|
+
def l(*args)
|
88
|
+
I18n.localize(*args)
|
89
|
+
end
|
90
|
+
|
91
|
+
def sort_column_name
|
92
|
+
@sort_column_name.presence || [@model.table_name, @name].join('.')
|
93
|
+
end
|
94
|
+
|
41
95
|
end
|
42
96
|
end
|
43
|
-
end
|
97
|
+
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
if Rails.env.test?
|
2
|
+
require File.expand_path('../../../spec/spec_helper', __FILE__)
|
3
|
+
Dir.glob(File.expand_path('../../../spec/{factories,support}/*.rb', __FILE__)).each do |file|
|
4
|
+
require file
|
5
|
+
end
|
4
6
|
end
|
data/lib/symphonia/version.rb
CHANGED
@@ -1,99 +1,96 @@
|
|
1
|
-
|
2
|
-
RSpec.describe AccountsController do
|
1
|
+
RSpec.describe Symphonia::AccountsController do
|
3
2
|
|
4
|
-
|
3
|
+
include ActiveJob::TestHelper
|
5
4
|
|
6
|
-
|
5
|
+
routes { Symphonia::Engine.routes }
|
7
6
|
|
8
|
-
|
7
|
+
let(:regular_user) { FactoryBot.create(:user) }
|
9
8
|
|
10
|
-
|
11
|
-
|
9
|
+
context 'logged', logged: true do
|
10
|
+
context '#update' do
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
it 'invalid' do
|
19
|
-
put :update, params: { user: { login: '' } }
|
20
|
-
expect(response).to have_http_status :success
|
21
|
-
end
|
12
|
+
it 'valid' do
|
13
|
+
put :update, params: { user: { login: Faker::Internet.user_name } }
|
14
|
+
expect(response).to redirect_to account_path
|
15
|
+
end
|
22
16
|
|
17
|
+
it 'invalid' do
|
18
|
+
put :update, params: { user: { login: '' } }
|
19
|
+
expect(response).to have_http_status :success
|
23
20
|
end
|
24
21
|
|
25
22
|
end
|
23
|
+
end
|
26
24
|
|
27
|
-
|
25
|
+
context '#resend_activation' do
|
28
26
|
|
29
|
-
|
30
|
-
|
27
|
+
let(:email) { Faker::Internet.email }
|
28
|
+
subject { get :resend_activation, params: { email: email } }
|
31
29
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
it 'non exist user' do
|
31
|
+
is_expected.to redirect_to :root
|
32
|
+
expect(flash[:error]).not_to be :blank
|
33
|
+
end
|
36
34
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
35
|
+
it 'active user' do
|
36
|
+
_user = FactoryBot.create(:user, email: email, status: 'active')
|
37
|
+
is_expected.to redirect_to :root
|
38
|
+
expect(flash[:error]).not_to be :blank
|
39
|
+
end
|
42
40
|
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
it 'pending user' do
|
42
|
+
user = FactoryBot.create(:user, email: email, status: 'pending')
|
43
|
+
token = user.perishable_token.dup
|
46
44
|
|
47
|
-
|
48
|
-
|
45
|
+
expect { get :resend_activation, params: { email: email } }.to have_enqueued_job.on_queue('mailers')
|
46
|
+
expect(response).to have_http_status :redirect
|
49
47
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
48
|
+
expect(user.reload.perishable_token).not_to eq token
|
49
|
+
expect(flash[:error]).to be_nil
|
50
|
+
expect(flash[:notice]).not_to be :blank
|
54
51
|
end
|
52
|
+
end
|
55
53
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
it 'valid token' do
|
61
|
-
user = FactoryBot.create(:user, status: 'pending')
|
62
|
-
user.update_columns(perishable_token: token)
|
63
|
-
is_expected.to redirect_to :login
|
64
|
-
expect(user.reload.status).to eq 'active'
|
65
|
-
end
|
54
|
+
context '#activation' do
|
55
|
+
let(:token) { SecureRandom.hex(3) }
|
56
|
+
subject { get :activation, params: { activation_code: token } }
|
66
57
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
58
|
+
it 'valid token' do
|
59
|
+
user = FactoryBot.create(:user, status: 'pending')
|
60
|
+
user.update_columns(perishable_token: token)
|
61
|
+
is_expected.to redirect_to :login
|
62
|
+
expect(user.reload.status).to eq 'active'
|
71
63
|
end
|
72
64
|
|
73
|
-
|
65
|
+
it 'invalid token' do
|
66
|
+
is_expected.to redirect_to :root
|
67
|
+
expect(flash[:error]).not_to be :blank
|
68
|
+
end
|
69
|
+
end
|
74
70
|
|
75
|
-
|
76
|
-
user = FactoryBot.create(:user, status: 'active')
|
71
|
+
context '#lost_password' do
|
77
72
|
|
78
|
-
|
79
|
-
|
80
|
-
end
|
73
|
+
it 'with mail' do
|
74
|
+
user = FactoryBot.create(:user, status: 'active')
|
81
75
|
|
82
|
-
|
83
|
-
|
84
|
-
expect { post :lost_password, params: { email: user.email } }.not_to have_enqueued_job.on_queue('mailers')
|
85
|
-
expect(flash[:error]).not_to be :blank
|
86
|
-
end
|
76
|
+
expect { post :lost_password, params: { email: user.email } }.to have_enqueued_job.on_queue('mailers')
|
77
|
+
expect(flash[:error]).to be_nil
|
87
78
|
end
|
88
79
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
expect(response).to redirect_to /login/
|
94
|
-
expect { subject.reload }.to change(subject, :crypted_password)
|
95
|
-
end
|
80
|
+
it 'with inactive user' do
|
81
|
+
user = FactoryBot.create(:user, status: 'pending')
|
82
|
+
expect { post :lost_password, params: { email: user.email } }.not_to have_enqueued_job.on_queue('mailers')
|
83
|
+
expect(flash[:error]).not_to be :blank
|
96
84
|
end
|
85
|
+
end
|
97
86
|
|
87
|
+
context "#reset_password" do
|
88
|
+
subject { FactoryBot.create :user }
|
89
|
+
it "reset" do
|
90
|
+
put :reset_password, params: { id: subject.perishable_token, password: "secret-pass-1" }
|
91
|
+
expect(response).to redirect_to /login/
|
92
|
+
expect { subject.reload }.to change(subject, :crypted_password)
|
93
|
+
end
|
98
94
|
end
|
95
|
+
|
99
96
|
end
|