add tests and fixtures
authorymh <ymh.work@gmail.com>
Wed, 14 Dec 2011 23:28:57 +0100
changeset 63 774ba82dca59
parent 62 10be6b9e55e7
child 64 caeb4c8b5487
add tests and fixtures
Controller/WikiTagController.php
DependencyInjection/Configuration.php
DependencyInjection/WikiTagExtension.php
Entity/DocumentRepository.php
Entity/TagRepository.php
Listener/DocumentListener.php
Model/Document.php
Services/DocumentService.php
Services/WikiTagServiceException.php
Tests/Services/DocumentServiceTest.php
Tests/Services/SearchServiceTest.php
Utils/WikiTagUtils.php
--- a/Controller/WikiTagController.php	Fri Dec 09 06:43:49 2011 +0100
+++ b/Controller/WikiTagController.php	Wed Dec 14 23:28:57 2011 +0100
@@ -16,6 +16,7 @@
 use IRI\Bundle\WikiTagBundle\Entity\DocumentTag;
 use IRI\Bundle\WikiTagBundle\Entity\Tag;
 use IRI\Bundle\WikiTagBundle\Utils\WikiTagUtils;
+use IRI\Bundle\WikiTagBundle\Services\WikiTagServiceException;
 use Pagerfanta\Pagerfanta;
 use Pagerfanta\Adapter\ArrayAdapter;
 use Pagerfanta\Adapter\DoctrineORMAdapter;
@@ -267,52 +268,15 @@
     {
         $id_doc = $this->getRequest()->request->get('wikitag_document_id');
         $tag_label = $this->getRequest()->request->get('value');
-        // We get the DocumentTags
-        $em = $this->getDoctrine()->getEntityManager();
-        $tags = $this->getDoctrine()->getRepository('WikiTagBundle:DocumentTag')->findByDocumentExternalId($id_doc);
-        $nb_tags = count($tags);
-        $found = false;
-        $i = 0;
-        while($i<$nb_tags && $found==false){
-            $dt = $tags[$i];
-            if(strtolower($dt->getTag()->getLabel())==strtolower($tag_label)){
-                $found = true;
-            }
-            $i++;
-        }
-        // If the label was found, we sent a bad request
-        if($found==true){
-            //TODO : translation
-            return new Response(json_encode(array('error' => 'duplicate_tag', 'message' => sprintf("Le tag %s existe déjà pour cette fiche.", $tag_label))),400);
-        }
-        // returns array($tag, $revision_id, $created)
-        try {
-            $ar = $this->getDoctrine()->getRepository('WikiTagBundle:Tag')->getOrCreateTag($tag_label);
+        
+        
+        try
+        {
+            $this->get('wiki_tag.document')->addTag($id_doc, $tag_label);
         }
-        catch (\Exception $e){
-            return new Response(json_encode(array('error' => 'wikipedia_request_failed', 'message' => $e->getMessage())),400);
-        }
-        
-        $tag = $ar[0];
-        $revision_id = $ar[1];
-        $created = $ar[2];
-        
-        $tags = $this->getDoctrine()->getRepository('WikiTagBundle:DocumentTag')->findByDocumentExternalId($id_doc, array('tag'=>$tag->getId()));
-        $nb_tags = count($tags);
-
-        if($created==true || $nb_tags==0){
-            $new_order_ar = $this->getDoctrine()->getRepository('WikiTagBundle:DocumentTag')->getMaxOrder($id_doc);
-            // The result is a double array. And reset(reset($newOrderAr)) is not allowed. And a string is returned.
-            $a1 = reset($new_order_ar);
-            $new_order = intval(reset($a1)) + 1;
-            $new_DT = new DocumentTag();
-            $new_DT->setDocument($this->getDoctrine()->getRepository('WikiTagBundle:Document')->findOneByExternalId($id_doc));
-            $new_DT->setTag($tag);
-            $new_DT->setOriginalOrder($new_order);
-            $new_DT->setTagOrder($new_order);
-            $new_DT->setWikipediaRevisionId($revision_id);
-            $em->persist($new_DT);
-            $em->flush();
+        catch (WikiTagServiceException $e)
+        {
+            return new Response(json_encode(array('error' => $e->getErrorCode(), 'message' => $e->getMessage())),$e->getCode());
         }
 
         return $this->renderDocTags($id_doc, $this->getRequest()->request->get('wikitag_document_profile'));
@@ -540,7 +504,7 @@
             $this->updateTagWithNewLabel($moved_tag, $tag_label);
         }
         catch (\Exception $e){
-            return new Response(json_encode(array('error' => 'wikipedia_request_failed', 'message' => $e->getMessage())),400);
+            return new Response(json_encode(array('error' => 'wikipedia_request_failed', 'message' => $e->getMessage())),500);
         }
         // We render the tag list.
         return $this->renderAllTags();
@@ -560,7 +524,7 @@
             $this->updateTagWithNewLabel($moved_tag, $moved_tag->getOriginalLabel());
         }
         catch (\Exception $e){
-            return new Response(json_encode(array('error' => 'wikipedia_request_failed', 'message' => $e->getMessage())),400);
+            return new Response(json_encode(array('error' => 'wikipedia_request_failed', 'message' => $e->getMessage())),500);
         }
         
         // We render the tag list.
@@ -580,7 +544,7 @@
             $this->updateTagWithNewLabel($tag, $tag->getLabel());
         }
         catch (\Exception $e){
-            return new Response(json_encode(array('error' => 'wikipedia_request_failed', 'message' => $e->getMessage())),400);
+            return new Response(json_encode(array('error' => 'wikipedia_request_failed', 'message' => $e->getMessage())),500);
         }
     
         // We render the tag list.
--- a/DependencyInjection/Configuration.php	Fri Dec 09 06:43:49 2011 +0100
+++ b/DependencyInjection/Configuration.php	Wed Dec 14 23:28:57 2011 +0100
@@ -25,6 +25,7 @@
         $rootNode
             ->children()
                 ->scalarNode('route_for_documents_by_tag')->defaultNull()->end()
+                ->booleanNode('ignore_wikipedia_error')->defaultFalse()->end()
                 ->scalarNode('document_class')->isRequired()->end()
                 ->scalarNode('document_id_column')->defaultValue('id')->end()
             ->end()
--- a/DependencyInjection/WikiTagExtension.php	Fri Dec 09 06:43:49 2011 +0100
+++ b/DependencyInjection/WikiTagExtension.php	Wed Dec 14 23:28:57 2011 +0100
@@ -29,6 +29,12 @@
         {
             $container->setParameter("wiki_tag.document_class", $config['document_class']);
         }
+
+        if(isset($config['ignore_wikipedia_error']))
+        {
+            $container->setParameter("wiki_tag.ignore_wikipedia_error", $config['ignore_wikipedia_error']);
+        }
+        
         
         if(isset($config['document_id_column']))
         {
--- a/Entity/DocumentRepository.php	Fri Dec 09 06:43:49 2011 +0100
+++ b/Entity/DocumentRepository.php	Wed Dec 14 23:28:57 2011 +0100
@@ -243,7 +243,7 @@
     public function getTagsStr($document)
     {
         $em = $this->getEntityManager();
-        $query = $em->createQuery("SELECT t.label FROM WikiTagBundle:DocumentTag dt JOIN dt.tag t WHERE dt.document = :docid");
+        $query = $em->createQuery("SELECT t.label FROM WikiTagBundle:DocumentTag dt JOIN dt.tag t WHERE dt.document = :docid ORDER BY dt.tagOrder");
         $query = $query->setParameter("docid", $document);
         $result = $query->getScalarResult();
         $tagstr = array();
@@ -253,6 +253,7 @@
         return $tagstr;
     }
     
+    
     /**
      * Update a wikitag document tags string.
      * @param DocumentInterface $document the wikitag document
--- a/Entity/TagRepository.php	Fri Dec 09 06:43:49 2011 +0100
+++ b/Entity/TagRepository.php	Wed Dec 14 23:28:57 2011 +0100
@@ -34,6 +34,7 @@
         $qb->select('t.label');
         $qb->from('WikiTagBundle:Tag','t');
         $qb->where($qb->expr()->orx(
+            $qb->expr()->like('t.label',$qb->expr()->literal(addcslashes(mysql_real_escape_string($seed),"%_")."%")),
             $qb->expr()->like('t.label',$qb->expr()->literal("%".addcslashes(mysql_real_escape_string($seed),"%_"))),
             $qb->expr()->like('t.label',$qb->expr()->literal("% ".addcslashes(mysql_real_escape_string($seed),"%_")."%"))
         ));
--- a/Listener/DocumentListener.php	Fri Dec 09 06:43:49 2011 +0100
+++ b/Listener/DocumentListener.php	Wed Dec 14 23:28:57 2011 +0100
@@ -19,6 +19,7 @@
 use Doctrine\Common\EventSubscriber;
 use Doctrine\ORM\Events;
 use Doctrine\ORM\Event\LifecycleEventArgs;
+use Doctrine\ORM\Event\OnFlushEventArgs;
 use Doctrine\ORM\Event\PreUpdateEventArgs;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -59,6 +60,7 @@
         Events::postUpdate,
         Events::preRemove,
         Events::postRemove,
+        Events::onFlush,
         );
     }
     
@@ -70,6 +72,11 @@
         $event_dispatcher->dispatch(WikiTagEvents::onTagChanged, $event);
     }
     
+    public function onFlush(OnFlushEventArgs $eventArgs)
+    {
+        
+    }
+    
     public function postPersist(LifecycleEventArgs $args)
     {
         $logger = $this->container->get('logger');
--- a/Model/Document.php	Fri Dec 09 06:43:49 2011 +0100
+++ b/Model/Document.php	Wed Dec 14 23:28:57 2011 +0100
@@ -26,7 +26,7 @@
     protected $manualOrder = false;
     
     /**
-     * @var string $externalId
+     * @var mixed $externalId
      */
     protected $externalId;
     
--- a/Services/DocumentService.php	Fri Dec 09 06:43:49 2011 +0100
+++ b/Services/DocumentService.php	Wed Dec 14 23:28:57 2011 +0100
@@ -9,8 +9,10 @@
  */
 namespace IRI\Bundle\WikiTagBundle\Services;
  
+use IRI\Bundle\WikiTagBundle\Entity\DocumentTag;
 use Symfony\Component\DependencyInjection\ContainerAware;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use IRI\Bundle\WikiTagBundle\Utils\WikiTagUtils;
 
 class DocumentService extends ContainerAware
 {
@@ -46,6 +48,7 @@
 
     /**
      * Copy the list of tags of one document to another.
+     * The ids are the ids of the "host" document.
 	 *
      * @param mixed $id_doc_src the source document id
      * @param mixed $id_doc_tgt the target document id
@@ -77,5 +80,90 @@
         
     }
     
+    /**
+     *
+     * Add a new tag to a "host" document.
+     * If the label already exists, an exception is raised.
+     *
+     * @param mixed $id_doc
+     * @param string|array $tag_label : the label of the new tag
+     */
+    public function addTags($id_doc, $tag_labels)
+    {
+        // We get the DocumentTags
+        $em = $this->getDoctrine()->getEntityManager();
+        
+        $need_flush = false;
+        
+        
+        if(!is_array($tag_labels)) {
+            $tag_labels = array($tag_labels);
+        }
+        
+        foreach ($tag_labels as $tag_label) {
+        
+            $normalized_tag_label = WikiTagUtils::normalizeTag($tag_label);
+            
+            $query = $em->createQuery("SELECT COUNT(dt.id) FROM WikiTagBundle:DocumentTag dt JOIN dt.tag t WHERE dt.document = :id_doc AND t.normalizedLabel = :label");
+            $query->setParameters(array("id_doc"=>$id_doc, "label"=>$normalized_tag_label));
+            
+            $nb_tags = $query->getSingleScalarResult();
+            
+            // If the label was found, we sent a bad request
+            if($nb_tags > 0){
+                throw new WikiTagServiceException(sprintf("Le tag %s existe déjà pour cette fiche.", $tag_label), 400, null, "duplicate_tag");
+            }
+            // returns array($tag, $revision_id, $created)
+            try {
+                $ar = $this->getDoctrine()->getRepository('WikiTagBundle:Tag')->getOrCreateTag($tag_label);
+            }
+            catch (\Exception $e){
+                throw new WikiTagServiceException($e->getMessage(), 500 , $e, "wikipedia_request_failed");
+            }
+            
+            $tag = $ar[0];
+            $revision_id = $ar[1];
+            $created = $ar[2];
+            
+            $tags = $this->getDoctrine()->getRepository('WikiTagBundle:DocumentTag')->findByDocumentExternalId($id_doc, array('tag'=>$tag->getId()));
+            $nb_tags = count($tags);
+            
+            if($created==true || $nb_tags==0){
+                $new_order_ar = $this->getDoctrine()->getRepository('WikiTagBundle:DocumentTag')->getMaxOrder($id_doc);
+                // The result is a double array. And reset(reset($newOrderAr)) is not allowed. And a string is returned.
+                $a1 = reset($new_order_ar);
+                $new_order = intval(reset($a1)) + 1;
+                $new_DT = new DocumentTag();
+                $new_DT->setDocument($this->getDoctrine()->getRepository('WikiTagBundle:Document')->findOneByExternalId($id_doc));
+                $new_DT->setTag($tag);
+                $new_DT->setOriginalOrder($new_order);
+                $new_DT->setTagOrder($new_order);
+                $new_DT->setWikipediaRevisionId($revision_id);
+                $em->persist($new_DT);
+                $need_flush = true;
+                
+            }
+        }
+        
+        if($need_flush) {
+            $em->flush();
+        }
+        
+        
+    }
+    
+    public function getTagLabels($id_doc)
+    {
+        $rep = $this->getDoctrine()->getRepository('WikiTagBundle:Document');
+        $doc = $rep->findOneByExternalId($id_doc);
+        
+        if(is_null($doc)) {
+            throw new WikiTagServiceException("Unknown document id");
+        }
+        
+        return $rep->getTagsStr($doc);
+
+    }
+    
         
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Services/WikiTagServiceException.php	Wed Dec 14 23:28:57 2011 +0100
@@ -0,0 +1,30 @@
+<?php
+/*
+ * This file is part of the WikiTagBundle package.
+ *
+ * (c) IRI <http://www.iri.centrepompidou.fr/>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace IRI\Bundle\WikiTagBundle\Services;
+
+class WikiTagServiceException extends \Exception
+{
+    /**
+     * The error code
+     * @var string
+     */
+    protected $error_code;
+    
+    public function __construct ($message = "", $code = 0, $previous = null, $error_code = "")
+    {
+        parent::__construct($message, $code, $previous);
+        $this->error_code = $error_code;
+    }
+    
+    public function getErrorCode() {
+        return $this->error_code;
+    }
+}
\ No newline at end of file
--- a/Tests/Services/DocumentServiceTest.php	Fri Dec 09 06:43:49 2011 +0100
+++ b/Tests/Services/DocumentServiceTest.php	Wed Dec 14 23:28:57 2011 +0100
@@ -16,12 +16,15 @@
 {
 
     protected $_container;
+    protected $_doctrine;
+    protected $_application;
+    protected $_kernel;
     
     public function __construct()
     {
-        $kernel = new \AppKernel("test", true);
-        $kernel->boot();
-        $this->_container = $kernel->getContainer();
+        $this->_kernel = new \AppKernel("test", true);
+        $this->_kernel->boot();
+        $this->_container = $this->_kernel->getContainer();
         parent::__construct();
     }
     
@@ -30,18 +33,67 @@
         return $this->_container->get($service);
     }
     
+    protected function getDoctrine()
+    {
+        if(is_null($this->_doctrine))
+        {
+            $this->_doctrine = $this->get('doctrine');
+        }
+        return $this->_doctrine;
+    }
+    
+    
+    public function testGetTagLabels()
+    {
+        $doc_service = $this->get("wiki_tag.document");
+        $doc1 = $this->getDoctrine()->getRepository("CompanyBaseBundle:Document")->findOneByTitle("Title 1");
         
+        $tags = $doc_service->getTagLabels($doc1->getId());
+        
+        $this->assertEquals(4,count($tags));
+        
+        $this->assertEquals(array("Tag1","Tag2","Tag3","Tag4"),$tags);
+        
+    }
+    
     public function testCopyTags()
     {
     
-        $search_service = $this->get("wiki_tag.document");
+        $doc_service = $this->get("wiki_tag.document");
+        
+        $doc1 = $this->getDoctrine()->getRepository("CompanyBaseBundle:Document")->findOneByTitle("Title 1");
+
+        $this->assertEquals(4,count($doc_service->getTagLabels($doc1->getId())));
+                
+        $doc2 = $this->getDoctrine()->getRepository("CompanyBaseBundle:Document")->findOneByTitle("Title 4");
         
-        // TODO : get doc 1
-        // TODO : get doc 2
-        // call copyTags
-    
+        $this->assertEquals(0,count($doc_service->getTagLabels($doc2->getId())));
+        
+        $doc_service->copyTags($doc1->getId(), $doc2->getId());
+
+        $this->assertEquals(4,count($doc_service->getTagLabels($doc2->getId())));
+        $this->assertEquals(array("Tag1","Tag2","Tag3","Tag4"),$doc_service->getTagLabels($doc2->getId()));
+        
     }
     
+    public function setUp()
+    {
+        $this->_application = new \Symfony\Bundle\FrameworkBundle\Console\Application($this->_kernel);
+        $this->_application->setAutoExit(false);
+        $this->runConsole("doctrine:schema:drop", array("--force" => true));
+        $this->runConsole("wikitag:schema:create");
+        $this->runConsole("cache:warmup");
+        $this->runConsole("doctrine:fixtures:load", array("--fixtures" => __DIR__ . "/../../../../../../../src/Company/BaseBundle/DataFixtures"));
+    }
+    
+    protected function runConsole($command, Array $options = array())
+    {
+        
+        $options["-e"] = "test";
+        $options["-q"] = null;
+        $options = array_merge($options, array('command' => $command));
+        return $this->_application->run(new \Symfony\Component\Console\Input\ArrayInput($options));
+    }
     
 }
 
