use strict; use Wiki::Toolkit::Store::Database; use Wiki::Toolkit::TestLib; use DBI; use Test::More; use Time::Piece; use Time::Seconds; if ( scalar @Wiki::Toolkit::TestLib::wiki_info == 0 ) { plan skip_all => "no backends configured"; } else { plan tests => ( 10 * scalar @Wiki::Toolkit::TestLib::wiki_info ); } # These tests are for the "new_only" parameter to ->list_recent_changes. # We set things up so that we have the following nodes: # - Ae Pub, in the Pubs category, added 8 days ago, edited 2 days ago and today # - Ae Bar, in the Bars category, added 5 days ago, edited today # - Ae Restaurant, in the Restaurants category, added today # - Ae Nother Pub, in the Pubs category, added today # Also, make it so the categories of these things were only added today. my $iterator = Wiki::Toolkit::TestLib->new_wiki_maker; while ( my $wiki = $iterator->new_wiki ) { # Store the time now, so we have a timestamp which precedes "today"'s # additions and edits. my $start_time = time; my $slept = sleep(2); warn "Slept for less than a second; test results may be unreliable" unless $slept >= 1; # Set up the data and run the tests. setup_nodes( wiki => $wiki ); my @nodes = $wiki->list_recent_changes( days => 4, ); my @names = sort map { $_->{name} } @nodes; is_deeply( \@names, [ "Ae Bar", "Ae Nother Pub", "Ae Pub", "Ae Restaurant" ], "all nodes returned when new_only omitted" ); @nodes = $wiki->list_recent_changes( days => 4, new_only => 0, ); @names = sort map { $_->{name} } @nodes; is_deeply( \@names, [ "Ae Bar", "Ae Nother Pub", "Ae Pub", "Ae Restaurant" ], "...and when it's set to false" ); @nodes = $wiki->list_recent_changes( days => 4, new_only => 1, ); @names = sort map { $_->{name} } @nodes; is_deeply( \@names, [ "Ae Nother Pub", "Ae Restaurant" ], "nodes edited but not added in last n days are omitted with new_only" ); @nodes = $wiki->list_recent_changes( between_days => [ 1, 6 ], include_all_changes => 1, # to make between_days work - bug? new_only => 1, ); @names = sort map { $_->{name} } @nodes; is_deeply( \@names, [ "Ae Bar" ], "...and this works for between_days too" ); @nodes = $wiki->list_recent_changes( since => $start_time, new_only => 1, ); @names = sort map { $_->{name} } @nodes; is_deeply( \@names, [ "Ae Nother Pub", "Ae Restaurant" ], "...and for since" ); @nodes = $wiki->list_recent_changes( last_n_changes => 3, new_only => 1, ); @names = sort map { $_->{name} } @nodes; is_deeply( \@names, [ "Ae Bar", "Ae Nother Pub", "Ae Restaurant" ], "...and for last n" ); @nodes = $wiki->list_recent_changes( days => 2, new_only => 1, metadata_is => { category => "Pubs" }, ); @names = sort map { $_->{name} } @nodes; is_deeply( \@names, [ "Ae Nother Pub" ], "combination of days and metadata_is omits things edited but " . "not added in recent days" ); # Ae Bar wasn't in the Bars category when it was added, but it is now. @nodes = $wiki->list_recent_changes( days => 6, new_only => 1, metadata_is => { category => "Bars" }, ); @names = sort map { $_->{name} } @nodes; is_deeply( \@names, [ "Ae Bar" ], "...and includes the things it should include" ); @nodes = $wiki->list_recent_changes( days => 6, new_only => 1, metadata_wasnt => { category => "Bars" }, ); @names = sort map { $_->{name} } @nodes; is_deeply( \@names, [ "Ae Bar", "Ae Nother Pub", "Ae Restaurant" ], "...and metadata_wasnt works too" ); # Ae Nother Pub was the only pub added to the Pubs category on creation. @nodes = $wiki->list_recent_changes( days => 10, new_only => 1, metadata_was => { category => "Pubs" }, ); @names = sort map { $_->{name} } @nodes; is_deeply( \@names, [ "Ae Nother Pub" ], "combination of new_only and metadata_was omits things which " . "didn't have the relevant data when they were created" ); } sub get_timestamp { my %args = @_; my $days = $args{days}; my $now = localtime; # overloaded by Time::Piece my $time = $now - ( $days * ONE_DAY ); return Wiki::Toolkit::Store::Database->_get_timestamp( $time ); } sub setup_nodes { my %args = @_; my $wiki = $args{wiki}; # For "Ae Pub", write directly to the database so we can fake having # written something in the past (white box testing). It might be a good # idea at some point to factor this out into Wiki::Toolkit::TestLib, as # it's used in other tests too. my $dbh = $wiki->store->dbh; my $content_sth = $dbh->prepare("INSERT INTO content (node_id,version,text,modified) VALUES (?,?,?,?)"); my $node_sth = $dbh->prepare("INSERT INTO node (id,name,version,text,modified) VALUES (?,?,?,?,?)"); $node_sth->execute( 10, "Ae Pub", 2, "foo", get_timestamp( days => 2 ) ) or die $dbh->errstr; $content_sth->execute( 10, 2, "foo", get_timestamp( days => 2 ) ) or die $dbh->errstr; $content_sth->execute( 10, 1, "foo", get_timestamp( days => 8 ) ) or die $dbh->errstr; # Now write it as per usual, to get the categories in. my %data = $wiki->retrieve_node( "Ae Pub" ); $wiki->write_node( "Ae Pub", $data{content}, $data{checksum}, { category => [ "Pubs" ] } ) or die "Couldn't write Ae Pub node"; # Now do Ae Bar the same way. $node_sth->execute( 20, "Ae Bar", 1, "foo", get_timestamp( days => 5 ) ) or die $dbh->errstr; $content_sth->execute( 20, 1, "foo", get_timestamp( days => 5 ) ) or die $dbh->errstr; %data = $wiki->retrieve_node( "Ae Bar" ); $wiki->write_node( "Ae Bar", $data{content}, $data{checksum}, { category => [ "Bars" ] } ) or die "Couldn't write Ae Bar node"; # The other nodes are simple. $wiki->write_node( "Ae Restaurant", "lalalalala", undef, { category => [ "Restaurants" ] } ) or die "Couldn't write Ae Restaurant node"; $wiki->write_node( "Ae Nother Pub", "beer", undef, { category => [ "Pubs" ] } ) or die "Couldn't write Ae Nother Pub node"; }