1
0
Fork 0
mirror of https://github.com/wallabag/wallabag.git synced 2025-09-15 18:57:05 +00:00

Move test files directly under tests/ directory

This commit is contained in:
Yassine Guedidi 2024-02-19 00:45:58 +01:00
parent a37b385c23
commit 24da70e338
117 changed files with 4 additions and 4 deletions

View file

@ -0,0 +1,375 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
use Wallabag\CoreBundle\Entity\Annotation;
use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\CoreBundle\Entity\User;
class AnnotationControllerTest extends WallabagCoreTestCase
{
/**
* @var KernelBrowser
*/
private $client;
protected function setUp(): void
{
parent::setUp();
$this->logInAs('admin');
$this->client = $this->getTestClient();
}
/**
* This data provider allow to tests annotation from the :
* - API POV (when user use the api to manage annotations)
* - and User POV (when user use the web interface - using javascript - to manage annotations).
*/
public function dataForEachAnnotations()
{
return [
['/api/annotations'],
['annotations'],
];
}
/**
* @dataProvider dataForEachAnnotations
*/
public function testGetAnnotations($prefixUrl)
{
$em = $this->client->getContainer()->get(EntityManagerInterface::class);
$user = $em
->getRepository(User::class)
->findOneByUserName('admin');
$entry = $em
->getRepository(Entry::class)
->findByUrlAndUserId('http://0.0.0.0/entry1', $user->getId());
if ('annotations' === $prefixUrl) {
$this->logInAs('admin');
}
$this->client->request('GET', $prefixUrl . '/' . $entry->getId() . '.json');
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertGreaterThanOrEqual(1, $content['total']);
}
/**
* @dataProvider dataForEachAnnotations
*/
public function testGetAnnotationsFromAnOtherUser($prefixUrl)
{
$em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
$otherUser = $em
->getRepository(User::class)
->findOneByUserName('bob');
$entry = $em
->getRepository(Entry::class)
->findByUrlAndUserId('http://0.0.0.0/entry3', $otherUser->getId());
if ('annotations' === $prefixUrl) {
$this->logInAs('admin');
}
$this->client->request('GET', $prefixUrl . '/' . $entry->getId() . '.json');
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertGreaterThanOrEqual(0, $content['total']);
}
/**
* @dataProvider dataForEachAnnotations
*/
public function testSetAnnotation($prefixUrl)
{
$em = $this->client->getContainer()->get(EntityManagerInterface::class);
$user = $em
->getRepository(User::class)
->findOneByUserName('admin');
if ('annotations' === $prefixUrl) {
$this->logInAs('admin');
}
/** @var Entry $entry */
$entry = $em
->getRepository(Entry::class)
->findOneByUsernameAndNotArchived('admin');
$headers = ['CONTENT_TYPE' => 'application/json'];
$content = json_encode([
'text' => 'my annotation',
'quote' => 'my quote',
'ranges' => [
['start' => '', 'startOffset' => 24, 'end' => '', 'endOffset' => 31],
],
]);
$this->client->request('POST', $prefixUrl . '/' . $entry->getId() . '.json', [], [], $headers, $content);
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertSame('Big boss', $content['user']);
$this->assertSame('v1.0', $content['annotator_schema_version']);
$this->assertSame('my annotation', $content['text']);
$this->assertSame('my quote', $content['quote']);
/** @var Annotation $annotation */
$annotation = $em
->getRepository(Annotation::class)
->findLastAnnotationByUserId($entry->getId(), $user->getId());
$this->assertSame('my annotation', $annotation->getText());
}
public function testAllowEmptyQuote()
{
$em = $this->client->getContainer()->get(EntityManagerInterface::class);
/** @var Entry $entry */
$entry = $em
->getRepository(Entry::class)
->findOneByUsernameAndNotArchived('admin');
$headers = ['CONTENT_TYPE' => 'application/json'];
$content = json_encode([
'text' => 'my annotation',
'quote' => null,
'ranges' => [
['start' => '', 'startOffset' => 24, 'end' => '', 'endOffset' => 31],
],
]);
$this->client->request('POST', '/api/annotations/' . $entry->getId() . '.json', [], [], $headers, $content);
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertSame('Big boss', $content['user']);
$this->assertSame('v1.0', $content['annotator_schema_version']);
$this->assertSame('my annotation', $content['text']);
$this->assertSame('', $content['quote']);
}
public function testAllowOmmittedQuote()
{
$em = $this->client->getContainer()->get(EntityManagerInterface::class);
/** @var Entry $entry */
$entry = $em
->getRepository(Entry::class)
->findOneByUsernameAndNotArchived('admin');
$headers = ['CONTENT_TYPE' => 'application/json'];
$content = json_encode([
'text' => 'my new annotation',
'ranges' => [
['start' => '', 'startOffset' => 25, 'end' => '', 'endOffset' => 32],
],
]);
$this->client->request('POST', '/api/annotations/' . $entry->getId() . '.json', [], [], $headers, $content);
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertSame('Big boss', $content['user']);
$this->assertSame('v1.0', $content['annotator_schema_version']);
$this->assertSame('my new annotation', $content['text']);
$this->assertSame('', $content['quote']);
}
/**
* @dataProvider dataForEachAnnotations
*/
public function testSetAnnotationWithQuoteTooLong($prefixUrl)
{
$em = $this->client->getContainer()->get(EntityManagerInterface::class);
if ('annotations' === $prefixUrl) {
$this->logInAs('admin');
}
/** @var Entry $entry */
$entry = $em
->getRepository(Entry::class)
->findOneByUsernameAndNotArchived('admin');
$longQuote = str_repeat('a', 10001);
$headers = ['CONTENT_TYPE' => 'application/json'];
$content = json_encode([
'text' => 'my annotation',
'quote' => $longQuote,
'ranges' => [
['start' => '', 'startOffset' => 24, 'end' => '', 'endOffset' => 31],
],
]);
$this->client->request('POST', $prefixUrl . '/' . $entry->getId() . '.json', [], [], $headers, $content);
$this->assertSame(400, $this->client->getResponse()->getStatusCode());
}
/**
* @dataProvider dataForEachAnnotations
*/
public function testEditAnnotation($prefixUrl)
{
$em = $this->client->getContainer()->get(EntityManagerInterface::class);
$user = $em
->getRepository(User::class)
->findOneByUserName('admin');
$entry = $em
->getRepository(Entry::class)
->findOneByUsernameAndNotArchived('admin');
$annotation = new Annotation($user);
$annotation->setEntry($entry);
$annotation->setText('This is my annotation /o/');
$annotation->setQuote('my quote');
$em->persist($annotation);
$em->flush();
$headers = ['CONTENT_TYPE' => 'application/json'];
$content = json_encode([
'text' => 'a modified annotation',
]);
$this->client->request('PUT', $prefixUrl . '/' . $annotation->getId() . '.json', [], [], $headers, $content);
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertSame('Big boss', $content['user']);
$this->assertSame('v1.0', $content['annotator_schema_version']);
$this->assertSame('a modified annotation', $content['text']);
$this->assertSame('my quote', $content['quote']);
/** @var Annotation $annotationUpdated */
$annotationUpdated = $em
->getRepository(Annotation::class)
->findOneById($annotation->getId());
$this->assertSame('a modified annotation', $annotationUpdated->getText());
$em->remove($annotationUpdated);
$em->flush();
}
/**
* @dataProvider dataForEachAnnotations
*/
public function testEditAnnotationFromAnOtherUser($prefixUrl)
{
$em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
$otherUser = $em
->getRepository(User::class)
->findOneByUserName('bob');
$entry = $em
->getRepository(Entry::class)
->findByUrlAndUserId('http://0.0.0.0/entry3', $otherUser->getId());
$annotation = $em
->getRepository(Annotation::class)
->findLastAnnotationByUserId($entry->getId(), $otherUser->getId());
$headers = ['CONTENT_TYPE' => 'application/json'];
$content = json_encode([
'text' => 'a modified annotation',
]);
$this->client->request('PUT', $prefixUrl . '/' . $annotation->getId() . '.json', [], [], $headers, $content);
$this->assertSame(404, $this->client->getResponse()->getStatusCode());
}
/**
* @dataProvider dataForEachAnnotations
*/
public function testDeleteAnnotation($prefixUrl)
{
$em = $this->client->getContainer()->get(EntityManagerInterface::class);
$user = $em
->getRepository(User::class)
->findOneByUserName('admin');
$entry = $em
->getRepository(Entry::class)
->findOneByUsernameAndNotArchived('admin');
$annotation = new Annotation($user);
$annotation->setEntry($entry);
$annotation->setText('This is my annotation /o/');
$annotation->setQuote('my quote');
$em->persist($annotation);
$em->flush();
if ('annotations' === $prefixUrl) {
$this->logInAs('admin');
}
$headers = ['CONTENT_TYPE' => 'application/json'];
$content = json_encode([
'text' => 'a modified annotation',
]);
$this->client->request('DELETE', $prefixUrl . '/' . $annotation->getId() . '.json', [], [], $headers, $content);
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertSame('This is my annotation /o/', $content['text']);
$annotationDeleted = $em
->getRepository(Annotation::class)
->findOneById($annotation->getId());
$this->assertNull($annotationDeleted);
}
/**
* @dataProvider dataForEachAnnotations
*/
public function testDeleteAnnotationFromAnOtherUser($prefixUrl)
{
$em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
$otherUser = $em
->getRepository(User::class)
->findOneByUserName('bob');
$entry = $em
->getRepository(Entry::class)
->findByUrlAndUserId('http://0.0.0.0/entry3', $otherUser->getId());
$annotation = $em
->getRepository(Annotation::class)
->findLastAnnotationByUserId($entry->getId(), $otherUser->getId());
$user = $em
->getRepository(User::class)
->findOneByUserName('admin');
$entry = $em
->getRepository(Entry::class)
->findOneByUsernameAndNotArchived('admin');
if ('annotations' === $prefixUrl) {
$this->logInAs('admin');
}
$headers = ['CONTENT_TYPE' => 'application/json'];
$content = json_encode([
'text' => 'a modified annotation',
]);
$this->client->request('DELETE', $prefixUrl . '/' . $annotation->getId() . '.json', [], [], $headers, $content);
$this->assertSame(404, $this->client->getResponse()->getStatusCode());
}
}

View file

@ -0,0 +1,45 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Api;
class ConfigRestControllerTest extends WallabagApiTestCase
{
public function testGetConfig()
{
$this->client->request('GET', '/api/config.json');
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
$config = json_decode($this->client->getResponse()->getContent(), true);
$this->assertArrayHasKey('id', $config);
$this->assertArrayHasKey('items_per_page', $config);
$this->assertArrayHasKey('language', $config);
$this->assertArrayHasKey('reading_speed', $config);
$this->assertArrayHasKey('action_mark_as_read', $config);
$this->assertArrayHasKey('list_mode', $config);
$this->assertArrayHasKey('display_thumbnails', $config);
$this->assertSame(200.0, $config['reading_speed']);
$this->assertSame('en', $config['language']);
$this->assertCount(7, $config);
$this->assertSame('application/json', $this->client->getResponse()->headers->get('Content-Type'));
}
public function testGetConfigWithoutAuthentication()
{
$client = $this->createUnauthorizedClient();
$client->request('GET', '/api/config.json');
$this->assertSame(401, $client->getResponse()->getStatusCode());
$config = json_decode($client->getResponse()->getContent(), true);
$this->assertArrayHasKey('error', $config);
$this->assertArrayHasKey('error_description', $config);
$this->assertSame('access_denied', $config['error']);
$this->assertSame('application/json', $client->getResponse()->headers->get('Content-Type'));
}
}

View file