--- a/Tests/Services/SearchServiceTest.php	Fri Dec 09 06:43:49 2011 +0100
+++ b/Tests/Services/SearchServiceTest.php	Wed Dec 14 23:28:57 2011 +0100
@@ -48,10 +48,10 @@
     
         $search_service = $this->get("wiki_tag.search");
     
-        $result = $search_service->completion("fra");
+        $result = $search_service->completion("tag");
     
         $this->assertNotNull($result, "tag cloud should not be null");
-        $this->assertGreaterThanOrEqual(1, count($result));
+        $this->assertEquals(4, count($result));
     }
     
     
--- a/Utils/WikiTagUtils.php	Fri Dec 09 06:43:49 2011 +0100
+++ b/Utils/WikiTagUtils.php	Wed Dec 14 23:28:57 2011 +0100
@@ -49,6 +49,15 @@
      */
     public static function getWikipediaInfo($tag_label_normalized, $page_id=null)
     {
+        // get ignore_wikipedia_error parameter
+        $ignore_wikipedia_error = false;
+        
+        if(key_exists('kernel', $GLOBALS)) {
+            $kernel = $GLOBALS['kernel'];
+            $ignore_wikipedia_error = $kernel->getContainer()->getParameter('wiki_tag.ignore_wikipedia_error');
+        }
+        
+        
         $params = array('action'=>'query', 'prop'=>'info|categories|langlinks', 'inprop'=>'url', 'lllimit'=>'500', 'cllimit'=>'500', 'rvprop'=>'ids', 'format'=>'json');
         if($tag_label_normalized!=null){
             $params['titles'] = urlencode($tag_label_normalized);
@@ -60,7 +69,17 @@
             return WikiTagUtils::returnNullResult(null);
         }
         
-        $ar = WikiTagUtils::requestWikipedia($params);
+        try {
+            $ar = WikiTagUtils::requestWikipedia($params);
+        }
+        catch(\Exception $e) {
+            if($ignore_wikipedia_error) {
+                return WikiTagUtils::returnNullResult(null);
+            }
+            else {
+                throw $e;
+            }
+        }
 
         $res = $ar[0];
         $original_response = $res;
@@ -99,7 +118,18 @@
         if($status==Tag::$TAG_URL_STATUS_DICT["redirection"])
         {
             $params['redirects'] = "true";
-            $ar = WikiTagUtils::requestWikipedia($params);
+            try {
+                $ar = WikiTagUtils::requestWikipedia($params);
+            }
+            catch(\Exception $e) {
+                if($ignore_wikipedia_error) {
+                    return WikiTagUtils::returnNullResult(null);
+                }
+                else {
+                    throw $e;
+                }
+            }
+            
             $res = $ar[0];
             $pages = $ar[1];
             #we know that we have at least one answer
@@ -144,7 +174,7 @@
         	'dbpedia_uri'=>$dbpedia_uri,
         	'revision_id'=>$revision_id,
         	'response'=>$original_response);
-        //return $url." <br/>RES =  ".$res/*." <br/>DUMP =  ".var_dump($pages)*/." <br/>COUNT =  ".count($pages)." <br/>page =  ".var_dump($page);
+        
         return $wp_response;
     }
     
@@ -172,6 +202,7 @@
         $ch = curl_init();
         curl_setopt($ch, CURLOPT_URL, $url);
         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+        //TODO: change
         curl_setopt($ch, CURLOPT_USERAGENT, 'http://www.iri.centrepompidou.fr');
         curl_setopt($ch, CURLOPT_TIMEOUT_MS, 5000);
         $res = curl_exec($ch);
@@ -180,7 +211,7 @@
         curl_close($ch);
         
         if ($curl_errno > 0) {
-            throw new \Exception("Wikipedia request failed. cURLError #$curl_errno: $curl_error\n");
+            throw new \Exception("Wikipedia request failed. cURLError #$curl_errno: $curl_error\n", $curl_errno, null);
         }
         
         $val = json_decode($res, true);