App-Netdisco

 view release on metacpan or  search on metacpan

xt/145-topology-del-only-matched.t  view on Meta::CPAN

#!/usr/bin/env perl

use strict;
use warnings;
no warnings 'once'; # the glob overrides below are single-use by design

# Deleting a manual topology link resets is_uplink, manual_topo and the
# remote_* columns on both of its ports. The route did that whether or not a
# manual link matched, so naming the two ends of a discovered uplink cleared
# its is_uplink flag, and with that the portctl_uplinks guard stopped
# protecting it until the next discovery. Only a deleted link may reset its
# ports.
#
# Only the DB edges are faked: the user, its roles, the schema and the
# devices. The route and its checks are the real ones, and the user is an
# admin so the role scoping of #1691 passes without a database.

BEGIN { $ENV{DANCER_ENVDIR} = '/dev/null'; }

use Test::More 0.88;
use App::Netdisco;
use App::Netdisco::Web;
use Dancer ':tests';
use Dancer::Test;

config->{logger} = 'null';

my $deleted;    # what the delete of the manual link returns
my @updated;    # updates made to device ports

package FakeSchema;
sub new       { return bless {}, $_[0] }
sub txn_do    { return $_[1]->() }
sub resultset { return $_[0] }
sub search    { return $_[0] }
sub delete    { return $deleted }

package FakePorts;
sub new    { return bless { ip => $_[1] }, $_[0] }
sub search { my ($s, $q) = @_; return bless { %$s, port => $q->{port} }, ref $s }
sub single { return $_[0] }
sub update { my ($s, $v) = @_; push @updated, [ $s->{ip}, $s->{port}, $v ]; return $s }

package FakeDevice;
sub new        { return bless { ip => $_[1] }, $_[0] }
sub in_storage { 1 }
sub ports      { return FakePorts->new($_[0]->{ip}) }

package main;

no warnings 'redefine';
*Dancer::Plugin::Auth::Extensible::logged_in_user = sub { return { username => 'someone' } };
*Dancer::Plugin::Auth::Extensible::user_roles     = sub { return wantarray ? ('admin') : ['admin'] };
*App::Netdisco::Web::Plugin::AdminTask::Topology::schema     = sub { return FakeSchema->new };
*App::Netdisco::Web::Plugin::AdminTask::Topology::get_device = sub { return FakeDevice->new($_[0]) };

set trust_x_remote_user => 1;

sub delete_link {
  @updated = ();
  Dancer::Cookies->init;
  # Dancer::Test drops a dashed name from its headers argument before the
  # request is built (see xt/57), so the XHR marker goes in the environment
  local $ENV{HTTP_X_REQUESTED_WITH} = 'XMLHttpRequest';
  return dancer_response(POST => '/ajax/control/admin/topology/del', {
    headers => [ 'X-REMOTE_USER' => 'someone' ],
    params  => { dev1 => '192.0.2.1', port1 => 'Gi1/1',
                 dev2 => '192.0.2.2', port2 => 'Gi1/2' },
  });
}

# DBI reports "no rows" as the true string "0E0" (see xt/98)
foreach my $none ('0E0', 0) {
  $deleted = $none;
  my $res = delete_link();
  is $res->status, 200, "topology_del__no_manual_link_matched_($none)__still_answers";
  is scalar @updated, 0, "topology_del__no_manual_link_matched_($none)__leaves_both_ports_alone";
}

$deleted = 1;
my $res = delete_link();
is $res->status, 200, 'topology_del__a_manual_link_matched__answers';
is_deeply [ map { [ $_->[0], $_->[1], $_->[2]->{is_uplink} ] } @updated ],
          [ [ '192.0.2.1', 'Gi1/1', \'false' ], [ '192.0.2.2', 'Gi1/2', \'false' ] ],
  'topology_del__a_manual_link_matched__resets_both_of_its_ports';

done_testing;



( run in 1.433 second using v1.01-cache-2.11-cpan-145b269f2f3 )