]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Merge pull request #3820 from lizyn/bugfix/incorrect-calculation-of-CJK-characters...
authorJérémy Benoist <j0k3r@users.noreply.github.com>
Mon, 7 Jan 2019 09:17:29 +0000 (10:17 +0100)
committerGitHub <noreply@github.com>
Mon, 7 Jan 2019 09:17:29 +0000 (10:17 +0100)
Fix incorrect reading time calculation for entries with CJK characters

15 files changed:
src/Wallabag/ApiBundle/Controller/TagRestController.php
src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php
src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTagData.php
src/Wallabag/CoreBundle/Repository/TagRepository.php
src/Wallabag/ImportBundle/Consumer/AbstractConsumer.php
src/Wallabag/ImportBundle/Import/AbstractImport.php
src/Wallabag/ImportBundle/Import/BrowserImport.php
src/Wallabag/ImportBundle/Import/ChromeImport.php
src/Wallabag/ImportBundle/Import/FirefoxImport.php
src/Wallabag/ImportBundle/Import/InstapaperImport.php
src/Wallabag/ImportBundle/Import/PinboardImport.php
src/Wallabag/ImportBundle/Import/PocketImport.php
src/Wallabag/ImportBundle/Import/ReadabilityImport.php
src/Wallabag/ImportBundle/Import/WallabagImport.php
tests/Wallabag/ApiBundle/Controller/TagRestControllerTest.php

index c6d6df6a91423718f5006cbace9f569eca6e7a7c..f3498f55a83f17bab2c881a75ea6918115dd1125 100644 (file)
@@ -46,12 +46,14 @@ class TagRestController extends WallabagRestController
         $this->validateAuthentication();
         $label = $request->get('tag', '');
 
-        $tag = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($label);
+        $tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findByLabelsAndUser([$label], $this->getUser()->getId());
 
-        if (empty($tag)) {
+        if (empty($tags)) {
             throw $this->createNotFoundException('Tag not found');
         }
 
+        $tag = $tags[0];
+
         $this->getDoctrine()
             ->getRepository('WallabagCoreBundle:Entry')
             ->removeTag($this->getUser()->getId(), $tag);
@@ -80,15 +82,7 @@ class TagRestController extends WallabagRestController
 
         $tagsLabels = $request->get('tags', '');
 
-        $tags = [];
-
-        foreach (explode(',', $tagsLabels) as $tagLabel) {
-            $tagEntity = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($tagLabel);
-
-            if (!empty($tagEntity)) {
-                $tags[] = $tagEntity;
-            }
-        }
+        $tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findByLabelsAndUser(explode(',', $tagsLabels), $this->getUser()->getId());
 
         if (empty($tags)) {
             throw $this->createNotFoundException('Tags not found');
@@ -120,6 +114,12 @@ class TagRestController extends WallabagRestController
     {
         $this->validateAuthentication();
 
+        $tagFromDb = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findByLabelsAndUser([$tag->getLabel()], $this->getUser()->getId());
+
+        if (empty($tagFromDb)) {
+            throw $this->createNotFoundException('Tag not found');
+        }
+
         $this->getDoctrine()
             ->getRepository('WallabagCoreBundle:Entry')
             ->removeTag($this->getUser()->getId(), $tag);
index 0e1510a29bf450f7c8e9e6067fb7c6ee2af84012..8e7a1d2af9503eef8543d22722bf9292528626ff 100644 (file)
@@ -14,97 +14,112 @@ class LoadEntryData extends AbstractFixture implements OrderedFixtureInterface
      */
     public function load(ObjectManager $manager)
     {
-        $entry1 = new Entry($this->getReference('admin-user'));
-        $entry1->setUrl('http://0.0.0.0/entry1');
-        $entry1->setReadingTime(11);
-        $entry1->setDomainName('domain.io');
-        $entry1->setMimetype('text/html');
-        $entry1->setTitle('test title entry1');
-        $entry1->setContent('This is my content /o/');
-        $entry1->setLanguage('en');
-
-        $entry1->addTag($this->getReference('foo-tag'));
-        $entry1->addTag($this->getReference('baz-tag'));
-
-        $manager->persist($entry1);
-
-        $this->addReference('entry1', $entry1);
-
-        $entry2 = new Entry($this->getReference('admin-user'));
-        $entry2->setUrl('http://0.0.0.0/entry2');
-        $entry2->setReadingTime(1);
-        $entry2->setDomainName('domain.io');
-        $entry2->setMimetype('text/html');
-        $entry2->setTitle('test title entry2');
-        $entry2->setContent('This is my content /o/');
-        $entry2->setOriginUrl('ftp://oneftp.tld');
-        $entry2->setLanguage('fr');
-
-        $manager->persist($entry2);
-
-        $this->addReference('entry2', $entry2);
-
-        $entry3 = new Entry($this->getReference('bob-user'));
-        $entry3->setUrl('http://0.0.0.0/entry3');
-        $entry3->setReadingTime(1);
-        $entry3->setDomainName('domain.io');
-        $entry3->setMimetype('text/html');
-        $entry3->setTitle('test title entry3');
-        $entry3->setContent('This is my content /o/');
-        $entry3->setLanguage('en');
-
-        $entry3->addTag($this->getReference('foo-tag'));
-        $entry3->addTag($this->getReference('bar-tag'));
-
-        $manager->persist($entry3);
-
-        $this->addReference('entry3', $entry3);
-
-        $entry4 = new Entry($this->getReference('admin-user'));
-        $entry4->setUrl('http://0.0.0.0/entry4');
-        $entry4->setReadingTime(12);
-        $entry4->setDomainName('domain.io');
-        $entry4->setMimetype('text/html');
-        $entry4->setTitle('test title entry4');
-        $entry4->setContent('This is my content /o/');
-        $entry4->setLanguage('en');
-
-        $entry4->addTag($this->getReference('foo-tag'));
-        $entry4->addTag($this->getReference('bar-tag'));
-
-        $manager->persist($entry4);
-
-        $this->addReference('entry4', $entry4);
-
-        $entry5 = new Entry($this->getReference('admin-user'));
-        $entry5->setUrl('http://0.0.0.0/entry5');
-        $entry5->setReadingTime(12);
-        $entry5->setDomainName('domain.io');
-        $entry5->setMimetype('text/html');
-        $entry5->setTitle('test title entry5');
-        $entry5->setContent('This is my content /o/');
-        $entry5->setStarred(true);
-        $entry5->setLanguage('fr');
-        $entry5->setPreviewPicture('http://0.0.0.0/image.jpg');
-
-        $manager->persist($entry5);
-
-        $this->addReference('entry5', $entry5);
-
-        $entry6 = new Entry($this->getReference('admin-user'));
-        $entry6->setUrl('http://0.0.0.0/entry6');
-        $entry6->setReadingTime(12);
-        $entry6->setDomainName('domain.io');
-        $entry6->setMimetype('text/html');
-        $entry6->setTitle('test title entry6');
-        $entry6->setContent('This is my content /o/');
-        $entry6->setArchived(true);
-        $entry6->setLanguage('de');
-        $entry6->addTag($this->getReference('bar-tag'));
-
-        $manager->persist($entry6);
-
-        $this->addReference('entry6', $entry6);
+        $entries = [
+            'entry1' => [
+                'user' => 'admin-user',
+                'url' => 'http://0.0.0.0/entry1',
+                'reading_time' => 11,
+                'domain' => 'domain.io',
+                'mime' => 'text/html',
+                'title' => 'test title entry1',
+                'content' => 'This is my content /o/',
+                'language' => 'en',
+                'tags' => ['foo-tag', 'baz-tag'],
+            ],
+            'entry2' => [
+                'user' => 'admin-user',
+                'url' => 'http://0.0.0.0/entry2',
+                'reading_time' => 1,
+                'domain' => 'domain.io',
+                'mime' => 'text/html',
+                'title' => 'test title entry2',
+                'content' => 'This is my content /o/',
+                'origin' => 'ftp://oneftp.tld',
+                'language' => 'fr',
+            ],
+            'entry3' => [
+                'user' => 'bob-user',
+                'url' => 'http://0.0.0.0/entry3',
+                'reading_time' => 1,
+                'domain' => 'domain.io',
+                'mime' => 'text/html',
+                'title' => 'test title entry3',
+                'content' => 'This is my content /o/',
+                'language' => 'en',
+                'tags' => ['foo-tag', 'bar-tag', 'bob-tag'],
+            ],
+            'entry4' => [
+                'user' => 'admin-user',
+                'url' => 'http://0.0.0.0/entry4',
+                'reading_time' => 12,
+                'domain' => 'domain.io',
+                'mime' => 'text/html',
+                'title' => 'test title entry4',
+                'content' => 'This is my content /o/',
+                'language' => 'en',
+                'tags' => ['foo-tag', 'bar-tag'],
+            ],
+            'entry5' => [
+                'user' => 'admin-user',
+                'url' => 'http://0.0.0.0/entry5',
+                'reading_time' => 12,
+                'domain' => 'domain.io',
+                'mime' => 'text/html',
+                'title' => 'test title entry5',
+                'content' => 'This is my content /o/',
+                'language' => 'fr',
+                'starred' => true,
+                'preview' => 'http://0.0.0.0/image.jpg',
+            ],
+            'entry6' => [
+                'user' => 'admin-user',
+                'url' => 'http://0.0.0.0/entry6',
+                'reading_time' => 12,
+                'domain' => 'domain.io',
+                'mime' => 'text/html',
+                'title' => 'test title entry6',
+                'content' => 'This is my content /o/',
+                'language' => 'de',
+                'archived' => true,
+                'tags' => ['bar-tag'],
+            ],
+        ];
+
+        foreach ($entries as $reference => $item) {
+            $entry = new Entry($this->getReference($item['user']));
+            $entry->setUrl($item['url']);
+            $entry->setReadingTime($item['reading_time']);
+            $entry->setDomainName($item['domain']);
+            $entry->setMimetype($item['mime']);
+            $entry->setTitle($item['title']);
+            $entry->setContent($item['content']);
+            $entry->setLanguage($item['language']);
+
+            if (isset($item['tags'])) {
+                foreach ($item['tags'] as $tag) {
+                    $entry->addTag($this->getReference($tag));
+                }
+            }
+
+            if (isset($item['origin'])) {
+                $entry->setOriginUrl($item['origin']);
+            }
+
+            if (isset($item['starred'])) {
+                $entry->setStarred($item['starred']);
+            }
+
+            if (isset($item['archived'])) {
+                $entry->setArchived($item['archived']);
+            }
+
+            if (isset($item['preview'])) {
+                $entry->setPreviewPicture($item['preview']);
+            }
+
+            $manager->persist($entry);
+            $this->addReference($reference, $entry);
+        }
 
         $manager->flush();
     }
index 0ecfd18b55ddab8c00f1616586f78a9f576af5c3..485445c1b99d6061721a217e85d195f6814a9481 100644 (file)
@@ -14,33 +14,22 @@ class LoadTagData extends AbstractFixture implements OrderedFixtureInterface
      */
     public function load(ObjectManager $manager)
     {
-        $tag1 = new Tag();
-        $tag1->setLabel('foo bar');
-
-        $manager->persist($tag1);
-
-        $this->addReference('foo-bar-tag', $tag1);
-
-        $tag2 = new Tag();
-        $tag2->setLabel('bar');
-
-        $manager->persist($tag2);
-
-        $this->addReference('bar-tag', $tag2);
-
-        $tag3 = new Tag();
-        $tag3->setLabel('baz');
-
-        $manager->persist($tag3);
-
-        $this->addReference('baz-tag', $tag3);
-
-        $tag4 = new Tag();
-        $tag4->setLabel('foo');
-
-        $manager->persist($tag4);
-
-        $this->addReference('foo-tag', $tag4);
+        $tags = [
+            'foo-bar-tag' => 'foo bar', //tag used for EntryControllerTest
+            'bar-tag' => 'bar',
+            'baz-tag' => 'baz', // tag used for ExportControllerTest
+            'foo-tag' => 'foo',
+            'bob-tag' => 'bob', // tag used for TagRestControllerTest
+        ];
+
+        foreach ($tags as $reference => $label) {
+            $tag = new Tag();
+            $tag->setLabel($label);
+
+            $manager->persist($tag);
+
+            $this->addReference($reference, $tag);
+        }
 
         $manager->flush();
     }
index 3ae9d4141161c4443eb98f9bc6533695558e6143..8464a6a55004c27cce23c5a2283af01dd56c1a74 100644 (file)
@@ -3,6 +3,7 @@
 namespace Wallabag\CoreBundle\Repository;
 
 use Doctrine\ORM\EntityRepository;
+use Doctrine\ORM\QueryBuilder;
 use Wallabag\CoreBundle\Entity\Tag;
 
 class TagRepository extends EntityRepository
@@ -45,12 +46,8 @@ class TagRepository extends EntityRepository
      */
     public function findAllTags($userId)
     {
-        $ids = $this->createQueryBuilder('t')
+        $ids = $this->getQueryBuilderByUser($userId)
             ->select('t.id')
-            ->leftJoin('t.entries', 'e')
-            ->where('e.user = :userId')->setParameter('userId', $userId)
-            ->groupBy('t.id')
-            ->orderBy('t.slug')
             ->getQuery()
             ->getArrayResult();
 
@@ -71,18 +68,30 @@ class TagRepository extends EntityRepository
      */
     public function findAllFlatTagsWithNbEntries($userId)
     {
-        return $this->createQueryBuilder('t')
+        return $this->getQueryBuilderByUser($userId)
             ->select('t.id, t.label, t.slug, count(e.id) as nbEntries')
             ->distinct(true)
-            ->leftJoin('t.entries', 'e')
-            ->where('e.user = :userId')
-            ->groupBy('t.id')
-            ->orderBy('t.slug')
-            ->setParameter('userId', $userId)
             ->getQuery()
             ->getArrayResult();
     }
 
+    public function findByLabelsAndUser($labels, $userId)
+    {
+        $qb = $this->getQueryBuilderByUser($userId)
+            ->select('t.id');
+
+        $ids = $qb->andWhere($qb->expr()->in('t.label', $labels))
+            ->getQuery()
+            ->getArrayResult();
+
+        $tags = [];
+        foreach ($ids as $id) {
+            $tags[] = $this->find($id);
+        }
+
+        return $tags;
+    }
+
     /**
      * Used only in test case to get a tag for our entry.
      *
@@ -101,13 +110,9 @@ class TagRepository extends EntityRepository
 
     public function findForArchivedArticlesByUser($userId)
     {
-        $ids = $this->createQueryBuilder('t')
+        $ids = $this->getQueryBuilderByUser($userId)
             ->select('t.id')
-            ->leftJoin('t.entries', 'e')
-            ->where('e.user = :userId')->setParameter('userId', $userId)
             ->andWhere('e.isArchived = true')
-            ->groupBy('t.id')
-            ->orderBy('t.slug')
             ->getQuery()
             ->getArrayResult();
 
@@ -118,4 +123,20 @@ class TagRepository extends EntityRepository
 
         return $tags;
     }
+
+    /**
+     * Retrieve a sorted list of tags used by a user.
+     *
+     * @param int $userId
+     *
+     * @return QueryBuilder
+     */
+    private function getQueryBuilderByUser($userId)
+    {
+        return $this->createQueryBuilder('t')
+            ->leftJoin('t.entries', 'e')
+            ->where('e.user = :userId')->setParameter('userId', $userId)
+            ->groupBy('t.id')
+            ->orderBy('t.slug');
+    }
 }
index b035f5cc5e83604cf2890dfa035a433a99478b49..e4bfbdf033807fca182b99343d6455d6361e451a 100644 (file)
@@ -52,6 +52,13 @@ abstract class AbstractConsumer
 
         $this->import->setUser($user);
 
+        if (false === $this->import->validateEntry($storedEntry)) {
+            $this->logger->warning('Entry is invalid', ['entry' => $storedEntry]);
+
+            // return true to skip message
+            return true;
+        }
+
         $entry = $this->import->parseEntry($storedEntry);
 
         if (null === $entry) {
index 58a234f46bd357dedf7abd8c14b9cc381b33df37..d39d71b6caf1e3b7def2c0b352b4ceeccdef0840 100644 (file)
@@ -118,6 +118,15 @@ abstract class AbstractImport implements ImportInterface
      */
     abstract public function parseEntry(array $importedEntry);
 
+    /**
+     * Validate that an entry is valid (like has some required keys, etc.).
+     *
+     * @param array $importedEntry
+     *
+     * @return bool
+     */
+    abstract public function validateEntry(array $importedEntry);
+
     /**
      * Fetch content from the ContentProxy (using graby).
      * If it fails return the given entry to be saved in all case (to avoid user to loose the content).
@@ -141,9 +150,9 @@ abstract class AbstractImport implements ImportInterface
     /**
      * Parse and insert all given entries.
      *
-     * @param $entries
+     * @param array $entries
      */
-    protected function parseEntries($entries)
+    protected function parseEntries(array $entries)
     {
         $i = 1;
         $entryToBeFlushed = [];
@@ -153,6 +162,10 @@ abstract class AbstractImport implements ImportInterface
                 $importedEntry = $this->setEntryAsRead($importedEntry);
             }
 
+            if (false === $this->validateEntry($importedEntry)) {
+                continue;
+            }
+
             $entry = $this->parseEntry($importedEntry);
 
             if (null === $entry) {
index 225f1791f5bfe6b6fdc04bba4a2d0abf9cc7c600..4678ae0c5133cfc79e0e18f95a242cab6cea7f5e 100644 (file)
@@ -149,9 +149,9 @@ abstract class BrowserImport extends AbstractImport
     /**
      * Parse and insert all given entries.
      *
-     * @param $entries
+     * @param array $entries
      */
-    protected function parseEntries($entries)
+    protected function parseEntries(array $entries)
     {
         $i = 1;
         $entryToBeFlushed = [];
index 09183abe47cbe321ed8067de34a9f816a6fde97c..eccee69869a1197c59bdf3e500953a4c6867d424 100644 (file)
@@ -30,6 +30,18 @@ class ChromeImport extends BrowserImport
         return 'import.chrome.description';
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function validateEntry(array $importedEntry)
+    {
+        if (empty($importedEntry['url'])) {
+            return false;
+        }
+
+        return true;
+    }
+
     /**
      * {@inheritdoc}
      */
index 73269fe164289a11d794a0c5bde7e31a18d2340f..8999e3f3932240accb4096b519af13a31230bdbc 100644 (file)
@@ -30,6 +30,18 @@ class FirefoxImport extends BrowserImport
         return 'import.firefox.description';
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function validateEntry(array $importedEntry)
+    {
+        if (empty($importedEntry['uri'])) {
+            return false;
+        }
+
+        return true;
+    }
+
     /**
      * {@inheritdoc}
      */
index e4f0970c0c3f41a531a9d548c46fdc175946e92c..5a18c7c0c6c82c0426ba8d2b436f6beed79b55bc 100644 (file)
@@ -105,6 +105,18 @@ class InstapaperImport extends AbstractImport
         return true;
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function validateEntry(array $importedEntry)
+    {
+        if (empty($importedEntry['url'])) {
+            return false;
+        }
+
+        return true;
+    }
+
     /**
      * {@inheritdoc}
      */
index 110b046422ae3c25a7f5be34f59c12e4d11938b2..995d1f2ca99f7ddb0ab330f89fcbb3bb5ff59cf5 100644 (file)
@@ -80,6 +80,18 @@ class PinboardImport extends AbstractImport
         return true;
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function validateEntry(array $importedEntry)
+    {
+        if (empty($importedEntry['href'])) {
+            return false;
+        }
+
+        return true;
+    }
+
     /**
      * {@inheritdoc}
      */
index c1b35b7ef028a0e261d9a072e867246eca4816eb..d364338996a652c83684d4d44ce39d960d77364d 100644 (file)
@@ -168,6 +168,18 @@ class PocketImport extends AbstractImport
         $this->client = $client;
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function validateEntry(array $importedEntry)
+    {
+        if (empty($importedEntry['resolved_url']) && empty($importedEntry['given_url'])) {
+            return false;
+        }
+
+        return true;
+    }
+
     /**
      * {@inheritdoc}
      *
index 002b27f46b5b2ace08be9f89ad402672496a9c8a..a5f3798e0277f05b4167c6318be47a9cb5d603b7 100644 (file)
@@ -80,6 +80,18 @@ class ReadabilityImport extends AbstractImport
         return true;
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function validateEntry(array $importedEntry)
+    {
+        if (empty($importedEntry['article__url'])) {
+            return false;
+        }
+
+        return true;
+    }
+
     /**
      * {@inheritdoc}
      */
index c64ccd64d196095ce8b9e3f913c4f856075f0fa3..350d06001f12202f6c6678b01b5f48da19773ace 100644 (file)
@@ -86,6 +86,18 @@ abstract class WallabagImport extends AbstractImport
         return $this;
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function validateEntry(array $importedEntry)
+    {
+        if (empty($importedEntry['url'])) {
+            return false;
+        }
+
+        return true;
+    }
+
     /**
      * {@inheritdoc}
      */
index 430e548d204078178b42bbdc957b9e6ee3ab1ebc..9daa94cd5346bf0a99d8cc73e0366666d830f749 100644 (file)
@@ -7,6 +7,8 @@ use Wallabag\CoreBundle\Entity\Tag;
 
 class TagRestControllerTest extends WallabagApiTestCase
 {
+    private $otherUserTagLabel = 'bob';
+
     public function testGetUserTags()
     {
         $this->client->request('GET', '/api/tags.json');
@@ -19,17 +21,33 @@ class TagRestControllerTest extends WallabagApiTestCase
         $this->assertArrayHasKey('id', $content[0]);
         $this->assertArrayHasKey('label', $content[0]);
 
+        $tagLabels = array_map(function ($i) {
+            return $i['label'];
+        }, $content);
+
+        $this->assertNotContains($this->otherUserTagLabel, $tagLabels, 'There is a possible tag leak');
+
         return end($content);
     }
 
     public function testDeleteUserTag()
     {
+        $em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
+        $entry = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneWithTags($this->user->getId());
+
+        $entry = $entry[0];
+
         $tagLabel = 'tagtest';
         $tag = new Tag();
         $tag->setLabel($tagLabel);
-
-        $em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
         $em->persist($tag);
+
+        $entry->addTag($tag);
+
+        $em->persist($entry);
         $em->flush();
         $em->clear();
 
@@ -53,6 +71,16 @@ class TagRestControllerTest extends WallabagApiTestCase
         $this->assertNull($tag, $tagLabel . ' was removed because it begun an orphan tag');
     }
 
+    public function testDeleteOtherUserTag()
+    {
+        $em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
+        $tag = $em->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($this->otherUserTagLabel);
+
+        $this->client->request('DELETE', '/api/tags/' . $tag->getId() . '.json');
+
+        $this->assertSame(404, $this->client->getResponse()->getStatusCode());
+    }
+
     public function dataForDeletingTagByLabel()
     {
         return [
@@ -112,6 +140,13 @@ class TagRestControllerTest extends WallabagApiTestCase
         $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
      */
@@ -180,4 +215,11 @@ class TagRestControllerTest extends WallabagApiTestCase
 
         $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());
+    }
 }