glib-web 0.4.74 → 0.5.4

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 (28) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/glib/json/libs.rb +30 -7
  3. data/app/controllers/glib/home_controller.rb +1 -1
  4. data/app/helpers/glib/json_ui/action_builder.rb +0 -18
  5. data/app/helpers/glib/json_ui/action_builder/http.rb +19 -0
  6. data/app/helpers/glib/json_ui/list_builders.rb +5 -0
  7. data/app/helpers/glib/json_ui/menu_builder.rb +1 -0
  8. data/app/helpers/glib/json_ui/page_helper.rb +21 -16
  9. data/app/views/json_ui/garage/actions/_dialogs.json.jbuilder +21 -12
  10. data/app/views/json_ui/garage/actions/_http.json.jbuilder +18 -0
  11. data/app/views/json_ui/garage/actions/_reload.json.jbuilder +17 -0
  12. data/app/views/json_ui/garage/actions/dialogs_oauth_post.json.jbuilder +6 -0
  13. data/app/views/json_ui/garage/actions/index.json.jbuilder +3 -18
  14. data/app/views/json_ui/garage/forms/dynamic_select_data.json.jbuilder +25 -10
  15. data/app/views/json_ui/garage/forms/file_upload.json.jbuilder +5 -5
  16. data/app/views/json_ui/garage/lists/_infinite_scroll_section.json.jbuilder +15 -5
  17. data/app/views/json_ui/garage/lists/templating.json.jbuilder +1 -1
  18. data/app/views/json_ui/garage/notifications/index.json.jbuilder +0 -43
  19. data/app/views/json_ui/garage/views/_chart_data.json.jbuilder +1 -1
  20. data/app/views/json_ui/garage/views/calendar_data.json.jbuilder +23 -27
  21. data/config/routes.rb +2 -0
  22. data/lib/glib-web.rb +1 -0
  23. data/lib/glib/json_crawler/action_crawlers/nav_initiate.rb +2 -2
  24. data/lib/glib/json_crawler/action_crawlers/windows_open.rb +8 -3
  25. data/lib/glib/json_crawler/http.rb +11 -12
  26. data/lib/glib/json_crawler/router.rb +1 -5
  27. data/lib/glib/test_helpers.rb +40 -0
  28. metadata +6 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2809128e8efe1991ed5a12aeb78637f4e4d4f7af
4
- data.tar.gz: 4896bb9197227a070abf19f033e54d4dd32efff9
3
+ metadata.gz: c258b37bbad81871f329c41e5b854b5b6563fb4f
4
+ data.tar.gz: 3e8d5f94006a46084869252b667d0c9e405de569
5
5
  SHA512:
6
- metadata.gz: bbca01d80afbe23375f5caf90011dffed09e01c6cad9955d270e894934a4fd87d34afca41b495634c813985f6a9606e82e63714faedca19f5a05b527321f6678
7
- data.tar.gz: b7d4840eeeae5194b8966b4458eab5674f6c9c50ede361add2068ce2d699526fb2a076671ea34cba885c863e76814fbd3c9bda7a55550923c635e936bdf469d9
6
+ metadata.gz: bece2c2bae109009e5b468e9e43cd52591b5c367977a8fec1b623e27876efd28d25a1432bde847943eb310fe62bef9f4e3b1b38ea93924f2767cb9e1a42c4477
7
+ data.tar.gz: 756e23d1771b4f1dae8eebe2d4d0f0c4f5397fc8762baac96c2c5bfe7ffc73a6fcab6cad2575d8aae760d84570edffeb456231d70a815918c234a8e5153895bf
@@ -46,14 +46,28 @@ module Glib::Json::Libs
46
46
  end
47
47
  end
48
48
 
49
- def json_libs_handle_404
50
- if json_ui_activated?
51
- render file: "#{Rails.root}/public/404.html", status: :not_found
49
+ def glib_json_handle_403
50
+ render file: Rails.root.join('public', '404.html'), status: :forbidden
51
+ end
52
+
53
+ def glib_json_handle_404
54
+ raise ActionController::RoutingError.new('Not Found')
55
+
56
+ # if json_ui_activated?
57
+ # render file: Rails.root.join('public', '404.html'), status: :not_found
58
+ # else
59
+ # raise exception
60
+ # end
61
+ end
62
+
63
+ def glib_json_handle_500(exception)
64
+ if json_ui_activated? && Rails.env.production?
65
+ Rollbar.error(exception) if defined?(Rollbar)
66
+ render file: Rails.root.join('public', '500.html'), status: :internal_server_error
52
67
  else
