marty 2.3.15 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
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