#!/usr/bin/env perl use strict; use warnings; use Test::More tests => 42; use Mock::CommandRegistry; use Plugin::Vote; my %ctx_a = ( irc => undef, logger => undef, who => 'user!who@example.com', where => "#channel_a", ided => undef, rest => undef, no_reenter => undef, ); my %ctx_b = %ctx_a; $ctx_b{where} = "#channel_b"; my $cr = new Mock::CommandRegistry; my $register = sub { $cr->register(@_); }; Plugin::Vote->configure($register, undef, undef, undef); # Test all expected commands registered { my @expected_commands = ("vote on", "vote yes", "vote no", "vote end"); for my $cmd (@expected_commands) { my $is_registered = $cr->is_registered_to_owner("Plugin::Vote", $cmd); ok($is_registered, "registered command $cmd"); } } # Test ending a vote when none is in progress produces error message { my %ctx = %ctx_a; my $r = $cr->run_owned("Plugin::Vote", "vote end", %ctx); ok($r =~ m/no vote.*progress/i, "no vote error message"); } sub ok_vote_match { my ($result, $expect_ayes, $expect_noes) = @_; if ($result =~ m/The votes are in.*Ayes: (\d+).*Noes: (\d+)/) { is($1, $expect_ayes, "ayes match"); is($2, $expect_noes, "ayes match"); } else { die("'$result' can't be taken apart"); } } sub vote_started { my ($result) = @_; $result =~ m/^Call to vote.*/; } # - Start a vote, end a vote, 0,0 { my %ctx = %ctx_a; $ctx{rest} = "topic1"; my $r = $cr->run_owned("Plugin::Vote", "vote on", %ctx); note($r); ok(vote_started($r), "vote started"); $ctx{rest} = ""; $r = $cr->run_owned("Plugin::Vote", "vote end", %ctx); note($r); ok_vote_match($r, 0, 0); } # - Start a vote, start another, error message, end a vote, 0,0 { my %ctx = %ctx_a; $ctx{rest} = "topic1"; my $r = $cr->run_owned("Plugin::Vote", "vote on", %ctx); note($r); ok(vote_started($r), "first vote started"); $ctx{rest} = "topic2"; $r = $cr->run_owned("Plugin::Vote", "vote on", %ctx); note($r); ok(!vote_started($r), "second vote not started"); $ctx{rest} = ""; $r = $cr->run_owned("Plugin::Vote", "vote end", %ctx); note($r); ok_vote_match($r, 0, 0); } # - Start a vote, vote yes, end a vote, 1,0 { my %ctx = %ctx_a; $ctx{rest} = "topic1"; my $r = $cr->run_owned("Plugin::Vote", "vote on", %ctx); note($r); ok(vote_started($r), "vote started"); $ctx{rest} = ""; $r = $cr->run_owned("Plugin::Vote", "vote yes", %ctx); note($r); $r = $cr->run_owned("Plugin::Vote", "vote end", %ctx); note($r); ok_vote_match($r, 1, 0); } # - Start a vote, vote no, end a vote, 0,1 { my %ctx = %ctx_a; $ctx{rest} = "topic1"; my $r = $cr->run_owned("Plugin::Vote", "vote on", %ctx); note($r); ok(vote_started($r), "vote started"); $ctx{rest} = ""; $r = $cr->run_owned("Plugin::Vote", "vote no", %ctx); note($r); $r = $cr->run_owned("Plugin::Vote", "vote end", %ctx); note($r); ok_vote_match($r, 0, 1); } # - Start a vote, vote yes twice, error message, end the vote, 1,0 { my %ctx = %ctx_a; $ctx{rest} = "topic1"; my $r = $cr->run_owned("Plugin::Vote", "vote on", %ctx); note($r); ok(vote_started($r), "vote started"); $ctx{rest} = ""; $r = $cr->run_owned("Plugin::Vote", "vote yes", %ctx); note($r); $r = $cr->run_owned("Plugin::Vote", "vote yes", %ctx); note($r); ok($r =~ m/already voted/, "user told about double vote"); $r = $cr->run_owned("Plugin::Vote", "vote end", %ctx); note($r); ok_vote_match($r, 1, 0); } # - Start a vote, vote no twice, error message, end the vote, 0,1 { my %ctx = %ctx_a; $ctx{rest} = "topic1"; my $r = $cr->run_owned("Plugin::Vote", "vote on", %ctx); note($r); ok(vote_started($r), "vote started"); $ctx{rest} = ""; $r = $cr->run_owned("Plugin::Vote", "vote no", %ctx); note($r); $r = $cr->run_owned("Plugin::Vote", "vote no", %ctx); note($r); ok($r =~ m/already voted/, "user told about double vote"); $r = $cr->run_owned("Plugin::Vote", "vote end", %ctx); note($r); ok_vote_match($r, 0, 1); } # - Start a vote, vote no then yes, error message, end the vote, 0,1 { my %ctx = %ctx_a; $ctx{rest} = "topic1"; my $r = $cr->run_owned("Plugin::Vote", "vote on", %ctx); note($r); ok(vote_started($r), "vote started"); $ctx{rest} = ""; $r = $cr->run_owned("Plugin::Vote", "vote no", %ctx); note($r); $r = $cr->run_owned("Plugin::Vote", "vote yes", %ctx); note($r); ok($r =~ m/already voted/, "user told about double vote"); $r = $cr->run_owned("Plugin::Vote", "vote end", %ctx); note($r); ok_vote_match($r, 0, 1); } # - Start a vote, two people vote yes, one no, end the vote, 2,1 { my %ctx = %ctx_a; $ctx{rest} = "topic1"; my $r = $cr->run_owned("Plugin::Vote", "vote on", %ctx); note($r); ok(vote_started($r), "vote started"); $ctx{rest} = ""; $r = $cr->run_owned("Plugin::Vote", "vote yes", %ctx); note($r); my $orig_who = $ctx{who}; $ctx{who} = "a$orig_who"; $r = $cr->run_owned("Plugin::Vote", "vote yes", %ctx); note($r); $ctx{who} = "b$orig_who"; $r = $cr->run_owned("Plugin::Vote", "vote no", %ctx); note($r); $ctx{who} = $orig_who; $r = $cr->run_owned("Plugin::Vote", "vote end", %ctx); note($r); ok_vote_match($r, 2, 1); } # Test cases cross-chan # - Start a vote #a, vote on #b, error message, end a vote, 0,0 { my %ctx = %ctx_a; # Start a vote on channel A $ctx{rest} = "topic1"; my $r = $cr->run_owned("Plugin::Vote", "vote on", %ctx); note($r); ok(vote_started($r), "vote started"); # Vote yes on channel B - should fail since votes are channel-bound $r = $cr->run_owned("Plugin::Vote", "vote yes", %ctx_b); note($r); $r = $cr->run_owned("Plugin::Vote", "vote end", %ctx); note($r); ok_vote_match($r, 0, 0); } # - Start a vote #a, start identical vote #b, vote #a yes, vote #b no, end #a vote, 1,0, end #b vote, 0,1 { my %ctx_m_a = %ctx_a; my %ctx_m_b = %ctx_b; # Start a vote on channel A $ctx_m_a{rest} = "topic1"; my $r = $cr->run_owned("Plugin::Vote", "vote on", %ctx_m_a); note($r); ok(vote_started($r), "vote A started"); # Start a vote on channel B $ctx_m_b{rest} = "topic1"; $r = $cr->run_owned("Plugin::Vote", "vote on", %ctx_m_b); note($r); ok(vote_started($r), "vote B started"); # Vote yes on channel A $r = $cr->run_owned("Plugin::Vote", "vote yes", %ctx_m_a); note($r); # Vote no on channel B $r = $cr->run_owned("Plugin::Vote", "vote no", %ctx_m_b); note($r); # Gather votes from A, expect 1 for, 0 against $r = $cr->run_owned("Plugin::Vote", "vote end", %ctx_m_a); note($r); ok_vote_match($r, 1, 0); # Gather votes from B, expect 0 for, 1 against $r = $cr->run_owned("Plugin::Vote", "vote end", %ctx_m_b); note($r); ok_vote_match($r, 0, 1); }