@ -0,0 +1,145 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Api;
use Doctrine\ORM\EntityManagerInterface;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
use Wallabag\CoreBundle\Entity\Api\Client;
class DeveloperControllerTest extends WallabagCoreTestCase
{
public function testCreateClient()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$em = $client->getContainer()->get(EntityManagerInterface::class);
$nbClients = $em->getRepository(Client::class)->findAll();
$crawler = $client->request('GET', '/developer/client/create');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$form = $crawler->filter('button[id=client_save]')->form();
$data = [
'client[name]' => 'My app',
];
$crawler = $client->submit($form, $data);
$this->assertSame(200, $client->getResponse()->getStatusCode());
$newNbClients = $em->getRepository(Client::class)->findAll();
$this->assertGreaterThan(\count($nbClients), \count($newNbClients));
$this->assertGreaterThan(1, $alert = $crawler->filter('.settings table strong')->extract(['_text']));
$this->assertStringContainsString('My app', $alert[0]);
}
public function testCreateToken()
{
$client = $this->getTestClient();
$apiClient = $this->createApiClientForUser('admin');
$client->request('POST', '/oauth/v2/token', [
'grant_type' => 'password',
'client_id' => $apiClient->getPublicId(),
'client_secret' => $apiClient->getSecret(),
'username' => 'admin',
'password' => 'mypassword',
]);
$this->assertSame(200, $client->getResponse()->getStatusCode());
$data = json_decode($client->getResponse()->getContent(), true);
$this->assertArrayHasKey('access_token', $data);
$this->assertArrayHasKey('expires_in', $data);
$this->assertArrayHasKey('token_type', $data);
$this->assertArrayHasKey('refresh_token', $data);
}
public function testCreateTokenWithBadClientId()
{
$client = $this->getTestClient();
$client->request('POST', '/oauth/v2/token', [
'grant_type' => 'password',
'client_id' => '$WALLABAG_CLIENT_ID',
'client_secret' => 'secret',
'username' => 'admin',
'password' => 'mypassword',
]);
$this->assertSame(400, $client->getResponse()->getStatusCode());
}
public function testListingClient()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$em = $client->getContainer()->get(EntityManagerInterface::class);
$nbClients = $em->getRepository(Client::class)->findAll();
$crawler = $client->request('GET', '/developer');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->assertSame(\count($nbClients), $crawler->filter('ul[class=collapsible] li')->count());
}
public function testDeveloperHowto()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/developer/howto/first-app');
$this->assertSame(200, $client->getResponse()->getStatusCode());
}
public function testRemoveClient()
{
$client = $this->getTestClient();
$adminApiClient = $this->createApiClientForUser('admin');
$em = $client->getContainer()->get(EntityManagerInterface::class);
// Try to remove an admin's client with a wrong user
$this->logInAs('bob');
$client->request('GET', '/developer');
$this->assertStringContainsString('no_client', $client->getResponse()->getContent());
$this->logInAs('bob');
$client->request('POST', '/developer/client/delete/' . $adminApiClient->getId());
$this->assertSame(403, $client->getResponse()->getStatusCode());
// Try to remove the admin's client with the good user
$this->logInAs('admin');
$crawler = $client->request('GET', '/developer');
$form = $crawler->filter('form[name=delete-client]')->form();
$client->submit($form);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$this->assertNull(
$em->getRepository(Client::class)->find($adminApiClient->getId()),
'The client should have been removed'
);
}
/**
* @param string $username
* @param array $grantTypes
*
* @return Client
*/
private function createApiClientForUser($username, $grantTypes = ['password'])
{
$client = $this->getTestClient();
$em = $client->getContainer()->get(EntityManagerInterface::class);
$userManager = $client->getContainer()->get('fos_user.user_manager.test');
$user = $userManager->findUserBy(['username' => $username]);
$apiClient = new Client($user);
$apiClient->setName('My app');
$apiClient->setAllowedGrantTypes($grantTypes);
$em->persist($apiClient);
$em->flush();
return $apiClient;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,67 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Api;
class SearchRestControllerTest extends WallabagApiTestCase
{
public function testGetSearchWithFullOptions()
{
$this->client->request('GET', '/api/search', [
'page' => 1,
'perPage' => 2,
'term' => 'entry', // 6 results
]);
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertGreaterThanOrEqual(1, \count($content));
$this->assertArrayHasKey('items', $content['_embedded']);
$this->assertGreaterThanOrEqual(0, $content['total']);
$this->assertSame(1, $content['page']);
$this->assertSame(2, $content['limit']);
$this->assertGreaterThanOrEqual(1, $content['pages']);
$this->assertArrayHasKey('_links', $content);
$this->assertArrayHasKey('self', $content['_links']);
$this->assertArrayHasKey('first', $content['_links']);
$this->assertArrayHasKey('last', $content['_links']);
foreach (['self', 'first', 'last'] as $link) {
$this->assertArrayHasKey('href', $content['_links'][$link]);
$this->assertStringContainsString('term=entry', $content['_links'][$link]['href']);
}
$this->assertSame('application/json', $this->client->getResponse()->headers->get('Content-Type'));
}
public function testGetSearchWithNoLimit()
{
$this->client->request('GET', '/api/search', [
'term' => 'entry',
]);
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertGreaterThanOrEqual(1, \count($content));
$this->assertArrayHasKey('items', $content['_embedded']);
$this->assertGreaterThanOrEqual(0, $content['total']);
$this->assertSame(1, $content['page']);
$this->assertGreaterThanOrEqual(1, $content['pages']);
$this->assertArrayHasKey('_links', $content);
$this->assertArrayHasKey('self', $content['_links']);
$this->assertArrayHasKey('first', $content['_links']);
$this->assertArrayHasKey('last', $content['_links']);
foreach (['self', 'first', 'last'] as $link) {
$this->assertArrayHasKey('href', $content['_links'][$link]);
$this->assertStringContainsString('term=entry', $content['_links'][$link]['href']);
}
$this->assertSame('application/json', $this->client->getResponse()->headers->get('Content-Type'));
}
}

View file

@ -0,0 +1,225 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Api;
use Doctrine\ORM\EntityManagerInterface;
use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\CoreBundle\Entity\Tag;
class TagRestControllerTest extends WallabagApiTestCase
{
private $otherUserTagLabel = 'bob';
public function testGetUserTags()
{
$this->client->request('GET', '/api/tags.json');
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertGreaterThan(0, $content);
$this->assertArrayHasKey('id', $content[0]);
$this->assertArrayHasKey('label', $content[0]);
$this->assertArrayHasKey('nbEntries', $content[0]);
$tagLabels = array_map(function ($i) {
return $i['label'];
}, $content);
$this->assertNotContains($this->otherUserTagLabel, $tagLabels, 'There is a possible tag leak');
}
public function testDeleteUserTag()
{
$em = $this->client->getContainer()->get(EntityManagerInterface::class);
$entry = $this->client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findOneWithTags($this->user->getId());
$entry = $entry[0];
$tagLabel = 'tagtest';
$tag = new Tag();
$tag->setLabel($tagLabel);
$em->persist($tag);
$entry->addTag($tag);
$em->persist($entry);
$em->flush();
$em->clear();
$this->client->request('DELETE', '/api/tags/' . $tag->getId() . '.json');
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertArrayHasKey('label', $content);
$this->assertSame($tag->getLabel(), $content['label']);
$this->assertSame($tag->getSlug(), $content['slug']);
$entries = $em->getRepository(Entry::class)
->findAllByTagId($this->user->getId(), $tag->getId());
$this->assertCount(0, $entries);
$tag = $em->getRepository(Tag::class)->findOneByLabel($tagLabel);
$this->assertNull($tag, $tagLabel . ' was removed because it begun an orphan tag');
}
public function testDeleteOtherUserTag()
{
$em = $this->client->getContainer()->get(EntityManagerInterface::class);
$tag = $em->getRepository(Tag::class)->findOneByLabel($this->otherUserTagLabel);
$this->client->request('DELETE', '/api/tags/' . $tag->getId() . '.json');
$this->assertSame(404, $this->client->getResponse()->getStatusCode());
}
public function dataForDeletingTagByLabel()
{
return [
'by_query' => [true],
'by_body' => [false],
];
}
/**
* @dataProvider dataForDeletingTagByLabel
*/
public function testDeleteTagByLabel($useQueryString)
{
$em = $this->client->getContainer()->get(EntityManagerInterface::class);
$entry = $this->client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findOneWithTags($this->user->getId());
$entry = $entry[0];
$tag = new Tag();
$tag->setLabel('Awesome tag for test');
$em->persist($tag);
$entry->addTag($tag);
$em->persist($entry);
$em->flush();
if ($useQueryString) {
$this->client->request('DELETE', '/api/tag/label.json?tag=' . $tag->getLabel());
} else {
$this->client->request('DELETE', '/api/tag/label.json', ['tag' => $tag->getLabel()]);
}
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertArrayHasKey('label', $content);
$this->assertSame($tag->getLabel(), $content['label']);
$this->assertSame($tag->getSlug(), $content['slug']);
$entries = $this->client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findAllByTagId($this->user->getId(), $tag->getId());
$this->assertCount(0, $entries);
}
public function testDeleteTagByLabelNotFound()
{
$this->client->request('DELETE', '/api/tag/label.json', ['tag' => 'does not exist']);
$this->assertSame(404, $this->client->getResponse()->getStatusCode());
}
public function testDeleteTagByLabelOtherUser()
{
$this->client->request('DELETE', '/api/tag/label.json', ['tag' => $this->otherUserTagLabel]);
$this->assertSame(404, $this->client->getResponse()->getStatusCode());
}
/**
* @dataProvider dataForDeletingTagByLabel
*/
public function testDeleteTagsByLabel($useQueryString)
{
$em = $this->client->getContainer()->get(EntityManagerInterface::class);
$entry = $this->client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findOneWithTags($this->user->getId());
$entry = $entry[0];
$tag = new Tag();
$tag->setLabel('Awesome tag for tagsLabel');
$em->persist($tag);
$tag2 = new Tag();
$tag2->setLabel('Awesome tag for tagsLabel 2');
$em->persist($tag2);
$entry->addTag($tag);
$entry->addTag($tag2);
$em->persist($entry);
$em->flush();
if ($useQueryString) {
$this->client->request('DELETE', '/api/tags/label.json?tags=' . $tag->getLabel() . ',' . $tag2->getLabel());
} else {
$this->client->request('DELETE', '/api/tags/label.json', ['tags' => $tag->getLabel() . ',' . $tag2->getLabel()]);
}
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertCount(2, $content);
$this->assertArrayHasKey('label', $content[0]);
$this->assertSame($tag->getLabel(), $content[0]['label']);
$this->assertSame($tag->getSlug(), $content[0]['slug']);
$this->assertArrayHasKey('label', $content[1]);
$this->assertSame($tag2->getLabel(), $content[1]['label']);
$this->assertSame($tag2->getSlug(), $content[1]['slug']);
$entries = $this->client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findAllByTagId($this->user->getId(), $tag->getId());
$this->assertCount(0, $entries);
$entries = $this->client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findAllByTagId($this->user->getId(), $tag2->getId());
$this->assertCount(0, $entries);
}
public function testDeleteTagsByLabelNotFound()
{
$this->client->request('DELETE', '/api/tags/label.json', ['tags' => 'does not exist']);
$this->assertSame(404, $this->client->getResponse()->getStatusCode());
}
public function testDeleteTagsByLabelOtherUser()
{
$this->client->request('DELETE', '/api/tags/label.json', ['tags' => $this->otherUserTagLabel]);
$this->assertSame(404, $this->client->getResponse()->getStatusCode());
}
}

View file

@ -0,0 +1,13 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Api;
class TaggingRuleRestControllerTest extends WallabagApiTestCase
{
public function testExportEntry()
{
$this->client->request('GET', '/api/taggingrule/export');
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
$this->assertSame('application/json', $this->client->getResponse()->headers->get('Content-Type'));
}
}

View file

@ -0,0 +1,185 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Api;
use Craue\ConfigBundle\Util\Config;
class UserRestControllerTest extends WallabagApiTestCase
{
public function testGetUser()
{
$this->client->request('GET', '/api/user.json');
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertArrayHasKey('id', $content);
$this->assertArrayHasKey('email', $content);
$this->assertArrayHasKey('name', $content);
$this->assertArrayHasKey('username', $content);
$this->assertArrayHasKey('created_at', $content);
$this->assertArrayHasKey('updated_at', $content);
$this->assertSame('bigboss@wallabag.org', $content['email']);
$this->assertSame('Big boss', $content['name']);
$this->assertSame('admin', $content['username']);
$this->assertSame('application/json', $this->client->getResponse()->headers->get('Content-Type'));
}
public function testGetUserWithoutAuthentication()
{
$client = $this->createUnauthorizedClient();
$client->request('GET', '/api/user.json');
$this->assertSame(401, $client->getResponse()->getStatusCode());
$content = json_decode($client->getResponse()->getContent(), true);
$this->assertArrayHasKey('error', $content);
$this->assertArrayHasKey('error_description', $content);
$this->assertSame('access_denied', $content['error']);
$this->assertSame('application/json', $client->getResponse()->headers->get('Content-Type'));
}
public function testCreateNewUser()
{
$this->client->getContainer()->get(Config::class)->set('api_user_registration', 1);
$this->client->request('PUT', '/api/user.json', [
'username' => 'google',
'password' => 'googlegoogle',
'email' => 'wallabag@google.com',
]);
$this->assertSame(201, $this->client->getResponse()->getStatusCode());
$content = json_decode($this->client->getResponse()->getContent(), true);
$this->assertArrayHasKey('id', $content);
$this->assertArrayHasKey('email', $content);
$this->assertArrayHasKey('username', $content);
$this->assertArrayHasKey('created_at', $content);
$this->assertArrayHasKey('updated_at', $content);
$this->assertArrayHasKey('default_client', $content);
$this->assertSame('wallabag@google.com', $content['email']);
$this->assertSame('google', $content['username']);
$this->assertArrayHasKey('client_secret', $content['default_client']);
$this->assertArrayHasKey('client_id', $content['default_client']);
$this->assertSame('Default client', $content['default_client']['name']);
$this->assertSame('application/json', $this->client->getResponse()->headers->get('Content-Type'));
$this->client->getContainer()->get(Config::class)->set('api_user_registration', 0);
}
public function testCreateNewUserWithoutAuthentication()
{
// create a new client instead of using $this->client to be sure client isn't authenticated
$client = $this->createUnauthorizedClient();
$client->getContainer()->get(Config::class)->set('api_user_registration', 1);
$client->request('PUT', '/api/user.json', [
'username' => 'google',
'password' => 'googlegoogle',
'email' => 'wallabag@google.com',
'client_name' => 'My client name !!',
]);
$this->assertSame(201, $client->getResponse()->getStatusCode());
$content = json_decode($client->getResponse()->getContent(), true);
$this->assertArrayHasKey('id', $content);
$this->assertArrayHasKey('email', $content);
$this->assertArrayHasKey('username', $content);
$this->assertArrayHasKey('created_at', $content);
$this->assertArrayHasKey('updated_at', $content);
$this->assertArrayHasKey('default_client', $content);
$this->assertSame('wallabag@google.com', $content['email']);
$this->assertSame('google', $content['username']);
$this->assertArrayHasKey('client_secret', $content['default_client']);
$this->assertArrayHasKey('client_id', $content['default_client']);
$this->assertSame('My client name !!', $content['default_client']['name']);
$this->assertSame('application/json', $client->getResponse()->headers->get('Content-Type'));
$client->getContainer()->get(Config::class)->set('api_user_registration', 0);
}
public function testCreateNewUserWithExistingEmail()
{
$client = $this->createUnauthorizedClient();
$client->getContainer()->get(Config::class)->set('api_user_registration', 1);
$client->request('PUT', '/api/user.json', [
'username' => 'admin',
'password' => 'googlegoogle',
'email' => 'bigboss@wallabag.org',
]);
$this->assertSame(400, $client->getResponse()->getStatusCode());
$content = json_decode($client->getResponse()->getContent(), true);
$this->assertArrayHasKey('error', $content);
$this->assertArrayHasKey('username', $content['error']);
$this->assertArrayHasKey('email', $content['error']);
// $this->assertEquals('fos_user.username.already_used', $content['error']['username'][0]);
// $this->assertEquals('fos_user.email.already_used', $content['error']['email'][0]);
// This shouldn't be translated ...
$this->assertSame('This value is already used.', $content['error']['username'][0]);
$this->assertSame('This value is already used.', $content['error']['email'][0]);
$this->assertSame('application/json', $client->getResponse()->headers->get('Content-Type'));
$client->getContainer()->get(Config::class)->set('api_user_registration', 0);
}
public function testCreateNewUserWithTooShortPassword()
{
$client = $this->createUnauthorizedClient();
$client->getContainer()->get(Config::class)->set('api_user_registration', 1);
$client->request('PUT', '/api/user.json', [
'username' => 'facebook',
'password' => 'face',
'email' => 'facebook@wallabag.org',
]);
$this->assertSame(400, $client->getResponse()->getStatusCode());
$content = json_decode($client->getResponse()->getContent(), true);
$this->assertArrayHasKey('error', $content);
$this->assertArrayHasKey('password', $content['error']);
$this->assertSame('validator.password_too_short', $content['error']['password'][0]);
$this->assertSame('application/json', $client->getResponse()->headers->get('Content-Type'));
$client->getContainer()->get(Config::class)->set('api_user_registration', 0);
}
public function testCreateNewUserWhenRegistrationIsDisabled()
{
$client = $this->createUnauthorizedClient();
$client->request('PUT', '/api/user.json', [
'username' => 'facebook',
'password' => 'face',
'email' => 'facebook@wallabag.org',
]);
$this->assertSame(403, $client->getResponse()->getStatusCode());
$content = json_decode($client->getResponse()->getContent(), true);
$this->assertArrayHasKey('error', $content);
$this->assertSame('application/json', $client->getResponse()->headers->get('Content-Type'));
}
}

View file

@ -0,0 +1,77 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Api;
use Doctrine\ORM\EntityManagerInterface;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Model\UserManager;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Wallabag\CoreBundle\Entity\User;
abstract class WallabagApiTestCase extends WebTestCase
{
/**
* @var KernelBrowser
*/
protected $client;
/**
* @var UserInterface
*/
protected $user;
protected function setUp(): void
{
parent::setUp();
$this->client = $this->createAuthorizedClient();
}
/**
* @return KernelBrowser
*/
protected function createUnauthorizedClient()
{
static::ensureKernelShutdown();
return static::createClient();
}
/**
* @return KernelBrowser
*/
protected function createAuthorizedClient()
{
$client = $this->createUnauthorizedClient();
$container = $client->getContainer();
/** @var UserManager $userManager */
$userManager = $container->get('fos_user.user_manager.test');
$firewallName = $container->getParameter('fos_user.firewall_name');
$this->user = $userManager->findUserBy(['username' => 'admin']);
$client->loginUser($this->user, $firewallName);
return $client;
}
/**
* Return the ID for the user admin.
* Used because on heavy testing we don't want to re-create the database on each run.
* Which means "admin" user won't have id 1 all the time.
*
* @param string $username
*
* @return int
*/
protected function getUserId($username = 'admin')
{
return $this->client
->getContainer()
->get(EntityManagerInterface::class)
->getRepository(User::class)
->findOneByUserName($username)
->getId();
}
}

View file

@ -0,0 +1,66 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Api;
use Craue\ConfigBundle\Util\Config;
class WallabagRestControllerTest extends WallabagApiTestCase
{
public function testGetVersion()
{
// create a new client instead of using $this->client to be sure client isn't authenticated
$client = $this->createUnauthorizedClient();
$client->request('GET', '/api/version');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$content = json_decode($client->getResponse()->getContent(), true);
$this->assertSame($client->getContainer()->getParameter('wallabag_core.version'), $content);
}
public function testGetInfo()
{
// create a new client instead of using $this->client to be sure client isn't authenticated
$client = $this->createUnauthorizedClient();
$client->request('GET', '/api/info');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$content = json_decode($client->getResponse()->getContent(), true);
$this->assertArrayHasKey('appname', $content);
$this->assertArrayHasKey('version', $content);
$this->assertArrayHasKey('allowed_registration', $content);
$this->assertSame('wallabag', $content['appname']);
}
public function testAllowedRegistration()
{
// create a new client instead of using $this->client to be sure client isn't authenticated
$client = $this->createUnauthorizedClient();
if (!$client->getContainer()->getParameter('fosuser_registration')) {
$this->markTestSkipped('fosuser_registration is not enabled.');
return;
}
$client->getContainer()->get(Config::class)->set('api_user_registration', 1);
$client->request('GET', '/api/info');
$content = json_decode($client->getResponse()->getContent(), true);
$this->assertTrue($content['allowed_registration']);
$client->getContainer()->get(Config::class)->set('api_user_registration', 0);
$client->request('GET', '/api/info');
$content = json_decode($client->getResponse()->getContent(), true);
$this->assertFalse($content['allowed_registration']);
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,370 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller;
use Doctrine\ORM\EntityManagerInterface;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
use Wallabag\CoreBundle\Entity\Entry;
class ExportControllerTest extends WallabagCoreTestCase
{
private $adminEntry;
private $bobEntry;
private $sameDomainEntry;
private $sameDomainEntry2;
public function testLogin()
{
$client = $this->getTestClient();
$client->request('GET', '/export/unread.csv');
$this->assertSame(302, $client->getResponse()->getStatusCode());
$this->assertStringContainsString('login', $client->getResponse()->headers->get('location'));
}
public function testUnknownCategoryExport()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->request('GET', '/export/awesomeness.epub');
$this->assertSame(404, $client->getResponse()->getStatusCode());
}
public function testUnknownFormatExport()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->request('GET', '/export/unread.xslx');
$this->assertSame(404, $client->getResponse()->getStatusCode());
}
public function testUnsupportedFormatExport()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->request('GET', '/export/unread.doc');
$this->assertSame(404, $client->getResponse()->getStatusCode());
$content = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findOneByUsernameAndNotArchived('admin');
$client->request('GET', '/export/' . $content->getId() . '.doc');
$this->assertSame(404, $client->getResponse()->getStatusCode());
}
public function testNonExistingEntryId()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->request('GET', '/export/0.pdf');
$this->assertSame(404, $client->getResponse()->getStatusCode());
}
public function testForbiddenEntryId()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$content = $client->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository(Entry::class)
->findOneByUsernameAndNotArchived('bob');
$client->request('GET', '/export/' . $content->getId() . '.pdf');
$this->assertSame(404, $client->getResponse()->getStatusCode());
}
public function testEpubExport()
{
$this->logInAs('admin');
$client = $this->getTestClient();
ob_start();
$crawler = $client->request('GET', '/export/archive.epub');
ob_end_clean();
$this->assertSame(200, $client->getResponse()->getStatusCode());
$headers = $client->getResponse()->headers;
$this->assertSame('application/epub+zip', $headers->get('content-type'));
$this->assertSame('attachment; filename="Archive articles.epub"', $headers->get('content-disposition'));
$this->assertSame('binary', $headers->get('content-transfer-encoding'));
}
public function testPdfExport()
{
$this->logInAs('admin');
$client = $this->getTestClient();
ob_start();
$crawler = $client->request('GET', '/export/all.pdf');
ob_end_clean();
$this->assertSame(200, $client->getResponse()->getStatusCode());
$headers = $client->getResponse()->headers;
$this->assertSame('application/pdf', $headers->get('content-type'));
$this->assertSame('attachment; filename="All articles.pdf"', $headers->get('content-disposition'));
$this->assertSame('binary', $headers->get('content-transfer-encoding'));
ob_start();
$crawler = $client->request('GET', '/export/tag_entries.pdf?tag=t:foo-bar');
ob_end_clean();
$this->assertSame(200, $client->getResponse()->getStatusCode());
$headers = $client->getResponse()->headers;
$this->assertSame('application/pdf', $headers->get('content-type'));
$this->assertSame('attachment; filename="Tag foo bar articles.pdf"', $headers->get('content-disposition'));
$this->assertSame('binary', $headers->get('content-transfer-encoding'));
}
public function testTxtExport()
{
$this->logInAs('admin');
$client = $this->getTestClient();
ob_start();
$crawler = $client->request('GET', '/export/all.txt');
ob_end_clean();
$this->assertSame(200, $client->getResponse()->getStatusCode());
$headers = $client->getResponse()->headers;
$this->assertSame('text/plain; charset=UTF-8', $headers->get('content-type'));
$this->assertSame('attachment; filename="All articles.txt"', $headers->get('content-disposition'));
$this->assertSame('UTF-8', $headers->get('content-transfer-encoding'));
}
public function testCsvExport()
{
$this->logInAs('admin');
$client = $this->getTestClient();
// to be sure results are the same
$contentInDB = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->createQueryBuilder('e')
->select('e, t')
->leftJoin('e.user', 'u')
->leftJoin('e.tags', 't')
->where('u.username = :username')->setParameter('username', 'admin')
->andWhere('e.isArchived = true')
->getQuery()
->getArrayResult();
ob_start();
$crawler = $client->request('GET', '/export/archive.csv');
ob_end_clean();
$this->assertSame(200, $client->getResponse()->getStatusCode());
$headers = $client->getResponse()->headers;
$this->assertSame('application/csv', $headers->get('content-type'));
$this->assertSame('attachment; filename="Archive articles.csv"', $headers->get('content-disposition'));
$this->assertSame('UTF-8', $headers->get('content-transfer-encoding'));
$csv = str_getcsv($client->getResponse()->getContent(), "\n");
$this->assertGreaterThan(1, $csv);
// +1 for title line
$this->assertCount(\count($contentInDB) + 1, $csv);
$this->assertSame('Title;URL;Content;Tags;"MIME Type";Language;"Creation date"', $csv[0]);
$this->assertStringContainsString($contentInDB[0]['title'], $csv[1]);
$this->assertStringContainsString($contentInDB[0]['url'], $csv[1]);
$this->assertStringContainsString($contentInDB[0]['content'], $csv[1]);
$this->assertStringContainsString($contentInDB[0]['mimetype'], $csv[1]);
$this->assertStringContainsString($contentInDB[0]['language'], $csv[1]);
$this->assertStringContainsString($contentInDB[0]['createdAt']->format('d/m/Y h:i:s'), $csv[1]);
foreach ($contentInDB[0]['tags'] as $tag) {
$this->assertStringContainsString($tag['label'], $csv[1]);
}
}
public function testJsonExport()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$contentInDB = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId('http://0.0.0.0/entry1', $this->getLoggedInUserId());
ob_start();
$crawler = $client->request('GET', '/export/' . $contentInDB->getId() . '.json');
ob_end_clean();
$this->assertSame(200, $client->getResponse()->getStatusCode());
$headers = $client->getResponse()->headers;
$this->assertSame('application/json', $headers->get('content-type'));
$this->assertSame('attachment; filename="' . $this->getSanitizedFilename($contentInDB->getTitle()) . '.json"', $headers->get('content-disposition'));
$this->assertSame('UTF-8', $headers->get('content-transfer-encoding'));
$content = json_decode($client->getResponse()->getContent(), true);
$this->assertArrayHasKey('id', $content[0]);
$this->assertArrayHasKey('title', $content[0]);
$this->assertArrayHasKey('url', $content[0]);
$this->assertArrayHasKey('is_archived', $content[0]);
$this->assertArrayHasKey('is_starred', $content[0]);
$this->assertArrayHasKey('content', $content[0]);
$this->assertArrayHasKey('mimetype', $content[0]);
$this->assertArrayHasKey('language', $content[0]);
$this->assertArrayHasKey('reading_time', $content[0]);
$this->assertArrayHasKey('domain_name', $content[0]);
$this->assertArrayHasKey('tags', $content[0]);
$this->assertArrayHasKey('created_at', $content[0]);
$this->assertArrayHasKey('updated_at', $content[0]);
$this->assertSame((int) $contentInDB->isArchived(), $content[0]['is_archived']);
$this->assertSame((int) $contentInDB->isStarred(), $content[0]['is_starred']);
$this->assertSame($contentInDB->getTitle(), $content[0]['title']);
$this->assertSame($contentInDB->getUrl(), $content[0]['url']);
$this->assertSame([['text' => 'This is my annotation /o/', 'quote' => 'content']], $content[0]['annotations']);
$this->assertSame($contentInDB->getMimetype(), $content[0]['mimetype']);
$this->assertSame($contentInDB->getLanguage(), $content[0]['language']);
$this->assertSame($contentInDB->getReadingtime(), $content[0]['reading_time']);
$this->assertSame($contentInDB->getDomainname(), $content[0]['domain_name']);
$this->assertContains('baz', $content[0]['tags']);
$this->assertContains('foo', $content[0]['tags']);
}
public function testJsonExportFromSearch()
{
$this->setUpForJsonExportFromSearch();
$this->logInAs('admin');
$client = $this->getTestClient();
ob_start();
$crawler = $client->request('GET', '/export/search.json?search_entry[term]=entry+search&currentRoute=homepage');
ob_end_clean();
$this->assertSame(200, $client->getResponse()->getStatusCode());
$headers = $client->getResponse()->headers;
$this->assertSame('application/json', $headers->get('content-type'));
$this->assertSame('attachment; filename="Search entry search articles.json"', $headers->get('content-disposition'));
$this->assertSame('UTF-8', $headers->get('content-transfer-encoding'));
$content = json_decode($client->getResponse()->getContent(), true);
$this->assertCount(1, $content);
$this->tearDownForJsonExportFromSearch();
}
public function testXmlExport()
{
$this->logInAs('admin');
$client = $this->getTestClient();
// to be sure results are the same
$contentInDB = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->createQueryBuilder('e')
->leftJoin('e.user', 'u')
->where('u.username = :username')->setParameter('username', 'admin')
->andWhere('e.isArchived = false')
->getQuery()
->getArrayResult();
ob_start();
$crawler = $client->request('GET', '/export/unread.xml');
ob_end_clean();
$this->assertSame(200, $client->getResponse()->getStatusCode());
$headers = $client->getResponse()->headers;
$this->assertSame('application/xml', $headers->get('content-type'));
$this->assertSame('attachment; filename="Unread articles.xml"', $headers->get('content-disposition'));
$this->assertSame('UTF-8', $headers->get('content-transfer-encoding'));
$content = new \SimpleXMLElement($client->getResponse()->getContent());
$this->assertGreaterThan(0, $content->count());
$this->assertCount(\count($contentInDB), $content);
$this->assertNotEmpty('id', (string) $content->entry[0]->id);
$this->assertNotEmpty('title', (string) $content->entry[0]->title);
$this->assertNotEmpty('url', (string) $content->entry[0]->url);
$this->assertNotEmpty('content', (string) $content->entry[0]->content);
$this->assertNotEmpty('domain_name', (string) $content->entry[0]->domain_name);
$this->assertNotEmpty('created_at', (string) $content->entry[0]->created_at);
$this->assertNotEmpty('updated_at', (string) $content->entry[0]->updated_at);
}
public function testJsonExportFromSameDomain()
{
$this->logInAs('admin');
$client = $this->getTestClient();
ob_start();
$crawler = $client->request('GET', '/export/same_domain.json?entry=1');
ob_end_clean();
$this->assertSame(200, $client->getResponse()->getStatusCode());
$headers = $client->getResponse()->headers;
$this->assertSame('application/json', $headers->get('content-type'));
$this->assertSame('attachment; filename="Same domain articles.json"', $headers->get('content-disposition'));
$this->assertSame('UTF-8', $headers->get('content-transfer-encoding'));
$content = json_decode($client->getResponse()->getContent(), true);
$this->assertCount(4, $content);
}
private function setUpForJsonExportFromSearch()
{
$client = $this->getTestClient();
$em = $this->getEntityManager();
$userRepository = $client->getContainer()
->get('wallabag_user.user_repository.test');
$user = $userRepository->findOneByUserName('admin');
$this->adminEntry = new Entry($user);
$this->adminEntry->setUrl('http://0.0.0.0/entry-search-admin');
$this->adminEntry->setTitle('test title entry search admin');
$this->adminEntry->setContent('this is my content /o/');
$em->persist($this->adminEntry);
$user = $userRepository->findOneByUserName('bob');
$this->bobEntry = new Entry($user);
$this->bobEntry->setUrl('http://0.0.0.0/entry-search-bob');
$this->bobEntry->setTitle('test title entry search bob');
$this->bobEntry->setContent('this is my content /o/');
$em->persist($this->bobEntry);
$em->flush();
}
private function tearDownForJsonExportFromSearch()
{
$em = $this->getEntityManager();
$em->remove($this->adminEntry);
$em->remove($this->bobEntry);
$em->flush();
}
private function getSanitizedFilename($title)
{
$transliterator = \Transliterator::createFromRules(':: Any-Latin; :: Latin-ASCII; :: NFD; :: [:Nonspacing Mark:] Remove; :: NFC;', \Transliterator::FORWARD);
return preg_replace('/[^A-Za-z0-9\- \']/', '', $transliterator->transliterate($title));
}
}

