From 25b4a0b139eb78eb6a67bccfaac0adeabd33a5b6 Mon Sep 17 00:00:00 2001 From: Colin Kuskie Date: Wed, 30 Sep 2009 16:50:08 -0700 Subject: [PATCH] Fix multiple Date and DateTime bugs. bug #11079 and bug #11071 --- docs/changelog/7.x.x.txt | 2 + lib/WebGUI/DateTime.pm | 2 +- lib/WebGUI/Form/Date.pm | 63 +++++++-------------- lib/WebGUI/Form/DateTime.pm | 75 +++++++++--------------- t/Form/Date.t | 63 +++++++++++++++++---- t/Form/DateTime.t | 110 ++++++++++++++++++++++++++++++++---- 6 files changed, 202 insertions(+), 113 deletions(-) diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index 5ec83baef..74500176c 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -27,6 +27,8 @@ - fixed #11068: ITransact_recurringStatus - fixed #11075: product destroys variants - fixed #11073: preview interchanges width and height properties + - fixed #11079: Datepicker, without times, does not highlight my birthday + - fixed #11071: Form::Date / Session::DateTime 7.8.0 - upgraded YUI to 2.8.0r4 diff --git a/lib/WebGUI/DateTime.pm b/lib/WebGUI/DateTime.pm index 69bc597b3..a015b7a96 100644 --- a/lib/WebGUI/DateTime.pm +++ b/lib/WebGUI/DateTime.pm @@ -153,7 +153,7 @@ sub new { $self = $class->SUPER::new(@_); } - elsif ($_[0] =~ /^\d+$/) + elsif ($_[0] =~ /^-?\d+$/) { $self = DateTime->from_epoch(epoch=>$_[0], time_zone=>"UTC", locale=>$locale); } diff --git a/lib/WebGUI/Form/Date.pm b/lib/WebGUI/Form/Date.pm index 1ae63bbc8..43310f647 100644 --- a/lib/WebGUI/Form/Date.pm +++ b/lib/WebGUI/Form/Date.pm @@ -19,6 +19,8 @@ use base 'WebGUI::Form::Text'; use WebGUI::Form::Hidden; use WebGUI::International; +my $isaEpoch = qr/^-?\d+$/; + =head1 NAME Package WebGUI::Form::Date @@ -137,9 +139,9 @@ sub getValue { my $self = shift; # This should probably be rewritten as a cascading ternary my $value = $self->SUPER::getValue(@_); - if (!$self->getDefaultValue || $self->getDefaultValue =~ m/^\d+$/) { + if (!$self->getDefaultValue || $self->getDefaultValue =~ $isaEpoch) { # Epoch format - if($value =~ /^\d+$/){ + if($value =~ $isaEpoch){ return $value; } return $self->session->datetime->setToEpoch($value); @@ -150,10 +152,7 @@ sub getValue { # NOTE: Cannot fix time zone since we don't have a complete date/time - # MySQL format - # YY(YY)?-MM-DD HH:MM:SS - - if($value =~ /^\d+$/){ + if($value =~ $isaEpoch){ return $self->session->datetime->epochToSet($value,$self->session->user->profileField( 'timeZone' )); } @@ -173,17 +172,17 @@ Return the date in a human readable format. =cut sub getValueAsHtml { - my ($self) = @_; + my ($self) = @_; # This should probably be rewritten as a cascading ternary - if (!$self->get("defaultValue") - || $self->get("defaultValue") =~ m/^\d+$/ - || !$self->get("value") - || $self->get("value") =~ m/^\d+$/) { - return $self->session->datetime->epochToHuman($self->getOriginalValue,"%z"); - } + if ( !$self->get("defaultValue") + || $self->get("defaultValue") =~ $isaEpoch + || !$self->get("value") + || $self->get("value") =~ $isaEpoch) { + return $self->session->datetime->epochToSet($self->getOriginalValue); + } else { - # MySQL format - my $value = $self->getOriginalValue; + # MySQL format + my $value = $self->getOriginalValue; return $value; } } @@ -217,17 +216,8 @@ sub toHtml { # No default date $value = $self->set("value",''); } - elsif (!$self->get("defaultValue") - || $self->get("defaultValue") =~ m/^\d+$/ - || !$self->get("value") - || $self->get("value") =~ m/^\d+$/) { - # Epoch format - $value = $session->datetime->epochToSet($self->getOriginalValue); - } else { - # MySQL format - $value = $self->getOriginalValue; - # NOTE: Cannot fix time zone since we don't have a complete date/time + $value = $self->getValueAsHtml; } my $style = $session->style; @@ -263,24 +253,11 @@ Renders the form field to HTML as a hidden field rather than whatever field type sub toHtmlAsHidden { my $self = shift; - my $value; - - # This should probably be rewritten as a cascading ternary - if (!$self->get("defaultValue") - || $self->get("defaultValue") =~ m/^\d+$/ - || !$self->get("value") - || $self->get("value") =~ m/^\d+$/) { - $value = $self->session->datetime->epochToSet($self->getOriginalValue,"%z"); - } else { - # MySQL format - $value = $self->getOriginalValue; - # NOTE: Cannot fix time zone since we don't have a complete date/time - } - - return WebGUI::Form::Hidden->new($self->session, - name => $self->get("name"), - value => $value, - )->toHtmlAsHidden; + my $value = $self->getValueAsHtml(); + return WebGUI::Form::Hidden->new($self->session, + name => $self->get("name"), + value => $value, + )->toHtmlAsHidden; } 1; diff --git a/lib/WebGUI/Form/DateTime.pm b/lib/WebGUI/Form/DateTime.pm index b601646f1..8a7f6b7d2 100644 --- a/lib/WebGUI/Form/DateTime.pm +++ b/lib/WebGUI/Form/DateTime.pm @@ -20,6 +20,8 @@ use WebGUI::Form::Hidden; use WebGUI::International; use WebGUI::DateTime; +my $isaEpoch = qr/^-?\d+$/; + =head1 NAME Package WebGUI::Form::DateTime @@ -139,9 +141,9 @@ sub getValue { # This should probably be rewritten as a cascading ternary my $value = $self->SUPER::getValue(@_); - if (!$self->getDefaultValue || $self->getDefaultValue =~ m/^\d+$/) { + if (!$self->getDefaultValue || $self->getDefaultValue =~ $isaEpoch) { # Epoch format - if($value =~ /^\d+$/){ + if($value =~ $isaEpoch){ return $value; } return $self->session->datetime->setToEpoch($value); @@ -150,7 +152,7 @@ sub getValue { # MySQL format # YY(YY)?-MM-DD HH:MM:SS - if($value =~ /^\d+$/){ + if($value =~ $isaEpoch){ return $self->session->datetime->epochToSet($value,$self->session->user->profileField( 'timeZone' )); } @@ -178,8 +180,10 @@ Return the date in a human readable format. sub getValueAsHtml { my ($self) = @_; # This should probably be rewritten as a cascading ternary - my $formatValue = $self->getDefaultValue || $self->getOriginalValue; - if (!$formatValue || $formatValue =~ m/^\d+$/) { + if ( !$self->get("defaultValue") + || $self->get("defaultValue") =~ $isaEpoch + || !$self->get("value") + || $self->get("value") =~ $isaEpoch) { return $self->session->datetime->epochToHuman($self->getOriginalValue,"%z %Z"); } else { @@ -216,22 +220,10 @@ Renders a date picker control. sub toHtml { my $self = shift; my $session = $self->session; - my $value; - # This should probably be rewritten as a cascading ternary - if (!$self->get("defaultValue") - || $self->get("defaultValue") =~ m/^\d+$/ - || !$self->get("value") - || $self->get("value") =~ m/^\d+$/) { - # Epoch format - $value = $session->datetime->epochToSet($self->getOriginalValue,1); - } else { - # MySQL format - $value = $self->getOriginalValue; - # Fix time zone - $value = WebGUI::DateTime->new($session, mysql => $value) - ->set_time_zone($self->get("timeZone")) - ->strftime("%Y-%m-%d %H:%M:%S"); - } + my $value = WebGUI::DateTime->new($session, $self->getOriginalValue) + ->set_time_zone($self->get("timeZone")) + ->strftime("%Y-%m-%d %H:%M:%S"); + my $style = $session->style; my $url = $session->url; $style->setLink($url->extras('yui/build/calendar/assets/skins/sam/calendar.css'), { rel=>"stylesheet", type=>"text/css", media=>"all" }); @@ -245,12 +237,12 @@ sub toHtml { $style->setScript($url->extras('yui-webgui/build/datepicker/datepicker.js'),{ type => 'text/javascript' }); return WebGUI::Form::Text->new($self->session, - name=>$self->get("name"), - value=>$value, - size=>$self->get("size"), - extras=>$self->get("extras") . ' onfocus="YAHOO.WebGUI.Form.DatePicker.display(this, true);"', - id=>$self->get('id'), - maxlength=>$self->get("maxlength") + name => $self->get("name"), + value => $value, + size => $self->get("size"), + extras => $self->get("extras") . ' onfocus="YAHOO.WebGUI.Form.DatePicker.display(this, true);"', + id => $self->get('id'), + maxlength => $self->get("maxlength") )->toHtml; } @@ -263,28 +255,15 @@ Renders the form field to HTML as a hidden field rather than whatever field type =cut sub toHtmlAsHidden { - my $self = shift; - my $value; + my $self = shift; + my $value = WebGUI::DateTime->new($self->session, $self->getOriginalValue) + ->set_time_zone($self->get("timeZone")) + ->strftime("%Y-%m-%d %H:%M:%S"); - # This should probably be rewritten as a cascading ternary - if (!$self->get("defaultValue") - || $self->get("defaultValue") =~ m/^\d+$/ - || !$self->get("value") - || $self->get("value") =~ m/^\d+$/) { - $value = $self->session->datetime->epochToSet($self->getOriginalValue,1); - } else { - # MySQL format - $value = $self->getOriginalValue; - # Fix Time zone - $value = WebGUI::DateTime->new($self->session, mysql => $value) - ->set_time_zone($self->get("timeZone")) - ->strftime("%Y-%m-%d %H:%M:%S"); - } - - return WebGUI::Form::Hidden->new( - name => $self->get("name"), - value => $value, - )->toHtmlAsHidden; + return WebGUI::Form::Hidden->new($self->session, + name => $self->get("name"), + value => $value, + )->toHtmlAsHidden; } 1; diff --git a/t/Form/Date.t b/t/Form/Date.t index 24003b336..bb23748a3 100644 --- a/t/Form/Date.t +++ b/t/Form/Date.t @@ -36,15 +36,21 @@ my $testBlock = [ }, { key => 'Date2', - testValue => "2008-08-01 16:34:26", - expected => $session->datetime->setToEpoch("2008-08-01 16:34:26"),#must call this so that value is appropriate for testers timezone + testValue => "2008-08-01", + expected => $session->datetime->setToEpoch("2008-08-01"),#must call this so that value is appropriate for testers timezone comment => 'MySQL formatted to epoch', }, + { + key => 'Date3', + testValue => '-1', + expected => '-1', + comment => 'negative epoch to negative epoch', + }, ]; my $formType = 'date'; -my $numTests = 16 + scalar @{ $testBlock } ; +my $numTests = 26 + scalar @{ $testBlock } ; plan tests => $numTests; @@ -110,13 +116,50 @@ WebGUI::Form_Checking::auto_check($session, $formType, $testBlock); #Dates to MySQL -my $date2 = WebGUI::Form::Date->new($session, {'defaultValue' => '2008-08-01 16:34:26'}); -is($date2->getValue(1217608466), '2008-08-01 11:34:26', "Epoch to MySQL"); -is($date2->getValue('2008-08-01 11:34:26'), '2008-08-01 11:34:26', "MySQL to MySQL"); +my $date2; +$date2 = WebGUI::Form::Date->new($session, {'defaultValue' => '2008-08-01 16:34:26'}); +is($date2->getValue(1217608466), '2008-08-01 11:34:26', "getValue, defaultValue MySQL format: Epoch to MySQL"); +is($date2->getValue('2008-08-01'), '2008-08-01', "... MySQL to MySQL"); +is($date2->getValue(-1), '1969-12-31 17:59:59', "... Negative epoch to MySQL"); -my $date2 = WebGUI::Form::Date->new($session); -is($date2->getValue(1217608466), 1217608466, "Default Epoch to Epoch"); -is($date2->getValue('2008-08-01 11:34:26'), 1217608466, "Default MySQL to Epoch"); +$date2 = WebGUI::Form::Date->new($session); +is($date2->getValue(1217608466), 1217608466, "getValue, no default: Default Epoch to Epoch"); +is($date2->getValue('2008-08-01'), 1217566800, "... Default MySQL to Epoch"); +is($date2->getValue(-1), -1, "... Default negative epoch to negative epoch"); -__END__ +my $bday = WebGUI::Test->webguiBirthday; +$date2 = WebGUI::Form::Date->new($session); +is($date2->getValueAsHtml(), $session->datetime->epochToSet($date2->getDefaultValue), "getValueAsHtml: no defaultValue set, no value set, returns now in user's format"); + +$date2 = WebGUI::Form::Date->new($session, {defaultValue => 1217608466}); +is($date2->getValueAsHtml(), '2008-08-01', "getValueAsHtml: defaultValue in epoch format, returns now in mysql format"); +is( + getValueFromForm($session, $date2->toHtmlAsHidden), + '2008-08-01', + "toHtmlAsHidden: defaultValue in epoch format, returns date in mysql format" +); +is( + getValueFromForm($session, $date2->toHtml), + '2008-08-01', + "toHtml: defaultValue in epoch format, returns date in mysql format" +); +$date2 = WebGUI::Form::Date->new($session, {defaultValue => -1}); +is($date2->getValueAsHtml(), '1969-12-31', "getValueAsHtml: defaultValue as negative epoch, returns in mysql format"); + +$date2 = WebGUI::Form::Date->new($session, {defaultValue => '2008-08-01'}); +is($date2->getValueAsHtml(), '2008-08-01', "getValueAsHtml: defaultValue in mysql format, returns default value in mysql format"); + +$date2 = WebGUI::Form::Date->new($session, {defaultValue => '2008-08-01', value => $bday, }); +is($date2->getValueAsHtml(), '2001-08-16', "getValueAsHtml: defaultValue in mysql format, value as epoch returns value in user's format"); + +$date2 = WebGUI::Form::Date->new($session, {defaultValue => '2008-08-01', value => '2001-08-16', }); +is($date2->getValueAsHtml(), '2001-08-16', "getValueAsHtml: defaultValue in mysql format, value as mysql returns value in mysql format"); + +sub getValueFromForm { + my ($session, $textForm) = @_; + my ($header, $footer) = (WebGUI::Form::formHeader($session), WebGUI::Form::formFooter($session)); + my @forms = HTML::Form->parse($header.$textForm.$footer, 'http://www.webgui.org'); + my @inputs = $forms[0]->inputs; + return $inputs[1]->{value}; +} diff --git a/t/Form/DateTime.t b/t/Form/DateTime.t index db2fdfaad..8b9365659 100644 --- a/t/Form/DateTime.t +++ b/t/Form/DateTime.t @@ -29,7 +29,7 @@ my $session = WebGUI::Test->session; my $formType = 'datetime'; -my $numTests = 15; +my $numTests = 34; plan tests => $numTests; @@ -82,23 +82,111 @@ is($input->name, 'preDateValue', 'Checking input name'); is($input->{size}, 19, 'Checking size param, set'); is($input->{maxlength}, 19, 'Checking maxlength param, set'); -##Test Form Output parsing -#Dates to Epoch -#WebGUI::Form_Checking::auto_check($session, $formType, $testBlock); +######################################### +# +# getValue +# +######################################### my $date1 = WebGUI::Form::DateTime->new($session, {'defaultValue' => time()}); $session->user->profileField( 'timeZone' , 'America/Chicago'); -is($date1->getValue(1217608466), 1217608466, "Epoch to Epch"); -is($date1->getValue('2008-08-01 16:34:26'), $session->datetime->setToEpoch("2008-08-01 16:34:26"), "MySQL to Epoch"); +is($date1->getValue(1217608466), 1217608466, "getValue, defaultValue epoch: Epoch to Epch"); +is($date1->getValue('2008-08-01 16:34:26'), 1217626466, "... MySQL to Epoch"); +is($date1->getValue(-1), -1, "... negative epoch to epoch"); my $date2 = WebGUI::Form::DateTime->new($session); -is($date2->getValue(1217608466), 1217608466, "Default Epoch to Epch"); -is($date2->getValue('2008-08-01 16:34:26'), $session->datetime->setToEpoch("2008-08-01 16:34:26"), "Default MySQL to Epoch"); +is($date2->getValue(1217608466), 1217608466, "getValue, no default: Default Epoch to Epch"); +is($date2->getValue('2008-08-01 16:34:26'), 1217626466, "... Default MySQL to Epoch"); +is($date2->getValue(-1), -1, "... negative epoch to epoch"); #Dates to MySQL my $date3 = WebGUI::Form::DateTime->new($session, {'defaultValue' => '2008-08-01 16:34:26'}); -is($date3->getValue(1217608466), '2008-08-01 11:34:26', "Epoch to MySQL"); -is($date3->getValue('2008-08-01 11:34:26'), '2008-08-01 16:34:26', "MySQL to MySQL");#UTC is 5 hours ahead of Chicago +is($date3->getValue(1217608466), '2008-08-01 11:34:26', "getValue, defaultValue is mysql, epoch to mySQL"); +is($date3->getValue('2008-08-01 11:34:26'), '2008-08-01 16:34:26', "... MySQL to MySQL");#UTC is 5 hours ahead of Chicago +is($date3->getValue(-1), '1969-12-31 17:59:59', "... negative epoch to mysql"); -__END__ +######################################### +# +# getValueAsHtml +# +######################################### +my $bday = WebGUI::Test->webguiBirthday; + +$date2 = WebGUI::Form::DateTime->new($session); +is($date2->getValueAsHtml(), $session->datetime->epochToHuman($date2->getDefaultValue,'%z %Z'), "getValueAsHtml: no defaultValue set, no value set, returns now in user's format"); + +$date2 = WebGUI::Form::DateTime->new($session, {defaultValue => 1217608466}); +is($date2->getValueAsHtml(), '8/1/2008 11:34 am', "getValueAsHtml: defaultValue in epoch format, returns now in user's format"); +is( + getValueFromForm($session, $date2->toHtmlAsHidden), + '2008-08-01 11:34:26', + "toHtmlAsHidden: defaultValue in mysql format, returns date in mysql format" +); +is( + getValueFromForm($session, $date2->toHtml), + '2008-08-01 11:34:26', + "toHtml: defaultValue in mysql format, returns date in mysql format" +); + +$date2 = WebGUI::Form::DateTime->new($session, {defaultValue => -1}); +is($date2->getValueAsHtml(), '12/31/1969 5:59 pm', "getValueAsHtml: defaultValue as negative epoch, returns as user's format"); +is( + getValueFromForm($session, $date2->toHtmlAsHidden), + '1969-12-31 17:59:59', + "toHtmlAsHidden: defaultValue as negative epoch, returns date/time in mysql format" +); +is( + getValueFromForm($session, $date2->toHtml), + '1969-12-31 17:59:59', + "toHtml: defaultValue in mysql format, returns date in mysql format" +); + + +$date2 = WebGUI::Form::DateTime->new($session, {defaultValue => '2008-08-01 11:34:26'}); +is($date2->getValueAsHtml(), '2008-08-01 06:34:26', "getValueAsHtml: defaultValue in mysql format, returns default value in mysql format"); +is( + getValueFromForm($session, $date2->toHtmlAsHidden), + '2008-08-01 06:34:26', + "toHtmlAsHidden: defaultValue in mysql format, returns date in mysql format" +); +is( + getValueFromForm($session, $date2->toHtml), + '2008-08-01 06:34:26', + "toHtml: defaultValue in mysql format, returns date in mysql format" +); + + +$date2 = WebGUI::Form::DateTime->new($session, {defaultValue => '2008-08-01 11:34:26', value => $bday, }); +is($date2->getValueAsHtml(), '8/16/2001 8:00 am', "getValueAsHtml: defaultValue in mysql format, value as epoch returns value in user's format"); +is( + getValueFromForm($session, $date2->toHtmlAsHidden), + '2001-08-16 08:00:00', + "toHtmlAsHidden: defaultValue in mysql format, value as epoch returns date in mysql format" +); +is( + getValueFromForm($session, $date2->toHtml), + '2001-08-16 08:00:00', + "toHtml: defaultValue in mysql format, value as epoch returns date in mysql format" +); + +$date2 = WebGUI::Form::DateTime->new($session, {defaultValue => '2008-08-01 11:34:26', value => '2001-08-16 13:00:00', }); +is($date2->getValueAsHtml(), '2001-08-16 08:00:00', "getValueAsHtml: defaultValue in mysql format, value as mysql returns value in mysql format"); +is( + getValueFromForm($session, $date2->toHtmlAsHidden), + '2001-08-16 08:00:00', + "toHtmlAsHidden: defaultValue in mysql format, value as mysql returns date in mysql format, adjusted for time zone" +); +is( + getValueFromForm($session, $date2->toHtml), + '2001-08-16 08:00:00', + "toHtml: defaultValue in mysql format, value as mysql returns date in mysql format, adjusted for time zone" +); + +sub getValueFromForm { + my ($session, $textForm) = @_; + my ($header, $footer) = (WebGUI::Form::formHeader($session), WebGUI::Form::formFooter($session)); + my @forms = HTML::Form->parse($header.$textForm.$footer, 'http://www.webgui.org'); + my @inputs = $forms[0]->inputs; + return $inputs[1]->{value}; +}