1# This make sures that we can close a DCC connection right after sending
2# some data over it. The original bug was that the DCC plugin didn't post
3# a delayed close event correctly so it ended up checking if there was data
4# left to be sent on an undefined value rather than the wheel in question.
5
6use strict;
7use warnings FATAL => 'all';
8use lib 't/inc';
9use POE::Component::IRC;
10use POE::Component::Server::IRC;
11use POE;
12use Test::More tests => 12;
13
14my $bot1 = POE::Component::IRC->spawn(
15    Flood        => 1,
16    plugin_debug => 1,
17);
18my $bot2 = POE::Component::IRC->spawn(
19    Flood        => 1,
20    plugin_debug => 1,
21);
22my $ircd = POE::Component::Server::IRC->spawn(
23    Auth      => 0,
24    AntiFlood => 0,
25);
26
27POE::Session->create(
28    package_states => [
29        main => [qw(
30            _start
31            ircd_listener_add
32            ircd_listener_failure
33            _shutdown
34            irc_001
35            irc_join
36            irc_disconnected
37            irc_dcc_request
38            irc_dcc_done
39            irc_dcc_chat
40            irc_dcc_start
41        )],
42    ],
43);
44
45$poe_kernel->run();
46
47sub _start {
48    my ($kernel) = $_[KERNEL];
49
50    $ircd->yield('register', 'all');
51    $ircd->yield('add_listener');
52    $kernel->delay(_shutdown => 60, 'Timed out');
53}
54
55sub ircd_listener_failure {
56    my ($kernel, $op, $reason) = @_[KERNEL, ARG1, ARG3];
57    $kernel->yield('_shutdown', "$op: $reason");
58}
59
60sub ircd_listener_add {
61    my ($kernel, $port) = @_[KERNEL, ARG0];
62
63    $bot1->yield(register => 'all');
64    $bot1->yield(connect => {
65        nick    => 'TestBot1',
66        server  => '127.0.0.1',
67        port    => $port,
68    });
69
70    $bot2->yield(register => 'all');
71    $bot2->yield(connect => {
72        nick    => 'TestBot2',
73        server  => '127.0.0.1',
74        port    => $port,
75    });
76}
77
78sub irc_001 {
79    my $irc = $_[SENDER]->get_heap();
80    pass('Logged in');
81    $irc->yield(join => '#testchannel');
82}
83
84sub irc_join {
85    my ($sender, $who, $where) = @_[SENDER, ARG0, ARG1];
86    my $nick = ( split /!/, $who )[0];
87    my $irc = $sender->get_heap();
88
89    if ($nick eq $irc->nick_name()) {
90        is($where, '#testchannel', 'Joined Channel Test');
91
92        if ($nick eq 'TestBot2') {
93            $irc->yield(dcc => TestBot1 => CHAT => '' => '' => 5);
94        }
95    }
96}
97
98sub irc_dcc_request {
99    my ($sender, $cookie) = @_[SENDER, ARG3];
100    pass('Got dcc request');
101    $sender->get_heap()->yield(dcc_accept => $cookie);
102}
103
104sub irc_dcc_start {
105    my ($sender, $id) = @_[SENDER, ARG0];
106    my $irc = $sender->get_heap();
107    pass('DCC started');
108
109    if ($irc->nick_name() eq 'TestBot2') {
110        $irc->yield(dcc_chat => $id => 'MOO');
111        $irc->yield(dcc_close => $id);
112    }
113}
114
115sub irc_dcc_chat {
116    my ($sender, $what) = @_[SENDER, ARG3];
117    is($what, 'MOO', 'DCC CHAT test');
118}
119
120sub irc_dcc_done {
121    pass('Got dcc close');
122    $_[SENDER]->get_heap()->yield('quit');
123}
124
125sub irc_disconnected {
126    my ($kernel, $heap) = @_[KERNEL, HEAP];
127    pass('irc_disconnected');
128    $heap->{count}++;
129    $kernel->yield('_shutdown') if $heap->{count} == 2;
130}
131
132sub _shutdown {
133    my ($kernel, $error) = @_[KERNEL, ARG0];
134    fail($error) if defined $error;
135
136    $kernel->alarm_remove_all();
137    $ircd->yield('shutdown');
138    $bot1->yield('shutdown');
139    $bot2->yield('shutdown');
140}
141
142