diff options
13 files changed, 547 insertions, 5 deletions
diff --git a/app/config/config.yml b/app/config/config.yml index a4584a1b..cfb0d54d 100644 --- a/app/config/config.yml +++ b/app/config/config.yml | |||
@@ -55,7 +55,7 @@ wallabag_user: | |||
55 | registration_enabled: "%fosuser_registration%" | 55 | registration_enabled: "%fosuser_registration%" |
56 | 56 | ||
57 | wallabag_import: | 57 | wallabag_import: |
58 | allow_mimetypes: ['application/octet-stream', 'application/json', 'text/plain'] | 58 | allow_mimetypes: ['application/octet-stream', 'application/json', 'text/plain', 'text/csv'] |
59 | resource_dir: "%kernel.root_dir%/../web/uploads/import" | 59 | resource_dir: "%kernel.root_dir%/../web/uploads/import" |
60 | 60 | ||
61 | # Twig Configuration | 61 | # Twig Configuration |
diff --git a/src/Wallabag/ImportBundle/Command/RedisWorkerCommand.php b/src/Wallabag/ImportBundle/Command/RedisWorkerCommand.php index 5f90e00f..c2c11f11 100644 --- a/src/Wallabag/ImportBundle/Command/RedisWorkerCommand.php +++ b/src/Wallabag/ImportBundle/Command/RedisWorkerCommand.php | |||
@@ -17,7 +17,7 @@ class RedisWorkerCommand extends ContainerAwareCommand | |||
17 | $this | 17 | $this |
18 | ->setName('wallabag:import:redis-worker') | 18 | ->setName('wallabag:import:redis-worker') |
19 | ->setDescription('Launch Redis worker') | 19 | ->setDescription('Launch Redis worker') |
20 | ->addArgument('serviceName', InputArgument::REQUIRED, 'Service to use: wallabag_v1, wallabag_v2, pocket or readability') | 20 | ->addArgument('serviceName', InputArgument::REQUIRED, 'Service to use: wallabag_v1, wallabag_v2, pocket, readability, firefox, chrome or instapaper') |
21 | ->addOption('maxIterations', '', InputOption::VALUE_OPTIONAL, 'Number of iterations before stoping', false) | 21 | ->addOption('maxIterations', '', InputOption::VALUE_OPTIONAL, 'Number of iterations before stoping', false) |
22 | ; | 22 | ; |
23 | } | 23 | } |
diff --git a/src/Wallabag/ImportBundle/Controller/ImportController.php b/src/Wallabag/ImportBundle/Controller/ImportController.php index 36a2a399..15de75ff 100644 --- a/src/Wallabag/ImportBundle/Controller/ImportController.php +++ b/src/Wallabag/ImportBundle/Controller/ImportController.php | |||
@@ -38,7 +38,11 @@ class ImportController extends Controller | |||
38 | $nbRabbitMessages = $this->getTotalMessageInRabbitQueue('pocket') | 38 | $nbRabbitMessages = $this->getTotalMessageInRabbitQueue('pocket') |
39 | + $this->getTotalMessageInRabbitQueue('readability') | 39 | + $this->getTotalMessageInRabbitQueue('readability') |
40 | + $this->getTotalMessageInRabbitQueue('wallabag_v1') | 40 | + $this->getTotalMessageInRabbitQueue('wallabag_v1') |
41 | + $this->getTotalMessageInRabbitQueue('wallabag_v2'); | 41 | + $this->getTotalMessageInRabbitQueue('wallabag_v2') |
42 | + $this->getTotalMessageInRabbitQueue('firefox') | ||
43 | + $this->getTotalMessageInRabbitQueue('chrome') | ||
44 | + $this->getTotalMessageInRabbitQueue('instapaper') | ||
45 | ; | ||
42 | } catch (\Exception $e) { | 46 | } catch (\Exception $e) { |
43 | $rabbitNotInstalled = true; | 47 | $rabbitNotInstalled = true; |
44 | } | 48 | } |
@@ -49,7 +53,11 @@ class ImportController extends Controller | |||
49 | $nbRedisMessages = $redis->llen('wallabag.import.pocket') | 53 | $nbRedisMessages = $redis->llen('wallabag.import.pocket') |
50 | + $redis->llen('wallabag.import.readability') | 54 | + $redis->llen('wallabag.import.readability') |
51 | + $redis->llen('wallabag.import.wallabag_v1') | 55 | + $redis->llen('wallabag.import.wallabag_v1') |
52 | + $redis->llen('wallabag.import.wallabag_v2'); | 56 | + $redis->llen('wallabag.import.wallabag_v2') |
57 | + $redis->llen('wallabag.import.firefox') | ||
58 | + $redis->llen('wallabag.import.chrome') | ||
59 | + $redis->llen('wallabag.import.instapaper') | ||
60 | ; | ||
53 | } catch (\Exception $e) { | 61 | } catch (\Exception $e) { |
54 | $redisNotInstalled = true; | 62 | $redisNotInstalled = true; |
55 | } | 63 | } |
diff --git a/src/Wallabag/ImportBundle/Controller/InstapaperController.php b/src/Wallabag/ImportBundle/Controller/InstapaperController.php new file mode 100644 index 00000000..c3fc8a39 --- /dev/null +++ b/src/Wallabag/ImportBundle/Controller/InstapaperController.php | |||
@@ -0,0 +1,77 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\ImportBundle\Controller; | ||
4 | |||
5 | use Symfony\Bundle\FrameworkBundle\Controller\Controller; | ||
6 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | ||
7 | use Symfony\Component\HttpFoundation\Request; | ||
8 | use Wallabag\ImportBundle\Form\Type\UploadImportType; | ||
9 | |||
10 | class InstapaperController extends Controller | ||
11 | { | ||
12 | /** | ||
13 | * @Route("/instapaper", name="import_instapaper") | ||
14 | */ | ||
15 | public function indexAction(Request $request) | ||
16 | { | ||
17 | $form = $this->createForm(UploadImportType::class); | ||
18 | $form->handleRequest($request); | ||
19 | |||
20 | $instapaper = $this->get('wallabag_import.instapaper.import'); | ||
21 | $instapaper->setUser($this->getUser()); | ||
22 | |||
23 | if ($this->get('craue_config')->get('import_with_rabbitmq')) { | ||
24 | $instapaper->setProducer($this->get('old_sound_rabbit_mq.import_instapaper_producer')); | ||
25 | } elseif ($this->get('craue_config')->get('import_with_redis')) { | ||
26 | $instapaper->setProducer($this->get('wallabag_import.producer.redis.instapaper')); | ||
27 | } | ||
28 | |||
29 | if ($form->isValid()) { | ||
30 | $file = $form->get('file')->getData(); | ||
31 | $markAsRead = $form->get('mark_as_read')->getData(); | ||
32 | $name = 'instapaper_'.$this->getUser()->getId().'.csv'; | ||
33 | |||
34 | if (null !== $file && in_array($file->getClientMimeType(), $this->getParameter('wallabag_import.allow_mimetypes')) && $file->move($this->getParameter('wallabag_import.resource_dir'), $name)) { | ||
35 | $res = $instapaper | ||
36 | ->setFilepath($this->getParameter('wallabag_import.resource_dir').'/'.$name) | ||
37 | ->setMarkAsRead($markAsRead) | ||
38 | ->import(); | ||
39 | |||
40 | $message = 'flashes.import.notice.failed'; | ||
41 | |||
42 | if (true === $res) { | ||
43 | $summary = $instapaper->getSummary(); | ||
44 | $message = $this->get('translator')->trans('flashes.import.notice.summary', [ | ||
45 | '%imported%' => $summary['imported'], | ||
46 | '%skipped%' => $summary['skipped'], | ||
47 | ]); | ||
48 | |||
49 | if (0 < $summary['queued']) { | ||
50 | $message = $this->get('translator')->trans('flashes.import.notice.summary_with_queue', [ | ||
51 | '%queued%' => $summary['queued'], | ||
52 | ]); | ||
53 | } | ||
54 | |||
55 | unlink($this->getParameter('wallabag_import.resource_dir').'/'.$name); | ||
56 | } | ||
57 | |||
58 | $this->get('session')->getFlashBag()->add( | ||
59 | 'notice', | ||
60 | $message | ||
61 | ); | ||
62 | |||
63 | return $this->redirect($this->generateUrl('homepage')); | ||
64 | } else { | ||
65 | $this->get('session')->getFlashBag()->add( | ||
66 | 'notice', | ||
67 | 'flashes.import.notice.failed_on_file' | ||
68 | ); | ||
69 | } | ||
70 | } | ||
71 | |||
72 | return $this->render('WallabagImportBundle:Instapaper:index.html.twig', [ | ||
73 | 'form' => $form->createView(), | ||
74 | 'import' => $instapaper, | ||
75 | ]); | ||
76 | } | ||
77 | } | ||
diff --git a/src/Wallabag/ImportBundle/Import/AbstractImport.php b/src/Wallabag/ImportBundle/Import/AbstractImport.php index a1a14576..764b390a 100644 --- a/src/Wallabag/ImportBundle/Import/AbstractImport.php +++ b/src/Wallabag/ImportBundle/Import/AbstractImport.php | |||
@@ -106,6 +106,10 @@ abstract class AbstractImport implements ImportInterface | |||
106 | $i = 1; | 106 | $i = 1; |
107 | 107 | ||
108 | foreach ($entries as $importedEntry) { | 108 | foreach ($entries as $importedEntry) { |
109 | if ($this->markAsRead) { | ||
110 | $importedEntry = $this->setEntryAsRead($importedEntry); | ||
111 | } | ||
112 | |||
109 | $entry = $this->parseEntry($importedEntry); | 113 | $entry = $this->parseEntry($importedEntry); |
110 | 114 | ||
111 | if (null === $entry) { | 115 | if (null === $entry) { |
diff --git a/src/Wallabag/ImportBundle/Import/InstapaperImport.php b/src/Wallabag/ImportBundle/Import/InstapaperImport.php new file mode 100644 index 00000000..356acf23 --- /dev/null +++ b/src/Wallabag/ImportBundle/Import/InstapaperImport.php | |||
@@ -0,0 +1,134 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\ImportBundle\Import; | ||
4 | |||
5 | use Wallabag\CoreBundle\Entity\Entry; | ||
6 | |||
7 | class InstapaperImport extends AbstractImport | ||
8 | { | ||
9 | private $filepath; | ||
10 | |||
11 | /** | ||
12 | * {@inheritdoc} | ||
13 | */ | ||
14 | public function getName() | ||
15 | { | ||
16 | return 'Instapaper'; | ||
17 | } | ||
18 | |||
19 | /** | ||
20 | * {@inheritdoc} | ||
21 | */ | ||
22 | public function getUrl() | ||
23 | { | ||
24 | return 'import_instapaper'; | ||
25 | } | ||
26 | |||
27 | /** | ||
28 | * {@inheritdoc} | ||
29 | */ | ||
30 | public function getDescription() | ||
31 | { | ||
32 | return 'import.instapaper.description'; | ||
33 | } | ||
34 | |||
35 | /** | ||
36 | * Set file path to the json file. | ||
37 | * | ||
38 | * @param string $filepath | ||
39 | */ | ||
40 | public function setFilepath($filepath) | ||
41 | { | ||
42 | $this->filepath = $filepath; | ||
43 | |||
44 | return $this; | ||
45 | } | ||
46 | |||
47 | /** | ||
48 | * {@inheritdoc} | ||
49 | */ | ||
50 | public function import() | ||
51 | { | ||
52 | if (!$this->user) { | ||
53 | $this->logger->error('InstapaperImport: user is not defined'); | ||
54 | |||
55 | return false; | ||
56 | } | ||
57 | |||
58 | if (!file_exists($this->filepath) || !is_readable($this->filepath)) { | ||
59 | $this->logger->error('InstapaperImport: unable to read file', ['filepath' => $this->filepath]); | ||
60 | |||
61 | return false; | ||
62 | } | ||
63 | |||
64 | $entries = []; | ||
65 | $handle = fopen($this->filepath, 'r'); | ||
66 | while (($data = fgetcsv($handle, 10240)) !== false) { | ||
67 | if ('URL' === $data[0]) { | ||
68 | continue; | ||
69 | } | ||
70 | |||
71 | $entries[] = [ | ||
72 | 'url' => $data[0], | ||
73 | 'title' => $data[1], | ||
74 | 'status' => $data[3], | ||
75 | 'is_archived' => $data[3] === 'Archive' || $data[3] === 'Starred', | ||
76 | 'is_starred' => $data[3] === 'Starred', | ||
77 | 'content_type' => '', | ||
78 | 'language' => '', | ||
79 | ]; | ||
80 | } | ||
81 | fclose($handle); | ||
82 | |||
83 | if ($this->producer) { | ||
84 | $this->parseEntriesForProducer($entries); | ||
85 | |||
86 | return true; | ||
87 | } | ||
88 | |||
89 | $this->parseEntries($entries); | ||
90 | |||
91 | return true; | ||
92 | } | ||
93 | |||
94 | /** | ||
95 | * {@inheritdoc} | ||
96 | */ | ||
97 | public function parseEntry(array $importedEntry) | ||
98 | { | ||
99 | $existingEntry = $this->em | ||
100 | ->getRepository('WallabagCoreBundle:Entry') | ||
101 | ->findByUrlAndUserId($importedEntry['url'], $this->user->getId()); | ||
102 | |||
103 | if (false !== $existingEntry) { | ||
104 | ++$this->skippedEntries; | ||
105 | |||
106 | return; | ||
107 | } | ||
108 | |||
109 | $entry = new Entry($this->user); | ||
110 | $entry->setUrl($importedEntry['url']); | ||
111 | $entry->setTitle($importedEntry['title']); | ||
112 | |||
113 | // update entry with content (in case fetching failed, the given entry will be return) | ||
114 | $entry = $this->fetchContent($entry, $importedEntry['url'], $importedEntry); | ||
115 | |||
116 | $entry->setArchived($importedEntry['is_archived']); | ||
117 | $entry->setStarred($importedEntry['is_starred']); | ||
118 | |||
119 | $this->em->persist($entry); | ||
120 | ++$this->importedEntries; | ||
121 | |||
122 | return $entry; | ||
123 | } | ||
124 | |||
125 | /** | ||
126 | * {@inheritdoc} | ||
127 | */ | ||
128 | protected function setEntryAsRead(array $importedEntry) | ||
129 | { | ||
130 | $importedEntry['is_archived'] = 1; | ||
131 | |||
132 | return $importedEntry; | ||
133 | } | ||
134 | } | ||
diff --git a/src/Wallabag/ImportBundle/Resources/config/rabbit.yml b/src/Wallabag/ImportBundle/Resources/config/rabbit.yml index 6ada6302..70b8a0d4 100644 --- a/src/Wallabag/ImportBundle/Resources/config/rabbit.yml +++ b/src/Wallabag/ImportBundle/Resources/config/rabbit.yml | |||
@@ -14,6 +14,13 @@ services: | |||
14 | - "@wallabag_user.user_repository" | 14 | - "@wallabag_user.user_repository" |
15 | - "@wallabag_import.readability.import" | 15 | - "@wallabag_import.readability.import" |
16 | - "@logger" | 16 | - "@logger" |
17 | wallabag_import.consumer.amqp.instapaper: | ||
18 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer | ||
19 | arguments: | ||
20 | - "@doctrine.orm.entity_manager" | ||
21 | - "@wallabag_user.user_repository" | ||
22 | - "@wallabag_import.instapaper.import" | ||
23 | - "@logger" | ||
17 | wallabag_import.consumer.amqp.wallabag_v1: | 24 | wallabag_import.consumer.amqp.wallabag_v1: |
18 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer | 25 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer |
19 | arguments: | 26 | arguments: |
diff --git a/src/Wallabag/ImportBundle/Resources/config/redis.yml b/src/Wallabag/ImportBundle/Resources/config/redis.yml index c9c2cf26..0a81e1b5 100644 --- a/src/Wallabag/ImportBundle/Resources/config/redis.yml +++ b/src/Wallabag/ImportBundle/Resources/config/redis.yml | |||
@@ -20,6 +20,26 @@ services: | |||
20 | - "@wallabag_import.readability.import" | 20 | - "@wallabag_import.readability.import" |
21 | - "@logger" | 21 | - "@logger" |
22 | 22 | ||
23 | # instapaper | ||
24 | wallabag_import.queue.redis.instapaper: | ||
25 | class: Simpleue\Queue\RedisQueue | ||
26 | arguments: | ||
27 | - "@wallabag_core.redis.client" | ||
28 | - "wallabag.import.instapaper" | ||
29 | |||
30 | wallabag_import.producer.redis.instapaper: | ||
31 | class: Wallabag\ImportBundle\Redis\Producer | ||
32 | arguments: | ||
33 | - "@wallabag_import.queue.redis.instapaper" | ||
34 | |||
35 | wallabag_import.consumer.redis.instapaper: | ||
36 | class: Wallabag\ImportBundle\Consumer\RedisEntryConsumer | ||
37 | arguments: | ||
38 | - "@doctrine.orm.entity_manager" | ||
39 | - "@wallabag_user.user_repository" | ||
40 | - "@wallabag_import.instapaper.import" | ||
41 | - "@logger" | ||
42 | |||
23 | 43 | ||
24 | wallabag_import.queue.redis.pocket: | 44 | wallabag_import.queue.redis.pocket: |
25 | class: Simpleue\Queue\RedisQueue | 45 | class: Simpleue\Queue\RedisQueue |
diff --git a/src/Wallabag/ImportBundle/Resources/config/services.yml b/src/Wallabag/ImportBundle/Resources/config/services.yml index 990f336d..89adc71b 100644 --- a/src/Wallabag/ImportBundle/Resources/config/services.yml +++ b/src/Wallabag/ImportBundle/Resources/config/services.yml | |||
@@ -57,6 +57,16 @@ services: | |||
57 | tags: | 57 | tags: |
58 | - { name: wallabag_import.import, alias: readability } | 58 | - { name: wallabag_import.import, alias: readability } |
59 | 59 | ||
60 | wallabag_import.instapaper.import: | ||
61 | class: Wallabag\ImportBundle\Import\InstapaperImport | ||
62 | arguments: | ||
63 | - "@doctrine.orm.entity_manager" | ||
64 | - "@wallabag_core.content_proxy" | ||
65 | calls: | ||
66 | - [ setLogger, [ "@logger" ]] | ||
67 | tags: | ||
68 | - { name: wallabag_import.import, alias: instapaper } | ||
69 | |||
60 | wallabag_import.firefox.import: | 70 | wallabag_import.firefox.import: |
61 | class: Wallabag\ImportBundle\Import\FirefoxImport | 71 | class: Wallabag\ImportBundle\Import\FirefoxImport |
62 | arguments: | 72 | arguments: |
diff --git a/src/Wallabag/ImportBundle/Resources/views/Instapaper/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Instapaper/index.html.twig new file mode 100644 index 00000000..5789361f --- /dev/null +++ b/src/Wallabag/ImportBundle/Resources/views/Instapaper/index.html.twig | |||
@@ -0,0 +1,45 @@ | |||
1 | {% extends "WallabagCoreBundle::layout.html.twig" %} | ||
2 | |||
3 | {% block title %}{{ 'import.instapaper.page_title'|trans }}{% endblock %} | ||
4 | |||
5 | {% block content %} | ||
6 | <div class="row"> | ||
7 | <div class="col s12"> | ||
8 | <div class="card-panel settings"> | ||
9 | {% include 'WallabagImportBundle:Import:_workerEnabled.html.twig' %} | ||
10 | |||
11 | <div class="row"> | ||
12 | <blockquote>{{ import.description|trans }}</blockquote> | ||
13 | <p>{{ 'import.instapaper.how_to'|trans }}</p> | ||
14 | |||
15 | <div class="col s12"> | ||
16 | {{ form_start(form, {'method': 'POST'}) }} | ||
17 | {{ form_errors(form) }} | ||
18 | <div class="row"> | ||
19 | <div class="file-field input-field col s12"> | ||
20 | {{ form_errors(form.file) }} | ||
21 | <div class="btn"> | ||
22 | <span>{{ form.file.vars.label|trans }}</span> | ||
23 | {{ form_widget(form.file) }} | ||
24 | </div> | ||
25 | <div class="file-path-wrapper"> | ||
26 | <input class="file-path validate" type="text"> | ||
27 | </div> | ||
28 | </div> | ||
29 | <div class="input-field col s6 with-checkbox"> | ||
30 | <h6>{{ 'import.form.mark_as_read_title'|trans }}</h6> | ||
31 | {{ form_widget(form.mark_as_read) }} | ||
32 | {{ form_label(form.mark_as_read) }} | ||
33 | </div> | ||
34 | </div> | ||
35 | |||
36 | {{ form_widget(form.save, { 'attr': {'class': 'btn waves-effect waves-light'} }) }} | ||
37 | |||
38 | {{ form_rest(form) }} | ||
39 | </form> | ||
40 | </div> | ||
41 | </div> | ||
42 | </div> | ||
43 | </div> | ||
44 | </div> | ||
45 | {% endblock %} | ||
diff --git a/tests/Wallabag/ImportBundle/Controller/ImportControllerTest.php b/tests/Wallabag/ImportBundle/Controller/ImportControllerTest.php index b6783a56..0bc40bdd 100644 --- a/tests/Wallabag/ImportBundle/Controller/ImportControllerTest.php +++ b/tests/Wallabag/ImportBundle/Controller/ImportControllerTest.php | |||
@@ -24,6 +24,6 @@ class ImportControllerTest extends WallabagCoreTestCase | |||
24 | $crawler = $client->request('GET', '/import/'); | 24 | $crawler = $client->request('GET', '/import/'); |
25 | 25 | ||
26 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | 26 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); |
27 | $this->assertEquals(6, $crawler->filter('blockquote')->count()); | 27 | $this->assertEquals(7, $crawler->filter('blockquote')->count()); |
28 | } | 28 | } |
29 | } | 29 | } |
diff --git a/tests/Wallabag/ImportBundle/Import/InstapaperImportTest.php b/tests/Wallabag/ImportBundle/Import/InstapaperImportTest.php new file mode 100644 index 00000000..75900bd7 --- /dev/null +++ b/tests/Wallabag/ImportBundle/Import/InstapaperImportTest.php | |||
@@ -0,0 +1,233 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Tests\Wallabag\ImportBundle\Import; | ||
4 | |||
5 | use Wallabag\ImportBundle\Import\InstapaperImport; | ||
6 | use Wallabag\UserBundle\Entity\User; | ||
7 | use Wallabag\CoreBundle\Entity\Entry; | ||
8 | use Wallabag\ImportBundle\Redis\Producer; | ||
9 | use Monolog\Logger; | ||
10 | use Monolog\Handler\TestHandler; | ||
11 | use Simpleue\Queue\RedisQueue; | ||
12 | use M6Web\Component\RedisMock\RedisMockFactory; | ||
13 | |||
14 | class InstapaperImportTest extends \PHPUnit_Framework_TestCase | ||
15 | { | ||
16 | protected $user; | ||
17 | protected $em; | ||
18 | protected $logHandler; | ||
19 | protected $contentProxy; | ||
20 | |||
21 | private function getInstapaperImport($unsetUser = false) | ||
22 | { | ||
23 | $this->user = new User(); | ||
24 | |||
25 | $this->em = $this->getMockBuilder('Doctrine\ORM\EntityManager') | ||
26 | ->disableOriginalConstructor() | ||
27 | ->getMock(); | ||
28 | |||
29 | $this->contentProxy = $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy') | ||
30 | ->disableOriginalConstructor() | ||
31 | ->getMock(); | ||
32 | |||
33 | $import = new InstapaperImport($this->em, $this->contentProxy); | ||
34 | |||
35 | $this->logHandler = new TestHandler(); | ||
36 | $logger = new Logger('test', [$this->logHandler]); | ||
37 | $import->setLogger($logger); | ||
38 | |||
39 | if (false === $unsetUser) { | ||
40 | $import->setUser($this->user); | ||
41 | } | ||
42 | |||
43 | return $import; | ||
44 | } | ||
45 | |||
46 | public function testInit() | ||
47 | { | ||
48 | $instapaperImport = $this->getInstapaperImport(); | ||
49 | |||
50 | $this->assertEquals('Instapaper', $instapaperImport->getName()); | ||
51 | $this->assertNotEmpty($instapaperImport->getUrl()); | ||
52 | $this->assertEquals('import.instapaper.description', $instapaperImport->getDescription()); | ||
53 | } | ||
54 | |||
55 | public function testImport() | ||
56 | { | ||
57 | $instapaperImport = $this->getInstapaperImport(); | ||
58 | $instapaperImport->setFilepath(__DIR__.'/../fixtures/instapaper-export.csv'); | ||
59 | |||
60 | $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') | ||
61 | ->disableOriginalConstructor() | ||
62 | ->getMock(); | ||
63 | |||
64 | $entryRepo->expects($this->exactly(3)) | ||
65 | ->method('findByUrlAndUserId') | ||
66 | ->willReturn(false); | ||
67 | |||
68 | $this->em | ||
69 | ->expects($this->any()) | ||
70 | ->method('getRepository') | ||
71 | ->willReturn($entryRepo); | ||
72 | |||
73 | $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') | ||
74 | ->disableOriginalConstructor() | ||
75 | ->getMock(); | ||
76 | |||
77 | $this->contentProxy | ||
78 | ->expects($this->exactly(3)) | ||
79 | ->method('updateEntry') | ||
80 | ->willReturn($entry); | ||
81 | |||
82 | $res = $instapaperImport->import(); | ||
83 | |||
84 | $this->assertTrue($res); | ||
85 | $this->assertEquals(['skipped' => 0, 'imported' => 3, 'queued' => 0], $instapaperImport->getSummary()); | ||
86 | } | ||
87 | |||
88 | public function testImportAndMarkAllAsRead() | ||
89 | { | ||
90 | $instapaperImport = $this->getInstapaperImport(); | ||
91 | $instapaperImport->setFilepath(__DIR__.'/../fixtures/instapaper-export.csv'); | ||
92 | |||
93 | $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') | ||
94 | ->disableOriginalConstructor() | ||
95 | ->getMock(); | ||
96 | |||
97 | $entryRepo->expects($this->exactly(3)) | ||
98 | ->method('findByUrlAndUserId') | ||
99 | ->will($this->onConsecutiveCalls(false, true, true)); | ||
100 | |||
101 | $this->em | ||
102 | ->expects($this->any()) | ||
103 | ->method('getRepository') | ||
104 | ->willReturn($entryRepo); | ||
105 | |||
106 | $this->contentProxy | ||
107 | ->expects($this->once()) | ||
108 | ->method('updateEntry') | ||
109 | ->willReturn(new Entry($this->user)); | ||
110 | |||
111 | // check that every entry persisted are archived | ||
112 | $this->em | ||
113 | ->expects($this->once()) | ||
114 | ->method('persist') | ||
115 | ->with($this->callback(function ($persistedEntry) { | ||
116 | return $persistedEntry->isArchived(); | ||
117 | })); | ||
118 | |||
119 | $res = $instapaperImport->setMarkAsRead(true)->import(); | ||
120 | |||
121 | $this->assertTrue($res); | ||
122 | |||
123 | $this->assertEquals(['skipped' => 2, 'imported' => 1, 'queued' => 0], $instapaperImport->getSummary()); | ||
124 | } | ||
125 | |||
126 | public function testImportWithRabbit() | ||
127 | { | ||
128 | $instapaperImport = $this->getInstapaperImport(); | ||
129 | $instapaperImport->setFilepath(__DIR__.'/../fixtures/instapaper-export.csv'); | ||
130 | |||
131 | $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') | ||
132 | ->disableOriginalConstructor() | ||
133 | ->getMock(); | ||
134 | |||
135 | $entryRepo->expects($this->never()) | ||
136 | ->method('findByUrlAndUserId'); | ||
137 | |||
138 | $this->em | ||
139 | ->expects($this->never()) | ||
140 | ->method('getRepository'); | ||
141 | |||
142 | $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') | ||
143 | ->disableOriginalConstructor() | ||
144 | ->getMock(); | ||
145 | |||
146 | $this->contentProxy | ||
147 | ->expects($this->never()) | ||
148 | ->method('updateEntry'); | ||
149 | |||
150 | $producer = $this->getMockBuilder('OldSound\RabbitMqBundle\RabbitMq\Producer') | ||
151 | ->disableOriginalConstructor() | ||
152 | ->getMock(); | ||
153 | |||
154 | $producer | ||
155 | ->expects($this->exactly(3)) | ||
156 | ->method('publish'); | ||
157 | |||
158 | $instapaperImport->setProducer($producer); | ||
159 | |||
160 | $res = $instapaperImport->setMarkAsRead(true)->import(); | ||
161 | |||
162 | $this->assertTrue($res); | ||
163 | $this->assertEquals(['skipped' => 0, 'imported' => 0, 'queued' => 3], $instapaperImport->getSummary()); | ||
164 | } | ||
165 | |||
166 | public function testImportWithRedis() | ||
167 | { | ||
168 | $instapaperImport = $this->getInstapaperImport(); | ||
169 | $instapaperImport->setFilepath(__DIR__.'/../fixtures/instapaper-export.csv'); | ||
170 | |||
171 | $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') | ||
172 | ->disableOriginalConstructor() | ||
173 | ->getMock(); | ||
174 | |||
175 | $entryRepo->expects($this->never()) | ||
176 | ->method('findByUrlAndUserId'); | ||
177 | |||
178 | $this->em | ||
179 | ->expects($this->never()) | ||
180 | ->method('getRepository'); | ||
181 | |||
182 | $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') | ||
183 | ->disableOriginalConstructor() | ||
184 | ->getMock(); | ||
185 | |||
186 | $this->contentProxy | ||
187 | ->expects($this->never()) | ||
188 | ->method('updateEntry'); | ||
189 | |||
190 | $factory = new RedisMockFactory(); | ||
191 | $redisMock = $factory->getAdapter('Predis\Client', true); | ||
192 | |||
193 | $queue = new RedisQueue($redisMock, 'instapaper'); | ||
194 | $producer = new Producer($queue); | ||
195 | |||
196 | $instapaperImport->setProducer($producer); | ||
197 | |||
198 | $res = $instapaperImport->setMarkAsRead(true)->import(); | ||
199 | |||
200 | $this->assertTrue($res); | ||
201 | $this->assertEquals(['skipped' => 0, 'imported' => 0, 'queued' => 3], $instapaperImport->getSummary()); | ||
202 | |||
203 | $this->assertNotEmpty($redisMock->lpop('instapaper')); | ||
204 | } | ||
205 | |||
206 | public function testImportBadFile() | ||
207 | { | ||
208 | $instapaperImport = $this->getInstapaperImport(); | ||
209 | $instapaperImport->setFilepath(__DIR__.'/../fixtures/wallabag-v1.jsonx'); | ||
210 | |||
211 | $res = $instapaperImport->import(); | ||
212 | |||
213 | $this->assertFalse($res); | ||
214 | |||
215 | $records = $this->logHandler->getRecords(); | ||
216 | $this->assertContains('InstapaperImport: unable to read file', $records[0]['message']); | ||
217 | $this->assertEquals('ERROR', $records[0]['level_name']); | ||
218 | } | ||
219 | |||
220 | public function testImportUserNotDefined() | ||
221 | { | ||
222 | $instapaperImport = $this->getInstapaperImport(true); | ||
223 | $instapaperImport->setFilepath(__DIR__.'/../fixtures/instapaper-export.csv'); | ||
224 | |||
225 | $res = $instapaperImport->import(); | ||
226 | |||
227 | $this->assertFalse($res); | ||
228 | |||
229 | $records = $this->logHandler->getRecords(); | ||
230 | $this->assertContains('InstapaperImport: user is not defined', $records[0]['message']); | ||
231 | $this->assertEquals('ERROR', $records[0]['level_name']); | ||
232 | } | ||
233 | } | ||
diff --git a/tests/Wallabag/ImportBundle/fixtures/instapaper-export.csv b/tests/Wallabag/ImportBundle/fixtures/instapaper-export.csv new file mode 100644 index 00000000..28a4c8e6 --- /dev/null +++ b/tests/Wallabag/ImportBundle/fixtures/instapaper-export.csv | |||
@@ -0,0 +1,4 @@ | |||
1 | URL,Title,Selection,Folder | ||
2 | http://www.liberation.fr/societe/2012/12/06/baumettes-un-tour-en-cellule_865551,Baumettes : un tour en cellule,,Unread | ||
3 | https://redditblog.com/2016/09/20/amp-and-reactredux/,AMP and React+Redux: Why Not?,,Archive | ||
4 | https://medium.com/@the_minh/why-foursquare-swarm-is-still-my-favourite-social-network-e38228493e6c,Why Foursquare / Swarm is still my favourite social network,,Starred | ||