praxis 0.22.pre.1 → 2.0.pre.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +5 -20
- data/CHANGELOG.md +328 -323
- data/lib/praxis.rb +13 -9
- data/lib/praxis/action_definition.rb +8 -10
- data/lib/praxis/action_definition/headers_dsl_compiler.rb +1 -1
- data/lib/praxis/api_definition.rb +27 -44
- data/lib/praxis/api_general_info.rb +2 -3
- data/lib/praxis/application.rb +15 -142
- data/lib/praxis/bootloader.rb +1 -2
- data/lib/praxis/bootloader_stages/environment.rb +13 -0
- data/lib/praxis/config.rb +1 -1
- data/lib/praxis/controller.rb +0 -2
- data/lib/praxis/dispatcher.rb +4 -6
- data/lib/praxis/docs/generator.rb +8 -18
- data/lib/praxis/docs/link_builder.rb +1 -1
- data/lib/praxis/error_handler.rb +5 -5
- data/lib/praxis/extensions/attribute_filtering/active_record_filter_query_builder.rb +1 -1
- data/lib/praxis/extensions/attribute_filtering/filtering_params.rb +1 -1
- data/lib/praxis/extensions/attribute_filtering/sequel_filter_query_builder.rb +125 -0
- data/lib/praxis/extensions/field_selection.rb +1 -12
- data/lib/praxis/extensions/field_selection/active_record_query_selector.rb +28 -34
- data/lib/praxis/extensions/field_selection/sequel_query_selector.rb +35 -39
- data/lib/praxis/extensions/rendering.rb +1 -1
- data/lib/praxis/file_group.rb +1 -1
- data/lib/praxis/handlers/xml.rb +1 -1
- data/lib/praxis/mapper/active_model_compat.rb +98 -0
- data/lib/praxis/mapper/resource.rb +242 -0
- data/lib/praxis/mapper/selector_generator.rb +154 -0
- data/lib/praxis/mapper/sequel_compat.rb +76 -0
- data/lib/praxis/media_type_identifier.rb +2 -1
- data/lib/praxis/middleware_app.rb +13 -15
- data/lib/praxis/multipart/part.rb +3 -5
- data/lib/praxis/notifications.rb +1 -1
- data/lib/praxis/plugins/mapper_plugin.rb +64 -0
- data/lib/praxis/request.rb +14 -7
- data/lib/praxis/request_stages/response.rb +2 -3
- data/lib/praxis/resource_definition.rb +15 -19
- data/lib/praxis/response.rb +6 -5
- data/lib/praxis/response_definition.rb +5 -7
- data/lib/praxis/response_template.rb +3 -4
- data/lib/praxis/responses/http.rb +36 -0
- data/lib/praxis/responses/internal_server_error.rb +12 -3
- data/lib/praxis/responses/multipart_ok.rb +11 -4
- data/lib/praxis/responses/validation_error.rb +10 -1
- data/lib/praxis/route.rb +1 -1
- data/lib/praxis/router.rb +3 -3
- data/lib/praxis/routing_config.rb +1 -1
- data/lib/praxis/tasks/api_docs.rb +2 -10
- data/lib/praxis/tasks/routes.rb +0 -1
- data/lib/praxis/trait.rb +1 -1
- data/lib/praxis/types/media_type_common.rb +2 -2
- data/lib/praxis/types/multipart.rb +1 -1
- data/lib/praxis/types/multipart_array.rb +2 -2
- data/lib/praxis/types/multipart_array/part_definition.rb +1 -1
- data/lib/praxis/version.rb +1 -1
- data/praxis.gemspec +11 -9
- data/spec/functional_spec.rb +0 -1
- data/spec/praxis/action_definition_spec.rb +16 -27
- data/spec/praxis/api_definition_spec.rb +8 -13
- data/spec/praxis/api_general_info_spec.rb +8 -3
- data/spec/praxis/application_spec.rb +8 -14
- data/spec/praxis/collection_spec.rb +3 -2
- data/spec/praxis/config_spec.rb +2 -2
- data/spec/praxis/extensions/field_selection/active_record_query_selector_spec.rb +106 -0
- data/spec/praxis/extensions/field_selection/sequel_query_selector_spec.rb +147 -0
- data/spec/praxis/extensions/field_selection/support/spec_resources_active_model.rb +130 -0
- data/spec/praxis/extensions/field_selection/support/spec_resources_sequel.rb +106 -0
- data/spec/praxis/handlers/xml_spec.rb +2 -2
- data/spec/praxis/mapper/resource_spec.rb +169 -0
- data/spec/praxis/mapper/selector_generator_spec.rb +325 -0
- data/spec/praxis/media_type_spec.rb +0 -10
- data/spec/praxis/middleware_app_spec.rb +16 -10
- data/spec/praxis/request_spec.rb +7 -17
- data/spec/praxis/request_stages/action_spec.rb +8 -1
- data/spec/praxis/request_stages/validate_spec.rb +1 -1
- data/spec/praxis/resource_definition_spec.rb +10 -12
- data/spec/praxis/response_definition_spec.rb +12 -26
- data/spec/praxis/response_spec.rb +6 -13
- data/spec/praxis/responses/internal_server_error_spec.rb +5 -2
- data/spec/praxis/router_spec.rb +5 -9
- data/spec/spec_app/app/controllers/instances.rb +1 -1
- data/spec/spec_app/config.ru +6 -1
- data/spec/spec_app/config/environment.rb +3 -21
- data/spec/spec_helper.rb +13 -17
- data/spec/support/be_deep_equal_matcher.rb +39 -0
- data/spec/support/spec_resources.rb +124 -0
- metadata +74 -53
- data/lib/praxis/extensions/attribute_filtering.rb +0 -28
- data/lib/praxis/extensions/attribute_filtering/query_builder.rb +0 -39
- data/lib/praxis/extensions/mapper_selectors.rb +0 -16
- data/lib/praxis/media_type_collection.rb +0 -127
- data/lib/praxis/plugins/praxis_mapper_plugin.rb +0 -246
- data/spec/praxis/media_type_collection_spec.rb +0 -157
- data/spec/praxis/plugins/praxis_mapper_plugin_spec.rb +0 -142
- data/spec/spec_app/app/models/person.rb +0 -3
@@ -4,9 +4,8 @@ module Praxis
|
|
4
4
|
|
5
5
|
class ResponseDefinition
|
6
6
|
attr_reader :name
|
7
|
-
|
8
|
-
|
9
|
-
def initialize(response_name, application, **spec, &block)
|
7
|
+
|
8
|
+
def initialize(response_name, **spec, &block)
|
10
9
|
unless response_name
|
11
10
|
raise Exceptions::InvalidConfiguration.new(
|
12
11
|
"Response name is required for a response specification"
|
@@ -14,7 +13,6 @@ module Praxis
|
|
14
13
|
end
|
15
14
|
@spec = { headers:{} }
|
16
15
|
@name = response_name
|
17
|
-
@application = application
|
18
16
|
self.instance_exec(**spec, &block) if block_given?
|
19
17
|
|
20
18
|
if self.status.nil?
|
@@ -143,9 +141,9 @@ module Praxis
|
|
143
141
|
# FIXME: remove load when when MediaTypeCommon.identifier returns a MediaTypeIdentifier
|
144
142
|
identifier = MediaTypeIdentifier.load(self.media_type.identifier)
|
145
143
|
|
146
|
-
default_handlers =
|
144
|
+
default_handlers = ApiDefinition.instance.info.produces
|
147
145
|
|
148
|
-
handlers =
|
146
|
+
handlers = Praxis::Application.instance.handlers.select do |k,v|
|
149
147
|
default_handlers.include?(k)
|
150
148
|
end
|
151
149
|
|
@@ -202,7 +200,7 @@ module Praxis
|
|
202
200
|
raise ArgumentError, "Parts definition for response #{name} does not allow :like and a block simultaneously"
|
203
201
|
end
|
204
202
|
if like
|
205
|
-
template =
|
203
|
+
template = ApiDefinition.instance.response(like)
|
206
204
|
@parts = template.compile(nil, **args)
|
207
205
|
else # block
|
208
206
|
@parts = Praxis::ResponseDefinition.new('anonymous', **args, &a_proc)
|
@@ -1,12 +1,11 @@
|
|
1
1
|
module Praxis
|
2
2
|
|
3
3
|
class ResponseTemplate
|
4
|
-
attr_reader :name, :block
|
4
|
+
attr_reader :name, :block
|
5
5
|
|
6
|
-
def initialize(response_name,
|
6
|
+
def initialize(response_name, &block)
|
7
7
|
@name = response_name
|
8
8
|
@block = block
|
9
|
-
@application = application
|
10
9
|
end
|
11
10
|
|
12
11
|
def compile(action=nil, **args)
|
@@ -24,7 +23,7 @@ module Praxis
|
|
24
23
|
args[:media_type] = media_type
|
25
24
|
end
|
26
25
|
end
|
27
|
-
Praxis::ResponseDefinition.new(name,
|
26
|
+
Praxis::ResponseDefinition.new(name, **args, &block)
|
28
27
|
end
|
29
28
|
|
30
29
|
def describe
|
@@ -131,5 +131,41 @@ module Praxis
|
|
131
131
|
self.status = 422
|
132
132
|
end
|
133
133
|
|
134
|
+
ApiDefinition.define do |api|
|
135
|
+
|
136
|
+
|
137
|
+
[
|
138
|
+
[ :accepted, 202, "The request has been accepted for processing, but the processing has not been completed." ],
|
139
|
+
[ :no_content, 204,"The server successfully processed the request, but is not returning any content."],
|
140
|
+
[ :multiple_choices, 300,"Indicates multiple options for the resource that the client may follow."],
|
141
|
+
[ :moved_permanently, 301,"This and all future requests should be directed to the given URI."],
|
142
|
+
[ :found, 302,"The requested resource resides temporarily under a different URI."],
|
143
|
+
[ :see_other, 303,"The response to the request can be found under another URI using a GET method"],
|
144
|
+
[ :not_modified, 304,"Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-Match."],
|
145
|
+
[ :temporary_redirect, 307,"In this case, the request should be repeated with another URI; however, future requests should still use the original URI."],
|
146
|
+
[ :bad_request, 400,"The request cannot be fulfilled due to bad syntax."],
|
147
|
+
[ :unauthorized, 401,"Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided."],
|
148
|
+
[ :forbidden, 403,"The request was a valid request, but the server is refusing to respond to it."],
|
149
|
+
[ :not_found, 404,"The requested resource could not be found but may be available again in the future."],
|
150
|
+
[ :method_not_allowed, 405,"A request was made of a resource using a request method not supported by that resource."],
|
151
|
+
[ :not_acceptable, 406,"The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request."],
|
152
|
+
[ :request_timeout, 408,"The server timed out waiting for the request."],
|
153
|
+
[ :conflict, 409, "Indicates that the request could not be processed because of conflict in the request, such as an edit conflict in the case of multiple updates."],
|
154
|
+
[ :precondition_failed, 412,"The server does not meet one of the preconditions that the requester put on the request."],
|
155
|
+
[ :unprocessable_entity, 422,"The request was well-formed but was unable to be followed due to semantic errors."],
|
156
|
+
].each do |name, code, base_description|
|
157
|
+
api.response_template name do |media_type: nil, location: nil, headers: nil, description: nil|
|
158
|
+
status code
|
159
|
+
description( description || base_description ) # description can "potentially" be overriden in an individual action.
|
160
|
+
|
161
|
+
media_type media_type if media_type
|
162
|
+
location location if location
|
163
|
+
headers headers if headers
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
|
134
170
|
end
|
135
171
|
end
|
@@ -13,15 +13,16 @@ module Praxis
|
|
13
13
|
@error = error
|
14
14
|
end
|
15
15
|
|
16
|
-
def format!(exception = @error
|
16
|
+
def format!(exception = @error)
|
17
17
|
if @error
|
18
|
-
|
18
|
+
|
19
|
+
if Application.instance.config.praxis.show_exceptions == true
|
19
20
|
msg = {
|
20
21
|
name: exception.class.name,
|
21
22
|
message: exception.message,
|
22
23
|
backtrace: exception.backtrace
|
23
24
|
}
|
24
|
-
msg[:cause] = format!(exception.cause
|
25
|
+
msg[:cause] = format!(exception.cause) if exception.cause
|
25
26
|
else
|
26
27
|
msg = {name: 'InternalServerError', message: "Something bad happened."}
|
27
28
|
end
|
@@ -33,4 +34,12 @@ module Praxis
|
|
33
34
|
|
34
35
|
end
|
35
36
|
|
37
|
+
ApiDefinition.define do |api|
|
38
|
+
api.response_template :internal_server_error do
|
39
|
+
description "A generic error message, given when an unexpected condition was encountered and no more specific message is suitable."
|
40
|
+
status 500
|
41
|
+
media_type "application/json"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
36
45
|
end
|
@@ -19,7 +19,7 @@ module Praxis
|
|
19
19
|
end
|
20
20
|
|
21
21
|
|
22
|
-
def encode!
|
22
|
+
def encode!
|
23
23
|
case @body
|
24
24
|
when Praxis::Types::MultipartArray
|
25
25
|
@body = @body.dump
|
@@ -28,9 +28,9 @@ module Praxis
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
def finish
|
32
|
-
format!
|
33
|
-
encode!
|
31
|
+
def finish
|
32
|
+
format!
|
33
|
+
encode!
|
34
34
|
|
35
35
|
@body = Array(@body)
|
36
36
|
|
@@ -41,4 +41,11 @@ module Praxis
|
|
41
41
|
|
42
42
|
end
|
43
43
|
|
44
|
+
ApiDefinition.define do |api|
|
45
|
+
api.response_template :multipart_ok do |media_type: Praxis::Types::MultipartArray|
|
46
|
+
status 200
|
47
|
+
media_type media_type
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
44
51
|
end
|
@@ -15,7 +15,7 @@ module Praxis
|
|
15
15
|
@documentation = documentation
|
16
16
|
end
|
17
17
|
|
18
|
-
def format!
|
18
|
+
def format!
|
19
19
|
@body = {name: 'ValidationError', summary: @summary }
|
20
20
|
@body[:errors] = @errors if @errors
|
21
21
|
|
@@ -31,4 +31,13 @@ module Praxis
|
|
31
31
|
|
32
32
|
end
|
33
33
|
|
34
|
+
|
35
|
+
ApiDefinition.define do |api|
|
36
|
+
api.response_template :validation_error do
|
37
|
+
description "An error message indicating that one or more elements of the request did not match the API specification for the action"
|
38
|
+
status 400
|
39
|
+
media_type "application/json"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
34
43
|
end
|
data/lib/praxis/route.rb
CHANGED
@@ -24,7 +24,7 @@ module Praxis
|
|
24
24
|
path_params = example_hash.select{|k,v| path_param_keys.include? k }
|
25
25
|
# Let's generate the example only using required params, to avoid mixing incompatible parameters
|
26
26
|
query_params = example_hash.select{|k,v| required_query_param_keys.include? k }
|
27
|
-
example = { verb: self.verb, url: self.path.expand(path_params), query_params: query_params }
|
27
|
+
example = { verb: self.verb, url: self.path.expand(path_params.transform_values(&:to_s)), query_params: query_params }
|
28
28
|
|
29
29
|
end
|
30
30
|
|
data/lib/praxis/router.rb
CHANGED
@@ -50,7 +50,7 @@ module Praxis
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def add_route(target, route)
|
53
|
-
path_versioning = (
|
53
|
+
path_versioning = (Application.instance.versioning_scheme == :path)
|
54
54
|
|
55
55
|
# DEPRECATED: remove with ResourceDefinition.version using: :path
|
56
56
|
path_versioning ||= (target.action.resource_definition.version_options[:using] == :path)
|
@@ -65,7 +65,7 @@ module Praxis
|
|
65
65
|
def call(env_or_request)
|
66
66
|
request = case env_or_request
|
67
67
|
when Hash
|
68
|
-
request_class.new(env_or_request
|
68
|
+
request_class.new(env_or_request)
|
69
69
|
when request_class
|
70
70
|
env_or_request
|
71
71
|
else
|
@@ -101,7 +101,7 @@ module Praxis
|
|
101
101
|
body += " Available versions = #{pretty_versions}."
|
102
102
|
end
|
103
103
|
headers = {"Content-Type" => "text/plain"}
|
104
|
-
if
|
104
|
+
if Praxis::Application.instance.config.praxis.x_cascade
|
105
105
|
headers['X-Cascade'] = 'pass'
|
106
106
|
end
|
107
107
|
result = [404, headers, [body]]
|
@@ -55,7 +55,7 @@ module Praxis
|
|
55
55
|
path = (base + path).gsub('//','/')
|
56
56
|
# Reject our own options
|
57
57
|
route_name = options.delete(:name);
|
58
|
-
pattern = Mustermann.new(path, {ignore_unknown_options: true}.merge( options ))
|
58
|
+
pattern = Mustermann.new(path, **{ignore_unknown_options: true}.merge( options ))
|
59
59
|
route = Route.new(verb, pattern, version, name: route_name, prefixed_path: prefixed_path, **options)
|
60
60
|
@routes << route
|
61
61
|
route
|
@@ -58,16 +58,8 @@ namespace :praxis do
|
|
58
58
|
require 'fileutils'
|
59
59
|
|
60
60
|
Praxis::Blueprint.caching_enabled = false
|
61
|
-
|
62
|
-
|
63
|
-
if apps.size == 1
|
64
|
-
# Backwards compatible directory generation when there's only 1 app
|
65
|
-
Praxis::Docs::Generator.generate(Dir.pwd, name: apps.first[0], skip_sub_directory: true)
|
66
|
-
else
|
67
|
-
apps.each do|name,instance|
|
68
|
-
Praxis::Docs::Generator.generate(Dir.pwd, name: name)
|
69
|
-
end
|
70
|
-
end
|
61
|
+
generator = Praxis::Docs::Generator.new(Dir.pwd)
|
62
|
+
generator.save!
|
71
63
|
end
|
72
64
|
|
73
65
|
end
|
data/lib/praxis/tasks/routes.rb
CHANGED
data/lib/praxis/trait.rb
CHANGED
@@ -76,7 +76,7 @@ module Praxis
|
|
76
76
|
dsl_compiler: ActionDefinition::HeadersDSLCompiler,
|
77
77
|
case_insensitive_load: true
|
78
78
|
}
|
79
|
-
Attributor::Hash.of(key: String).construct(Proc.new {}, hash_opts)
|
79
|
+
Attributor::Hash.of(key: String).construct(Proc.new {}, **hash_opts)
|
80
80
|
else
|
81
81
|
Attributor::Hash.construct(Proc.new {})
|
82
82
|
end
|
@@ -32,8 +32,8 @@ module Praxis
|
|
32
32
|
#
|
33
33
|
# @return [String] the string-representation of this type's identifier
|
34
34
|
def identifier(identifier=nil)
|
35
|
-
return @identifier
|
36
|
-
|
35
|
+
return @identifier unless identifier
|
36
|
+
@identifier = MediaTypeIdentifier.load(identifier)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -12,7 +12,7 @@ module Praxis
|
|
12
12
|
return value if value.kind_of?(self) || value.nil?
|
13
13
|
|
14
14
|
unless (value.kind_of?(::String) && ! content_type.nil?)
|
15
|
-
raise Attributor::CoercionError
|
15
|
+
raise Attributor::CoercionError.new(context: context, from: value.class, to: self.name, value: value)
|
16
16
|
end
|
17
17
|
|
18
18
|
headers = {'Content-Type' => content_type}
|
@@ -83,7 +83,7 @@ module Praxis
|
|
83
83
|
|
84
84
|
self.multiple << name if multiple
|
85
85
|
|
86
|
-
compiler = Attributor::DSLCompiler.new(self, opts)
|
86
|
+
compiler = Attributor::DSLCompiler.new(self, **opts)
|
87
87
|
|
88
88
|
if filename
|
89
89
|
filename_attribute = compiler.define('filename', String, required: true)
|
@@ -218,7 +218,7 @@ module Praxis
|
|
218
218
|
attr_accessor :preamble
|
219
219
|
attr_reader :content_type
|
220
220
|
|
221
|
-
def initialize(content_type: self.class.identifier)
|
221
|
+
def initialize(content_type: self.class.identifier.to_s)
|
222
222
|
self.content_type = content_type
|
223
223
|
end
|
224
224
|
|
@@ -14,7 +14,7 @@ module Praxis
|
|
14
14
|
|
15
15
|
def update_attribute(attribute, options, block)
|
16
16
|
attribute.options.merge!(options)
|
17
|
-
attribute.type.attributes(options, &block)
|
17
|
+
attribute.type.attributes(**options, &block)
|
18
18
|
end
|
19
19
|
|
20
20
|
def create_attribute(type=Attributor::Struct, **opts, &block)
|
data/lib/praxis/version.rb
CHANGED
data/praxis.gemspec
CHANGED
@@ -21,22 +21,21 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.executables << 'praxis'
|
22
22
|
|
23
23
|
spec.add_dependency 'rack', '>= 1'
|
24
|
-
spec.add_dependency 'mustermann', '>=
|
24
|
+
spec.add_dependency 'mustermann', '>=1.1', '<=2'
|
25
25
|
spec.add_dependency 'activesupport', '>= 3'
|
26
26
|
spec.add_dependency 'mime', '~> 0'
|
27
|
-
spec.add_dependency 'praxis-
|
28
|
-
spec.add_dependency '
|
29
|
-
spec.add_dependency '
|
30
|
-
spec.add_dependency 'thor', '~> 0.18'
|
27
|
+
spec.add_dependency 'praxis-blueprints', '>= 3.4'
|
28
|
+
spec.add_dependency 'attributor', '>= 5.4'
|
29
|
+
spec.add_dependency 'thor'
|
31
30
|
spec.add_dependency 'terminal-table', '~> 1.4'
|
32
31
|
|
33
32
|
spec.add_development_dependency 'bundler'
|
34
33
|
spec.add_development_dependency 'rake', '~> 0.9'
|
35
34
|
spec.add_development_dependency 'rake-notes', '~> 0'
|
36
35
|
if RUBY_PLATFORM !~ /java/
|
37
|
-
spec.add_development_dependency 'pry'
|
38
|
-
spec.add_development_dependency 'pry-byebug'
|
39
|
-
spec.add_development_dependency 'pry-stack_explorer'
|
36
|
+
spec.add_development_dependency 'pry'
|
37
|
+
spec.add_development_dependency 'pry-byebug'
|
38
|
+
spec.add_development_dependency 'pry-stack_explorer'
|
40
39
|
spec.add_development_dependency 'sqlite3', '~> 1'
|
41
40
|
else
|
42
41
|
spec.add_development_dependency 'jdbc-sqlite3'
|
@@ -50,6 +49,9 @@ Gem::Specification.new do |spec|
|
|
50
49
|
spec.add_development_dependency 'rack-test', '~> 0'
|
51
50
|
spec.add_development_dependency 'simplecov', '~> 0'
|
52
51
|
spec.add_development_dependency 'fuubar', '~> 2'
|
53
|
-
spec.add_development_dependency 'yard',
|
52
|
+
spec.add_development_dependency 'yard', ">= 0.9.20"
|
54
53
|
spec.add_development_dependency 'coveralls'
|
54
|
+
# Just for the query selector extensions etc...
|
55
|
+
spec.add_development_dependency 'sequel', '~> 5'
|
56
|
+
spec.add_development_dependency 'activerecord', '> 4'
|
55
57
|
end
|
data/spec/functional_spec.rb
CHANGED
@@ -136,7 +136,6 @@ describe 'Functional specs' do
|
|
136
136
|
headers = last_response.headers
|
137
137
|
expect(headers['Content-Type']).to eq('application/json')
|
138
138
|
expect(headers['Spec-Middleware']).to eq('used')
|
139
|
-
expect(headers['Content-Length']).to eq(last_response.body.size.to_s)
|
140
139
|
end
|
141
140
|
|
142
141
|
it 'returns early when making the before filter break' do
|
@@ -1,15 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Praxis::ActionDefinition do
|
4
|
-
|
5
|
-
before(:context) do
|
6
|
-
Thread.current[:praxis_instance] = Praxis::Application.new(name: 'action_definition_spec', skip_registration: true)
|
7
|
-
end
|
8
|
-
|
9
|
-
let(:praxis_instance) do
|
10
|
-
Thread.current[:praxis_instance]
|
11
|
-
end
|
12
|
-
|
13
4
|
class SpecMediaType < Praxis::MediaType
|
14
5
|
identifier 'application/json'
|
15
6
|
|
@@ -40,8 +31,10 @@ describe Praxis::ActionDefinition do
|
|
40
31
|
end
|
41
32
|
end
|
42
33
|
end
|
34
|
+
|
43
35
|
subject(:action) do
|
44
|
-
|
36
|
+
|
37
|
+
Praxis::ApiDefinition.define do |api|
|
45
38
|
api.response_template :ok do |media_type: , location: nil, headers: nil, description: nil |
|
46
39
|
status 200
|
47
40
|
|
@@ -49,10 +42,6 @@ describe Praxis::ActionDefinition do
|
|
49
42
|
location location
|
50
43
|
headers headers if headers
|
51
44
|
end
|
52
|
-
|
53
|
-
api.info do # applies to all API infos
|
54
|
-
base_path "/pref"
|
55
|
-
end
|
56
45
|
end
|
57
46
|
Praxis::ActionDefinition.new(:foo, resource_definition) do
|
58
47
|
routing { get '/:one' }
|
@@ -122,11 +111,11 @@ describe Praxis::ActionDefinition do
|
|
122
111
|
let(:traits) { {test: trait} }
|
123
112
|
|
124
113
|
before do
|
125
|
-
allow(
|
114
|
+
allow(Praxis::ApiDefinition.instance).to receive(:traits).and_return(traits)
|
126
115
|
end
|
127
116
|
|
128
117
|
its('params.attributes.keys') { should eq [:inherited, :app_name, :name, :one]}
|
129
|
-
its('routes.first.path.to_s') { should eq '/
|
118
|
+
its('routes.first.path.to_s') { should eq '/api/foobars/hello_world/test_trait/:app_name/:one' }
|
130
119
|
its(:traits) { should eq [:test] }
|
131
120
|
|
132
121
|
it 'is reflected in the describe output' do
|
@@ -292,7 +281,7 @@ describe Praxis::ActionDefinition do
|
|
292
281
|
subject(:action) { resource_definition.actions[:show] }
|
293
282
|
|
294
283
|
it 'works' do
|
295
|
-
expansion = action.primary_route.path.expand(cloud_id:232, id: 2)
|
284
|
+
expansion = action.primary_route.path.expand(cloud_id:'232', id: '2')
|
296
285
|
expect(expansion).to eq "/api/clouds/232/instances/2"
|
297
286
|
end
|
298
287
|
|
@@ -326,9 +315,11 @@ describe Praxis::ActionDefinition do
|
|
326
315
|
end
|
327
316
|
|
328
317
|
context 'with a base_path and base_params on ApiDefinition' do
|
329
|
-
|
330
|
-
|
331
|
-
|
318
|
+
# Without getting a fresh new ApiDefinition it is very difficult to test stuff using the Singleton
|
319
|
+
# So for some tests we're gonna create a new instance and work with it to avoid the singleton issues
|
320
|
+
let(:non_singleton_api) do
|
321
|
+
api_def=Praxis::ApiDefinition.__send__(:new)
|
322
|
+
api_def.instance_eval do |api|
|
332
323
|
|
333
324
|
api.info do
|
334
325
|
base_path '/apps/:app_name'
|
@@ -341,13 +332,11 @@ describe Praxis::ActionDefinition do
|
|
341
332
|
end
|
342
333
|
|
343
334
|
end
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
params { attribute :one, String }
|
350
|
-
end
|
335
|
+
api_def
|
336
|
+
end
|
337
|
+
|
338
|
+
before do
|
339
|
+
allow(Praxis::ApiDefinition).to receive(:instance).and_return(non_singleton_api)
|
351
340
|
end
|
352
341
|
|
353
342
|
its('routes.first.path.to_s') { should eq '/apps/:app_name/foobars/hello_world/:one' }
|