mirror of
https://github.com/chenasraf/nextcloud-pantry.git
synced 2026-05-18 01:28:57 +00:00
193 lines
6.1 KiB
PHP
193 lines
6.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
// SPDX-FileCopyrightText: Chen Asraf <contact@casraf.dev>
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
namespace OCA\Pantry\Tests\Unit\Service;
|
|
|
|
use OCA\Pantry\Db\Note;
|
|
use OCA\Pantry\Db\NoteMapper;
|
|
use OCA\Pantry\Exception\NotFoundException;
|
|
use OCA\Pantry\Service\NoteService;
|
|
use OCP\AppFramework\Db\DoesNotExistException;
|
|
use PHPUnit\Framework\MockObject\MockObject;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class NoteServiceTest extends TestCase {
|
|
/** @var NoteMapper&MockObject */
|
|
private NoteMapper $noteMapper;
|
|
private NoteService $svc;
|
|
|
|
protected function setUp(): void {
|
|
$this->noteMapper = $this->createMock(NoteMapper::class);
|
|
$this->svc = new NoteService($this->noteMapper);
|
|
}
|
|
|
|
private function makeNote(array $overrides = []): Note {
|
|
$n = new Note();
|
|
$n->setHouseId($overrides['houseId'] ?? 1);
|
|
$n->setTitle($overrides['title'] ?? 'Groceries');
|
|
$n->setContent($overrides['content'] ?? null);
|
|
$n->setColor($overrides['color'] ?? null);
|
|
$n->setCreatedBy($overrides['createdBy'] ?? 'admin');
|
|
$n->setSortOrder($overrides['sortOrder'] ?? 0);
|
|
$n->setCreatedAt($overrides['createdAt'] ?? 1000);
|
|
$n->setUpdatedAt($overrides['updatedAt'] ?? 1000);
|
|
if (isset($overrides['id'])) {
|
|
$ref = new \ReflectionProperty($n, 'id');
|
|
$ref->setValue($n, $overrides['id']);
|
|
}
|
|
return $n;
|
|
}
|
|
|
|
public function testListNotesDelegatesToMapper(): void {
|
|
$notes = [$this->makeNote()];
|
|
$this->noteMapper->expects($this->once())
|
|
->method('findByHouse')
|
|
->with(1)
|
|
->willReturn($notes);
|
|
|
|
$this->assertSame($notes, $this->svc->listNotes(1));
|
|
}
|
|
|
|
public function testGetNoteThrowsNotFoundWhenMissing(): void {
|
|
$this->noteMapper->method('findById')
|
|
->willThrowException(new DoesNotExistException(''));
|
|
|
|
$this->expectException(NotFoundException::class);
|
|
$this->svc->getNote(999);
|
|
}
|
|
|
|
public function testCreateNoteSetsFieldsAndInserts(): void {
|
|
$this->noteMapper->expects($this->once())
|
|
->method('insert')
|
|
->with($this->callback(function (Note $n) {
|
|
return $n->getHouseId() === 1
|
|
&& $n->getTitle() === 'My Note'
|
|
&& $n->getContent() === 'Some content'
|
|
&& $n->getColor() === '#ff0000'
|
|
&& $n->getCreatedBy() === 'alice'
|
|
&& $n->getCreatedAt() > 0;
|
|
}))
|
|
->willReturnArgument(0);
|
|
|
|
$result = $this->svc->createNote(1, 'alice', ' My Note ', 'Some content', '#ff0000');
|
|
$this->assertSame('My Note', $result->getTitle());
|
|
}
|
|
|
|
public function testCreateNoteRejectsEmptyTitle(): void {
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->svc->createNote(1, 'alice', ' ', null, null);
|
|
}
|
|
|
|
public function testCreateNoteRejectsInvalidColor(): void {
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->svc->createNote(1, 'alice', 'Test', null, 'red');
|
|
}
|
|
|
|
public function testCreateNoteAllowsNullColor(): void {
|
|
$this->noteMapper->expects($this->once())
|
|
->method('insert')
|
|
->with($this->callback(fn (Note $n) => $n->getColor() === null))
|
|
->willReturnArgument(0);
|
|
|
|
$this->svc->createNote(1, 'alice', 'Test', null, null);
|
|
}
|
|
|
|
public function testUpdateNotePatchesTitleContentColor(): void {
|
|
$note = $this->makeNote(['id' => 1]);
|
|
$this->noteMapper->method('findById')->willReturn($note);
|
|
$this->noteMapper->expects($this->once())->method('update');
|
|
|
|
$result = $this->svc->updateNote(1, [
|
|
'title' => 'New Title',
|
|
'content' => 'New content',
|
|
'color' => '#00ff00',
|
|
]);
|
|
$this->assertSame('New Title', $result->getTitle());
|
|
$this->assertSame('New content', $result->getContent());
|
|
$this->assertSame('#00ff00', $result->getColor());
|
|
}
|
|
|
|
public function testUpdateNoteRejectsEmptyTitle(): void {
|
|
$note = $this->makeNote(['id' => 1]);
|
|
$this->noteMapper->method('findById')->willReturn($note);
|
|
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->svc->updateNote(1, ['title' => ' ']);
|
|
}
|
|
|
|
public function testUpdateNoteRejectsInvalidColor(): void {
|
|
$note = $this->makeNote(['id' => 1]);
|
|
$this->noteMapper->method('findById')->willReturn($note);
|
|
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->svc->updateNote(1, ['color' => 'nope']);
|
|
}
|
|
|
|
public function testUpdateNoteClearsContentWithEmptyString(): void {
|
|
$note = $this->makeNote(['id' => 1, 'content' => 'Old']);
|
|
$this->noteMapper->method('findById')->willReturn($note);
|
|
$this->noteMapper->expects($this->once())->method('update');
|
|
|
|
$result = $this->svc->updateNote(1, ['content' => '']);
|
|
$this->assertNull($result->getContent());
|
|
}
|
|
|
|
public function testUpdateNoteClearsColorWithEmptyString(): void {
|
|
$note = $this->makeNote(['id' => 1, 'color' => '#ff0000']);
|
|
$this->noteMapper->method('findById')->willReturn($note);
|
|
$this->noteMapper->expects($this->once())->method('update');
|
|
|
|
$result = $this->svc->updateNote(1, ['color' => '']);
|
|
$this->assertNull($result->getColor());
|
|
}
|
|
|
|
public function testUpdateNoteSortOrder(): void {
|
|
$note = $this->makeNote(['id' => 1, 'sortOrder' => 0]);
|
|
$this->noteMapper->method('findById')->willReturn($note);
|
|
$this->noteMapper->expects($this->once())->method('update');
|
|
|
|
$result = $this->svc->updateNote(1, ['sortOrder' => 5]);
|
|
$this->assertSame(5, $result->getSortOrder());
|
|
}
|
|
|
|
public function testDeleteNoteRemovesFromMapper(): void {
|
|
$note = $this->makeNote(['id' => 1]);
|
|
$this->noteMapper->method('findById')->willReturn($note);
|
|
$this->noteMapper->expects($this->once())
|
|
->method('delete')
|
|
->with($note);
|
|
|
|
$this->svc->deleteNote(1);
|
|
}
|
|
|
|
public function testReorderNotesUpdatesMatchingItems(): void {
|
|
$n1 = $this->makeNote(['id' => 1, 'houseId' => 1]);
|
|
$n2 = $this->makeNote(['id' => 2, 'houseId' => 1]);
|
|
$foreign = $this->makeNote(['id' => 3, 'houseId' => 99]);
|
|
|
|
$this->noteMapper->method('findById')->willReturnCallback(function (int $id) use ($n1, $n2, $foreign) {
|
|
return match ($id) {
|
|
1 => $n1,
|
|
2 => $n2,
|
|
3 => $foreign,
|
|
default => throw new DoesNotExistException(''),
|
|
};
|
|
});
|
|
|
|
$this->noteMapper->expects($this->exactly(2))->method('update');
|
|
|
|
$this->svc->reorderNotes(1, [
|
|
['id' => 2, 'sortOrder' => 0],
|
|
['id' => 1, 'sortOrder' => 1],
|
|
['id' => 3, 'sortOrder' => 2], // wrong house
|
|
]);
|
|
|
|
$this->assertSame(1, $n1->getSortOrder());
|
|
$this->assertSame(0, $n2->getSortOrder());
|
|
}
|
|
}
|