53
68
  raise exception
54
69
  end
55
70
  end
56
-
57
71
 
58
72
 
59
73
  module ClassMethods
@@ -111,11 +125,20 @@ module Glib::Json::Libs
111
125
  end
112
126
  end
113
127
 
114
- def json_libs_rescue_404
115
- rescue_from ActiveRecord::RecordNotFound do |exception|
116
- json_libs_handle_404
128
+ # Call this before other rescues. Later rescue_from statements will take precedence, so more specific
129
+ # rescues have to be declared later.
130
+ def json_libs_rescue_500
131
+ rescue_from StandardError do |exception|
132
+ glib_json_handle_500(exception)
117
133
  end
118
134
  end
119
135
 
136
+ def json_libs_rescue_404
137
+ # Removed because it doesn't seem to offer anything extra
138
+ # rescue_from ActiveRecord::RecordNotFound do |exception|
139
+ # glib_json_handle_404
140
+ # end
141
+ end
142
+
120
143
  end
121
144
  end
@@ -1,6 +1,6 @@
1
1
  module Glib
2
2
  class HomeController < ApplicationController
3
- if glib_auth_inited?
3
+ if try(:glib_auth_inited?)
4
4
  skip_before_action :glib_load_resource
5
5
  skip_before_action :glib_authorize_resource
6
6
  end
@@ -75,24 +75,6 @@ module Glib
75
75
  end
76
76
  end
77
77
 
78
- module Http
79
- class Post < Action
80
- string :url, cache: true
81
- hash :formData
82
- end
83
-
84
- class Patch < Action
85
- string :url, cache: true
86
- hash :formData
87
- end
88
-
89
- class Delete < Action
90
- string :url, cache: true
91
- hash :formData
92
- end
93
-
94
- end
95
-
96
78
  ###
97
79
  end
98
80
  end
@@ -0,0 +1,19 @@
1
+ class Glib::JsonUi::ActionBuilder
2
+ module Http
3
+ class Post < Action
4
+ string :url, cache: true
5
+ hash :formData
6
+ end
7
+
8
+ class Patch < Action
9
+ string :url, cache: true
10
+ hash :formData
11
+ end
12
+
13
+ class Delete < Action
14
+ string :url, cache: true
15
+ hash :formData
16
+ end
17
+
18
+ end
19
+ end
@@ -41,6 +41,11 @@ module Glib
41
41
 
42
42
  class Custom < Thumbnail
43
43
  string :template
44
+
45
+ # TODO: Experimental
46
+ hash :extra
47
+
48
+ # TODO: Deprecate
44
49
  hash :data
45
50
  end
46
51
  end
@@ -35,6 +35,7 @@ module Glib
35
35
 
36
36
  class Label < MenuItem
37
37
  string :text
38
+ singleton_array :styleClass, :styleClasses
38
39
 
39
40
  # Override
40
41
  def created
@@ -17,22 +17,27 @@ module Glib
17
17
  @__json_ui_page
18
18
  end
19
19
 
