The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
use strict;

use Test::More;
use URI::Escape;
use Wiki::Toolkit::TestLib;

my $iterator = Wiki::Toolkit::TestLib->new_wiki_maker;
plan tests => ( 3 + $iterator->number * 22 );

use_ok( "Wiki::Toolkit::Feed::RSS" );

eval { my $rss = Wiki::Toolkit::Feed::RSS->new; };
ok( $@, "new croaks if no wiki object supplied" );

eval {
        my $rss = Wiki::Toolkit::Feed::RSS->new( wiki => "foo" );
     };
ok( $@, "new croaks if something that isn't a wiki object supplied" );

while ( my $wiki = $iterator->new_wiki ) {

    # First, write some data.

    # Write two versions of one node
    # The recent changes should only show it once though
    $wiki->write_node( "Old Node",
                       "First version of Old Node" );
    my %old_node = $wiki->retrieve_node("Old Node");
    $wiki->write_node( "Old Node",
                       "We will write at least 15 nodes after this one",
                       $old_node{'checksum'} );

    my $slept = sleep(2);
    warn "Slept for less than a second, 'days=n' test may pass even if buggy"
      unless $slept >= 1;

    for my $i ( 1 .. 15 ) {
        $wiki->write_node( "Temp Node $i", "foo" );
    }

    $slept = sleep(2);
    warn "Slept for less than a second, test results may not be trustworthy"
      unless $slept >= 1;

    $wiki->write_node( "Test Node 1",
                       "Just a plain test",
                         undef,
                         { username => "Kake",
                           comment  => "new node",
                           category => [ 'TestCategory1', 'Meta' ]
                         }
                       );

    $slept = sleep(2);
    warn "Slept for less than a second, 'items=n' test may fail"
      unless $slept >= 1;

    $wiki->write_node( "Calthorpe Arms",
                         "CAMRA-approved pub near King's Cross",
                         undef,
                         { comment  => "Stub page, please update!",
                           username => "Kake",
                           postcode => "WC1X 8JR",
                           locale   => [ "Bloomsbury" ]
                       }
    );

    $wiki->write_node( "Test Node 2",
                       "Gosh, another test!",
                       undef,
                       {
                         username     => "nou",
                         comment      => "This is a minor edit.",
                         major_change => 0,
                       }
                     );

    # Now set up a feed object and test it.

    my %default_config = (
            wiki          => $wiki,
            site_name     => "Wiki::Toolkit Test Site",
            make_node_url => sub {
                                 my $id = uri_escape($_[0]);
                                 my $version = $_[1] || '';
                                 $version = uri_escape($version) if $version;
                                 "http://example.com/?id=$id;version=$version";
                             },
            recent_changes_link => "http://example.com/recentchanges"
    );
    my $rss = eval {
        Wiki::Toolkit::Feed::RSS->new(
            %default_config,
            site_url => "http://example.com/kakeswiki/",
        );
    };
    is( $@, "",
       "'new' doesn't croak if wiki object and mandatory parameters supplied"
    );
    isa_ok( $rss, "Wiki::Toolkit::Feed::RSS" );

    my $feed = eval { $rss->recent_changes; };
    is( $@, "", "->recent_changes doesn't croak" );

    # Check the things that are generated by the mandatory arguments.
    like( $feed,
      qr|<item rdf:about="http://example.com/\?id=Test%20Node%201;version=1">|,
          "make_node_url is used" );

    like( $feed, qr|<modwiki:version>1</modwiki:version>|,
          "version numbers included in feed" );

    like( $feed, qr|<modwiki:status>new</modwiki:status>|,
          "page status included in feed" );

    like( $feed, qr|<modwiki:importance>major</modwiki:importance>|,
          "change importance included and defaults to 'major'" );

    my $charset = $wiki->store->{_charset};
    like( $feed, qr|<?xml version="1.0"|, "is xml" );
    like( $feed, qr|<?xml version="1.0" encoding="$charset"|, "is xml" );

    # Check stuff that comes from the metadata.
    like( $feed, qr|<dc:contributor>Kake</dc:contributor>|,
          "username picked up as contributor" );

    like( $feed, qr|<description>.*\[nou]</description>|,
          "username included in description" );

    like( $feed, qr|<dc:subject>TestCategory1</dc:subject>|,
          "dublin core subject contains category" );

    # Check that interwiki things are passed through right.
    $rss = Wiki::Toolkit::Feed::RSS->new(
        %default_config,
        interwiki_identifier => "KakesWiki",
        site_url => "http://example.com/kakeswiki/",
    );
    $feed = $rss->recent_changes;
    like( $feed, qr|<modwiki:interwiki>KakesWiki</modwiki:interwiki>|,
          "interwiki identifier passed through OK" );

    # Check that diff url comes through.
    $rss = Wiki::Toolkit::Feed::RSS->new(
        %default_config,
        make_diff_url        => sub {
            my $node_name = shift;
            return "http://example.com/?action=show_diff;id="
                 . uri_escape($node_name)
                                    },
        site_url => "http://example.com/kakeswiki/",
    );
    $feed = $rss->recent_changes;
    like( $feed, qr|<modwiki:diff>http://example.com/\?action=show_diff;id=Calthorpe%20Arms</modwiki:diff>|,
          "make_diff_url used" );

    # Check that history url comes through.
    # Will use a different character set
    $rss = Wiki::Toolkit::Feed::RSS->new(
        %default_config,
        make_history_url        => sub {
            my $node_name = shift;
            return "http://example.com/?action=history;id="
                 . uri_escape($node_name)
                                    },
        site_url => "http://example.com/kakeswiki/",
        encoding => "UTF-16"
    );
    $feed = $rss->recent_changes;
    like( $feed, qr|<modwiki:history>http://example.com/\?action=history;id=Calthorpe%20Arms</modwiki:history>|,
          "make_history_url used" );

    # Test the 'items' parameter.
    $feed = $rss->recent_changes( items => 2 );
    unlike( $feed, qr|<title>Test Node 1</title>|, "items param works" );

    # Test the 'days' parameter.
    $feed = $rss->recent_changes( days => 2 );
    like( $feed, qr|<title>Old Node</title>|, "days param works" );

    # Test ignoring minor changes.
    $feed = $rss->recent_changes( ignore_minor_edits => 1 );
    unlike( $feed, qr|This is a minor change.|,
            "ignore_minor_edits works" );

    # Test personalised feeds.
    $feed = $rss->recent_changes(
                                  filter_on_metadata => {
                                                          username => "Kake",
                                                        },
                                );
    unlike( $feed, qr|<dc:contributor>nou</dc:contributor>|,
            "can filter on a single metadata criterion" );

    $feed = $rss->recent_changes(
                                  filter_on_metadata => {
                                                    username => "Kake",
                                                    locale   => "Bloomsbury",
                                                        },
                                );
    unlike( $feed, qr|<title>Test Node 1</title>|,
            "can filter on two criteria" );

    # Test the xml headers again, now we have given a character set
    like( $feed, qr|<?xml version="1.0"|, "is xml" );
    like( $feed, qr|<?xml version="1.0" encoding="UTF-16"|, "is xml" );
}