ff-tbl-macros 0.1.8
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 +7 -0
- data/Dockerfile +13 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +117 -0
- data/MIT-LICENSE +18 -0
- data/README.md +147 -0
- data/lib/ff-tbl-macros.rb +29 -0
- data/lib/macros/auth.rb +9 -0
- data/lib/macros/auth/authenticate.rb +24 -0
- data/lib/macros/auth/sign_in.rb +43 -0
- data/lib/macros/auth/sign_out.rb +48 -0
- data/lib/macros/base.rb +37 -0
- data/lib/macros/contract.rb +8 -0
- data/lib/macros/contract/extract_params.rb +25 -0
- data/lib/macros/contract/prepopulate.rb +16 -0
- data/lib/macros/ctx.rb +9 -0
- data/lib/macros/ctx/copy.rb +18 -0
- data/lib/macros/ctx/inspect.rb +28 -0
- data/lib/macros/ctx/validate_presence.rb +20 -0
- data/lib/macros/current_user.rb +7 -0
- data/lib/macros/current_user/set.rb +25 -0
- data/lib/macros/error.rb +7 -0
- data/lib/macros/error/set_from_contract.rb +19 -0
- data/lib/macros/model.rb +10 -0
- data/lib/macros/model/build.rb +32 -0
- data/lib/macros/model/copy.rb +17 -0
- data/lib/macros/model/destroy.rb +18 -0
- data/lib/macros/model/persist.rb +21 -0
- data/lib/macros/search.rb +7 -0
- data/lib/macros/search/query.rb +34 -0
- data/lib/macros/verify_params.rb +7 -0
- data/lib/macros/verify_params/date.rb +17 -0
- data/lib/macros/version.rb +6 -0
- data/spec/lib/auth/authenticate_spec.rb +21 -0
- data/spec/lib/auth/sign_in_spec.rb +37 -0
- data/spec/lib/auth/sign_out_spec.rb +37 -0
- data/spec/lib/auth_spec.rb +15 -0
- data/spec/lib/contract/extract_params_spec.rb +35 -0
- data/spec/lib/contract/prepopulate_spec.rb +27 -0
- data/spec/lib/contract_spec.rb +14 -0
- data/spec/lib/ctx/copy_spec.rb +27 -0
- data/spec/lib/ctx/inspect_spec.rb +26 -0
- data/spec/lib/ctx/validate_presence_spec.rb +20 -0
- data/spec/lib/ctx_spec.rb +19 -0
- data/spec/lib/current_user.rb +7 -0
- data/spec/lib/current_user/set_spec.rb +24 -0
- data/spec/lib/error/set_from_contract_spec.rb +27 -0
- data/spec/lib/error_spec.rb +7 -0
- data/spec/lib/ff_tbl_macros_spec.rb +11 -0
- data/spec/lib/model/build_spec.rb +53 -0
- data/spec/lib/model/copy_spec.rb +26 -0
- data/spec/lib/model/destroy_spec.rb +13 -0
- data/spec/lib/model/persist_spec.rb +45 -0
- data/spec/lib/model_spec.rb +21 -0
- data/spec/lib/search/query_spec.rb +23 -0
- data/spec/lib/search_spec.rb +9 -0
- data/spec/lib/verify_params/date_spec.rb +22 -0
- data/spec/lib/verify_params_spec.rb +9 -0
- data/spec/spec_helper.rb +38 -0
- metadata +169 -0
data/lib/macros/base.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Macros
|
4
|
+
# Base class for all the Trbr step macros
|
5
|
+
class Base
|
6
|
+
include Uber::Callable
|
7
|
+
|
8
|
+
# @param args Any arguments that our macro operation supports
|
9
|
+
# @return Single step object that can be used in operation step
|
10
|
+
def initialize(*args)
|
11
|
+
self.args = args
|
12
|
+
end
|
13
|
+
|
14
|
+
# To follow Trbr concept of named steps we have to register class instances
|
15
|
+
# with given class names - this method registers a class so it can be used
|
16
|
+
# with brackets. It will create a method that has a name that has the same name
|
17
|
+
# as a class from which we want to use an object to handle a step
|
18
|
+
#
|
19
|
+
# @param step_name [Symbol] name that we want to use
|
20
|
+
# @param proxy [Boolean] is this just a proxy for Trailblazer built in operation
|
21
|
+
#
|
22
|
+
# @example Register with :create
|
23
|
+
# register :create #=> Macros::Create()
|
24
|
+
def self.register(step_name, proxy: false)
|
25
|
+
klass = step_name.to_s.split('_').collect(&:capitalize).join
|
26
|
+
|
27
|
+
define_singleton_method klass do |*args|
|
28
|
+
base = "#{self}::#{klass}".constantize
|
29
|
+
proxy ? base.new(*args).call : base.new(*args)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
attr_accessor :args
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Macros
|
4
|
+
class Contract
|
5
|
+
class ExtractParams < Macros::Base
|
6
|
+
# @return [Macros::Contract::ExtractParams] step macro instance
|
7
|
+
# @param from [Hash] key in params
|
8
|
+
# @example scope not passed
|
9
|
+
# Macros::Contract::ExtractParams(from: :scope)
|
10
|
+
|
11
|
+
def initialize(from:)
|
12
|
+
@from = from
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(ctx, **)
|
16
|
+
return false unless ctx[:params]
|
17
|
+
|
18
|
+
scope = ctx[@from]
|
19
|
+
return false unless scope
|
20
|
+
|
21
|
+
ctx['contract.default.params'] = ctx[:params][scope]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Macros
|
4
|
+
class Contract
|
5
|
+
class Prepopulate < Macros::Base
|
6
|
+
def initialize(options_key: nil)
|
7
|
+
@options_key = options_key
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(ctx, **)
|
11
|
+
options = ctx[@options_key] || {}
|
12
|
+
ctx['contract.default'].prepopulate!(options)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/macros/ctx.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Macros
|
4
|
+
class Ctx
|
5
|
+
class Copy < Macros::Base
|
6
|
+
def initialize(origin_key, destination_key)
|
7
|
+
@origin_key = origin_key
|
8
|
+
@destination_key = destination_key
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(ctx, **)
|
12
|
+
return false unless ctx[@origin_key]
|
13
|
+
|
14
|
+
ctx[@destination_key] = ctx[@origin_key]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Macros
|
4
|
+
class Ctx
|
5
|
+
# Prints the entire tbl context or just a single resource
|
6
|
+
#
|
7
|
+
# @example prints the entire tbl context
|
8
|
+
# step Macros::Ctx::Inspect()
|
9
|
+
#
|
10
|
+
# @example prints the :model resource from the tbl context
|
11
|
+
# step Macros::Ctx::Inspect(key: :model)
|
12
|
+
class Inspect < Macros::Base
|
13
|
+
# @return [Macros::Debug::Ctx] step macro instance
|
14
|
+
# @param key [Symbol or String] ctx key under which is a resource to which we want to assign, optional
|
15
|
+
def initialize(key: nil)
|
16
|
+
@key = key
|
17
|
+
end
|
18
|
+
|
19
|
+
def call(ctx, **)
|
20
|
+
if @key
|
21
|
+
p ctx[@key]
|
22
|
+
else
|
23
|
+
p ctx
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Macros
|
4
|
+
class Ctx
|
5
|
+
class ValidatePresence < Macros::Base
|
6
|
+
# Check if the key set in the context
|
7
|
+
# @param key [Symbol]
|
8
|
+
# @example key not passed
|
9
|
+
# Macros::Contract::ExtractParams()
|
10
|
+
def initialize(key)
|
11
|
+
@key = key
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param ctx [Trailblazer::Skill] tbl context hash
|
15
|
+
def call(ctx, **)
|
16
|
+
!!ctx[@key]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Macros
|
4
|
+
class CurrentUser
|
5
|
+
VALID_CURRENT_USER_CLASS_NAMES = %w[User Admin].freeze
|
6
|
+
|
7
|
+
# Sets the current_user in the context.
|
8
|
+
#
|
9
|
+
class Set < Macros::Base
|
10
|
+
# @return [Macro::CurrentUser::Set] step macro instance
|
11
|
+
def initialize(key: :model)
|
12
|
+
@key = key
|
13
|
+
end
|
14
|
+
|
15
|
+
# Sets the current user in the context
|
16
|
+
# @param ctx [Trailblazer::Skill] tbl context hash
|
17
|
+
def call(ctx, **)
|
18
|
+
return false unless ctx[@key]
|
19
|
+
return false unless VALID_CURRENT_USER_CLASS_NAMES.include? ctx[@key].class.name.demodulize
|
20
|
+
|
21
|
+
ctx[:current_user] = ctx[@key]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/macros/error.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Macros
|
4
|
+
class Error
|
5
|
+
# Set error messages in the context using contract errors
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# step Macros::Error::SetFromContract
|
9
|
+
class SetFromContract < Macros::Base
|
10
|
+
def call(ctx, **)
|
11
|
+
error_messages = ctx['contract.default']&.errors&.messages
|
12
|
+
return false unless error_messages
|
13
|
+
|
14
|
+
ctx[:error_messages] = error_messages
|
15
|
+
!!ctx[:error_messages]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/macros/model.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Macros
|
4
|
+
class Model
|
5
|
+
class Build < Macros::Base
|
6
|
+
# @return [Macros::Model::Build] step macro instance
|
7
|
+
# @param from [Hash] required attribute, key in the context to build model class from
|
8
|
+
# @example
|
9
|
+
# Macros::Model::Build(from: :scope)
|
10
|
+
# @param condition [Hash] attribute the model should respond to as the condition to be set.
|
11
|
+
# @example model should respond to :last_sign_in_at
|
12
|
+
# Macros::Model::Build(from: :scope, respond_to: :last_sign_in_at)
|
13
|
+
|
14
|
+
def initialize(from:, respond_to: nil)
|
15
|
+
@from = from
|
16
|
+
@respond_to = respond_to
|
17
|
+
end
|
18
|
+
|
19
|
+
# Sets the model in the context
|
20
|
+
# @param ctx [Trailblazer::Skill] tbl context hash
|
21
|
+
def call(ctx, **)
|
22
|
+
scope = ctx[@from]
|
23
|
+
return false unless scope
|
24
|
+
|
25
|
+
klass = scope.to_s.classify.constantize
|
26
|
+
return false if @respond_to && !klass.new.respond_to?(@respond_to)
|
27
|
+
|
28
|
+
ctx[:model] = klass.new
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Macros
|
4
|
+
class Model
|
5
|
+
class Copy < Macros::Base
|
6
|
+
def initialize(ctx_key = nil)
|
7
|
+
@ctx_key = ctx_key
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(ctx, **)
|
11
|
+
return false unless ctx[@ctx_key]
|
12
|
+
|
13
|
+
ctx[:model] = ctx[@ctx_key]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Macros
|
4
|
+
class Model
|
5
|
+
# Destroy step for removing object assigned in ctx['model']
|
6
|
+
# @example
|
7
|
+
# step Macros::Model::Destroy()
|
8
|
+
class Destroy < Macros::Base
|
9
|
+
# Destroys a given model
|
10
|
+
# @param _ctx [Trailblazer::Skill] context accumulator
|
11
|
+
# @param model [Object] object that we want to destroy
|
12
|
+
def call(_ctx, model:, **)
|
13
|
+
model.destroy
|
14
|
+
model.destroyed?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Macros
|
4
|
+
class Model
|
5
|
+
# Persist object from the context
|
6
|
+
# @example
|
7
|
+
# step Macros::Model::Persist(ctx_key: :weekly_plan_editing)
|
8
|
+
class Persist < Macros::Base
|
9
|
+
def initialize(ctx_key: :model, method: :save!)
|
10
|
+
@ctx_key = ctx_key
|
11
|
+
@method = method
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(ctx, **)
|
15
|
+
return false unless ctx[@ctx_key]
|
16
|
+
|
17
|
+
ctx[@ctx_key].public_send(@method)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Macros
|
4
|
+
class Search
|
5
|
+
class Query < Macros::Base
|
6
|
+
# @return [Macros::Search::Results] step macro instance
|
7
|
+
#
|
8
|
+
# @example searchable is optional
|
9
|
+
# Macros::Search::Query(searchable: Admin)
|
10
|
+
def initialize(searchable:)
|
11
|
+
@searchable = searchable
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param ctx [Trailblazer::Skill] tbl context hash
|
15
|
+
#
|
16
|
+
# The search params are passed in ctx[:params] and look like this:
|
17
|
+
# `{q: 'the query', page: 2}`
|
18
|
+
#
|
19
|
+
# The orders is passed in ctx[:order] and looks like this:
|
20
|
+
# `{created_at: :desc}`
|
21
|
+
def call(ctx, params:, order: nil, **)
|
22
|
+
return false unless @searchable
|
23
|
+
|
24
|
+
ctx[:searchable] = @searchable
|
25
|
+
ransack_search_result = @searchable.ransack params[:q]
|
26
|
+
ctx[:query] = ransack_search_result
|
27
|
+
|
28
|
+
temp_search_results = ransack_search_result.result
|
29
|
+
search_results = order ? temp_search_results.order(order) : temp_search_results
|
30
|
+
ctx[:search_results] = search_results.page params[:page]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Macros
|
4
|
+
class VerifyParams
|
5
|
+
class Date < Macros::Base
|
6
|
+
def initialize(params_key: :date)
|
7
|
+
@params_key = params_key
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(ctx, **)
|
11
|
+
return false unless ctx[:params]
|
12
|
+
|
13
|
+
ctx[:params][@params_key].class == ::Date
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Macros::Auth::Authenticate do
|
4
|
+
include Warden::Test::Mock
|
5
|
+
|
6
|
+
subject(:authenticate_step) { described_class.new }
|
7
|
+
|
8
|
+
before do
|
9
|
+
warden.set_user(user, scope: scope)
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:user) { mock_model('User') }
|
13
|
+
let(:scope) { :user }
|
14
|
+
let(:ctx) { {} }
|
15
|
+
|
16
|
+
it 'expects to authenticate' do
|
17
|
+
authenticate_step.call(ctx, scope: scope, warden: warden)
|
18
|
+
|
19
|
+
expect(ctx[:model]).to eql user
|
20
|
+
end
|
21
|
+
end
|