20
- # Use this only if you need to generate json independently from the current `json_ui_page`
21
- def json_ui_menu(&block)
22
- @__json_ui_menu_page ||= Page.new(Jbuilder.new, self)
23
- json = @__json_ui_menu_page.json
24
- json.nil!
25
- block&.call @__json_ui_menu_page.menu_builder
26
- json.attributes!
27
- end
28
-
29
- # Use this only if you need to generate json independently from the current `json_ui_page`
30
- def json_ui_panel(&block)
31
- @__json_ui_panel_page ||= Page.new(Jbuilder.new, self)
32
- json = @__json_ui_panel_page.json
33
- json.nil!
34
- block&.call @__json_ui_panel_page.view_builder
35
- json.attributes!
20
+ # # Use this only if you need to generate json independently from the current `json_ui_page`
21
+ # def json_ui_menu(&block)
22
+ # @__json_ui_menu_page ||= Page.new(Jbuilder.new, self)
23
+ # json = @__json_ui_menu_page.json
24
+ # json.nil!
25
+ # block&.call @__json_ui_menu_page.menu_builder
26
+ # json.attributes!
27
+ # end
28
+
29
+ # # Use this only if you need to generate json independently from the current `json_ui_page`
30
+ # def json_ui_panel(&block)
31
+ # @__json_ui_panel_page ||= Page.new(Jbuilder.new, self)
32
+ # json = @__json_ui_panel_page.json
33
+ # json.nil!
34
+ # block&.call @__json_ui_panel_page.view_builder
35
+ # json.attributes!
36
+ # end
37
+
38
+ def json_ui_section(json, &block)
39
+ @__json_ui_section ||= Page.new(json, self)
40
+ @__json_ui_section.list_section_builder
36
41
  end
37
42
 
38
43
  class Page
@@ -79,17 +79,26 @@ section.rows builder: ->(template) do
79
79
  end
80
80
 
81
81
  template.thumbnail title: 'dialogs/oauth', onClick: ->(action) do
82
- provider = {
83
- name: "facebook",
84
- webRequestUrl: "https://www.facebook.com/v3.1/dialog/oauth?auth_type=rerequest&client_id=CLIENT_ID&redirect_uri=http%3A%2F%2Fwww.lvh.me%3A3000%2Foauth_callback%2Ffacebook&response_type=code&scope=email",
85
- requestUrl: "https://www.facebook.com/v3.1/dialog/oauth",
86
- clientId: "CLIENT_ID",
87
- redirectUrl: "http://www.lvh.me:3000/oauth_callback/facebook.json"
88
- }
89
-
90
- action.dialogs_oauth provider: provider, providerParamName: "session[oauth_provider]", callbackUrlParamName: "session[[oauth_callback_url]", onSuccess: ->(action) do
91
- action.http_post url: 'TODO: post params to server'
82
+ if respond_to?(:user_facebook_omniauth_authorize_url)
83
+ provider = {
84
+ name: 'facebook',
85
+ webRequestUrl: user_facebook_omniauth_authorize_url(format: nil, _render: nil),
86
+ requestUrl: user_facebook_omniauth_authorize_url(format: nil),
87
+ clientId: Devise.omniauth_configs[:facebook].strategy[:client_id],
88
+ permissions: Devise.omniauth_configs[:facebook].strategy[:scope],
89
+ redirectUrl: user_facebook_omniauth_callback_url(format: nil)
90
+ }
91
+ action.dialogs_oauth provider: provider, providerParamName: 'session[oauth_provider]', callbackUrlParamName: 'session[[oauth_callback_url]', onSuccess: ->(subaction) do
92
+ subaction.http_post url: json_ui_garage_url(path: 'actions/dialogs_oauth_post'), formData: {
93
+ authenticity_token: form_authenticity_token
94
+ }
95
+ end
96
+ else
97
+ action.dialogs_alert message: 'To enable this, set up omniauth using devise'
98
+ # E.g.
99
+ # Add `devise :omniauthable, omniauth_providers: %i[facebook]` to user.rb
100
+ # Add `gem 'omniauth-facebook'` to Gemfile
101
+ # Add `config.omniauth :facebook` to devise.rb
92
102
  end
93
103
  end
