shaf 0.5.1 → 0.5.2
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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/shaf/api_doc/document.rb +2 -2
- data/lib/shaf/extensions/authorize.rb +8 -5
- data/lib/shaf/extensions/resource_uris.rb +1 -1
- data/lib/shaf/extensions/symbolic_routes.rb +14 -7
- data/lib/shaf/generator/serializer.rb +3 -3
- data/lib/shaf/generator/templates/api/controller.rb.erb +1 -1
- data/lib/shaf/generator/templates/api/policy.rb.erb +0 -4
- data/lib/shaf/helpers/payload.rb +2 -0
- data/lib/shaf/spec.rb +0 -2
- data/lib/shaf/spec/base.rb +11 -2
- data/lib/shaf/spec/fixture.rb +23 -31
- data/lib/shaf/spec/fixtures.rb +90 -20
- data/lib/shaf/spec/integration_spec.rb +1 -14
- data/lib/shaf/spec/payload_utils.rb +3 -3
- data/lib/shaf/spec/serializer_spec.rb +4 -0
- data/lib/shaf/tasks.rb +1 -1
- data/lib/shaf/version.rb +1 -1
- data/templates/spec/spec_helper.rb +1 -0
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a9af4fa12d1002e4c4fcfe233c640e0efff4d779d8bed3b884dec7da3d2d7eef
|
4
|
+
data.tar.gz: 7748f68242de611ece5e8f556686e924f627f6346f5c90e56b1b15d3bbd4ce04
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0dc246772c0a1c5d74d738a4618173e83819a67d9cb88e17b37c7894ffbc27ce977f1acfb2edcf3cf88bc12fc34f202e9e974d930976ff997c26f2cceaa1b3cb
|
7
|
+
data.tar.gz: 4fb0286154086c4859b109f79fd70836d3dd44d777688964b235cb32a2ad1afc897f8ae3df9544616934d9b63363c2714e6d11d81d4d0c327238b46aae3db50d
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
@@ -70,7 +70,7 @@ module Shaf
|
|
70
70
|
hash.to_yaml
|
71
71
|
end
|
72
72
|
|
73
|
-
def
|
73
|
+
def to_html
|
74
74
|
# For some reason redcarpet don't like to surround my markdown code blocks
|
75
75
|
# with <pre> tags, so let's fix that here.
|
76
76
|
options = {autolink: true, fenced_code_blocks: true}
|
@@ -84,7 +84,7 @@ module Shaf
|
|
84
84
|
def write_html(output)
|
85
85
|
FileUtils.mkdir_p(output) unless Dir.exist? output
|
86
86
|
File.open(File.join(output, "#{model.downcase}.html"), "w") do |file|
|
87
|
-
file.write(
|
87
|
+
file.write(to_html)
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'sinatra/base'
|
2
2
|
|
3
3
|
module Shaf
|
4
|
-
|
5
4
|
module Authorize
|
6
|
-
class NoPolicyError <
|
7
|
-
class PolicyViolationError <
|
5
|
+
class NoPolicyError < Error; end
|
6
|
+
class PolicyViolationError < Error; end
|
7
|
+
class MissingPolicyAction < Error; end
|
8
8
|
|
9
9
|
attr_reader :policy_class
|
10
10
|
|
@@ -20,7 +20,10 @@ module Shaf
|
|
20
20
|
module Helpers
|
21
21
|
def authorize(action, resource = nil)
|
22
22
|
policy(resource) or raise Authorize::NoPolicyError
|
23
|
-
|
23
|
+
method = __method_for(action)
|
24
|
+
return @policy.public_send(method) if @policy.respond_to? method
|
25
|
+
raise Authorize::MissingPolicyAction,
|
26
|
+
"#{@policy.class} does not implement method #{method}"
|
24
27
|
end
|
25
28
|
|
26
29
|
def authorize!(action, resource = nil)
|
@@ -35,7 +38,7 @@ module Shaf
|
|
35
38
|
@policy = self.class.policy_class&.new(user, resource)
|
36
39
|
end
|
37
40
|
|
38
|
-
def
|
41
|
+
def __method_for(action)
|
39
42
|
return action if action.to_s.end_with? '?'
|
40
43
|
"#{action}?".to_sym
|
41
44
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Shaf
|
2
2
|
module SymbolicRoutes
|
3
|
-
|
3
|
+
class UriHelperNotRegisterdError < Error; end
|
4
|
+
|
5
|
+
SUPPORTED_METHODS = [
|
4
6
|
:get,
|
5
7
|
:put,
|
6
8
|
:post,
|
@@ -10,18 +12,23 @@ module Shaf
|
|
10
12
|
:options,
|
11
13
|
:link,
|
12
14
|
:unlink
|
13
|
-
].
|
14
|
-
|
15
|
-
|
15
|
+
].freeze
|
16
|
+
|
17
|
+
SUPPORTED_METHODS.each do |m|
|
18
|
+
define_method m do |path, collection: false, &block|
|
19
|
+
super(rewrite_path(path, collection), &block)
|
16
20
|
end
|
17
21
|
end
|
18
22
|
|
19
|
-
def rewrite_path(path)
|
23
|
+
def rewrite_path(path, collection = nil)
|
20
24
|
return path unless path.is_a? Symbol
|
21
25
|
|
22
26
|
m = "#{path}_template"
|
23
|
-
|
24
|
-
|
27
|
+
return send(m, collection) if respond_to? m
|
28
|
+
|
29
|
+
raise UriHelperNotRegisterdError, <<~RUBY
|
30
|
+
Undefined method '#{m}'. Did you forget to register a uri helper for #{path}?
|
31
|
+
RUBY
|
25
32
|
end
|
26
33
|
end
|
27
34
|
end
|
@@ -144,7 +144,7 @@ module Shaf
|
|
144
144
|
link(
|
145
145
|
rel: "doc:create-form",
|
146
146
|
desc: "Link to a form used to create new #{name} resources",
|
147
|
-
uri: "
|
147
|
+
uri: "/#{plural_name}/form",
|
148
148
|
uri_helper: "new_#{name}_uri"
|
149
149
|
)
|
150
150
|
end
|
@@ -185,12 +185,12 @@ module Shaf
|
|
185
185
|
def collection_with_doc
|
186
186
|
<<~EOS.split("\n")
|
187
187
|
collection of: '#{plural_name}' do
|
188
|
+
curie(:doc) { doc_curie_uri('#{name}') }
|
189
|
+
|
188
190
|
link :self, #{plural_name}_uri
|
189
191
|
link :up, root_uri
|
190
192
|
|
191
193
|
#{create_link.join("\n ")}
|
192
|
-
link :'doc:create-form', new_#{name}_uri
|
193
|
-
curie(:doc) { doc_curie_uri('#{name}') }
|
194
194
|
end
|
195
195
|
EOS
|
196
196
|
end
|
@@ -54,7 +54,7 @@ class <%= controller_class_name %> < BaseController
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def <%= name %>
|
57
|
-
<%= model_class_name %>[params['id']].tap do |<%= name %>|
|
57
|
+
@<%= name %> ||= <%= model_class_name %>[params['id']].tap do |<%= name %>|
|
58
58
|
raise NotFoundError.new(clazz: <%= model_class_name %>, id: params['id']) unless <%= name %>
|
59
59
|
end
|
60
60
|
end
|
data/lib/shaf/helpers/payload.rb
CHANGED
@@ -91,6 +91,8 @@ module Shaf
|
|
91
91
|
http_cache = kwargs.fetch(:http_cache, Settings.http_cache)
|
92
92
|
add_cache_headers(serialized) if http_cache
|
93
93
|
|
94
|
+
log.info "#{request.request_method} #{request.path_info} => #{status}"
|
95
|
+
|
94
96
|
if preferred_response == mime_type(:html)
|
95
97
|
respond_with_html(resource, serialized)
|
96
98
|
else
|
data/lib/shaf/spec.rb
CHANGED
data/lib/shaf/spec/base.rb
CHANGED
@@ -3,7 +3,7 @@ module Shaf
|
|
3
3
|
class Base < Minitest::Spec
|
4
4
|
include Minitest::Hooks
|
5
5
|
include PayloadUtils
|
6
|
-
include Fixtures
|
6
|
+
include Fixtures::Accessors
|
7
7
|
|
8
8
|
TRANSACTION_OPTIONS = {
|
9
9
|
rollback: :always,
|
@@ -13,7 +13,7 @@ module Shaf
|
|
13
13
|
|
14
14
|
around(:all) do |&block|
|
15
15
|
DB.transaction(TRANSACTION_OPTIONS) do
|
16
|
-
Shaf::Spec::Fixtures.load
|
16
|
+
Shaf::Spec::Fixtures.load(reload: true)
|
17
17
|
super(&block)
|
18
18
|
end
|
19
19
|
end
|
@@ -21,6 +21,15 @@ module Shaf
|
|
21
21
|
around do |&block|
|
22
22
|
DB.transaction(TRANSACTION_OPTIONS) { super(&block) }
|
23
23
|
end
|
24
|
+
|
25
|
+
before do
|
26
|
+
$logger&.info <<~LOG
|
27
|
+
\n
|
28
|
+
##########################################################################
|
29
|
+
# #{self.class.superclass.name} - #{name}
|
30
|
+
##########################################################################
|
31
|
+
LOG
|
32
|
+
end
|
24
33
|
end
|
25
34
|
end
|
26
35
|
end
|
data/lib/shaf/spec/fixture.rb
CHANGED
@@ -4,58 +4,50 @@ require 'shaf/utils'
|
|
4
4
|
module Shaf
|
5
5
|
module Spec
|
6
6
|
class Fixture
|
7
|
-
include Fixtures
|
8
7
|
|
9
|
-
|
8
|
+
include Fixtures::Accessors
|
9
|
+
|
10
|
+
attr_reader :name
|
11
|
+
|
12
|
+
def self.define(name, &block)
|
10
13
|
return unless block_given?
|
11
|
-
|
12
|
-
new(collection_name, collection, block).run
|
14
|
+
Fixtures.fixture_defined new(name.to_sym, block)
|
13
15
|
end
|
14
16
|
|
15
|
-
def initialize(
|
16
|
-
@
|
17
|
-
@collection = collection
|
17
|
+
def initialize(name, block)
|
18
|
+
@name = name
|
18
19
|
@block = block
|
19
20
|
end
|
20
21
|
|
21
|
-
def
|
22
|
+
def init
|
22
23
|
instance_exec(&@block)
|
24
|
+
self
|
23
25
|
end
|
24
26
|
|
25
|
-
def
|
26
|
-
|
27
|
+
def add_entry(entry_name, resrc = nil, &block)
|
28
|
+
value = block ? instance_exec(&block) : resrc
|
29
|
+
fixtures = send(name)
|
30
|
+
fixtures[entry_name] = value
|
27
31
|
end
|
28
32
|
|
29
33
|
private
|
30
34
|
|
31
35
|
def method_missing(method, *args, &block)
|
32
|
-
|
33
|
-
|
34
|
-
elsif resource_name?(args.size, block_given?)
|
35
|
-
resource(method, args.first, &block)
|
36
|
-
else
|
37
|
-
super
|
38
|
-
end
|
36
|
+
return super unless resource_name?(args.size, block_given?)
|
37
|
+
add_entry(method, args.first, &block)
|
39
38
|
end
|
40
39
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
-
fixture_files = Fixtures.fixture_files
|
45
|
-
fixtures = fixture_files.map { |f| File.basename(f, ".rb") }
|
46
|
-
i = fixtures.index(method.to_s)
|
47
|
-
return false unless i
|
40
|
+
def respond_to_missing?(*)
|
41
|
+
true
|
42
|
+
end
|
48
43
|
|
49
|
-
|
50
|
-
|
44
|
+
def nested_fixture?(*args)
|
45
|
+
args.size == 1 && args.first.is_a?(Symbol)
|
51
46
|
end
|
52
47
|
|
53
48
|
def resource_name?(arg_count, block_given)
|
54
|
-
if block_given
|
55
|
-
|
56
|
-
else
|
57
|
-
arg_count == 1
|
58
|
-
end
|
49
|
+
arg_count += 1 if block_given
|
50
|
+
arg_count == 1
|
59
51
|
end
|
60
52
|
end
|
61
53
|
end
|
data/lib/shaf/spec/fixtures.rb
CHANGED
@@ -1,32 +1,102 @@
|
|
1
1
|
module Shaf
|
2
2
|
module Spec
|
3
|
-
|
4
|
-
class FixtureNotFound < StandardError; end
|
5
|
-
|
6
3
|
module Fixtures
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
class FixtureNotFound < StandardError
|
5
|
+
def initialize(name, key = nil)
|
6
|
+
msg =
|
7
|
+
if key
|
8
|
+
"Instance '#{key}' is not found in fixture '#{name}'! " \
|
9
|
+
"Either it does not exist in the fixture definition or " \
|
10
|
+
"there is a circular dependency with your fixtures."
|
11
|
+
else
|
12
|
+
"No such fixture: #{name}"
|
13
|
+
end
|
10
14
|
|
11
|
-
|
12
|
-
|
13
|
-
Dir[File.join(dir, '**', '*.rb')]
|
15
|
+
super(msg)
|
16
|
+
end
|
14
17
|
end
|
15
18
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
19
|
+
class << self
|
20
|
+
def load(reload: false)
|
21
|
+
clear if reload
|
22
|
+
require_fixture_files
|
23
|
+
init_fixtures
|
24
|
+
end
|
25
|
+
|
26
|
+
def clear
|
27
|
+
fixtures.each { |name, _| Accessors.clear(name) }
|
28
|
+
@initialized_fixtures = []
|
29
|
+
end
|
30
|
+
|
31
|
+
def init_fixtures
|
32
|
+
fixtures.each { |name, fixture| init_fixture(name, fixture) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def init_fixture(name, fixture = nil)
|
36
|
+
fixture ||= fixtures[name]
|
37
|
+
raise FixtureNotFound, name unless fixture
|
38
|
+
return if initialized? name
|
39
|
+
|
40
|
+
initialized_fixtures << name
|
41
|
+
fixture.init
|
42
|
+
end
|
43
|
+
|
44
|
+
def fixture_defined(fixture)
|
45
|
+
fixtures[fixture.name] = fixture
|
46
|
+
Accessors.add(fixture.name)
|
47
|
+
end
|
48
|
+
|
49
|
+
def fixtures
|
50
|
+
@fixtures ||= {}
|
51
|
+
end
|
52
|
+
|
53
|
+
def initialized_fixtures
|
54
|
+
@initialized_fixtures ||= []
|
55
|
+
end
|
56
|
+
|
57
|
+
def require_fixture_files
|
58
|
+
fixture_files.each { |file| require(file) }
|
59
|
+
end
|
60
|
+
|
61
|
+
def fixture_files
|
62
|
+
@fixture_files ||= Dir[File.join(fixture_dir, '**', '*.rb')]
|
63
|
+
end
|
64
|
+
|
65
|
+
def fixture_dir
|
66
|
+
Shaf::Settings.fixtures_dir || 'spec/fixtures'
|
67
|
+
end
|
20
68
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
collection
|
69
|
+
def initialized?(name)
|
70
|
+
initialized_fixtures.include? name
|
71
|
+
end
|
25
72
|
end
|
26
73
|
|
27
|
-
|
28
|
-
|
29
|
-
collection
|
74
|
+
module Accessors
|
75
|
+
class << self
|
76
|
+
def collection(name)
|
77
|
+
@collections ||= {}
|
78
|
+
@collections[name] ||= {}
|
79
|
+
end
|
80
|
+
|
81
|
+
def clear(name)
|
82
|
+
collection(name).clear
|
83
|
+
end
|
84
|
+
|
85
|
+
def add(name)
|
86
|
+
collection = collection(name)
|
87
|
+
return if instance_methods.include? name
|
88
|
+
|
89
|
+
define_method(name) do |arg = nil|
|
90
|
+
Fixtures.init_fixture(name) unless Fixtures.initialized? name
|
91
|
+
if arg.nil?
|
92
|
+
collection
|
93
|
+
elsif collection.key? arg
|
94
|
+
collection[arg]
|
95
|
+
else
|
96
|
+
raise FixtureNotFound.new(name, arg)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
30
100
|
end
|
31
101
|
end
|
32
102
|
end
|
@@ -19,7 +19,7 @@ module Shaf
|
|
19
19
|
return nil if body.empty?
|
20
20
|
JSON.parse(body, symbolize_names: true)
|
21
21
|
rescue JSON::ParserError => e
|
22
|
-
assert e.nil?, "Could not parse reponse as json"
|
22
|
+
assert e.nil?, "Could not parse reponse as json (#{body[0..40]})"
|
23
23
|
end
|
24
24
|
|
25
25
|
def app
|
@@ -43,19 +43,6 @@ module Shaf
|
|
43
43
|
def clear_auth_token
|
44
44
|
@__integration_test_auth_token = nil
|
45
45
|
end
|
46
|
-
|
47
|
-
# def login(email, pass)
|
48
|
-
# params = {email: email, password: pass}
|
49
|
-
# header 'Content-Type', 'application/json'
|
50
|
-
# post Shaf::UriHelper.session_uri, JSON.generate(params)
|
51
|
-
# @__integration_test_auth_token = attribute[:auth_token]
|
52
|
-
# end
|
53
|
-
#
|
54
|
-
# def logout
|
55
|
-
# delete Shaf::UriHelper.session_uri
|
56
|
-
# @__integration_test_auth_token = nil
|
57
|
-
# end
|
58
|
-
|
59
46
|
end
|
60
47
|
end
|
61
48
|
end
|
@@ -18,7 +18,7 @@ module Shaf
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def links
|
21
|
-
last_payload[:_links] ||
|
21
|
+
last_payload[:_links] || {}
|
22
22
|
end
|
23
23
|
|
24
24
|
def link_rels
|
@@ -98,9 +98,9 @@ module Shaf
|
|
98
98
|
def assert_has_link(rel)
|
99
99
|
assert last_payload.key?(:_links), "Response does not have any links: #{last_payload}"
|
100
100
|
assert last_payload[:_links][rel.to_sym],
|
101
|
-
"Response does not contain link with rel '#{rel}': #{last_payload}"
|
101
|
+
"Response does not contain link with rel '#{rel}'!\nResponse: #{last_payload}"
|
102
102
|
assert last_payload[:_links][rel.to_sym][:href],
|
103
|
-
"link with rel '#{rel}' in
|
103
|
+
"link with rel '#{rel}' in response does not have a href!\nResponse: #{last_payload}"
|
104
104
|
end
|
105
105
|
|
106
106
|
def refute_has_link(rel)
|
data/lib/shaf/tasks.rb
CHANGED
data/lib/shaf/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shaf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sammy Henningsson
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
ZMhjYR7sRczGJx+GxGU2EaR0bjRsPVlC4ywtFxoOfRG3WaJcpWGEoAoMJX6Z0bRv
|
31
31
|
M40=
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2018-
|
33
|
+
date: 2018-10-21 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: rake
|
metadata.gz.sig
CHANGED
Binary file
|