1
0
Fork 0
mirror of https://github.com/wallabag/wallabag.git synced 2025-08-01 17:38:38 +00:00

Add Delicious import

Since 2021, you can export again your data \o/

Also fix indentation in json fixtures files.
This commit is contained in:
Jeremy Benoist 2021-02-08 09:08:12 +01:00
parent 890c7d0bfa
commit dd9d6a4c64
No known key found for this signature in database
GPG key ID: BCA73962457ACC3C
23 changed files with 984 additions and 370 deletions

View file

@ -0,0 +1,199 @@
<?php
namespace Tests\Wallabag\ImportBundle\Controller;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
class DeliciousControllerTest extends WallabagCoreTestCase
{
public function testImportDelicious()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/import/delicious');
$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 testImportDeliciousWithRabbitEnabled()
{
$this->logInAs('admin');
$client = $this->getClient();
$client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 1);
$crawler = $client->request('GET', '/import/delicious');
$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('craue_config')->set('import_with_rabbitmq', 0);
}
public function testImportDeliciousBadFile()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/import/delicious');
$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 testImportDeliciousWithRedisEnabled()
{
$this->checkRedis();
$this->logInAs('admin');
$client = $this->getClient();
$client->getContainer()->get('craue_config')->set('import_with_redis', 1);
$crawler = $client->request('GET', '/import/delicious');
$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/delicious_export.2021.02.06_21.10.json', 'delicious.json');
$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('wallabag_core.redis.client')->lpop('wallabag.import.delicious'));
$client->getContainer()->get('craue_config')->set('import_with_redis', 0);
}
public function testImportDeliciousWithFile()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/import/delicious');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../fixtures/delicious_export.2021.02.06_21.10.json', 'delicious.json');
$data = [
'upload_import_file[file]' => $file,
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$content = $client->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('WallabagCoreBundle:Entry')
->findByUrlAndUserId(
'https://feross.org/spoofmac/',
$this->getLoggedInUserId()
);
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
$this->assertStringContainsString('flashes.import.notice.summary', $body[0]);
$this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content);
$tags = $content->getTags();
$this->assertContains('osx', $tags, 'It includes the "osx" tag');
$this->assertGreaterThanOrEqual(4, count($tags));
$this->assertInstanceOf(\DateTime::class, $content->getCreatedAt());
$this->assertSame('2013-01-17', $content->getCreatedAt()->format('Y-m-d'));
}
public function testImportDeliciousWithFileAndMarkAllAsRead()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/import/delicious');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../fixtures/delicious_export.2021.02.06_21.10.json', 'delicious-read.json');
$data = [
'upload_import_file[file]' => $file,
'upload_import_file[mark_as_read]' => 1,
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$content1 = $client->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('WallabagCoreBundle:Entry')
->findByUrlAndUserId(
'https://stackoverflow.com/review/',
$this->getLoggedInUserId()
);
$this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content1);
$content2 = $client->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('WallabagCoreBundle:Entry')
->findByUrlAndUserId(
'https://addyosmani.com/basket.js/',
$this->getLoggedInUserId()
);
$this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content2);
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
$this->assertStringContainsString('flashes.import.notice.summary', $body[0]);
}
public function testImportDeliciousWithEmptyFile()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/import/delicious');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../fixtures/test.txt', 'test.txt');
$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]);
}
}

View file

@ -1,36 +1,38 @@
{
"checksum": "f3aa0e9c0edad632a246f7e98ec64918",
"roots": {
"bookmark_bar": {
"children": [ {
"date_added": "13118850929335823",
"id": "6",
"name": "\"La multiplication des chefs de projet est une catastrophe managériale majeure\", affirme le sociologue François Dupuy - Ressources humaines",
"type": "url",
"url": "http://www.usinenouvelle.com/article/la-multiplication-des-chefs-de-projet-est-une-catastrophe-manageriale-majeure-affirme-le-sociologue-francois-dupuy.N307730"
} ],
"date_added": "13118829474385693",
"date_modified": "13118850929335823",
"id": "1",
"name": "Barre de favoris",
"type": "folder"
},
"other": {
"children": [ ],
"date_added": "13118829474385701",
"date_modified": "0",
"id": "2",
"name": "Autres favoris",
"type": "folder"
},
"synced": {
"children": [ ],
"date_added": "13118829474385702",
"date_modified": "0",
"id": "3",
"name": "Favoris sur mobile",
"type": "folder"
}
},
"version": 1
"checksum": "f3aa0e9c0edad632a246f7e98ec64918",
"roots": {
"bookmark_bar": {
"children": [
{
"date_added": "13118850929335823",
"id": "6",
"name": "\"La multiplication des chefs de projet est une catastrophe managériale majeure\", affirme le sociologue François Dupuy - Ressources humaines",
"type": "url",
"url": "http://www.usinenouvelle.com/article/la-multiplication-des-chefs-de-projet-est-une-catastrophe-manageriale-majeure-affirme-le-sociologue-francois-dupuy.N307730"
}
],
"date_added": "13118829474385693",
"date_modified": "13118850929335823",
"id": "1",
"name": "Barre de favoris",
"type": "folder"
},
"other": {
"children": [],
"date_added": "13118829474385701",
"date_modified": "0",
"id": "2",
"name": "Autres favoris",
"type": "folder"
},
"synced": {
"children": [],
"date_added": "13118829474385702",
"date_modified": "0",
"id": "3",
"name": "Favoris sur mobile",
"type": "folder"
}
},
"version": 1
}

View file

@ -0,0 +1,44 @@
[
{
"title": "basket.js - a simple script loader that caches scripts with localStorage",
"tags": [
"basket",
"javascript",
"loader",
"localStorage"
],
"url": "https://addyosmani.com/basket.js/",
"description": "\"A simple (proof-of-concept) script loader that caches scripts with localStorage\"",
"created": "1358531607",
"others": 9,
"owner": "maciej",
"private": "0"
},
{
"title": "Review - Stack Overflow",
"tags": [
""
],
"url": "https://stackoverflow.com/review/",
"description": "",
"created": "1358457437",
"others": 84,
"owner": "maciej",
"private": "0"
},
{
"title": "Announcing SpoofMAC - Spoof your MAC address in Mac OS X",
"tags": [
"MAC_address",
"osx",
"mac",
"spoof"
],
"url": "https://feross.org/spoofmac/",
"description": "",
"created": "1358425796",
"others": 6,
"owner": "maciej",
"private": "0"
}
]

View file

@ -1,13 +1,13 @@
[
{
"created_at": "2015-09-09 11:10:32 UTC",
"title": "Qualité de code - Intégration de php-git-hooks dans Symfony2 - Experts Symfony et Drupal - Lexik",
"url": "https://devblog.lexik.fr/git/qualite-de-code-integration-de-php-git-hooks-dans-symfony2-2842",
"description": null,
"tags": [
"tag1",
"tag2"
],
"is_saved": true
}
{
"created_at": "2015-09-09 11:10:32 UTC",
"title": "Qualité de code - Intégration de php-git-hooks dans Symfony2 - Experts Symfony et Drupal - Lexik",
"url": "https://devblog.lexik.fr/git/qualite-de-code-integration-de-php-git-hooks-dans-symfony2-2842",
"description": null,
"tags": [
"tag1",
"tag2"
],
"is_saved": true
}
]

View file

@ -1,63 +1,63 @@
{
"guid": "root________",
"title": "",
"index": 0,
"dateAdded": 1388166091504000,
"lastModified": 1472897622350000,
"id": 1,
"type": "text/x-moz-place-container",
"root": "placesRoot",
"children": [
"guid": "root________",
"title": "",
"index": 0,
"dateAdded": 1388166091504000,
"lastModified": 1472897622350000,
"id": 1,
"type": "text/x-moz-place-container",
"root": "placesRoot",
"children": [
{
"guid": "toolbar_____",
"title": "Barre personnelle",
"index": 1,
"dateAdded": 1388166091504000,
"lastModified": 1472897622263000,
"id": 3,
"annos": [
{
"guid": "toolbar_____",
"title": "Barre personnelle",
"index": 1,
"dateAdded": 1388166091504000,
"lastModified": 1472897622263000,
"id": 3,
"annos": [
{
"name": "bookmarkProperties/description",
"flags": 0,
"expires": 4,
"value": "Ajoutez des marque-pages dans ce dossier pour les voir apparaître sur votre barre personnelle"
}
],
"type": "text/x-moz-place-container",
"root": "toolbarFolder",
"children": [
{
"guid": "tard77lzbC5H",
"title": "Orange offre un meilleur réseau mobile que Bouygues et SFR, Free derrière - L'Express L'Expansion",
"index": 1,
"dateAdded": 1388166091644000,
"lastModified": 1388166091644000,
"tags":"test,tag",
"id": 4,
"type": "text/x-moz-place",
"uri": "http://lexpansion.lexpress.fr/high-tech/orange-offre-un-meilleur-reseau-mobile-que-bouygues-et-sfr-free-derriere_1811554.html"
},
{
"guid": "E385l9vZ_LVn",
"title": "Le journaliste et cinéaste Claude Lanzmann est mort",
"index": 1,
"dateAdded": 1388166091544000,
"lastModified": 1388166091545000,
"id": 5,
"type": "text/x-moz-place",
"uri": "https://www.lemonde.fr/disparitions/article/2018/07/05/le-journaliste-et-cineaste-claude-lanzmann-est-mort_5326313_3382.html"
}
]
"name": "bookmarkProperties/description",
"flags": 0,
"expires": 4,
"value": "Ajoutez des marque-pages dans ce dossier pour les voir apparaître sur votre barre personnelle"
}
],
"type": "text/x-moz-place-container",
"root": "toolbarFolder",
"children": [
{
"guid": "tard77lzbC5H",
"title": "Orange offre un meilleur réseau mobile que Bouygues et SFR, Free derrière - L'Express L'Expansion",
"index": 1,
"dateAdded": 1388166091644000,
"lastModified": 1388166091644000,
"tags": "test,tag",
"id": 4,
"type": "text/x-moz-place",
"uri": "http://lexpansion.lexpress.fr/high-tech/orange-offre-un-meilleur-reseau-mobile-que-bouygues-et-sfr-free-derriere_1811554.html"
},
{
"guid": "unfiled_____",
"title": "Autres marque-pages",
"index": 3,
"dateAdded": 1388166091504000,
"lastModified": 1388166091542000,
"id": 6,
"type": "text/x-moz-place-container",
"root": "unfiledBookmarksFolder"
"guid": "E385l9vZ_LVn",
"title": "Le journaliste et cinéaste Claude Lanzmann est mort",
"index": 1,
"dateAdded": 1388166091544000,
"lastModified": 1388166091545000,
"id": 5,
"type": "text/x-moz-place",
"uri": "https://www.lemonde.fr/disparitions/article/2018/07/05/le-journaliste-et-cineaste-claude-lanzmann-est-mort_5326313_3382.html"
}
]
]
},
{
"guid": "unfiled_____",
"title": "Autres marque-pages",
"index": 3,
"dateAdded": 1388166091504000,
"lastModified": 1388166091542000,
"id": 6,
"type": "text/x-moz-place-container",
"root": "unfiledBookmarksFolder"
}
]
}

View file

@ -1,3 +1,35 @@
[{"href":"https:\/\/developers.google.com\/web\/updates\/2016\/07\/infinite-scroller","description":"Complexities of an Infinite Scroller","extended":"TL;DR: Re-use your DOM elements and remove the ones that are far away from the viewport. Use placeholders to account for delayed data","meta":"21ff61c6f648901168f9e6119f53df7d","hash":"e69b65724cca1c585b446d4c47865d76","time":"2016-10-31T15:57:56Z","shared":"yes","toread":"no","tags":"infinite dom performance scroll"},
{"href":"https:\/\/ma.ttias.be\/varnish-explained\/","description":"Varnish (explained) for PHP developers","extended":"A few months ago, I gave a presentation at LaraconEU in Amsterdam titled \"Varnish for PHP developers\". The generic title of that presentation is actually Varnish Explained and this is a write-up of that presentation, the video and the slides.","meta":"d32ad9fac2ed29da4aec12c562e9afb1","hash":"21dd6bdda8ad62666a2c9e79f6e80f98","time":"2016-10-26T06:43:03Z","shared":"yes","toread":"no","tags":"varnish PHP"},
{"href":"https:\/\/ilia.ws\/files\/nginx_torontophpug.pdf","description":"Nginx Tricks for PHP Developers","extended":"","meta":"9adbb5c4ca6760e335b920800d88c70a","hash":"0189bb08f8bd0122c6544bed4624c546","time":"2016-10-05T07:11:27Z","shared":"yes","toread":"no","tags":"nginx PHP best_practice"}]
[
{
"href": "https://developers.google.com/web/updates/2016/07/infinite-scroller",
"description": "Complexities of an Infinite Scroller",
"extended": "TL;DR: Re-use your DOM elements and remove the ones that are far away from the viewport. Use placeholders to account for delayed data",
"meta": "21ff61c6f648901168f9e6119f53df7d",
"hash": "e69b65724cca1c585b446d4c47865d76",
"time": "2016-10-31T15:57:56Z",
"shared": "yes",
"toread": "no",
"tags": "infinite dom performance scroll"
},
{
"href": "https://ma.ttias.be/varnish-explained/",
"description": "Varnish (explained) for PHP developers",
"extended": "A few months ago, I gave a presentation at LaraconEU in Amsterdam titled \"Varnish for PHP developers\". The generic title of that presentation is actually Varnish Explained and this is a write-up of that presentation, the video and the slides.",
"meta": "d32ad9fac2ed29da4aec12c562e9afb1",
"hash": "21dd6bdda8ad62666a2c9e79f6e80f98",
"time": "2016-10-26T06:43:03Z",
"shared": "yes",
"toread": "no",
"tags": "varnish PHP"
},
{
"href": "https://ilia.ws/files/nginx_torontophpug.pdf",
"description": "Nginx Tricks for PHP Developers",
"extended": "",
"meta": "9adbb5c4ca6760e335b920800d88c70a",
"hash": "0189bb08f8bd0122c6544bed4624c546",
"time": "2016-10-05T07:11:27Z",
"shared": "yes",
"toread": "no",
"tags": "nginx PHP best_practice"
}
]

