App-DrivePlayer

 view release on metacpan or  search on metacpan

lib/App/DrivePlayer/SheetDB.pm  view on Meta::CPAN


# ------------------------------------------------------------------
# Sync  (bidirectional reconcile)
# ------------------------------------------------------------------

# Reconcile the local DB with the sheet per these rules:
#   - Both sides have a value for a field, different: DB wins.
#   - One side blank/missing: fill from the other (blank = missing).
#   - drive_id only in DB: add to sheet.
#   - drive_id only on sheet: ask drive_exists; if exists, add to DB; else
#     delete from sheet.  If drive_exists throws, keep the row as-is
#     (never destroy data on an API error).
#   - Scan-folder list: union, never auto-delete (config is user-owned).
# Returns a summary hashref.
sub sync_with_db {
    my ($self, $db, %opts) = @_;
    my $drive_exists = $opts{drive_exists} || sub { 1 };
    my $ss = $self->_open();

    my %summary = (
        folders_added_local => 0,

lib/App/DrivePlayer/SheetDB.pm  view on Meta::CPAN

"missing" on either side, so cleared fields cannot be propagated.

=item *

C<drive_id> in the DB but not the sheet: row added to the sheet.

=item *

C<drive_id> on the sheet but not in the DB: C<drive_exists-E<gt>($id)>
is called.  A truthy result adds the track to the DB; a falsy result
deletes the row from the sheet.  If the callback throws (API failure),
the row is preserved on both sides --sync never destroys data on error.

=item *

Scan-folder list: union only; folders are never auto-deleted because
the list is user-owned configuration.

=back

Returns a summary hashref.

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


    my $p = fake_player();
    isa_ok $p, 'App::DrivePlayer::Player', 'constructor returns Player';
    is $p->state, 'stop', 'initial state is stop';
    is $p->current_track, undef, 'no current track initially';
}

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

    throws_ok { App::DrivePlayer::Player->new() }
        qr/required/i,
        'constructor requires auth';
}

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

    lives_ok {
        App::DrivePlayer::Player->new(auth => fake_auth())
    } 'constructor without callbacks lives';



( run in 0.812 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )