Add new command

Clean code
Add new command
Import last modified and deleted date
Replace arrow functions by lambda functions
Add properties to class
Add dependency to composer.json
Signed-off-by: Vitor Mattos <vitor@php.rio>
Turn private methods
Add output messages and associate users to cards

Signed-off-by: Vitor Mattos <vitor@php.rio>
This commit is contained in:
Vitor Mattos
2021-07-09 23:35:56 -03:00
committed by Julius Härtl
parent 89028c74cb
commit 48df98ce67
13 changed files with 1513 additions and 355 deletions

View File

@@ -0,0 +1,77 @@
<?php
/**
* @copyright Copyright (c) 2021 Vitor Mattos <vitor@php.rio>
*
* @author Vitor Mattos <vitor@php.rio>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Deck\Command;
use OCA\Deck\Command\Helper\TrelloHelper;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class BoardImportTest extends \Test\TestCase {
/** @var TrelloHelper */
private $trelloHelper;
/** @var BoardImport */
private $boardImport;
public function setUp(): void {
parent::setUp();
$this->trelloHelper = $this->createMock(TrelloHelper::class);
$this->boardImport = new BoardImport(
$this->trelloHelper
);
$questionHelper = new QuestionHelper();
$this->boardImport->setHelperSet(
new HelperSet([
$questionHelper
])
);
}
public function testExecuteWithSuccess() {
$input = $this->createMock(InputInterface::class);
$input->method('getOption')
->withConsecutive(
[$this->equalTo('system')],
[$this->equalTo('setting')],
[$this->equalTo('data')]
)
->will($this->returnValueMap([
['system', 'trello'],
['setting', __DIR__ . '/fixtures/setting-trello.json'],
['data', __DIR__ . '/fixtures/data-trello.json']
]));
$output = $this->createMock(OutputInterface::class);
$output
->expects($this->once())
->method('writeLn')
->with('Done!');
$this->invokePrivate($this->boardImport, 'interact', [$input, $output]);
$actual = $this->invokePrivate($this->boardImport, 'execute', [$input, $output]);
$this->assertEquals(0, $actual);
}
}

View File

@@ -0,0 +1,134 @@
<?php
/**
* @copyright Copyright (c) 2021 Vitor Mattos <vitor@php.rio>
*
* @author Vitor Mattos <vitor@php.rio>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Deck\Command;
use OCA\Deck\Command\Helper\TrelloHelper;
use OCA\Deck\Db\AclMapper;
use OCA\Deck\Db\AssignmentMapper;
use OCA\Deck\Db\CardMapper;
use OCA\Deck\Db\StackMapper;
use OCA\Deck\Service\BoardService;
use OCA\Deck\Service\LabelService;
use OCP\IDBConnection;
use OCP\IUserManager;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class TrelloHelperTest extends \Test\TestCase {
/** @var BoardService */
private $boardService;
/** @var LabelService */
private $labelService;
/** @var StackMapper */
private $stackMapper;
/** @var CardMapper */
private $cardMapper;
/** @var IDBConnection */
private $connection;
/** @var IUserManager */
private $userManager;
/** @var TrelloHelper */
private $trelloHelper;
public function setUp(): void {
parent::setUp();
$this->boardService = $this->createMock(BoardService::class);
$this->labelService = $this->createMock(LabelService::class);
$this->stackMapper = $this->createMock(StackMapper::class);
$this->cardMapper = $this->createMock(CardMapper::class);
$this->assignmentMapper = $this->createMock(AssignmentMapper::class);
$this->aclMapper = $this->createMock(AclMapper::class);
$this->connection = $this->createMock(IDBConnection::class);
$this->userManager = $this->createMock(IUserManager::class);
$this->trelloHelper = new TrelloHelper(
$this->boardService,
$this->labelService,
$this->stackMapper,
$this->cardMapper,
$this->assignmentMapper,
$this->aclMapper,
$this->connection,
$this->userManager
);
$questionHelper = new QuestionHelper();
$command = new BoardImport($this->trelloHelper);
$command->setHelperSet(
new HelperSet([
$questionHelper
])
);
$this->trelloHelper->setCommand($command);
}
public function testImportWithSuccess() {
$input = $this->createMock(InputInterface::class);
$input->method('getOption')
->withConsecutive(
[$this->equalTo('data')],
[$this->equalTo('setting')]
)
->will($this->returnValueMap([
['data', __DIR__ . '/../fixtures/data-trello.json'],
['setting', __DIR__ . '/../fixtures/setting-trello.json']
]));
$output = $this->createMock(OutputInterface::class);
$user = $this->createMock(\OCP\IUser::class);
$user
->method('getUID')
->willReturn('admin');
$this->userManager
->method('get')
->willReturn($user);
$this->userManager
->method('get')
->willReturn($user);
$board = $this->createMock(\OCA\Deck\Db\Board::class);
$this->boardService
->expects($this->once())
->method('create')
->willReturn($board);
$label = $this->createMock(\OCA\Deck\Db\Label::class);
$this->labelService
->expects($this->once())
->method('create')
->willReturn($label);
$stack = $this->createMock(\OCA\Deck\Db\Stack::class);
$this->stackMapper
->expects($this->once())
->method('insert')
->willReturn($stack);
$card = $this->createMock(\OCA\Deck\Db\Card::class);
$this->cardMapper
->expects($this->once())
->method('insert')
->willReturn($card);
$this->trelloHelper->validate($input, $output);
$actual = $this->trelloHelper->import($input, $output);
$this->assertNull($actual);
}
}

View File

@@ -0,0 +1,582 @@
{
"id": "fakeboardidhash",
"name": "Test Board Name",
"desc": "",
"descData": null,
"closed": false,
"dateClosed": null,
"idOrganization": null,
"shortLink": "qwerty",
"powerUps": [],
"dateLastActivity": "2021-07-10T17:01:58.633Z",
"idTags": [],
"datePluginDisable": null,
"creationMethod": null,
"idBoardSource": null,
"idMemberCreator": "fakeidmemberhash",
"idEnterprise": null,
"pinned": false,
"starred": false,
"url": "https://trello.com/b/qwerty/fakeboardurl",
"prefs": {
"permissionLevel": "private",
"hideVotes": false,
"voting": "disabled",
"comments": "members",
"invitations": "members",
"selfJoin": false,
"cardCovers": true,
"isTemplate": false,
"cardAging": "regular",
"calendarFeedEnabled": false,
"background": "blue",
"backgroundImage": null,
"backgroundImageScaled": null,
"backgroundTile": false,
"backgroundBrightness": "dark",
"backgroundColor": "#0079BF",
"backgroundBottomColor": "#0079BF",
"backgroundTopColor": "#0079BF",
"canBePublic": true,
"canBeEnterprise": true,
"canBeOrg": true,
"canBePrivate": true,
"canInvite": true
},
"shortUrl": "https://trello.com/b/qwerty",
"premiumFeatures": [],
"enterpriseOwned": false,
"ixUpdate": "67",
"limits": {
"attachments": {
"perBoard": {
"status": "ok",
"disableAt": 36000,
"warnAt": 32400
},
"perCard": {
"status": "ok",
"disableAt": 1000,
"warnAt": 900
}
},
"boards": {
"totalMembersPerBoard": {
"status": "ok",
"disableAt": 1600,
"warnAt": 1440
}
},
"cards": {
"openPerBoard": {
"status": "ok",
"disableAt": 5000,
"warnAt": 4500
},
"openPerList": {
"status": "ok",
"disableAt": 5000,
"warnAt": 4500
},
"totalPerBoard": {
"status": "ok",
"disableAt": 2000000,
"warnAt": 1800000
},
"totalPerList": {
"status": "ok",
"disableAt": 1000000,
"warnAt": 900000
}
},
"checklists": {
"perBoard": {
"status": "ok",
"disableAt": 2000000,
"warnAt": 1800000
},
"perCard": {
"status": "ok",
"disableAt": 500,
"warnAt": 450
}
},
"checkItems": {
"perChecklist": {
"status": "ok",
"disableAt": 200,
"warnAt": 180
}
},
"customFields": {
"perBoard": {
"status": "ok",
"disableAt": 50,
"warnAt": 45
}
},
"customFieldOptions": {
"perField": {
"status": "ok",
"disableAt": 50,
"warnAt": 45
}
},
"labels": {
"perBoard": {
"status": "ok",
"disableAt": 1000,
"warnAt": 900
}
},
"lists": {
"openPerBoard": {
"status": "ok",
"disableAt": 500,
"warnAt": 450
},
"totalPerBoard": {
"status": "ok",
"disableAt": 3000,
"warnAt": 2700
}
},
"stickers": {
"perCard": {
"status": "ok",
"disableAt": 70,
"warnAt": 63
}
},
"reactions": {
"perAction": {
"status": "ok",
"disableAt": 1000,
"warnAt": 900
},
"uniquePerAction": {
"status": "ok",
"disableAt": 17,
"warnAt": 16
}
}
},
"subscribed": false,
"templateGallery": null,
"dateLastView": "2021-07-10T17:01:58.665Z",
"labelNames": {
"green": "",
"yellow": "",
"orange": "",
"red": "",
"purple": "",
"blue": "",
"sky": "",
"lime": "",
"pink": "",
"black": ""
},
"actions": [
{
"id": "60e9d2869efe2e1141be2798",
"idMemberCreator": "fakeidmemberhash",
"data": {
"idMember": "fakeidmemberhash",
"deactivated": false,
"card": {
"id": "hashcard7",
"name": "Name Card 7",
"idShort": 7,
"shortLink": "fakeshortlinkcard7"
},
"board": {
"id": "fakeboardidhash",
"name": "Test Board Name",
"shortLink": "qwerty"
},
"member": {
"id": "fakeidmemberhash",
"name": "John Doe"
}
},
"type": "removeMemberFromCard",
"date": "2021-07-10T17:01:58.636Z",
"appCreator": null,
"limits": {},
"member": {
"id": "fakeidmemberhash",
"username": "johndoe",
"activityBlocked": false,
"avatarHash": "fakeavatarhash",
"avatarUrl": "https://trello-members.s3.amazonaws.com/fakeidmemberhash/fakeavatarhash",
"fullName": "John Doe",
"idMemberReferrer": null,
"initials": "JD",
"nonPublic": {
"fullName": "John Doe",
"initials": "JD",
"avatarUrl": "https://trello-members.s3.amazonaws.com/fakeidmemberhash/fakeavatarhash",
"avatarHash": "fakeavatarhash"
},
"nonPublicAvailable": true
},
"memberCreator": {
"id": "fakeidmemberhash",
"username": "johndoe",
"activityBlocked": false,
"avatarHash": "fakeavatarhash",
"avatarUrl": "https://trello-members.s3.amazonaws.com/fakeidmemberhash/fakeavatarhash",
"fullName": "John Doe",
"idMemberReferrer": null,
"initials": "JD",
"nonPublic": {
"fullName": "John Doe",
"initials": "JD",
"avatarUrl": "https://trello-members.s3.amazonaws.com/fakeidmemberhash/fakeavatarhash",
"avatarHash": "fakeavatarhash"
},
"nonPublicAvailable": true
}
},
{
"id": "60e9d1832ff82d10c0cea6ba",
"idMemberCreator": "fakeidmemberhash",
"data": {
"idMember": "fakeidmemberhash",
"card": {
"id": "hashcard7",
"name": "Name Card 7",
"idShort": 7,
"shortLink": "fakeshortlinkcard7"
},
"board": {
"id": "fakeboardidhash",
"name": "Test Board Name",
"shortLink": "qwerty"
},
"member": {
"id": "fakeidmemberhash",
"name": "John Doe"
}
},
"type": "addMemberToCard",
"date": "2021-07-10T16:57:39.999Z",
"appCreator": null,
"limits": {},
"member": {
"id": "fakeidmemberhash",
"username": "johndoe",
"activityBlocked": false,
"avatarHash": "fakeavatarhash",
"avatarUrl": "https://trello-members.s3.amazonaws.com/fakeidmemberhash/fakeavatarhash",
"fullName": "John Doe",
"idMemberReferrer": null,
"initials": "JD",
"nonPublic": {
"fullName": "John Doe",
"initials": "JD",
"avatarUrl": "https://trello-members.s3.amazonaws.com/fakeidmemberhash/fakeavatarhash",
"avatarHash": "fakeavatarhash"
},
"nonPublicAvailable": true
},
"memberCreator": {
"id": "fakeidmemberhash",
"username": "johndoe",
"activityBlocked": false,
"avatarHash": "fakeavatarhash",
"avatarUrl": "https://trello-members.s3.amazonaws.com/fakeidmemberhash/fakeavatarhash",
"fullName": "John Doe",
"idMemberReferrer": null,
"initials": "JD",
"nonPublic": {
"fullName": "John Doe",
"initials": "JD",
"avatarUrl": "https://trello-members.s3.amazonaws.com/fakeidmemberhash/fakeavatarhash",
"avatarHash": "fakeavatarhash"
},
"nonPublicAvailable": true
}
},
{
"id": "59bbfc4bf36aa0270d6bfd43",
"idMemberCreator": "fakeidmemberhash",
"data": {
"board": {
"shortLink": "qwerty",
"name": "Test Board Name",
"id": "fakeboardidhash"
},
"list": {
"name": "TODO",
"id": "hashlisttodo"
},
"card": {
"shortLink": "fakeshortlinkcard7",
"idShort": 7,
"name": "Name Card 7",
"id": "hashcard7"
}
},
"type": "createCard",
"date": "2017-09-15T16:14:03.187Z",
"appCreator": null,
"limits": {},
"memberCreator": {
"id": "fakeidmemberhash",
"username": "johndoe",
"activityBlocked": false,
"avatarHash": "fakeavatarhash",
"avatarUrl": "https://trello-members.s3.amazonaws.com/fakeidmemberhash/fakeavatarhash",
"fullName": "John Doe",
"idMemberReferrer": null,
"initials": "JD",
"nonPublic": {
"fullName": "John Doe",
"initials": "JD",
"avatarUrl": "https://trello-members.s3.amazonaws.com/fakeidmemberhash/fakeavatarhash",
"avatarHash": "fakeavatarhash"
},
"nonPublicAvailable": true
}
},
{
"id": "59bbfb8e4a6f8ca35be9b82a",
"idMemberCreator": "fakeidmemberhash",
"data": {
"board": {
"shortLink": "qwerty",
"name": "Test Board Name",
"id": "fakeboardidhash"
},
"list": {
"name": "TODO",
"id": "hashlisttodo"
}
},
"type": "createList",
"date": "2017-09-15T16:10:54.714Z",
"appCreator": null,
"limits": {},
"memberCreator": {
"id": "fakeidmemberhash",
"username": "johndoe",
"activityBlocked": false,
"avatarHash": "fakeavatarhash",
"avatarUrl": "https://trello-members.s3.amazonaws.com/fakeidmemberhash/fakeavatarhash",
"fullName": "John Doe",
"idMemberReferrer": null,
"initials": "JD",
"nonPublic": {
"fullName": "John Doe",
"initials": "JD",
"avatarUrl": "https://trello-members.s3.amazonaws.com/fakeidmemberhash/fakeavatarhash",
"avatarHash": "fakeavatarhash"
},
"nonPublicAvailable": true
}
},
{
"id": "59bbfb88973b76e586edec5e",
"idMemberCreator": "fakeidmemberhash",
"data": {
"board": {
"shortLink": "qwerty",
"name": "Test Board Name",
"id": "fakeboardidhash"
}
},
"type": "createBoard",
"date": "2017-09-15T16:10:48.069Z",
"appCreator": null,
"limits": {},
"memberCreator": {
"id": "fakeidmemberhash",
"username": "johndoe",
"activityBlocked": false,
"avatarHash": "fakeavatarhash",
"avatarUrl": "https://trello-members.s3.amazonaws.com/fakeidmemberhash/fakeavatarhash",
"fullName": "John Doe",
"idMemberReferrer": null,
"initials": "JD",
"nonPublic": {
"fullName": "John Doe",
"initials": "JD",
"avatarUrl": "https://trello-members.s3.amazonaws.com/fakeidmemberhash/fakeavatarhash",
"avatarHash": "fakeavatarhash"
},
"nonPublicAvailable": true
}
}
],
"cards": [
{
"id": "hashcard7",
"address": null,
"checkItemStates": null,
"closed": false,
"coordinates": null,
"creationMethod": null,
"dateLastActivity": "2021-07-10T17:01:58.633Z",
"desc": "",
"descData": null,
"dueReminder": null,
"idBoard": "fakeboardidhash",
"idLabels": [],
"idList": "hashlisttodo",
"idMembersVoted": [],
"idShort": 7,
"idAttachmentCover": null,
"locationName": null,
"manualCoverAttachment": false,
"name": "Name Card 7",
"pos": 65535,
"shortLink": "fakeshortlinkcard7",
"isTemplate": false,
"cardRole": null,
"badges": {
"attachmentsByType": {
"trello": {
"board": 0,
"card": 0
}
},
"location": false,
"votes": 0,
"viewingMemberVoted": false,
"subscribed": false,
"fogbugz": "",
"checkItems": 0,
"checkItemsChecked": 0,
"checkItemsEarliestDue": null,
"comments": 0,
"attachments": 0,
"description": false,
"due": null,
"dueComplete": false,
"start": null
},
"dueComplete": false,
"due": null,
"email": "johndoe+card7@boards.trello.com",
"idChecklists": [],
"idMembers": [],
"labels": [],
"limits": {
"attachments": {
"perCard": {
"status": "ok",
"disableAt": 1000,
"warnAt": 900
}
},
"checklists": {
"perCard": {
"status": "ok",
"disableAt": 500,
"warnAt": 450
}
},
"stickers": {
"perCard": {
"status": "ok",
"disableAt": 70,
"warnAt": 63
}
}
},
"shortUrl": "https://trello.com/c/fakeshortlinkcard7",
"start": null,
"subscribed": false,
"url": "https://trello.com/c/fakeshortlinkcard7/7-name-card-7",
"cover": {
"idAttachment": null,
"color": null,
"idUploadedBackground": null,
"size": "normal",
"brightness": "dark",
"idPlugin": null
},
"attachments": [],
"pluginData": [],
"customFieldItems": []
}
],
"labels": [
{
"id": "59bbfb881314a339999eb855",
"idBoard": "fakeboardidhash",
"name": "",
"color": "yellow"
}
],
"lists": [
{
"id": "hashlisttodo",
"name": "TODO",
"closed": false,
"pos": 65535,
"softLimit": null,
"creationMethod": null,
"idBoard": "fakeboardidhash",
"limits": {
"cards": {
"openPerList": {
"status": "ok",
"disableAt": 5000,
"warnAt": 4500
},
"totalPerList": {
"status": "ok",
"disableAt": 1000000,
"warnAt": 900000
}
}
},
"subscribed": false
}
],
"members": [
{
"id": "fakeidmemberhash",
"bio": "",
"bioData": {
"emoji": {}
},
"confirmed": true,
"memberType": "normal",
"username": "johndoe",
"activityBlocked": false,
"avatarHash": "fakeavatarhash",
"avatarUrl": "https://trello-members.s3.amazonaws.com/fakeidmemberhash/fakeavatarhash",
"fullName": "John Doe",
"idEnterprise": null,
"idEnterprisesDeactivated": [],
"idMemberReferrer": null,
"idPremOrgsAdmin": [],
"initials": "JD",
"nonPublic": {
"fullName": "John Doe",
"initials": "JD",
"avatarUrl": "https://trello-members.s3.amazonaws.com/fakeidmemberhash/fakeavatarhash",
"avatarHash": "fakeavatarhash"
},
"nonPublicAvailable": true,
"products": [],
"url": "https://trello.com/johndoe",
"status": "disconnected"
}
],
"checklists": [],
"customFields": [],
"memberships": [
{
"id": "59bbfb88973b76e586edec5d",
"idMember": "fakeidmemberhash",
"memberType": "admin",
"unconfirmed": false,
"deactivated": false
}
],
"pluginData": []
}

View File

@@ -0,0 +1,7 @@
{
"owner": "admin",
"color": "0800fd",
"uidRelation": {
"johndoe": "admin"
}
}