View file

@ -0,0 +1,315 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller;
use Doctrine\ORM\EntityManagerInterface;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\CoreBundle\Entity\User;
class FeedControllerTest extends WallabagCoreTestCase
{
public function validateDom($xml, $type, $nb = null, $tagValue = null)
{
$doc = new \DOMDocument();
$doc->loadXML($xml);
$xpath = new \DOMXPath($doc);
$xpath->registerNamespace('a', 'http://www.w3.org/2005/Atom');
if (null === $nb) {
$this->assertGreaterThan(0, $xpath->query('//a:entry')->length);
} else {
$this->assertSame($nb, $xpath->query('//a:entry')->length);
}
$this->assertSame(1, $xpath->query('/a:feed')->length);
$this->assertSame(1, $xpath->query('/a:feed/a:title')->length);
$this->assertStringContainsString('favicon.ico', $xpath->query('/a:feed/a:icon')->item(0)->nodeValue);
$this->assertStringContainsString('logo-square.png', $xpath->query('/a:feed/a:logo')->item(0)->nodeValue);
$this->assertSame(1, $xpath->query('/a:feed/a:updated')->length);
$this->assertSame(1, $xpath->query('/a:feed/a:generator')->length);
$this->assertSame('wallabag', $xpath->query('/a:feed/a:generator')->item(0)->nodeValue);
$this->assertSame('admin', $xpath->query('/a:feed/a:author/a:name')->item(0)->nodeValue);
$this->assertSame(1, $xpath->query('/a:feed/a:subtitle')->length);
if (null !== $tagValue && str_starts_with($type, 'tag')) {
$this->assertSame('wallabag — ' . $type . ' ' . $tagValue . ' feed', $xpath->query('/a:feed/a:title')->item(0)->nodeValue);
$this->assertSame('Atom feed for entries tagged with ' . $tagValue, $xpath->query('/a:feed/a:subtitle')->item(0)->nodeValue);
} else {
$this->assertSame('wallabag — ' . $type . ' feed', $xpath->query('/a:feed/a:title')->item(0)->nodeValue);
$this->assertSame('Atom feed for ' . $type . ' entries', $xpath->query('/a:feed/a:subtitle')->item(0)->nodeValue);
}
$this->assertSame(1, $xpath->query('/a:feed/a:link[@rel="self"]')->length);
$this->assertStringContainsString($type, $xpath->query('/a:feed/a:link[@rel="self"]')->item(0)->getAttribute('href'));
$this->assertSame(1, $xpath->query('/a:feed/a:link[@rel="last"]')->length);
foreach ($xpath->query('//a:entry') as $item) {
$this->assertSame(1, $xpath->query('a:title', $item)->length);
$this->assertSame(1, $xpath->query('a:link[@rel="via"]', $item)->length);
$this->assertSame(1, $xpath->query('a:link[@rel="alternate"]', $item)->length);
$this->assertSame(1, $xpath->query('a:id', $item)->length);
$this->assertSame(1, $xpath->query('a:published', $item)->length);
$this->assertSame(1, $xpath->query('a:content', $item)->length);
}
}
public function dataForBadUrl()
{
return [
[
'/feed/admin/YZIOAUZIAO/unread',
],
[
'/feed/wallace/YZIOAUZIAO/starred',
],
[
'/feed/wallace/YZIOAUZIAO/archives',
],
[
'/feed/wallace/YZIOAUZIAO/all',
],
];
}
/**
* @dataProvider dataForBadUrl
*/
public function testBadUrl($url)
{
$client = $this->getTestClient();
$client->request('GET', $url);
$this->assertSame(404, $client->getResponse()->getStatusCode());
}
public function testUnread()
{
$client = $this->getTestClient();
$em = $client->getContainer()->get(EntityManagerInterface::class);
$user = $em
->getRepository(User::class)
->findOneByUsername('admin');
$config = $user->getConfig();
$config->setFeedToken('SUPERTOKEN');
$config->setFeedLimit(2);
$em->persist($config);
$em->flush();
$client->request('GET', '/feed/admin/SUPERTOKEN/unread');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->validateDom($client->getResponse()->getContent(), 'unread', 2);
}
public function testStarred()
{
$client = $this->getTestClient();
$em = $client->getContainer()->get(EntityManagerInterface::class);
$user = $em
->getRepository(User::class)
->findOneByUsername('admin');
$config = $user->getConfig();
$config->setFeedToken('SUPERTOKEN');
$config->setFeedLimit(1);
$em->persist($config);
$em->flush();
$client = $this->getTestClient();
$client->request('GET', '/feed/admin/SUPERTOKEN/starred');
$this->assertSame(200, $client->getResponse()->getStatusCode(), 1);
$this->validateDom($client->getResponse()->getContent(), 'starred');
}
public function testArchives()
{
$client = $this->getTestClient();
$em = $client->getContainer()->get(EntityManagerInterface::class);
$user = $em
->getRepository(User::class)
->findOneByUsername('admin');
$config = $user->getConfig();
$config->setFeedToken('SUPERTOKEN');
$config->setFeedLimit(null);
$em->persist($config);
$em->flush();
$client = $this->getTestClient();
$client->request('GET', '/feed/admin/SUPERTOKEN/archive');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->validateDom($client->getResponse()->getContent(), 'archive');
}
public function testAll()
{
$client = $this->getTestClient();
$em = $client->getContainer()->get(EntityManagerInterface::class);
$user = $em
->getRepository(User::class)
->findOneByUsername('admin');
$config = $user->getConfig();
$config->setFeedToken('SUPERTOKEN');
$config->setFeedLimit(null);
$em->persist($config);
$em->flush();
$client = $this->getTestClient();
$client->request('GET', '/feed/admin/SUPERTOKEN/all');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->validateDom($client->getResponse()->getContent(), 'all');
}
public function testPagination()
{
$client = $this->getTestClient();
$em = $client->getContainer()->get(EntityManagerInterface::class);
$user = $em
->getRepository(User::class)
->findOneByUsername('admin');
$config = $user->getConfig();
$config->setFeedToken('SUPERTOKEN');
$config->setFeedLimit(1);
$em->persist($config);
$em->flush();
$client = $this->getTestClient();
$client->request('GET', '/feed/admin/SUPERTOKEN/unread');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->validateDom($client->getResponse()->getContent(), 'unread');
$client->request('GET', '/feed/admin/SUPERTOKEN/unread/2');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->validateDom($client->getResponse()->getContent(), 'unread');
$client->request('GET', '/feed/admin/SUPERTOKEN/unread/3000');
$this->assertSame(302, $client->getResponse()->getStatusCode());
}
public function testTags()
{
$client = $this->getTestClient();
$em = $client->getContainer()->get(EntityManagerInterface::class);
$user = $em
->getRepository(User::class)
->findOneByUsername('admin');
$config = $user->getConfig();
$config->setFeedToken('SUPERTOKEN');
$config->setFeedLimit(null);
$em->persist($config);
$entry1 = $em
->getRepository(Entry::class)
->find(1)
;
$entry4 = $em
->getRepository(Entry::class)
->find(4)
;
$now = new \DateTimeImmutable('now');
$day1 = $now->modify('-8 days');
$day2 = $now->modify('-6 days');
$day3 = $now->modify('-4 days');
$day4 = $now->modify('-2 days');
$entry1->setCreatedAt($day1);
$entry4->setCreatedAt($day2);
$property = (new \ReflectionObject($entry4))->getProperty('updatedAt');
$property->setAccessible(true);
$property->setValue($entry4, $day3);
// We have to flush and sleep here to be sure that $entry1 and $entry4 have different updatedAt values
$em->flush();
sleep(2);
$property = (new \ReflectionObject($entry1))->getProperty('updatedAt');
$property->setAccessible(true);
$property->setValue($entry1, $day4);
$em->flush();
$client = $this->getTestClient();
// tag foo - without sort
$crawler = $client->request('GET', '/feed/admin/SUPERTOKEN/tags/t:foo');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->assertSame('test title entry4', $crawler->filterXPath('//feed/entry[1]/title')->text());
$this->assertSame('test title entry1', $crawler->filterXPath('//feed/entry[2]/title')->text());
// tag foo - with sort created
$crawler = $client->request('GET', '/feed/admin/SUPERTOKEN/tags/t:foo?sort=created');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->assertSame('test title entry4', $crawler->filterXPath('//feed/entry[1]/title')->text());
$this->assertSame('test title entry1', $crawler->filterXPath('//feed/entry[2]/title')->text());
// tag foo - with sort updated
$crawler = $client->request('GET', '/feed/admin/SUPERTOKEN/tags/t:foo?sort=updated');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->assertSame('test title entry1', $crawler->filterXPath('//feed/entry[1]/title')->text());
$this->assertSame('test title entry4', $crawler->filterXPath('//feed/entry[2]/title')->text());
// tag foo - with invalid sort
$client->request('GET', '/feed/admin/SUPERTOKEN/tags/t:foo?sort=invalid');
$this->assertSame(400, $client->getResponse()->getStatusCode());
// tag foo/3000
$client->request('GET', '/feed/admin/SUPERTOKEN/tags/t:foo/3000');
$this->assertSame(302, $client->getResponse()->getStatusCode());
}
public function dataForRedirect()
{
return [
[
'/admin/YZIOAUZIAO/unread.xml',
],
[
'/admin/YZIOAUZIAO/starred.xml',
],
[
'/admin/YZIOAUZIAO/archive.xml',
],
[
'/admin/YZIOAUZIAO/all.xml',
],
[
'/admin/YZIOAUZIAO/tags/foo.xml',
],
];
}
/**
* @dataProvider dataForRedirect
*/
public function testRedirectFromRssToAtom($url)
{
$client = $this->getTestClient();
$client->request('GET', $url);
$this->assertSame(301, $client->getResponse()->getStatusCode());
}
}