94
-
95
- end
104
+ end
@@ -0,0 +1,18 @@
1
+
2
+ section.header padding: glib_json_padding_list, childViews: ->(header) do
3
+ header.h3 text: 'HTTP'
4
+ end
5
+
6
+ section.rows builder: ->(template) do
7
+ template.thumbnail title: 'http/post', onClick: ->(action) do
8
+ action.http_post url: json_ui_garage_url(path: 'forms/basic_post'), formData: { 'user[name]' => 'New Joe' }
9
+ end
10
+
11
+ template.thumbnail title: 'http/patch', onClick: ->(action) do
12
+ action.http_patch url: json_ui_garage_url(path: 'forms/basic_post'), formData: { 'user[name]' => 'Edit Joe' }
13
+ end
14
+
15
+ template.thumbnail title: 'http/delete', onClick: ->(action) do
16
+ action.http_delete url: json_ui_garage_url(path: 'forms/basic_post'), formData: { 'user[name]' => 'Delete Joe' }
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ section.header padding: glib_json_padding_list, childViews: ->(header) do
2
+ header.h3 text: 'Reload'
3
+ header.spacer height: 6
4
+ header.label text: 'Reload does not open a new page/screen. Click reload a few times, then click back and notice that it goes back to the page before the reload.'
5
+ end
6
+
7
+ section.rows builder: ->(template) do
8
+ template.thumbnail title: "windows/reload (timestamp: #{DateTime.current.to_i})", onClick: ->(action) do
9
+ action.windows_reload
10
+ end
11
+
12
+ reload_counter = params[:reload_counter].to_i
13
+ reload_counter = 0 if reload_counter > 5
14
+ template.thumbnail title: "windows/reload with URL (counter: #{reload_counter})", onClick: ->(action) do
15
+ action.windows_reload url: json_ui_garage_url(path: 'actions/index', reload_counter: reload_counter + 1)
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ facebook_graph = Koala::Facebook::API.new(params[:credentials][:token])
2
+ profile = facebook_graph.get_object('me')
3
+
4
+ json_ui_response json do |action|
5
+ action.dialogs_alert message: profile
6
+ end
@@ -15,24 +15,9 @@ json_ui_page json do |page|
15
15
  end, ->(section) do
16
16
  render "#{@path_prefix}/actions/timeouts", section: section
17
17
  end, ->(section) do
18
- section.header padding: glib_json_padding_list, childViews: ->(header) do
19
- header.h3 text: 'Reload'
20
- header.spacer height: 6
21
- header.label text: 'Reload does not open a new page/screen. Click reload a few times, then click back and notice that it goes back to the page before the reload.'
22
- end
23
-
24
- section.rows builder: ->(template) do
25
- template.thumbnail title: "windows/reload (timestamp: #{DateTime.current.to_i})", onClick: ->(action) do
26
- action.windows_reload
27
- end
28
-
29
- reload_counter = params[:reload_counter].to_i
30
- reload_counter = 0 if reload_counter > 5
31
- template.thumbnail title: "windows/reload with URL (counter: #{reload_counter})", onClick: ->(action) do
32
- action.windows_reload url: json_ui_garage_url(path: 'actions/index', reload_counter: reload_counter + 1)
33
- end
34
-
35
- end
18
+ render "#{@path_prefix}/actions/http", section: section
19
+ end, ->(section) do
20
+ render "#{@path_prefix}/actions/reload", section: section
36
21
  end
37
22
  ]
38
23
  end
@@ -6,18 +6,33 @@ if page < 2
6
6
  json.nextPageUrl json_ui_garage_url(path: 'forms/dynamic_select_data', page: page + 1)
7
7
  end
8
8
 
9
- json.rows do
9
+ # json.rows do
10
10
 
11
+ # count_per_page = 20
12
+ # count_per_page.times do |i|
13
+ # json.child! do
14
+ # index = page * count_per_page + i
15
+ # json.template 'thumbnail'
16
+ # json.title "City #{index} (#{params[:q]})"
17
+ # json.subtitle "State #{index}"
18
+ # json.subsubtitle "Country #{index}"
19
+ # json.value "id#{index}"
20
+ # json.text "Item #{index}"
21
+ # end
22
+ # end
23
+ # end
24
+
25
+ section = json_ui_section json
26
+ section.rows builder: ->(row) do
11
27
  count_per_page = 20
12
28
  count_per_page.times do |i|
13
- json.child! do
14
- index = page * count_per_page + i
15
- json.template 'thumbnail'
16
- json.title "City #{index} (#{params[:q]})"
17
- json.subtitle "State #{index}"
18
- json.subsubtitle "Country #{index}"
19
- json.value "id#{index}"
20
- json.text "Item #{index}"
21
- end
29
+ index = page * count_per_page + i
30
+ row.custom title: "City #{index} (#{params[:q]})",
31
+ subtitle: "State #{index}",
32
+ subsubtitle: "Country #{index}",
33
+ extra: {
34
+ value: "id#{index}",
35
+ text: "Item #{index}"
36
+ }
22
37
  end
