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 => ( 22 * 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.
$wiki->write_node( "Reun Thai", "A restaurant", undef,
{ postcode => "W6 9PL",
category => [ "Thai Food", "Restaurant", "Hammersmith" ],
latitude => "51.911", longitude => "" } );
my %node = $wiki->retrieve_node( "Reun Thai" );
my $data = $node{metadata}{postcode};
is( ref $data, "ARRAY", "arrayref always returned" );
is( $node{metadata}{postcode}[0], "W6 9PL",
"...simple metadata retrieved" );
my $cats = $node{metadata}{category};
is_deeply( [ sort @{$cats||[]} ],
[ "Hammersmith", "Restaurant", "Thai Food" ],
"...more complex metadata too" );
# Test list_nodes_by_metadata.
$wiki->write_node( "The Old Trout", "A pub", undef,
{ category => [ "Pub", "Hammersmith" ] } );
my @nodes = $wiki->list_nodes_by_metadata(
metadata_type => "category",
metadata_value => "Hammersmith" );
is_deeply( [ sort @nodes ], [ "Reun Thai", "The Old Trout" ],
"list_nodes_by_metadata returns everything it should" );
$wiki->write_node( "The Three Cups", "Another pub", undef,
{ category => "Pub" } );
@nodes = $wiki->list_nodes_by_metadata( metadata_type => "category",
metadata_value => "Pub" );
is_deeply( [ sort @nodes ], [ "The Old Trout", "The Three Cups" ],
"...and not things it shouldn't" );
# Case insensitivity option.
@nodes = $wiki->list_nodes_by_metadata(
metadata_type => "category",
metadata_value => "hammersmith",
ignore_case => 0,
);
is_deeply( [ sort @nodes ], [ ],
"ignore_case => 0 doesn't ignore case of metadata_value" );
@nodes = $wiki->list_nodes_by_metadata(
metadata_type => "category",
metadata_value => "hammersmith",
ignore_case => 1,
);
is_deeply( [ sort @nodes ], [ "Reun Thai", "The Old Trout" ],
"ignore_case => 1 ignores case of metadata_value" );
@nodes = $wiki->list_nodes_by_metadata(
metadata_type => "Category",
metadata_value => "Hammersmith",
ignore_case => 1,
);
is_deeply( [ sort @nodes ], [ "Reun Thai", "The Old Trout" ],
"...and case of metadata_type" );
# Test list_nodes_by_missing_metadata
# Shouldn't get any if we search on category
@nodes = $wiki->list_nodes_by_missing_metadata(
metadata_type => "category"
);
is( scalar @nodes, 0, "All have metadata category" );
# By latitude, should only get The Old Trout+The Three Cups
@nodes = $wiki->list_nodes_by_missing_metadata(
metadata_type => "latitude"
);
is_deeply( [ sort @nodes ], [ "The Old Trout", "The Three Cups" ],
"By lat, not Reun Thai" );
# By longitude, we should get all (Reun Thai has it blank)
@nodes = $wiki->list_nodes_by_missing_metadata(
metadata_type => "longitude"
);
is_deeply( [ sort @nodes ], [ "Reun Thai", "The Old Trout", "The Three Cups" ], "By long, get all" );
# With category=Pub, we should get only the Reun Thai
@nodes = $wiki->list_nodes_by_missing_metadata(
metadata_type => "category",
metadata_value => "Pub"
);
is_deeply( [ sort @nodes ], [ "Reun Thai" ], "Reun Thai not a pub" );
# With Category, we should get all
@nodes = $wiki->list_nodes_by_missing_metadata(
metadata_type => "Category"
);
is_deeply( [ sort @nodes ], [ "Reun Thai", "The Old Trout", "The Three Cups" ], "By Category, get all" );
# With category=hammersmith, we should get all
@nodes = $wiki->list_nodes_by_missing_metadata(
metadata_type => "category",
metadata_value => "hammersmith"
);
is_deeply( [ sort @nodes ], [ "Reun Thai", "The Old Trout", "The Three Cups" ], "By category=hammersmith (case sensitive), get all" );
# But with category=hammersmith+case insensitive, shouldn't get any
@nodes = $wiki->list_nodes_by_missing_metadata(
metadata_type => "category",
metadata_value => "hammersmith",
ignore_case => 1
);
is_deeply( [ sort @nodes ], [ "The Three Cups" ], "By category=hammersmith (ci), get all but the three cups" );
%node = $wiki->retrieve_node("The Three Cups");
$wiki->write_node( "The Three Cups", "Not a pub any more",
$node{checksum} );
@nodes = $wiki->list_nodes_by_metadata( metadata_type => "category",
metadata_value => "Pub" );
is_deeply( [ sort @nodes ], [ "The Old Trout" ],
"removing metadata from a node stops it showing up in list_nodes_by_metadata" );
my $dbh = eval { $wiki->store->dbh; };
my $id_sql = "SELECT id FROM node WHERE name='Reun Thai'";
my $id = @{ $dbh->selectcol_arrayref($id_sql) }[0];
$wiki->delete_node("Reun Thai");
@nodes = $wiki->list_nodes_by_metadata( metadata_type => "category",
metadata_value => "Hammersmith" );
is_deeply( [ sort @nodes ], [ "The Old Trout" ],
"...as does deleting a node" );
# Check that deleting a node really does clear out the metadata.
SKIP: {
skip "Test only works on database backends", 1 unless $dbh;
# White box testing.
my $sql = "SELECT metadata_type, metadata_value FROM metadata
WHERE node_id = $id";
my $sth = $dbh->prepare($sql);
$sth->execute;
my ( $type, $value ) = $sth->fetchrow_array;
is_deeply( [ $type, $value ], [undef, undef],
"deletion of a node removes metadata from database" );
}
# Test checksumming.
%node = $wiki->retrieve_node("The Three Cups");
ok( $wiki->write_node( "The Three Cups", "Not a pub any more",
$node{checksum}, { newdata => "foo" } ),
"writing node with metadata succeeds when checksum fresh" );
ok( !$wiki->write_node( "The Three Cups", "Not a pub any more",
$node{checksum}, { newdata => "bar" } ),
"writing node with identical content but different metadata fails when checksum not updated" );
# Test with duplicate metadata.
$wiki->write_node( "Dupe Test", "test", undef,
{ foo => [ "bar", "bar" ] } );
%node = $wiki->retrieve_node( "Dupe Test" );
is( scalar @{$node{metadata}{foo}}, 1,
"duplicate metadata only written once" );
# Test version is updated when metadata is removed.
$wiki->write_node( "Dupe Test", "test", $node{checksum} );
%node = $wiki->retrieve_node( "Dupe Test" );
is( $node{version}, 2, "version updated when metadata removed" );
}