[Jifty-commit] r5223 - in Net-Jifty: . t

Jifty commits jifty-commit at lists.jifty.org
Mon Mar 17 13:18:21 EDT 2008


Author: sartak
Date: Mon Mar 17 13:18:20 2008
New Revision: 5223

Added:
   Net-Jifty/t/005-validate.t
Modified:
   Net-Jifty/   (props changed)
   Net-Jifty/Changes
   Net-Jifty/lib/Net/Jifty.pm

Log:
 r52726 at onn:  sartak | 2008-03-17 13:18:08 -0400
 Add validate_action_args method and have ->act, ->create, etc use it if the
 strict_arguments attribute is true
 Idea and proof of concept by John SJ Anderson


Modified: Net-Jifty/Changes
==============================================================================
--- Net-Jifty/Changes	(original)
+++ Net-Jifty/Changes	Mon Mar 17 13:18:20 2008
@@ -6,6 +6,9 @@
             with config in it. Each file is Hash::Merge'd. This lets your
             app have whatever context you want, based on where you are.
         appname is no longer required
+        Add validate_action_args method and have ->act, ->create, etc use it
+            if the strict_arguments attribute is true
+                idea and proof of concept by John SJ Anderson
 
 0.05    Mon Dec 21 01:56:40
         Removed canonicalize_action and canonicalize_model

Modified: Net-Jifty/lib/Net/Jifty.pm
==============================================================================
--- Net-Jifty/lib/Net/Jifty.pm	(original)
+++ Net-Jifty/lib/Net/Jifty.pm	Mon Mar 17 13:18:20 2008
@@ -178,6 +178,13 @@
     documentation => "The filename to look for in each parent directory",
 );
 
+has strict_arguments => (
+    is            => 'rw',
+    isa           => 'Bool',
+    default       => 0,
+    documentation => "Check to make sure mandatory arguments are provided, and no unknown arguments are included",
+);
+
 =head2 BUILD
 
 Each L<Net::Jifty> object will do the following upon creation:
@@ -393,6 +400,9 @@
     my $self   = shift;
     my $action = shift;
 
+    $self->validate_action_args($action => @_)
+        if $self->strict_arguments;
+
     return $self->post(["action", $action], @_);
 }
 
@@ -406,6 +416,9 @@
     my $self  = shift;
     my $model = shift;
 
+    $self->validate_action_args([create => $model] => @_)
+        if $self->strict_arguments;
+
     return $self->post(["model", $model], @_);
 }
 
@@ -421,6 +434,9 @@
     my $key    = shift;
     my $value  = shift;
 
+    $self->validate_action_args([delete => $model] => $key => $value)
+        if $self->strict_arguments;
+
     return $self->method(delete => ["model", $model, $key, $value]);
 }
 
@@ -436,6 +452,9 @@
     my $key    = shift;
     my $value  = shift;
 
+    $self->validate_action_args([update => $model] => $key => $value, @_)
+        if $self->strict_arguments;
+
     return $self->method(put => ["model", $model, $key, $value], @_);
 }
 
@@ -486,6 +505,55 @@
     return $self->get(["search", $model, @args]);
 }
 
+=head2 validate_action_args action => args
+
+Validates the given action, to check to make sure that all mandatory arguments
+are given and that no unknown arguments are given.
+
+You may give action as a string, which will be interpreted as the action name;
+or as an array reference for CRUD - the first element will be the action
+(create, update, or delete) and the second element will be the model name.
+
+This will throw an error or if validation succeeds, will return 1.
+
+=cut
+
+sub validate_action_args {
+    my $self   = shift;
+    my $action = shift;
+    my %args   = @_;
+
+    my $name;
+    if (ref($action) eq 'ARRAY') {
+        my ($operation, $model) = @$action;
+
+        # drop MyApp::Model::
+        $model =~ s/.*:://;
+
+        confess "Invalid model operation: $operation. Expected 'create', 'update', or 'delete'." unless $operation =~ m{^(?:create|update|delete)$}i;
+
+        $name = ucfirst(lc $operation) . $model;
+    }
+    else {
+        $name = $action;
+    }
+
+    my $action_args = $self->get("action/$name");
+
+    for my $arg (keys %$action_args) {
+        confess "Mandatory argument '$arg' not given for action $name."
+            if $action_args->{$arg}{mandatory} && !defined($args{$arg});
+        delete $args{$arg};
+    }
+
+    if (keys %args) {
+        confess "Unknown arguments given for action $name: "
+              . join(', ', keys %args);
+    }
+
+    return 1;
+}
+
 =head2 get_sid
 
 Retrieves the sid from the L<LWP::UserAgent> object.