23
38
  end
@@ -8,18 +8,18 @@ options = {
8
8
 
9
9
  json_ui_page json do |page|
10
10
  render "#{@path_prefix}/nav_menu", json: json, page: page
11
-
11
+
12
12
  page.form options.merge(childViews: ->(form) do
13
13
  rules1 = { fileType: "image/*", maxFileSize: 5000 }
14
14
  rules2 = { fileType: "image/*", maxFileSize: 1, fileTypeErrorText: 'Invalid!', maxFileSizeErrorText: 'Too big!' }
15
- form.fields_file name: 'user[photo][]', width: 'matchParent', label: 'Photo', accepts: rules1, directUploadUrl: rails_direct_uploads_url,
15
+ form.fields_file name: 'user[photo][]', width: 'matchParent', label: 'Landscape Photo', accepts: rules1, directUploadUrl: rails_direct_uploads_url,
16
16
  value: 'eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBFQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--193dc0d939b9558fc4973fafbba91d989cbb04d4',
17
17
  fileUrl: 'https://imageserver-demo.herokuapp.com/image/itinerarybuilder-demo/o6CKzNt67PWnkPdUEnWMt7pr?h=100&w=100',
18
18
  fileTitle: '1 month ago',
19
- placeholderView: { type: 'image', width: 100, height: 100 }
19
+ placeholderView: { type: 'image', width: 100, height: 75, url: 'https://www.atms.com.au/wp-content/uploads/2019/10/placeholder-1-1024x683.png?x93630' }
20
20
 
21
- form.fields_file name: 'user[photo][]', width: 'matchParent', label: 'Photo', accepts: rules2, directUploadUrl: rails_direct_uploads_url,
22
- placeholderView: { type: 'avatar', width: 100, height: 100 }
21
+ form.fields_file name: 'user[photo][]', width: 'matchParent', label: 'Avatar', accepts: rules2, directUploadUrl: rails_direct_uploads_url,
22
+ placeholderView: { type: 'avatar', width: 100, height: 100, url: 'data:image/jpeg;base64,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' }
23
23
 
24
24
  form.fields_submit text: 'Submit'
25
25
  # form.button text: 'Submit', onClick: ->(action) { action.forms_submit }
@@ -1,10 +1,20 @@
1
- json.rows do
1
+
2
+ # json.rows do
3
+ # batch_count = 30
4
+ # batch_count.times do |i|
5
+ # index = page * batch_count + i
6
+ # json.child! do
7
+ # json.template 'thumbnail'
8
+ # json.title "Item #{index}"
9
+ # end
10
+ # end
11
+ # end
12
+
13
+ section = json_ui_section json
14
+ section.rows builder: ->(row) do
2
15
  batch_count = 30
3
16
  batch_count.times do |i|
4
17
  index = page * batch_count + i
5
- json.child! do
6
- json.template 'thumbnail'
7
- json.title "Item #{index}"
8
- end
18
+ row.thumbnail title: "Item #{index}"
9
19
  end
10
20
  end
@@ -14,7 +14,7 @@ json_ui_page json do |page|
14
14
  end
15
15
  template.thumbnail title: 'Item with subtitle', subtitle: 'Item subtitle'
16
16
  template.thumbnail title: 'Item with chips', chips: ->(menu) do
17
- menu.button text: 'FInished', styleClass: 'info'
17
+ menu.button text: 'Finished', styleClass: 'info'
18
18
  menu.button props: { text: 'Succeeded', styleClass: 'success' }
19
19
  end
20
20
 
@@ -1,23 +1,5 @@
1
1
  json.title 'Notifications'
2
2
 
3
- # json.ws({
4
- # "socket" => {
5
- # "endpoint" => "/socket/websocket",
6
- # "params" => {
7
- # "vsn": "2.0.0"
8
- # }
9
- # },
10
- # # "topic" => "room:30",
11
- # # "event" => "comments_updated",
12
- # "topic" => "links",
13
- # "event" => "new_link_added",
14
- # "header" => {
15
- # "user_id" => 2,
16
- # "prev_item_id" => nil,
17
- # "last_item_id" => nil
18
- # }
19
- # })
20
-
21
3
  page = json_ui_page json
22
4
  render "#{@path_prefix}/nav_menu", json: json, page: page, top_nav: true
23
5
 
@@ -31,31 +13,6 @@ page.list firstSection: ->(section) do
31
13
 
32
14
  template.thumbnail title: 'WebSocket Real-time Update', onClick: ->(action) do
33
15
  action.windows_open url: json_ui_garage_url(path: 'notifications/web_socket')
34
- # dialogs_notification title: 'Hello World', message: 'This is a notification', onClick: ->(subaction) do
35
- # subaction.dialogs_alert message: 'Perform action'
36
- # end
37
16
  end
38
-
39
- # template.thumbnail title: 'Send WebSocket Notification', onClick: ->(action) do
40
- # json.action "ws/push"
41
- # json.topic "links"
42
- # json.event "new_link"
43
- # json.payload({
44
- # "club_id": "2",
45
- # "room_id": "30",
46
- # "user_id": "2"
47
- # # title: "TITLE",
48
- # # url: "URL"
49
- # })
50
-
51
- # # "topic": "room:30",
52
- # # "event": "create_comment",
53
- # # "payload": {
54
- # # "club_id": "2",
55
- # # "room_id": "30",
56
- # # "user_id": "2"
57
- # # }
58
-
59
- # end
60
17
  end
61
18
  end
@@ -14,4 +14,4 @@ if page_index < 3
14
14
  json.points (from.month.ago.to_date..to.month.ago.to_date).map { |d| { x: d, y: 100 + rand(40) } }
15
15
  end
16
16
  ]
17
- end
17
+ end
@@ -1,34 +1,30 @@
1
-
2
- json.events do
3
-
4
- json.child! do
5
- json.start '2018-12-14'
6
- json.end '2018-12-17'
7
- json.text 'Hackathon'
8
- json.onClick do
9
- json.action 'dialogs/alert-v1'
10
- json.message 'At Town Hall'
1
+ section = json_ui_section json
2
+ section.rows builder: ->(row) do
3
+ row.custom title: 'Hackathon',
4
+ extra: {
5
+ start: '2018-12-14',
6
+ end: '2018-12-17'
7
+ },
8
+ onClick: ->(action) do
9
+ action.dialogs_alert message: 'At Town Hall'
11
10
  end
12
- end
13
11
 
14
- json.child! do
15
- json.start '2018-12-30'
16
- json.end '2018-12-30'
17
- json.text 'Birthday'
18
- json.onClick do
19
- json.action 'dialogs/alert-v1'
20
- json.message 'At home'
12
+ row.custom title: 'Birthday',
13
+ extra: {
14
+ start: '2018-12-30',
15
+ end: '2018-12-30'
16
+ },
17
+ onClick: ->(action) do
18
+ action.dialogs_alert message: 'At home'
21
19
  end
22
- end
23
20
 
24
- json.child! do
25
- json.start '2018-12-31'
26
- json.end '2018-12-31'
27
- json.text 'Conference'
28
- json.onClick do
29
- json.action 'dialogs/alert-v1'
30
- json.message 'In Perth'
21
+ row.custom title: 'Conference',
22
+ extra: {
23
+ start: '2018-12-31',
24
+ end: '2019-01-02'
25
+ },
26
+ onClick: ->(action) do
27
+ action.dialogs_alert message: 'In Perth'
31
28
  end
32
- end
33
29
 
34
30
  end
@@ -2,5 +2,7 @@ Glib::Web::Engine.routes.draw do
2
2
  scope module: :glib do
3
3
  get 'json_ui_garage', to: 'home#json_ui_garage'
4
4
  post 'json_ui_garage', to: 'home#json_ui_garage'
5
+ patch 'json_ui_garage', to: 'home#json_ui_garage'
6
+ delete 'json_ui_garage', to: 'home#json_ui_garage'
5
7
  end
6
8
  end
@@ -5,3 +5,4 @@ require "glib/json_crawler"
5
5
 
6
6
  require 'glib/dynamic_text'
7
7
  require 'glib/crypt'
8
+ require 'glib/test_helpers'
@@ -3,9 +3,9 @@ module Glib
3
3
  class NavInitiate < ActionCrawler
4
4
  def initialize(http, args, action)
5
5
  super(http)
6
-
6
+
7
7
  @http = http
8
- if (json = @http.get args['url'], action) && (left_drawer = json['leftDrawer'])
8
+ if (json = (@http.get args['url'], action, args.except('url'))) && (left_drawer = json['leftDrawer'])
9
9
  crawl left_drawer['header']&.[]('childViews')
10
10
  crawl left_drawer['rows']
11
11
  end
@@ -4,7 +4,7 @@ module Glib
4
4
  def initialize(http, args, action)
5
5
  @http = http
6
6
  if (url = args['url'])
7
- json = @http.get url, action
7
+ json = @http.get(url, action, args.except('url'))
8
8
 
9
9
  unless json.nil?
10
10
  crawl json['header']&.[]('childViews')
@@ -12,11 +12,16 @@ module Glib
12
12
  crawl json['footer']&.[]('childViews')
13
13
 
14
14
  json['rightNavButtons']&.each do |button|
15
- click button
15
+ if button['buttons'].present?
16
+ button['buttons'].each do |inner_button|
17
+ click inner_button
18
+ end
19
+ else
20
+ click button
21
+ end
16
22
  end
17
23
  end
18
24
  end
19
-
20
25
  end
21
26
  end
22
27
  end
@@ -20,8 +20,8 @@ module Glib
20
20
  @router = router
21
21
  end
22
22
 
23
- def get(url, action, inspect_result = true)
24
- fetch(:get, url, action, {}, inspect_result)
23
+ def get(url, action, params = {}, inspect_result = true)
24
+ fetch(:get, url, action, params, inspect_result)
25
25
  end
26
26
 
27
27
  def post(url, action, params)
@@ -40,14 +40,6 @@ module Glib
40
40
  fetch(:delete, url, action, {})
41
41
  end
42
42
 
43
- def controller
44
- @context.integration_session.controller
45
- end
46
-
47
- def action_name
48
- controller.action_name.to_sym
49
- end
50
-
51
43
  private
52
44
  Response = Struct.new :code, :headers, :media_type, :body do
53
45
  def initialize(*)
@@ -66,13 +58,16 @@ module Glib
66
58
  history << url
67
59
  end
68
60
 
69
- @context.assert_match(URI_REGEXP, url)
61
+ if !URI_REGEXP.match(url)
62
+ raise "Invalid URL: `#{url}`. Make sure to use the absolute URL."
63
+ end
70
64
 
71
65
  http_header = {
72
66
  'Client-DeviceOS' => user[:device],
73
67
  'Client-Version' => user[:version],
74
68
  'X-CSRF-Token' => user[:token]
75
69
  }
70
+ http_header.merge!(params[:headers]) if params[:headers].present?
76
71
 
77
72
  params.each do |name, value|
78
73
  params[name] = '' if value.is_a?(Array) && value.size == 0
@@ -83,6 +78,10 @@ module Glib
83
78
  @context.send(method, url, params: params, headers: http_header)
84
79
  raw_response = @context.response
85
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
86
85
  rescue => ex
87
86
  if !inspect_result
88
87
  case ex
@@ -103,7 +102,7 @@ module Glib
103
102
  if (code = response.code) == 302
104
103
  redirect_uri = URI(response.headers['Location'])
105
104
  redirect_uri.query = [redirect_uri.query, 'format=json'].compact.join('&')
106
- get redirect_uri.to_s, action
105
+ get redirect_uri.to_s, action, params
107
106
  else
108
107
  response_times << response.headers['X-Runtime'].to_f
109
108
  @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}"
