mirror of
https://github.com/wallabag/wallabag.git
synced 2025-06-27 16:36:00 +00:00
Add Pocket and Shaarli imports
This commit is contained in:
parent
70999075a6
commit
b1614e9267
26 changed files with 1732 additions and 10 deletions
|
@ -123,9 +123,9 @@ class FirefoxControllerTest extends WallabagCoreTestCase
|
|||
);
|
||||
|
||||
$this->assertInstanceOf(Entry::class, $content);
|
||||
$this->assertNotEmpty($content->getMimetype(), 'Mimetype for http://lexpansion.lexpress.fr is ok');
|
||||
$this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for http://lexpansion.lexpress.fr is ok');
|
||||
$this->assertNotEmpty($content->getLanguage(), 'Language for http://lexpansion.lexpress.fr is ok');
|
||||
$this->assertNotEmpty($content->getMimetype(), 'Mimetype for 20minutes.fr is ok');
|
||||
$this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for 20minutes.fr is ok');
|
||||
$this->assertNotEmpty($content->getLanguage(), 'Language for 20minutes.fr is ok');
|
||||
$this->assertCount(3, $content->getTags());
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,6 @@ class ImportControllerTest extends WallabagCoreTestCase
|
|||
$crawler = $client->request('GET', '/import/');
|
||||
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
$this->assertSame(11, $crawler->filter('blockquote')->count());
|
||||
$this->assertSame(13, $crawler->filter('blockquote')->count());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Wallabag\ImportBundle\Controller;
|
||||
|
||||
use Craue\ConfigBundle\Util\Config;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Predis\Client;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
|
||||
use Wallabag\CoreBundle\Entity\Entry;
|
||||
|
||||
class PocketHtmlControllerTest extends WallabagCoreTestCase
|
||||
{
|
||||
public function testImportPocketHtml()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/import/pocket_html');
|
||||
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
$this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count());
|
||||
$this->assertSame(1, $crawler->filter('input[type=file]')->count());
|
||||
}
|
||||
|
||||
public function testImportPocketHtmlWithRabbitEnabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1);
|
||||
|
||||
$crawler = $client->request('GET', '/import/pocket_html');
|
||||
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
$this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count());
|
||||
$this->assertSame(1, $crawler->filter('input[type=file]')->count());
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 0);
|
||||
}
|
||||
|
||||
public function testImportPocketHtmlBadFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/import/pocket_html');
|
||||
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
|
||||
|
||||
$data = [
|
||||
'upload_import_file[file]' => '',
|
||||
];
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
}
|
||||
|
||||
public function testImportPocketHtmlWithRedisEnabled()
|
||||
{
|
||||
$this->checkRedis();
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
$client->getContainer()->get(Config::class)->set('import_with_redis', 1);
|
||||
|
||||
$crawler = $client->request('GET', '/import/pocket_html');
|
||||
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
$this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count());
|
||||
$this->assertSame(1, $crawler->filter('input[type=file]')->count());
|
||||
|
||||
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
|
||||
|
||||
$file = new UploadedFile(__DIR__ . '/../fixtures/ril_export.html', 'Bookmarks');
|
||||
|
||||
$data = [
|
||||
'upload_import_file[file]' => $file,
|
||||
];
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertSame(302, $client->getResponse()->getStatusCode());
|
||||
|
||||
$crawler = $client->followRedirect();
|
||||
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.summary', $body[0]);
|
||||
|
||||
$this->assertNotEmpty($client->getContainer()->get(Client::class)->lpop('wallabag.import.pocket_html'));
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
|
||||
}
|
||||
|
||||
public function testImportWallabagWithPocketHtmlFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/import/pocket_html');
|
||||
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
|
||||
|
||||
$file = new UploadedFile(__DIR__ . '/../fixtures/ril_export.html', 'Bookmarks');
|
||||
|
||||
$data = [
|
||||
'upload_import_file[file]' => $file,
|
||||
];
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertSame(302, $client->getResponse()->getStatusCode());
|
||||
|
||||
$crawler = $client->followRedirect();
|
||||
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.summary', $body[0]);
|
||||
|
||||
$content = $client->getContainer()
|
||||
->get(EntityManagerInterface::class)
|
||||
->getRepository(Entry::class)
|
||||
->findByUrlAndUserId(
|
||||
'https://www.20minutes.fr/sport/4002755-20220928-tarn-lapins-ravagent-terrain-match-rugby-doit-etre-annule',
|
||||
$this->getLoggedInUserId()
|
||||
);
|
||||
|
||||
$this->assertInstanceOf(Entry::class, $content);
|
||||
$this->assertNotEmpty($content->getMimetype(), 'Mimetype for 20minutes.fr is ok');
|
||||
$this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for 20minutes.fr is ok');
|
||||
$this->assertNotEmpty($content->getLanguage(), 'Language for 20minutes.fr is ok');
|
||||
$this->assertCount(3, $content->getTags());
|
||||
|
||||
$content = $client->getContainer()
|
||||
->get(EntityManagerInterface::class)
|
||||
->getRepository(Entry::class)
|
||||
->findByUrlAndUserId(
|
||||
'https://www.lemonde.fr/disparitions/article/2018/07/05/le-journaliste-et-cineaste-claude-lanzmann-est-mort_5326313_3382.html',
|
||||
$this->getLoggedInUserId()
|
||||
);
|
||||
|
||||
$this->assertInstanceOf(Entry::class, $content);
|
||||
$this->assertNotEmpty($content->getMimetype(), 'Mimetype for https://www.lemonde.fr is ok');
|
||||
$this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for https://www.lemonde.fr is ok');
|
||||
$this->assertNotEmpty($content->getLanguage(), 'Language for https://www.lemonde.fr is ok');
|
||||
}
|
||||
|
||||
public function testImportWallabagWithEmptyFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/import/pocket_html');
|
||||
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
|
||||
|
||||
$file = new UploadedFile(__DIR__ . '/../fixtures/test.html', 'test.html');
|
||||
|
||||
$data = [
|
||||
'upload_import_file[file]' => $file,
|
||||
];
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertSame(302, $client->getResponse()->getStatusCode());
|
||||
|
||||
$crawler = $client->followRedirect();
|
||||
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.failed', $body[0]);
|
||||
}
|
||||
}
|
168
tests/Wallabag/ImportBundle/Controller/ShaarliControllerTest.php
Normal file
168
tests/Wallabag/ImportBundle/Controller/ShaarliControllerTest.php
Normal file
|
@ -0,0 +1,168 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Wallabag\ImportBundle\Controller;
|
||||
|
||||
use Craue\ConfigBundle\Util\Config;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Predis\Client;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
|
||||
use Wallabag\CoreBundle\Entity\Entry;
|
||||
|
||||
class ShaarliControllerTest extends WallabagCoreTestCase
|
||||
{
|
||||
public function testImportShaarli()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/import/shaarli');
|
||||
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
$this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count());
|
||||
$this->assertSame(1, $crawler->filter('input[type=file]')->count());
|
||||
}
|
||||
|
||||
public function testImportShaarliWithRabbitEnabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1);
|
||||
|
||||
$crawler = $client->request('GET', '/import/shaarli');
|
||||
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
$this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count());
|
||||
$this->assertSame(1, $crawler->filter('input[type=file]')->count());
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 0);
|
||||
}
|
||||
|
||||
public function testImportShaarliBadFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/import/shaarli');
|
||||
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
|
||||
|
||||
$data = [
|
||||
'upload_import_file[file]' => '',
|
||||
];
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
}
|
||||
|
||||
public function testImportShaarliWithRedisEnabled()
|
||||
{
|
||||
$this->checkRedis();
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
$client->getContainer()->get(Config::class)->set('import_with_redis', 1);
|
||||
|
||||
$crawler = $client->request('GET', '/import/shaarli');
|
||||
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
$this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count());
|
||||
$this->assertSame(1, $crawler->filter('input[type=file]')->count());
|
||||
|
||||
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
|
||||
|
||||
$file = new UploadedFile(__DIR__ . '/../fixtures/shaarli-bookmarks.html', 'Bookmarks');
|
||||
|
||||
$data = [
|
||||
'upload_import_file[file]' => $file,
|
||||
];
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertSame(302, $client->getResponse()->getStatusCode());
|
||||
|
||||
$crawler = $client->followRedirect();
|
||||
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.summary', $body[0]);
|
||||
|
||||
$this->assertNotEmpty($client->getContainer()->get(Client::class)->lpop('wallabag.import.shaarli'));
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
|
||||
}
|
||||
|
||||
public function testImportWallabagWithShaarliFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/import/shaarli');
|
||||
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
|
||||
|
||||
$file = new UploadedFile(__DIR__ . '/../fixtures/shaarli-bookmarks.html', 'Bookmarks');
|
||||
|
||||
$data = [
|
||||
'upload_import_file[file]' => $file,
|
||||
];
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertSame(302, $client->getResponse()->getStatusCode());
|
||||
|
||||
$crawler = $client->followRedirect();
|
||||
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.summary', $body[0]);
|
||||
|
||||
$content = $client->getContainer()
|
||||
->get(EntityManagerInterface::class)
|
||||
->getRepository(Entry::class)
|
||||
->findByUrlAndUserId(
|
||||
'https://www.20minutes.fr/sport/4002755-20220928-tarn-lapins-ravagent-terrain-match-rugby-doit-etre-annule',
|
||||
$this->getLoggedInUserId()
|
||||
);
|
||||
|
||||
$this->assertInstanceOf(Entry::class, $content);
|
||||
$this->assertNotEmpty($content->getMimetype(), 'Mimetype for 20minutes.fr is ok');
|
||||
$this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for 20minutes.fr is ok');
|
||||
$this->assertNotEmpty($content->getLanguage(), 'Language for 20minutes.fr is ok');
|
||||
$this->assertCount(2, $content->getTags());
|
||||
|
||||
$content = $client->getContainer()
|
||||
->get(EntityManagerInterface::class)
|
||||
->getRepository(Entry::class)
|
||||
->findByUrlAndUserId(
|
||||
'https://www.lemonde.fr/disparitions/article/2018/07/05/le-journaliste-et-cineaste-claude-lanzmann-est-mort_5326313_3382.html',
|
||||
$this->getLoggedInUserId()
|
||||
);
|
||||
|
||||
$this->assertInstanceOf(Entry::class, $content);
|
||||
$this->assertNotEmpty($content->getMimetype(), 'Mimetype for https://www.lemonde.fr is ok');
|
||||
$this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for https://www.lemonde.fr is ok');
|
||||
$this->assertNotEmpty($content->getLanguage(), 'Language for https://www.lemonde.fr is ok');
|
||||
}
|
||||
|
||||
public function testImportWallabagWithEmptyFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/import/shaarli');
|
||||
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
|
||||
|
||||
$file = new UploadedFile(__DIR__ . '/../fixtures/test.html', 'test.html');
|
||||
|
||||
$data = [
|
||||
'upload_import_file[file]' => $file,
|
||||
];
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertSame(302, $client->getResponse()->getStatusCode());
|
||||
|
||||
$crawler = $client->followRedirect();
|
||||
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.failed', $body[0]);
|
||||
}
|
||||
}
|
254
tests/Wallabag/ImportBundle/Import/PocketHtmlImportTest.php
Normal file
254
tests/Wallabag/ImportBundle/Import/PocketHtmlImportTest.php
Normal file
|
@ -0,0 +1,254 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Wallabag\ImportBundle\Import;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use M6Web\Component\RedisMock\RedisMockFactory;
|
||||
use Monolog\Handler\TestHandler;
|
||||
use Monolog\Logger;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Predis\Client;
|
||||
use Simpleue\Queue\RedisQueue;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Wallabag\CoreBundle\Entity\Entry;
|
||||
use Wallabag\CoreBundle\Helper\ContentProxy;
|
||||
use Wallabag\CoreBundle\Helper\TagsAssigner;
|
||||
use Wallabag\CoreBundle\Repository\EntryRepository;
|
||||
use Wallabag\ImportBundle\Import\PocketHtmlImport;
|
||||
use Wallabag\ImportBundle\Redis\Producer;
|
||||
use Wallabag\UserBundle\Entity\User;
|
||||
|
||||
class PocketHtmlImportTest extends TestCase
|
||||
{
|
||||
protected $user;
|
||||
protected $em;
|
||||
protected $logHandler;
|
||||
protected $contentProxy;
|
||||
protected $tagsAssigner;
|
||||
|
||||
public function testInit()
|
||||
{
|
||||
$pocketHtmlImport = $this->getPocketHtmlImport();
|
||||
|
||||
$this->assertSame('Pocket HTML', $pocketHtmlImport->getName());
|
||||
$this->assertNotEmpty($pocketHtmlImport->getUrl());
|
||||
$this->assertSame('import.pocket_html.description', $pocketHtmlImport->getDescription());
|
||||
}
|
||||
|
||||
public function testImport()
|
||||
{
|
||||
$pocketHtmlImport = $this->getPocketHtmlImport(false, 2);
|
||||
$pocketHtmlImport->setFilepath(__DIR__ . '/../fixtures/ril_export.html');
|
||||
|
||||
$entryRepo = $this->getMockBuilder(EntryRepository::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$entryRepo->expects($this->exactly(2))
|
||||
->method('findByUrlAndUserId')
|
||||
->willReturn(false);
|
||||
|
||||
$this->em
|
||||
->expects($this->any())
|
||||
->method('getRepository')
|
||||
->willReturn($entryRepo);
|
||||
|
||||
$entry = $this->getMockBuilder(Entry::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->contentProxy
|
||||
->expects($this->exactly(2))
|
||||
->method('updateEntry')
|
||||
->willReturn($entry);
|
||||
|
||||
$res = $pocketHtmlImport->import();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertSame(['skipped' => 0, 'imported' => 2, 'queued' => 0], $pocketHtmlImport->getSummary());
|
||||
}
|
||||
|
||||
public function testImportAndMarkAllAsRead()
|
||||
{
|
||||
$pocketHtmlImport = $this->getPocketHtmlImport(false, 1);
|
||||
$pocketHtmlImport->setFilepath(__DIR__ . '/../fixtures/ril_export.html');
|
||||
|
||||
$entryRepo = $this->getMockBuilder(EntryRepository::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$entryRepo->expects($this->exactly(2))
|
||||
->method('findByUrlAndUserId')
|
||||
->will($this->onConsecutiveCalls(false, true));
|
||||
|
||||
$this->em
|
||||
->expects($this->any())
|
||||
->method('getRepository')
|
||||
->willReturn($entryRepo);
|
||||
|
||||
$this->contentProxy
|
||||
->expects($this->exactly(1))
|
||||
->method('updateEntry')
|
||||
->willReturn(new Entry($this->user));
|
||||
|
||||
// check that every entry persisted are archived
|
||||
$this->em
|
||||
->expects($this->any())
|
||||
->method('persist')
|
||||
->with($this->callback(function ($persistedEntry) {
|
||||
return (bool) $persistedEntry->isArchived();
|
||||
}));
|
||||
|
||||
$res = $pocketHtmlImport
|
||||
->setMarkAsRead(true)
|
||||
->import();
|
||||
|
||||
$this->assertTrue($res);
|
||||
|
||||
$this->assertSame(['skipped' => 1, 'imported' => 1, 'queued' => 0], $pocketHtmlImport->getSummary());
|
||||
}
|
||||
|
||||
public function testImportWithRabbit()
|
||||
{
|
||||
$pocketHtmlImport = $this->getPocketHtmlImport();
|
||||
$pocketHtmlImport->setFilepath(__DIR__ . '/../fixtures/ril_export.html');
|
||||
|
||||
$entryRepo = $this->getMockBuilder(EntryRepository::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$entryRepo->expects($this->never())
|
||||
->method('findByUrlAndUserId');
|
||||
|
||||
$this->em
|
||||
->expects($this->never())
|
||||
->method('getRepository');
|
||||
|
||||
$entry = $this->getMockBuilder(Entry::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->contentProxy
|
||||
->expects($this->never())
|
||||
->method('updateEntry');
|
||||
|
||||
$producer = $this->getMockBuilder(\OldSound\RabbitMqBundle\RabbitMq\Producer::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$producer
|
||||
->expects($this->exactly(2))
|
||||
->method('publish');
|
||||
|
||||
$pocketHtmlImport->setProducer($producer);
|
||||
|
||||
$res = $pocketHtmlImport->setMarkAsRead(true)->import();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertSame(['skipped' => 0, 'imported' => 0, 'queued' => 2], $pocketHtmlImport->getSummary());
|
||||
}
|
||||
|
||||
public function testImportWithRedis()
|
||||
{
|
||||
$pocketHtmlImport = $this->getPocketHtmlImport();
|
||||
$pocketHtmlImport->setFilepath(__DIR__ . '/../fixtures/ril_export.html');
|
||||
|
||||
$entryRepo = $this->getMockBuilder(EntryRepository::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$entryRepo->expects($this->never())
|
||||
->method('findByUrlAndUserId');
|
||||
|
||||
$this->em
|
||||
->expects($this->never())
|
||||
->method('getRepository');
|
||||
|
||||
$entry = $this->getMockBuilder(Entry::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->contentProxy
|
||||
->expects($this->never())
|
||||
->method('updateEntry');
|
||||
|
||||
$factory = new RedisMockFactory();
|
||||
$redisMock = $factory->getAdapter(Client::class, true);
|
||||
|
||||
$queue = new RedisQueue($redisMock, 'pocket_html');
|
||||
$producer = new Producer($queue);
|
||||
|
||||
$pocketHtmlImport->setProducer($producer);
|
||||
|
||||
$res = $pocketHtmlImport->setMarkAsRead(true)->import();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertSame(['skipped' => 0, 'imported' => 0, 'queued' => 2], $pocketHtmlImport->getSummary());
|
||||
|
||||
$this->assertNotEmpty($redisMock->lpop('pocket_html'));
|
||||
}
|
||||
|
||||
public function testImportBadFile()
|
||||
{
|
||||
$pocketHtmlImport = $this->getPocketHtmlImport();
|
||||
$pocketHtmlImport->setFilepath(__DIR__ . '/../fixtures/wallabag-v1.jsonx');
|
||||
|
||||
$res = $pocketHtmlImport->import();
|
||||
|
||||
$this->assertFalse($res);
|
||||
|
||||
$records = $this->logHandler->getRecords();
|
||||
$this->assertStringContainsString('Pocket HTML Import: unable to read file', $records[0]['message']);
|
||||
$this->assertSame('ERROR', $records[0]['level_name']);
|
||||
}
|
||||
|
||||
public function testImportUserNotDefined()
|
||||
{
|
||||
$pocketHtmlImport = $this->getPocketHtmlImport(true);
|
||||
$pocketHtmlImport->setFilepath(__DIR__ . '/../fixtures/ril_export.html');
|
||||
|
||||
$res = $pocketHtmlImport->import();
|
||||
|
||||
$this->assertFalse($res);
|
||||
|
||||
$records = $this->logHandler->getRecords();
|
||||
$this->assertStringContainsString('Pocket HTML Import: user is not defined', $records[0]['message']);
|
||||
$this->assertSame('ERROR', $records[0]['level_name']);
|
||||
}
|
||||
|
||||
private function getPocketHtmlImport($unsetUser = false, $dispatched = 0)
|
||||
{
|
||||
$this->user = new User();
|
||||
|
||||
$this->em = $this->getMockBuilder(EntityManager::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->contentProxy = $this->getMockBuilder(ContentProxy::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->tagsAssigner = $this->getMockBuilder(TagsAssigner::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$dispatcher = $this->getMockBuilder(EventDispatcher::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$dispatcher
|
||||
->expects($this->exactly($dispatched))
|
||||
->method('dispatch');
|
||||
|
||||
$this->logHandler = new TestHandler();
|
||||
$logger = new Logger('test', [$this->logHandler]);
|
||||
|
||||
$wallabag = new PocketHtmlImport($this->em, $this->contentProxy, $this->tagsAssigner, $dispatcher, $logger);
|
||||
|
||||
if (false === $unsetUser) {
|
||||
$wallabag->setUser($this->user);
|
||||
}
|
||||
|
||||
return $wallabag;
|
||||
}
|
||||
}
|
254
tests/Wallabag/ImportBundle/Import/ShaarliImportTest.php
Normal file
254
tests/Wallabag/ImportBundle/Import/ShaarliImportTest.php
Normal file
|
@ -0,0 +1,254 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Wallabag\ImportBundle\Import;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use M6Web\Component\RedisMock\RedisMockFactory;
|
||||
use Monolog\Handler\TestHandler;
|
||||
use Monolog\Logger;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Predis\Client;
|
||||
use Simpleue\Queue\RedisQueue;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Wallabag\CoreBundle\Entity\Entry;
|
||||
use Wallabag\CoreBundle\Helper\ContentProxy;
|
||||
use Wallabag\CoreBundle\Helper\TagsAssigner;
|
||||
use Wallabag\CoreBundle\Repository\EntryRepository;
|
||||
use Wallabag\ImportBundle\Import\ShaarliImport;
|
||||
use Wallabag\ImportBundle\Redis\Producer;
|
||||
use Wallabag\UserBundle\Entity\User;
|
||||
|
||||
class ShaarliImportTest extends TestCase
|
||||
{
|
||||
protected $user;
|
||||
protected $em;
|
||||
protected $logHandler;
|
||||
protected $contentProxy;
|
||||
protected $tagsAssigner;
|
||||
|
||||
public function testInit()
|
||||
{
|
||||
$shaarliImport = $this->getShaarliImport();
|
||||
|
||||
$this->assertSame('Shaarli', $shaarliImport->getName());
|
||||
$this->assertNotEmpty($shaarliImport->getUrl());
|
||||
$this->assertSame('import.shaarli.description', $shaarliImport->getDescription());
|
||||
}
|
||||
|
||||
public function testImport()
|
||||
{
|
||||
$shaarliImport = $this->getShaarliImport(false, 2);
|
||||
$shaarliImport->setFilepath(__DIR__ . '/../fixtures/shaarli-bookmarks.html');
|
||||
|
||||
$entryRepo = $this->getMockBuilder(EntryRepository::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$entryRepo->expects($this->exactly(2))
|
||||
->method('findByUrlAndUserId')
|
||||
->willReturn(false);
|
||||
|
||||
$this->em
|
||||
->expects($this->any())
|
||||
->method('getRepository')
|
||||
->willReturn($entryRepo);
|
||||
|
||||
$entry = $this->getMockBuilder(Entry::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->contentProxy
|
||||
->expects($this->exactly(2))
|
||||
->method('updateEntry')
|
||||
->willReturn($entry);
|
||||
|
||||
$res = $shaarliImport->import();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertSame(['skipped' => 0, 'imported' => 2, 'queued' => 0], $shaarliImport->getSummary());
|
||||
}
|
||||
|
||||
public function testImportAndMarkAllAsRead()
|
||||
{
|
||||
$shaarliImport = $this->getShaarliImport(false, 1);
|
||||
$shaarliImport->setFilepath(__DIR__ . '/../fixtures/shaarli-bookmarks.html');
|
||||
|
||||
$entryRepo = $this->getMockBuilder(EntryRepository::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$entryRepo->expects($this->exactly(2))
|
||||
->method('findByUrlAndUserId')
|
||||
->will($this->onConsecutiveCalls(false, true));
|
||||
|
||||
$this->em
|
||||
->expects($this->any())
|
||||
->method('getRepository')
|
||||
->willReturn($entryRepo);
|
||||
|
||||
$this->contentProxy
|
||||
->expects($this->exactly(1))
|
||||
->method('updateEntry')
|
||||
->willReturn(new Entry($this->user));
|
||||
|
||||
// check that every entry persisted are archived
|
||||
$this->em
|
||||
->expects($this->any())
|
||||
->method('persist')
|
||||
->with($this->callback(function ($persistedEntry) {
|
||||
return (bool) $persistedEntry->isArchived();
|
||||
}));
|
||||
|
||||
$res = $shaarliImport
|
||||
->setMarkAsRead(true)
|
||||
->import();
|
||||
|
||||
$this->assertTrue($res);
|
||||
|
||||
$this->assertSame(['skipped' => 1, 'imported' => 1, 'queued' => 0], $shaarliImport->getSummary());
|
||||
}
|
||||
|
||||
public function testImportWithRabbit()
|
||||
{
|
||||
$shaarliImport = $this->getShaarliImport();
|
||||
$shaarliImport->setFilepath(__DIR__ . '/../fixtures/shaarli-bookmarks.html');
|
||||
|
||||
$entryRepo = $this->getMockBuilder(EntryRepository::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$entryRepo->expects($this->never())
|
||||
->method('findByUrlAndUserId');
|
||||
|
||||
$this->em
|
||||
->expects($this->never())
|
||||
->method('getRepository');
|
||||
|
||||
$entry = $this->getMockBuilder(Entry::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->contentProxy
|
||||
->expects($this->never())
|
||||
->method('updateEntry');
|
||||
|
||||
$producer = $this->getMockBuilder(\OldSound\RabbitMqBundle\RabbitMq\Producer::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$producer
|
||||
->expects($this->exactly(2))
|
||||
->method('publish');
|
||||
|
||||
$shaarliImport->setProducer($producer);
|
||||
|
||||
$res = $shaarliImport->setMarkAsRead(true)->import();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertSame(['skipped' => 0, 'imported' => 0, 'queued' => 2], $shaarliImport->getSummary());
|
||||
}
|
||||
|
||||
public function testImportWithRedis()
|
||||
{
|
||||
$shaarliImport = $this->getShaarliImport();
|
||||
$shaarliImport->setFilepath(__DIR__ . '/../fixtures/shaarli-bookmarks.html');
|
||||
|
||||
$entryRepo = $this->getMockBuilder(EntryRepository::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$entryRepo->expects($this->never())
|
||||
->method('findByUrlAndUserId');
|
||||
|
||||
$this->em
|
||||
->expects($this->never())
|
||||
->method('getRepository');
|
||||
|
||||
$entry = $this->getMockBuilder(Entry::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->contentProxy
|
||||
->expects($this->never())
|
||||
->method('updateEntry');
|
||||
|
||||
$factory = new RedisMockFactory();
|
||||
$redisMock = $factory->getAdapter(Client::class, true);
|
||||
|
||||
$queue = new RedisQueue($redisMock, 'shaarli');
|
||||
$producer = new Producer($queue);
|
||||
|
||||
$shaarliImport->setProducer($producer);
|
||||
|
||||
$res = $shaarliImport->setMarkAsRead(true)->import();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertSame(['skipped' => 0, 'imported' => 0, 'queued' => 2], $shaarliImport->getSummary());
|
||||
|
||||
$this->assertNotEmpty($redisMock->lpop('shaarli'));
|
||||
}
|
||||
|
||||
public function testImportBadFile()
|
||||
{
|
||||
$shaarliImport = $this->getShaarliImport();
|
||||
$shaarliImport->setFilepath(__DIR__ . '/../fixtures/wallabag-v1.jsonx');
|
||||
|
||||
$res = $shaarliImport->import();
|
||||
|
||||
$this->assertFalse($res);
|
||||
|
||||
$records = $this->logHandler->getRecords();
|
||||
$this->assertStringContainsString('Wallabag HTML Import: unable to read file', $records[0]['message']);
|
||||
$this->assertSame('ERROR', $records[0]['level_name']);
|
||||
}
|
||||
|
||||
public function testImportUserNotDefined()
|
||||
{
|
||||
$shaarliImport = $this->getShaarliImport(true);
|
||||
$shaarliImport->setFilepath(__DIR__ . '/../fixtures/shaarli-bookmarks.html');
|
||||
|
||||
$res = $shaarliImport->import();
|
||||
|
||||
$this->assertFalse($res);
|
||||
|
||||
$records = $this->logHandler->getRecords();
|
||||
$this->assertStringContainsString('Wallabag HTML Import: user is not defined', $records[0]['message']);
|
||||
$this->assertSame('ERROR', $records[0]['level_name']);
|
||||
}
|
||||
|
||||
private function getShaarliImport($unsetUser = false, $dispatched = 0)
|
||||
{
|
||||
$this->user = new User();
|
||||
|
||||
$this->em = $this->getMockBuilder(EntityManager::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->contentProxy = $this->getMockBuilder(ContentProxy::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->tagsAssigner = $this->getMockBuilder(TagsAssigner::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$dispatcher = $this->getMockBuilder(EventDispatcher::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$dispatcher
|
||||
->expects($this->exactly($dispatched))
|
||||
->method('dispatch');
|
||||
|
||||
$this->logHandler = new TestHandler();
|
||||
$logger = new Logger('test', [$this->logHandler]);
|
||||
|
||||
$wallabag = new ShaarliImport($this->em, $this->contentProxy, $this->tagsAssigner, $dispatcher, $logger);
|
||||
|
||||
if (false === $unsetUser) {
|
||||
$wallabag->setUser($this->user);
|
||||
}
|
||||
|
||||
return $wallabag;
|
||||
}
|
||||
}
|
21
tests/Wallabag/ImportBundle/fixtures/ril_export.html
Normal file
21
tests/Wallabag/ImportBundle/fixtures/ril_export.html
Normal file
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--So long and thanks for all the fish-->
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>Pocket Export</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Unread</h1>
|
||||
<ul>
|
||||
<li><a href="https://www.20minutes.fr/sport/4002755-20220928-tarn-lapins-ravagent-terrain-match-rugby-doit-etre-annule" time_added="1688628695" tags="ifttt,new_entry_simple">Tarn : Des lapins ravagent le terrain, le match de rugby doit être annulé</a></li>
|
||||
<li><a href="https://www.lemonde.fr/disparitions/article/2018/07/05/le-journaliste-et-cineaste-claude-lanzmann-est-mort_5326313_3382.html" time_added="1688627412" tags="ifttt,new_entry_simple">Le journaliste et cinéaste Claude Lanzmann est mort</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h1>Read Archive</h1>
|
||||
<ul>
|
||||
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
13
tests/Wallabag/ImportBundle/fixtures/shaarli-bookmarks.html
Normal file
13
tests/Wallabag/ImportBundle/fixtures/shaarli-bookmarks.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE NETSCAPE-Bookmark-file-1>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
|
||||
<!-- This is an automatically generated file.
|
||||
It will be read and overwritten.
|
||||
Do Not Edit! -->
|
||||
<TITLE>Bookmarks</TITLE>
|
||||
<H1>Shaarli export of all bookmarks on Mon, 17 Jul 23 14:31:25 +0200</H1>
|
||||
<DL><p>
|
||||
<DT><A HREF="https://www.20minutes.fr/sport/4002755-20220928-tarn-lapins-ravagent-terrain-match-rugby-doit-etre-annule" ADD_DATE="1686813518" LAST_MODIFIED="1686813519" PRIVATE="0" TAGS="firefoxos">The Legacy of Firefox OS. In the two years or so since Mozilla… | by Ben Francis | Medium</A>
|
||||
<DD>In the two years or so since Mozilla announced the end of Firefox OS as a Mozilla-run project, the B2G source code has found its way into a surprising number of commercial products.
|
||||
<DT><A HREF="https://www.lemonde.fr/disparitions/article/2018/07/05/le-journaliste-et-cineaste-claude-lanzmann-est-mort_5326313_3382.html" ADD_DATE="1683376565" LAST_MODIFIED="1683376571" PRIVATE="0" TAGS="eleventy,this,javascript,filter,data">Template Filters — Eleventy</A>
|
||||
</DL><p>
|
||||
<script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
|
Loading…
Add table
Add a link
Reference in a new issue