Skip to content

Commit

Permalink
Implement router validations
Browse files Browse the repository at this point in the history
  • Loading branch information
apexatoll committed Sep 22, 2023
1 parent aafb730 commit b27e1b0
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 3 deletions.
27 changes: 27 additions & 0 deletions lib/kangaru/router.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,38 @@ module Kangaru
class Router
using Patches::Constantise

class UndefinedControllerError < StandardError; end

class UndefinedActionError < StandardError; end

attr_reader :command, :namespace

def initialize(command, namespace: Object)
@command = command
@namespace = namespace

validate_controller_defined!
validate_action_defined!
end

private

def controller_class
@controller_class ||= command.controller.constantise(root: namespace)
end

def validate_controller_defined!
return if namespace.const_defined?(command.controller)

raise UndefinedControllerError,
"#{command.controller} is not defined in #{namespace}"
end

def validate_action_defined!
return if controller_class.instance_methods.include?(command.action)

raise UndefinedActionError,
"#{command.action} is not defined by #{command.controller}"
end
end
end
16 changes: 16 additions & 0 deletions sig/kangaru/router.rbs
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
module Kangaru
class Router
class UndefinedControllerError < StandardError
end

class UndefinedActionError < StandardError
end

attr_reader command: Command
attr_reader namespace: Module

def initialize: (Command, ?namespace: Module) -> void

private

@controller_class: untyped

def controller_class: -> untyped

def validate_controller_defined!: -> void

def validate_action_defined!: -> void
end
end
45 changes: 42 additions & 3 deletions spec/kangaru/router_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,50 @@

let(:namespace) { SomeNamespace }

before { stub_const "SomeNamespace", Module.new }
let(:controller_class) do
Class.new(described_class) { def some_action = nil }
end

before do
stub_const "SomeNamespace", Module.new
stub_const "SomeNamespace::SomeController", controller_class
end

describe "#initialize" do
it "sets the attributes" do
expect(router).to have_attributes(command:, namespace:)
context "when command controller is not defined" do
let(:controller) { "AnotherController" }

it "raises an error" do
expect { router }.to raise_error(
described_class::UndefinedControllerError,
"#{controller} is not defined in #{namespace}"
)
end
end

context "when command controller is defined" do
let(:controller) { "SomeController" }

context "and command action is not defined" do
let(:controller_class) { Class.new(described_class) }

it "raises an error" do
expect { router }.to raise_error(
described_class::UndefinedActionError,
"#{action} is not defined by #{controller}"
)
end
end

context "and command action is defined" do
it "does not raise an error" do
expect { router }.not_to raise_error
end

it "sets the attributes" do
expect(router).to have_attributes(command:, namespace:)
end
end
end
end
end

0 comments on commit b27e1b0

Please sign in to comment.