<?php
/**
 * @author Daniel J. Summers <daniel@bitbadger.solutions>
 * @license MIT
 */

declare(strict_types=1);

use BitBadger\PDODocument\{DocumentException, Exists, Field, Find, RemoveFields};
use Test\Integration\SQLite\ThrowawayDb;
use Test\Integration\TestDocument;

pest()->group('integration', 'sqlite');

describe('::byId()', function () {
    test('updates an existing document', function () {
        RemoveFields::byId(ThrowawayDb::TABLE, 'two', ['sub', 'value']);
        $tryDoc = Find::byId(ThrowawayDb::TABLE, 'two', TestDocument::class);
        expect($tryDoc)->isSome->toBeTrue()
            ->and($tryDoc->value)->sub->toBeNull()
            ->and($tryDoc->value->value)->toBeEmpty();
    });
    test('does nothing when the field to remove does not exist', function () {
        expect(Exists::byFields(ThrowawayDb::TABLE, [Field::exists('a_field_that_does_not_exist')]))->toBeFalse();
        RemoveFields::byId(ThrowawayDb::TABLE, 'one', ['a_field_that_does_not_exist']);
    });
    test('does nothing when the document does not exist', function () {
        expect(Exists::byId(ThrowawayDb::TABLE, 'fifty'))->toBeFalse();
        RemoveFields::byId(ThrowawayDb::TABLE, 'fifty', ['sub']);
    });
});

describe('::byFields()', function () {
    test('updates matching documents', function () {
        RemoveFields::byFields(ThrowawayDb::TABLE, [Field::equal('num_value', 17)], ['sub']);
        $doc = Find::firstByFields(ThrowawayDb::TABLE, [Field::equal('num_value', 17)], TestDocument::class);
        expect($doc)->isSome->toBeTrue()->and($doc->value)->sub->toBeNull();
    });
    test('does nothing when the field to remove does not exist', function () {
        expect(Exists::byFields(ThrowawayDb::TABLE, [Field::exists('nada')]))->toBeFalse();
        RemoveFields::byFields(ThrowawayDb::TABLE, [Field::equal('num_value', 17)], ['nada']);
    });
    test('does nothing when no documents match', function () {
        expect(Exists::byFields(ThrowawayDb::TABLE, [Field::notEqual('missing', 'nope')]))->toBeFalse();
        RemoveFields::byFields(ThrowawayDb::TABLE, [Field::notEqual('missing', 'nope')], ['value']);
    });
});

describe('::byContains()', function () {
    test('throws an exception', function () {
        expect(fn () => RemoveFields::byContains('', [], []))->toThrow(DocumentException::class);
    });
});

describe('::byJsonPath()', function () {
    test('throws an exception', function () {
        expect(fn () => RemoveFields::byJsonPath('', '', []))->toThrow(DocumentException::class);
    });
});