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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8acd94fdad2d0427eaea410e20f8df3acccec4ddb55d6932c8ac558a4f320cb
|
4
|
+
data.tar.gz: e6d14dc726a688d44bc575c512678522890c90b2cb848167f7dc2a2a661de034
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03a0f36614dfde9a168825250d41a94c8c7a5912b83d2ee347fa0ed9fdaf10da1d08b28b0ff8497dccf4ef0999d76eadbfb8bd320fde1e4a6636a307297a8df7
|
7
|
+
data.tar.gz: '039559d4fd376ce6741a9fa8ea71a7276daba6df5050dcf3950f24e78cc2bb8c5944cb425e45dbc6ce4a7b6f32b5e69a0c27bd74f5dcf664271476f1da3b8771'
|
data/.gemignore
ADDED
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
inherit_from: .rubocop_todo.yml
|
2
|
-
require:
|
2
|
+
require:
|
3
|
+
- rubocop-performance
|
4
|
+
- rubocop-rails
|
3
5
|
|
4
6
|
AllCops:
|
5
7
|
TargetRubyVersion: 2.4.2
|
@@ -46,3 +48,34 @@ Style/SymbolArray:
|
|
46
48
|
Security/MarshalLoad:
|
47
49
|
Exclude:
|
48
50
|
- 'lib/marty/cache_adapters/redis.rb'
|
51
|
+
|
52
|
+
Rails/TimeZone:
|
53
|
+
EnforcedStyle: strict
|
54
|
+
|
55
|
+
Rails/OutputSafety:
|
56
|
+
Exclude:
|
57
|
+
- 'app/components/marty/main_auth_app.rb'
|
58
|
+
|
59
|
+
Rails/HelperInstanceVariable:
|
60
|
+
Exclude:
|
61
|
+
- 'app/helpers/marty/script_set.rb' # It's a class, not a helper
|
62
|
+
|
63
|
+
Rails/SkipsModelValidations:
|
64
|
+
Exclude:
|
65
|
+
- 'app/models/marty/promise.rb'
|
66
|
+
|
67
|
+
Rails/DynamicFindBy:
|
68
|
+
Exclude:
|
69
|
+
- 'app/models/marty/data_grid.rb' # Enum
|
70
|
+
- 'app/models/marty/enum.rb' # Enum
|
71
|
+
- 'spec/features/**/*'
|
72
|
+
- 'spec/support/**/*'
|
73
|
+
|
74
|
+
Rails/ApplicationRecord:
|
75
|
+
Enabled: false
|
76
|
+
|
77
|
+
Rails/ApplicationJob:
|
78
|
+
Enabled: false
|
79
|
+
|
80
|
+
Rails/ApplicationController:
|
81
|
+
Enabled: false
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -26,3 +26,13 @@ load 'rails/tasks/engine.rake'
|
|
26
26
|
Bundler::GemHelper.install_tasks
|
27
27
|
|
28
28
|
task default: 'app:spec'
|
29
|
+
|
30
|
+
namespace :marty do
|
31
|
+
desc 'Merge the results of various SimpleCov coverage reports'
|
32
|
+
task merge_coverage_reports: :environment do
|
33
|
+
require_relative 'spec/support/simplecov_helper'
|
34
|
+
SimpleCovHelper.configure_profile
|
35
|
+
puts 'Merging code coverage reports...'
|
36
|
+
SimpleCovHelper.merge_all_results!
|
37
|
+
end
|
38
|
+
end
|
@@ -4,13 +4,25 @@
|
|
4
4
|
(function() {
|
5
5
|
this.RailsApp || (this.RailsApp = {});
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
this.RailsApp.startActionCable = () => {
|
8
|
+
// Already started
|
9
|
+
if (RailsApp.cable) {
|
10
|
+
return false;
|
11
|
+
}
|
12
|
+
|
13
|
+
const protocol =
|
14
|
+
window.location.protocol.slice(0, 5) === "https" ? "wss" : "ws";
|
15
|
+
|
16
|
+
if (window.location.port === "") {
|
17
|
+
RailsApp.cable = ActionCable.createConsumer(
|
18
|
+
`${protocol}://${window.location.hostname}/cable`
|
19
|
+
);
|
20
|
+
} else {
|
21
|
+
RailsApp.cable = ActionCable.createConsumer(
|
22
|
+
`${protocol}://${window.location.hostname}:${window.location.port}/cable`
|
23
|
+
);
|
24
|
+
}
|
25
|
+
|
26
|
+
return true;
|
27
|
+
};
|
16
28
|
}.call(this));
|
@@ -1,7 +1,10 @@
|
|
1
1
|
module Marty
|
2
2
|
class NotificationChannel < ::ApplicationCable::Channel
|
3
3
|
def subscribed
|
4
|
-
reject && return unless
|
4
|
+
reject && return unless
|
5
|
+
Rails.application.config.marty.enable_action_cable
|
6
|
+
|
7
|
+
reject && return if current_user.blank?
|
5
8
|
stream_from "marty_notifications_#{current_user.id}"
|
6
9
|
end
|
7
10
|
end
|
@@ -103,7 +103,7 @@ class Marty::ApiLogView < Marty::Grid
|
|
103
103
|
c.field_config = {
|
104
104
|
xtype: :displayfield,
|
105
105
|
}
|
106
|
-
c.getter = lambda { |r| Time.at(r.timestamp) }
|
106
|
+
c.getter = lambda { |r| Time.zone.at(r.timestamp) }
|
107
107
|
c.sorting_scope = lambda { |r, dir| r.order('timestamp ' + dir.to_s) }
|
108
108
|
|
109
109
|
# FIXME?: The UI AR/PG DateTime workaround requires the timestamp to be cast
|
@@ -5,6 +5,13 @@
|
|
5
5
|
require 'marty/notifications/window'
|
6
6
|
|
7
7
|
class Marty::AuthApp < Marty::SimpleApp
|
8
|
+
def configure(c)
|
9
|
+
super
|
10
|
+
|
11
|
+
enable_action_cable = Rails.application.config.marty.enable_action_cable
|
12
|
+
client_config[:marty_enable_action_cable] = enable_action_cable
|
13
|
+
end
|
14
|
+
|
8
15
|
client_class do |c|
|
9
16
|
c.include :auth_app
|
10
17
|
end
|
@@ -44,7 +51,7 @@ class Marty::AuthApp < Marty::SimpleApp
|
|
44
51
|
def unread_notifications_count
|
45
52
|
user = Mcfly.whodunnit
|
46
53
|
|
47
|
-
return 0
|
54
|
+
return 0 if user.blank?
|
48
55
|
|
49
56
|
user.unread_web_notifications_count
|
50
57
|
end
|
@@ -118,7 +118,13 @@
|
|
118
118
|
},
|
119
119
|
|
120
120
|
netzkeInitComponentCallback() {
|
121
|
+
if (!this.config.clientConfig.marty_enable_action_cable) {
|
122
|
+
return;
|
123
|
+
}
|
124
|
+
|
121
125
|
try {
|
126
|
+
RailsApp.startActionCable();
|
127
|
+
|
122
128
|
const subscription = RailsApp.cable.subscriptions.subscriptions.find(
|
123
129
|
(sub) => sub.identifier === '{"channel":"Marty::NotificationChannel"}'
|
124
130
|
);
|
@@ -116,9 +116,9 @@ module Marty; class DataGridView < McflyGridPanel
|
|
116
116
|
Marty::RoleType.from_nice_names(plist)
|
117
117
|
end
|
118
118
|
dg.permissions = {
|
119
|
-
view: view.
|
120
|
-
edit_data: edit_data.
|
121
|
-
edit_all: edit_all.
|
119
|
+
view: view.presence || [],
|
120
|
+
edit_data: edit_data.presence || [],
|
121
|
+
edit_all: edit_all.presence || [],
|
122
122
|
}
|
123
123
|
dg.save!
|
124
124
|
end
|
@@ -142,7 +142,7 @@ module Marty; class DataGridView < McflyGridPanel
|
|
142
142
|
endpoint :edit_window__edit_form__submit do |params|
|
143
143
|
data = ActiveSupport::JSON.decode(params[:data])
|
144
144
|
|
145
|
-
dg = DataGrid.
|
145
|
+
dg = DataGrid.find_by(id: data['id'])
|
146
146
|
|
147
147
|
begin
|
148
148
|
dg.update_from_import(data['name'], data['export'])
|
@@ -169,7 +169,7 @@ module Marty; class DataGridView < McflyGridPanel
|
|
169
169
|
endpoint :show_grid do |params|
|
170
170
|
record_id = params[:record_id]
|
171
171
|
|
172
|
-
dg = DataGrid.
|
172
|
+
dg = DataGrid.find_by(id: record_id)
|
173
173
|
|
174
174
|
return client.netzke_notify('No data grid.') unless dg
|
175
175
|
|
@@ -193,7 +193,7 @@ module Marty; class DataGridView < McflyGridPanel
|
|
193
193
|
endpoint :edit_grid do |params|
|
194
194
|
record_id = params[:record_id]
|
195
195
|
|
196
|
-
dg = DataGrid.
|
196
|
+
dg = DataGrid.find_by(id: record_id)
|
197
197
|
|
198
198
|
return client.netzke_notify('No data grid.') unless dg
|
199
199
|
|
@@ -13,7 +13,7 @@ module Marty::Extras::Misc
|
|
13
13
|
renderer: "function(v){return ('0' + v).slice (-2);}",
|
14
14
|
# FIXME: a little bogus since this is computed statically. lambda
|
15
15
|
# didn't work.
|
16
|
-
default_value:
|
16
|
+
default_value: Time.zone.today.month
|
17
17
|
}
|
18
18
|
def self.numberfield_cfg(decimal_places)
|
19
19
|
{
|
@@ -63,7 +63,7 @@ class Marty::LogView < Marty::Grid
|
|
63
63
|
c.field_config = {
|
64
64
|
xtype: :displayfield,
|
65
65
|
}
|
66
|
-
c.getter = lambda { |r| Time.at(r.timestamp) }
|
66
|
+
c.getter = lambda { |r| Time.zone.at(r.timestamp) }
|
67
67
|
c.sorting_scope = lambda { |r, dir| r.order('timestamp ' + dir.to_s) }
|
68
68
|
|
69
69
|
# FIXME?: The UI AR/PG DateTime workaround requires the timestamp to be cast
|
@@ -42,7 +42,7 @@ class Marty::PostingGrid < Marty::Grid
|
|
42
42
|
# Prepare an HTML popup with session details such that the
|
43
43
|
# contents can be easily pasted into a spreadsheet.
|
44
44
|
|
45
|
-
pt = Marty::Posting.
|
45
|
+
pt = Marty::Posting.find_by(id: record_id)
|
46
46
|
|
47
47
|
dt = pt.created_dt.to_s == 'Infinity' ? '---' :
|
48
48
|
pt.created_dt.strftime('%Y-%m-%d %I:%M %p')
|
@@ -61,7 +61,7 @@ class Marty::ScriptForm < Marty::Form
|
|
61
61
|
data[k] = nil if v.blank? || v == 'null'
|
62
62
|
end
|
63
63
|
|
64
|
-
@record = script = Marty::Script.
|
64
|
+
@record = script = Marty::Script.find_by(id: data['id'])
|
65
65
|
|
66
66
|
unless script
|
67
67
|
client.netzke_notify 'no record'
|
@@ -81,7 +81,7 @@ class Marty::ScriptForm < Marty::Form
|
|
81
81
|
end
|
82
82
|
|
83
83
|
begin
|
84
|
-
dev = Marty::Tag.
|
84
|
+
dev = Marty::Tag.find_by(name: 'DEV')
|
85
85
|
Marty::ScriptSet.new(dev).parse_check(script.name, data['body'])
|
86
86
|
rescue Delorean::ParseError => e
|
87
87
|
client.netzke_notify e.message
|
@@ -106,7 +106,7 @@ class Marty::ScriptForm < Marty::Form
|
|
106
106
|
return client.netzke_notify('Permission Denied') unless
|
107
107
|
self.class.has_any_perm?
|
108
108
|
|
109
|
-
script = Marty::Script.
|
109
|
+
script = Marty::Script.find_by(id: script_id)
|
110
110
|
|
111
111
|
return client.netzke_notify('bad script') unless script
|
112
112
|
|
@@ -24,7 +24,7 @@ class Marty::ApplicationController < ActionController::Base
|
|
24
24
|
reset_session
|
25
25
|
reset_signed_cookies
|
26
26
|
else
|
27
|
-
session[:atime] = Time.now.utc.to_i
|
27
|
+
session[:atime] = Time.zone.now.utc.to_i
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -35,13 +35,13 @@ class Marty::ApplicationController < ActionController::Base
|
|
35
35
|
|
36
36
|
if session_lifetime
|
37
37
|
return true unless session[:ctime] &&
|
38
|
-
(Time.now.utc.to_i -
|
38
|
+
(Time.zone.now.utc.to_i -
|
39
39
|
session[:ctime].to_i <= session_lifetime.to_i * 60)
|
40
40
|
end
|
41
41
|
|
42
42
|
if session_timeout
|
43
43
|
return true unless session[:atime] &&
|
44
|
-
(Time.now.utc.to_i - session[:atime].to_i <= session_timeout.to_i * 60)
|
44
|
+
(Time.zone.now.utc.to_i - session[:atime].to_i <= session_timeout.to_i * 60)
|
45
45
|
end
|
46
46
|
|
47
47
|
false
|
@@ -49,8 +49,8 @@ class Marty::ApplicationController < ActionController::Base
|
|
49
49
|
|
50
50
|
def start_user_session(user)
|
51
51
|
session[:user_id] = user.id
|
52
|
-
session[:ctime] = Time.now.utc.to_i
|
53
|
-
session[:atime] = Time.now.utc.to_i
|
52
|
+
session[:ctime] = Time.zone.now.utc.to_i
|
53
|
+
session[:atime] = Time.zone.now.utc.to_i
|
54
54
|
|
55
55
|
set_signed_cookies
|
56
56
|
end
|
@@ -119,12 +119,12 @@ class Marty::ApplicationController < ActionController::Base
|
|
119
119
|
|
120
120
|
def failed_authentication(login)
|
121
121
|
logger.info("Failed authentication for '#{login}' " +
|
122
|
-
"from #{request.remote_ip} at #{Time.now.utc}")
|
122
|
+
"from #{request.remote_ip} at #{Time.zone.now.utc}")
|
123
123
|
end
|
124
124
|
|
125
125
|
def successful_authentication(user)
|
126
126
|
logger.info("Successful authentication for '#{user.login}' " +
|
127
|
-
"from #{request.remote_ip} at #{Time.now.utc}")
|
127
|
+
"from #{request.remote_ip} at #{Time.zone.now.utc}")
|
128
128
|
set_user(user)
|
129
129
|
end
|
130
130
|
|
@@ -1,4 +1,6 @@
|
|
1
|
-
class Marty::DelayedJobController <
|
1
|
+
class Marty::DelayedJobController < ApplicationController
|
2
|
+
# FIXME: We probably don't need this endpoint anymore.
|
3
|
+
# It's not used by lambda
|
2
4
|
def trigger
|
3
5
|
work_off_job if delayed_job.present?
|
4
6
|
render json: { status: :ok }, status: :ok
|
@@ -7,7 +9,7 @@ class Marty::DelayedJobController < ActionController::Base
|
|
7
9
|
private
|
8
10
|
|
9
11
|
def delayed_job
|
10
|
-
return
|
12
|
+
return if params['id'].blank?
|
11
13
|
|
12
14
|
@delayed_job ||= ::Delayed::Job.find_by(id: params['id'])
|
13
15
|
end
|
@@ -15,8 +17,9 @@ class Marty::DelayedJobController < ActionController::Base
|
|
15
17
|
def work_off_job
|
16
18
|
return if delayed_job.locked_at.present?
|
17
19
|
|
18
|
-
::Delayed::Job.
|
19
|
-
|
20
|
+
::Delayed::Job.find_by(id: delayed_job.id)&.update!(
|
21
|
+
locked_at: ::Delayed::Job.db_time_now, locked_by: 'Lambda'
|
22
|
+
)
|
20
23
|
|
21
24
|
w = ::Delayed::Worker.new
|
22
25
|
w.run(delayed_job)
|
@@ -8,7 +8,7 @@ module Marty::Diagnostic; class Controller < ActionController::Base
|
|
8
8
|
def op
|
9
9
|
@result = Reporter.run(request)
|
10
10
|
rescue NameError
|
11
|
-
render file: 'public/400', formats: [:html], status:
|
11
|
+
render file: 'public/400', formats: [:html], status: :bad_request, layout: false
|
12
12
|
else
|
13
13
|
respond_to do |format|
|
14
14
|
format.html { @result = display_parameters }
|
@@ -1,8 +1,8 @@
|
|
1
|
-
class Marty::JobController <
|
1
|
+
class Marty::JobController < ApplicationController
|
2
2
|
def download
|
3
3
|
job_id = params['job_id']
|
4
4
|
|
5
|
-
promise = Marty::Promise.
|
5
|
+
promise = Marty::Promise.find_by(id: job_id)
|
6
6
|
|
7
7
|
if promise
|
8
8
|
format = promise.cformat
|
@@ -3,7 +3,7 @@ class Marty::ApiAuth < Marty::Base
|
|
3
3
|
|
4
4
|
KEY_SIZE = 19
|
5
5
|
|
6
|
-
|
6
|
+
validates :app_name, :api_key, :script_name, presence: true
|
7
7
|
|
8
8
|
class ApiAuthValidator < ActiveModel::Validator
|
9
9
|
def validate(api)
|
@@ -18,8 +18,8 @@ class Marty::ApiAuth < Marty::Base
|
|
18
18
|
validates_with ApiAuthValidator
|
19
19
|
|
20
20
|
mcfly_validates_uniqueness_of :api_key, scope: [:script_name]
|
21
|
-
|
22
|
-
:obsoleted_dt]
|
21
|
+
validates :app_name, uniqueness: { scope: [:script_name,
|
22
|
+
:obsoleted_dt] }
|
23
23
|
|
24
24
|
before_validation do
|
25
25
|
self.api_key = Marty::ApiAuth.generate_key if
|