marty 9.3.0 → 9.3.2
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 +4 -4
- data/.gemignore +2 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +34 -1
- data/Gemfile +1 -0
- data/Rakefile +10 -0
- data/app/assets/javascripts/marty/cable.js +21 -9
- data/app/channels/application_cable/connection.rb +1 -1
- data/app/channels/marty/notification_channel.rb +4 -1
- data/app/components/marty/api_config_view.rb +1 -1
- data/app/components/marty/api_log_view.rb +1 -1
- data/app/components/marty/auth_app.rb +8 -1
- data/app/components/marty/auth_app/client/auth_app.js +6 -0
- data/app/components/marty/data_grid_view.rb +6 -6
- data/app/components/marty/extras/misc.rb +1 -1
- data/app/components/marty/log_view.rb +1 -1
- data/app/components/marty/posting_grid.rb +1 -1
- data/app/components/marty/script_form.rb +3 -3
- data/app/components/marty/user_view.rb +1 -1
- data/app/components/marty/users/user_view.rb +1 -1
- data/app/controllers/marty/application_controller.rb +7 -7
- data/app/controllers/marty/delayed_job_controller.rb +7 -4
- data/app/controllers/marty/diagnostic/controller.rb +1 -1
- data/app/controllers/marty/job_controller.rb +2 -2
- data/app/models/marty/api_auth.rb +3 -3
- data/app/models/marty/api_config.rb +1 -1
- data/app/models/marty/base_rule.rb +1 -1
- data/app/models/marty/config.rb +5 -5
- data/app/models/marty/data_grid.rb +3 -3
- data/app/models/marty/delorean_rule.rb +2 -2
- data/app/models/marty/grid_index_boolean.rb +2 -2
- data/app/models/marty/grid_index_int4range.rb +1 -1
- data/app/models/marty/grid_index_integer.rb +1 -1
- data/app/models/marty/grid_index_numrange.rb +1 -1
- data/app/models/marty/grid_index_string.rb +1 -1
- data/app/models/marty/import_type.rb +2 -2
- data/app/models/marty/notifications/notification.rb +2 -1
- data/app/models/marty/posting.rb +6 -6
- data/app/models/marty/posting_type.rb +2 -2
- data/app/models/marty/promise.rb +4 -3
- data/app/models/marty/script.rb +7 -7
- data/app/models/marty/tag.rb +5 -5
- data/app/models/marty/token.rb +1 -1
- data/app/models/marty/user.rb +11 -10
- data/app/models/marty/user_role.rb +2 -2
- data/app/models/marty/vw_promise.rb +2 -1
- data/app/services/marty/background_job/update_schedule.rb +1 -1
- data/app/services/marty/data_grid/constraint.rb +4 -3
- data/app/services/marty/jobs/schedule.rb +2 -2
- data/lib/marty/data_change.rb +1 -1
- data/lib/marty/data_conversion.rb +1 -1
- data/lib/marty/migrations.rb +2 -2
- data/lib/marty/rpc_call.rb +2 -1
- data/lib/marty/rule_script_set.rb +1 -3
- data/lib/marty/util.rb +2 -2
- data/lib/marty/version.rb +1 -1
- data/lib/tasks/scripts_tasks.rake +2 -2
- data/marty.gemspec +5 -1
- data/spec/controllers/job_controller_spec.rb +7 -7
- data/spec/controllers/rpc_controller_spec.rb +8 -8
- data/spec/controllers/rpc_import_spec.rb +3 -3
- data/spec/features/data_blame_report_spec.rb +1 -1
- data/spec/features/data_grid_spec.rb +101 -3
- data/spec/features/enum_values_report_spec.rb +1 -1
- data/spec/features/extjs_spec.rb +1 -1
- data/spec/features/jobs_dashboard_spec.rb +2 -2
- data/spec/features/log_view_spec.rb +1 -1
- data/spec/features/reporting_spec.rb +3 -3
- data/spec/features/scripting_spec.rb +3 -3
- data/spec/features/scripting_test_spec.rb +3 -3
- data/spec/features/user_list_report_spec.rb +1 -1
- data/spec/fixtures/misc/data_grid_6.txt +9 -0
- data/spec/fixtures/misc/data_grid_7.txt +7 -0
- data/spec/fixtures/misc/data_grid_8.txt +10 -0
- data/spec/fixtures/misc/data_grid_9.txt +10 -0
- data/spec/lib/data_blame_spec.rb +1 -1
- data/spec/lib/data_importer_spec.rb +4 -4
- data/spec/lib/delorean_query_spec.rb +1 -1
- data/spec/lib/logger_spec.rb +1 -1
- data/spec/lib/mcfly_model_spec.rb +2 -2
- data/spec/lib/table_report_spec.rb +1 -1
- data/spec/models/api_auth_spec.rb +2 -2
- data/spec/models/data_grid_spec.rb +3 -3
- data/spec/models/posting_spec.rb +12 -12
- data/spec/models/promise_spec.rb +1 -1
- data/spec/models/rule_spec.rb +1 -1
- data/spec/models/script_spec.rb +1 -1
- data/spec/other/diagnostic/delayed_job_version_spec.rb +1 -1
- data/spec/spec_helper.rb +3 -0
- data/spec/support/netzke.rb +2 -2
- data/spec/support/setup.rb +1 -1
- data/spec/support/simplecov_helper.rb +94 -0
- data/spec/support/users.rb +2 -2
- metadata +8 -3
- data/.gitlab-ci.yml +0 -117
@@ -69,7 +69,7 @@ class Marty::BaseRule < Marty::Base
|
|
69
69
|
"- Error in rule '#{name}' field 'results': #{res_err.capitalize}" if res_err
|
70
70
|
end
|
71
71
|
|
72
|
-
|
72
|
+
validates :name, presence: true
|
73
73
|
validate :validate
|
74
74
|
validate :validate_simple_guard_options
|
75
75
|
|
data/app/models/marty/config.rb
CHANGED
@@ -7,8 +7,8 @@ class Marty::Config < Marty::Base
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
validates :key, :value, presence: true
|
11
|
+
validates :key, uniqueness: true
|
12
12
|
validates_with ConfigValidator
|
13
13
|
|
14
14
|
delorean_fn :lookup, sig: 1 do |key|
|
@@ -29,7 +29,7 @@ class Marty::Config < Marty::Base
|
|
29
29
|
"(given #{args.size}, expected 1..2)"
|
30
30
|
end
|
31
31
|
|
32
|
-
entry =
|
32
|
+
entry = find_by(key: args[0])
|
33
33
|
return entry.get_value if entry
|
34
34
|
return args[1] if args.size > 1
|
35
35
|
|
@@ -37,7 +37,7 @@ class Marty::Config < Marty::Base
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def self.[]=(key, value)
|
40
|
-
entry =
|
40
|
+
entry = find_by(key: key)
|
41
41
|
if !entry
|
42
42
|
entry = new
|
43
43
|
entry.key = key
|
@@ -53,7 +53,7 @@ class Marty::Config < Marty::Base
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def self.del(key)
|
56
|
-
entry =
|
56
|
+
entry = find_by(key: key)
|
57
57
|
if entry
|
58
58
|
result = entry.get_value
|
59
59
|
entry.destroy
|
@@ -35,7 +35,7 @@ class Marty::DataGrid < Marty::Base
|
|
35
35
|
attr, type, keys, rs_keep =
|
36
36
|
inf['attr'], inf['type'], inf['keys'], inf['rs_keep']
|
37
37
|
|
38
|
-
|
38
|
+
if rs_keep.present?
|
39
39
|
m = /\A *(<|<=|>|>=)? *([a-z][a-z_0-9]+) *\z/.match(rs_keep)
|
40
40
|
unless m
|
41
41
|
dg.errors.add(:base, "invalid grid modifier expression: #{rs_keep}")
|
@@ -81,7 +81,7 @@ class Marty::DataGrid < Marty::Base
|
|
81
81
|
end
|
82
82
|
data_check = Marty::DataGrid::Constraint.check_data(dg.data_type,
|
83
83
|
dg.data, con_chk)
|
84
|
-
return
|
84
|
+
return if data_check.blank?
|
85
85
|
|
86
86
|
data_check.each do |(err, x, y)|
|
87
87
|
dg.errors.add(:base, "cell #{x}, #{y} fails constraint check") if
|
@@ -94,7 +94,7 @@ class Marty::DataGrid < Marty::Base
|
|
94
94
|
|
95
95
|
has_mcfly
|
96
96
|
|
97
|
-
|
97
|
+
validates :name, :data, :metadata, presence: true
|
98
98
|
|
99
99
|
mcfly_validates_uniqueness_of :name
|
100
100
|
validates_with DataGridValidator
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class Marty::DeloreanRule < Marty::BaseRule
|
2
2
|
self.abstract_class = true
|
3
3
|
|
4
|
-
|
4
|
+
validates :rule_type, :start_dt, presence: true
|
5
5
|
|
6
6
|
def validate
|
7
7
|
super
|
@@ -200,7 +200,7 @@ class Marty::DeloreanRule < Marty::BaseRule
|
|
200
200
|
|
201
201
|
def self.get_grid_rename_handler(klass)
|
202
202
|
proc do |old, new|
|
203
|
-
klass.where(obsoleted_dt: 'infinity').
|
203
|
+
klass.where(obsoleted_dt: 'infinity').find_each do |r|
|
204
204
|
r.grids.each { |k, v| r.grids[k] = new if v == old }
|
205
205
|
r.results.each do |k, _v|
|
206
206
|
r.results[k] = %Q("#{new}") if
|
@@ -1,4 +1,4 @@
|
|
1
1
|
class Marty::GridIndexBoolean < Marty::Base
|
2
|
-
|
3
|
-
|
2
|
+
validates :created_dt, :data_grid_id, :attr, :index, presence: true
|
3
|
+
validates :key, inclusion: { in: [true, false, nil] }
|
4
4
|
end
|
@@ -27,8 +27,8 @@ class Marty::ImportType < Marty::Base
|
|
27
27
|
self.preprocess_function = nil if preprocess_function.blank?
|
28
28
|
end
|
29
29
|
|
30
|
-
|
31
|
-
|
30
|
+
validates :name, :db_model_name, :role, presence: true
|
31
|
+
validates :name, uniqueness: true
|
32
32
|
validates_with ImportTypeValidator
|
33
33
|
|
34
34
|
def get_model_class
|
data/app/models/marty/posting.rb
CHANGED
@@ -2,7 +2,7 @@ class Marty::Posting < Marty::Base
|
|
2
2
|
has_mcfly append_only: true
|
3
3
|
|
4
4
|
mcfly_validates_uniqueness_of :name
|
5
|
-
|
5
|
+
validates :name, :posting_type_id, :comment, presence: true
|
6
6
|
|
7
7
|
belongs_to :user, class_name: 'Marty::User'
|
8
8
|
belongs_to :posting_type
|
@@ -16,19 +16,19 @@ class Marty::Posting < Marty::Base
|
|
16
16
|
# use Time.now.strftime to name the posting. This has the effect
|
17
17
|
# of using the host's timezone. i.e. since we're in PST8PDT, names
|
18
18
|
# will be based off of the Pacific TZ.
|
19
|
-
dt ||= Time.now
|
19
|
+
dt ||= Time.zone.now
|
20
20
|
"#{posting_type.name}-#{dt.strftime('%Y%m%d-%H%M')}"
|
21
21
|
end
|
22
22
|
|
23
23
|
before_validation :set_posting_name
|
24
24
|
def set_posting_name
|
25
|
-
posting_type = Marty::PostingType.
|
25
|
+
posting_type = Marty::PostingType.find_by(id: posting_type_id)
|
26
26
|
self.name = self.class.make_name(posting_type, created_dt)
|
27
27
|
true
|
28
28
|
end
|
29
29
|
|
30
30
|
def self.do_create(type_name, dt, comment)
|
31
|
-
posting_type = Marty::PostingType.
|
31
|
+
posting_type = Marty::PostingType.find_by(name: type_name)
|
32
32
|
|
33
33
|
raise "unknown posting type #{name}" unless posting_type
|
34
34
|
|
@@ -50,12 +50,12 @@ class Marty::Posting < Marty::Base
|
|
50
50
|
# might be created. Or, use regular validates_uniqueness_of instead
|
51
51
|
# of mcfly_validates_uniqueness_of.
|
52
52
|
delorean_fn :lookup, sig: 1 do |name|
|
53
|
-
p = select(get_struct_attrs).
|
53
|
+
p = select(get_struct_attrs).find_by(name: name)
|
54
54
|
make_openstruct(p)
|
55
55
|
end
|
56
56
|
|
57
57
|
delorean_fn :lookup_dt, sig: 1 do |name|
|
58
|
-
|
58
|
+
find_by(name: name).try(:created_dt)
|
59
59
|
end
|
60
60
|
|
61
61
|
delorean_fn :first_match, sig: [1, 2] do |dt, posting_type = nil|
|
data/app/models/marty/promise.rb
CHANGED
@@ -13,9 +13,10 @@ class Marty::Promise < Marty::Base
|
|
13
13
|
has_many :children,
|
14
14
|
foreign_key: 'parent_id',
|
15
15
|
class_name: 'Marty::Promise',
|
16
|
-
dependent: :destroy
|
16
|
+
dependent: :destroy,
|
17
|
+
inverse_of: :parent
|
17
18
|
|
18
|
-
|
19
|
+
validates :title, :promise_type, presence: true
|
19
20
|
|
20
21
|
belongs_to :parent, class_name: 'Marty::Promise'
|
21
22
|
belongs_to :user, class_name: 'Marty::User'
|
@@ -94,7 +95,7 @@ class Marty::Promise < Marty::Base
|
|
94
95
|
end
|
95
96
|
|
96
97
|
def self.job_by_id(job_id)
|
97
|
-
Delayed::Job.uncached { Delayed::Job.
|
98
|
+
Delayed::Job.uncached { Delayed::Job.find_by(id: job_id) }
|
98
99
|
end
|
99
100
|
|
100
101
|
def work_off_job(job)
|
data/app/models/marty/script.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
class Marty::Script < Marty::Base
|
2
2
|
has_mcfly
|
3
3
|
|
4
|
-
|
4
|
+
validates :name, :body, presence: true
|
5
5
|
mcfly_validates_uniqueness_of :name
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
validates :name,
|
7
|
+
format: { with: /\A[A-Z][a-zA-Z0-9]*(::[A-Z][a-zA-Z0-9]*)*\z/,
|
8
|
+
message: I18n.t('script.save_error') }
|
9
9
|
|
10
10
|
belongs_to :user, class_name: 'Marty::User'
|
11
11
|
|
@@ -50,7 +50,7 @@ class Marty::Script < Marty::Base
|
|
50
50
|
end
|
51
51
|
|
52
52
|
delorean_fn :pretty_print, sig: 1 do |id|
|
53
|
-
script =
|
53
|
+
script = find_by id: id
|
54
54
|
|
55
55
|
next "unknown script #{id}" unless script
|
56
56
|
|
@@ -96,7 +96,7 @@ class Marty::Script < Marty::Base
|
|
96
96
|
tag = Marty::Tag.get_latest1
|
97
97
|
latest = Marty::Script.order('created_dt DESC').first
|
98
98
|
|
99
|
-
tag_time = (dt || [latest.try(:created_dt), Time.now].compact.max) +
|
99
|
+
tag_time = (dt || [latest.try(:created_dt), Time.zone.now].compact.max) +
|
100
100
|
1.second
|
101
101
|
|
102
102
|
# If no tag_time is provided, the tag created_dt will be the same
|
@@ -149,7 +149,7 @@ class Marty::Script < Marty::Base
|
|
149
149
|
return paths_from_config if paths_from_config.present?
|
150
150
|
|
151
151
|
[
|
152
|
-
|
152
|
+
Rails.root.join('delorean'),
|
153
153
|
# FIXME: HACKY, wouldn't it be better to use
|
154
154
|
# Gem::Specification.find_by_name("marty").gem_dir??
|
155
155
|
File.expand_path('../../../../delorean', __FILE__),
|
data/app/models/marty/tag.rb
CHANGED
@@ -2,7 +2,7 @@ class Marty::Tag < Marty::Base
|
|
2
2
|
has_mcfly append_only: true
|
3
3
|
|
4
4
|
mcfly_validates_uniqueness_of :name
|
5
|
-
|
5
|
+
validates :name, :comment, presence: true
|
6
6
|
|
7
7
|
belongs_to :user, class_name: 'Marty::User'
|
8
8
|
|
@@ -17,7 +17,7 @@ class Marty::Tag < Marty::Base
|
|
17
17
|
# use Time.now.strftime to name the posting. This has the effect
|
18
18
|
# of using the host's timezone. i.e. since we're in PST8PDT, names
|
19
19
|
# will be based off of the Pacific TZ.
|
20
|
-
dt ||= Time.now
|
20
|
+
dt ||= Time.zone.now
|
21
21
|
dt.strftime('%Y%m%d-%H%M')
|
22
22
|
end
|
23
23
|
|
@@ -44,9 +44,9 @@ class Marty::Tag < Marty::Base
|
|
44
44
|
# many different types of arguments.
|
45
45
|
case tag_id
|
46
46
|
when Integer, /\A[0-9]+\z/
|
47
|
-
tag =
|
47
|
+
tag = find_by(id: tag_id)
|
48
48
|
when String
|
49
|
-
tag =
|
49
|
+
tag = find_by(name: tag_id)
|
50
50
|
# if tag name wasn't found, look for a matching
|
51
51
|
# posting, then find the tag whose created_dt <= posting dt.
|
52
52
|
if !tag
|
@@ -65,7 +65,7 @@ class Marty::Tag < Marty::Base
|
|
65
65
|
end
|
66
66
|
|
67
67
|
delorean_fn :lookup, cache: true, sig: 1 do |name|
|
68
|
-
t =
|
68
|
+
t = find_by(name: name).select(get_struct_attrs)
|
69
69
|
t && t.attributes
|
70
70
|
end
|
71
71
|
|
data/app/models/marty/token.rb
CHANGED
data/app/models/marty/user.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
class Marty::User < Marty::Base
|
2
|
-
|
3
|
-
|
2
|
+
validates :login, :firstname, :lastname, presence: true
|
3
|
+
validates :login, uniqueness: true
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
validates :login, format: { with: /\A[a-z0-9_\-@\.]*\z/i }
|
6
|
+
validates :login, :firstname, :lastname, length: { maximum: 100 }
|
7
7
|
|
8
8
|
MARTY_IMPORT_UNIQUENESS = [:login]
|
9
9
|
|
@@ -13,7 +13,8 @@ class Marty::User < Marty::Base
|
|
13
13
|
:notification_deliveries,
|
14
14
|
class_name: '::Marty::Notifications::Delivery',
|
15
15
|
dependent: :destroy,
|
16
|
-
foreign_key: :recipient_id
|
16
|
+
foreign_key: :recipient_id,
|
17
|
+
inverse_of: :recipient
|
17
18
|
)
|
18
19
|
|
19
20
|
scope :active, -> { where(active: true) }
|
@@ -56,7 +57,7 @@ class Marty::User < Marty::Base
|
|
56
57
|
# Make sure no one can sign in with an empty password
|
57
58
|
return nil if password.empty?
|
58
59
|
|
59
|
-
user =
|
60
|
+
user = find_by(login: login)
|
60
61
|
|
61
62
|
return nil if !user || !user.active?
|
62
63
|
|
@@ -93,7 +94,7 @@ class Marty::User < Marty::Base
|
|
93
94
|
raise "bad auth_source: #{auth_source.inspect}"
|
94
95
|
end
|
95
96
|
|
96
|
-
|
97
|
+
find_by(login: login) if ok
|
97
98
|
end
|
98
99
|
|
99
100
|
def self.current=(user)
|
@@ -135,8 +136,8 @@ class Marty::User < Marty::Base
|
|
135
136
|
# 1 - Do not allow user to edit own record
|
136
137
|
# 2 - Do not allow user to edit the application system record
|
137
138
|
if user_manager_only
|
138
|
-
system_user = Marty::User.
|
139
|
-
Rails.configuration.marty.system_account.to_s)
|
139
|
+
system_user = Marty::User.find_by(
|
140
|
+
login: Rails.configuration.marty.system_account.to_s)
|
140
141
|
system_id = system_user.id if system_user
|
141
142
|
|
142
143
|
roles = user_roles.map(&:role)
|
@@ -173,6 +174,6 @@ class Marty::User < Marty::Base
|
|
173
174
|
errors.add :base,
|
174
175
|
"Users cannot be deleted - set 'Active' to false to disable the account"
|
175
176
|
|
176
|
-
throw :abort
|
177
|
+
throw :abort if errors.present?
|
177
178
|
end
|
178
179
|
end
|
@@ -2,7 +2,8 @@ class Marty::VwPromise < Marty::Base
|
|
2
2
|
has_many :children,
|
3
3
|
foreign_key: 'parent_id',
|
4
4
|
class_name: 'Marty::VwPromise',
|
5
|
-
dependent: :destroy
|
5
|
+
dependent: :destroy,
|
6
|
+
inverse_of: :parent
|
6
7
|
|
7
8
|
belongs_to :parent, class_name: 'Marty::VwPromise'
|
8
9
|
belongs_to :user, class_name: 'Marty::User'
|
@@ -4,7 +4,7 @@ module Marty
|
|
4
4
|
def self.call(id:, job_class:)
|
5
5
|
model = Marty::BackgroundJob::Schedule.find_by(id: id)
|
6
6
|
|
7
|
-
return remove_schedule(job_class: job_class)
|
7
|
+
return remove_schedule(job_class: job_class) if model.blank?
|
8
8
|
return remove_schedule(job_class: job_class) if model.off?
|
9
9
|
return schedule(job_class: job_class) if model.on?
|
10
10
|
end
|
@@ -14,7 +14,7 @@ module Marty
|
|
14
14
|
[r[0, 2], r[2..-1].reverse]
|
15
15
|
else
|
16
16
|
raw_vals = constraint.split('|')
|
17
|
-
return
|
17
|
+
return if raw_vals.blank?
|
18
18
|
raise 'list constraint not allowed for type Float' if dt == 'float'
|
19
19
|
|
20
20
|
pt = 'infinity'
|
@@ -37,6 +37,7 @@ module Marty
|
|
37
37
|
[data_type]
|
38
38
|
end
|
39
39
|
types << Integer if types.include?(Float)
|
40
|
+
types
|
40
41
|
end
|
41
42
|
|
42
43
|
# if check_data is called from validation, data has already been converted
|
@@ -55,8 +56,8 @@ module Marty
|
|
55
56
|
err = nil
|
56
57
|
begin
|
57
58
|
cvt_val = cvt && !data_v.class.in?(rt) ?
|
58
|
-
DataGrid.parse_fvalue(pt, data_v, dt, klass)
|
59
|
-
|
59
|
+
[DataGrid.parse_fvalue(pt, data_v, dt, klass)].
|
60
|
+
flatten.first : data_v
|
60
61
|
rescue StandardError => e
|
61
62
|
err = e.message
|
62
63
|
end
|
@@ -4,10 +4,10 @@ module Marty
|
|
4
4
|
extend Delorean::Functions
|
5
5
|
|
6
6
|
delorean_fn :call, sig: 0 do
|
7
|
-
glob = Rails.root.join('app
|
7
|
+
glob = Rails.root.join('app/jobs/**/*_job.rb')
|
8
8
|
Dir.glob(glob).sort.each { |f| require f }
|
9
9
|
|
10
|
-
glob2 = Marty.root.join('app
|
10
|
+
glob2 = Marty.root.join('app/jobs/**/*_job.rb')
|
11
11
|
Dir.glob(glob2).sort.each { |f| require f }
|
12
12
|
|
13
13
|
Delayed::Job.where.not(cron: nil).each(&:destroy!)
|
data/lib/marty/data_change.rb
CHANGED