diff --git a/UnitTestContrib/test/unit/PluginHandlerTests.pm b/UnitTestContrib/test/unit/PluginHandlerTests.pm index 2898613..5e771bb 100644 --- a/UnitTestContrib/test/unit/PluginHandlerTests.pm +++ b/UnitTestContrib/test/unit/PluginHandlerTests.pm @@ -167,42 +167,80 @@ sub checkCalls { sub test_saveHandlers { my $this = shift; + + my $user = $this->{session}->{user}; + $this->assert_not_null($user); + my $topicObject = Foswiki::Meta->load( $this->{session}, $this->{test_web}, 'Tropic' ); + my $text = $topicObject->text() || ''; + $text =~ s/^\s*\* Set BLAH =.*$//gm; + $text .= "\n\t* Set BLAH = BEFORE\n"; + $text .= "\nNOCALL\n"; + $topicObject->text($text); + try { + $topicObject->save(); + } + catch Foswiki::AccessControlException with { + $this->assert( 0, shift->stringify() ); + } + catch Error::Simple with { + $this->assert( 0, shift->stringify() || '' ); + }; + + my $q = Foswiki::Func::getRequestObject(); + $this->{session}->finish(); + $this->{session} = new Foswiki( $Foswiki::cfg{GuestUserLogin}, $q ); + + Foswiki::Func::pushTopicContext( $this->{test_web}, 'Tropic' ); + $this->makePlugin( 'saveHandlers', <<'HERE'); sub beforeSaveHandler { #my( $text, $topic, $theWeb, $meta ) = @_; - #$tester->assert_str_equals('Zero', $_[0], "ONE $_[0]"); $tester->assert_str_equals('Tropic', $_[1], "TWO $_[1]"); $tester->assert_str_equals($tester->{test_web}, $_[2], "THREE $_[2]"); $tester->assert($_[3]->isa('Foswiki::Meta'), "FOUR $_[3]"); $tester->assert_str_equals('Wibble', $_[3]->get('WIBBLE')->{wibble}); + Foswiki::Func::pushTopicContext( $this->{test_web}, 'Tropic' ); + $tester->assert_str_equals( "BEFORE", + $_[3]->getPreference("BLAH")); + #Foswiki::Func::getPreferencesValue("BLAH") ); $_[0] =~ s/NOCALL/B4SAVE/g; + $_[0] =~ s/BEFORE/AFTER/g; $called->{beforeSaveHandler}++; } sub afterSaveHandler { #my( $text, $topic, $theWeb, $error, $meta ) = @_; - #$tester->assert_str_equals('One', $_[0]); $tester->assert_str_equals('Tropic', $_[1]); $tester->assert_str_equals($tester->{test_web}, $_[2]); $tester->assert_null($_[3]); $tester->assert($_[4]->isa('Foswiki::Meta'), "OUCH $_[4]"); $tester->assert_str_equals('Wibble', $_[4]->get('WIBBLE')->{wibble}); $tester->assert_matches( qr/B4SAVE/, $_[0]); + Foswiki::Func::pushTopicContext( $this->{test_web}, 'Tropic' ); + print STDOUT "Checking preference after save\n"; + $tester->assert_str_equals( "AFTER", + $_[4]->getPreference("BLAH")); + #Foswiki::Func::getPreferencesValue("BLAH") ); $called->{afterSaveHandler}++; } HERE # Test to ensure that the before and after save handlers are both called, # and that modifications made to the text are actaully written to the topic file - my $meta = Foswiki::Meta->new( $this->{session}, $this->{test_web}, "Tropic", "NOCALL" ); + my $meta = Foswiki::Meta->load( $this->{session}, $this->{test_web}, "Tropic" ); $meta->put( 'WIBBLE', { wibble => 'Wibble' } ); $meta->save(); $this->checkCalls( 1, 'beforeSaveHandler' ); $this->checkCalls( 1, 'afterSaveHandler' ); my $newMeta = Foswiki::Meta->load( $this->{session}, $this->{test_web}, "Tropic" ); - $this->assert_str_equals('B4SAVE', $newMeta->text()); + $this->assert_matches( qr\B4SAVE\, $newMeta->text()); $this->assert_str_equals('Wibble', $newMeta->get('WIBBLE')->{wibble}); + $this->assert_str_equals( "AFTER", + $newMeta->getPreference("BLAH")); + Foswiki::Func::pushTopicContext( $this->{test_web}, 'Tropic' ); + $this->assert_str_equals( "AFTER", + Foswiki::Func::getPreferencesValue("BLAH") ); } diff --git a/core/lib/Foswiki/Meta.pm b/core/lib/Foswiki/Meta.pm index 5970f07..692e7e1 100644 --- a/core/lib/Foswiki/Meta.pm +++ b/core/lib/Foswiki/Meta.pm @@ -1900,6 +1900,17 @@ sub save { $signal = shift; }; + delete $this->{_preferences}; + # Refresh preferences values + #if ( $this->{_web} && $this->{_topic} && !defined $signal ) { + + # Refresh is needed only if preferences were already loaded. + # If not, they'll get loaded lazily (and up-to-date) when needed. + # if ( $this->{_preferences} ) { + # $this->{_preferences}->refresh(); + # } + #} + # Semantics inherited from TWiki. See # TWiki:Codev.BugBeforeSaveHandlerBroken if ( $plugins->haveHandlerFor('afterSaveHandler') ) { diff --git a/core/lib/Foswiki/Prefs/BaseBackend.pm b/core/lib/Foswiki/Prefs/BaseBackend.pm index fef003b..fbc774f 100644 --- a/core/lib/Foswiki/Prefs/BaseBackend.pm +++ b/core/lib/Foswiki/Prefs/BaseBackend.pm @@ -104,6 +104,18 @@ sub insert { =begin TML +---++ ObjectMethod refresh() + +Parse the topic again to get the most up-to-date preferences. + +=cut + +sub refresh { + ASSERT('Pure virtual method - child classes must redefine'); +} + +=begin TML + ---++ ObjectMethod cleanupInsertValue($value_ref) Utility method that cleans $$vaue_ref for later use in insert(). diff --git a/core/lib/Foswiki/Prefs/Parser.pm b/core/lib/Foswiki/Prefs/Parser.pm index fc826e9..665f3e3 100644 --- a/core/lib/Foswiki/Prefs/Parser.pm +++ b/core/lib/Foswiki/Prefs/Parser.pm @@ -30,12 +30,13 @@ Parse settings from the topic and add them to the preferences in $prefs =cut sub parse { - my ( $topicObject, $prefs ) = @_; + my $prefs = shift; # Process text first my $key = ''; my $value = ''; my $type; + my $topicObject = $prefs->topicObject; my $text = $topicObject->text(); $text = '' unless defined $text; diff --git a/core/lib/Foswiki/Prefs/TopicRAM.pm b/core/lib/Foswiki/Prefs/TopicRAM.pm index bb49e2e..ad942bb 100644 --- a/core/lib/Foswiki/Prefs/TopicRAM.pm +++ b/core/lib/Foswiki/Prefs/TopicRAM.pm @@ -29,7 +29,8 @@ sub new { $this->{local} = {}; if ( $topicObject->existsInStore() ) { - Foswiki::Prefs::Parser::parse( $topicObject, $this ); + $this->{topicObject} = $topicObject; + Foswiki::Prefs::Parser::parse( $this ); } $this->{topicObject} = $topicObject; @@ -76,6 +77,15 @@ sub getLocal { return $this->{local}{$key}; } +sub refresh { + my $this = shift; + $this->{values} = {}; + $this->{local} = {}; + if ( $this->{topicObject}->existsInStore() ) { + Foswiki::Prefs::Parser::parse($this); + } +} + sub insert { my ( $this, $type, $key, $value ) = @_;