feat: Initial commit
This commit is contained in:
parent
b3175cb4b8
commit
1281ebff03
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
vendor/
|
||||
main.uml
|
||||
composer.lock
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "baikal-storage-plugin",
|
||||
"description": "ABaikal plugin to sync iCal objects into storages such as taskwarrior and todist",
|
||||
"name": "aerex/baikal-storage-plugin",
|
||||
"description": "A Baikal plugin to sync iCal objects into storages such as taskwarrior and todist",
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"task",
|
||||
@ -23,10 +23,12 @@
|
||||
"nesbot/carbon": "^2.0.0",
|
||||
"laminas/laminas-validator": "^2.13",
|
||||
"laminas/laminas-stdlib": "^3.2",
|
||||
"psr/container": "^1.0"
|
||||
"psr/container": "^1.0",
|
||||
"symfony/config": "^5.0",
|
||||
"symfony/process": "^3.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "> 4.8, <=6.0.0"
|
||||
"phpunit/phpunit": "^7.4"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
@ -36,7 +38,9 @@
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Aerex\\Taskwarrior\\": "src/taskwarrior"
|
||||
"Aerex\\BaikalStorage\\Storages\\": "lib/Storages/",
|
||||
"Aerex\\BaikalStorage\\Configs\\": "lib/Configs/",
|
||||
"Aerex\\BaikalStorage\\": "lib/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
12
lib/AbstractConsole.php
Normal file
12
lib/AbstractConsole.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Aerex\BaikalStorage;
|
||||
|
||||
abstract class AbstractConsole {
|
||||
|
||||
function __construct($defaultArgs) {
|
||||
$this->defaultArgs = $defaultArgs;
|
||||
}
|
||||
|
||||
abstract protected function execute($cmd, $args, $input = null);
|
||||
}
|
47
lib/Configs/ConfigBuilder.php
Normal file
47
lib/Configs/ConfigBuilder.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Aerex\BaikalStorage\Configs;
|
||||
|
||||
use Symfony\Component\Config\Definition\ConfigurationInterface;
|
||||
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
|
||||
use Symfony\Component\Config\Definition\Processor;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
class ConfigBuilder implements ConfigurationInterface {
|
||||
private $configs = [];
|
||||
private $configFile;
|
||||
|
||||
public function __construct($configFile = '~/.config/baikal') {
|
||||
$this->configFile = $configFile;
|
||||
$this->processor = new Processor();
|
||||
}
|
||||
|
||||
public function add($config) {
|
||||
$this->configs[] = $config;
|
||||
}
|
||||
|
||||
public function getConfigTreeBuilder() {
|
||||
$treeBuilder = new TreeBuilder('configs');
|
||||
$rootNode = $treeBuilder->getRootNode();
|
||||
$ref = $rootNode->children();
|
||||
foreach ($this->configs as $config) {
|
||||
$ref = $ref->append($config->get());
|
||||
}
|
||||
$ref->end();
|
||||
return $treeBuilder;
|
||||
}
|
||||
|
||||
public function readContent() {
|
||||
if (!is_dir($this->configFile)) {
|
||||
mkdir($this->configFile);
|
||||
}
|
||||
$contents = sprintf('%s/storage.yml', $this->configFile);
|
||||
return file_get_contents($contents);
|
||||
}
|
||||
|
||||
public function loadYaml() {
|
||||
$contents = $this->readContent();
|
||||
$parseContents = Yaml::parse($contents);
|
||||
return $this->processor->processConfiguration($this, [$parseContents]);
|
||||
}
|
||||
}
|
17
lib/Configs/TaskwarriorConfig.php
Normal file
17
lib/Configs/TaskwarriorConfig.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Aerex\BaikalStorage\Configs;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
|
||||
|
||||
class TaskwarriorConfig {
|
||||
public function get() {
|
||||
$treeBuilder = new TreeBuilder('taskwarrior');
|
||||
$node = $treeBuilder->getRootNode();
|
||||
$node->children()
|
||||
->scalarNode('data_dir')
|
||||
->defaultValue('~/.task')
|
||||
->end();
|
||||
return $node;
|
||||
}
|
||||
}
|
21
lib/Configs/Todotxt.php
Normal file
21
lib/Configs/Todotxt.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Aerex\BaikalStorage\Configs;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
|
||||
|
||||
class Config extends AbstractConfig {
|
||||
protected function getConfigTree() {
|
||||
$treeBuilder = new TreeBuilder('config');
|
||||
$rootNode = $treeBuilder->getRootNode();
|
||||
|
||||
$rootNode->children
|
||||
->scalarNode('storage')
|
||||
->isRequired()
|
||||
->ifNotInArray(['todotxt'])
|
||||
->thenInvalid('Invalid storage %s')
|
||||
->end();
|
||||
return $treeBuilder;
|
||||
}
|
||||
}
|
||||
|
39
lib/Console.php
Normal file
39
lib/Console.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Aerex\BaikalStorage;
|
||||
|
||||
use Symfony\Component\Process\Process;
|
||||
use Symfony\Component\Process\Exception\ProcessFailedException as ProcessFailedException;
|
||||
|
||||
class Console extends AbstractConsole {
|
||||
private $defaultArgs = [];
|
||||
|
||||
function __construct($defaultArgs) {
|
||||
$this->defaultArgs = $defaultArgs;
|
||||
}
|
||||
|
||||
private function convertToString($input) {
|
||||
if (is_array($input)) {
|
||||
return json_encode($input);
|
||||
}
|
||||
}
|
||||
|
||||
public function execute($cmd, $args, $input = null) {
|
||||
$stdin[] = $cmd;
|
||||
$stdin[] = array_merge($stdin, $this->defaultArgs, $args);
|
||||
|
||||
if (isset($input)) {
|
||||
$stdin[] = $this->convertToString($input);
|
||||
$process = new Process($stdin);
|
||||
}
|
||||
|
||||
try {
|
||||
$process->mustRun();
|
||||
return $process->getOutput();
|
||||
} catch (ProcessFailedException $error) {
|
||||
echo $error->getMessage();
|
||||
throw $error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
156
lib/Plugin.php
Normal file
156
lib/Plugin.php
Normal file
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
namespace Aerex\BaikalStorage;
|
||||
|
||||
use Aerex\BaikalStorage\Storages\Taskwarrior;
|
||||
use Aerex\BaikalStorage\Configs\ConfigBuilder;
|
||||
use Aerex\BaikalStorage\Configs\TaskwarriorConfig;
|
||||
use Sabre\DAV\Exception\BadRequest;
|
||||
use Sabre\HTTP\RequestInterface;
|
||||
use Sabre\HTTP\ResponseInterface;
|
||||
use Sabre\DAV\ServerPlugin;
|
||||
use Sabre\DAV\Server;
|
||||
|
||||
/**
|
||||
* The plugin to interact with Baikal and external storages
|
||||
*
|
||||
*/
|
||||
class Plugin extends ServerPlugin {
|
||||
|
||||
/**
|
||||
* Reference to server object.
|
||||
*
|
||||
* @var Server
|
||||
*/
|
||||
protected $server;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @var StorageManager
|
||||
*/
|
||||
protected $storageManager;
|
||||
|
||||
/**
|
||||
* @var ConfigBuilder
|
||||
*/
|
||||
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Creates the Taskwarrior plugin
|
||||
*
|
||||
* @param CalendarProcessor $TWCalManager
|
||||
*
|
||||
*/
|
||||
function __construct($config = null){
|
||||
if (isset($config)) {
|
||||
$this->config = $config;
|
||||
} else {
|
||||
$this->config = new ConfigBuilder();
|
||||
}
|
||||
$this->storageManager = new StorageManager($this->config);
|
||||
$this->addStorages();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure available storages in storage manager
|
||||
*
|
||||
*/
|
||||
|
||||
public function addStorages() {
|
||||
$taskwarrior = new Taskwarrior(new Console(['rc.verbose=nothing', 'rc.hooks=off']), new TaskwarriorConfig());
|
||||
$this->storageManager->addStorage(Taskwarrior::NAME, $taskwarrior);
|
||||
$this->storageManager->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the plugin
|
||||
*
|
||||
* @param Server $server
|
||||
* @return void */
|
||||
function initialize(Server $server) {
|
||||
$this->server = $server;
|
||||
$server->on('beforeMethod:*', [$this, 'beforeMethod'], 15);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a plugin name.
|
||||
*
|
||||
* Using this name other plugins will be able to access other plugins
|
||||
* using DAV\Server::getPlugin
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getPluginName() {
|
||||
|
||||
return 'taskwarrior';
|
||||
|
||||
}
|
||||
/**
|
||||
* This method is called before any HTTP method handler.
|
||||
*
|
||||
* This method intercepts any GET, DELETE, PUT and PROPFIND calls to
|
||||
* filenames that are known to match the 'temporary file' regex.
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function beforeMethod(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
|
||||
switch ($request->getMethod()) {
|
||||
case 'PUT':
|
||||
$this->httpPut($request, $response);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This method handles the PUT method.
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function httpPut(RequestInterface $request){
|
||||
$body = $request->getBodyAsString();
|
||||
$vCal = \Sabre\VObject\Reader::read($body);
|
||||
try {
|
||||
$this->storageManager->import($vCal);
|
||||
} catch(BadRequest $e){
|
||||
throw new BadRequest($e->getMessage(), null, $e);
|
||||
} catch(\Exception $e){
|
||||
throw new \Exception($e->getMessage(), null, $e);
|
||||
}
|
||||
|
||||
$request->setBody($body);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a bunch of meta-data about the plugin.
|
||||
*
|
||||
* Providing this information is optional, and is mainly displayed by the
|
||||
* Browser plugin.
|
||||
*
|
||||
* The description key in the returned array may contain html and will not
|
||||
* be sanitized.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getPluginInfo() {
|
||||
|
||||
return [
|
||||
'name' => $this->getPluginName(),
|
||||
'description' => 'The plugin provides synchronization between taskwarrior tasks and iCAL events',
|
||||
'link' => null,
|
||||
];
|
||||
|
||||
}
|
||||
}
|
57
lib/StorageManager.php
Normal file
57
lib/StorageManager.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Aerex\BaikalStorage;
|
||||
|
||||
use Sabre\VObject\Component\VCalendar as Calendar;
|
||||
use Aerex\BaikalStorage\Configs\ConfigBuilder;
|
||||
|
||||
class StorageManager {
|
||||
|
||||
/**
|
||||
* @var Storage[]
|
||||
*/
|
||||
|
||||
private $storages = [];
|
||||
|
||||
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
private $configBuilder;
|
||||
private $configs;
|
||||
|
||||
public function __construct($configBuilder){
|
||||
$this->configBuilder = $configBuilder;
|
||||
}
|
||||
|
||||
public function getStorages() {
|
||||
return $this->storages;
|
||||
}
|
||||
|
||||
public function getConfigs() {
|
||||
return $this->configs;
|
||||
}
|
||||
|
||||
public function addStorage($name, $storage) {
|
||||
$this->configBuilder->add($storage->getConfig());
|
||||
$this->storages[$name] = $storage;
|
||||
}
|
||||
|
||||
public function init() {
|
||||
$this->configs = $this->configBuilder->loadYaml();
|
||||
}
|
||||
|
||||
public function import(Calendar $calendar) {
|
||||
if (!isset($this->configs)) {
|
||||
throw new \Exception('StorageManger was not initialize or configs are not defined');
|
||||
}
|
||||
foreach ($this->configs as $key => $value) {
|
||||
$storage = $this->storages[$key];
|
||||
if (!isset($storage)){
|
||||
throw new \Exception();
|
||||
}
|
||||
$storage->setRawConfigs($this->configs[$key]);
|
||||
$storage->save($calendar);
|
||||
}
|
||||
}
|
||||
}
|
12
lib/Storages/IStorage.php
Normal file
12
lib/Storages/IStorage.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Aerex\BaikalStorage\Storages;
|
||||
|
||||
use Sabre\VObject\Component\VCalendar as Calendar;
|
||||
|
||||
interface IStorage {
|
||||
public function save(Calendar $c);
|
||||
public function refresh();
|
||||
public function getConfig();
|
||||
public function setRawConfigs();
|
||||
}
|
89
lib/Storages/Taskwarrior.php
Normal file
89
lib/Storages/Taskwarrior.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace Aerex\BaikalStorage\Storages;
|
||||
|
||||
use Sabre\VObject\Component\VCalendar as Calendar;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class Taskwarrior implements IStorage {
|
||||
|
||||
private const DATA_FILES = ['pending.data', 'completed.data', 'undo.data'];
|
||||
private $rawConfigs;
|
||||
public const NAME = 'taskwarrior';
|
||||
private $tasks = [];
|
||||
public function __construct($console, $config) {
|
||||
$this->console = $console;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function getConfig() {
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
public function setRawConfigs($rawConfigs) {
|
||||
$this->rawConfigs = $rawConfigs;
|
||||
}
|
||||
|
||||
public function refresh() {
|
||||
$dataDir = $this->rawConfigs['data_dir'];
|
||||
$fp = fopen(sprintf('%s/taskwarrior-baikal-storage.lock', $dataDir), 'a');
|
||||
|
||||
if (!$fp || !flock($fp, LOCK_EX | LOCK_NB, $eWouldBlock) || $eWouldBlock) {
|
||||
fputs(STDERR, 'Could not get lock');
|
||||
}
|
||||
|
||||
$mtime = 0;
|
||||
$tasksUpdated = false;
|
||||
foreach (Taskwarrior::DATA_FILES as $dataFile) {
|
||||
$fmtime = filemtime(sprintf('%s/%s', $this->config['data_dir'], $dataFile));
|
||||
if ($fmtime > $mtime) {
|
||||
$mtime = $fmtime;
|
||||
$tasksUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($tasksUpdated) {
|
||||
$tasks = $this->console->execute('task', ['export']);
|
||||
foreach ($tasks as $task) {
|
||||
$this->tasks[$task['uuid']] = $task;
|
||||
}
|
||||
}
|
||||
fclose($fp);
|
||||
unlink(sprintf('%s/taskwarrior-baikal-storage.lock', $dataDir));
|
||||
}
|
||||
|
||||
public function vObjectToTask($vtodo) {
|
||||
if ($this->tasks['uid'] == $vtodo->UID) {
|
||||
$task = $this->tasks['uid'];
|
||||
} else {
|
||||
$task = [];
|
||||
$task['uid'] = $vtodo->UID;
|
||||
}
|
||||
|
||||
|
||||
if (!isset($vtodo->DESCRIPTION) && isset($vtodo->SUMMARY)){
|
||||
$task['description'] = $vtodo->SUMMARY;
|
||||
} else {
|
||||
$task['description'] = $vtodo->DESCRIPTION;
|
||||
}
|
||||
|
||||
if (isset($vtodo->DTSTAMP)){
|
||||
$task['entry'] = new Carbon($vtodo->DTSTAMP->getDateTime()->format(\DateTime::W3C));
|
||||
}
|
||||
|
||||
if (isset($vtodo->DUE)){
|
||||
$task['due'] = new Carbon($vtodo->DUE->getDateTime()->format(\DateTime::W3C));
|
||||
}
|
||||
|
||||
return $task;
|
||||
}
|
||||
|
||||
public function save(Calendar $c) {
|
||||
if (!isset($c->VTODO)){
|
||||
throw new \Exception('Calendar event does not contain VTODO');
|
||||
}
|
||||
$this->refresh();
|
||||
$task = $this->vObjectToTask($c->VTODO);
|
||||
$this->console->execute('task', ['import'], $task);
|
||||
}
|
||||
}
|
88
lib/Storages/Todotxt.php
Normal file
88
lib/Storages/Todotxt.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace Aerex\BaikalStorage\Storages;
|
||||
|
||||
use Sabre\VObject\Component\VCalendar as Calendar;
|
||||
use Carbon\Carbon;
|
||||
class Todotxt implements IStorage {
|
||||
|
||||
private $dataFiles = [];
|
||||
public const name = 'taskwarrior';
|
||||
private $todos = [];
|
||||
public function __construct($console) {
|
||||
$this->console = $console;
|
||||
}
|
||||
|
||||
public function setConfig($config) {
|
||||
$this->config = $config;
|
||||
array_push($this->dataFiles, $config['todo_file']);
|
||||
array_push($this->dataFiles, $config['done_file']);
|
||||
array_push($this->dataFiles, $config['report_file']);
|
||||
}
|
||||
|
||||
private function parseRaw($rawTodos) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
private function refresh() {
|
||||
$dataDir = $this->config['todo_dir'];
|
||||
$fp = fopen(sprintf('%s/baikal-todo-storage.lock', $dataDir), 'a');
|
||||
|
||||
if (!$fp || !flock($fp, LOCK_EX | LOCK_NB, $eWouldBlock) || $eWouldBlock) {
|
||||
fputs(STDERR, 'Could not get lock');
|
||||
}
|
||||
|
||||
$mtime = 0;
|
||||
$tasksUpdated = false;
|
||||
foreach ($this->dataFiles as $dataFile) {
|
||||
$fmtime = filemtime(sprintf('%s/%s', $this->config['data_dir'], $dataFile));
|
||||
if ($fmtime > $mtime) {
|
||||
$mtime = $fmtime;
|
||||
$tasksUpdated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($tasksUpdated) {
|
||||
$rawTodos = $this->console->execute('cat', [$this->config['todo_file']]);
|
||||
$todos = $this->parseRaw($rawTodos);
|
||||
foreach ($todos as $todo) {
|
||||
$this->todos[$todo['line']] = $todos;
|
||||
}
|
||||
}
|
||||
fclose($fp);
|
||||
unlink(sprintf('%s/baikal-todo-storage.lock', $dataDir));
|
||||
}
|
||||
|
||||
public function vObjectToTodo($vtodo) {
|
||||
$task = [];
|
||||
|
||||
$task['uid'] = $vtodo->UID;
|
||||
|
||||
if(!isset($vtodo->DESCRIPTION) && isset($vtodo->SUMMARY)){
|
||||
$task['description'] = $vtodo->SUMMARY;
|
||||
} else {
|
||||
$task['description'] = $vtodo->DESCRIPTION;
|
||||
}
|
||||
|
||||
if (isset($vtodo->DTSTAMP)){
|
||||
$task['entry'] = new Carbon($vtodo->DTSTAMP->getDateTime()->format(\DateTime::W3C));
|
||||
}
|
||||
|
||||
if (isset($vtodo->DUE)){
|
||||
$task['due'] = new Carbon($vtodo->DUE->getDateTime()->format(\DateTime::W3C));
|
||||
}
|
||||
|
||||
return $task;
|
||||
}
|
||||
|
||||
public function save(Calendar $c) {
|
||||
if (!isset($c->VTODO)){
|
||||
throw new Exception('Could not find iCal VTODO event');
|
||||
}
|
||||
$this->refresh();
|
||||
$task = $this->vObjectToTodo($c->VTODO);
|
||||
$this->console->execute('task', ['import'], $task);
|
||||
}
|
||||
}
|
29
phpunit.xml.dist
Normal file
29
phpunit.xml.dist
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0"?>
|
||||
<phpunit
|
||||
colors="true"
|
||||
bootstrap="vendor/autoload.php"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
beStrictAboutTestsThatDoNotTestAnything="true">
|
||||
|
||||
|
||||
<testsuite name="Baikal Storage Plug Tests">
|
||||
<directory>./lib/tests</directory>
|
||||
</testsuite>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./lib</directory>
|
||||
<exclude>
|
||||
<directory>./lib/tests</directory>
|
||||
<directory>./vendor</directory>
|
||||
</exclude>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
<logging>
|
||||
<log type="coverage-html" target="/tmp/report" lowUpperBound="35"
|
||||
highLowerBound="70"/>
|
||||
</logging>
|
||||
</phpunit>
|
2
tests/Fixtures/taskwarrior_config.yml
Normal file
2
tests/Fixtures/taskwarrior_config.yml
Normal file
@ -0,0 +1,2 @@
|
||||
taskwarrior:
|
||||
data_dir: '~/task'
|
71
tests/StorageManagerTest.php
Normal file
71
tests/StorageManagerTest.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace Aerex\BaikalStorage;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Aerex\BaikalStorage\AbstractConsole;
|
||||
use Aerex\BaikalStorage\Configs\ConfigBuilder;
|
||||
use Aerex\BaikalStorage\Configs\TaskwarriorConfig;
|
||||
use Aerex\BaikalStorage\Storages\Taskwarrior;
|
||||
use Aerex\BaikalStorage\Storages\IStorage;
|
||||
use Sabre\VObject\Component\VCalendar as Calendar;
|
||||
|
||||
class StorageManagerTest extends TestCase {
|
||||
|
||||
/**
|
||||
* @var \PHPUnit_Framework_MockObject_MockObject
|
||||
* */
|
||||
private $mockConsole;
|
||||
|
||||
private $mockStorage;
|
||||
|
||||
public $mockConfigBuilder;
|
||||
|
||||
function setUp() {
|
||||
$this->mockConfigBuilder = $this->getMockBuilder(ConfigBuilder::class)
|
||||
->setMethods(['readContent'])
|
||||
->setConstructorArgs([''])
|
||||
->getMock();
|
||||
$this->mockConsole = $this->createMock(AbstractConsole::class);
|
||||
$this->mockStorage = $this->createMock(IStorage::class);
|
||||
}
|
||||
|
||||
public function testAddTaskwarriorStorage() {
|
||||
$this->mockConfigBuilder->expects($this->once())
|
||||
->method('readContent')
|
||||
->willReturn(file_get_contents(__DIR__ . '/Fixtures/taskwarrior_config.yml'));
|
||||
$tw = new Taskwarrior($this->mockConsole, new TaskwarriorConfig());
|
||||
$manager = new StorageManager($this->mockConfigBuilder);
|
||||
$manager->addStorage(Taskwarrior::NAME, $tw);
|
||||
$storages = $manager->getStorages();
|
||||
$manager->init();
|
||||
$configs = $manager->getConfigs();
|
||||
$this->assertEquals(sizeof(array_keys($storages)), 1, 'Taskwarrior storage was not added');
|
||||
$this->assertEquals(sizeof(array_keys($configs)), 1, 'Taskwarrior config was not loaded');
|
||||
$this->assertArrayHasKey('taskwarrior', $storages, 'Storages should have taskwarrior');
|
||||
$this->assertArrayHasKey('taskwarrior', $configs, 'Configs should have taskwarrior');
|
||||
}
|
||||
|
||||
public function testTaskwarriorImport() {
|
||||
$cal = new Calendar();
|
||||
$this->mockConfigBuilder->expects($this->once())
|
||||
->method('readContent')
|
||||
->willReturn(file_get_contents(__DIR__ . '/Fixtures/taskwarrior_config.yml'));
|
||||
$this->mockStorage->expects($this->once())
|
||||
->method('save')
|
||||
->with($this->equalTo($cal));
|
||||
$this->mockStorage->expects($this->once())
|
||||
->method('setRawConfigs')
|
||||
->with($this->equalTo(['data_dir' => '~/.task']));
|
||||
$this->mockStorage->expects($this->once())
|
||||
->method('getConfig')
|
||||
->willReturn(new TaskwarriorConfig());
|
||||
|
||||
$manager = new StorageManager($this->mockConfigBuilder);
|
||||
$manager->addStorage(Taskwarrior::NAME, $this->mockStorage);
|
||||
$manager->init();
|
||||
|
||||
$manager->import($cal);
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user