Added: Net-Jifty/t/005-validate.t
==============================================================================
--- (empty file)
+++ Net-Jifty/t/005-validate.t	Mon Mar 17 13:18:20 2008
@@ -0,0 +1,111 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use Test::More tests => 20;
+use lib 't/lib';
+use Net::Jifty::Test;
+
+my $j = Net::Jifty::Test->new();
+$j->ua->clear();
+
+my %args = (
+    a => 'b',
+    c => 'd',
+);
+
+$Net::Jifty::Test::content = << "YAML";
+---
+a: {}
+b: {}
+c: {}
+YAML
+
+$j->validate_action_args(["create", "Jifty::Model::Foo"], %args);
+my ($name, $args) = $j->ua->next_call;
+is($name, 'get', 'used get for validation');
+is($args->[1], 'http://jifty.org/=/action/CreateFoo.yml', 'correct URL');
+$j->ua->clear;
+
+$Net::Jifty::Test::content = << "YAML";
+---
+a:
+    mandatory: 1
+c:
+    mandatory: 1
+YAML
+
+$j->validate_action_args(["create", "Jifty::Model::Foo"], %args);
+($name, $args) = $j->ua->next_call;
+is($name, 'get', 'used get for validation');
+is($args->[1], 'http://jifty.org/=/action/CreateFoo.yml', 'correct URL');
+$j->ua->clear;
+
+$Net::Jifty::Test::content = << "YAML";
+---
+a:
+    mandatory: 1
+b:
+    mandatory: 1
+c:
+    mandatory: 1
+YAML
+
+eval { $j->validate_action_args("CreateFoo", %args) };
+like($@, qr/^Mandatory argument 'b' not given for action CreateFoo\. at /);
+
+($name, $args) = $j->ua->next_call;
+is($name, 'get', 'used get for validation');
+is($args->[1], 'http://jifty.org/=/action/CreateFoo.yml', 'correct URL');
+$j->ua->clear;
+
+$Net::Jifty::Test::content = << "YAML";
+---
+a:
+    mandatory: 1
+b: {}
+YAML
+
+eval { $j->validate_action_args(["create", "Jifty::Model::Foo"], %args) };
+like($@, qr/^Unknown arguments given for action CreateFoo: c at /);
+
+($name, $args) = $j->ua->next_call;
+is($name, 'get', 'used get for validation');
+is($args->[1], 'http://jifty.org/=/action/CreateFoo.yml', 'correct URL');
+$j->ua->clear;
+
+
+$j = Net::Jifty::Test->new(strict_arguments => 1);
+$j->ua->clear();
+
+$Net::Jifty::Test::content = << "YAML";
+---
+c: {}
+YAML
+
+eval { $j->act("CreateFoo", %args) };
+like($@, qr/^Unknown arguments given for action CreateFoo: a at /);
+($name, $args) = $j->ua->next_call;
+is($name, 'get', 'used get for validation');
+is($args->[1], 'http://jifty.org/=/action/CreateFoo.yml', 'correct URL');
+$j->ua->clear;
+
+$Net::Jifty::Test::content = << "YAML";
+---
+a: {}
+c: {}
+YAML
+
+$j->create("Jifty::Model::Foo", %args);
+($name, $args) = $j->ua->next_call;
+is($name, 'get', 'used get for validation');
+is($args->[1], 'http://jifty.org/=/action/CreateFoo.yml', 'correct URL');
+
+($name, $args) = $j->ua->next_call;
+is($name, 'request', 'used request for create');
+isa_ok($args->[1], 'HTTP::Request', 'argument is an HTTP request');
+is($args->[1]->method, 'POST', 'correct method (POST)');
+is($args->[1]->uri, 'http://jifty.org/=/model/Jifty%3A%3AModel%3A%3AFoo.yml', 'correct URL');
+like($args->[1]->content, qr/^(a=b&c=d|c=d&a=b)$/, 'correct arguments');
+
+$j->ua->clear;
+


More information about the Jifty-commit mailing list