#!/usr/bin/env perl use warnings; use strict; use Jifty::Test::Dist tests => 101; use Jifty::Test::WWW::Mechanize; my $server = Jifty::Test->make_server; isa_ok($server, 'Jifty::Server'); my $URL = $server->started_ok; my $mech = Jifty::Test::WWW::Mechanize->new(); ok(1, 'Loaded the test script'); my $u1 = TestApp::Plugin::REST::Model::User->new( current_user => TestApp::Plugin::REST::CurrentUser->superuser, ); $u1->create(name => 'test', email => 'test@example.com'); ok($u1->id); our $FORMAT_NUMBER; sub result_of { local $Test::Builder::Level = $Test::Builder::Level + 1; my $request = shift; my $test = shift; if (!ref($request)) { $request = { mech_method => 'get', url => $request, }; } my %loaders = ( yml => \&Jifty::YAML::Load, json => \&Jifty::JSON::jsonToObj, js => sub { my $js = shift; $js =~ s/.*? = //; # variable assignment return Jifty::JSON::jsonToObj($js); }, ); local $FORMAT_NUMBER = 0; for my $format (keys %loaders) { $FORMAT_NUMBER++; my $url = $URL . $request->{url} . '.' . $format; my $method = $request->{mech_method}; my $response = $mech->$method($url, @{ $request->{mech_args} || [] }); ok($response->is_success, "$method successful"); my @contents = $response->content; if (my $location = $response->header('Location')) { $response = $mech->get($location); ok($response->is_success, "redirect successful"); push @contents, $response->content; } local $Test::Builder::Level = $Test::Builder::Level + 1; eval { @contents = map { scalar $loaders{$format}->($_) } @contents; }; fail($@) if $@; $test->(@contents); } } sub result_of_post { local $Test::Builder::Level = $Test::Builder::Level + 1; my $request = shift; my $parameters = shift; my $test = shift; if (!ref($request)) { $request = { mech_method => 'post', mech_args => [$parameters], url => $request, }; } result_of($request, $test); } result_of '/=/model' => sub { is_deeply($_[0], [ 'TestApp.Plugin.REST.Model.Group', 'TestApp.Plugin.REST.Model.User', ]); }; result_of '/=/model/User' => sub { is(scalar keys %{ $_[0] }, 4, 'four keys in the user record'); }; result_of '/=/model/user/id' => sub { is(@{ $_[0] }, 1, "one user"); }; result_of '/=/model/user/id/1' => sub { is_deeply($_[0], { name => 'test', email => 'test@example.com', id => 1, tasty => undef, }); }; result_of '/=/model/user/id/1/email' => sub { is($_[0], 'test@example.com'); }; result_of_post '/=/model/user' => { name => 'moose', email => 'moose@example.com', } => sub { my ($action_result, $record) = @_; my $id = 2 + ($FORMAT_NUMBER - 1); is_deeply($action_result, { action_class => 'TestApp::Plugin::REST::Action::CreateUser', content => { id => $id }, error => undef, failure => 0, field_errors => {}, field_warnings => {}, message => 'Created', success => 1, }); is_deeply($record, { email => 'moose@example.com', id => $id, name => 'moose', tasty => undef, }); }; # on PUT '/=/model/*/*/*' => \&replace_item; # on DELETE '/=/model/*/*/*' => \&delete_item; # on POST '/=/model/*' => \&create_item; $mech->post( $URL . '/=/model/User', { name => "moose", email => 'moose@example.com' } ); is($mech->status, 200, "create via POST to model worked"); $mech->post( $URL . '/=/model/Group', { } ); is($mech->status, 403, "create via POST to model with disallowed create action failed with 403"); # on GET '/=/search/*/**' => \&search_items; $mech->get_ok('/=/search/user/id/1.yml'); my $content = get_content(); is_deeply($content, [{ name => 'test', email => 'test@example.com', id => 1, tasty => undef }]); $mech->get_ok('/=/search/user/id/1/name/test.yml'); $content = get_content(); is_deeply($content, [{ name => 'test', email => 'test@example.com', id => 1, tasty => undef }]); $mech->get_ok('/=/search/user/id/1'); $content = get_content(); unlike($content, qr/HASH/); like($content, qr/test\@example.com/); $mech->get_ok('/=/search/user/id/1.html'); $content = get_content(); like($content, qr/test\@example.com/); $mech->get_ok('/=/search/user/id/1/name/test/email.yml'); $content = get_content(); is_deeply($content, ['test@example.com']); $mech->get('/=/search/Usery/id/1.yml'); is($mech->status,'404'); $mech->get('/=/search/user/id/1/name/foo.yml'); is($mech->status,'200'); $content = get_content(); is_deeply($content, []); # on GET '/=/action' => \&list_actions; my @actions = qw( TestApp.Plugin.REST.Action.CreateGroup TestApp.Plugin.REST.Action.UpdateGroup TestApp.Plugin.REST.Action.SearchGroup TestApp.Plugin.REST.Action.ExecuteGroup TestApp.Plugin.REST.Action.CreateUser TestApp.Plugin.REST.Action.UpdateUser TestApp.Plugin.REST.Action.DeleteUser TestApp.Plugin.REST.Action.SearchUser TestApp.Plugin.REST.Action.ExecuteUser TestApp.Plugin.REST.Action.DoSomething Jifty.Action.Autocomplete Jifty.Action.Redirect); $mech->get_ok('/=/action/'); is($mech->status, 200); for (@actions) { $mech->content_contains($_); } $mech->get_ok('/=/action.yml'); my @got = @{get_content()}; is( join(",", sort @got ), join(",",sort @actions), , "Got all the actions as YAML"); # on GET '/=/action/*' => \&list_action_params; $mech->get_ok('/=/action/DoSomething'); is($mech->status, 200); $mech->get_ok('/=/action/TestApp::Plugin::REST::Action::DoSomething'); is($mech->status, 200); $mech->get_ok('/=/action/TestApp.Plugin.REST.Action.DoSomething'); is($mech->status, 200); # Parameter name $mech->content_contains('email'); # Parameter label $mech->content_contains('Email'); # Default value $mech->content_contains('example@email.com'); $mech->get_ok('/=/action/DoSomething.yml'); is($mech->status, 200); my %args = %{get_content()}; ok($args{email}, "Action has an email parameter"); is($args{email}{label}, 'Email', 'email has the correct label'); is($args{email}{default_value}, 'example@email.com', 'email has the correct default'); # on POST '/=/action/*' => \&run_action; # $mech->post( $URL . '/=/action/DoSomething', { email => 'good@email.com' } ); $mech->content_contains('Something happened!'); $mech->post( $URL . '/=/action/DoSomething', { email => 'bad@email.com' } ); $mech->content_contains('Bad looking email'); $mech->content_lacks('Something happened!'); $mech->post( $URL . '/=/action/DoSomething', { email => 'warn@email.com' } ); $mech->content_contains('Warning for email'); $mech->content_contains('Something happened!'); # Test YAML posts $mech->post ( $URL . '/=/action/DoSomething.yml', { email => 'good@email.com' } ); my %content; eval { %content = %{get_content()}; }; ok($content{success}); is($content{message}, 'Something happened!'); $mech->post ( $URL . '/=/action/DoSomething.yaml', { email => 'bad@email.com' } ); eval { %content = %{get_content()}; }; ok(!$content{success}, "Action that doesn't validate fails"); is($content{field_errors}{email}, 'Bad looking email'); sub get_content { return Jifty::YAML::Load($mech->content)} 1;