marty 2.3.15 → 2.4.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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +2 -2
  3. data/app/components/marty/api_auth_view.rb +27 -4
  4. data/app/components/marty/api_config_view.rb +27 -4
  5. data/app/components/marty/extras/layout.rb +4 -7
  6. data/app/components/marty/form.rb +8 -0
  7. data/app/components/marty/grid.rb +45 -19
  8. data/app/components/marty/main_auth_app.rb +12 -11
  9. data/app/controllers/marty/rpc_controller.rb +63 -150
  10. data/app/models/marty/api_auth.rb +86 -14
  11. data/app/models/marty/api_config.rb +11 -6
  12. data/app/models/marty/delorean_rule.rb +3 -2
  13. data/config/routes.rb +1 -1
  14. data/db/migrate/501_add_api_class_to_marty_api_config.rb +6 -0
  15. data/db/migrate/502_add_parameters_to_marty_api_auth.rb +5 -0
  16. data/lib/marty/util.rb +0 -15
  17. data/lib/marty/version.rb +1 -1
  18. data/other/marty/api/base.rb +207 -0
  19. data/other/marty/diagnostic/aws/ec2_instance.rb +12 -87
  20. data/other/marty/diagnostic/environment_variables.rb +1 -1
  21. data/spec/controllers/job_controller_spec.rb +1 -1
  22. data/spec/dummy/app/components/gemini/xyz_rule_view.rb +1 -0
  23. data/spec/dummy/config/application.rb +1 -0
  24. data/spec/features/enum_spec.rb +35 -100
  25. data/spec/features/log_view_spec.rb +5 -5
  26. data/spec/features/rule_spec.rb +30 -30
  27. data/spec/features/user_view_spec.rb +0 -2
  28. data/spec/lib/logger_spec.rb +1 -1
  29. data/spec/models/api_auth_spec.rb +33 -12
  30. data/spec/models/event_spec.rb +1 -1
  31. data/spec/models/promise_spec.rb +1 -1
  32. data/spec/models/user_spec.rb +6 -6
  33. data/spec/spec_helper.rb +69 -9
  34. data/spec/support/{shared_connection_db_helpers.rb → clean_db_helpers.rb} +2 -2
  35. data/spec/support/delayed_job_helpers.rb +1 -1
  36. data/spec/support/{users.rb → integration_helpers.rb} +9 -11
  37. data/spec/support/{setup.rb → spec_setup.rb} +6 -19
  38. data/spec/support/user_helpers.rb +12 -0
  39. metadata +10 -21
  40. data/spec/dummy/app/assets/client/application.css +0 -13
  41. data/spec/dummy/app/assets/client/application.js +0 -15
  42. data/spec/support/chromedriver.rb +0 -41
  43. data/spec/support/components/netzke_combobox.rb +0 -57
  44. data/spec/support/components/netzke_grid.rb +0 -356
  45. data/spec/support/custom_matchers.rb +0 -18
  46. data/spec/support/custom_selectors.rb +0 -49
  47. data/spec/support/download_helper.rb +0 -52
  48. data/spec/support/helper.rb +0 -20
  49. data/spec/support/netzke.rb +0 -306
  50. data/spec/support/performance_helper.rb +0 -26
  51. data/spec/support/post_run_logger.rb +0 -32
  52. data/spec/support/shared_connection.rb +0 -31
  53. data/spec/support/structure_compare.rb +0 -62
  54. data/spec/support/suite.rb +0 -27
@@ -1,356 +0,0 @@
1
- require 'capybara/dsl'
2
- require 'rspec/matchers'
3
- require Pathname.new(__FILE__).parent.parent.to_s + '/netzke'
4
-
5
- module Marty; module RSpec; module Components
6
- class NetzkeGrid
7
- include Netzke
8
- include Capybara::DSL
9
- #include RSpec::Matchers
10
-
11
- attr_reader :name, :grid
12
-
13
- def initialize(name, c_type)
14
- # for now, also allows treepanel
15
- @name = name
16
- if /^\d+$/.match(name)
17
- @grid = ext_find(c_type, nil, name)
18
- else
19
- @grid = ext_find(ext_arg(c_type, name: name))
20
- end
21
- end
22
-
23
- def id
24
- res = run_js <<-JS
25
- var c = #{grid};
26
- return c.view.id;
27
- JS
28
- res
29
- end
30
-
31
- def row_count
32
- res = run_js <<-JS
33
- return #{grid}.getStore().getTotalCount();
34
- JS
35
- res.to_i
36
- end
37
-
38
- def page_size
39
- res = run_js <<-JS
40
- return #{grid}.getStore().pageSize();
41
- JS
42
- res.to_i
43
- end
44
-
45
- alias :row_total :row_count
46
-
47
- def row_modified_count
48
- res = run_js <<-JS
49
- return #{grid}.getStore().getUpdatedRecords().length;
50
- JS
51
- res.to_i
52
- end
53
-
54
- def data_desc row
55
- res = run_js <<-JS
56
- var r = #{grid}.getStore().getAt(#{row.to_i-1});
57
- return r.data.desc
58
- JS
59
- res.gsub(/<.*?>/, '')
60
- end
61
-
62
- def click_col col
63
- el = run_js <<-JS
64
- #{ext_var(grid, 'grid')}
65
- return #{ext_find(ext_arg('gridcolumn', text: col), 'grid')}.id
66
- JS
67
-
68
- find("#" + el).click
69
- end
70
-
71
- def get_col_vals(col, cnt=row_count, init=0)
72
- # NOTE: does not validate the # of rows
73
- run_js <<-JS
74
- var result = [];
75
- for (var i = #{init}; i < #{init.to_i + cnt.to_i}; i++) {
76
- #{ext_cell_val('i', col, grid)}
77
- if(value instanceof Date){
78
- result.push(value.toISOString().substring(0,value.toISOString().indexOf('T')));
79
- } else {
80
- result.push(value);
81
- };
82
- };
83
- return result;
84
- JS
85
- end
86
-
87
- def validate_col_vals(col, val, cnt, init=0)
88
- run_js <<-JS
89
- for (var i = #{init}; i < #{init.to_i + cnt.to_i}; i++) {
90
- #{ext_cell_val('i', col, grid)}
91
- if (value != #{val}) { return false };
92
- };
93
- return true;
94
- JS
95
- end
96
-
97
- def cell_value(row, col)
98
- run_js <<-JS
99
- #{ext_cell_val(row.to_i - 1, col, grid)}
100
- return value;
101
- JS
102
- end
103
-
104
- def select_row(row, click_after=true)
105
- resid = run_js(<<-JS, 10.0)
106
- #{ext_var(grid, 'grid')}
107
- grid.getSelectionModel().select(#{row.to_i-1});
108
- return grid.getView().getNode(#{row.to_i-1}).id;
109
- JS
110
- el = find_by_id(resid)
111
- el.click if click_after
112
- wait_for_ajax
113
- return el
114
- end
115
-
116
- def set_row_vals row, fields
117
- js_set_fields = fields.each_pair.map do |k,v|
118
- "r.set('#{k}', '#{v}');"
119
- end.join
120
-
121
- run_js <<-JS
122
- #{ext_var(ext_row(row.to_i - 1, grid), 'r')}
123
- #{js_set_fields}
124
- JS
125
- end
126
-
127
- def get_row_vals row, fields=nil
128
- res = run_js <<-JS
129
- #{ext_var(grid, 'grid')}
130
- return Ext.encode(#{ext_row(row.to_i - 1, 'grid')}.data);
131
- JS
132
- temp = JSON.parse(res)
133
- parsed = temp.merge(temp.delete('association_values') || {})
134
- fields ? fields.each_with_object({}).each{|k,h| h[k] = parsed[k]} :
135
- parsed
136
- end
137
-
138
- def sorted_by? col, direction = 'asc'
139
- run_js <<-JS
140
- #{ext_var(grid, 'grid')}
141
- #{ext_var(ext_col(col, 'grid'), 'col')}
142
- var colValues = [];
143
-
144
- grid.getStore().each(function(r){
145
- var val = col.assoc ? r.get('association_values')['#{col}'] :
146
- r.get('#{col}');
147
- if (val) colValues.#{direction == 'asc' ? 'push' : 'unshift'}(val);
148
- });
149
-
150
- return colValues.toString() === Ext.Array.sort(colValues).toString();
151
- JS
152
- end
153
-
154
- def grid_combobox_values(row, field)
155
- run_js <<-JS
156
- #{start_edit_combobox(row, field)}
157
- JS
158
-
159
- # hacky: delay for combobox to render, assumes combobox is not empty
160
- run_js <<-JS
161
- #{ext_var(grid, 'grid')}
162
- #{ext_var(ext_netzkecombo(field), 'combo')}
163
- var r = [];
164
- #{ext_var(ext_celleditor, 'editor')}
165
- var store = combo.getStore();
166
-
167
- // force a retry if the store is still loading
168
- if (store.loading == true) {
169
- now = new Date().getTime();
170
- while(new Date().getTime() < now + 100) { }
171
- return false;
172
- }
173
-
174
- for(var i = 0; i < store.getCount(); i++) {
175
- r.push(store.getAt(i).get('text'));
176
- };
177
-
178
- editor.completeEdit();
179
- return r;
180
- JS
181
- end
182
-
183
- def get_combobox_val(index, row, field)
184
- run_js <<-JS
185
- #{start_edit_combobox(row, field)}
186
- JS
187
-
188
- run_js <<-JS
189
- #{ext_var(grid, 'grid')}
190
- #{ext_var(ext_netzkecombo(field), 'combo')}
191
- #{ext_var(ext_celleditor, 'editor')}
192
- var val = combo.getStore().getAt(#{index}).get('text');
193
- editor.completeEdit();
194
- return val;
195
- JS
196
- end
197
-
198
- def start_edit_grid_combobox(row, field)
199
- <<-JS
200
- #{ext_var(grid, 'grid')}
201
- #{ext_var(ext_netzkecombo(field), 'combo')}
202
- #{ext_var(ext_celleditor, 'editor')}
203
-
204
- editor.startEditByPosition({ row:#{row.to_i-1},
205
- column:grid.headerCt.items.findIndex('name', '#{field}') });
206
-
207
- var now = new Date().getTime();
208
- while(new Date().getTime() < now + 500) { }
209
-
210
- combo.onTriggerClick();
211
- JS
212
- end
213
-
214
- def id_of_edit_field(row, field)
215
- res = run_js <<-JS
216
- #{ext_var(grid, 'grid')}
217
- #{ext_var(ext_celleditor, 'editor')}
218
-
219
- editor.startEditByPosition({ row:#{row.to_i-1},
220
- column:grid.headerCt.items.findIndex('name', '#{field}') });
221
- return editor.activeEditor.field.inputId;
222
- JS
223
- res
224
- end
225
-
226
- def end_edit(row, field)
227
- run_js <<-JS
228
- #{ext_var(grid, 'grid')}
229
- #{ext_var(ext_celleditor, 'editor')}
230
- editor.completeEdit();
231
- return true;
232
- JS
233
- end
234
-
235
- def id_of_checkbox(row, field)
236
- res = run_js <<-JS
237
- #{ext_var(grid, 'grid')}
238
- #{ext_var(ext_celleditor, 'editor')}
239
-
240
- editor.startEditByPosition({ row:#{row.to_i-1},
241
- column:grid.headerCt.items.findIndex('name', '#{field}') });
242
- return editor.activeEditor.field.getItemId();
243
- JS
244
- res
245
- end
246
-
247
- ############################################################################
248
- # grid combobox helpers
249
- ############################################################################
250
-
251
- def select_combobox(selection, row, field)
252
- run_js <<-JS
253
- #{start_edit_combobox(row, field)}
254
-
255
- rec = combo.findRecordByDisplay('#{selection}');
256
- if (rec == false) { return false; }
257
- combo.setValue(rec);
258
- combo.onTriggerClick();
259
- editor.completeEdit();
260
- return true
261
- JS
262
- end
263
-
264
- def select_combobox_enum(selection, row, field)
265
- run_js <<-JS
266
- #{start_edit_combobox_enum(row, field)}
267
-
268
- rec = combo.findRecordByDisplay('#{selection}');
269
- if (rec == false) { return false; }
270
- combo.setValue(rec);
271
- editor.completeEdit();
272
- return true
273
- JS
274
- end
275
-
276
- def combobox_values(row, field)
277
- run_js <<-JS
278
- #{start_edit_combobox(row, field)}
279
- JS
280
-
281
- # hacky: delay for combobox to render, assumes that the combobox is not empty
282
- run_js <<-JS
283
- #{ext_var(grid, 'grid')}
284
- #{ext_var(ext_netzkecombo(field), 'combo')}
285
- var r = [];
286
- #{ext_var(ext_celleditor, 'editor')}
287
- var store = combo.getStore();
288
-
289
- // force a retry if the store is still loading
290
- if (store.loading == true) {
291
- now = new Date().getTime();
292
- while(new Date().getTime() < now + 100) { }
293
- return false;
294
- }
295
-
296
- for(var i = 0; i < store.getCount(); i++) {
297
- r.push(store.getAt(i).get('text'));
298
- };
299
-
300
- editor.completeEdit();
301
- return r;
302
- JS
303
- end
304
-
305
- def get_combobox_val(index, row, field)
306
- run_js <<-JS
307
- #{start_edit_combobox(row, field)}
308
- JS
309
-
310
- run_js <<-JS
311
- #{ext_var(grid, 'grid')}
312
- #{ext_var(ext_netzkecombo(field), 'combo')}
313
- #{ext_var(ext_celleditor, 'editor')}
314
- var val = combo.getStore().getAt(#{index}).get('text');
315
- editor.completeEdit();
316
- return val;
317
- JS
318
- end
319
-
320
- def start_edit_combobox(row, field)
321
- <<-JS
322
- #{ext_var(grid, 'grid')}
323
- #{ext_var(ext_netzkecombo(field), 'combo')}
324
- #{ext_var(ext_celleditor, 'editor')}
325
-
326
- editor.startEditByPosition({ row:#{row.to_i-1},
327
- column:grid.headerCt.items.findIndex('name', '#{field}') });
328
-
329
- var now = new Date().getTime();
330
- while(new Date().getTime() < now + 500) { }
331
-
332
- combo.onTriggerClick();
333
- JS
334
- end
335
-
336
- def start_edit_combobox_enum(row, field)
337
- <<-JS
338
- #{ext_var(grid, 'grid')}
339
- #{ext_combo(field, 'combo')}
340
- #{ext_var(ext_celleditor, 'editor')}
341
-
342
- editor.startEditByPosition({ row:#{row.to_i-1},
343
- column:grid.headerCt.items.findIndex('name', '#{field}') });
344
- JS
345
- end
346
-
347
- def end_edit(row, field)
348
- run_js <<-JS
349
- #{ext_var(grid, 'grid')}
350
- #{ext_var(ext_celleditor, 'editor')}
351
- editor.completeEdit();
352
- return true;
353
- JS
354
- end
355
- end
356
- end end end
@@ -1,18 +0,0 @@
1
- require 'rspec'
2
-
3
- RSpec::Matchers.define :netzke_include do |expected|
4
- match do |actual|
5
- parsed_values = actual.each_with_object({}) do | (k, v), h |
6
- h[k] = v == "False" ? false : v
7
- end
8
- expect(parsed_values).to include(expected.stringify_keys)
9
- end
10
-
11
- diffable
12
- end
13
-
14
- RSpec::Matchers.define :match_fuzzily do |expected|
15
- msg = nil
16
- match { |actual| !(msg = struct_compare(actual, expected)) }
17
- failure_message { |_| msg }
18
- end
@@ -1,49 +0,0 @@
1
- Capybara.add_selector(:gridpanel) do
2
- xpath do |name|
3
- ".//div[contains(@id, '#{name}')][not(contains(@id, 'splitter'))] | "\
4
- ".//div[contains(@id, '#{name.camelize(:lower)}')]"\
5
- "[not(contains(@id, 'splitter'))]"
6
- end
7
- end
8
-
9
- Capybara.add_selector(:msg) do
10
- xpath do
11
- "//div[@id='msg-div']"
12
- end
13
- end
14
-
15
- Capybara.add_selector(:body) do
16
- xpath do
17
- ".//div[@data-ref='body']"
18
- end
19
- end
20
-
21
- Capybara.add_selector(:input) do
22
- xpath do |name|
23
- "//input[@name='#{name}']"
24
- end
25
- end
26
-
27
- Capybara.add_selector(:status) do
28
- xpath do |name|
29
- "//div[contains(@id, 'statusbar')]//div[text()='#{name}']"
30
- end
31
- end
32
-
33
- Capybara.add_selector(:btn) do
34
- xpath do |name|
35
- ".//span[text()='#{name}']"
36
- end
37
- end
38
-
39
- Capybara.add_selector(:refresh) do
40
- xpath do
41
- ".//div[contains(@class, 'x-tool-refresh')]"
42
- end
43
- end
44
-
45
- Capybara.add_selector(:gridcolumn) do
46
- xpath do |name|
47
- ".//span[contains(@class, 'x-column-header')][text()='#{name}']/.."
48
- end
49
- end
@@ -1,52 +0,0 @@
1
- module Marty::RSpec::DownloadHelper
2
- TIMEOUT = 10
3
- PATH = Rails.root.join('spec/tmp/downloads')
4
-
5
- ACCEPTED_EXTS = ['.xlsx', '.csv']
6
-
7
- extend self
8
-
9
- def downloads
10
- Dir[PATH.join("*")]
11
- end
12
-
13
- def download
14
- downloads.first
15
- end
16
-
17
- def download_content
18
- wait_for_download
19
- # doesn't work for excel files...
20
- File.read(download)
21
- end
22
-
23
- def download_content_acceptable?
24
- wait_for_download
25
- downloads.each do |f|
26
- return false unless ACCEPTED_EXTS.include? File.extname(f)
27
- end
28
- true
29
- end
30
-
31
- def wait_for_download
32
- Timeout.timeout(TIMEOUT) do
33
- sleep 0.1 until downloaded?
34
- end
35
- end
36
-
37
- def downloaded?
38
- downloads.any? && !downloading?
39
- end
40
-
41
- def downloading?
42
- downloads.grep(/\.part$/).any? ||
43
- downloads.select { |f| File.size(f).zero? }.any?
44
- end
45
-
46
- def clear_downloads
47
- FileUtils.rm_f(downloads)
48
- Timeout.timeout(TIMEOUT) do
49
- sleep 0.1 until !downloads.any?
50
- end
51
- end
52
- end