View file

@ -1,25 +1,25 @@
{
"bookmarks": [
{
"article__excerpt": "This is a guest post from Moritz Beller from the Delft University of Technology in The Netherlands. His team produced amazing research on several million Travis CI builds, creating invaluable&hellip;",
"favorite": false,
"date_archived": "2016-08-02T06:49:30",
"article__url": "https://blog.travis-ci.com/2016-07-28-what-we-learned-from-analyzing-2-million-travis-builds/",
"date_added": "2016-08-01T05:24:16",
"date_favorited": null,
"article__title": "Travis",
"archive": true
},
{
"article__excerpt": "The GraphQL Type system describes the capabilities of a GraphQL server and is used to determine if a query is valid. The type system also describes the input types of query variables to determine if&hellip;",
"favorite": false,
"date_archived": "2016-07-19T06:48:31",
"article__url": "https://facebook.github.io/graphql/October2016/",
"date_added": "2016-06-24T17:50:16",
"date_favorited": null,
"article__title": "GraphQL",
"archive": true
}
],
"recommendations": []
"bookmarks": [
{
"article__excerpt": "This is a guest post from Moritz Beller from the Delft University of Technology in The Netherlands. His team produced amazing research on several million Travis CI builds, creating invaluable&hellip;",
"favorite": false,
"date_archived": "2016-08-02T06:49:30",
"article__url": "https://blog.travis-ci.com/2016-07-28-what-we-learned-from-analyzing-2-million-travis-builds/",
"date_added": "2016-08-01T05:24:16",
"date_favorited": null,
"article__title": "Travis",
"archive": true
},
{
"article__excerpt": "The GraphQL Type system describes the capabilities of a GraphQL server and is used to determine if a query is valid. The type system also describes the input types of query variables to determine if&hellip;",
"favorite": false,
"date_archived": "2016-07-19T06:48:31",
"article__url": "https://facebook.github.io/graphql/October2016/",
"date_added": "2016-06-24T17:50:16",
"date_favorited": null,
"article__title": "GraphQL",
"archive": true
}
],
"recommendations": []
}

View file

@ -1,29 +1,29 @@
{
"bookmarks": [
{
"article__excerpt": "When Twitter started it had so much promise to change the way we communicate. But now it has been ruined by the amount of garbage and hate we have to wade through. It&#x2019;s like that polluted&hellip;",
"favorite": false,
"date_archived": null,
"article__url": "https://venngage.com/blog/hashtags-are-worthless/",
"date_added": "2016-08-25T12:05:00",
"date_favorited": null,
"article__title": "We Looked At 167,943 Tweets & Found Out Hashtags Are Worthless",
"archive": false
},
{
"article__title": "No title found",
"article__url": "http://news.nationalgeographic.com/2016/02/160211-albatrosses-mothers-babies-animals-science/&sf20739758=1",
"archive": false,
"date_added": "2016-09-08T11:55:58+0200",
"favorite": true
},
{
"archive": 0,
"date_added": "2016-09-08T11:55:58+0200",
"favorite": 0,
"article__title": "Bordeaux: Poche, chocolatine… Une association traduit aux étudiants étrangers les mots du Sud-Ouest",
"article__url": "https://www.20minutes.fr/bordeaux/2120479-20170823-bordeaux-poche-chocolatine-association-traduit-etudiants-etrangers-mots-sud-ouest"
}
],
"recommendations": []
"bookmarks": [
{
"article__excerpt": "When Twitter started it had so much promise to change the way we communicate. But now it has been ruined by the amount of garbage and hate we have to wade through. It&#x2019;s like that polluted&hellip;",
"favorite": false,
"date_archived": null,
"article__url": "https://venngage.com/blog/hashtags-are-worthless/",
"date_added": "2016-08-25T12:05:00",
"date_favorited": null,
"article__title": "We Looked At 167,943 Tweets & Found Out Hashtags Are Worthless",
"archive": false
},
{
"article__title": "No title found",
"article__url": "http://news.nationalgeographic.com/2016/02/160211-albatrosses-mothers-babies-animals-science/&sf20739758=1",
"archive": false,
"date_added": "2016-09-08T11:55:58+0200",
"favorite": true
},
{
"archive": 0,
"date_added": "2016-09-08T11:55:58+0200",
"favorite": 0,
"article__title": "Bordeaux: Poche, chocolatine… Une association traduit aux étudiants étrangers les mots du Sud-Ouest",
"article__url": "https://www.20minutes.fr/bordeaux/2120479-20170823-bordeaux-poche-chocolatine-association-traduit-etudiants-etrangers-mots-sud-ouest"
}
],
"recommendations": []
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long