<commit_before>use Mojo::Base -strict;

BEGIN {
  $ENV{MOJO_NO_IPV6} = 1;
  $ENV{MOJO_REACTOR} = 'Mojo::Reactor::Poll';
}

use Test::More;
use Mojo::ByteStream 'b';
use Mojo::JSON 'j';
use Mojolicious::Lite;
use Test::Mojo;

websocket '/echo' => sub {
  my $self = shift;
  $self->tx->max_websocket_size(262145);
  $self->on(binary => sub { shift->send({binary => shift}) });
  $self->on(
    text => sub {
      my ($self, $bytes) = @_;
      $self->send("echo: $bytes");
    }
  );
};

get '/echo' => {text => 'plain echo!'};

websocket '/json' => sub {
  my $self = shift;
  $self->on(
    json => sub {
      my ($self, $json) = @_;
      return $self->send({json => [@$json, 4]}) if ref $json eq 'ARRAY';
      $json->{test} += 1;
      $self->send({json => $json});
    }
  );
};

get '/plain' => {text => 'Nothing to see here!'};

websocket '/push' => sub {
  my $self = shift;
  my $id = Mojo::IOLoop->recurring(0.1 => sub { $self->send('push') });
  $self->on(finish => sub { Mojo::IOLoop->remove($id) });
};

websocket '/unicode' => sub {
  my $self = shift;
  $self->on(
    message => sub {
      my ($self, $msg) = @_;
      $self->send("♥: $msg");
    }
  );
};

websocket '/bytes' => sub {
  my $self = shift;
  $self->on(
    frame => sub {
      my ($ws, $frame) = @_;
      $ws->send({$frame->[4] == 2 ? 'binary' : 'text', $frame->[5]});
    }
  );
};

websocket '/once' => sub {
  my $self = shift;
  $self->on(
    message => sub {
      my ($self, $msg) = @_;
      $self->send("ONE: $msg");
    }
  );
  $self->tx->once(
    message => sub {
      my ($tx, $msg) = @_;
      $self->send("TWO: $msg");
    }
  );
};

under '/nested';

websocket sub {
  my $self = shift;
  my $echo = $self->cookie('echo') // '';
  $self->cookie(echo => 'again');
  $self->on(
    message => sub {
      my ($self, $msg) = @_;
      $self->send("nested echo: $msg$echo")->finish(1000);
    }
  );
};

get {text => 'plain nested!'};

post {data => 'plain nested too!'};

my $t = Test::Mojo->new;

# Simple roundtrip
$t->websocket_ok('/echo')->send_ok('hello')->message_ok('got a message')
  ->message_is('echo: hello')->finish_ok;

# Multiple roundtrips
$t->websocket_ok('/echo')->send_ok('hello again')
  ->message_ok->message_is('echo: hello again')->send_ok('and one more time')
  ->message_ok->message_is('echo: and one more time')->finish_ok;

# Custom header and protocols
$t->websocket_ok('/echo' => {DNT => 1} => ['foo', 'bar', 'baz'])
  ->header_is('Sec-WebSocket-Protocol' => 'foo')->send_ok('hello')<commit_msg>better tests for WebSocket handshake<commit_after>use Mojo::Base -strict;

BEGIN {
  $ENV{MOJO_NO_IPV6} = 1;
  $ENV{MOJO_REACTOR} = 'Mojo::Reactor::Poll';
}

use Test::More;
use Mojo::ByteStream 'b';
use Mojo::JSON 'j';
use Mojolicious::Lite;
use Test::Mojo;

websocket '/echo' => sub {
  my $self = shift;
  $self->tx->max_websocket_size(262145);
  $self->on(binary => sub { shift->send({binary => shift}) });
  $self->on(
    text => sub {
      my ($self, $bytes) = @_;
      $self->send("echo: $bytes");
    }
  );
};

get '/echo' => {text => 'plain echo!'};

websocket '/json' => sub {
  my $self = shift;
  $self->on(
    json => sub {
      my ($self, $json) = @_;
      return $self->send({json => [@$json, 4]}) if ref $json eq 'ARRAY';
      $json->{test} += 1;
      $self->send({json => $json});
    }
  );
};

get '/plain' => {text => 'Nothing to see here!'};

websocket '/push' => sub {
  my $self = shift;
  my $id = Mojo::IOLoop->recurring(0.1 => sub { $self->send('push') });
  $self->on(finish => sub { Mojo::IOLoop->remove($id) });
};

websocket '/unicode' => sub {
  my $self = shift;
  $self->on(
    message => sub {
      my ($self, $msg) = @_;
      $self->send("♥: $msg");
    }
  );
};

websocket '/bytes' => sub {
  my $self = shift;
  $self->on(
    frame => sub {
      my ($ws, $frame) = @_;
      $ws->send({$frame->[4] == 2 ? 'binary' : 'text', $frame->[5]});
    }
  );
};

websocket '/once' => sub {
  my $self = shift;
  $self->on(
    message => sub {
      my ($self, $msg) = @_;
      $self->send("ONE: $msg");
    }
  );
  $self->tx->once(
    message => sub {
      my ($tx, $msg) = @_;
      $self->send("TWO: $msg");
    }
  );
};

under '/nested';

websocket sub {
  my $self = shift;
  my $echo = $self->cookie('echo') // '';
  $self->cookie(echo => 'again');
  $self->on(
    message => sub {
      my ($self, $msg) = @_;
      $self->send("nested echo: $msg$echo")->finish(1000);
    }
  );
};

get {text => 'plain nested!'};

post {data => 'plain nested too!'};

my $t = Test::Mojo->new;

# Simple roundtrip
$t->websocket_ok('/echo')->send_ok('hello')->message_ok('got a message')
  ->message_is('echo: hello')->finish_ok;

# Multiple roundtrips
$t->websocket_ok('/echo')->send_ok('hello again')
  ->message_ok->message_is('echo: hello again')->send_ok('and one more time')
  ->message_ok->message_is('echo: and one more time')->finish_ok;

# Custom headers and protocols
my $headers = {DNT => 1, 'Sec-WebSocket-Key' => '<KEY>};
$t->websocket_ok('/echo' => $headers => ['foo', 'bar', 'baz'])
  ->header_is('Sec-WebSocket-Accept'   => 'I+x5C3/LJxrmDrWw42nMP4pCSes=')
  ->header_is('Sec-WebSocket-Protocol' => 'foo')->send_ok('hello')
{'fraction_non_alphanumeric': 0.24505093215452622, 'fraction_numerical': 0.00864885642898328, 'mean_word_length': 3.126883425852498, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 161, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1346764', 'n_tokens_mistral': 2083, 'n_tokens_neox': 2018, 'n_words': 430}