@@ -19,10 +19,6 @@ module Glib
19
19
  end
20
20
 
21
21
  def step(http, args)
22
- if (controller = http.controller)
23
- Glib::JsonCrawler::Coverage.coverage_files.add(controller.class.instance_method(http.action_name).source_location.first)
24
- end
25
-
26
22
  case args['view']
27
23
  when 'fields/submit-v1', 'fields/submit'
28
24
  @depth += 1
@@ -73,7 +69,7 @@ module Glib
73
69
  @depth += 1
74
70
  target_router.read_only_actions.each do |crawler_action|
75
71
  action, url = crawler_action
76
- http.get url, action, false
72
+ http.get(url, action, {}, false)
77
73
  end
78
74
  end
79
75
 
@@ -0,0 +1,40 @@
1
+ module Glib
2
+ module TestHelpers
3
+ def response_assert_equal
4
+ expected = __get_previous_result_from_git
5
+ result = __log(response.body)
6
+ assert_equal JSON.parse(expected), JSON.parse(result), "Result mismatch! #{__git_is_available? ? `git diff #{__log_dir}/#{__log_file}` : ''}"
7
+ end
8
+
9
+ private
10
+ def __git_is_available?
11
+ @__git_is_available ||= (`git status 2>&1` =~ /fatal/).nil?
12
+ end
13
+
14
+ def __log_dir
15
+ if @__log_dir.nil?
16
+ @__log_dir = File.expand_path("#{Rails.root}/test/controllers/#{self.class.to_s.underscore}_results", File.dirname(__FILE__))
17
+ unless File.directory?(@__log_dir)
18
+ FileUtils.mkdir_p(@__log_dir)
19
+ end
20
+ end
21
+ @__log_dir
22
+ end
23
+
24
+ def __log_file
25
+ @__log_file ||= "#{self.method_name}.json"
26
+ end
27
+
28
+ def __log json
29
+ File.open("#{File.join(__log_dir, __log_file)}", "w") do |f|
30
+ f << JSON.pretty_generate( JSON.parse(json) )
31
+ end
32
+ json
33
+ end
34
+
35
+ def __get_previous_result_from_git
36
+ `git checkout -- "#{File.join(__log_dir, __log_file)}" > /dev/null 2>&1` if __git_is_available?
37
+ File.exists?(File.join(__log_dir, __log_file)) ? File.open(File.join(__log_dir, __log_file)).read : "\{\}"
38
+ end
39
+ end
40
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glib-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.74
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''
@@ -79,6 +79,7 @@ files:
79
79
  - app/helpers/glib/json_ui/abstract_builder.rb
