decko 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/decko/response.rb +80 -57
- data/lib/decko/rest_spec_helper.rb +22 -0
- data/rails/controllers/card_controller.rb +28 -22
- data/rails/engine-routes.rb +35 -41
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aeacf2fbbf0981f2cee104c70ae92aa444ebaac7
|
4
|
+
data.tar.gz: f1eb236d57cf919828baeea2ee765b96a7d42fa1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d877cc738c99466edc35464b075ea017bfe1fe48d2c322767c190ae2a61627c17cb59fcf0f9d91d20e784f809ccbc7e804ab0c2757450711c5b94f13082c853d
|
7
|
+
data.tar.gz: db58b0aecd2e3f1a9a59b714ff2925ade4bc3b64218fad93185f4df246cf0850be88dd13b2056787ba9087a226eb3e9ecba8fcba25fa5fb00b8579b0a712eda3
|
data/lib/decko/response.rb
CHANGED
@@ -2,7 +2,22 @@ module Decko
|
|
2
2
|
# methods for managing decko responses
|
3
3
|
module Response
|
4
4
|
private
|
5
|
-
def
|
5
|
+
def respond format, result, status
|
6
|
+
if status == 302
|
7
|
+
hard_redirect result
|
8
|
+
elsif format.is_a?(Card::Format::FileFormat) && status == 200
|
9
|
+
send_file(*result)
|
10
|
+
else
|
11
|
+
render_response result.to_s.html_safe, status, format.mime_type
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def render_response body, status, content_type
|
16
|
+
render body: body, status: status, content_type: content_type
|
17
|
+
end
|
18
|
+
|
19
|
+
# return a redirect response
|
20
|
+
def hard_redirect url
|
6
21
|
url = card_url url # make sure we have absolute url
|
7
22
|
if Card::Env.ajax?
|
8
23
|
# lets client reset window location
|
@@ -14,93 +29,101 @@ module Decko
|
|
14
29
|
end
|
15
30
|
end
|
16
31
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
content_type: format.mime_type
|
26
|
-
end
|
32
|
+
# return a standard GET response directly.
|
33
|
+
# Used in AJAX situations where PRG pattern is unwieldy
|
34
|
+
def soft_redirect success
|
35
|
+
@card = success.target
|
36
|
+
require_card_for_soft_redirect!
|
37
|
+
self.params = Card::Env[:params] = soft_redirect_params
|
38
|
+
load_action
|
39
|
+
show
|
27
40
|
end
|
28
41
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
42
|
+
def soft_redirect_params
|
43
|
+
new_params = params.clone
|
44
|
+
new_params.delete :card
|
45
|
+
new_params.delete :action
|
46
|
+
new_params.merge Card::Env.success.params
|
33
47
|
end
|
34
48
|
|
35
|
-
def
|
36
|
-
|
37
|
-
Card::
|
38
|
-
self.params =
|
39
|
-
success.soft_redirect? ? success.params : params.merge(success.params)
|
49
|
+
def require_card_for_soft_redirect!
|
50
|
+
return if card.is_a? Card
|
51
|
+
raise Card::Error, "tried to do soft redirect without a card"
|
40
52
|
end
|
41
53
|
|
54
|
+
# (obviously) deprecated
|
42
55
|
def send_deprecated_asset
|
43
|
-
filename = [params[:
|
56
|
+
filename = [params[:mark], params[:format]].join(".")
|
44
57
|
# for security, block relative paths
|
45
58
|
raise Card::Error::BadAddress if filename.include? "../"
|
46
59
|
path = Decko::Engine.paths["gem-assets"].existent.first
|
47
60
|
send_file File.join(path, filename), x_sendfile: true
|
48
61
|
end
|
49
62
|
|
50
|
-
|
63
|
+
# TODO: everything below should go in a separate file
|
64
|
+
# below is about beginning (initialization). above is about end (response)
|
65
|
+
# Both this file and that would make sense as submodules of CardController
|
66
|
+
|
67
|
+
def load_format
|
68
|
+
request.format = :html if Card::Env.ajax? && !params[:format]
|
51
69
|
card.format format_name_from_params
|
52
70
|
end
|
53
71
|
|
54
72
|
def format_name_from_params
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
return
|
67
|
-
when nil
|
68
|
-
|
73
|
+
explicit_file_format? ? :file : request.format.to_sym
|
74
|
+
end
|
75
|
+
|
76
|
+
def explicit_file_format?
|
77
|
+
params[:explicit_file] || !Card::Format.registered.member?(request.format)
|
78
|
+
end
|
79
|
+
|
80
|
+
def interpret_mark mark
|
81
|
+
case mark
|
82
|
+
when "*previous"
|
83
|
+
# Why support this? It's only needed in Success, right? Deprecate?
|
84
|
+
return hard_redirect(Card::Env.previous_location)
|
85
|
+
when nil
|
86
|
+
implicit_mark
|
69
87
|
else
|
70
|
-
|
88
|
+
explicit_mark mark
|
71
89
|
end
|
72
90
|
end
|
73
91
|
|
74
|
-
def
|
92
|
+
def explicit_mark mark
|
93
|
+
# we should find the place where we produce these bad urls
|
94
|
+
mark.valid_encoding? ? mark : mark.force_encoding("ISO-8859-1").encode("UTF-8")
|
95
|
+
end
|
96
|
+
|
97
|
+
def implicit_mark
|
75
98
|
case
|
76
|
-
when
|
77
|
-
|
78
|
-
when
|
79
|
-
|
80
|
-
when Card::Format.tagged(params[:view], :unknown_ok)
|
81
|
-
""
|
82
|
-
else
|
83
|
-
Card.global_setting(:home) || "Home"
|
99
|
+
when initial_setup then ""
|
100
|
+
when (name = params.dig :card, :name) then name
|
101
|
+
when view_does_not_require_name? then ""
|
102
|
+
else home_mark
|
84
103
|
end
|
85
104
|
end
|
86
105
|
|
87
|
-
def
|
88
|
-
Card
|
106
|
+
def home_mark
|
107
|
+
Card.global_setting(:home) || "Home"
|
89
108
|
end
|
90
109
|
|
91
|
-
def
|
92
|
-
params[:
|
93
|
-
params[:view] = "setup"
|
94
|
-
""
|
110
|
+
def view_does_not_require_name?
|
111
|
+
Card::Format.tagged params[:view], :unknown_ok
|
95
112
|
end
|
96
113
|
|
97
|
-
|
98
|
-
|
99
|
-
|
114
|
+
# alters params
|
115
|
+
def initial_setup
|
116
|
+
return unless initial_setup?
|
117
|
+
prepare_setup_card!
|
118
|
+
end
|
119
|
+
|
120
|
+
def initial_setup?
|
121
|
+
Card::Auth.needs_setup? && Card::Env.html?
|
100
122
|
end
|
101
123
|
|
102
|
-
def
|
103
|
-
params[:
|
124
|
+
def prepare_setup_card!
|
125
|
+
params[:card] = { type_id: Card.default_accounted_type_id }
|
126
|
+
params[:view] = "setup"
|
104
127
|
end
|
105
128
|
end
|
106
129
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
module Decko
|
4
|
+
# for use in REST API specs
|
5
|
+
module RestSpecMethods
|
6
|
+
def with_token_for usermark
|
7
|
+
yield Card[usermark].account.reset_token
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# for use in REST API specs
|
12
|
+
module RestSpecHelper
|
13
|
+
def self.describe_api &block
|
14
|
+
RSpec.describe CardController, type: :controller do
|
15
|
+
routes { Decko::Engine.routes }
|
16
|
+
include Capybara::DSL
|
17
|
+
include RestSpecMethods
|
18
|
+
instance_eval(&block)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -49,37 +49,43 @@ class CardController < ActionController::Base
|
|
49
49
|
|
50
50
|
before_action :setup, except: [:asset]
|
51
51
|
before_action :authenticate, except: [:asset]
|
52
|
-
before_action :
|
52
|
+
before_action :load_mark, only: [:read]
|
53
53
|
before_action :load_card, except: [:asset]
|
54
|
+
before_action :load_action, only: [:read]
|
54
55
|
before_action :refresh_card, only: [:create, :update, :delete]
|
55
56
|
|
56
57
|
def setup
|
57
58
|
Card::Machine.refresh_script_and_style unless params[:explicit_file]
|
58
59
|
Card::Cache.renew
|
59
60
|
Card::Env.reset controller: self
|
60
|
-
request.format = :html if Card::Env.ajax? && !params[:format]
|
61
61
|
end
|
62
62
|
|
63
63
|
def authenticate
|
64
64
|
Card::Auth.set_current params[:token], params[:current]
|
65
65
|
end
|
66
66
|
|
67
|
-
def
|
68
|
-
params[:
|
67
|
+
def load_mark
|
68
|
+
params[:mark] = interpret_mark params[:mark]
|
69
69
|
end
|
70
70
|
|
71
71
|
def load_card
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
72
|
+
handle_errors do
|
73
|
+
@card = Card.controller_fetch params
|
74
|
+
raise Card::Error::NotFound unless card
|
75
|
+
record_as_main
|
76
|
+
end
|
77
77
|
end
|
78
78
|
|
79
79
|
def load_action
|
80
|
-
|
80
|
+
handle_errors do
|
81
|
+
card.select_action_by_params params
|
82
|
+
if params[:edit_draft] && card.drafts.present?
|
83
|
+
card.content = card.last_draft_content
|
84
|
+
end
|
85
|
+
end
|
81
86
|
end
|
82
87
|
|
88
|
+
# TODO: refactor this away this when new layout handling is ready
|
83
89
|
def record_as_main
|
84
90
|
Card::Env[:main_name] = params[:main] || card&.name || ""
|
85
91
|
end
|
@@ -96,27 +102,27 @@ class CardController < ActionController::Base
|
|
96
102
|
end
|
97
103
|
end
|
98
104
|
|
105
|
+
def handle_errors
|
106
|
+
yield
|
107
|
+
card.errors.any? ? render_errors : true
|
108
|
+
end
|
109
|
+
|
110
|
+
# successful create, update, or delete action
|
99
111
|
def render_success
|
100
|
-
success = Card::Env.success
|
101
|
-
|
102
|
-
|
103
|
-
card_redirect success.to_url
|
104
|
-
elsif success.target.is_a? String
|
105
|
-
render plain: success.target
|
112
|
+
success = Card::Env.success.in_context card.name
|
113
|
+
if Card::Env.ajax? && !success.hard_redirect?
|
114
|
+
soft_redirect success
|
106
115
|
else
|
107
|
-
|
108
|
-
show
|
116
|
+
hard_redirect success.to_url
|
109
117
|
end
|
110
118
|
end
|
111
119
|
|
112
120
|
def show view=nil, status=200
|
113
121
|
card.action = :read
|
114
|
-
|
115
|
-
|
116
|
-
format = format_from_params card
|
122
|
+
format = load_format
|
117
123
|
result = render_page format, view
|
118
124
|
status = format.error_status || status
|
119
|
-
|
125
|
+
respond format, result, status
|
120
126
|
end
|
121
127
|
|
122
128
|
def render_page format, view
|
data/rails/engine-routes.rb
CHANGED
@@ -1,55 +1,49 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
|
3
3
|
Decko::Engine.routes.draw do
|
4
|
-
|
4
|
+
files = Decko::Engine.config.files_web_path
|
5
|
+
file_matchers = { mark: /[^-]+/, explicit_file: true, rev_id: /[^-]+/ }
|
6
|
+
|
5
7
|
root "card#read"
|
6
|
-
get "#{Decko::Engine.config.files_web_path}/:id/:rev_id(-:size).:format" =>
|
7
|
-
"card#read", id: /[^-]+/, rev_id: /[^-]+/, explicit_file: true
|
8
|
-
get "#{Decko::Engine.config.files_web_path}/:id(-:size)-:rev_id.:format" =>
|
9
|
-
"card#read", id: /[^-]+/, explicit_file: true # deprecated
|
10
|
-
get "assets/*filename" => "card#asset"
|
11
|
-
get "javascripts/*filename" => "card#asset"
|
12
|
-
get "jasmine/*filename" => "card#asset"
|
13
|
-
|
14
|
-
get "recent(.:format)" => "card#read", id: ":recent" # obviate by making links use codename
|
15
|
-
# match ':view:(:id(.:format))' => 'card#read', via: :get
|
16
|
-
get "(/wagn)/:id(.:format)" => "card#read" # /wagn is deprecated
|
17
|
-
|
18
|
-
# RESTful
|
19
|
-
post "/" => "card#create"
|
20
|
-
put "/" => "card#update"
|
21
|
-
delete "/" => "card#delete"
|
22
8
|
|
23
|
-
|
24
|
-
|
25
|
-
|
9
|
+
# explicit file request
|
10
|
+
get({ "#{files}/:mark/:rev_id(-:size).:format" => "card#read" }.merge(file_matchers))
|
11
|
+
|
12
|
+
# DEPRECATED (old file and asset requests)
|
13
|
+
get({ "#{files}/:mark(-:size)-:rev_id.:format" => "card#read" }.merge(file_matchers))
|
14
|
+
%w[assets javascripts jasmine].each do |prefix|
|
15
|
+
get "#{prefix}/*mark" => "card#asset"
|
16
|
+
end
|
26
17
|
|
27
|
-
|
18
|
+
# Standard GET requests
|
19
|
+
get "(/wagn)/:mark(.:format)" => "card#read" # /wagn is deprecated
|
28
20
|
|
29
|
-
#
|
30
|
-
#
|
31
|
-
get "
|
32
|
-
get "card/:view(/:
|
21
|
+
# Alternate GET requests
|
22
|
+
get "new/:type" => "card#read", view: "new" # common case for card without mark
|
23
|
+
get ":mark/view/:view(.:format)" => "card#read" # simplifies API documentation
|
24
|
+
get "card/:view(/:mark(.:format))" => "card#read", view: /new|edit/ # legacy
|
33
25
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
# use type_code rather than id because in some cases (eg populating test data) routes must get loaded without loading Card
|
26
|
+
# RESTful (without mark)
|
27
|
+
post "/" => "card#create"
|
28
|
+
put "/" => "card#update"
|
29
|
+
patch "/" => "card#update"
|
30
|
+
delete "/" => "card#delete"
|
40
31
|
|
41
|
-
|
42
|
-
|
43
|
-
#
|
32
|
+
# RESTful (with mark)
|
33
|
+
match ":mark(.:format)" => "card#create", via: :post
|
34
|
+
match ":mark(.:format)" => "card#update", via: %i[put patch]
|
35
|
+
match ":mark(.:format)" => "card#delete", via: :delete
|
44
36
|
|
45
|
-
#
|
37
|
+
# explicit GET alternatives for transactions
|
46
38
|
%w[create read update delete asset].each do |action|
|
47
|
-
get "(card)/#{action}(/:
|
39
|
+
get "(card)/#{action}(/:mark(.:format))" => "card", action: action
|
48
40
|
end
|
49
41
|
|
50
|
-
|
51
|
-
match "(card)/
|
52
|
-
match "(card)/
|
53
|
-
#
|
54
|
-
|
42
|
+
# for super-explicit over-achievers
|
43
|
+
match "(card)/create(/:mark(.:format))" => "card#create", via: %i[post patch]
|
44
|
+
match "(card)/update(/:mark(.:format))" => "card#update", via: %i[post put patch]
|
45
|
+
match "(card)/delete(/:mark(.:format))" => "card#delete", via: :delete
|
46
|
+
|
47
|
+
# Wildcard for bad addresses
|
48
|
+
get "*mark" => "card#read", view: "bad_address"
|
55
49
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: decko
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ethan McCutchen
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2018-
|
14
|
+
date: 2018-08-20 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: card
|
@@ -19,14 +19,14 @@ dependencies:
|
|
19
19
|
requirements:
|
20
20
|
- - '='
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 1.96.
|
22
|
+
version: 1.96.1
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - '='
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 1.96.
|
29
|
+
version: 1.96.1
|
30
30
|
description: a wiki approach to stuctured data, dynamic interaction, and web design
|
31
31
|
email:
|
32
32
|
- info@decko.org
|
@@ -113,6 +113,7 @@ files:
|
|
113
113
|
- lib/decko/generators/decko/templates/spec/spec_helper.rb
|
114
114
|
- lib/decko/mods_spec_helper.rb
|
115
115
|
- lib/decko/response.rb
|
116
|
+
- lib/decko/rest_spec_helper.rb
|
116
117
|
- lib/decko/script_decko_loader.rb
|
117
118
|
- lib/decko/tasks/alias.rb
|
118
119
|
- lib/decko/tasks/cucumber.rake
|