#!/usr/bin/perl use Mojolicious::Lite -signatures; helper users => sub ($c) { # probably a database in reality? state $users => { 2 => 'John H', 4 => 'Sam A', } }; get '/' => sub ($c) { $c->render(template => 'index') } => 'index'; get '/user/:id' => [id => qr/\d*[02468]/] => sub ($c) { my $id = $c->param('id'); if ( exists app->users->{$id} ) { $c->redirect_to('user_by_name', name=>app->users->{$id} ) } else { $c->reply->not_found } } => 'user_by_id'; get '/user/:name' => sub ($c) { # a very inefficient grep here, don't use this in production!! if ( grep { $_ eq $c->param('name') } values app->users->%* ) { $c->render( template=>'user' ) } else { $c->reply->not_found } } => 'user_by_name'; app->start; __DATA__ @@ layouts/main.html.ep
User List
This is <%= $name %>'s Page
%= link_to Home => 'index'; ####
use Mojo::Base -strict, -signatures;
use Test::Mojo;
use Test::More;
use Mojo::File;
use Mojo::Util qw/url_escape/;
my $t = Test::Mojo->new( Mojo::File->new('/path/to/app.pl') );
$t->get_ok('/')->status_is(200)->content_like(qr/\bUser List\b/);
$t->get_ok('/user/1')->status_is(404);
$t->get_ok('/user/2')
->header_is(location => '/user/' . url_escape 'John H');
$t->get_ok('/user/3')->status_is(404);
$t->get_ok('/user/4')
->header_is(location => '/user/' . url_escape 'Sam A');
$t->get_ok('/user/5')->status_is(404);
$t->get_ok('/user/6')->status_is(404);
$t->get_ok('/user/2/') # trailing slash
->header_is(location => '/user/' . url_escape 'John H');
$t->get_ok('/user/John H')->status_is(200)
->content_like(qr/\bThis is John H's Page\b/);
$t->get_ok('/user/Sam A')->status_is(200)
->content_like(qr/\bThis is Sam A's Page\b/);
$t->get_ok('/user/John Doe')->status_is(404);
done_testing;