App-DrivePlayer

 view release on metacpan or  search on metacpan

t/unit/Test/DrivePlayer/DB.pm  view on Meta::CPAN

package Test::DrivePlayer::DB;

use strict;
use warnings;

use Test::Most;
use Test::DrivePlayer::TestBase;
use Test::DrivePlayer::Utils qw( :all );

use parent 'Test::DrivePlayer::TestBase';

# Each test gets a fresh in-memory-like DB via a temp file.
sub setup : Tests(setup) {
    my ($self) = @_;
    $self->SUPER::setup();
    $self->{db} = fake_db($self->_temp_db_path);
    return;
}

sub db { $_[0]->{db} }

# ---- Schema ----

sub schema_deployed : Tests(3) {
    my ($self) = @_;

    my $dbh = $self->db->schema->storage->dbh;
    my @tables = map { (split /\./, $_)[-1] =~ s/"//gr }
                 $dbh->tables(undef, undef, undef, 'TABLE');

    ok grep({ $_ eq 'scan_folders' } @tables), 'scan_folders table created';
    ok grep({ $_ eq 'folders'      } @tables), 'folders table created';
    ok grep({ $_ eq 'tracks'       } @tables), 'tracks table created';
}

sub second_connect_no_redeploy : Tests(1) {
    my ($self) = @_;

    # Re-connecting to an existing DB must not fail (tables already exist).
    my $db2 = fake_db($self->_temp_db_path);
    ok $db2->track_count >= 0, 'second connection to existing DB succeeds';
}

# ---- scan_folders ----

sub upsert_scan_folder_create : Tests(4) {
    my ($self) = @_;

    my $sf = $self->db->upsert_scan_folder(FAKE_FOLDER_ID, FAKE_FOLDER_NAME);
    is ref($sf), 'HASH',             'upsert_scan_folder returns hashref';
    ok $sf->{id},                    'returned row has id';
    is $sf->{drive_id}, FAKE_FOLDER_ID,   'drive_id correct';
    is $sf->{name},     FAKE_FOLDER_NAME, 'name correct';
}

sub upsert_scan_folder_update : Tests(2) {
    my ($self) = @_;

    $self->db->upsert_scan_folder(FAKE_FOLDER_ID, 'Original Name');
    my $updated = $self->db->upsert_scan_folder(FAKE_FOLDER_ID, 'Updated Name');
    is $updated->{name}, 'Updated Name', 'name updated on conflict';
    is $self->db->schema->resultset('ScanFolder')->count, 1, 'no duplicate row created';
}

sub get_scan_folder_by_drive_id : Tests(3) {
    my ($self) = @_;

    $self->db->upsert_scan_folder(FAKE_FOLDER_ID, FAKE_FOLDER_NAME);
    my $sf = $self->db->get_scan_folder_by_drive_id(FAKE_FOLDER_ID);
    is $sf->{drive_id}, FAKE_FOLDER_ID,   'found by drive_id';
    is $sf->{name},     FAKE_FOLDER_NAME, 'name correct';
    is $self->db->get_scan_folder_by_drive_id('nonexistent'), undef, 'returns undef when not found';
}

sub all_scan_folders_ordering : Tests(2) {
    my ($self) = @_;

    $self->db->upsert_scan_folder('id_z', 'Zzz Folder');
    $self->db->upsert_scan_folder('id_a', 'Aaa Folder');
    $self->db->upsert_scan_folder('id_m', 'Mmm Folder');

    my @folders = $self->db->all_scan_folders;
    is scalar @folders, 3, 'all_scan_folders returns all rows';
    is $folders[0]{name}, 'Aaa Folder', 'scan_folders ordered by name';
}

sub delete_scan_folder_cascade : Tests(3) {
    my ($self) = @_;

    my $sf  = $self->db->upsert_scan_folder(FAKE_FOLDER_ID, FAKE_FOLDER_NAME);
    my $fld = $self->db->upsert_folder(sample_folder(scan_folder_id => $sf->{id}));
    $self->db->upsert_track(sample_track(folder_id => $fld->{id}));

    is $self->db->track_count, 1, 'track exists before delete';
    $self->db->delete_scan_folder(FAKE_FOLDER_ID);
    is $self->db->schema->resultset('ScanFolder')->count, 0, 'scan_folder deleted';
    is $self->db->track_count, 0, 'tracks cascade-deleted';
}

# ---- folders ----

sub upsert_folder_create : Tests(5) {
    my ($self) = @_;

    my $sf  = $self->db->upsert_scan_folder(FAKE_FOLDER_ID, FAKE_FOLDER_NAME);
    my $fld = $self->db->upsert_folder(sample_folder(scan_folder_id => $sf->{id}));

    is ref($fld), 'HASH',          'upsert_folder returns hashref';
    ok $fld->{id},                 'returned row has id';
    is $fld->{name},  'Rock',      'name correct';
    ok defined $fld->{path},       'path present';
    is $fld->{scan_folder_id}, $sf->{id}, 'scan_folder_id correct';
}

sub upsert_folder_update : Tests(2) {
    my ($self) = @_;

    my $sf = $self->db->upsert_scan_folder(FAKE_FOLDER_ID, FAKE_FOLDER_NAME);
    $self->db->upsert_folder(sample_folder(scan_folder_id => $sf->{id}, name => 'OldName'));
    my $updated = $self->db->upsert_folder(
        sample_folder(scan_folder_id => $sf->{id}, name => 'NewName')
    );
    is $updated->{name}, 'NewName', 'folder name updated on conflict';
    is $self->db->schema->resultset('Folder')->count, 1, 'no duplicate folder row';
}

sub get_folder_by_drive_id : Tests(2) {
    my ($self) = @_;

    my $sf = $self->db->upsert_scan_folder(FAKE_FOLDER_ID, FAKE_FOLDER_NAME);
    $self->db->upsert_folder(sample_folder(scan_folder_id => $sf->{id}));
    my $fld = $self->db->get_folder_by_drive_id('folder_drive_id_rock');
    is $fld->{name}, 'Rock', 'folder found by drive_id';
    is $self->db->get_folder_by_drive_id('nope'), undef, 'returns undef when not found';
}

sub folders_for_scan_folder : Tests(2) {
    my ($self) = @_;

    my $sf  = $self->db->upsert_scan_folder(FAKE_FOLDER_ID, FAKE_FOLDER_NAME);
    $self->db->upsert_folder(sample_folder(
        scan_folder_id => $sf->{id}, drive_id => 'f1', name => 'Z', path => 'Z'
    ));
    $self->db->upsert_folder(sample_folder(
        scan_folder_id => $sf->{id}, drive_id => 'f2', name => 'A', path => 'A'
    ));

    my @flds = $self->db->folders_for_scan_folder($sf->{id});
    is scalar @flds, 2,      'returns all folders for scan_folder';
    is $flds[0]{name}, 'A',  'folders ordered by path';
}

# ---- tracks ----

sub upsert_track_create : Tests(6) {
    my ($self) = @_;

    my $sf  = $self->db->upsert_scan_folder(FAKE_FOLDER_ID, FAKE_FOLDER_NAME);
    my $fld = $self->db->upsert_folder(sample_folder(scan_folder_id => $sf->{id}));
    $self->db->upsert_track(sample_track(folder_id => $fld->{id}));

    is $self->db->track_count, 1, 'track inserted';
    my $t = $self->db->get_track_by_drive_id(FAKE_TRACK_ID);
    is ref($t), 'HASH',                   'get_track_by_drive_id returns hashref';
    is $t->{title},       'Bohemian Rhapsody', 'title correct';
    is $t->{artist},      'Queen',             'artist correct';
    is $t->{album},       'A Night at the Opera', 'album correct';
    is $t->{track_number}, 11,                'track_number correct';
}

sub upsert_track_update : Tests(5) {
    my ($self) = @_;

    my $sf  = $self->db->upsert_scan_folder(FAKE_FOLDER_ID, FAKE_FOLDER_NAME);
    my $fld = $self->db->upsert_folder(sample_folder(scan_folder_id => $sf->{id}));

    # First upsert sets metadata; second upsert (re-scan) should preserve it.
    $self->db->upsert_track(sample_track(folder_id => $fld->{id}, title => 'Old Title'));
    $self->db->upsert_track(sample_track(folder_id => $fld->{id}, title => 'New Title'));

    is $self->db->track_count, 1,          'no duplicate on upsert';
    my $t = $self->db->get_track_by_drive_id(FAKE_TRACK_ID);
    is $t->{title},  'Old Title', 'existing metadata preserved on re-scan';



( run in 2.701 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )