summaryrefslogtreecommitdiff
path: root/demos/time-tracker/protected/pages/Docs/UserClassAndExceptions.page
diff options
context:
space:
mode:
Diffstat (limited to 'demos/time-tracker/protected/pages/Docs/UserClassAndExceptions.page')
-rw-r--r--demos/time-tracker/protected/pages/Docs/UserClassAndExceptions.page202
1 files changed, 0 insertions, 202 deletions
diff --git a/demos/time-tracker/protected/pages/Docs/UserClassAndExceptions.page b/demos/time-tracker/protected/pages/Docs/UserClassAndExceptions.page
deleted file mode 100644
index f85e00be..00000000
--- a/demos/time-tracker/protected/pages/Docs/UserClassAndExceptions.page
+++ /dev/null
@@ -1,202 +0,0 @@
-<com:TContent ID="body">
-<h1>More complete ProjectTestCase</h1>
-<p>
-In creating a new project, we need to check the following:
-<ul>
- <li>that the project does not already exists, i.e. no duplicate project name</li>
- <li>that the project creator and project manager exists when a new project is created</li>
-</ul>
-So to perform this task, we will modified the test code.
-<com:TTextHighlighter Language="php" CssClass="source">
-function testProjectDaoCanCreateNewProject()
-{
- $project = new Project();
- $project->ID = 1;
- $project->Name = "Project 1";
- $project->CreatorUserName = "Customer A";
- $project->ManagerUserName = "Manager A";
-
- $customer = new TimeTrackerUser();
- $customer->ID = 1;
- $customer->Name = "Customer A";
-
- $manager = new TimeTrackerUser();
- $manager->ID = 2;
- $manager->Name = "Manager A";
-
- if(($conn = $this->connection) instanceof MockTSqlMapper)
- {
- //return the customer and manager
- $conn->setReturnValue('queryForObject',
- $customer, array('GetUserByName', 'Customer A'));
- $conn->setReturnValue('queryForObject',
- $manager, array('GetUserByName', 'Manager A'));
-
- //project does not exist
- $conn->setReturnValue('queryForObject',
- null, array('GetProjectByName', 'Project 1'));
-
- $param['project'] = $project;
- $param['creator'] = $customer->ID;
- $param['manager'] = $manager->ID;
-
- $conn->setReturnValue('insert', true,
- array('CreateNewProject', $param));
- $conn->setReturnReference('queryForObject',
- $project, array('GetProjectByID', 1));
-
- //we expect queryForObject to be called 3 times
- $conn->expectMinimumCallCount('queryForObject', 3);
- $conn->expectAtLeastOnce('insert');
- }
-
- $this->assertTrue($this->dao->createNewProject($project));
- $this->assertEqual($this->dao->getProjectByID(1), $project);
-}
-</com:TTextHighlighter>
-</p>
-<p>It may seem very weird that there is so much code in the tests
-and why we even bother to write all these test codes. Well, using the
-above test code we have the following advantages.</p>
-<div class="info"><b class="tip">Advantages of Mock</b>
-<ol>
- <li>we don't need a real database base connection to test the code,
- this means we can start relying on tested code ealier</li>
- <li>when a test fails we know that problem is not part of the database</li>
- <li>when a test fail, we can quickly pin point the problem</li>
- <li>the test suite gives us the confidence to refactor our code</li>
-</ol>
-</div>
-
-<p>Of couse, the test will not be able to cover the higher interactions, such as
-the user interface, so intergration or functional web test will be used later on.
-</p>
-
-<p>So how did we come up with the above tests? We started simple, then we
-ask what sort of things it should handle. We assume that the connection object
-work as expect or known to be unexpected and see how the method we want to test handle
-these situations.</p>
-
-<p>If we run the above test, we will be faced with numerous errors. First will be
-that the <tt>TimeTrackerUser</tt> can not be found.</p>
-
-<h1>Creating a new User Class</h1>
-<p>Notice that the <tt>Project</tt> class contains <tt>CreatorUserName</tt>
-and <tt>ManagerUserName</tt> properties. So at some point we
-are going to need at least one <tt>User</tt> class. We shall name the class as
-<tt>TimeTrackerUser</tt> and save it as <tt>APP_CODE/TimeTrackerUser.php</tt>
-<com:TTextHighlighter Language="php" CssClass="source">
-&lt;?php
-Prado::using('System.Security.TUser');
-Prado::using('System.Security.TUserManager');
-class TimeTrackerUser extends TUser
-{
- private $_ID;
-
- public function __construct()
- {
- parent::__construct(new TUserManager());
- }
-
- public function getID(){ return $this->_ID; }
-
- public function setID($value)
- {
- if(is_null($this->_ID))
- $this->_ID = $value;
- else
- throw new TimeTrackerUserException(
- 'timetracker_user_readonly_id');
- }
-}
-?&gt;
-</com:TTextHighlighter>
-
-<h1>Custom Exceptions</h1>
-<p>We enforce that the ID of the user to be read-only once it has been
-set by throwing a custom exception. Prado's exception classes
-uses a string key to find a localized exception string containing more
-detailed description of the exception. The default exception messages
-are stored in the <tt>framework/Exceptions/messages.txt</tt>. This
-file location can be changed by overriding the <tt>getErrorMessageFile()</tt>
-method of <tt>TException</tt> class. We define a custom exception class
-for all Time Tracker application exceptions as <tt>TimeTrackerException</tt>
-and save the class as <tt>APP_CODE/TimeTrackerException.php</tt>.</p>
-
-<com:TTextHighlighter Language="php" CssClass="source">
-&lt;?php
-class TimeTrackerException extends TException
-{
- /**
- * @return string path to the error message file
- */
- protected function getErrorMessageFile()
- {
- return dirname(__FILE__).'/exceptions.txt';
- }
-}
-?&gt;
-</com:TTextHighlighter>
-
-<p>We then create a <tt>exceptions.txt</tt> file in the <tt>APP_CODE</tt>
-directory with the following content.</p>
-
-<com:TTextHighlighter Language="text" CssClass="source">
-timetracker_user_readonly_id = Time tracker user ID is read-only.
-</com:TTextHighlighter>
-
-<p>Additional parameters passed in the exception constructor can be
-added the message string using <tt>{0}</tt> as the first additional parameter,
-and <tt>{1}</tt> as the second additional parameter, and so on.
-For example, suppose we want to raise the follow exception.
-</p>
-
-<com:TTextHighlighter Language="php" CssClass="source">
-throw new TimeTrackerException('project_exists', $projectName);
-</com:TTextHighlighter>
-
-<p>The exception error message in <tt>exceptions.txt</tt> may contain something like:</p>
-<com:TTextHighlighter Language="text" CssClass="source">
-project_exists = Time tracker project '{0}' already exists.
-</com:TTextHighlighter>
-
-<h1>Completing the test case</h1>
-<p>From the unit test code, we can pretty much see what the implementation
-for <tt>createNewProject()</tt> will look like.</p>
-
-<com:TTextHighlighter Language="php" CssClass="source">
-public function createNewProject($project)
-{
- $sqlmap = $this->getConnection();
- $creator = $sqlmap->queryForObject('GetUserByName', $project->CreatorUserName);
- $manager = $sqlmap->queryForObject('GetUserByName', $project->ManagerUserName);
- $exists = $sqlmap->queryForObject('GetProjectByName', $project->Name);
- if($exists)
- {
- throw new TimeTrackerException(
- 'project_exists', $project->Name);
- }
- else if(!$creator || !$manager)
- {
- throw new TimeTrackerException(
- 'invalid_creator_and_manager',
- $project->Name, $project->CreatorUserName,
- $project->ManagerUserName);
- }
- else
- {
- $param['project'] = $project;
- $param['creator'] = $creator->ID;
- $param['manager'] = $manager->ID;
- return $sqlmap->insert('CreateNewProject', $param);
- }
-}
-</com:TTextHighlighter>
-
-<div class="tip"><b class="tip">Tip:</b>
-A hierachy of exception class can be used to have fine exception handling.
-Since this is a small project and for simplicity, we shall use the application level
-<tt>TimeTrackerException</tt> exception class for most exception cases.
-</div>
-
-</com:TContent> \ No newline at end of file