diff --git a/core/control/Controller.php b/core/control/Controller.php index f7133f687..751582d90 100644 --- a/core/control/Controller.php +++ b/core/control/Controller.php @@ -550,4 +550,4 @@ class Controller extends RequestHandler { } } -?> \ No newline at end of file +?> diff --git a/core/control/HTTPRequest.php b/core/control/HTTPRequest.php index 01c008326..7294341c5 100644 --- a/core/control/HTTPRequest.php +++ b/core/control/HTTPRequest.php @@ -263,6 +263,7 @@ class HTTPRequest extends Object implements ArrayAccess { $response->addHeader("Content-Type", "$mimeType; name=\"" . addslashes($fileName) . "\""); $response->addHeader("Content-disposition", "attachment; filename=" . addslashes($fileName)); $response->addHeader("Content-Length", strlen($fileData)); + $response->addHeader("Pragma", ""); // Necessary because IE has issues sending files over SSL return $response; } diff --git a/core/control/RequestHandler.php b/core/control/RequestHandler.php index 46eeba9f0..c2a420048 100644 --- a/core/control/RequestHandler.php +++ b/core/control/RequestHandler.php @@ -133,7 +133,7 @@ class RequestHandler extends ViewableData { // But if we have more content on the URL and we don't know what to do with it, return an error. } else { - return $this->httpError(400, "I can't handle sub-URLs of a $this->class object."); + return $this->httpError(404, "I can't handle sub-URLs of a $this->class object."); } return $this; diff --git a/core/model/ErrorPage.php b/core/model/ErrorPage.php index e0c6797b7..111963a27 100755 --- a/core/model/ErrorPage.php +++ b/core/model/ErrorPage.php @@ -184,9 +184,7 @@ class ErrorPage extends Page { * @package cms */ class ErrorPage_Controller extends Page_Controller { - public function init() { - parent::init(); - + public function index() { Director::set_status_code($this->failover->ErrorCode ? $this->failover->ErrorCode : 404); } } diff --git a/core/model/fieldtypes/Boolean.php b/core/model/fieldtypes/Boolean.php index 561cd8031..6868c4aad 100644 --- a/core/model/fieldtypes/Boolean.php +++ b/core/model/fieldtypes/Boolean.php @@ -19,11 +19,11 @@ class Boolean extends DBField { } function Nice() { - return ($this->value) ? "yes" : "no"; + return ($this->value) ? _t('Boolean.YES', 'Yes') : _t('Boolean.NO', 'No'); } function NiceAsBoolean() { - return ($this->value) ? "true" : "false"; + return ($this->value) ? 'true' : 'false'; } /** @@ -32,7 +32,7 @@ class Boolean extends DBField { function saveInto($dataObject) { $fieldName = $this->name; if($fieldName) { - $dataObject->$fieldName = $this->value ? 1 : 0; + $dataObject->$fieldName = ($this->value) ? 1 : 0; } else { user_error("DBField::saveInto() Called on a nameless '$this->class' object", E_USER_ERROR); } @@ -41,6 +41,16 @@ class Boolean extends DBField { public function scaffoldFormField($title = null, $params = null) { return new CheckboxField($this->name, $title); } + + public function scaffoldSearchField($title = null) { + $anyText = _t('Boolean.ANY', 'Any'); + $source = array( + 1 => _t('Boolean.YES', 'Yes'), + 0 => _t('Boolean.NO', 'No') + ); + + return new DropdownField($this->name, $title, $source, '', null, "($anyText)"); + } /** * Return an encoding of the given value suitable for inclusion in a SQL statement. diff --git a/core/model/fieldtypes/Date.php b/core/model/fieldtypes/Date.php index b5a1e4432..9ccc5d2b1 100644 --- a/core/model/fieldtypes/Date.php +++ b/core/model/fieldtypes/Date.php @@ -91,7 +91,7 @@ class Date extends DBField { /** * Return the date formatted using the given strftime formatting string. * - * strftime obeyes the current LC_TIME/LC_ALL when printing lexical values + * strftime obeys the current LC_TIME/LC_ALL when printing lexical values * like day- and month-names */ function FormatI18N($formattingString) { diff --git a/core/model/fieldtypes/Enum.php b/core/model/fieldtypes/Enum.php index 16adedc0c..4ae18cd54 100755 --- a/core/model/fieldtypes/Enum.php +++ b/core/model/fieldtypes/Enum.php @@ -47,27 +47,25 @@ class Enum extends DBField { DB::requireField($this->tableName, $this->name, $values); } + /** + * Return a dropdown field suitable for editing this field + */ + function formField($title = null, $name = null, $hasEmpty = false, $value = "", $form = null, $emptyString = null) { + if(!$title) $title = $this->name; + if(!$name) $name = $this->name; + + $field = new DropdownField($name, $title, $this->enumValues($hasEmpty), $value, $form, $emptyString); + + return $field; + } public function scaffoldFormField($title = null, $params = null) { return $this->formField($title); } - /** - * Return a dropdown field suitable for editing this field - */ - function formField($title = null, $name = null, $hasEmpty = false, $value = "", $form = null) { - if(!$title) $title = $this->name; - if(!$name) $name = $this->name; - - $field = new DropdownField($name, $title, $this->enumValues($hasEmpty), $value, $form); - - return $field; - } - function scaffoldSearchField($title = null) { - $field = $this->formField($title); - $field->Source = array_merge(array("" => "(Any)"), $this->enumValues()); - return $field; + $anyText = _t('Enum.ANY', 'Any'); + return $this->formField($title, null, false, '', null, "($anyText)"); } /** diff --git a/dev/CSVParser.php b/dev/CSVParser.php index c24ceaf97..57b5822c2 100644 --- a/dev/CSVParser.php +++ b/dev/CSVParser.php @@ -74,8 +74,8 @@ class CSVParser extends Object implements Iterator { function __construct($filename, $delimiter = ",", $enclosure = '"') { $filename = Director::getAbsFile($filename); $this->filename = $filename; - $tis->delimiter = ","; - $this->enclosure = '"'; + $this->delimiter = $delimiter; + $this->enclosure = $enclosure; } /** diff --git a/dev/Debug.php b/dev/Debug.php index 8f2bb710d..d1e22ceb0 100644 --- a/dev/Debug.php +++ b/dev/Debug.php @@ -256,7 +256,7 @@ class Debug { echo $friendlyErrorMessage; } else { $errorFilePath = ErrorPage::get_filepath_for_errorcode($statusCode, Translatable::current_locale()); - if(file_exists($errorfilePath)) { + if(file_exists($errorFilePath)) { echo file_get_contents(ASSETS_PATH . "/error-$statusCode.html"); } else { $renderer = new DebugView(); diff --git a/filesystem/Folder.php b/filesystem/Folder.php index 82baae8c3..d3db001a0 100755 --- a/filesystem/Folder.php +++ b/filesystem/Folder.php @@ -316,7 +316,7 @@ class Folder extends File { $this, "Files", "File", - array("Title" => _t('Folder.TITLE', "Title"), "LinkedURL" => _t('Folder.FILENAME', "Filename")), + array("Title" => _t('Folder.TITLE', "Title"), "Filename" => _t('Folder.FILENAME', "Filename")), "" ); $fileList->setFolder($this); @@ -330,9 +330,6 @@ class Folder extends File { $deleteButton = new HiddenField('deletemarked'); } - $inlineFormAction = new InlineFormAction("delete_unused_thumbnails", _t('Folder.DELETEUNUSEDTHUMBNAILS', 'Delete unused thumbnails')); - $inlineFormAction->includeDefaultJS(false) ; - $fields = new FieldSet( new HiddenField("Title"), new TabSet("Root", @@ -355,12 +352,7 @@ class Folder extends File { ) ), new Tab("UnusedFiles", _t('Folder.UNUSEDFILESTAB', "Unused files"), - new LiteralField( "UnusedAssets", "

"._t('Folder.UNUSEDFILESTITLE', 'Unused files')."

" ), - $this->getAssetList(), - new FieldGroup( - new LiteralField( "UnusedThumbnails", "

"._t('Folder.UNUSEDTHUMBNAILSTITLE', 'Unused thumbnails')."

"), - $inlineFormAction - ) + new Folder_UnusedAssetsField($this) ) ), new HiddenField("ID") @@ -371,34 +363,12 @@ class Folder extends File { return $fields; } - /** - * Creates table for displaying unused files. - * - * @returns AssetTableField - */ - protected function getAssetList() { - $where = $this->getUsedFilesList(); - $assetList = new AssetTableField( - $this, - "AssetList", - "File", - array("Title" => _t('Folder.TITLE', "Title"), "LinkedURL" => _t('Folder.FILENAME', "Filename")), - "", - $where - ); - $assetList->setPopupCaption(_t('Folder.VIEWASSET', "View Asset")); - $assetList->setPermissions(array("show","delete")); - $assetList->Markable = false; - return $assetList; - - } - /** * Looks for files used in system and create where clause which contains all ID's of files. * * @returns String where clause which will work as filter. */ - protected function getUsedFilesList() { + public function getUsedFilesList() { $result = DB::query("SELECT DISTINCT \"FileID\" FROM \"SiteTree_ImageTracking\""); $usedFiles = array(); $where = ""; @@ -446,4 +416,60 @@ HTML; } -?> +class Folder_UnusedAssetsField extends CompositeField { + protected $folder; + + public function __construct($folder) { + $this->folder = $folder; + parent::__construct(new FieldSet()); + } + + public function getChildren() { + if($this->children->Count() == 0) { + $inlineFormAction = new InlineFormAction("delete_unused_thumbnails", _t('Folder.DELETEUNUSEDTHUMBNAILS', 'Delete unused thumbnails')); + $inlineFormAction->includeDefaultJS(false) ; + + $this->children = new FieldSet( + new LiteralField( "UnusedAssets", "

"._t('Folder.UNUSEDFILESTITLE', 'Unused files')."

" ), + $this->getAssetList(), + new FieldGroup( + new LiteralField( "UnusedThumbnails", "

"._t('Folder.UNUSEDTHUMBNAILSTITLE', 'Unused thumbnails')."

"), + $inlineFormAction + ) + ); + $this->children->setForm($this->form); + } + return $this->children; + } + + public function FieldHolder() { + $output = ""; + foreach($this->getChildren() as $child) { + $output .= $child->FieldHolder(); + } + return $output; + } + + + /** + * Creates table for displaying unused files. + * + * @returns AssetTableField + */ + protected function getAssetList() { + $where = $this->folder->getUsedFilesList(); + $assetList = new AssetTableField( + $this->folder, + "AssetList", + "File", + array("Title" => _t('Folder.TITLE', "Title"), "LinkedURL" => _t('Folder.FILENAME', "Filename")), + "", + $where + ); + $assetList->setPopupCaption(_t('Folder.VIEWASSET', "View Asset")); + $assetList->setPermissions(array("show","delete")); + $assetList->Markable = false; + return $assetList; + } +} +?> \ No newline at end of file diff --git a/forms/CheckboxField.php b/forms/CheckboxField.php index a31d56603..1a6045a14 100755 --- a/forms/CheckboxField.php +++ b/forms/CheckboxField.php @@ -5,13 +5,20 @@ * @subpackage fields-basic */ class CheckboxField extends FormField { - /** - * Returns a single checkbox field - used by templates. - * - * Shouldn't this have a value? - */ protected $disabled; + + function setValue($value) { + $this->value = ($value) ? 1 : 0; + } + + function dataValue() { + return ($this->value) ? 1 : 0; + } + + function Value() { + return ($this->value) ? 1 : 0; + } function Field() { $attributes = array( @@ -19,6 +26,7 @@ class CheckboxField extends FormField { 'class' => ($this->extraClass() ? $this->extraClass() : ''), 'id' => $this->id(), 'name' => $this->Name(), + 'value' => 1, 'checked' => $this->value ? 'checked' : '', 'tabindex' => $this->getTabIndex() ); @@ -27,12 +35,7 @@ class CheckboxField extends FormField { return $this->createTag('input', $attributes); } - - - function dataValue() { - return $this->value ? 1 : 0; - } - + /** * Checkboxes use the RightLabelledFieldHolder template, to put the field on the left * and the label on the right. See {@link FormField::FieldHolder} for more information about @@ -76,7 +79,7 @@ HTML; */ function performReadonlyTransformation() { - $field = new CheckboxField_Readonly($this->name, $this->title, $this->value ? 'Yes' : 'No'); + $field = new CheckboxField_Readonly($this->name, $this->title, $this->value ? _t('CheckboxField.YES', 'Yes') : _t('CheckboxField.NO', 'No')); $field->setForm($this->form); return $field; } @@ -99,7 +102,7 @@ class CheckboxField_Readonly extends ReadonlyField { } function setValue($val) { - $this->value = ($val) ? 'Yes' : 'No'; + $this->value = ($val) ? _t('CheckboxField.YES', 'Yes') : _t('CheckboxField.NO', 'No'); } } diff --git a/forms/DropdownField.php b/forms/DropdownField.php index 8cc06ccbb..a1bd69877 100755 --- a/forms/DropdownField.php +++ b/forms/DropdownField.php @@ -77,9 +77,20 @@ class DropdownField extends FormField { } foreach($source as $value => $title) { - $selected = ($value == $this->value) ? 'selected' : null; - if($selected && $this->value != 0) { - $this->isSelected = true; + + // Blank value of field and source (e.g. "" => "(Any)") + if($value === '' && ($this->value === '' || $this->value === null)) { + $selected = 'selected'; + } else { + // Normal value from the source + if($value) { + $selected = ($value == $this->value) ? 'selected' : null; + } else { + // Do a type check comparison, we might have an array key of 0 + $selected = ($value === $this->value) ? 'selected' : null; + } + + $this->isSelected = ($selected) ? true : false; } $options .= $this->createTag( @@ -92,7 +103,7 @@ class DropdownField extends FormField { ); } } - + $attributes = array( 'class' => ($this->extraClass() ? $this->extraClass() : ''), 'id' => $this->id(), diff --git a/forms/FormField.php b/forms/FormField.php index 5c71912dc..66520f691 100644 --- a/forms/FormField.php +++ b/forms/FormField.php @@ -118,7 +118,7 @@ class FormField extends RequestHandler { * * @return string */ - function Message(){ + function Message() { return $this->message; } @@ -130,7 +130,7 @@ class FormField extends RequestHandler { * * @return string */ - function MessageType(){ + function MessageType() { return $this->messageType; } diff --git a/integration/Geoip.php b/integration/Geoip.php index ddcc39a13..1ce65b7e4 100755 --- a/integration/Geoip.php +++ b/integration/Geoip.php @@ -1,14 +1,7 @@ $CountryName) + * By default, it will return an array, keyed by + * the country code with a value of the country + * name. + * + * To return the code only, pass in true for the + * $codeOnly parameter. + * + * @param string $address The IP address to get the country of + * @param boolean $codeOnly Returns just the country code */ - static function ip2country($address, $codeOnly = false) { + static function ip2country($address, $codeOnly = false) { + // Return if in CLI, or you'll get this error: "sh: geoiplookup: command not found" + if(Director::is_cli()) return false; - // Detect internal networks - this is us, so we're NZ - if(substr($address, 0, 7) == "192.168" || substr($address,0,4) == "127.") { - $code = 'NZ'; - } else { - $cmd = 'geoiplookup ' . escapeshellarg($address); - exec($cmd, $result, $code); - // Note: At time of writing, $result is always zero for this program + $cmd = 'geoiplookup ' . escapeshellarg($address); + exec($cmd, $result, $code); + // Note: At time of writing, $result is always zero for this program - if($code == 127) return false; - if($result == false) return false; - - // Always returns one line of code, e.g. : - // Geoip Country Edition: GB, United Kingdom - // NZ - $country = $result[0]; - - $start = strpos($country, ':'); - if($start) $start += 2; - $code = substr($country, $start, 2); // skip space - } + if($code == 127) return false; + if($result == false) return false; + + // Always returns one line of code, e.g. : + // Geoip Country Edition: GB, United Kingdom + // NZ + $country = $result[0]; + + $start = strpos($country, ':'); + if($start) $start += 2; + $code = substr($country, $start, 2); // skip space if($code == 'IP' || $code == '--') { - if(self::$default_country_code) $code = self::$default_country_code; - else return false; + if(self::$default_country_code) { + $code = self::$default_country_code; + } else { + return false; + } } if(!$codeOnly) { - $name = substr($country, $start+4); + $name = substr($country, $start + 4); if(!$name) $name = $this->countryCode2name($code); return array('code' => $code, 'name' => $name); @@ -315,7 +315,6 @@ class Geoip extends Object { } } - /** * Returns the country code, for the current visitor */ @@ -378,5 +377,4 @@ class Geoip extends Object { return $dropdown; } } - -?> +?> \ No newline at end of file diff --git a/security/Member.php b/security/Member.php index 20d0429a8..2873bdcbf 100644 --- a/security/Member.php +++ b/security/Member.php @@ -240,6 +240,23 @@ class Member extends DataObject { $this->extend('memberLoggedIn'); } + /** + * Check if the member ID logged in session actually + * has a database record of the same ID. If there is + * no logged in user, FALSE is returned anyway. + * + * @return boolean TRUE record found FALSE no record found + */ + static function logged_in_session_exists() { + if($id = Member::currentUserID()) { + if($member = DataObject::get_by_id('Member', $id)) { + if($member->exists()) return true; + } + } + + return false; + } + /** * Log the user in if the "remember login" cookie is set * diff --git a/security/MemberLoginForm.php b/security/MemberLoginForm.php index 09c6d5a42..3a56e51fc 100644 --- a/security/MemberLoginForm.php +++ b/security/MemberLoginForm.php @@ -43,16 +43,7 @@ class MemberLoginForm extends LoginForm { $backURL = Session::get('BackURL'); } - // We assume if session is storing a member ID, that member exists in the DB - $sessMemberExistsInDB = true; - if($sessionMemberID = Member::currentUserID()) { - $sessMemberInDB = DataObject::get_by_id('Member', $sessionMemberID); - if(!($sessMemberInDB && $sessMemberInDB->exists())) { - $sessMemberExistsInDB = false; - } - } - - if($checkCurrentUser && Member::currentUserID() && $sessMemberExistsInDB) { + if($checkCurrentUser && Member::currentUserID() && Member::logged_in_session_exists()) { $fields = new FieldSet( new HiddenField("AuthenticationMethod", null, $this->authenticator_class, $this) ); diff --git a/tests/ErrorPageTest.php b/tests/ErrorPageTest.php index a59190104..f5c84ffaa 100644 --- a/tests/ErrorPageTest.php +++ b/tests/ErrorPageTest.php @@ -1,31 +1,39 @@ assertTrue($errorPage instanceof ErrorPage); + $page = $this->objFromFixture('ErrorPage', '404'); - /* Test the URL of the error page out to get a response */ - $response = Director::test(Director::makeRelative($errorPage->Link())); + /* The page is an instance of ErrorPage */ + $this->assertTrue($page instanceof ErrorPage, 'The page is an instance of ErrorPage'); - /* We have an HTTPResponse object for the error page */ - $this->assertTrue($response instanceof HTTPResponse); + $response = $this->get($page->URLSegment); /* We have body text from the error page */ - $this->assertTrue($response->getBody() != null); + $this->assertNotNull($response->getBody(), 'We have body text from the error page'); /* Status code of the HTTPResponse for error page is "404" */ - $this->assertTrue($response->getStatusCode() == '404'); + $this->assertEquals($response->getStatusCode(), '404', 'Status cod eof the HTTPResponse for error page is "404"'); /* Status message of the HTTPResponse for error page is "Not Found" */ - $this->assertTrue($response->getStatusDescription() == 'Not Found'); + $this->assertEquals($response->getStatusDescription(), 'Not Found', 'Status message of the HTTResponse for error page is "Not found"'); + } + + function testBehaviourOfShowInMenuAndShowInSearchFlags() { + $page = $this->objFromFixture('ErrorPage', '404'); + + /* Don't show the error page in the menus */ + $this->assertEquals($page->ShowInMenus, 0, 'Don\'t show the error page in the menus'); + + /* Don't show the error page in the search */ + $this->assertEquals($page->ShowInSearch, 0, 'Don\'t show the error page in search'); } } - ?> \ No newline at end of file diff --git a/tests/ObjectStaticTest.php b/tests/ObjectStaticTest.php index 2c23cf58a..e2d47bdf9 100644 --- a/tests/ObjectStaticTest.php +++ b/tests/ObjectStaticTest.php @@ -118,5 +118,4 @@ class ObjectStaticTest_Combined2 extends ObjectStaticTest_Combined1 { class ObjectStaticTest_Combined3 extends ObjectStaticTest_Combined2 { public static $first = array('test_3'); public static $second = array('test_3'); -} -/**#@-*/ +} \ No newline at end of file diff --git a/tests/forms/CheckboxFieldTest.php b/tests/forms/CheckboxFieldTest.php new file mode 100644 index 000000000..403232873 --- /dev/null +++ b/tests/forms/CheckboxFieldTest.php @@ -0,0 +1,123 @@ +setValue(true); + + /* dataValue() for the field is 1 */ + $this->assertEquals($field->dataValue(), 1, 'dataValue() returns a 1'); + + /* Value() returns 1 as well */ + $this->assertEquals($field->Value(), 1, 'Value() returns a 1'); + } + + function testFieldValueString() { + /* Create the field, and set the value as "on" (raw request field value from DOM) */ + $field = new CheckboxField('IsChecked', 'Checked'); + $field->setValue('on'); + + /* dataValue() for the field is 1 */ + $this->assertEquals($field->dataValue(), 1, 'dataValue() returns a 1'); + + /* Value() returns 1 as well */ + $this->assertEquals($field->Value(), 1, 'Value() returns a 1'); + } + + function testFieldValueSettingNull() { + /* Create the field, and set the value as NULL */ + $field = new CheckboxField('IsChecked', 'Checked'); + $field->setValue(null); + + /* dataValue() for the field is 0 */ + $this->assertEquals($field->dataValue(), 0, 'dataValue() returns a 0'); + + /* Value() returns 0 as well */ + $this->assertEquals($field->Value(), 0, 'Value() returns a 0'); + } + + function testFieldValueSettingFalse() { + /* Create the field, and set the value as NULL */ + $field = new CheckboxField('IsChecked', 'Checked'); + $field->setValue(false); + + /* dataValue() for the field is 0 */ + $this->assertEquals($field->dataValue(), 0, 'dataValue() returns a 0'); + + /* Value() returns 0 as well */ + $this->assertEquals($field->Value(), 0, 'Value() returns a 0'); + } + + function testFieldValueWithoutSettingValue() { + /* Create the field, but don't set any value on it */ + $field = new CheckboxField('IsChecked', 'Checked'); + + /* dataValue() for the field is 0 */ + $this->assertEquals($field->dataValue(), 0, 'dataValue() returns a 0'); + + /* Value() returns 0 as well */ + $this->assertEquals($field->Value(), 0, 'Value() returns a 0'); + } + + function testSavingChecked() { + /* Create a new test data record */ + $article = new CheckboxFieldTest_Article(); + + /* Create a field, with a value of 1 */ + $field = new CheckboxField('IsChecked', 'Checked', 1); + + /* Save the field into our Article object */ + $field->saveInto($article); + + /* Write the record to the test database */ + $article->write(); + + /* Check that IsChecked column contains a 1 */ + $this->assertEquals( + DB::query("SELECT IsChecked FROM CheckboxFieldTest_Article")->value(), + 1, + 'We have a 1 set in the database, because the field saved into as a 1' + ); + + /* Delete the record we tested */ + $article->delete(); + } + + function testSavingUnchecked() { + /* Create a new test data record */ + $article = new CheckboxFieldTest_Article(); + + /* Create a field, with no value */ + $field = new CheckboxField('IsChecked', 'Checked'); + + /* Save the field into our Article object */ + $field->saveInto($article); + + /* Write the record to the test database */ + $article->write(); + + /* Check that IsChecked column contains a 0 */ + $this->assertEquals( + DB::query("SELECT IsChecked FROM CheckboxFieldTest_Article")->value(), + 0, + 'We have a 0 set in the database, because the field saved into as a 0' + ); + + /* Delete the record we tested */ + $article->delete(); + } + +} +class CheckboxFieldTest_Article extends DataObject implements TestOnly { + + public static $db = array( + 'IsChecked' => 'Boolean' + ); + +} +?> \ No newline at end of file diff --git a/tests/forms/CheckboxSetFieldTest.php b/tests/forms/CheckboxSetFieldTest.php index 0dd700ced..be1006662 100644 --- a/tests/forms/CheckboxSetFieldTest.php +++ b/tests/forms/CheckboxSetFieldTest.php @@ -1,5 +1,8 @@ 'No', 1 => 'Yes'), '', null, '(Select one)'); $dropdownField->addExtraClass('thisIsMyExtraClassForDropdownField'); preg_match('/thisIsMyExtraClassForDropdownField/', $dropdownField->Field(), $matches); - $this->assertTrue($matches[0] == 'thisIsMyExtraClassForDropdownField'); + $this->assertEquals($matches[0], 'thisIsMyExtraClassForDropdownField'); } function testGetSource() { @@ -89,5 +89,127 @@ class DropdownFieldTest extends SapphireTest { ) ); } + + function testNumberOfSelectOptionsAvailable() { + /* Create a field with a blank value */ + $field = $this->testDropdownField('(Any)'); + + /* 3 options are available */ + $this->assertEquals(count($this->findOptionElements($field->Field())), 3, '3 options are available'); + + /* There is one selected option, since a dropdown can only possibly have one! */ + $selectedOptions = $this->findSelectedOptionElements($field->Field()); + $this->assertEquals(count($selectedOptions), 1, 'We only have 1 selected option, since a dropdown can only possibly have one!'); + + /* Create a field without a blank value */ + $field = $this->testDropdownField(); + + /* 2 options are available */ + $this->assertEquals(count($this->findOptionElements($field->Field())), 2, '2 options are available'); + + /* There are no selected options */ + $selectedOptions = $this->findSelectedOptionElements($field->Field()); + $this->assertEquals(count($selectedOptions), 0, 'There are no selected options'); + } + + function testIntegerZeroValueSeelctedOptionBehaviour() { + $field = $this->testDropdownField('(Any)', 0); + $selectedOptions = $this->findSelectedOptionElements($field->Field()); + + /* The selected option is "No" */ + $this->assertEquals((string) $selectedOptions[0], 'No', 'The selected option is "No"'); + } + + function testBlankStringValueSelectedOptionBehaviour() { + $field = $this->testDropdownField('(Any)'); + $selectedOptions = $this->findSelectedOptionElements($field->Field()); + + /* The selected option is "(Any)" */ + $this->assertEquals((string) $selectedOptions[0], '(Any)', 'The selected option is "(Any)"'); + } + + function testNullValueSelectedOptionBehaviour() { + $field = $this->testDropdownField('(Any)', null); + $selectedOptions = $this->findSelectedOptionElements($field->Field()); + + /* The selected option is "(Any)" */ + $this->assertEquals((string) $selectedOptions[0], '(Any)', 'The selected option is "(Any)"'); + } + + function testStringValueSelectedOptionBehaviour() { + $field = $this->testDropdownField('(Any)', '1'); + $selectedOptions = $this->findSelectedOptionElements($field->Field()); + + /* The selected option is "Yes" */ + $this->assertEquals((string) $selectedOptions[0], 'Yes', 'The selected option is "Yes"'); + + $field->setSource(array( + 'Cats' => 'Cats and Kittens', + 'Dogs' => 'Dogs and Puppies' + )); + $field->setValue('Cats'); + + $selectedOptions = $this->findSelectedOptionElements($field->Field()); + + /* The selected option is "Cats and Kittens" */ + $this->assertEquals((string) $selectedOptions[0], 'Cats and Kittens', 'The selected option is "Cats and Kittens"'); + } + + /** + * Create a test dropdown field, with the option to + * set what source and blank value it should contain + * as optional parameters. + * + * @param string|null $emptyString The text to display for the empty value + * @param string|integer $value The default value of the field + * @return DropdownField object + */ + function testDropdownField($emptyString = null, $value = '') { + /* Set up source, with 0 and 1 integers as the values */ + $source = array( + 0 => 'No', + 1 => 'Yes' + ); + + return new DropdownField('Field', null, $source, $value, null, $emptyString); + } + + /** + * Find all the