Posts Tagged ‘cakephp’

12Jan

So, I read this article a couple days ago: http://mark-story.com/posts/view/testing-cakephp-controllers-the-hard-way . As a result I started pulling my hair out. I decided that is too much work. Perhaps CakePHP 1.3 fixed some of the issues mentioned in that document, but no one has really documented anything. In any case, it took a few days of experimentation, but I got a nice template going. I see a ton of people interested in testing now a days, one thing to remember when you are starting out is that we are only testing controllers, and as such should only test what THIS controller is doing. Controllers in this sense only transfer data from one place to another, add a little bit of data, and really function as  glue between models, views, components, utility classes etc. SOOO you should not be testing auth methods or if data is saved (thats what the tests for those classes are for. Furthermore, don’t test cake internal functions.

A couple more notes before the code…
– You need to set your debug level to 3
– This was a test straight from a CakeTestCase I started working on
– I tried a few ways to get access to auth/session data. This seemed to be the easiest way to do this. Simply login to your site with the user level that you’d like to test (or stay logged out). I tried to manually set the session data. I think cake doesn’t like that, and kills your session as a result.

<?php
/**
* @author parris
*/
class LrapackagesControllerTest extends CakeTestCase{
    /**
    * These should go somewhere more global
    */
    private function genRandomString() {
        $length = 10;
        $characters = '0123456789abcdefghijklmnopqrstuvwxyz';
        $string = '';
        for ($p = 0; $p < $length; $p++) {
            $string .= $characters[mt_rand(0, strlen($characters)-1)];
        }
        return $string;
    }

    private function genRandomDouble() {
        srand((double)microtime()*1000000);
        $randomnumber = rand(0,5);
        return $randomnumber;
    }

    function startCase(){
        echo "<h1>Starting LrapackagesController Test Case</h1>";
        $this->path = APP_PATH.'/lrabuilder/lrapackages/';
        $this->testPackage = array(
            'Lrapackage'=>array(
                'name'=>$this->genRandomString(),
                'part_number'=>$this->genRandomString(),
                'version'=>$this->genRandomDouble()
            ));
    }

    function endCase(){
        echo "<h1>Ending LrapackagesController Test Case</h1>";
    }

    function startTest($method){
        echo '<h3>Starting method '.$method.'</h3>';
    }

    function endTest($method){
        echo '<hr/>';
    }

    function testAdd(){
		$result = $this->testAction($this->path.'add',array('data'=>$this->testPackage,'method'=>'post','return'=>'vars'));
		if($_SESSION['Auth']['User']['role_id']==1 || $_SESSION['Auth']['User']['role_id']==2)
		  $this->tAddLoggedInUser($result['cakeDebug']->data['Lrapackage']);
		else
		  tAddPublicUser($result);
	}

    function tAddLoggedInUser($data){
        $this->assertEqual($data['name'],$this->testPackage['Lrapackage']['name']);
        $this->assertEqual($data['part_number'],$this->testPackage['Lrapackage']['part_number']);
        //I would assertWithinMargin, but since the data needs to be identical, I don't need that.
        $this->assertEqual($data['version'],$this->testPackage['Lrapackage']['version']);
        //1000 is selected arbitrarily, but I dont care about real accuracy here.
        $this->assertWithinMargin(strtotime($data['created']),strtotime(date('Y-m-d H:i:s')),1000);
        $this->assertEqual($data['user_id'],$_SESSION['Auth']['User']['id']);
    }

    function tAddPublicUser(){
    	//echo($result); the only bad thing about this method is that you need to decide what the return var is before you
    	//have the session info... however, assuming you have properly setup your acl you shouldn't even need this test...
        //let the acl tests confirm that logged out users dont have access to logged in areas!!
    }

    function testIndex(){
        $result = $this->testAction($this->path.'index');
        //debug($result); this results in an overwhelming amount of data, be selective of the output!!
    }
}

Questions?

Go forth and unit test :)!

Some useful docs:

http://simpletest.org/api/SimpleTest/

http://simpletest.org/api/SimpleTest/Extensions/PHPUnit_TestCase.html

http://simpletest.org/api/SimpleTest/UnitTester/UnitTestCase.htm

http://book.cakephp.org/view/1210/Testing-controllers

Share
19Apr

We need your help!!!

Andy Manoske and myself are representing the fine people of SJSU, CS Club, Game Dev, California and our respective organizations and communities this Friday in Washington D.C. for Project Tesla, a software tool.

But we need your help. Tesla has been well-recieved with 33,000 votes by people all around the world, and it’s battling neck and neck with some other folks for the coveted People’s Choice award. We need YOUR vote to help us clinch this award and EVERY vote counts.

How do you vote?

1.) Go to http://www.imaginecup.us/peopleschoice.aspx
2.) Click on “The Tesla Project”
3.) At the bottom rank us x-number of stars and submit your vote.

Please tell EVERYONE you know! We’re SO close to winning this, and we really need all of your guys’ help!

I will post video updates as the week goes on showing off our progress towards and during our stay in DC.
Technologies Used: CakePHP, .net C# (client), and tons of math!

We have significantly upgraded our project since the video mentioned earlier.

If you would like to be part of our testimonials at the competition please leave me a comment with your name and organization! You just need to discuss the value and importance of the Tesla Project!

Thanks! 🙂

Share
14Sep

So based on this one article within the bakery I made a carpool app with the google maps api. The coolest addition was that incorporated google maps api v2, and marker placement in real time via prototype. It kinda functions like craigslist where you would enter in your email and password and it would let you make a post. It is there for a limited amount of time and then it disappears.

A big issue when coming up with this concept was that people would not want to enter in their addresses. Luckily the solution was already built in. So rather than typing in your address, you can type in Safeway and a street name and it will drop a pin there! Not sure what I want to do with this one. I have a few ideas for google maps + letswoosh, but I want to keep that under wraps for now!

Check it out: www.parrisstudios.com/carpool

Share
27Mar

This is somewhat based off of the articles found in the bakery at cakephp.org; however, I will be expanding on those tutorials a bit. First of all, everyone likes fancy loading bars or spinners so here is a good site that will handle creating that for you: http://www.ajaxload.info/

One of my main challenges today was trying to properly narrow the results in each page depending on the category within the site I am located. This was not quite obvious. Another problem I had was trying to get data from other models. The first was more easily solvable. The second required me to use a request action. I am looking for a more elegant solution, but until then this gets the job done.

My controller is simple:


function cat($catId){
//Configure::write('debug', '2');
if(!$this->RequestHandler->isAjax()) {

}

$this->set('cat',$this->Event->EventCategory->find('first',array('conditions'=>array('EventCategory.id'=>$catId),'fields'=>array('EventCategory.id','EventCategory.cat_name'))));
$this->set('catId',$catId);
$this->set('events', $this->paginate(null, array('Event.event_category_id' => $catId,'Event.event_date>=curdate()')));

if($this->RequestHandler->isAjax()) {
$this->viewPath = 'elements'.DS.'events';
$this->render('paging');
}
}

The important line is where I set events with the call to paginate. This allows me to limit the results in the same why I would use find. Unfortunatly, unlike find it will not retrieve associated results.

View for cat


echo $javascript->link("prototype",false);
echo $javascript->link("scriptaculous/scriptaculous.js",false);
echo $javascript->link("columns/matching_columns",false);
//$paginator->options(array('update' => 'CatPaging', 'indicator' => 'LoadingDiv'));
?>
<div id="LoadingDiv" style="display: none;">
image('ajax-loader.gif'); ?></div>
<div id="CatPaging">
renderElement('events/paging'); ?></div>

elements/events/paging.ctp


$paginator->options(
array('update'=>'CatPaging',
'url'=>array('controller'=>'Events', 'action'=>'cat'),
'indicator' => 'LoadingDiv'));
?>
<div style="width: 100%; position: relative; float: left;">

// stuff here

</div>
<div style="margin: 15px 0pt; width: 100%; position: relative; text-align: center; float: left;">
prev('<<',array('url'=>$this->params['pass'])); ?> .
numbers(array('separator'=>' . ','url'=>$this->params['pass'])); ?> .
next('>>',array('url'=>$this->params['pass'])); ?></div>

I had to use the ‘url’ option and use $this->params[‘pass’] so that my url including the parameter transfered over to the pagination. Now I can use pagination within the categories of my events model! Not too bad.

I hope this helps someone! I was tweaking it for a few hours today. I hope it saves someone a little time.

Here it is in action: http://www.letswoosh.com/events/cat/1 (of course this is assuming I have at least 7events posted, right now there are 7. So tomorrow it may look like nothing is happening 🙁 )

Enjoy!

Share
6Feb

I posted this component in the bakery. It works for cake 1.2.

It is pretty light weight, and all you need is CURL.

Check it out!

http://bakery.cakephp.org/articles/view/paypal-direct-payment-component-using-curl

Share