use strict; use Wiki::Toolkit::TestLib; use Test::More; if ( scalar @Wiki::Toolkit::TestLib::wiki_info == 0 ) { plan skip_all => "no backends configured"; } else { plan tests => ( 25 * scalar @Wiki::Toolkit::TestLib::wiki_info ); } my $iterator = Wiki::Toolkit::TestLib->new_wiki_maker; while ( my $wiki = $iterator->new_wiki ) { # Put some test data in. ##### Test recent_changes. We'll write these nodes, in this order, ##### with this metadata, sleeping for at least a second in between ##### writes, and then run the tests. ##### ##### Node1 (Kake, minor tidying) ##### Everyone's Favourite Hobby (nou) ##### Another Node (nou) my $start_time = time; do_sleep(); my $node = "Node1"; my %node_data = $wiki->retrieve_node( $node ); $wiki->write_node( $node, @node_data{ qw( content checksum ) }, { username => "Kake", edit_type => "Minor tidying", comment => "Test", } ); do_sleep(); $node = "Everyone's Favourite Hobby"; %node_data = $wiki->retrieve_node( $node ); $wiki->write_node( $node, @node_data{ qw( content checksum ) }, { comment => "Test", } ); do_sleep(); $node = "Another Node"; %node_data = $wiki->retrieve_node( $node ); $wiki->write_node( $node, @node_data{ qw( content checksum ) }, { username => "nou", comment => "Test", } ); ##### ##### Ready to run the tests now. ##### # Test by "in last n days". my @nodes = $wiki->list_recent_changes( days => 1 ); my @nodenames = map { $_->{name} } @nodes; my %unique = map { $_ => 1 } @nodenames; is_deeply( [sort keys %unique], ["Another Node", "Everyone's Favourite Hobby", "Node1"], "recent_changes for last 1 day gets the right results" ); is_deeply( \@nodenames, ["Another Node", "Everyone's Favourite Hobby", "Node1"], "...in the right order" ); # returns in reverse chron. order foreach my $node ( @nodes ) { is( ref $node->{metadata}{comment}, "ARRAY", "...metadata is returned as a hash of array refs" ); my @comments = @{$node->{metadata}{comment}}; is( $comments[0], "Test", "...correct metadata is returned" ); } # Test by "last n nodes changed". @nodes = $wiki->list_recent_changes( last_n_changes => 2 ); @nodenames = map { $_->{name} } @nodes; print "# Found nodes: " . join(" ", @nodenames) . "\n"; is_deeply( \@nodenames, ["Another Node", "Everyone's Favourite Hobby"], "recent_changes 'last_n_changes' works" ); eval { $wiki->list_recent_changes( last_n_changes => "foo" ); }; ok( $@, "...and croaks on bad input" ); # Test by "since time T". @nodes = $wiki->list_recent_changes( since => $start_time ); @nodenames = sort map { $_->{name} } @nodes; is_deeply( \@nodenames, ["Another Node", "Everyone's Favourite Hobby", "Node1"], "recent_changes 'since' returns the right results" ); ok( $nodes[0]{last_modified}, "...and a plausible (not undef or empty) last_modified timestamp"); # Test metadata_is. (We only actually expect a single result.) @nodes = $wiki->list_recent_changes( last_n_changes => 2, metadata_is => { username => "Kake" } ); is( scalar @nodes, 1, "metadata_is does constrain the search" ); is( $nodes[0]{name}, "Node1", "...correctly" ); # Test metadata_isnt. @nodes = $wiki->list_recent_changes( last_n_changes => 1, metadata_isnt => { username => "Kake" } ); is( scalar @nodes, 1, "metadata_isnt, too" ); is( $nodes[0]{name}, "Another Node", "...correctly" ); print "# " . join(" ", map { $_->{name} } @nodes) . "\n"; @nodes = $wiki->list_recent_changes( last_n_changes => 1, metadata_isnt => { edit_type => "Minor tidying" } ); is( scalar @nodes, 1, "metadata_isnt includes nodes where this metadata type isn't set" ); is( $nodes[0]{name}, "Another Node", "...correctly" ); eval { @nodes = $wiki->list_recent_changes( last_n_changes => 1, metadata_isnt => { arthropod => "millipede" } ); }; is( $@, "", "list_recent_changes doesn't die when metadata_isnt doesn't omit anything" ); ##### ##### Write to Another Node again for testing metadata_was and the ##### effect of the presence and absence of include_all_changes ##### do_sleep(); $node = "Another Node"; %node_data = $wiki->retrieve_node( $node ); $wiki->write_node( $node, @node_data{ qw( content checksum ) }, { username => "Kake", comment => "Kake writes the node that nou wrote", edit_type => "Minor tidying", } ); @nodes = $wiki->list_recent_changes( days => 1 ); is( scalar @nodes, 3, "By default each node returned only once however many times changed" ); @nodes = $wiki->list_recent_changes( days => 1, include_all_changes => 1 ); is( scalar @nodes, 4, "...returned more than once when 'include_all_changes' set" ); @nodes = $wiki->list_recent_changes( last_n_changes => 5, metadata_was => { username => "nou" } ); is( scalar @nodes, 1, "metadata_was returns nodes whose current version doesn't match" ); is( $nodes[0]{name}, "Another Node", "...correctly" ); is( $nodes[0]{version}, 1, "...and the correct version" ); ##### Testing metadata_wasnt - Everyone's Favourite Hobby and ##### Another Node were both written as *not* minor edits, but ##### then a minor edit was made on Another Node. We expect ##### metadata_wasnt to still return Another Node though. @nodes = $wiki->list_recent_changes( last_n_changes => 5, metadata_wasnt => { edit_type => "Minor tidying", }, ); is( scalar @nodes, 2, "metadata_wasnt returns nodes whose current version matches" ); } sub do_sleep { my $slept = sleep(2); warn "Slept for less than a second, test results may be unreliable" unless $slept >= 1; }