View file

@ -0,0 +1,148 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
class IgnoreOriginInstanceRuleControllerTest extends WallabagCoreTestCase
{
public function testListIgnoreOriginInstanceRule()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/ignore-origin-instance-rules/');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$body = $crawler->filter('body')->extract(['_text'])[0];
$this->assertStringContainsString('ignore_origin_instance_rule.description', $body);
$this->assertStringContainsString('ignore_origin_instance_rule.list.create_new_one', $body);
}
public function testIgnoreOriginInstanceRuleCreationEditionDeletion()
{
$this->logInAs('admin');
$client = $this->getTestClient();
// Creation
$crawler = $client->request('GET', '/ignore-origin-instance-rules/new');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$body = $crawler->filter('body')->extract(['_text'])[0];
$this->assertStringContainsString('ignore_origin_instance_rule.new_ignore_origin_instance_rule', $body);
$this->assertStringContainsString('ignore_origin_instance_rule.form.back_to_list', $body);
$form = $crawler->filter('button[id=ignore_origin_instance_rule_save]')->form();
$data = [
'ignore_origin_instance_rule[rule]' => 'host = "foo.example.com"',
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertStringContainsString('flashes.ignore_origin_instance_rule.notice.added', $crawler->filter('body')->extract(['_text'])[0]);
// Edition
$editLink = $crawler->filter('div[id=content] table a')->last()->link();
$crawler = $client->click($editLink);
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->assertStringContainsString('foo.example.com', $crawler->filter('form[name=ignore_origin_instance_rule] input[type=text]')->extract(['value'])[0]);
$body = $crawler->filter('body')->extract(['_text'])[0];
$this->assertStringContainsString('ignore_origin_instance_rule.edit_ignore_origin_instance_rule', $body);
$this->assertStringContainsString('ignore_origin_instance_rule.form.back_to_list', $body);
$form = $crawler->filter('button[id=ignore_origin_instance_rule_save]')->form();
$data = [
'ignore_origin_instance_rule[rule]' => 'host = "bar.example.com"',
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertStringContainsString('flashes.ignore_origin_instance_rule.notice.updated', $crawler->filter('body')->extract(['_text'])[0]);
$editLink = $crawler->filter('div[id=content] table a')->last()->link();
$crawler = $client->click($editLink);
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->assertStringContainsString('bar.example.com', $crawler->filter('form[name=ignore_origin_instance_rule] input[type=text]')->extract(['value'])[0]);
$deleteForm = $crawler->filter('body')->selectButton('ignore_origin_instance_rule.form.delete')->form();
$client->submit($deleteForm, []);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertStringContainsString('flashes.ignore_origin_instance_rule.notice.deleted', $crawler->filter('body')->extract(['_text'])[0]);
}
public function dataForIgnoreOriginInstanceRuleCreationFail()
{
return [
[
[
'ignore_origin_instance_rule[rule]' => 'foo = "bar"',
],
[
'The variable',
'does not exist.',
],
],
[
[
'ignore_origin_instance_rule[rule]' => '_all != "none"',
],
[
'The operator',
'does not exist.',
],
],
];
}
/**
* @dataProvider dataForIgnoreOriginInstanceRuleCreationFail
*/
public function testIgnoreOriginInstanceRuleCreationFail($data, $messages)
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/ignore-origin-instance-rules/new');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$form = $crawler->filter('button[id=ignore_origin_instance_rule_save]')->form();
$crawler = $client->submit($form, $data);
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
foreach ($messages as $message) {
$this->assertStringContainsString($message, $body[0]);
}
}
}

View file

@ -0,0 +1,158 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Import;
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 ChromeControllerTest extends WallabagCoreTestCase
{
public function testImportChrome()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/chrome');
$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 testImportChromeWithRabbitEnabled()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1);
$crawler = $client->request('GET', '/import/chrome');
$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 testImportChromeBadFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/chrome');
$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 testImportChromeWithRedisEnabled()
{
$this->checkRedis();
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_redis', 1);
$crawler = $client->request('GET', '/import/chrome');
$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/Import/chrome-bookmarks', '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.chrome'));
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
}
public function testImportWallabagWithChromeFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/chrome');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/chrome-bookmarks', '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/3256363-20220321-tournoi-vi-nations-trophee-gagne-xv-france-fini-fond-seine',
$this->getLoggedInUserId()
);
$this->assertInstanceOf(Entry::class, $content);
$this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for https://www.20minutes.fr is ok');
$this->assertNotEmpty($content->getLanguage(), 'Language for https://www.20minutes.fr is ok');
$this->assertCount(1, $content->getTags());
$createdAt = $content->getCreatedAt();
$this->assertSame('2011', $createdAt->format('Y'));
$this->assertSame('07', $createdAt->format('m'));
}
public function testImportWallabagWithEmptyFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/chrome');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/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

@ -0,0 +1,203 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Import;
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 DeliciousControllerTest extends WallabagCoreTestCase
{
public function testImportDelicious()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$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->getTestClient();
$client->getContainer()->get(Config::class)->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(Config::class)->set('import_with_rabbitmq', 0);
}
public function testImportDeliciousBadFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$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->getTestClient();
$client->getContainer()->get(Config::class)->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/Import/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(Client::class)->lpop('wallabag.import.delicious'));
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
}
public function testImportDeliciousWithFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/delicious');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/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(EntityManagerInterface::class)
->getRepository(Entry::class)
->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(Entry::class, $content);
$tags = $content->getTagsLabel();
$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->getTestClient();
$crawler = $client->request('GET', '/import/delicious');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/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(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId(
'https://stackoverflow.com/review/',
$this->getLoggedInUserId()
);
$this->assertInstanceOf(Entry::class, $content1);
$content2 = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId(
'https://addyosmani.com/basket.js/',
$this->getLoggedInUserId()
);
$this->assertInstanceOf(Entry::class, $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->getTestClient();
$crawler = $client->request('GET', '/import/delicious');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/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

@ -0,0 +1,136 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Import;
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 ElcuratorControllerTest extends WallabagCoreTestCase
{
public function testImportElcurator()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/elcurator');
$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 testImportElcuratorWithRabbitEnabled()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1);
$crawler = $client->request('GET', '/import/elcurator');
$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 testImportElcuratorBadFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/elcurator');
$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 testImportElcuratorWithRedisEnabled()
{
$this->checkRedis();
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_redis', 1);
$crawler = $client->request('GET', '/import/elcurator');
$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/Import/elcurator.json', 'elcurator.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(Client::class)->lpop('wallabag.import.elcurator'));
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
}
public function testImportElcuratorWithFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/elcurator');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/elcurator.json', 'elcurator.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]);
$content = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId(
'https://devblog.lexik.fr/git/qualite-de-code-integration-de-php-git-hooks-dans-symfony2-2842',
$this->getLoggedInUserId()
);
$this->assertInstanceOf(Entry::class, $content);
$this->assertStringContainsString('Qualité de code - Intégration de php-git-hooks dans Symfony2', $content->getTitle());
$this->assertSame('2015-09-09', $content->getCreatedAt()->format('Y-m-d'));
$this->assertTrue($content->isStarred(), 'Entry is starred');
$tags = $content->getTagsLabel();
$this->assertContains('tag1', $tags, 'It includes the "tag1" tag');
$this->assertContains('tag2', $tags, 'It includes the "tag2" tag');
}
}

View file

@ -0,0 +1,172 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Import;
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 FirefoxControllerTest extends WallabagCoreTestCase
{
public function testImportFirefox()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/firefox');
$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 testImportFirefoxWithRabbitEnabled()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1);
$crawler = $client->request('GET', '/import/firefox');
$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 testImportFirefoxBadFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/firefox');
$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 testImportFirefoxWithRedisEnabled()
{
$this->checkRedis();
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_redis', 1);
$crawler = $client->request('GET', '/import/firefox');
$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/Import/firefox-bookmarks.json', '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.firefox'));
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
}
public function testImportWallabagWithFirefoxFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/firefox');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/firefox-bookmarks.json', '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');
$createdAt = $content->getCreatedAt();
$this->assertSame('2013', $createdAt->format('Y'));
$this->assertSame('12', $createdAt->format('m'));
}
public function testImportWallabagWithEmptyFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/firefox');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/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

@ -0,0 +1,29 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Import;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
class ImportControllerTest extends WallabagCoreTestCase
{
public function testLogin()
{
$client = $this->getTestClient();
$client->request('GET', '/import/');
$this->assertSame(302, $client->getResponse()->getStatusCode());
$this->assertStringContainsString('login', $client->getResponse()->headers->get('location'));
}
public function testImportList()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->assertSame(12, $crawler->filter('blockquote')->count());
}
}

View file

