glib-web 0.5.44 → 0.5.45

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 (171) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/glib/analytics/funnel.rb +61 -61
  3. data/app/controllers/concerns/glib/auth/policy.rb +148 -148
  4. data/app/controllers/concerns/glib/json/dynamic_text.rb +126 -126
  5. data/app/controllers/concerns/glib/json/libs.rb +144 -144
  6. data/app/controllers/concerns/glib/json/new_dynamic_text.rb +122 -122
  7. data/app/controllers/concerns/glib/json/transformation.rb +11 -11
  8. data/app/controllers/concerns/glib/json/traversal.rb +87 -87
  9. data/app/controllers/concerns/glib/json/ui.rb +88 -88
  10. data/app/controllers/concerns/glib/json/validation.rb +13 -13
  11. data/app/controllers/glib/home_controller.rb +16 -16
  12. data/app/helpers/glib/app_feature_support_helper.rb +16 -16
  13. data/app/helpers/glib/dynamic_images_helper.rb +55 -55
  14. data/app/helpers/glib/dynamic_texts_helper.rb +42 -42
  15. data/app/helpers/glib/enum_helper.rb +8 -8
  16. data/app/helpers/glib/forms_helper.rb +15 -15
  17. data/app/helpers/glib/json_ui/abstract_builder.rb +294 -294
  18. data/app/helpers/glib/json_ui/action_builder.rb +131 -131
  19. data/app/helpers/glib/json_ui/action_builder/dialogs.rb +58 -58
  20. data/app/helpers/glib/json_ui/action_builder/http.rb +39 -39
  21. data/app/helpers/glib/json_ui/action_builder/sheets.rb +15 -15
  22. data/app/helpers/glib/json_ui/action_builder/snackbars.rb +41 -41
  23. data/app/helpers/glib/json_ui/action_builder/windows.rb +26 -26
  24. data/app/helpers/glib/json_ui/analytics_helper.rb +17 -17
  25. data/app/helpers/glib/json_ui/dynamic_field_builders.rb +25 -25
  26. data/app/helpers/glib/json_ui/generic_builders.rb +28 -28
  27. data/app/helpers/glib/json_ui/list_builders.rb +104 -104
  28. data/app/helpers/glib/json_ui/menu_builder.rb +94 -94
  29. data/app/helpers/glib/json_ui/page_helper.rb +213 -213
  30. data/app/helpers/glib/json_ui/response_helper.rb +25 -25
  31. data/app/helpers/glib/json_ui/split_builders.rb +32 -32
  32. data/app/helpers/glib/json_ui/styling_helper.rb +47 -47
  33. data/app/helpers/glib/json_ui/table_builders.rb +74 -74
  34. data/app/helpers/glib/json_ui/view_builder.rb +208 -208
  35. data/app/helpers/glib/json_ui/view_builder/banners.rb +24 -24
  36. data/app/helpers/glib/json_ui/view_builder/charts.rb +33 -33
  37. data/app/helpers/glib/json_ui/view_builder/fields.rb +236 -235
  38. data/app/helpers/glib/json_ui/view_builder/panels.rb +250 -250
  39. data/app/helpers/glib/urls_helper.rb +7 -7
  40. data/app/models/glib/active_storage/attachment.rb +9 -9
  41. data/app/models/glib/active_storage/blob.rb +9 -9
  42. data/app/models/glib/application_record.rb +18 -18
  43. data/app/models/glib/dynamic_text_record.rb +9 -9
  44. data/app/models/glib/text.rb +95 -95
  45. data/app/policies/glib/application_policy.rb +161 -161
  46. data/app/validators/email_typo_validator.rb +38 -38
  47. data/app/validators/email_validator.rb +7 -7
  48. data/app/validators/url_validator.rb +20 -20
  49. data/app/views/json_ui/garage/_nav_menu.json.jbuilder +70 -70
  50. data/app/views/json_ui/garage/actions/_dialogs.json.jbuilder +104 -104
  51. data/app/views/json_ui/garage/actions/_http.json.jbuilder +24 -24
  52. data/app/views/json_ui/garage/actions/_reload.json.jbuilder +17 -17
  53. data/app/views/json_ui/garage/actions/_sheets.json.jbuilder +18 -18
  54. data/app/views/json_ui/garage/actions/_snackbars.json.jbuilder +33 -33
  55. data/app/views/json_ui/garage/actions/_timeouts.json.jbuilder +18 -18
  56. data/app/views/json_ui/garage/actions/_windows.json.jbuilder +24 -24
  57. data/app/views/json_ui/garage/actions/dialogs_oauth_post.json.jbuilder +6 -6
  58. data/app/views/json_ui/garage/actions/index.json.jbuilder +22 -22
  59. data/app/views/json_ui/garage/forms/_alert_post_data.json.jbuilder +6 -6
  60. data/app/views/json_ui/garage/forms/basic.json.jbuilder +21 -21
  61. data/app/views/json_ui/garage/forms/basic_post.json.jbuilder +8 -8
  62. data/app/views/json_ui/garage/forms/checkboxes.json.jbuilder +43 -43
  63. data/app/views/json_ui/garage/forms/conditional_value.json.jbuilder +36 -36
  64. data/app/views/json_ui/garage/forms/dynamic_group.json.jbuilder +56 -56
  65. data/app/views/json_ui/garage/forms/dynamic_select.json.jbuilder +25 -25
  66. data/app/views/json_ui/garage/forms/dynamic_select_data.json.jbuilder +38 -38
  67. data/app/views/json_ui/garage/forms/file_upload.json.jbuilder +65 -65
  68. data/app/views/json_ui/garage/forms/floating_submit.json.jbuilder +31 -31
  69. data/app/views/json_ui/garage/forms/generic_post.json.jbuilder +3 -3
  70. data/app/views/json_ui/garage/forms/get_request.json.jbuilder +28 -28
  71. data/app/views/json_ui/garage/forms/index.json.jbuilder +110 -110
  72. data/app/views/json_ui/garage/forms/new_rich_text.json.jbuilder +40 -40
  73. data/app/views/json_ui/garage/forms/pickers.json.jbuilder +48 -48
  74. data/app/views/json_ui/garage/forms/rich_text.json.jbuilder +40 -40
  75. data/app/views/json_ui/garage/forms/selects.json.jbuilder +70 -70
  76. data/app/views/json_ui/garage/forms/show_hide.json.jbuilder +105 -105
  77. data/app/views/json_ui/garage/forms/styled_boxes.json.jbuilder +36 -36
  78. data/app/views/json_ui/garage/forms/submission_flow.json.jbuilder +17 -17
  79. data/app/views/json_ui/garage/forms/submission_flow_post.json.jbuilder +24 -24
  80. data/app/views/json_ui/garage/forms/submission_indicator.json.jbuilder +63 -63
  81. data/app/views/json_ui/garage/forms/submission_indicator_post.json.jbuilder +25 -25
  82. data/app/views/json_ui/garage/forms/text_validation.json.jbuilder +57 -22
  83. data/app/views/json_ui/garage/home/blank.json.jbuilder +11 -11
  84. data/app/views/json_ui/garage/home/index.json.jbuilder +32 -32
  85. data/app/views/json_ui/garage/home/slow.json.jbuilder +11 -11
  86. data/app/views/json_ui/garage/lists/_autoload_section.json.jbuilder +28 -28
  87. data/app/views/json_ui/garage/lists/autoload_all.json.jbuilder +32 -32
  88. data/app/views/json_ui/garage/lists/autoload_as_needed.json.jbuilder +35 -35
  89. data/app/views/json_ui/garage/lists/chat_ui.json.jbuilder +93 -93
  90. data/app/views/json_ui/garage/lists/edit_actions.json.jbuilder +54 -54
  91. data/app/views/json_ui/garage/lists/fab.json.jbuilder +12 -12
  92. data/app/views/json_ui/garage/lists/index.json.jbuilder +32 -32
  93. data/app/views/json_ui/garage/lists/reordering.json.jbuilder +24 -24
  94. data/app/views/json_ui/garage/lists/templating.json.jbuilder +35 -35
  95. data/app/views/json_ui/garage/notifications/android_post.json.jbuilder +48 -48
  96. data/app/views/json_ui/garage/notifications/index.json.jbuilder +32 -32
  97. data/app/views/json_ui/garage/notifications/web_socket.json.jbuilder +60 -60
  98. data/app/views/json_ui/garage/pages/flat_centered.json.jbuilder +29 -29
  99. data/app/views/json_ui/garage/pages/full_width.json.jbuilder +29 -29
  100. data/app/views/json_ui/garage/pages/full_width_height.json.jbuilder +16 -16
  101. data/app/views/json_ui/garage/pages/index.json.jbuilder +58 -58
  102. data/app/views/json_ui/garage/pages/layout.json.jbuilder +18 -18
  103. data/app/views/json_ui/garage/pages/loading_indicator.json.jbuilder +10 -10
  104. data/app/views/json_ui/garage/pages/nav_buttons.json.jbuilder +21 -21
  105. data/app/views/json_ui/garage/pages/nested_scroll.json.jbuilder +40 -40
  106. data/app/views/json_ui/garage/pages/tab_bar.json.jbuilder +27 -27
  107. data/app/views/json_ui/garage/panels/_styled.json.jbuilder +78 -78
  108. data/app/views/json_ui/garage/panels/card.json.jbuilder +4 -4
  109. data/app/views/json_ui/garage/panels/carousel.json.jbuilder +37 -37
  110. data/app/views/json_ui/garage/panels/custom.json.jbuilder +17 -17
  111. data/app/views/json_ui/garage/panels/flow.json.jbuilder +49 -49
  112. data/app/views/json_ui/garage/panels/horizontal.json.jbuilder +91 -91
  113. data/app/views/json_ui/garage/panels/index.json.jbuilder +132 -132
  114. data/app/views/json_ui/garage/panels/outlined.json.jbuilder +4 -4
  115. data/app/views/json_ui/garage/panels/responsive.json.jbuilder +98 -98
  116. data/app/views/json_ui/garage/panels/split.json.jbuilder +182 -182
  117. data/app/views/json_ui/garage/panels/vertical.json.jbuilder +50 -50
  118. data/app/views/json_ui/garage/services/dynamic_text.json.jbuilder +13 -13
  119. data/app/views/json_ui/garage/services/image.json.jbuilder +47 -47
  120. data/app/views/json_ui/garage/services/index.json.jbuilder +17 -17
  121. data/app/views/json_ui/garage/tables/_autoload_section.json.jbuilder +16 -16
  122. data/app/views/json_ui/garage/tables/autoload_all.json.jbuilder +43 -43
  123. data/app/views/json_ui/garage/tables/autoload_as_needed.json.jbuilder +50 -50
  124. data/app/views/json_ui/garage/tables/export_import.json.jbuilder +29 -29
  125. data/app/views/json_ui/garage/tables/horizontal_scroll.json.jbuilder +26 -26
  126. data/app/views/json_ui/garage/tables/index.json.jbuilder +25 -25
  127. data/app/views/json_ui/garage/tables/layout.json.jbuilder +36 -36
  128. data/app/views/json_ui/garage/views/_chart_data.json.jbuilder +17 -17
  129. data/app/views/json_ui/garage/views/banners.json.jbuilder +63 -63
  130. data/app/views/json_ui/garage/views/calendar_data.json.jbuilder +30 -30
  131. data/app/views/json_ui/garage/views/charts.json.jbuilder +115 -115
  132. data/app/views/json_ui/garage/views/icons.json.jbuilder +1450 -1450
  133. data/app/views/json_ui/garage/views/images.json.jbuilder +89 -89
  134. data/app/views/json_ui/garage/views/index.json.jbuilder +54 -54
  135. data/app/views/json_ui/garage/views/links.json.jbuilder +70 -70
  136. data/app/views/json_ui/garage/views/map_cluster_data.json.jbuilder +41 -41
  137. data/app/views/json_ui/garage/views/map_data.json.jbuilder +51 -51
  138. data/app/views/json_ui/garage/views/maps.json.jbuilder +31 -31
  139. data/app/views/json_ui/garage/views/markdowns.json.jbuilder +41 -41
  140. data/app/views/json_ui/garage/views/misc.json.jbuilder +34 -34
  141. data/app/views/json_ui/garage/views/texts.json.jbuilder +41 -41
  142. data/app/views/layouts/json_ui/renderer.html.erb +35 -35
  143. data/config/routes.rb +7 -7
  144. data/lib/generators/glib/install_generator.rb +24 -24
  145. data/lib/generators/templates/20191017062519_create_texts.rb +12 -12
  146. data/lib/generators/templates/20191024063257_add_scope_to_texts.rb +7 -7
  147. data/lib/generators/templates/20191112095018_add_lang_to_texts.rb +7 -7
  148. data/lib/generators/templates/20191126071051_create_active_storage_tables.active_storage.rb +27 -27
  149. data/lib/generators/templates/database.yml +107 -107
  150. data/lib/generators/templates/dynamic_text.rb +2 -2
  151. data/lib/glib-web.rb +9 -9
  152. data/lib/glib/crypt/utils.rb +26 -26
  153. data/lib/glib/dynamic_text/config.rb +21 -21
  154. data/lib/glib/engine.rb +7 -7
  155. data/lib/glib/json_crawler.rb +11 -11
  156. data/lib/glib/json_crawler/action_crawler.rb +23 -23
  157. data/lib/glib/json_crawler/action_crawlers/action_http.rb +11 -11
  158. data/lib/glib/json_crawler/action_crawlers/forms_submit.rb +48 -48
  159. data/lib/glib/json_crawler/action_crawlers/menu.rb +12 -12
  160. data/lib/glib/json_crawler/action_crawlers/nav_initiate.rb +19 -19
  161. data/lib/glib/json_crawler/action_crawlers/run_multiple.rb +13 -13
  162. data/lib/glib/json_crawler/action_crawlers/windows_open.rb +33 -33
  163. data/lib/glib/json_crawler/coverage.rb +20 -20
  164. data/lib/glib/json_crawler/http.rb +120 -120
  165. data/lib/glib/json_crawler/router.rb +96 -96
  166. data/lib/glib/mailer_tester.rb +36 -36
  167. data/lib/glib/test_helpers.rb +40 -40
  168. data/lib/glib/value.rb +7 -7
  169. data/lib/glib/version.rb +5 -5
  170. data/lib/tasks/db.rake +95 -95
  171. metadata +3 -2
@@ -1,120 +1,120 @@
1
- module Glib
2
- module JsonCrawler
3
- class Http
4
- attr_accessor :history, :response_times, :user, :router
5
-
6
- URI_REGEXP = /\A#{URI.regexp}\z/
7
-
8
- VALID_RESPONSE_CODES = [
9
- (200..299).to_a,
10
- ## Note, the JSON API does not allow redirects
11
- # 401, ## UNAUTHORIZED Should be used for not-logged-in
12
- # 403, ## FORBIDDEN Should be used for logged-in but not allowed to access
13
- ].flatten
14
-
15
- def initialize(context, user, router)
16
- @context = context
17
- @history = []
18
- @response_times = []
19
- @user = user
20
- @router = router
21
- end
22
-
23
- def get(url, action, params = {}, inspect_result = true)
24
- fetch(:get, url, action, params, inspect_result)
25
- end
26
-
27
- def post(url, action, params)
28
- fetch(:post, url, action, params)
29
- end
30
-
31
- def patch(url, action, params)
32
- fetch(:patch, url, action, params)
33
- end
34
-
35
- def put(url, action, params)
36
- fetch(:put, url, action, params)
37
- end
38
-
39
- def delete(url, action, params = {})
40
- fetch(:delete, url, action, {})
41
- end
42
-
43
- private
44
- Response = Struct.new :code, :headers, :media_type, :body do
45
- def initialize(*)
46
- super
47
- self.headers ||= {}
48
- self.media_type ||= 'text/plain'
49
- end
50
- end
51
-
52
- def fetch(method, url, action, params = {}, inspect_result = true)
53
- return nil if url.blank?
54
-
55
- if method == :get
56
- return nil if history.include?(url)
57
-
58
- history << url
59
- end
60
-
61
- if !URI_REGEXP.match(url)
62
- raise "Invalid URL: `#{url}`. Make sure to use the absolute URL."
63
- end
64
-
65
- http_header = {
66
- 'Client-DeviceOS' => user[:device],
67
- 'Client-Version' => user[:version],
68
- 'X-CSRF-Token' => user[:token]
69
- }
70
- http_header.merge!(params[:headers]) if params[:headers].present?
71
-
72
- params.each do |name, value|
73
- params[name] = '' if value.is_a?(Array) && value.size == 0
74
- end
75
-
76
- response = nil
77
- begin
78
- @context.send(method, url, params: params, headers: http_header)
79
- raw_response = @context.response
80
- response = Response.new(raw_response.code.to_i, raw_response.headers, raw_response.media_type, raw_response.body)
81
-
82
- if (controller = @context.controller)
83
- Glib::JsonCrawler::Coverage.coverage_files.add(controller.class.instance_method(controller.action_name).source_location.first)
84
- end
85
- rescue => ex
86
- if !inspect_result
87
- case ex
88
- when ActionController::RoutingError, ActiveRecord::RecordNotFound
89
- response = Response.new(404)
90
- end
91
- end
92
-
93
- if !response
94
- puts "Crashed on #{url}"
95
- raise
96
- end
97
- end
98
-
99
- @router.log(action, url, response)
100
-
101
- if inspect_result
102
- if (code = response.code) == 302
103
- redirect_uri = URI(response.headers['Location'])
104
- redirect_uri.query = [redirect_uri.query, 'format=json'].compact.join('&')
105
- get redirect_uri.to_s, action, params
106
- else
107
- response_times << response.headers['X-Runtime'].to_f
108
-
109
- @context.assert_includes VALID_RESPONSE_CODES, code, "Expected a valid response but was [#{response.code}] #{Rack::Utils::HTTP_STATUS_CODES[response.code.to_i]}:\n#{url}"
110
- if response.media_type == 'application/json'
111
- JSON.parse(response.body)
112
- else
113
- nil
114
- end
115
- end
116
- end
117
- end
118
- end
119
- end
120
- end
1
+ module Glib
2
+ module JsonCrawler
3
+ class Http
4
+ attr_accessor :history, :response_times, :user, :router
5
+
6
+ URI_REGEXP = /\A#{URI.regexp}\z/
7
+
8
+ VALID_RESPONSE_CODES = [
9
+ (200..299).to_a,
10
+ ## Note, the JSON API does not allow redirects
11
+ # 401, ## UNAUTHORIZED Should be used for not-logged-in
12
+ # 403, ## FORBIDDEN Should be used for logged-in but not allowed to access
13
+ ].flatten
14
+
15
+ def initialize(context, user, router)
16
+ @context = context
17
+ @history = []
18
+ @response_times = []
19
+ @user = user
20
+ @router = router
21
+ end
22
+
23
+ def get(url, action, params = {}, inspect_result = true)
24
+ fetch(:get, url, action, params, inspect_result)
25
+ end
26
+
27
+ def post(url, action, params)
28
+ fetch(:post, url, action, params)
29
+ end
30
+
31
+ def patch(url, action, params)
32
+ fetch(:patch, url, action, params)
33
+ end
34
+
35
+ def put(url, action, params)
36
+ fetch(:put, url, action, params)
37
+ end
38
+
39
+ def delete(url, action, params = {})
40
+ fetch(:delete, url, action, {})
41
+ end
42
+
43
+ private
44
+ Response = Struct.new :code, :headers, :media_type, :body do
45
+ def initialize(*)
46
+ super
47
+ self.headers ||= {}
48
+ self.media_type ||= 'text/plain'
49
+ end
50
+ end
51
+
52
+ def fetch(method, url, action, params = {}, inspect_result = true)
53
+ return nil if url.blank?
54
+
55
+ if method == :get
56
+ return nil if history.include?(url)
57
+
58
+ history << url
59
+ end
60
+
61
+ if !URI_REGEXP.match(url)
62
+ raise "Invalid URL: `#{url}`. Make sure to use the absolute URL."
63
+ end
64
+
65
+ http_header = {
66
+ 'Client-DeviceOS' => user[:device],
67
+ 'Client-Version' => user[:version],
68
+ 'X-CSRF-Token' => user[:token]
69
+ }
70
+ http_header.merge!(params[:headers]) if params[:headers].present?
71
+
72
+ params.each do |name, value|
73
+ params[name] = '' if value.is_a?(Array) && value.size == 0
74
+ end
75
+
76
+ response = nil
77
+ begin
78
+ @context.send(method, url, params: params, headers: http_header)
79
+ raw_response = @context.response
80
+ response = Response.new(raw_response.code.to_i, raw_response.headers, raw_response.media_type, raw_response.body)
81
+
82
+ if (controller = @context.controller)
83
+ Glib::JsonCrawler::Coverage.coverage_files.add(controller.class.instance_method(controller.action_name).source_location.first)
84
+ end
85
+ rescue => ex
86
+ if !inspect_result
87
+ case ex
88
+ when ActionController::RoutingError, ActiveRecord::RecordNotFound
89
+ response = Response.new(404)
90
+ end
91
+ end
92
+
93
+ if !response
94
+ puts "Crashed on #{url}"
95
+ raise
96
+ end
97
+ end
98
+
99
+ @router.log(action, url, response)
100
+
101
+ if inspect_result
102
+ if (code = response.code) == 302
103
+ redirect_uri = URI(response.headers['Location'])
104
+ redirect_uri.query = [redirect_uri.query, 'format=json'].compact.join('&')
105
+ get redirect_uri.to_s, action, params
106
+ else
107
+ response_times << response.headers['X-Runtime'].to_f
108
+
109
+ @context.assert_includes VALID_RESPONSE_CODES, code, "Expected a valid response but was [#{response.code}] #{Rack::Utils::HTTP_STATUS_CODES[response.code.to_i]}:\n#{url}"
110
+ if response.media_type == 'application/json'
111
+ JSON.parse(response.body)
112
+ else
113
+ nil
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -1,96 +1,96 @@
1
- module Glib
2
- module JsonCrawler
3
- class Router
4
- attr_reader :read_only_actions
5
-
6
- def log(action, url, response = nil)
7
- @logger.puts ' ' * @depth + [
8
- action,
9
- response.present? ? response.code : nil,
10
- url
11
- ].compact.join(' :: ')
12
- end
13
-
14
- def initialize(logger)
15
- @depth = -1
16
- @logger = logger
17
- @visitor = Glib::Json::Traversal::Visitor.new
18
- @read_only_actions = Set.new
19
- end
20
-
21
- def step(http, args)
22
- # TODO: Refactor
23
- case args['view']
24
- when 'fields/submit-v1', 'fields/submit'
25
- @depth += 1
26
- forms = @visitor.forms
27
- JsonCrawler::FormsSubmit.new(http, forms.last)
28
- @depth -= 1
29
- return
30
- end
31
-
32
- if args.is_a?(Hash) && args['rel'] != 'nofollow'
33
- if (on_click = (args.fetch('onClick', nil)))
34
- process_action(http, on_click)
35
- end
36
- end
37
- end
38
-
39
- def process_action(http, spec)
40
- action = spec['action']
41
- params = spec
42
-
43
- if action.present?
44
- @depth += 1
45
- case action
46
- when 'initiate_navigation'
47
- @read_only_actions.add([action, params['url']])
48
- JsonCrawler::NavInitiate.new(http, params, action)
49
- when 'runMultiple-v1', 'runMultiple'
50
- JsonCrawler::RunMultiple.new(http, params, action)
51
- when 'windows/open-v1', 'dialogs/open-v1', 'windows/reload-v1', 'windows/open', 'dialogs/open', 'windows/reload'
52
- @read_only_actions.add([action, params['url']])
53
- JsonCrawler::WindowsOpen.new(http, params, action)
54
- when 'sheets/select-v1', 'sheets/select'
55
- JsonCrawler::Menu.new(http, params, action)
56
- when 'http/post-v1', 'http/post'
57
- JsonCrawler::ActionHttp.new(:post, http, params, action)
58
- when 'forms/submit-v1', 'forms/submit'
59
- forms = @visitor.forms
60
- # raise 'Submit action needs to be inside a form' if forms.size < 1
61
- JsonCrawler::FormsSubmit.new(http, forms.last)
62
- else
63
- unless [
64
- 'http/delete-v1', 'dialogs/oauth-v1', 'windows/openWeb-v1',
65
- 'http/delete', 'dialogs/oauth', 'windows/openWeb'
66
- ].include?(action)
67
- @read_only_actions.add([action, params['url']])
68
- end
69
- self.log action, params['url']
70
- end
71
- @depth -= 1
72
- end
73
- end
74
-
75
- def follow(http, target_router)
76
- @depth += 1
77
- target_router.read_only_actions.each do |crawler_action|
78
- action, url = crawler_action
79
- http.get(url, action, {}, false)
80
- end
81
- end
82
-
83
- def tear_down
84
- # NOTE: Experimental, to address issue where sometimes changes don't get saved.
85
- # FINDING: Doesn't work
86
- # @logger.flush
87
-
88
- @logger.close
89
- end
90
-
91
- def crawl_multiple(views, block)
92
- @visitor.traverse_multiple views, block
93
- end
94
- end
95
- end
96
- end
1
+ module Glib
2
+ module JsonCrawler
3
+ class Router
4
+ attr_reader :read_only_actions
5
+
6
+ def log(action, url, response = nil)
7
+ @logger.puts ' ' * @depth + [
8
+ action,
9
+ response.present? ? response.code : nil,
10
+ url
11
+ ].compact.join(' :: ')
12
+ end
13
+
14
+ def initialize(logger)
15
+ @depth = -1
16
+ @logger = logger
17
+ @visitor = Glib::Json::Traversal::Visitor.new
18
+ @read_only_actions = Set.new
19
+ end
20
+
21
+ def step(http, args)
22
+ # TODO: Refactor
23
+ case args['view']
24
+ when 'fields/submit-v1', 'fields/submit'
25
+ @depth += 1
26
+ forms = @visitor.forms
27
+ JsonCrawler::FormsSubmit.new(http, forms.last)
28
+ @depth -= 1
29
+ return
30
+ end
31
+
32
+ if args.is_a?(Hash) && args['rel'] != 'nofollow'
33
+ if (on_click = (args.fetch('onClick', nil)))
34
+ process_action(http, on_click)
35
+ end
36
+ end
37
+ end
38
+
39
+ def process_action(http, spec)
40
+ action = spec['action']
41
+ params = spec
42
+
43
+ if action.present?
44
+ @depth += 1
45
+ case action
46
+ when 'initiate_navigation'
47
+ @read_only_actions.add([action, params['url']])
48
+ JsonCrawler::NavInitiate.new(http, params, action)
49
+ when 'runMultiple-v1', 'runMultiple'
50
+ JsonCrawler::RunMultiple.new(http, params, action)
51
+ when 'windows/open-v1', 'dialogs/open-v1', 'windows/reload-v1', 'windows/open', 'dialogs/open', 'windows/reload'
52
+ @read_only_actions.add([action, params['url']])
53
+ JsonCrawler::WindowsOpen.new(http, params, action)
54
+ when 'sheets/select-v1', 'sheets/select'
55
+ JsonCrawler::Menu.new(http, params, action)
56
+ when 'http/post-v1', 'http/post'
57
+ JsonCrawler::ActionHttp.new(:post, http, params, action)
58
+ when 'forms/submit-v1', 'forms/submit'
59
+ forms = @visitor.forms
60
+ # raise 'Submit action needs to be inside a form' if forms.size < 1
61
+ JsonCrawler::FormsSubmit.new(http, forms.last)
62
+ else
63
+ unless [
64
+ 'http/delete-v1', 'dialogs/oauth-v1', 'windows/openWeb-v1',
65
+ 'http/delete', 'dialogs/oauth', 'windows/openWeb'
66
+ ].include?(action)
67
+ @read_only_actions.add([action, params['url']])
68
+ end
69
+ self.log action, params['url']
70
+ end
71
+ @depth -= 1
72
+ end
73
+ end
74
+
75
+ def follow(http, target_router)
76
+ @depth += 1
77
+ target_router.read_only_actions.each do |crawler_action|
78
+ action, url = crawler_action
79
+ http.get(url, action, {}, false)
80
+ end
81
+ end
82
+
83
+ def tear_down
84
+ # NOTE: Experimental, to address issue where sometimes changes don't get saved.
85
+ # FINDING: Doesn't work
86
+ # @logger.flush
87
+
88
+ @logger.close
89
+ end
90
+
91
+ def crawl_multiple(views, block)
92
+ @visitor.traverse_multiple views, block
93
+ end
94
+ end
95
+ end
96
+ end
@@ -1,36 +1,36 @@
1
- module Glib
2
- module MailerTester
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- project_root = Rails.root
7
- paths = Dir.glob(project_root + 'test/mailers/previews/*')
8
- paths.each do |file|
9
- require file
10
- end
11
-
12
- ActionMailer::Preview.subclasses.each do |preview_class|
13
- preview = preview_class.new
14
-
15
- preview_class.instance_methods(false).each do |mailer_method|
16
- test "mailer for #{preview_class}##{mailer_method}" do
17
- preview.send(mailer_method).deliver_now
18
-
19
- logfile = File.join(log_dir, "#{preview_class.name.underscore}##{mailer_method}.txt")
20
-
21
- # Use rstrip to avoid trailing space issues
22
- expected = File.exist?(logfile) ? File.read(logfile).rstrip : ''
23
- last_delivery = ActionMailer::Base.deliveries.last
24
- result = last_delivery.html_part.body.raw_source.rstrip
25
-
26
- logger = File.open(logfile, 'w')
27
- logger.puts result
28
- logger.close
29
-
30
- assert_equal expected, result, "Result mismatch! #{logfile.sub(/\.txt$/, '')}"
31
- end
32
- end
33
- end
34
- end
35
- end
36
- end
1
+ module Glib
2
+ module MailerTester
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ project_root = Rails.root
7
+ paths = Dir.glob(project_root + 'test/mailers/previews/*')
8
+ paths.each do |file|
9
+ require file
10
+ end
11
+
12
+ ActionMailer::Preview.subclasses.each do |preview_class|
13
+ preview = preview_class.new
14
+
15
+ preview_class.instance_methods(false).each do |mailer_method|
16
+ test "mailer for #{preview_class}##{mailer_method}" do
17
+ preview.send(mailer_method).deliver_now
18
+
19
+ logfile = File.join(log_dir, "#{preview_class.name.underscore}##{mailer_method}.txt")
20
+
21
+ # Use rstrip to avoid trailing space issues
22
+ expected = File.exist?(logfile) ? File.read(logfile).rstrip : ''
23
+ last_delivery = ActionMailer::Base.deliveries.last
24
+ result = last_delivery.html_part.body.raw_source.rstrip
25
+
26
+ logger = File.open(logfile, 'w')
27
+ logger.puts result
28
+ logger.close
29
+
30
+ assert_equal expected, result, "Result mismatch! #{logfile.sub(/\.txt$/, '')}"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end