Cavil-CLI

 view release on metacpan or  search on metacpan

t/lib/CavilCliTest.pm  view on Meta::CPAN

# Run the CLI as a user would: seed @ARGV with the check command and the caller's arguments, and point it at
# the mock. Capture stdout, stderr and the exit code. Credentials go through the environment because
# there is no --url/--token to pass (see Cavil::CLI): the server and its token always travel as a pair.
sub run ($self, @args) { return $self->run_command('check', @args) }

# Same, but for an arbitrary command (e.g. whoami) rather than the check default.
sub run_command ($self, @argv) {
  return $self->_invoke(\@argv, undef, {CAVIL_URL => $self->url, CAVIL_API_KEY => 'test-token'});
}

# Same, with whatever credentials the caller wants in the environment (a bad token, or only one of the pair).
sub run_with_env ($self, $env, @argv) { return $self->_invoke(\@argv, undef, $env) }

# Run exactly the given arguments with no credentials in the environment, optionally feeding stdin (for the
# config command's prompts). Used to exercise resolution from the saved config file.
sub run_bare ($self, $argv, $stdin = undef) { return $self->_invoke($argv, $stdin) }

sub _invoke ($self, $argv, $stdin = undef, $env = {}) {
  my $cli = $self->cli;
  my ($out, $err, $code) = ('', '', undef);
  my $run = sub {
    local @ARGV = @$argv;

    # A whole copy, so a CAVIL_URL or CAVIL_API_KEY in the real environment cannot reach the code under test.

t/scenario_whoami.t  view on Meta::CPAN

    is $result->{exit}, 2, 'one half of the pair is a usage error';
    like $result->{stderr}, qr/from the same source/, 'and says why';
  }

  # --url would aim the saved token at a different server, so it is only accepted when saving settings.
  my $aimed = $test->run_bare(['whoami', '--url', $test->url]);
  is $aimed->{exit}, 2, '--url is refused outside the config command';
  like $aimed->{stderr}, qr/only applies to 'cavil-cli config'/, 'pointing at the command that does take it';
};

subtest 'config saves credentials and later commands use them without any flags' => sub {

  # --url is fine on the command line; the token is read from stdin (never a flag), here by piping it in.
  my $save = $test->run_bare(['config', '--url', $test->url], "test-token\n");
  is $save->{exit}, 0, 'saving succeeds';
  like $save->{stdout},   qr/Saved configuration/, 'it confirms the save';
  unlike $save->{stdout}, qr/test-token/,          'and never echoes the token';

  # --show reveals the URL but masks the token.
  my $show = $test->run_bare(['config', '--show']);
  like $show->{stdout},   qr{url:\s+\Q@{[$test->url]}\E}, 'show lists the url';
  like $show->{stdout},   qr/token:\s+\*+ \(set\)/,       'show masks the token';
  unlike $show->{stdout}, qr/test-token/,                 'the real token is never printed';

  # whoami with no flags and nothing in the environment now works, from the saved config alone.
  my $who = $test->run_bare(['whoami']);
  is $who->{exit}, 0, 'the saved credentials authenticate';
  like $who->{stdout}, qr/Authenticated as tester/, 'and identify the user';
};

done_testing;



( run in 1.207 second using v1.01-cache-2.11-cpan-007c89162af )