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.
- checksums.yaml +4 -4
- data/app/controllers/concerns/glib/json/libs.rb +30 -7
- data/app/controllers/glib/home_controller.rb +1 -1
- data/app/helpers/glib/json_ui/action_builder.rb +0 -18
- data/app/helpers/glib/json_ui/action_builder/http.rb +19 -0
- data/app/helpers/glib/json_ui/list_builders.rb +5 -0
- data/app/helpers/glib/json_ui/menu_builder.rb +1 -0
- data/app/helpers/glib/json_ui/page_helper.rb +21 -16
- data/app/views/json_ui/garage/actions/_dialogs.json.jbuilder +21 -12
- data/app/views/json_ui/garage/actions/_http.json.jbuilder +18 -0
- data/app/views/json_ui/garage/actions/_reload.json.jbuilder +17 -0
- data/app/views/json_ui/garage/actions/dialogs_oauth_post.json.jbuilder +6 -0
- data/app/views/json_ui/garage/actions/index.json.jbuilder +3 -18
- data/app/views/json_ui/garage/forms/dynamic_select_data.json.jbuilder +25 -10
- data/app/views/json_ui/garage/forms/file_upload.json.jbuilder +5 -5
- data/app/views/json_ui/garage/lists/_infinite_scroll_section.json.jbuilder +15 -5
- data/app/views/json_ui/garage/lists/templating.json.jbuilder +1 -1
- data/app/views/json_ui/garage/notifications/index.json.jbuilder +0 -43
- data/app/views/json_ui/garage/views/_chart_data.json.jbuilder +1 -1
- data/app/views/json_ui/garage/views/calendar_data.json.jbuilder +23 -27
- data/config/routes.rb +2 -0
- data/lib/glib-web.rb +1 -0
- data/lib/glib/json_crawler/action_crawlers/nav_initiate.rb +2 -2
- data/lib/glib/json_crawler/action_crawlers/windows_open.rb +8 -3
- data/lib/glib/json_crawler/http.rb +11 -12
- data/lib/glib/json_crawler/router.rb +1 -5
- data/lib/glib/test_helpers.rb +40 -0
- metadata +6 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c258b37bbad81871f329c41e5b854b5b6563fb4f
|
4
|
+
data.tar.gz: 3e8d5f94006a46084869252b667d0c9e405de569
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
50
|
-
|
51
|
-
|
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
|
-
|
115
|
-
|
116
|
-
|
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
|
@@ -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
|
@@ -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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
action.
|
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
|
@@ -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
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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:
|
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: '
|
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
|
-
|
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
|
-
|
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: '
|
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
|
@@ -1,34 +1,30 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
data/config/routes.rb
CHANGED
@@ -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
|
data/lib/glib-web.rb
CHANGED
@@ -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
|
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
|
-
|
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,
|
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
|
-
|
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
|
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
|
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
|