diff --git a/Gemfile.lock b/Gemfile.lock index 3777cfe..5100223 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,11 +1,10 @@ PATH remote: ../trailblazer specs: - trailblazer (2.0.0.beta1) + trailblazer (2.0.6) declarative reform (>= 2.2.0, < 3.0.0) - trailblazer-operation - uber (>= 0.1.0, < 0.2.0) + trailblazer-operation (>= 0.0.12, < 0.1.0) PATH remote: . @@ -17,12 +16,16 @@ GEM remote: https://rubygems.org/ specs: concurrent-ruby (1.0.2) - declarative (0.0.8) - uber (>= 0.0.15) - disposable (0.3.2) - declarative (>= 0.0.8, < 1.0.0) + declarative (0.0.9) + declarative-builder (0.1.0) + declarative-option (< 0.2.0) + declarative-option (0.1.0) + disposable (0.4.3) + declarative (>= 0.0.9, < 1.0.0) + declarative-builder (< 0.2.0) + declarative-option (< 0.2.0) representable (>= 2.4.0, <= 3.1.0) - uber + uber (< 0.2.0) dry-configurable (0.3.0) concurrent-ruby (~> 1.0) dry-container (0.5.0) @@ -57,19 +60,19 @@ GEM minitest-line (0.6.3) minitest (~> 5.0) multi_json (1.12.1) - pipetree (0.0.4) + pipetree (0.1.1) rake (11.3.0) - reform (2.2.3) - disposable (>= 0.3.0, < 0.4.0) + reform (2.2.4) + disposable (>= 0.4.1) representable (>= 2.4.0, < 3.1.0) - uber (>= 0.0.15, < 0.2.0) - representable (3.0.2) - declarative (~> 0.0.5) - uber (>= 0.0.15, < 0.2.0) - trailblazer-operation (0.0.6) + representable (3.0.4) + declarative (< 0.1.0) + declarative-option (< 0.2.0) + uber (< 0.2.0) + trailblazer-operation (0.0.13) declarative - pipetree (>= 0.0.4, < 0.1.0) - uber (>= 0.1.0, < 0.2.0) + pipetree (>= 0.1.1, < 0.2.0) + uber uber (0.1.0) PLATFORMS @@ -86,4 +89,4 @@ DEPENDENCIES trailblazer-endpoint! BUNDLED WITH - 1.12.5 + 1.14.6 diff --git a/lib/trailblazer/endpoint.rb b/lib/trailblazer/endpoint.rb index 8879e38..c5b853a 100644 --- a/lib/trailblazer/endpoint.rb +++ b/lib/trailblazer/endpoint.rb @@ -19,10 +19,13 @@ class Endpoint resolve: ->(result) { result }), # TODO: we could add unauthorized here. unauthenticated: Dry::Matcher::Case.new( - match: ->(result) { result.failure? && result["result.policy.default"].failure? }, # FIXME: we might need a &. here ;) + match: ->(result) { result.failure? && result["result.policy.default"] && result["result.policy.default"].failure? }, resolve: ->(result) { result }), invalid: Dry::Matcher::Case.new( match: ->(result) { result.failure? && result["result.contract.default"] && result["result.contract.default"].failure? }, + resolve: ->(result) { result }), + failure: Dry::Matcher::Case.new( + match: ->(result) { result.failure? }, resolve: ->(result) { result }) ) @@ -35,6 +38,7 @@ def self.call(operation_class, handlers, *args, &block) def call(result, handlers=nil, &block) matcher.(result, &block) and return if block_given? # evaluate user blocks first. matcher.(result, &handlers) # then, generic Rails handlers in controller context. + rescue Dry::Matcher::NonExhaustiveMatchError # tmp solution, need to figure our how to handle NonExhaustiveMatchError errors end def matcher diff --git a/lib/trailblazer/endpoint/rails.rb b/lib/trailblazer/endpoint/rails.rb index dac01ab..8dccf84 100644 --- a/lib/trailblazer/endpoint/rails.rb +++ b/lib/trailblazer/endpoint/rails.rb @@ -21,6 +21,7 @@ def call m.created { |result| controller.head 201, location: "#{@path}/#{result["model"].id}" }#, result["representer.serializer.class"].new(result["model"]).to_json m.success { |result| controller.head 200, location: "#{@path}/#{result["model"].id}" } m.invalid { |result| controller.render json: result["representer.errors.class"].new(result['result.contract.default'].errors).to_json, status: 422 } + m.failure { |result| controller.render json: { :error=>"unknown error" }, status: 422 } end end end diff --git a/test/endpoint_test.rb b/test/endpoint_test.rb index 3abc0bc..120a911 100644 --- a/test/endpoint_test.rb +++ b/test/endpoint_test.rb @@ -1,4 +1,4 @@ -require "test_helper" +require "./test_helper" require "reform" require "trailblazer" @@ -85,7 +85,6 @@ class Create < Trailblazer::Operation step Model( Song, :new ) step Contract::Build() step Contract::Validate( representer: self["representer.deserializer.class"] ) - step Persist( method: :sync ) step ->(options) { options["model"].id = 9 } end @@ -100,7 +99,6 @@ def render(options) # not authenticated, 401 it do result = Create.( { id: 1 }, "user.current" => false ) - # puts "@@@@@ #{result.inspect}" Trailblazer::Endpoint.new.(result, handlers) _data.inspect.must_equal %{[[:head, 401]]} @@ -110,14 +108,13 @@ def render(options) # length is ignored as it's not defined in the deserializer. it do result = Create.( {}, "user.current" => ::Module, "document" => '{"id": 9, "title": "Encores", "length": 999 }' ) - # puts "@@@@@ #{result.inspect}" Trailblazer::Endpoint.new.(result, handlers) _data.inspect.must_equal '[[:head, 201, {:location=>"/songs/9"}]]' end - class Update < Create - self.~ Model( :find_by ) + class Update < Trailblazer::Operation + step Model( Song, :find_by ) end # 404 @@ -128,6 +125,22 @@ class Update < Create _data.inspect.must_equal '[[:head, 404]]' end + class Verified < Trailblazer::Operation + step :verified + + def verified(options, params:, **) + false + end + end + + # failure case when you don't have any contract or policies, but operation failed + it do + result = Verified.({}, "user.current" => ::Module ) + + Trailblazer::Endpoint.new.(result, handlers) + _data.inspect.must_equal "[{:json=>{:error=>\"unknown error\"}, :status=>422}]" + end + #--- # validation failure 422 # success @@ -154,10 +167,12 @@ class Update < Create end # generic handler because user handler doesn't match. + # TODO: fix this, it's fail because we expect user handlers to be run if they were passed + # need to figure out how to run generic Rails handlers if there was no correct user handler it do invoked = nil - endpoint( Update, { id: nil }, args: {"user.current" => ::Module} ) do |res| + endpoint(Update, args: [{ id: nil }, {"user.current" => ::Module}]) do |res| res.invalid { invoked = "my invalid!" } end @@ -167,7 +182,7 @@ class Update < Create # only generic handler it do - endpoint(Update, { id: nil }) + endpoint(Update, args: [{ id: nil }, {"user.current" => ::Module}] ) _data.must_equal [[:head, 404]] end end diff --git a/test/rails-app/Gemfile b/test/rails-app/Gemfile index f21143a..6dd8dea 100644 --- a/test/rails-app/Gemfile +++ b/test/rails-app/Gemfile @@ -1,6 +1,5 @@ source 'https://rubygems.org' - # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 5.0.0', '>= 5.0.0.1' # Use sqlite3 as the database for Active Record @@ -10,8 +9,7 @@ gem 'sqlite3' gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] gem "trailblazer-endpoint", path: "../../." -gem "trailblazer", path: "../../../trailblazer" -gem "trailblazer-operation", path: "../../../operation" -# gem "trailblazer-rails" +gem "trailblazer" +gem "trailblazer-operation" gem "multi_json" diff --git a/test/rails-app/Gemfile.lock b/test/rails-app/Gemfile.lock index a72cf06..d5ca239 100644 --- a/test/rails-app/Gemfile.lock +++ b/test/rails-app/Gemfile.lock @@ -1,22 +1,5 @@ PATH - remote: ../../../operation - specs: - trailblazer-operation (0.0.6) - declarative - pipetree (>= 0.0.4, < 0.1.0) - uber (>= 0.1.0, < 0.2.0) - -PATH - remote: ../../../trailblazer - specs: - trailblazer (2.0.0.beta1) - declarative - reform (>= 2.2.0, < 3.0.0) - trailblazer-operation - uber (>= 0.1.0, < 0.2.0) - -PATH - remote: ../../. + remote: ../.. specs: trailblazer-endpoint (0.0.1) dry-matcher @@ -64,12 +47,16 @@ GEM arel (7.1.4) builder (3.2.2) concurrent-ruby (1.0.2) - declarative (0.0.8) - uber (>= 0.0.15) - disposable (0.3.2) - declarative (>= 0.0.8, < 1.0.0) + declarative (0.0.9) + declarative-builder (0.1.0) + declarative-option (< 0.2.0) + declarative-option (0.1.0) + disposable (0.4.3) + declarative (>= 0.0.9, < 1.0.0) + declarative-builder (< 0.2.0) + declarative-option (< 0.2.0) representable (>= 2.4.0, <= 3.1.0) - uber + uber (< 0.2.0) dry-matcher (0.5.0) erubis (2.7.0) globalid (0.3.7) @@ -89,7 +76,7 @@ GEM nio4r (1.2.1) nokogiri (1.6.8.1) mini_portile2 (~> 2.1.0) - pipetree (0.0.4) + pipetree (0.1.1) rack (2.0.1) rack-test (0.6.3) rack (>= 1.0) @@ -117,13 +104,13 @@ GEM rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rake (11.3.0) - reform (2.2.3) - disposable (>= 0.3.0, < 0.4.0) + reform (2.2.4) + disposable (>= 0.4.1) representable (>= 2.4.0, < 3.1.0) - uber (>= 0.0.15, < 0.2.0) - representable (3.0.2) - declarative (~> 0.0.5) - uber (>= 0.0.15, < 0.2.0) + representable (3.0.4) + declarative (< 0.1.0) + declarative-option (< 0.2.0) + uber (< 0.2.0) sprockets (3.7.0) concurrent-ruby (~> 1.0) rack (> 1, < 3) @@ -134,6 +121,15 @@ GEM sqlite3 (1.3.12) thor (0.19.1) thread_safe (0.3.5) + trailblazer (2.0.0) + declarative + reform (>= 2.2.0, < 3.0.0) + trailblazer-operation (>= 0.0.9) + uber (>= 0.1.0, < 0.2.0) + trailblazer-operation (0.0.13) + declarative + pipetree (>= 0.1.1, < 0.2.0) + uber tzinfo (1.2.2) thread_safe (~> 0.1) uber (0.1.0) @@ -148,10 +144,10 @@ DEPENDENCIES multi_json rails (~> 5.0.0, >= 5.0.0.1) sqlite3 - trailblazer! + trailblazer trailblazer-endpoint! - trailblazer-operation! + trailblazer-operation tzinfo-data BUNDLED WITH - 1.12.5 + 1.14.6 diff --git a/test/test_helper.rb b/test/test_helper.rb index ada5c51..acb25c2 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,3 +1,4 @@ +$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) + require "minitest/autorun" require "trailblazer" -require "trailblazer/endpoint"