зеркало из https://github.com/nextcloud/deck.git
feat: Let occ deck:import default to deck json importer
Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
Родитель
cccc4f2f67
Коммит
e7d5fbff63
|
@ -25,6 +25,7 @@ namespace OCA\Deck\Command;
|
|||
|
||||
use OCA\Deck\Service\Importer\BoardImportCommandService;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
@ -41,7 +42,9 @@ class BoardImport extends Command {
|
|||
*/
|
||||
protected function configure() {
|
||||
$allowedSystems = $this->boardImportCommandService->getAllowedImportSystems();
|
||||
$names = array_column($allowedSystems, 'name');
|
||||
$names = array_map(function ($name) {
|
||||
return '"' . $name . '"';
|
||||
}, array_column($allowedSystems, 'internalName'));
|
||||
$this
|
||||
->setName('deck:import')
|
||||
->setDescription('Import data')
|
||||
|
@ -50,7 +53,7 @@ class BoardImport extends Command {
|
|||
null,
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'Source system for import. Available options: ' . implode(', ', $names) . '.',
|
||||
null
|
||||
'DeckJson',
|
||||
)
|
||||
->addOption(
|
||||
'config',
|
||||
|
@ -66,6 +69,11 @@ class BoardImport extends Command {
|
|||
'Data file to import.',
|
||||
'data.json'
|
||||
)
|
||||
->addArgument(
|
||||
'file',
|
||||
InputArgument::OPTIONAL,
|
||||
'File to import',
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@ class RelationalEntity extends Entity implements \JsonSerializable {
|
|||
|
||||
$attr = lcfirst(substr($methodName, 3));
|
||||
if (array_key_exists($attr, $this->_resolvedProperties) && str_starts_with($methodName, 'set')) {
|
||||
if (!is_scalar($args[0])) {
|
||||
if ($args[0] !== null && !is_scalar($args[0])) {
|
||||
$args[0] = $args[0]['primaryKey'];
|
||||
}
|
||||
parent::setter($attr, $args);
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace OCA\Deck\Service\Importer;
|
|||
|
||||
use OCA\Deck\Exceptions\ConflictException;
|
||||
use OCA\Deck\NotFoundException;
|
||||
use OCA\Deck\Service\Importer\Systems\DeckJsonService;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
@ -76,6 +77,10 @@ class BoardImportCommandService extends BoardImportService {
|
|||
}
|
||||
|
||||
protected function validateConfig(): void {
|
||||
// FIXME: Make config optional for deck plain importer (but use a call on the importer insterad)
|
||||
if ($this->getImportSystem() instanceof DeckJsonService) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$config = $this->getInput()->getOption('config');
|
||||
if (is_string($config)) {
|
||||
|
@ -145,6 +150,18 @@ class BoardImportCommandService extends BoardImportService {
|
|||
if (!$this->getImportSystem()->needValidateData()) {
|
||||
return;
|
||||
}
|
||||
$data = $this->getInput()->getArgument('file');
|
||||
if (is_string($data)) {
|
||||
if (!file_exists($data)) {
|
||||
throw new \OCP\Files\NotFoundException('Could not find file ' . $data);
|
||||
}
|
||||
$data = json_decode(file_get_contents($data));
|
||||
if ($data instanceof \stdClass) {
|
||||
$this->setData($data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$data = $this->getInput()->getOption('data');
|
||||
if (is_string($data)) {
|
||||
$data = json_decode(file_get_contents($data));
|
||||
|
|
|
@ -84,6 +84,8 @@ class BoardImportService {
|
|||
) {
|
||||
$this->board = new Board();
|
||||
$this->disableCommentsEvents();
|
||||
|
||||
$this->config = new \stdClass();
|
||||
}
|
||||
|
||||
private function disableCommentsEvents(): void {
|
||||
|
@ -151,6 +153,11 @@ class BoardImportService {
|
|||
|
||||
public function getAllowedImportSystems(): array {
|
||||
if (!$this->allowedSystems) {
|
||||
$this->addAllowedImportSystem([
|
||||
'name' => DeckJsonService::$name,
|
||||
'class' => DeckJsonService::class,
|
||||
'internalName' => 'DeckJson'
|
||||
]);
|
||||
$this->addAllowedImportSystem([
|
||||
'name' => TrelloApiService::$name,
|
||||
'class' => TrelloApiService::class,
|
||||
|
@ -161,11 +168,6 @@ class BoardImportService {
|
|||
'class' => TrelloJsonService::class,
|
||||
'internalName' => 'TrelloJson'
|
||||
]);
|
||||
$this->addAllowedImportSystem([
|
||||
'name' => DeckJsonService::$name,
|
||||
'class' => DeckJsonService::class,
|
||||
'internalName' => 'DeckJson'
|
||||
]);
|
||||
}
|
||||
$this->eventDispatcher->dispatchTyped(new BoardImportGetAllowedEvent($this));
|
||||
return $this->allowedSystems;
|
||||
|
|
|
@ -31,8 +31,6 @@ use OCA\Deck\Db\Card;
|
|||
use OCA\Deck\Db\Label;
|
||||
use OCA\Deck\Db\Stack;
|
||||
use OCA\Deck\Service\Importer\ABoardImportService;
|
||||
use OCP\IL10N;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
|
||||
|
@ -44,8 +42,6 @@ class DeckJsonService extends ABoardImportService {
|
|||
|
||||
public function __construct(
|
||||
private IUserManager $userManager,
|
||||
private IURLGenerator $urlGenerator,
|
||||
private IL10N $l10n
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -86,6 +82,20 @@ class DeckJsonService extends ABoardImportService {
|
|||
}
|
||||
}
|
||||
|
||||
public function mapMember($uid): ?string {
|
||||
|
||||
$uidCandidate = $this->members[$uid]?->getUID() ?? null;
|
||||
if ($uidCandidate) {
|
||||
return $uidCandidate;
|
||||
}
|
||||
|
||||
if ($this->userManager->userExists($uid)) {
|
||||
return $uid;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getCardAssignments(): array {
|
||||
$assignments = [];
|
||||
foreach ($this->tmpCards as $sourceCard) {
|
||||
|
@ -176,6 +186,7 @@ class DeckJsonService extends ABoardImportService {
|
|||
$card = new Card();
|
||||
$card->setTitle($cardSource->title);
|
||||
$card->setLastModified($cardSource->lastModified);
|
||||
$card->setCreatedAt($cardSource->createdAt);
|
||||
$card->setArchived($cardSource->archived);
|
||||
$card->setDescription($cardSource->description);
|
||||
$card->setStackId($this->stacks[$cardSource->stackId]->getId());
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace OCA\Deck\Db;
|
|||
use OCA\Deck\Command\BoardImport;
|
||||
use OCA\Deck\Service\Importer\BoardImportService;
|
||||
use OCA\Deck\Service\Importer\Systems\DeckJsonService;
|
||||
use OCP\AppFramework\Db\Entity;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IUserManager;
|
||||
|
@ -117,10 +118,98 @@ class ImportExportTest extends \Test\TestCase {
|
|||
|
||||
public function assertDatabase() {
|
||||
$boardMapper = \OCP\Server::get(BoardMapper::class);
|
||||
$stackMapper = \OCP\Server::get(StackMapper::class);
|
||||
$cardMapper = \OCP\Server::get(CardMapper::class);
|
||||
|
||||
$boards = $boardMapper->findAllByOwner('admin');
|
||||
self::assertEquals('My test board', $boards[0]->getTitle());
|
||||
self::assertEquals('Shared board', $boards[1]->getTitle());
|
||||
self::assertEquals(2, count($boards));
|
||||
|
||||
$board = $boards[0];
|
||||
self::assertEntity(Board::fromRow([
|
||||
'title' => 'My test board',
|
||||
'color' => 'e0ed31',
|
||||
'owner' => 'admin',
|
||||
]), $board);
|
||||
|
||||
$stacks = $stackMapper->findAll($board->getId());
|
||||
self::assertCount(3, $stacks);
|
||||
self::assertEntity(Stack::fromRow([
|
||||
'title' => 'A',
|
||||
'order' => 999,
|
||||
'boardId' => $boards[0]->getId(),
|
||||
]), $stacks[0]);
|
||||
self::assertEntity(Stack::fromRow([
|
||||
'title' => 'B',
|
||||
'order' => 999,
|
||||
'boardId' => $boards[0]->getId(),
|
||||
]), $stacks[1]);
|
||||
self::assertEntity(Stack::fromRow([
|
||||
'title' => 'C',
|
||||
'order' => 999,
|
||||
'boardId' => $boards[0]->getId(),
|
||||
]), $stacks[2]);
|
||||
|
||||
$cards = $cardMapper->findAll($stacks[0]->getId());
|
||||
self::assertEntity(Card::fromRow([
|
||||
'title' => '1',
|
||||
'description' => '',
|
||||
'type' => 'plain',
|
||||
'lastModified' => 1689667779,
|
||||
'createdAt' => 1689667569,
|
||||
'owner' => 'admin',
|
||||
'duedate' => new \DateTime('2050-07-24T22:00:00.000000+0000'),
|
||||
'order' => 999,
|
||||
'stackId' => $stacks[0]->getId(),
|
||||
]), $cards[0]);
|
||||
self::assertEntity(Card::fromRow([
|
||||
'title' => '2',
|
||||
'duedate' => new \DateTime('2050-07-24T22:00:00.000000+0000'),
|
||||
]), $cards[1], true);
|
||||
self::assertEntity(Card::fromParams([
|
||||
'title' => '3',
|
||||
'duedate' => null,
|
||||
]), $cards[2], true);
|
||||
|
||||
$cards = $cardMapper->findAll($stacks[1]->getId());
|
||||
self::assertEntity(Card::fromParams([
|
||||
'title' => '6',
|
||||
'duedate' => null,
|
||||
'description' => "# Test description\n\nHello world",
|
||||
]), $cards[2], true);
|
||||
|
||||
// Shared board
|
||||
$sharedBoard = $boards[1];
|
||||
self::assertEntity(Board::fromRow([
|
||||
'title' => 'Shared board',
|
||||
'color' => '30b6d8',
|
||||
'owner' => 'admin',
|
||||
]), $sharedBoard);
|
||||
|
||||
$stacks = $stackMapper->findAll($sharedBoard->getId());
|
||||
self::assertCount(3, $stacks);
|
||||
}
|
||||
|
||||
public static function assertEntity(Entity $expected, Entity $actual, bool $checkProperties = false) {
|
||||
if ($checkProperties === true) {
|
||||
$e = clone $expected;
|
||||
$a = clone $actual;
|
||||
foreach ($e->getUpdatedFields() as $property => $updated) {
|
||||
$expectedValue = call_user_func([$e, 'get' . ucfirst($property)]);
|
||||
$actualValue = call_user_func([$a, 'get' . ucfirst($property)]);
|
||||
self::assertEquals(
|
||||
$expectedValue,
|
||||
$actualValue
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$e = clone $expected;
|
||||
$e->setId(null);
|
||||
$a = clone $actual;
|
||||
$a->setId(null);
|
||||
$e->resetUpdatedFields();
|
||||
$a->resetUpdatedFields();
|
||||
self::assertEquals($e, $a);
|
||||
}
|
||||
}
|
||||
|
||||
public function tearDown(): void {
|
||||
|
|
|
@ -118,6 +118,9 @@ class BoardImportServiceTest extends \Test\TestCase {
|
|||
$this->trelloJsonService
|
||||
->method('getJsonSchemaPath')
|
||||
->willReturn($configFile);
|
||||
$this->trelloJsonService
|
||||
->method('getBoards')
|
||||
->willReturn([$data]);
|
||||
$this->boardImportService->setImportSystem($this->trelloJsonService);
|
||||
|
||||
$owner = $this->createMock(IUser::class);
|
||||
|
@ -192,8 +195,7 @@ class BoardImportServiceTest extends \Test\TestCase {
|
|||
->expects($this->once())
|
||||
->method('insert');
|
||||
|
||||
$actual = $this->boardImportService->import();
|
||||
|
||||
$this->assertNull($actual);
|
||||
$this->boardImportService->import();
|
||||
self::assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче