I have the following test for my behavior in 

tests\TestCase\Model\Behavior\SluggableBehaviorTest.php

<?php
namespace App\Test\TestCase\Model\Behavior;

use App\Model\Behavior\SluggableBehavior;
use Cake\TestSuite\TestCase;
//use ArrayObject;
use Cake\Core\Plugin;
use Cake\ORM\Entity;
use Cake\ORM\Table;
use PHPUnit_Framework_TestCase;

/**
 * App\Model\Behavior\SluggableBehavior Test Case
 */
class SluggableBehaviorTest extends TestCase
{

    private $config = array();
    
    /**
     * setUp method
     *
     * @return void
     */
    public function setUp()
    {
        parent::setUp();
        
        $this->config = [
            'field' => 'title',
            'slug' => 'slug',
            'scope' => array(),
            'separator' => '-',
            'unique' => true,
            'update' => false,
            'trigger' => false
        ];

    }

    /**
     * tearDown method
     *
     * @return void
     */
    public function tearDown()
    {
        unset($this->Sluggable);

        parent::tearDown();
    }

    /**
     * Test initial setup
     *
     * @return void
     */
    public function testInitialization()
    {
        $this->markTestIncomplete('Not implemented yet.');
    }
    
    /**
     * Data provider method for testing valid file uploads
     *
     * @return array
     */
    public function slugEntityProvider()
    {
        return [
            [
                [],
                ['title' => 'Test', 'slug' => ''],
                ['title' => 'Test', 'slug' => 'test']
            ],
            [
                ['field' => 'other_title', 'slug' => 'other_slug'],
                ['other_title' => 'Test Name', 'other_slug' => ''],
                ['other_title' => 'Test Name', 'other_slug' => 'test-name']
            ],
            [
                ['separator' => '_'],
                ['title' => 'Test Name', 'slug' => ''],
                ['title' => 'Test Name', 'slug' => 'test_name']            
            ]             
        ];
        
    }
    /**
     * Test that correct field is slugged
     * 
     * @dataProvider slugEntityProvider
     */    
    public function testSlug(array $configUpdates, array $entityData, array 
$expected)
    {
        $config = $this->config;
        foreach($configUpdates as $key => $value) {
            $config[$key] = $value;
        }           
        
        $table = $this->getMock('Cake\ORM\Table', null);
        $Sluggable = $this->getMockBuilder(
'App\Model\Behavior\SluggableBehavior')
            ->setConstructorArgs([$table, $config])
            ->setMethods(['makeUniqueSlug'])
            ->getMock();
               
        $Sluggable->expects($this->once())
            ->method('makeUniqueSlug')
            ->will($this->returnValue($expected[$config['slug']]));
            
        $entity = new Entity($entityData);
        
        $Sluggable->slug($entity);
        
        $this->assertEquals($expected[$config['slug']], $entity[$config[
'slug']]);
    }
    
    /**
     * Data provider method for testing valid file uploads
     *
     * @return array
     */
    public function beforeSaveEntityProvider()
    {
        return [
            [
                ['update' => false],
                ['slug' => 1],
                ['title' => 'Test Name', 'slug' => ''],
                ['title' => 'Test Name', 'slug' => 'test-name']            
            ],
            [
                ['update' => false],
                ['slug' => 0],
                ['id' => 1, 'title' => 'Test Name', 'slug' => 'test'],
                ['id' => 1, 'title' => 'Test Name', 'slug' => 'test']       
     
            ],
            [
                ['update' => true],
                ['slug' => 1],
                ['id' => 1, 'title' => 'Test Name', 'slug' => 'test'],
                ['id' => 1, 'title' => 'Test Name', 'slug' => 'test-name'] 
           
            ],            
            [
                ['trigger' => false],
                ['slug' => 1],
                ['title' => 'Test Name', 'slug' => '',     'trigger' => 
false],
                ['title' => 'Test Name', 'slug' => 'test', 'trigger' => 
false]            
            ],
            [
                ['trigger' => 'use_slug'],
                ['slug' => 0],
                ['title' => 'Test Name', 'slug' => '', 'use_slug' => false],
                ['title' => 'Test Name', 'slug' => '', 'use_slug' => false] 
           
            ]
        ];
    }
    
    /**
     * Test that field is only slugged when config specifies
     * 
     * @dataProvider beforeSaveEntityProvider
     */     
    public function testBeforeSave(array $configUpdates, array $methodCalls, 
array $entityData, array $expected)
    {
        $config = $this->config;
        foreach($configUpdates as $key => $value) {
            $config[$key] = $value;
        }          
        
        $table = $this->getMock('Cake\ORM\Table', null);
        $Sluggable = $this->getMockBuilder(
'App\Model\Behavior\SluggableBehavior')
            ->setConstructorArgs([$table, $config])
            ->setMethods(['slug'])
            ->getMock();
        
        if ($methodCalls['slug'] == 1) {
            $Sluggable->expects($this->once())
                ->method('slug')
                ->will($this->returnValue($expected[$config['slug']]));     
       
        } elseif ($methodCalls['slug'] == 0) {
            $Sluggable->expects($this->never())
                ->method('slug')
                ->will($this->returnValue($expected[$config['slug']]));     
         
        }   
            
        $entity = new Entity($entityData);
        
        $Sluggable->beforeSave($this->getMock('Cake\Event\Event', null, [
'beforeSave']), $entity);
    }
    
    
}

The function I want to test in the behavior is
src\Model\Behavior\SluggableBehavior.php
    /**
     * Generates a unique slug for that table.
     *
     * @param \Cake\ORM\Entity $entity the entity that is going to be saved
     * @return $slug
     */    
    protected function _makeUniqueSlug(Entity $entity)
    {
        
        $config = $this->config();   
        $slug =  Inflector::slug($entity->get($config['field']), $config[
'separator']);
        
        if (!$config['unique']) {
            return $slug;
        }
        
        $results = $this->_scope($this->_table->find())
            ->select(['id', $config['slug']])
            ->where([$config['slug'] => $slug])
            ->orWhere([$config['slug'] . ' REGEXP' => '^' . $slug . $config[
'separator'] . '[0-9]+'])
            ->all();
        
        $duplicates = array();
        foreach ($results as $result) {
            $duplicates[] = $result->{$config['slug']};
        }       
        
        if (!empty($duplicates)) {
            $startSlug = $slug;
            $index = 1;

            while ($index > 0) {
                if (!in_array($startSlug . $config['separator'] . $index, 
$duplicates)) {
                    $slug = $startSlug . $config['separator'] . $index;
                    $index = -1;
                }
                $index++;
            }
        }
        
        return $slug;     
    }

    /**
     * Alters the passed query so that it only returns scoped records as 
defined
     * in the tree configuration.
     *
     * @param \Cake\ORM\Query $query the Query to modify
     * @return \Cake\ORM\Query
     */
    protected function _scope($query)
    {
        $config = $this->config();

        if (is_array($config['scope'])) {
            return $query->where($config['scope']);
        } elseif (is_callable($config['scope'])) {
            return $config['scope']($query);
        }

        return $query;
    }
 

How do I mock the query to check for duplicates, or attach a fixture to a 
mock table class?

Thanks.


-- 
Like Us on FaceBook https://www.facebook.com/CakePHP
Find us on Twitter http://twitter.com/CakePHP

--- 
You received this message because you are subscribed to the Google Groups 
"CakePHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/cake-php.
For more options, visit https://groups.google.com/d/optout.

Reply via email to