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.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/Dockerfile +13 -0
  3. data/Gemfile +17 -0
  4. data/Gemfile.lock +117 -0
  5. data/MIT-LICENSE +18 -0
  6. data/README.md +147 -0
  7. data/lib/ff-tbl-macros.rb +29 -0
  8. data/lib/macros/auth.rb +9 -0
  9. data/lib/macros/auth/authenticate.rb +24 -0
  10. data/lib/macros/auth/sign_in.rb +43 -0
  11. data/lib/macros/auth/sign_out.rb +48 -0
  12. data/lib/macros/base.rb +37 -0
  13. data/lib/macros/contract.rb +8 -0
  14. data/lib/macros/contract/extract_params.rb +25 -0
  15. data/lib/macros/contract/prepopulate.rb +16 -0
  16. data/lib/macros/ctx.rb +9 -0
  17. data/lib/macros/ctx/copy.rb +18 -0
  18. data/lib/macros/ctx/inspect.rb +28 -0
  19. data/lib/macros/ctx/validate_presence.rb +20 -0
  20. data/lib/macros/current_user.rb +7 -0
  21. data/lib/macros/current_user/set.rb +25 -0
  22. data/lib/macros/error.rb +7 -0
  23. data/lib/macros/error/set_from_contract.rb +19 -0
  24. data/lib/macros/model.rb +10 -0
  25. data/lib/macros/model/build.rb +32 -0
  26. data/lib/macros/model/copy.rb +17 -0
  27. data/lib/macros/model/destroy.rb +18 -0
  28. data/lib/macros/model/persist.rb +21 -0
  29. data/lib/macros/search.rb +7 -0
  30. data/lib/macros/search/query.rb +34 -0
  31. data/lib/macros/verify_params.rb +7 -0
  32. data/lib/macros/verify_params/date.rb +17 -0
  33. data/lib/macros/version.rb +6 -0
  34. data/spec/lib/auth/authenticate_spec.rb +21 -0
  35. data/spec/lib/auth/sign_in_spec.rb +37 -0
  36. data/spec/lib/auth/sign_out_spec.rb +37 -0
  37. data/spec/lib/auth_spec.rb +15 -0
  38. data/spec/lib/contract/extract_params_spec.rb +35 -0
  39. data/spec/lib/contract/prepopulate_spec.rb +27 -0
  40. data/spec/lib/contract_spec.rb +14 -0
  41. data/spec/lib/ctx/copy_spec.rb +27 -0
  42. data/spec/lib/ctx/inspect_spec.rb +26 -0
  43. data/spec/lib/ctx/validate_presence_spec.rb +20 -0
  44. data/spec/lib/ctx_spec.rb +19 -0
  45. data/spec/lib/current_user.rb +7 -0
  46. data/spec/lib/current_user/set_spec.rb +24 -0
  47. data/spec/lib/error/set_from_contract_spec.rb +27 -0
  48. data/spec/lib/error_spec.rb +7 -0
  49. data/spec/lib/ff_tbl_macros_spec.rb +11 -0
  50. data/spec/lib/model/build_spec.rb +53 -0
  51. data/spec/lib/model/copy_spec.rb +26 -0
  52. data/spec/lib/model/destroy_spec.rb +13 -0
  53. data/spec/lib/model/persist_spec.rb +45 -0
  54. data/spec/lib/model_spec.rb +21 -0
  55. data/spec/lib/search/query_spec.rb +23 -0
  56. data/spec/lib/search_spec.rb +9 -0
  57. data/spec/lib/verify_params/date_spec.rb +22 -0
  58. data/spec/lib/verify_params_spec.rb +9 -0
  59. data/spec/spec_helper.rb +38 -0
  60. metadata +169 -0
@@ -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,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Macros
4
+ class Contract < Macros::Base
5
+ register :extract_params
6
+ register :prepopulate
7
+ end
8
+ 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,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Macros
4
+ class Ctx < Macros::Base
5
+ register :copy
6
+ register :inspect
7
+ register :validate_presence
8
+ end
9
+ end
@@ -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,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Macros
4
+ class CurrentUser < Macros::Base
5
+ register :set
6
+ end
7
+ 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
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Macros
4
+ class Error < Macros::Base
5
+ register :set_from_contract
6
+ end
7
+ end
@@ -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
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Macros
4
+ class Model < Macros::Base
5
+ register :build
6
+ register :copy
7
+ register :destroy
8
+ register :persist
9
+ end
10
+ end
@@ -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,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Macros
4
+ class Search < Macros::Base
5
+ register :query
6
+ end
7
+ 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,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Macros
4
+ class VerifyParams < Macros::Base
5
+ register :date
6
+ end
7
+ 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,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Macros
4
+ # Current version
5
+ VERSION = '0.1.8'
6
+ 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