This is a really quick and dirty example of how you can infer a form schema from a dry-type Struct or Value and how you might use it in a HTTP controller.
Last active
March 26, 2016 14:45
-
-
Save coop/4a035a609fffa74eb4ac to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "rspec" | |
require "json" | |
require "dry-types" | |
require "dry-validation" | |
module Types | |
include Dry::Types.module | |
RegionCode = Types::Strict::String.constrained( | |
format: /\A(au|nz|uk|ie)\z/, | |
) | |
end | |
class OpenSettlement < Dry::Types::Value | |
attribute :region_code, Types::RegionCode | |
attribute :period_ending_on, Types::Strict::Date | |
end | |
class CommandsController | |
attr_reader :payload | |
def initialize(payload) | |
@payload = payload | |
end | |
def call | |
payload_validator.call(payload).messages | |
end | |
private | |
def payload_validator | |
command_present = !(command.nil? || command == "") | |
validator = arg_validator if command_present | |
@payload_validator ||= Dry::Validation.Form do | |
key(:command).required | |
if command_present | |
key(:args).schema(validator) | |
else | |
key(:args).maybe(:hash?) | |
end | |
end | |
end | |
def arg_validator | |
arg_validators[command_klass] | |
end | |
def arg_validators | |
@arg_validators ||= Hash.new do |hash, key| | |
hash[key] = Dry::Validation.Form do | |
key.schema.each do |attribute, type| | |
key(attribute).required(type) | |
end | |
end | |
end | |
end | |
def command_klass | |
@command_klass ||= Object.const_get(payload[:command]) | |
end | |
def command | |
payload[:command] | |
end | |
def args | |
payload[:args] | |
end | |
end | |
RSpec.describe "command enqueuing" do | |
it "errors with an empty payload" do | |
payload = {} | |
controller = CommandsController.new(payload) | |
errors = controller.call | |
expect(errors).to eq( | |
command: ["is missing"], | |
args: ["is missing"], | |
) | |
end | |
it "errors when command is missing from payload" do | |
payload = { | |
args: {}, | |
} | |
controller = CommandsController.new(payload) | |
errors = controller.call | |
expect(errors).to eq( | |
command: ["is missing"], | |
) | |
end | |
it "errors with an invalid set of args" do | |
payload = { | |
command: "OpenSettlement", | |
args: { | |
region_code: "au", | |
}, | |
} | |
controller = CommandsController.new(payload) | |
errors = controller.call | |
expect(errors).to eq( | |
args: { | |
period_ending_on: ["is missing"], | |
}, | |
) | |
end | |
it "validates correct params" do | |
payload = { | |
command: "OpenSettlement", | |
args: { | |
region_code: "au", | |
period_ending_on: "2016-03-31", | |
}, | |
} | |
controller = CommandsController.new(payload) | |
errors = controller.call | |
expect(errors).to be_empty | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment