decko 0.6.0 → 0.6.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c2c0b62be6973d42ca0313378dbbc42161349f30
4
- data.tar.gz: 065f3de25caebaa321a6170cdae58a7471456cb5
3
+ metadata.gz: aeacf2fbbf0981f2cee104c70ae92aa444ebaac7
4
+ data.tar.gz: f1eb236d57cf919828baeea2ee765b96a7d42fa1
5
5
  SHA512:
6
- metadata.gz: 75874b945a5c272db5bbbce646ecd8f866a80bb9dad9933caaaefcc6204b177288929e7166eca04339fae2a7b3c37f20cb47411f322607ba8cc4950039c3ed8f
7
- data.tar.gz: 20fd9ae8f95b4583d10f57fc3c6621d7d955daa4ea09ef977076e10e4feef9560db96bf20a9ed2e89db1a8c0893095855de96ab9364b50d89a9f1ef002dace22
6
+ metadata.gz: d877cc738c99466edc35464b075ea017bfe1fe48d2c322767c190ae2a61627c17cb59fcf0f9d91d20e784f809ccbc7e804ab0c2757450711c5b94f13082c853d
7
+ data.tar.gz: db58b0aecd2e3f1a9a59b714ff2925ade4bc3b64218fad93185f4df246cf0850be88dd13b2056787ba9087a226eb3e9ecba8fcba25fa5fb00b8579b0a712eda3
@@ -2,7 +2,22 @@ module Decko
2
2
  # methods for managing decko responses
3
3
  module Response
4
4
  private
5
- def card_redirect url
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
- def deliver format, result, status
18
- if status == 302
19
- card_redirect result
20
- elsif format.is_a?(Card::Format::FileFormat) && status == 200
21
- send_file(*result)
22
- else
23
- render body: result.to_s.html_safe,
24
- status: status,
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 reset_card new_card
30
- @card = new_card
31
- update_params_for_success
32
- @card.select_action_by_params params
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 update_params_for_success
36
- success = Card::Env.success
37
- Card::Env[:params] =
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[:filename], params[:format]].join(".")
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
- def format_from_params card
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
- return :file if params[:explicit_file]
56
- format = request.format
57
- # format = request.parameters[:format]
58
- # unknown format
59
- return :file unless Card::Format.registered.member?(format)
60
- format.to_sym
61
- end
62
-
63
- def interpret_id id
64
- case id
65
- when "*previous" then
66
- return card_redirect(Card::Env.previous_location)
67
- when nil then
68
- determine_id
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
- validate_id_encoding id
88
+ explicit_mark mark
71
89
  end
72
90
  end
73
91
 
74
- def determine_id
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 prompt_setup?
77
- prepare_setup_card!
78
- when params[:card] && params[:card][:name]
79
- params[:card][:name]
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 prompt_setup?
88
- Card::Auth.needs_setup? && Card::Env.html?
106
+ def home_mark
107
+ Card.global_setting(:home) || "Home"
89
108
  end
90
109
 
91
- def prepare_setup_card!
92
- params[:card] = { type_id: Card.default_accounted_type_id }
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
- def validate_id_encoding id
98
- # we should find the place where we produce these bad urls
99
- id.valid_encoding? ? id : id.force_encoding("ISO-8859-1").encode("UTF-8")
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 use_draft?
103
- params[:edit_draft] && card.drafts.present?
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 :load_id, only: [:read]
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 load_id
68
- params[:id] = interpret_id params[:id]
67
+ def load_mark
68
+ params[:mark] = interpret_mark params[:mark]
69
69
  end
70
70
 
71
71
  def load_card
72
- @card = Card.controller_fetch params
73
- raise Card::Error::NotFound unless @card
74
- load_action
75
- record_as_main
76
- card.errors.any? ? render_errors : true
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
- @card.select_action_by_params params
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
- success.name_context = @card.name
102
- if !Card::Env.ajax? || success.hard_redirect?
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
- reset_card success.target
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
- card.content = card.last_draft_content if use_draft?
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
- deliver format, result, status
125
+ respond format, result, status
120
126
  end
121
127
 
122
128
  def render_page format, view
@@ -1,55 +1,49 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
3
  Decko::Engine.routes.draw do
4
- # most common
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
- match ":id(.:format)" => "card#create", via: :post
24
- match ":id(.:format)" => "card#update", via: :put
25
- match ":id(.:format)" => "card#delete", via: :delete
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
- get ":id/view/:view(.:format)" => "card#read"
18
+ # Standard GET requests
19
+ get "(/wagn)/:mark(.:format)" => "card#read" # /wagn is deprecated
28
20
 
29
- # ~~~~~~~~~~~~~~~~~~~~~~~~~~
30
- # legacy
31
- get "new/:type" => "card#read", view: "new"
32
- get "card/:view(/:id(.:format))" => "card#read", view: /new|edit/
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
- get "account/signin" => "card#read", id: ":signin"
35
- get "account/signout" => "card#delete", id: ":signin"
36
- get "account/signup" => "card#read", view: "new", card: { type_code: :signup }
37
- get "account/invite" => "card#read", view: "new", card: { type_code: :signup }
38
- get "account/accept" => "card#read", view: "edit", card: { type_code: :signup }
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
- get "admin/stats" => "card#read", id: ":admin"
42
- get "admin/:task" => "card#update", id: ":admin"
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
- # standard non-RESTful
37
+ # explicit GET alternatives for transactions
46
38
  %w[create read update delete asset].each do |action|
47
- get "(card)/#{action}(/:id(.:format))" => "card", action: action
39
+ get "(card)/#{action}(/:mark(.:format))" => "card", action: action
48
40
  end
49
41
 
50
- match "(card)/create(/:id(.:format))" => "card#create", via: [:post, :patch]
51
- match "(card)/update(/:id(.:format))" => "card#update", via: [:post, :put, :patch]
52
- match "(card)/delete(/:id(.:format))" => "card#delete", via: :delete
53
- # other
54
- get "*id" => "card#read", view: "bad_address"
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.0
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-07-23 00:00:00.000000000 Z
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.0
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.0
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