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

Jason Gottshall jgottshall at capwiz.com
Tue Sep 30 16:25:10 BST 2008


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' };

   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...

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.

I'll play with this and let you know what I come up with. Thanks for the 
input!

Jason




More information about the Catalyst-dev mailing list