[Catalyst-dev] subdomain hook for Catalyst::Test

Matt S Trout dbix-class at trout.me.uk
Wed Oct 1 02:12:21 BST 2008


On Tue, Sep 30, 2008 at 11:25:10AM -0400, Jason Gottshall wrote:
> Matt S Trout wrote:
> >On Wed, Sep 17, 2008 at 06:12:48PM -0400, Jason Gottshall wrote:
> >>Our app allows for virtual subdomains that (among other things) enable 
> >>specific behaviors in the app.
> >>
> >>For example,
> >>  http://www.myapp.com/foo/bar
> >>and
> >>  http://magic.myapp.com/foo/bar
> >>both point to same app, but the latter has "magic" behaviors associated 
> >>with it.
> >>
> >>The problem is that we're having trouble writing tests against specific 
> >>behaviors in our controller tests, particularly when we want to test 
> >>several different subdomains within the same script.
> >>
> >>My current solution is to set an environment variable in the test script 
> >>specifing the desired subdomain. I've added hooks to the app that will 
> >>use this value if available, so that controller tests using a "local" 
> >>instance of the app instantiated with Catalyst::Test and a faked request 
> >>will Just Work. But we run into trouble when we try to run the tests 
> >>against a "remote" server by setting CATALYST_SERVER. The env var 
> >>setting embedded in the script obviously is not visible to the server 
> >>instance that's running remotely.
> >>
> >>In order to remedy this problem, I've patched Catalyst::Test to look for 
> >>my new env var and prepend it to the CATALYST_SERVER host component. It 
> >>works great! But I'm wondering whether this patch is worthy of adding to 
> >>the core, or if there's a different way I should be approaching the 
> >>problem. Here's a diff against 5.70/trunk:
> >
> >Could we not make request() take the domain or something?
> >
> >It's currently single argument so adding an options hashref would be fine,
> >plus maybe some way to provide default values therefore in the cases where
> >we're doing request() from inside other code?
> 
> Sounds like a nice idea. Maybe the default value could be dealt with at 
> import time:
> 
>   use Test::More tests => 2;
>   use Catalyst::Test 'MyApp', { default_subdomain => 'fizzle' };

Don't make it subdomain only, many apps serve multiple distinct hosts
(think white-labeling)
 
>   ok( request( '/foo/' )->is_success, 'foo succeeds for fizzle' );
>   ok( request( '/foo/', { subdomain => 'snazzle' } )->is_redirect, 'foo 
> redirects for snazzle');
> 
> It would be nice, though, to have a mechanism for changing the "default" 
> at some point, so one could run groups of tests on a single subdomain 
> without having to pass it explicitly with each request. Of course, one 
> could always just wrap a set of tests for a specific subdomain in its 
> own test file, but that's not quite as cool...

how about $Catalyst::Test::default_domain or something, and then you can do

sub with_domain {
  my ($domain, $code) = @_;
  local $Catalyst::Test::default_domain = $domain;
  $code->();
}

with_domain 'foo.com' => sub {

  ok( request ('/foo/' )->is_success, 'w00t' );

};

> Matt's comments also jolted me to the realization that my original plan 
> for handling the subdomain for a "local" instance of the app was 
> probably misguided. Instead of hacking my app's code to recognize the 
> subdomain ENV var, I should have patched Catalyst::Test::local_request() 
>  to mock up the subdomain in the first place. Then my code doesn't have 
> to have a hack solely for the test environment, and 
> Catalyst::Test::request() does the Right Thing regardless of whether 
> it's operating locally or remotely. Duh.

Spot on.

-- 
      Matt S Trout       Need help with your Catalyst or DBIx::Class project?
   Technical Director                    http://www.shadowcat.co.uk/catalyst/
 Shadowcat Systems Ltd.  Want a managed development or deployment platform?
http://chainsawblues.vox.com/            http://www.shadowcat.co.uk/servers/



More information about the Catalyst-dev mailing list