Airlock

 view release on metacpan or  search on metacpan

docs/superpowers/plans/2026-10-02-airlock-phase-1.md  view on Meta::CPAN


  sub request {
    my ( $self, $method, $url, $args ) = @_;
    my $body = $args->{content} // '';
    my ( $path ) = $url =~ m{\Ahttps?://[^/]+(/[^?]*)};
    push @{ $self->seen }, { method => $method, url => $url, body => $body, headers => $args->{headers} };
    CORE::open( my $input, '<', \$body ) or die $!;
    my $psgi = $self->app->( {
      REQUEST_METHOD  => $method,
      PATH_INFO       => $path,
      CONTENT_TYPE    => $args->{headers}{'content-type'},
      CONTENT_LENGTH  => length $body,
      REMOTE_ADDR     => '127.0.0.1',
      HTTP_USER_AGENT => 'local-ua',
      'psgi.input'    => $input
    } );
    return {
      success => $psgi->[0] < 400 ? 1 : '',
      status  => $psgi->[0],
      reason  => 'local',
      content => join( '', @{ $psgi->[2] } ),

docs/superpowers/plans/2026-10-02-airlock-phase-1.md  view on Meta::CPAN

  return ( $t, $client, \@slept, $ua );
}

subtest 'start' => sub {
  my ( $t, $client, undef, $ua ) = fixture();
  my $start = $client->start;
  like( $start->{device_code}, qr/\A[0-9a-f]{64}\z/, 'device_code' );
  like( $start->{user_code}, qr/\A\w{4}-\w{4}\z/, 'user_code' );
  is( $t->row( $start->{device_code} )->{scope}, 'read write', 'the scope arrived' );
  is( $ua->seen->[0]{headers}{accept}, 'application/json', 'asks for JSON' );
  like( $ua->seen->[0]{headers}{'content-type'}, qr{\Aapplication/x-www-form-urlencoded}, 'sends a form' );

  my ( undef, $unknown ) = fixture( client_id => 'nope' );
  ok( !eval { $unknown->start; 1 }, 'an unknown client croaks' );
  like( $@, qr/start failed: invalid_client/, 'with the server error' );
};

subtest 'login: approved while polling' => sub {
  my ( $t, $client, $slept ) = fixture(
    after_sleep => sub {
      my ( $t, $polls ) = @_;

t/70-client.t  view on Meta::CPAN


  sub request {
    my ( $self, $method, $url, $args ) = @_;
    my $body = $args->{content} // '';
    my ( $path ) = $url =~ m{\Ahttps?://[^/]+(/[^?]*)};
    push @{ $self->seen }, { method => $method, url => $url, body => $body, headers => $args->{headers} };
    CORE::open( my $input, '<', \$body ) or die $!;
    my $psgi = $self->app->( {
      REQUEST_METHOD  => $method,
      PATH_INFO       => $path,
      CONTENT_TYPE    => $args->{headers}{'content-type'},
      CONTENT_LENGTH  => length $body,
      REMOTE_ADDR     => '127.0.0.1',
      HTTP_USER_AGENT => 'local-ua',
      'psgi.input'    => $input
    } );
    return {
      success => $psgi->[0] < 400 ? 1 : '',
      status  => $psgi->[0],
      reason  => 'local',
      content => join( '', @{ $psgi->[2] } ),

t/70-client.t  view on Meta::CPAN

  return ( $t, $client, \@slept, $ua );
}

subtest 'start' => sub {
  my ( $t, $client, undef, $ua ) = fixture();
  my $start = $client->start;
  like( $start->{device_code}, qr/\A[0-9a-f]{64}\z/, 'device_code' );
  like( $start->{user_code}, qr/\A\w{4}-\w{4}\z/, 'user_code' );
  is( $t->row( $start->{device_code} )->{scope}, 'read write', 'the scope arrived' );
  is( $ua->seen->[0]{headers}{accept}, 'application/json', 'asks for JSON' );
  like( $ua->seen->[0]{headers}{'content-type'}, qr{\Aapplication/x-www-form-urlencoded}, 'sends a form' );

  my ( undef, $unknown ) = fixture( client_id => 'nope' );
  ok( !eval { $unknown->start; 1 }, 'an unknown client croaks' );
  like( $@, qr/start failed: invalid_client/, 'with the server error' );
};

subtest 'login: approved while polling' => sub {
  my ( $t, $client, $slept ) = fixture(
    after_sleep => sub {
      my ( $t, $polls ) = @_;



( run in 1.407 second using v1.01-cache-2.11-cpan-03fa5a55a2b )