From df47d0a07ced61182834dc4af0e629a51fe997ad Mon Sep 17 00:00:00 2001 From: Colin Kuskie Date: Thu, 28 Feb 2008 23:22:55 +0000 Subject: [PATCH] Add more POD to Pluggable. Add more POD to FlatRate.pm, for the to be written calculate method. Build create and new methods for Ship, convert existing code to throw exceptions. Tests for Ship, that look suspiciously similar to ShipDriver. --- lib/WebGUI/Pluggable.pm | 11 ++- lib/WebGUI/Shop/Ship.pm | 33 +++++--- lib/WebGUI/Shop/ShipDriver/FlatRate.pm | 3 +- t/Shop/Ship.t | 110 +++++++++++++++++++++++-- 4 files changed, 136 insertions(+), 21 deletions(-) diff --git a/lib/WebGUI/Pluggable.pm b/lib/WebGUI/Pluggable.pm index 709d6bf77..7fb0c2400 100644 --- a/lib/WebGUI/Pluggable.pm +++ b/lib/WebGUI/Pluggable.pm @@ -46,7 +46,7 @@ These functions are available from this package: #------------------------------------------------------------------- -=head2 instanciate ( module, method, params ) +=head2 instanciate ( module, sub, params ) Dynamically ensures that a plugin module is loaded into memory. Then instanciates a new object from the module. Croaks on failure. @@ -54,6 +54,15 @@ Dynamically ensures that a plugin module is loaded into memory. Then instanciate The name of the module you'd like to load like "WebGUI::Asset::Snippet"; +=head3 sub + +The name of the constructor you would like to invoke from the module. Usually "new", or sometimes "create". + +=head3 params + +An array ref of params to send to the constructor. In WebGUI, the first param should be a WebGUI::Session +object. + =cut sub instanciate { diff --git a/lib/WebGUI/Shop/Ship.pm b/lib/WebGUI/Shop/Ship.pm index 325828deb..d590ef728 100644 --- a/lib/WebGUI/Shop/Ship.pm +++ b/lib/WebGUI/Shop/Ship.pm @@ -7,6 +7,7 @@ use WebGUI::International; use WebGUI::Shop::ShipDriver; use WebGUI::Pluggable; use WebGUI::Utility; +use WebGUI::Exception; =head1 NAME @@ -41,7 +42,8 @@ sub _loadDriver { =head2 create ( $session, $class, $options ) -The interface method for creating new, configured instances of ShipDriver. +The interface method for creating new, configured instances of ShipDriver. If the ShipperDriver throws an exception, it is propagated +back up to the top. =head3 $session @@ -60,17 +62,18 @@ A list of properties to assign to this ShipperDriver. See C for det sub create { my $class = shift; my $session = shift; - croak "create requires a session object" + WebGUI::Error::InvalidParam->throw(error => q{Must provide a session variable}) unless ref $session eq 'WebGUI::Session'; my $requestedClass = shift; - croak "create requires the name of a class to create an object" + WebGUI::Error::InvalidParam->throw(error => q{Must provide a class to create an object}) unless defined $requestedClass; - croak "The requested class $class is not enabled in your WebGUI configuration file" + WebGUI::Error::InvalidParam->throw(error => qq{The requested class $requestedClass is not enabled in your WebGUI configuration file}) unless isIn($requestedClass, @{ WebGUI::Shop::Ship->getDrivers($session) } ); my $options = shift; - croak "You must pass a hashref of options to create a new ShipDriver object" + WebGUI::Error::InvalidParam->throw(error => q{You must pass a hashref of options to create a new ShipDriver object}) unless defined($options) and ref $options eq 'HASH' and scalar keys %{ $options }; - + my $driver = eval { WebGUI::Pluggable::instanciate($requestedClass, 'create', [ $session, $options ]) }; + return $driver; } #------------------------------------------------------------------- @@ -82,14 +85,14 @@ from the WebGUI config file. =head3 $session -A WebGUI::Session object. +A WebGUI::Session object. A WebGUI::Error::InvalidParam exception will be thrown if it doesn't get one. =cut sub getDrivers { my $class = shift; my $session = shift; - croak "getDrivers requires a session object" + WebGUI::Error::InvalidParam->throw(error => q{Must provide a session variable}) unless ref $session eq 'WebGUI::Session'; return $session->config->get('shippingDrivers'); } @@ -103,7 +106,7 @@ with the key of the primary hash being the shipperId of the driver, and sub keys =head3 $session -A WebGUI::Session object. +A WebGUI::Session object. A WebGUI::Error::InvalidParam exception will be thrown if it doesn't get one. =head3 @@ -121,7 +124,8 @@ sub getOptions { =head2 new ( $session, $shipperId ) Looks up an existing ShipperDriver in the db by shipperId and returns -that object. +that object. If the ShipperDriver throws an exception, it is propagated +back up to the top. =head3 $session @@ -136,11 +140,16 @@ The ID of a shipper to look up and instanciate. sub new { my $class = shift; my $session = shift; - croak "new requires a session object" + WebGUI::Error::InvalidParam->throw(error => q{Must provide a session variable}) unless ref $session eq 'WebGUI::Session'; my $shipperId = shift; - croak "new requires a shipperId" + WebGUI::Error::InvalidParam->throw(error => q{Must provide a shipperId}) unless defined $shipperId; + my $requestedClass = $session->db->quickScalar('select className from shipper where shipperId=?',[$shipperId]); + WebGUI::Error::ObjectNotFound->throw(error => q{shipperId not found in db}, id => $shipperId) + unless $requestedClass; + my $driver = eval { WebGUI::Pluggable::instanciate($requestedClass, 'new', [ $session, $shipperId ]) }; + return $driver; } 1; diff --git a/lib/WebGUI/Shop/ShipDriver/FlatRate.pm b/lib/WebGUI/Shop/ShipDriver/FlatRate.pm index 3d7dd0213..8e692e0bf 100644 --- a/lib/WebGUI/Shop/ShipDriver/FlatRate.pm +++ b/lib/WebGUI/Shop/ShipDriver/FlatRate.pm @@ -36,7 +36,8 @@ Returns a shipping price. Calculates the shipping price using the following form =head3 $cart A WebGUI::Shop::Cart object. The contents of the cart are analyzed to calculate -the shipping costs. +the shipping costs. If no items in the cart require shipping, then no shipping +costs are assessed. =cut diff --git a/t/Shop/Ship.t b/t/Shop/Ship.t index 61a149d78..954732286 100644 --- a/t/Shop/Ship.t +++ b/t/Shop/Ship.t @@ -31,7 +31,7 @@ my $session = WebGUI::Test->session; #---------------------------------------------------------------------------- # Tests -my $tests = 7; +my $tests = 23; plan tests => 1 + $tests; #---------------------------------------------------------------------------- @@ -52,9 +52,19 @@ skip 'Unable to load module WebGUI::Shop::Ship', $tests unless $loaded; ####################################################################### my $drivers; +my $e; eval { $drivers = WebGUI::Shop::Ship->getDrivers(); }; -like ($@, qr/getDrivers requires a session object/, 'getDrivers croaks without session'); +$e = Exception::Class->caught(); +isa_ok($e, 'WebGUI::Error::InvalidParam', 'getDrivers takes an exception to not giving it a session variable'); +cmp_deeply( + $e, + methods( + error => 'Must provide a session variable', + ), + 'getDrivers: requires a session variable', +); + $drivers = WebGUI::Shop::Ship->getDrivers($session); @@ -71,19 +81,63 @@ cmp_deeply( ####################################################################### eval { $drivers = WebGUI::Shop::Ship->create(); }; -like ($@, qr/create requires a session object/, 'create croaks without session'); +$e = Exception::Class->caught(); +isa_ok($e, 'WebGUI::Error::InvalidParam', 'create takes an exception to not giving it a session variable'); +cmp_deeply( + $e, + methods( + error => 'Must provide a session variable', + ), + 'create: requires a session variable', +); eval { $drivers = WebGUI::Shop::Ship->create($session); }; -like ($@, qr/create requires the name of a class/, 'create croaks without a class'); +$e = Exception::Class->caught(); +isa_ok($e, 'WebGUI::Error::InvalidParam', 'create croaks without a class'); +cmp_deeply( + $e, + methods( + error => 'Must provide a class to create an object', + ), + 'create croaks without a class', +); + eval { $drivers = WebGUI::Shop::Ship->create($session, 'WebGUI::Shop::ShipDriver::FreeShipping'); }; -like ($@, qr/The requested class \S+ is not enabled in your WebGUI configuration file/, 'create croaks without a configured class'); +$e = Exception::Class->caught(); +isa_ok($e, 'WebGUI::Error::InvalidParam', 'create croaks without a configured class'); +cmp_deeply( + $e, + methods( + error => 'The requested class WebGUI::Shop::ShipDriver::FreeShipping is not enabled in your WebGUI configuration file', + ), + 'create croaks without a configured class', +); eval { $drivers = WebGUI::Shop::Ship->create($session, 'WebGUI::Shop::ShipDriver::FlatRate'); }; -like ($@, qr/You must pass a hashref of options to create a new ShipDriver object/, 'create croaks without options to build a object with'); +$e = Exception::Class->caught(); +isa_ok($e, 'WebGUI::Error::InvalidParam', 'create croaks without options to build a object with'); +cmp_deeply( + $e, + methods( + error => 'You must pass a hashref of options to create a new ShipDriver object', + ), + 'create croaks without options to build a object with', +); eval { $drivers = WebGUI::Shop::Ship->create($session, 'WebGUI::Shop::ShipDriver::FlatRate', {}); }; -like ($@, qr/You must pass a hashref of options to create a new ShipDriver object/, 'create croaks without options to build a object with'); +$e = Exception::Class->caught(); +isa_ok($e, 'WebGUI::Error::InvalidParam', 'create croaks without options to build a object with'); +cmp_deeply( + $e, + methods( + error => 'You must pass a hashref of options to create a new ShipDriver object', + ), + 'create croaks without options to build a object with', +); + +my $driver = WebGUI::Shop::Ship->create($session, 'WebGUI::Shop::ShipDriver::FlatRate', { enabled=>1, label=>q{Jake's Jailbird Airmail}}); +isa_ok($driver, 'WebGUI::Shop::ShipDriver::FlatRate', 'created a new, configured FlatRate driver'); ####################################################################### @@ -92,6 +146,48 @@ like ($@, qr/You must pass a hashref of options to create a new ShipDriver objec # ####################################################################### +my $oldDriver; + +eval { $oldDriver = WebGUI::Shop::Ship->new(); }; +$e = Exception::Class->caught(); +isa_ok($e, 'WebGUI::Error::InvalidParam', 'new takes exception to not giving it a session object'); +cmp_deeply( + $e, + methods( + error => 'Must provide a session variable', + ), + 'new takes exception to not giving it a session object', +); + +eval { $oldDriver = WebGUI::Shop::Ship->new($session); }; +$e = Exception::Class->caught(); +isa_ok($e, 'WebGUI::Error::InvalidParam', 'new takes exception to not giving it a shipperId'); +cmp_deeply( + $e, + methods( + error => 'Must provide a shipperId', + ), + 'new takes exception to not giving it a shipperId', +); + +eval { $oldDriver = WebGUI::Shop::Ship->new($session, 'notEverAnId'); }; +$e = Exception::Class->caught(); +isa_ok($e, 'WebGUI::Error::ObjectNotFound', 'new croaks unless the requested shipperId object exists in the db'); +cmp_deeply( + $e, + methods( + error => 'shipperId not found in db', + id => 'notEverAnId', + ), + 'new croaks unless the requested shipperId object exists in the db', +); + +my $driverCopy = WebGUI::Shop::Ship->new($session, $driver->shipperId); + +is($driverCopy->getId, $driver->getId, 'same id'); +is($driverCopy->className, $driver->className, 'same className'); +cmp_deeply($driverCopy->options, $driver->options, 'same options'); + } #----------------------------------------------------------------------------