[Catalyst-dev] subdomain hook for Catalyst::Test
Jason Gottshall
jgottshall at capwiz.com
Fri Oct 3 18:33:00 BST 2008
Matt S Trout wrote:
> 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)
Good point. We actually do full-blown white-labeling in addition to
virtual subdomains, which I hadn't really begun to consider yet. But it
is going to be basically the same mechanism, so it's worthing including.
Now that I think about it, what would/should happen if the test
specifies a complete white-label domain and you've got
$ENV{CATALYST_SERVER} set to run tests on a "remote" server? I guess you
would need to have a local hosts file set up to route those requests
back to the test server, or something. That's one main reason that I
still want to allow explicitly for subdomains: my local DNS already
handles virtual subdomains for the domain(s) where I run my
CATALYST_SERVER, so tests that specify a subdomain will already work
locally or remotely.
I'm happy to implement the full white-labeling piece as well, but it
seems to have some caveats...
>> 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' );
>
> };
Why doesn't my brain come up with lovely stuff like that?
Jason
More information about the Catalyst-dev
mailing list