@ -0,0 +1,216 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Import;
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 InstapaperControllerTest extends WallabagCoreTestCase
{
public function testImportInstapaper()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/instapaper');
$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 testImportInstapaperWithRabbitEnabled()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1);
$crawler = $client->request('GET', '/import/instapaper');
$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 testImportInstapaperBadFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/instapaper');
$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 testImportInstapaperWithRedisEnabled()
{
$this->checkRedis();
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_redis', 1);
$crawler = $client->request('GET', '/import/instapaper');
$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/Import/instapaper-export.csv', 'instapaper.csv');
$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.instapaper'));
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
}
public function testImportInstapaperWithFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/instapaper');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/instapaper-export.csv', 'instapaper.csv');
$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.liberation.fr/societe/police-justice/cours-dassises-on-efface-le-peuple-dun-processus-judiciaire-dont-il-est-pourtant-le-coeur-battant-20210414_FYUNIZENHRGHZLAZEKSMKZYEPI/',
$this->getLoggedInUserId()
);
$this->assertInstanceOf(Entry::class, $content);
$this->assertNotEmpty($content->getMimetype(), 'Mimetype for https://www.liberation.fr is ok');
$this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for https://www.liberation.fr is ok');
$this->assertNotEmpty($content->getLanguage(), 'Language for https://www.liberation.fr is ok');
$this->assertContains('foot', $content->getTagsLabel(), 'It includes the "foot" tag');
$this->assertCount(1, $content->getTags());
$this->assertInstanceOf(\DateTime::class, $content->getCreatedAt());
$content = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId(
'https://www.20minutes.fr/high-tech/2077615-20170531-quoi-exactement-tweet-covfefe-donald-trump-persiste-signe',
$this->getLoggedInUserId()
);
$this->assertContains('foot', $content->getTagsLabel());
$this->assertContains('test_tag', $content->getTagsLabel());
$this->assertCount(2, $content->getTags());
}
public function testImportInstapaperWithFileAndMarkAllAsRead()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/instapaper');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/instapaper-export.csv', 'instapaper-read.csv');
$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(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId(
'https://redditblog.com/2016/09/20/amp-and-reactredux/',
$this->getLoggedInUserId()
);
$this->assertTrue($content1->isArchived());
$content2 = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId(
'https://medium.com/@the_minh/why-foursquare-swarm-is-still-my-favourite-social-network-e38228493e6c',
$this->getLoggedInUserId()
);
$this->assertTrue($content2->isArchived());
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
$this->assertStringContainsString('flashes.import.notice.summary', $body[0]);
}
public function testImportInstapaperWithEmptyFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/instapaper');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/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

@ -0,0 +1,210 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Import;
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 PinboardControllerTest extends WallabagCoreTestCase
{
public function testImportPinboard()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/pinboard');
$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 testImportPinboardWithRabbitEnabled()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1);
$crawler = $client->request('GET', '/import/pinboard');
$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 testImportPinboardBadFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/pinboard');
$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 testImportPinboardWithRedisEnabled()
{
$this->checkRedis();
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_redis', 1);
$crawler = $client->request('GET', '/import/pinboard');
$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/Import/pinboard_export', 'pinboard.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(Client::class)->lpop('wallabag.import.pinboard'));
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
}
public function testImportPinboardWithFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/pinboard');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/pinboard_export', 'pinboard.json');
$data = [
'upload_import_file[file]' => $file,
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$content = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId(
'https://ma.ttias.be/varnish-explained/',
$this->getLoggedInUserId()
);
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
$this->assertStringContainsString('flashes.import.notice.summary', $body[0]);
$this->assertInstanceOf(Entry::class, $content);
$this->assertNotEmpty($content->getMimetype(), 'Mimetype for https://ma.ttias.be is ok');
$this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for https://ma.ttias.be is ok');
$this->assertNotEmpty($content->getLanguage(), 'Language for https://ma.ttias.be is ok');
$tags = $content->getTagsLabel();
$this->assertContains('foot', $tags, 'It includes the "foot" tag');
$this->assertContains('varnish', $tags, 'It includes the "varnish" tag');
$this->assertContains('php', $tags, 'It includes the "php" tag');
$this->assertCount(3, $tags);
$this->assertInstanceOf(\DateTime::class, $content->getCreatedAt());
$this->assertSame('2016-10-26', $content->getCreatedAt()->format('Y-m-d'));
}
public function testImportPinboardWithFileAndMarkAllAsRead()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/pinboard');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/pinboard_export', 'pinboard-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(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId(
'https://ilia.ws/files/nginx_torontophpug.pdf',
$this->getLoggedInUserId()
);
$this->assertInstanceOf(Entry::class, $content1);
$this->assertTrue($content1->isArchived());
$content2 = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId(
'https://developers.google.com/web/updates/2016/07/infinite-scroller',
$this->getLoggedInUserId()
);
$this->assertInstanceOf(Entry::class, $content2);
$this->assertTrue($content2->isArchived());
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
$this->assertStringContainsString('flashes.import.notice.summary', $body[0]);
}
public function testImportPinboardWithEmptyFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/pinboard');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/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

@ -0,0 +1,142 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Import;
use Craue\ConfigBundle\Util\Config;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
use Wallabag\CoreBundle\Import\PocketImport;
class PocketControllerTest extends WallabagCoreTestCase
{
public function testImportPocket()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/pocket');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->assertSame(1, $crawler->filter('button[name=action]')->count());
}
public function testImportPocketWithRabbitEnabled()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1);
$crawler = $client->request('GET', '/import/pocket');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->assertSame(1, $crawler->filter('button[name=action]')->count());
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 0);
}
public function testImportPocketWithRedisEnabled()
{
$this->checkRedis();
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_redis', 1);
$crawler = $client->request('GET', '/import/pocket');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->assertSame(1, $crawler->filter('button[name=action]')->count());
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
}
public function testImportPocketAuthBadToken()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->request('GET', '/import/pocket/auth');
$this->assertSame(302, $client->getResponse()->getStatusCode());
}
public function testImportPocketAuth()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$pocketImport = $this->getMockBuilder(PocketImport::class)
->disableOriginalConstructor()
->getMock();
$pocketImport
->expects($this->once())
->method('getRequestToken')
->willReturn('token');
static::$kernel->getContainer()->set(PocketImport::class, $pocketImport);
$client->request('GET', '/import/pocket/auth');
$this->assertSame(301, $client->getResponse()->getStatusCode());
$this->assertStringContainsString('getpocket.com/auth/authorize', $client->getResponse()->headers->get('location'));
}
public function testImportPocketCallbackWithBadToken()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$pocketImport = $this->getMockBuilder(PocketImport::class)
->disableOriginalConstructor()
->getMock();
$pocketImport
->expects($this->once())
->method('authorize')
->willReturn(false);
static::$kernel->getContainer()->set(PocketImport::class, $pocketImport);
$client->request('GET', '/import/pocket/callback');
$this->assertSame(302, $client->getResponse()->getStatusCode());
$this->assertStringContainsString('/', $client->getResponse()->headers->get('location'), 'Import is ok, redirect to homepage');
$this->assertSame('flashes.import.notice.failed', $client->getContainer()->get(SessionInterface::class)->getFlashBag()->peek('notice')[0]);
}
public function testImportPocketCallback()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$pocketImport = $this->getMockBuilder(PocketImport::class)
->disableOriginalConstructor()
->getMock();
$pocketImport
->expects($this->once())
->method('authorize')
->willReturn(true);
$pocketImport
->expects($this->once())
->method('setMarkAsRead')
->with(false)
->willReturn($pocketImport);
$pocketImport
->expects($this->once())
->method('import')
->willReturn(true);
static::$kernel->getContainer()->set(PocketImport::class, $pocketImport);
$client->request('GET', '/import/pocket/callback');
$this->assertSame(302, $client->getResponse()->getStatusCode());
$this->assertStringContainsString('/', $client->getResponse()->headers->get('location'), 'Import is ok, redirect to homepage');
$this->assertSame('flashes.import.notice.summary', $client->getContainer()->get(SessionInterface::class)->getFlashBag()->peek('notice')[0]);
}
}

View file

@ -0,0 +1,168 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Import;
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/Import/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/Import/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/Import/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]);
}
}

View file

@ -0,0 +1,208 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Import;
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 ReadabilityControllerTest extends WallabagCoreTestCase
{
public function testImportReadability()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/readability');
$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 testImportReadabilityWithRabbitEnabled()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1);
$crawler = $client->request('GET', '/import/readability');
$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 testImportReadabilityBadFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/readability');
$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 testImportReadabilityWithRedisEnabled()
{
$this->checkRedis();
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_redis', 1);
$crawler = $client->request('GET', '/import/readability');
$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/Import/readability.json', 'readability.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(Client::class)->lpop('wallabag.import.readability'));
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
}
public function testImportReadabilityWithFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/readability');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/readability.json', 'readability.json');
$data = [
'upload_import_file[file]' => $file,
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$content = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId(
'https://www.20minutes.fr/bordeaux/2120479-20170823-bordeaux-poche-chocolatine-association-traduit-etudiants-etrangers-mots-sud-ouest',
$this->getLoggedInUserId()
);
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
$this->assertStringContainsString('flashes.import.notice.summary', $body[0]);
$this->assertInstanceOf(Entry::class, $content);
$this->assertNotEmpty($content->getMimetype(), 'Mimetype for https://www.20minutes.fr is ok');
$this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for https://www.20minutes.fr is ok');
$this->assertNotEmpty($content->getLanguage(), 'Language for https://www.20minutes.fr is ok');
$tags = $content->getTagsLabel();
$this->assertContains('foot', $tags, 'It includes the "foot" tag');
$this->assertCount(1, $tags);
$this->assertInstanceOf(\DateTime::class, $content->getCreatedAt());
$this->assertSame('2016-09-08', $content->getCreatedAt()->format('Y-m-d'));
}
public function testImportReadabilityWithFileAndMarkAllAsRead()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/readability');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/readability-read.json', 'readability-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(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId(
'https://blog.travis-ci.com/2016-07-28-what-we-learned-from-analyzing-2-million-travis-builds/',
$this->getLoggedInUserId()
);
$this->assertInstanceOf(Entry::class, $content1);
$this->assertTrue($content1->isArchived());
$content2 = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId(
'https://facebook.github.io/graphql/October2016/',
$this->getLoggedInUserId()
);
$this->assertInstanceOf(Entry::class, $content2);
$this->assertTrue($content2->isArchived());
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
$this->assertStringContainsString('flashes.import.notice.summary', $body[0]);
}
public function testImportReadabilityWithEmptyFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/readability');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/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

@ -0,0 +1,168 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Import;
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/Import/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/Import/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/Import/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]);
}
}

View file

@ -0,0 +1,209 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Import;
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 WallabagV1ControllerTest extends WallabagCoreTestCase
{
public function testImportWallabag()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/wallabag-v1');
$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 testImportWallabagWithRabbitEnabled()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1);
$crawler = $client->request('GET', '/import/wallabag-v1');
$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 testImportWallabagBadFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/wallabag-v1');
$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 testImportWallabagWithRedisEnabled()
{
$this->checkRedis();
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_redis', 1);
$crawler = $client->request('GET', '/import/wallabag-v1');
$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/Import/wallabag-v1.json', 'wallabag-v1.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(Client::class)->lpop('wallabag.import.wallabag_v1'));
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
}
public function testImportWallabagWithFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/wallabag-v1');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/wallabag-v1.json', 'wallabag-v1.json');
$data = [
'upload_import_file[file]' => $file,
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$content = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId(
'http://www.framablog.org/index.php/post/2014/02/05/Framabag-service-libre-gratuit-interview-developpeur',
$this->getLoggedInUserId()
);
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
$this->assertStringContainsString('flashes.import.notice.summary', $body[0]);
$this->assertInstanceOf(Entry::class, $content);
$this->assertEmpty($content->getMimetype(), 'Mimetype for http://www.framablog.org is empty');
$this->assertSame($content->getPreviewPicture(), 'http://www.framablog.org/public/_img/framablog/wallaby_baby.jpg');
$this->assertEmpty($content->getLanguage(), 'Language for http://www.framablog.org is empty');
$tags = $content->getTagsLabel();
$this->assertContains('foot', $tags, 'It includes the "foot" tag');
$this->assertContains('framabag', $tags, 'It includes the "framabag" tag');
$this->assertCount(2, $tags);
$this->assertInstanceOf(\DateTime::class, $content->getCreatedAt());
}
public function testImportWallabagWithFileAndMarkAllAsRead()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/wallabag-v1');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/wallabag-v1-read.json', 'wallabag-v1-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(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId(
'http://gilbert.pellegrom.me/recreating-the-square-slider',
$this->getLoggedInUserId()
);
$this->assertInstanceOf(Entry::class, $content1);
$this->assertTrue($content1->isArchived());
$content2 = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId(
'https://www.wallabag.org/features/',
$this->getLoggedInUserId()
);
$this->assertInstanceOf(Entry::class, $content2);
$this->assertTrue($content2->isArchived());
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
$this->assertStringContainsString('flashes.import.notice.summary', $body[0]);
}
public function testImportWallabagWithEmptyFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/wallabag-v1');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/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

@ -0,0 +1,184 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller\Import;
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 WallabagV2ControllerTest extends WallabagCoreTestCase
{
public function testImportWallabag()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/wallabag-v2');
$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 testImportWallabagWithRabbitEnabled()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1);
$crawler = $client->request('GET', '/import/wallabag-v2');
$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 testImportWallabagBadFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/wallabag-v2');
$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 testImportWallabagWithRedisEnabled()
{
$this->checkRedis();
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('import_with_redis', 1);
$crawler = $client->request('GET', '/import/wallabag-v2');
$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/Import/wallabag-v2.json', 'wallabag-v2.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(Client::class)->lpop('wallabag.import.wallabag_v2'));
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
}
public function testImportWallabagWithFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/wallabag-v2');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/wallabag-v2.json', 'wallabag-v2.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]);
$content = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId(
'https://www.liberation.fr/planete/2015/10/26/refugies-l-ue-va-creer-100-000-places-d-accueil-dans-les-balkans_1408867',
$this->getLoggedInUserId()
);
$this->assertInstanceOf(Entry::class, $content);
// empty because it wasn't re-imported
$this->assertEmpty($content->getMimetype(), 'Mimetype for https://www.liberation.fr is empty');
$this->assertEmpty($content->getPreviewPicture(), 'Preview picture for https://www.liberation.fr is empty');
$this->assertEmpty($content->getLanguage(), 'Language for https://www.liberation.fr is empty');
$tags = $content->getTagsLabel();
$this->assertContains('foot', $tags, 'It includes the "foot" tag');
$this->assertCount(1, $tags);
$content = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId(
'https://www.mediapart.fr/',
$this->getLoggedInUserId()
);
$this->assertInstanceOf(Entry::class, $content);
$this->assertNotEmpty($content->getMimetype(), 'Mimetype for https://www.mediapart.fr is ok');
$this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for https://www.mediapart.fr is ok');
$this->assertNotEmpty($content->getLanguage(), 'Language for https://www.mediapart.fr is ok');
$tags = $content->getTagsLabel();
$this->assertContains('foot', $tags, 'It includes the "foot" tag');
$this->assertContains('mediapart', $tags, 'It includes the "mediapart" tag');
$this->assertContains('blog', $tags, 'It includes the "blog" tag');
$this->assertCount(3, $tags);
$this->assertInstanceOf(\DateTime::class, $content->getCreatedAt());
$this->assertSame('2016-09-08', $content->getCreatedAt()->format('Y-m-d'));
$this->assertTrue($content->isStarred(), 'Entry is starred');
}
public function testImportWallabagWithEmptyFile()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/import/wallabag-v2');
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/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

@ -0,0 +1,99 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller;
use Doctrine\ORM\EntityManagerInterface;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
use Wallabag\CoreBundle\Entity\User;
class SecurityControllerTest extends WallabagCoreTestCase
{
public function testLoginWithEmail()
{
$this->logInAsUsingHttp('bigboss@wallabag.org');
$client = $this->getTestClient();
$client->followRedirects();
$crawler = $client->request('GET', '/config');
$this->assertStringContainsString('config.form_feed.description', $crawler->filter('body')->extract(['_text'])[0]);
}
public function testLoginWithout2Factor()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->followRedirects();
$crawler = $client->request('GET', '/config');
$this->assertStringContainsString('config.form_feed.description', $crawler->filter('body')->extract(['_text'])[0]);
}
public function testLoginWith2FactorEmail()
{
$client = $this->getTestClient();
$client->followRedirects();
$em = $client->getContainer()->get(EntityManagerInterface::class);
$user = $em
->getRepository(User::class)
->findOneByUsername('admin');
$user->setEmailTwoFactor(true);
$em->persist($user);
$em->flush();
$this->logInAsUsingHttp('admin');
$crawler = $client->request('GET', '/config');
$this->assertStringContainsString('trusted', $crawler->filter('body')->extract(['_text'])[0]);
// restore user
$user = $em
->getRepository(User::class)
->findOneByUsername('admin');
$user->setEmailTwoFactor(false);
$em->persist($user);
$em->flush();
}
public function testLoginWith2FactorGoogle()
{
$client = $this->getTestClient();
$client->followRedirects();
$em = $client->getContainer()->get(EntityManagerInterface::class);
$user = $em
->getRepository(User::class)
->findOneByUsername('admin');
$user->setGoogleAuthenticatorSecret('26LDIHYGHNELOQEM');
$em->persist($user);
$em->flush();
$this->logInAsUsingHttp('admin');
$crawler = $client->request('GET', '/config');
$this->assertStringContainsString('trusted', $crawler->filter('body')->extract(['_text'])[0]);
// restore user
$user = $em
->getRepository(User::class)
->findOneByUsername('admin');
$user->setGoogleAuthenticatorSecret(null);
$em->persist($user);
$em->flush();
}
public function testEnabledRegistration()
{
$client = $this->getTestClient();
if (!$client->getContainer()->getParameter('fosuser_registration')) {
$this->markTestSkipped('fosuser_registration is not enabled.');
return;
}
$client->followRedirects();
$client->request('GET', '/register');
$this->assertStringContainsString('registration.submit', $client->getResponse()->getContent());
}
}

View file

@ -0,0 +1,32 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
/**
* The controller `SettingsController` does not exist.
* This test cover security against the internal settings page managed by CraueConfigBundle.
*/
class SettingsControllerTest extends WallabagCoreTestCase
{
public function testSettingsWithAdmin()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/settings');
$this->assertSame(200, $client->getResponse()->getStatusCode());
}
public function testSettingsWithNormalUser()
{
$this->logInAs('bob');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/settings');
$this->assertSame(403, $client->getResponse()->getStatusCode());
}
}

View file

@ -0,0 +1,155 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller;
use Craue\ConfigBundle\Util\Config;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
use Wallabag\CoreBundle\Entity\SiteCredential;
class SiteCredentialControllerTest extends WallabagCoreTestCase
{
public function testAccessDeniedBecauseFeatureDisabled()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->getContainer()->get(Config::class)->set('restricted_access', 0);
$client->request('GET', '/site-credentials/');
$this->assertSame(404, $client->getResponse()->getStatusCode());
$client->getContainer()->get(Config::class)->set('restricted_access', 1);
}
public function testListSiteCredential()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/site-credentials/');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$body = $crawler->filter('body')->extract(['_text'])[0];
$this->assertStringContainsString('site_credential.description', $body);
$this->assertStringContainsString('site_credential.list.create_new_one', $body);
}
public function testNewSiteCredential()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/site-credentials/new');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$body = $crawler->filter('body')->extract(['_text'])[0];
$this->assertStringContainsString('site_credential.new_site_credential', $body);
$this->assertStringContainsString('site_credential.form.back_to_list', $body);
$form = $crawler->filter('button[id=site_credential_save]')->form();
$data = [
'site_credential[host]' => 'google.io',
'site_credential[username]' => 'sergei',
'site_credential[password]' => 'microsoft',
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertStringContainsString('flashes.site_credential.notice.added', $crawler->filter('body')->extract(['_text'])[0]);
}
public function testEditSiteCredential()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$credential = $this->createSiteCredential($client);
$crawler = $client->request('GET', '/site-credentials/' . $credential->getId() . '/edit');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$body = $crawler->filter('body')->extract(['_text'])[0];
$this->assertStringContainsString('site_credential.edit_site_credential', $body);
$this->assertStringContainsString('site_credential.form.back_to_list', $body);
$form = $crawler->filter('button[id=site_credential_save]')->form();
$data = [
'site_credential[host]' => 'google.io',
'site_credential[username]' => 'larry',
'site_credential[password]' => 'microsoft',
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertStringContainsString('flashes.site_credential.notice.updated', $crawler->filter('body')->extract(['_text'])[0]);
}
public function testEditFromADifferentUserSiteCredential()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$credential = $this->createSiteCredential($client);
$this->logInAs('bob');
$client->request('GET', '/site-credentials/' . $credential->getId() . '/edit');
$this->assertSame(403, $client->getResponse()->getStatusCode());
}
public function testDeleteSiteCredential()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$credential = $this->createSiteCredential($client);
$crawler = $client->request('GET', '/site-credentials/' . $credential->getId() . '/edit');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$deleteForm = $crawler->filter('body')->selectButton('site_credential.form.delete')->form();
$client->submit($deleteForm, []);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertStringContainsString('flashes.site_credential.notice.deleted', $crawler->filter('body')->extract(['_text'])[0]);
}
private function createSiteCredential(KernelBrowser $client)
{
$credential = new SiteCredential($this->getLoggedInUser());
$credential->setHost('google.io');
$credential->setUsername('sergei');
$credential->setPassword('microsoft');
$em = $client->getContainer()->get(EntityManagerInterface::class);
$em->persist($credential);
$em->flush();
return $credential;
}
}

View file

@ -0,0 +1,28 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
class StaticControllerTest extends WallabagCoreTestCase
{
public function testAbout()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->request('GET', '/about');
$this->assertSame(200, $client->getResponse()->getStatusCode());
}
public function testHowto()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->request('GET', '/howto');
$this->assertSame(200, $client->getResponse()->getStatusCode());
}
}

View file

@ -0,0 +1,573 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller;
use Doctrine\ORM\EntityManagerInterface;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\CoreBundle\Entity\Tag;
use Wallabag\CoreBundle\Entity\User;
/**
* @group Tag
*/
class TagControllerTest extends WallabagCoreTestCase
{
public $tagName = 'opensource';
public $caseTagName = 'OpenSource';
public function testList()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$client->request('GET', '/tag/list');
$this->assertSame(200, $client->getResponse()->getStatusCode());
}
public function testAddTagToEntry()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$entry = new Entry($this->getLoggedInUser());
$entry->setUrl('http://0.0.0.0/foo');
$this->getEntityManager()->persist($entry);
$this->getEntityManager()->flush();
$this->getEntityManager()->clear();
$crawler = $client->request('GET', '/view/' . $entry->getId());
$form = $crawler->filter('form[name=tag]')->form();
$data = [
'tag[label]' => $this->caseTagName,
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
// be sure to reload the entry
$entry = $this->getEntityManager()->getRepository(Entry::class)->find($entry->getId());
$this->assertCount(1, $entry->getTags());
$this->assertContains($this->tagName, $entry->getTagsLabel());
// tag already exists and already assigned
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$entry = $this->getEntityManager()->getRepository(Entry::class)->find($entry->getId());
$this->assertCount(1, $entry->getTags());
// tag already exists but still not assigned to this entry
$data = [
'tag[label]' => 'foo bar',
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$entry = $this->getEntityManager()->getRepository(Entry::class)->find($entry->getId());
$this->assertCount(2, $entry->getTags());
}
public function testAddMultipleTagToEntry()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$entry = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId('http://0.0.0.0/entry2', $this->getLoggedInUserId());
$crawler = $client->request('GET', '/view/' . $entry->getId());
$form = $crawler->filter('form[name=tag]')->form();
$data = [
'tag[label]' => 'foo2, Bar2',
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$newEntry = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->find($entry->getId());
$tags = $newEntry->getTags()->toArray();
foreach ($tags as $key => $tag) {
$tags[$key] = $tag->getLabel();
}
$this->assertGreaterThanOrEqual(2, \count($tags));
$this->assertNotFalse(array_search('foo2', $tags, true), 'Tag foo2 is assigned to the entry');
$this->assertNotFalse(array_search('bar2', $tags, true), 'Tag bar2 is assigned to the entry');
}
public function testRemoveTagFromEntry()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$tag = new Tag();
$tag->setLabel($this->tagName);
$entry = new Entry($this->getLoggedInUser());
$entry->setUrl('http://0.0.0.0/foo');
$entry->addTag($tag);
$this->getEntityManager()->persist($entry);
$this->getEntityManager()->flush();
$this->getEntityManager()->clear();
// We make a first request to set an history and test redirection after tag deletion
$crawler = $client->request('GET', '/view/' . $entry->getId());
$entryUri = $client->getRequest()->getRequestUri();
$link = $crawler->filter('a[href^="/remove-tag/' . $entry->getId() . '/' . $tag->getId() . '"]')->link();
$client->click($link);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$this->assertSame($entryUri, $client->getResponse()->getTargetUrl());
// re-retrieve the entry to be sure to get fresh data from database (mostly for tags)
$entry = $this->getEntityManager()->getRepository(Entry::class)->find($entry->getId());
$this->assertNotContains($this->tagName, $entry->getTagsLabel());
$client->request('GET', '/remove-tag/' . $entry->getId() . '/' . $tag->getId());
$this->assertSame(404, $client->getResponse()->getStatusCode());
$tag = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Tag::class)
->findOneByLabel($this->tagName);
$this->assertNull($tag, $this->tagName . ' was removed because it begun an orphan tag');
}
public function testRemoveTag()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$tag = new Tag();
$tag->setLabel($this->tagName);
$entry = new Entry($this->getLoggedInUser());
$entry->setUrl('http://0.0.0.0/foo');
$entry->addTag($tag);
$this->getEntityManager()->persist($entry);
$entry2 = new Entry($this->getLoggedInUser());
$entry2->setUrl('http://0.0.0.0/bar');
$entry2->addTag($tag);
$this->getEntityManager()->persist($entry2);
$this->getEntityManager()->flush();
$this->getEntityManager()->clear();
$crawler = $client->request('GET', '/tag/list');
$link = $crawler->filter('a[id="delete-' . $tag->getSlug() . '"]')->link();
$client->click($link);
$tag = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Tag::class)
->findOneByLabel($this->tagName);
$this->assertNull($tag, $this->tagName . ' was removed because it begun an orphan tag');
$user = $this->getEntityManager()
->getRepository(User::class)
->findOneByUserName('admin');
$entry = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId('http://0.0.0.0/foo', $user->getId());
$entry2 = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId('http://0.0.0.0/bar', $user->getId());
$this->assertEmpty($entry->getTagsLabel());
$this->assertEmpty($entry2->getTagsLabel());
}
public function testShowEntriesForTagAction()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$em = $client->getContainer()
->get(EntityManagerInterface::class);
$tag = new Tag();
$tag->setLabel($this->tagName);
$entry = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->findByUrlAndUserId('http://0.0.0.0/entry4', $this->getLoggedInUserId());
$tag->addEntry($entry);
$em->persist($entry);
$em->persist($tag);
$em->flush();
$tag = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Tag::class)
->findOneByEntryAndTagLabel($entry, $this->tagName);
$crawler = $client->request('GET', '/tag/list/' . $tag->getSlug());
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->assertCount(1, $crawler->filter('[id*="entry-"]'));
$entry->removeTag($tag);
$em->remove($tag);
$em->flush();
}
public function testRenameTagUsingTheFormInsideTagList()
{
$newTagLabel = 'rename label';
$this->logInAs('admin');
$client = $this->getTestClient();
$tag = new Tag();
$tag->setLabel($this->tagName);
$entry = new Entry($this->getLoggedInUser());
$entry->setUrl('http://0.0.0.0/foo');
$entry->addTag($tag);
$this->getEntityManager()->persist($entry);
$entry2 = new Entry($this->getLoggedInUser());
$entry2->setUrl('http://0.0.0.0/bar');
$entry2->addTag($tag);
$this->getEntityManager()->persist($entry2);
$this->getEntityManager()->flush();
$this->getEntityManager()->clear();
// We make a first request to set an history and test redirection after tag deletion
$crawler = $client->request('GET', '/tag/list');
$form = $crawler->filter('#tag-' . $tag->getId() . ' form')->form();
$data = [
'tag[label]' => $newTagLabel,
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertStringContainsString('flashes.tag.notice.tag_renamed', $crawler->filter('body')->extract(['_text'])[0]);
$freshEntry = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->find($entry->getId());
$freshEntry2 = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->find($entry2->getId());
$tags = [];
$tagsFromEntry = $freshEntry->getTags()->toArray();
foreach ($tagsFromEntry as $key => $item) {
$tags[$key] = $item->getLabel();
}
$tagsFromEntry2 = $freshEntry2->getTags()->toArray();
foreach ($tagsFromEntry2 as $key => $item) {
$tags[$key] = $item->getLabel();
}
$this->assertFalse(array_search($tag->getLabel(), $tags, true), 'Previous tag is not attach to entries anymore.');
$newTag = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Tag::class)
->findByLabel($newTagLabel);
$this->assertCount(1, $newTag, 'New tag exists.');
$this->assertTrue($newTag[0]->hasEntry($freshEntry), 'New tag is assigned to the entry.');
$this->assertTrue($newTag[0]->hasEntry($freshEntry2), 'New tag is assigned to the entry2.');
}
public function testRenameTagWithSameLabel()
{
$tagLabel = 'same label';
$this->logInAs('admin');
$client = $this->getTestClient();
$tag = new Tag();
$tag->setLabel($tagLabel);
$entry = new Entry($this->getLoggedInUser());
$entry->setUrl('http://0.0.0.0/foobar');
$entry->addTag($tag);
$this->getEntityManager()->persist($entry);
$this->getEntityManager()->flush();
$this->getEntityManager()->clear();
// We make a first request to set an history and test redirection after tag deletion
$crawler = $client->request('GET', '/tag/list');
$form = $crawler->filter('#tag-' . $tag->getId() . ' form')->form();
$data = [
'tag[label]' => $tagLabel,
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$this->assertStringNotContainsString('flashes.tag.notice.tag_renamed', $crawler->filter('body')->extract(['_text'])[0]);
$freshEntry = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->find($entry->getId());
$tags = [];
$tagsFromEntry = $freshEntry->getTags()->toArray();
foreach ($tagsFromEntry as $key => $item) {
$tags[$key] = $item->getLabel();
}
$this->assertNotFalse(array_search($tag->getLabel(), $tags, true), 'Tag is still assigned to the entry.');
$newTag = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Tag::class)
->findByLabel($tagLabel);
$this->assertCount(1, $newTag);
$this->assertSame($tag->getId(), $newTag[0]->getId(), 'Tag is unchanged.');
$this->assertTrue($newTag[0]->hasEntry($freshEntry), 'Tag is still assigned to the entry.');
}
public function testRenameTagWithSameLabelDifferentCase()
{
$tagLabel = 'same label';
$newTagLabel = 'saMe labEl';
$this->logInAs('admin');
$client = $this->getTestClient();
$tag = new Tag();
$tag->setLabel($tagLabel);
$entry = new Entry($this->getLoggedInUser());
$entry->setUrl('http://0.0.0.0/foobar');
$entry->addTag($tag);
$this->getEntityManager()->persist($entry);
$this->getEntityManager()->flush();
$this->getEntityManager()->clear();
// We make a first request to set an history and test redirection after tag deletion
$crawler = $client->request('GET', '/tag/list');
$form = $crawler->filter('#tag-' . $tag->getId() . ' form')->form();
$data = [
'tag[label]' => $newTagLabel,
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$this->assertStringNotContainsString('flashes.tag.notice.tag_renamed', $crawler->filter('body')->extract(['_text'])[0]);
$freshEntry = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->find($entry->getId());
$tags = [];
$tagsFromEntry = $freshEntry->getTags()->toArray();
foreach ($tagsFromEntry as $key => $item) {
$tags[$key] = $item->getLabel();
}
$this->assertFalse(array_search($newTagLabel, $tags, true));
$tagFromRepo = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Tag::class)
->findByLabel($tagLabel);
$newTagFromRepo = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Tag::class)
->findByLabel($newTagLabel);
$this->assertCount(0, $newTagFromRepo);
$this->assertCount(1, $tagFromRepo);
$this->assertSame($tag->getId(), $tagFromRepo[0]->getId(), 'Tag is unchanged.');
$this->assertTrue($tagFromRepo[0]->hasEntry($freshEntry), 'Tag is still assigned to the entry.');
}
public function testRenameTagWithExistingLabel()
{
$tagLabel = 'existing label';
$previousTagLabel = 'previous label';
$this->logInAs('admin');
$client = $this->getTestClient();
$tag = new Tag();
$tag->setLabel($tagLabel);
$previousTag = new Tag();
$previousTag->setLabel($previousTagLabel);
$entry1 = new Entry($this->getLoggedInUser());
$entry1->setUrl('http://0.0.0.0/foobar');
$entry1->addTag($previousTag);
$this->getEntityManager()->persist($entry1);
$entry2 = new Entry($this->getLoggedInUser());
$entry2->setUrl('http://0.0.0.0/baz');
$entry2->addTag($tag);
$this->getEntityManager()->persist($entry2);
$this->getEntityManager()->flush();
$this->getEntityManager()->clear();
// We make a first request to set an history and test redirection after tag deletion
$crawler = $client->request('GET', '/tag/list');
$form = $crawler->filter('#tag-' . $previousTag->getId() . ' form')->form();
$data = [
'tag[label]' => $tagLabel,
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$this->assertStringNotContainsString('flashes.tag.notice.tag_renamed', $crawler->filter('body')->extract(['_text'])[0]);
$freshEntry1 = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->find($entry1->getId());
$freshEntry2 = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->find($entry2->getId());
$tagFromRepo = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Tag::class)
->findByLabel($tagLabel);
$previousTagFromRepo = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Tag::class)
->findByLabel($previousTagLabel);
$this->assertCount(1, $tagFromRepo);
$this->assertTrue($tagFromRepo[0]->hasEntry($freshEntry1));
$this->assertTrue($tagFromRepo[0]->hasEntry($freshEntry2), 'Tag is assigned to the entry.');
$this->assertFalse($previousTagFromRepo[0]->hasEntry($freshEntry1));
}
public function testAddUnicodeTagLabel()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$entry = new Entry($this->getLoggedInUser());
$entry->setUrl('http://0.0.0.0/tag-caché');
$this->getEntityManager()->persist($entry);
$this->getEntityManager()->flush();
$this->getEntityManager()->clear();
$crawler = $client->request('GET', '/view/' . $entry->getId());
$form = $crawler->filter('form[name=tag]')->form();
$data = [
'tag[label]' => 'cache',
];
$client->submit($form, $data);
$crawler = $client->request('GET', '/view/' . $entry->getId());
$form = $crawler->filter('form[name=tag]')->form();
$data = [
'tag[label]' => 'caché',
];
$client->submit($form, $data);
$newEntry = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->find($entry->getId());
$tags = $newEntry->getTags()->toArray();
foreach ($tags as $key => $tag) {
$tags[$key] = $tag->getLabel();
}
$this->assertGreaterThanOrEqual(2, \count($tags));
$this->assertNotFalse(array_search('cache', $tags, true), 'Tag cache is assigned to the entry');
$this->assertNotFalse(array_search('caché', $tags, true), 'Tag caché is assigned to the entry');
}
public function testAssignTagsOnSearchResults()
{
$this->logInAs('admin');
$client = $this->getTestClient();
// Search on unread list
$crawler = $client->request('GET', '/unread/list');
$form = $crawler->filter('form[name=search]')->form();
$data = [
'search_entry[term]' => 'title',
];
$crawler = $client->submit($form, $data);
$client->click($crawler->selectLink('entry.list.assign_search_tag')->link());
$client->followRedirect();
$entries = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Entry::class)
->getBuilderForSearchByUser($this->getLoggedInUserId(), 'title', 'unread')
->getQuery()->getResult();
foreach ($entries as $entry) {
$tags = $entry->getTagsLabel();
$this->assertContains('title', $tags);
}
$tag = $client->getContainer()
->get(EntityManagerInterface::class)
->getRepository(Tag::class)
->findByLabelsAndUser(['title'], $this->getLoggedInUserId());
$this->assertCount(1, $tag);
}
}

View file

@ -0,0 +1,99 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
class UserControllerTest extends WallabagCoreTestCase
{
public function testLogin()
{
$client = $this->getTestClient();
$client->request('GET', '/users/list');
$this->assertSame(302, $client->getResponse()->getStatusCode());
$this->assertStringContainsString('login', $client->getResponse()->headers->get('location'));
}
public function testCompleteScenario()
{
$this->logInAs('admin');
$client = $this->getTestClient();
// Create a new user in the database
$crawler = $client->request('GET', '/users/list');
$this->assertSame(200, $client->getResponse()->getStatusCode(), 'Unexpected HTTP status code for GET /users/');
$crawler = $client->click($crawler->selectLink('user.list.create_new_one')->link());
// Fill in the form and submit it
$form = $crawler->selectButton('user.form.save')->form([
'new_user[username]' => 'test_user',
'new_user[email]' => 'test@test.io',
'new_user[plainPassword][first]' => 'testtest',
'new_user[plainPassword][second]' => 'testtest',
]);
$client->submit($form);
$client->followRedirect();
$crawler = $client->request('GET', '/users/list');
// Check data in the show view
$this->assertGreaterThan(0, $crawler->filter('td:contains("test_user")')->count(), 'Missing element td:contains("test_user")');
// Edit the user
$crawler = $client->click($crawler->selectLink('user.list.edit_action')->last()->link());
$form = $crawler->selectButton('user.form.save')->form([
'user[name]' => 'Foo User',
'user[username]' => 'test_user',
'user[email]' => 'test@test.io',
'user[enabled]' => true,
]);
$client->submit($form);
$crawler = $client->followRedirect();
// Check the element contains an attribute with value equals "Foo User"
$this->assertGreaterThan(0, $crawler->filter('[value="Foo User"]')->count(), 'Missing element [value="Foo User"]');
$crawler = $client->request('GET', '/users/list');
$crawler = $client->click($crawler->selectLink('user.list.edit_action')->last()->link());
// Delete the user
$client->submit($crawler->selectButton('user.form.delete')->form());
$crawler = $client->followRedirect();
// Check the user has been delete on the list
$this->assertDoesNotMatchRegularExpression('/Foo User/', $client->getResponse()->getContent());
}
public function testDeleteDisabledForLoggedUser()
{
$this->logInAs('admin');
$client = $this->getTestClient();
$crawler = $client->request('GET', '/users/' . $this->getLoggedInUserId() . '/edit');
$disabled = $crawler->selectButton('user.form.delete')->extract(['disabled']);
$this->assertSame('disabled', $disabled[0]);
}
public function testUserSearch()
{
$this->logInAs('admin');
$client = $this->getTestClient();
// Search on unread list
$crawler = $client->request('GET', '/users/list');
$form = $crawler->filter('form[name=search_users]')->form();
$data = [
'search_user[term]' => 'admin',
];
$crawler = $client->submit($form, $data);
$this->assertCount(2, $crawler->filter('tr')); // 1 result + table header
}
}