Skip to content
This repository was archived by the owner on Sep 10, 2021. It is now read-only.

Commit 88dd75e

Browse files
author
Michael Grauer
committed
BUG: refs #0281: Enforced unique Assetstore path and name in model, plus tests.
1 parent ccf426a commit 88dd75e

File tree

3 files changed

+253
-0
lines changed

3 files changed

+253
-0
lines changed

core/models/base/AssetstoreModelBase.php

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,83 @@ public function __construct()
3434
/** Abstract functions */
3535
abstract function getAll();
3636

37+
/**
38+
* helper function to detect a collision between a row with the
39+
* passed in keyVal (which should be null for a new row), and any
40+
* existing rows with the column $var having the value $value.
41+
* @param type $var column name
42+
* @param type $value column value
43+
* @param type $keyVal key value for passed in row, or null if a new row
44+
* @return type
45+
*/
46+
protected function detectCollision($var, $value, $keyVal)
47+
{
48+
// detect whether the current Assetstore will collide for the
49+
// variable value with an existing row
50+
$found = $this->findBy($var, $value);
51+
if(isset($found) && sizeof($found) > 0)
52+
{
53+
foreach($found as $existingAssetstoreDao)
54+
{
55+
// if the current dao does not already exist
56+
// then it collides with an existing row
57+
if(empty($keyVal))
58+
{
59+
return true;
60+
}
61+
else
62+
{
63+
// the current dao does already exist
64+
if($existingAssetstoreDao->getKey() !== $keyVal)
65+
{
66+
// if the current dao does exist and it is different than
67+
// the existingAssestoreDao then
68+
// it is a collision with an existing other row
69+
return true;
70+
}
71+
else
72+
{
73+
// if the current dao does exist and it shares the same key
74+
// it is updating itself, so there is no collision
75+
return false;
76+
}
77+
}
78+
}
79+
}
80+
else
81+
{
82+
// no matching rows found, no collision
83+
return false;
84+
}
85+
}
86+
87+
88+
3789
/** save an assetsore*/
3890
public function save($dao)
3991
{
92+
$key = $this->_key;
93+
// get the keyValue of the dao that is to be saved
94+
if(isset($dao->$key))
95+
{
96+
// the dao has a keyValue
97+
$keyVal = $dao->$key;
98+
}
99+
else
100+
{
101+
// the dao is for a new row, and doesn't yet have a keyValue
102+
$keyVal = null;
103+
}
104+
$path = $dao->getPath();
105+
if(empty($path) || $this->detectCollision('path', $path, $keyVal))
106+
{
107+
throw new Zend_Exception('Assetstore paths must be unique');
108+
}
109+
$name = $dao->getName();
110+
if(empty($name) || $this->detectCollision('name', $name, $keyVal))
111+
{
112+
throw new Zend_Exception('Assetstore names must be unique');
113+
}
40114
parent::save($dao);
41115
}
42116

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
<?php
2+
/*=========================================================================
3+
MIDAS Server
4+
Copyright (c) Kitware SAS. 20 rue de la Villette. All rights reserved.
5+
69328 Lyon, FRANCE.
6+
7+
See Copyright.txt for details.
8+
This software is distributed WITHOUT ANY WARRANTY; without even
9+
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10+
PURPOSE. See the above copyright notices for more information.
11+
=========================================================================*/
12+
/** AssetstoreModelTest*/
13+
class AssetstoreModelTest extends DatabaseTestCase
14+
{
15+
/** init test*/
16+
public function setUp()
17+
{
18+
$this->setupDatabase(array('default'));
19+
$this->_models = array('Assetstore');
20+
$this->_daos = array();
21+
parent::setUp();
22+
}
23+
24+
25+
26+
/**
27+
* helper function, will save an Assetstore, using either the passed in
28+
* assetstoreDao or creating a new one, will set the three parameter
29+
* values before saving.
30+
* @param type $name
31+
* @param type $path
32+
* @param type $type
33+
* @param AssetstoreDao $assetstoreDao
34+
* @return AssetstoreDao
35+
*/
36+
protected function validSaveTestcase($name, $path, $type, $assetstoreDao = null)
37+
{
38+
if(empty($assetstoreDao))
39+
{
40+
$assetstoreDao = new AssetstoreDao();
41+
}
42+
$assetstoreDao->setName($name);
43+
$assetstoreDao->setPath($path);
44+
$assetstoreDao->setType($type);
45+
$this->Assetstore->save($assetstoreDao);
46+
return $assetstoreDao;
47+
}
48+
49+
/**
50+
* helper function, attempts to save an Assetstore, using either the passed in
51+
* assetstoreDao or creating a new one, will set the three parameter
52+
* values before saving, expects that the save will fail, and asserts
53+
* that an exception has been thrown by the Assetstore Model.
54+
* @param type $name
55+
* @param type $path
56+
* @param type $type
57+
* @param AssetstoreDao $assetstoreDao
58+
*/
59+
protected function invalidSaveTestcase($name, $path, $type, $assetstoreDao = null)
60+
{
61+
if(empty($assetstoreDao))
62+
{
63+
$assetstoreDao = new AssetstoreDao();
64+
}
65+
$assetstoreDao->setName($name);
66+
$assetstoreDao->setPath($path);
67+
$assetstoreDao->setType($type);
68+
try
69+
{
70+
$this->Assetstore->save($assetstoreDao);
71+
$this->fail('Expected an exception saving assetstoreDao, but did not get one.');
72+
}
73+
catch(Zend_Exception $ze)
74+
{
75+
// if we got here, this is the correct behavior
76+
$this->assertTrue(true);
77+
}
78+
}
79+
80+
/** test the save method*/
81+
public function testSave()
82+
{
83+
84+
// expect that there will be one assetstore to start out, Default
85+
// this will probably need to be expanded once we start adding implementations
86+
// for the other two types of assetstore
87+
// for now, a local Default assetstore is expected
88+
$all = $this->Assetstore->getAll();
89+
$this->assertEquals(sizeof($all), 1);
90+
$default = $all[0];
91+
$this->assertEquals('Default', $default->getName());
92+
// Correct Create Test
93+
94+
95+
// create new ones with a different path from existing ones
96+
97+
$assetstoreDao1 = $this->validSaveTestcase('test_assetstore_1', '/testassetstore1/path', '0');
98+
$assetstoreDao2 = $this->validSaveTestcase('test_assetstore_2', '/testassetstore2/path', '1');
99+
$assetstoreDao3 = $this->validSaveTestcase('test_assetstore_3', '/testassetstore3/path', '2');
100+
101+
// make sure one got saved
102+
$found = $this->Assetstore->findBy('name', 'test_assetstore_3');
103+
$this->assertNotEmpty($found);
104+
$savedDao = $found[0];
105+
$this->assertTrue($this->Assetstore->compareDao($assetstoreDao3, $savedDao));
106+
107+
// Incorrect Create Tests
108+
109+
// create a new one with empty path, should fail
110+
$this->invalidSaveTestcase('test_assetstore_4', '', '0');
111+
112+
// create a new one with same path as existing ones, should fail
113+
$this->invalidSaveTestcase('test_assetstore_4', '/testassetstore1/path', '0');
114+
115+
// create a new one with empty name, should fail
116+
$this->invalidSaveTestcase('', '/testassetstore4/path', '0');
117+
118+
// create a new one with same path as existing ones, should fail
119+
$this->invalidSaveTestcase('test_assetstore_3', '/testassetstore4/path', '0');
120+
121+
// Incorrect Edit&Save Tests
122+
123+
// take existing, try to save with empty name
124+
$savedName = $assetstoreDao1->getName();
125+
$this->invalidSaveTestcase('', $assetstoreDao1->getPath(), $assetstoreDao1->getType(), $assetstoreDao1);
126+
$assetstoreDao1->setName($savedName);
127+
128+
// take existing, try to save with empty path
129+
$savedPath = $assetstoreDao1->getPath();
130+
$this->invalidSaveTestcase($assetstoreDao1->getName(), '', $assetstoreDao1->getType(), $assetstoreDao1);
131+
$assetstoreDao1->setPath($savedPath);
132+
133+
// take existing, try to save with a colliding name
134+
$savedName = $assetstoreDao1->getName();
135+
$this->invalidSaveTestcase($assetstoreDao2->getName(), $assetstoreDao1->getPath(), $assetstoreDao1->getType(), $assetstoreDao1);
136+
$assetstoreDao1->setName($savedName);
137+
138+
// take existing, try to save with a colliding path
139+
$savedPath = $assetstoreDao1->getPath();
140+
$this->invalidSaveTestcase($assetstoreDao1->getName(), $assetstoreDao2->getPath(), $assetstoreDao1->getType(), $assetstoreDao1);
141+
$assetstoreDao1->setPath($savedPath);
142+
143+
// Correct Edit&Save Tests
144+
145+
// take existing, try to save with a non-colliding name
146+
$savedName = $assetstoreDao1->getName();
147+
$newName = 'noncollidingname1';
148+
$this->validSaveTestcase($newName, $assetstoreDao1->getPath(), $assetstoreDao1->getType(), $assetstoreDao1);
149+
150+
// check that the new value is saved
151+
$found = $this->Assetstore->findBy('name', $newName);
152+
$this->assertNotEmpty($found);
153+
$foundDao = $found[0];
154+
$this->assertTrue($this->Assetstore->compareDao($foundDao, $assetstoreDao1));
155+
$this->assertEquals($foundDao->getName(), $newName);
156+
$assetstoreDao1->setName($savedName);
157+
158+
159+
// take existing, try to save with a non-colliding path
160+
$savedPath = $assetstoreDao1->getPath();
161+
$newPath = 'noncolliding/path';
162+
$this->validSaveTestcase($assetstoreDao1->getName(), $newPath, $assetstoreDao1->getType(), $assetstoreDao1);
163+
164+
// check that the new value is saved
165+
$found = $this->Assetstore->findBy('path', $newPath);
166+
$this->assertNotEmpty($found);
167+
$foundDao = $found[0];
168+
$this->assertTrue($this->Assetstore->compareDao($foundDao, $assetstoreDao1));
169+
$this->assertEquals($foundDao->getPath(), $newPath);
170+
$assetstoreDao1->setPath($savedPath);
171+
172+
// delete the newly added ones to clean up
173+
$this->Assetstore->delete($assetstoreDao1);
174+
$this->Assetstore->delete($assetstoreDao2);
175+
$this->Assetstore->delete($assetstoreDao3);
176+
}
177+
178+
}

core/tests/models/base/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
add_midas_test( AssetstoreModel AssetstoreModelTest.php )
12
add_midas_test( FeedModel FeedModelTest.php )
23
add_midas_test( FeedpolicygroupModel FeedpolicygroupModelTest.php )
34
add_midas_test( FeedpolicyuserModel FeedpolicyuserModelTest.php )

0 commit comments

Comments
 (0)