80
80
  - app/helpers/glib/json_ui/action_builder.rb
81
81
  - app/helpers/glib/json_ui/action_builder/dialogs.rb
82
+ - app/helpers/glib/json_ui/action_builder/http.rb
82
83
  - app/helpers/glib/json_ui/action_builder/sheets.rb
83
84
  - app/helpers/glib/json_ui/action_builder/snackbars.rb
84
85
  - app/helpers/glib/json_ui/action_builder/windows.rb
@@ -107,10 +108,13 @@ files:
107
108
  - app/views/app/views/json_ui/vue/renderer.html.erb
108
109
  - app/views/json_ui/garage/_nav_menu.json.jbuilder
109
110
  - app/views/json_ui/garage/actions/_dialogs.json.jbuilder
111
+ - app/views/json_ui/garage/actions/_http.json.jbuilder
112
+ - app/views/json_ui/garage/actions/_reload.json.jbuilder
110
113
  - app/views/json_ui/garage/actions/_sheets.json.jbuilder
111
114
  - app/views/json_ui/garage/actions/_snackbars.json.jbuilder
112
115
  - app/views/json_ui/garage/actions/_timeouts.json.jbuilder
113
116
  - app/views/json_ui/garage/actions/_windows.json.jbuilder
117
+ - app/views/json_ui/garage/actions/dialogs_oauth_post.json.jbuilder
114
118
  - app/views/json_ui/garage/actions/index.json.jbuilder
115
119
  - app/views/json_ui/garage/forms/_alert_post_data.json.jbuilder
116
120
  - app/views/json_ui/garage/forms/basic.json.jbuilder
@@ -209,6 +213,7 @@ files:
209
213
  - lib/glib/json_crawler/coverage.rb
210
214
  - lib/glib/json_crawler/http.rb
211
215
  - lib/glib/json_crawler/router.rb
216
+ - lib/glib/test_helpers.rb
212
217
  - lib/glib/value.rb
213
218
  - lib/glib/version.rb
214
219
  - lib/tasks/db.rake