ModelTest.php 7.67 KB
Newer Older
Alexander Makarov committed
1 2 3
<?php

namespace yiiunit\framework\base;
Alexander Makarov committed
4

Alexander Makarov committed
5
use yii\base\Model;
Alexander Makarov committed
6 7
use yiiunit\TestCase;
use yiiunit\data\base\Speaker;
Alexander Makarov committed
8 9
use yiiunit\data\base\Singer;
use yiiunit\data\base\InvalidRulesModel;
Alexander Makarov committed
10 11

/**
12
 * @group base
Alexander Makarov committed
13 14 15
 */
class ModelTest extends TestCase
{
Qiang Xue committed
16 17 18 19 20 21
	protected function setUp()
	{
		parent::setUp();
		$this->mockApplication();
	}

22
	public function testGetAttributeLabel()
Alexander Makarov committed
23 24 25 26 27 28 29 30 31 32 33 34 35
	{
		$speaker = new Speaker();
		$this->assertEquals('First Name', $speaker->getAttributeLabel('firstName'));
		$this->assertEquals('This is the custom label', $speaker->getAttributeLabel('customLabel'));
		$this->assertEquals('Underscore Style', $speaker->getAttributeLabel('underscore_style'));
	}

	public function testGetAttributes()
	{
		$speaker = new Speaker();
		$speaker->firstName = 'Qiang';
		$speaker->lastName = 'Xue';

Alexander Makarov committed
36
		$this->assertEquals([
Alexander Makarov committed
37 38 39 40
			'firstName' => 'Qiang',
			'lastName' => 'Xue',
			'customLabel' => null,
			'underscore_style' => null,
Alexander Makarov committed
41
		], $speaker->getAttributes());
Alexander Makarov committed
42

Alexander Makarov committed
43
		$this->assertEquals([
Alexander Makarov committed
44 45
			'firstName' => 'Qiang',
			'lastName' => 'Xue',
Alexander Makarov committed
46
		], $speaker->getAttributes(['firstName', 'lastName']));
Alexander Makarov committed
47

Alexander Makarov committed
48
		$this->assertEquals([
Alexander Makarov committed
49 50
			'firstName' => 'Qiang',
			'lastName' => 'Xue',
Alexander Makarov committed
51
		], $speaker->getAttributes(null, ['customLabel', 'underscore_style']));
Alexander Makarov committed
52

Alexander Makarov committed
53
		$this->assertEquals([
Alexander Makarov committed
54
			'firstName' => 'Qiang',
Alexander Makarov committed
55
		], $speaker->getAttributes(['firstName', 'lastName'], ['lastName', 'customLabel', 'underscore_style']));
Alexander Makarov committed
56 57 58 59 60 61
	}

	public function testSetAttributes()
	{
		// by default mass assignment doesn't work at all
		$speaker = new Speaker();
Alexander Makarov committed
62
		$speaker->setAttributes(['firstName' => 'Qiang', 'underscore_style' => 'test']);
Alexander Makarov committed
63 64 65 66 67 68
		$this->assertNull($speaker->firstName);
		$this->assertNull($speaker->underscore_style);

		// in the test scenario
		$speaker = new Speaker();
		$speaker->setScenario('test');
Alexander Makarov committed
69
		$speaker->setAttributes(['firstName' => 'Qiang', 'underscore_style' => 'test']);
Alexander Makarov committed
70 71 72
		$this->assertNull($speaker->underscore_style);
		$this->assertEquals('Qiang', $speaker->firstName);

Alexander Makarov committed
73
		$speaker->setAttributes(['firstName' => 'Qiang', 'underscore_style' => 'test'], false);
Alexander Makarov committed
74 75 76 77
		$this->assertEquals('test', $speaker->underscore_style);
		$this->assertEquals('Qiang', $speaker->firstName);
	}

78 79 80 81 82
	public function testLoad()
	{
		$singer = new Singer();
		$this->assertEquals('Singer', $singer->formName());

Alexander Makarov committed
83
		$post = ['firstName' => 'Qiang'];
84 85 86 87 88 89 90 91 92 93

		Speaker::$formName = '';
		$model = new Speaker();
		$model->setScenario('test');
		$this->assertTrue($model->load($post));
		$this->assertEquals('Qiang', $model->firstName);

		Speaker::$formName = 'Speaker';
		$model = new Speaker();
		$model->setScenario('test');
Alexander Makarov committed
94
		$this->assertTrue($model->load(['Speaker' => $post]));
95 96 97 98 99
		$this->assertEquals('Qiang', $model->firstName);

		Speaker::$formName = 'Speaker';
		$model = new Speaker();
		$model->setScenario('test');
Alexander Makarov committed
100
		$this->assertFalse($model->load(['Example' => []]));
101 102 103
		$this->assertEquals('', $model->firstName);
	}

Alexander Makarov committed
104 105 106 107 108 109 110 111
	public function testActiveAttributes()
	{
		// by default mass assignment doesn't work at all
		$speaker = new Speaker();
		$this->assertEmpty($speaker->activeAttributes());

		$speaker = new Speaker();
		$speaker->setScenario('test');
Alexander Makarov committed
112
		$this->assertEquals(['firstName', 'lastName', 'underscore_style'], $speaker->activeAttributes());
Alexander Makarov committed
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
	}

	public function testIsAttributeSafe()
	{
		// by default mass assignment doesn't work at all
		$speaker = new Speaker();
		$this->assertFalse($speaker->isAttributeSafe('firstName'));

		$speaker = new Speaker();
		$speaker->setScenario('test');
		$this->assertTrue($speaker->isAttributeSafe('firstName'));

	}

	public function testErrors()
	{
		$speaker = new Speaker();

		$this->assertEmpty($speaker->getErrors());
		$this->assertEmpty($speaker->getErrors('firstName'));
		$this->assertEmpty($speaker->getFirstErrors());

		$this->assertFalse($speaker->hasErrors());
		$this->assertFalse($speaker->hasErrors('firstName'));

		$speaker->addError('firstName', 'Something is wrong!');
Alexander Makarov committed
139 140
		$this->assertEquals(['firstName' => ['Something is wrong!']], $speaker->getErrors());
		$this->assertEquals(['Something is wrong!'], $speaker->getErrors('firstName'));
Alexander Makarov committed
141 142

		$speaker->addError('firstName', 'Totally wrong!');
Alexander Makarov committed
143 144
		$this->assertEquals(['firstName' => ['Something is wrong!', 'Totally wrong!']], $speaker->getErrors());
		$this->assertEquals(['Something is wrong!', 'Totally wrong!'], $speaker->getErrors('firstName'));
Alexander Makarov committed
145 146 147 148 149

		$this->assertTrue($speaker->hasErrors());
		$this->assertTrue($speaker->hasErrors('firstName'));
		$this->assertFalse($speaker->hasErrors('lastName'));

Qiang Xue committed
150
		$this->assertEquals(['firstName' => 'Something is wrong!'], $speaker->getFirstErrors());
Alexander Makarov committed
151 152 153 154
		$this->assertEquals('Something is wrong!', $speaker->getFirstError('firstName'));
		$this->assertNull($speaker->getFirstError('lastName'));

		$speaker->addError('lastName', 'Another one!');
Alexander Makarov committed
155 156
		$this->assertEquals([
			'firstName' => [
Alexander Makarov committed
157 158
				'Something is wrong!',
				'Totally wrong!',
Alexander Makarov committed
159 160 161
			],
			'lastName' => ['Another one!'],
		], $speaker->getErrors());
Alexander Makarov committed
162 163

		$speaker->clearErrors('firstName');
Alexander Makarov committed
164 165 166
		$this->assertEquals([
			'lastName' => ['Another one!'],
		], $speaker->getErrors());
Alexander Makarov committed
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189

		$speaker->clearErrors();
		$this->assertEmpty($speaker->getErrors());
		$this->assertFalse($speaker->hasErrors());
	}

	public function testArraySyntax()
	{
		$speaker = new Speaker();

		// get
		$this->assertNull($speaker['firstName']);

		// isset
		$this->assertFalse(isset($speaker['firstName']));

		// set
		$speaker['firstName'] = 'Qiang';

		$this->assertEquals('Qiang', $speaker['firstName']);
		$this->assertTrue(isset($speaker['firstName']));

		// iteration
Alexander Makarov committed
190
		$attributes = [];
resurtm committed
191
		foreach ($speaker as $key => $attribute) {
Alexander Makarov committed
192 193
			$attributes[$key] = $attribute;
		}
Alexander Makarov committed
194
		$this->assertEquals([
Alexander Makarov committed
195 196 197 198
			'firstName' => 'Qiang',
			'lastName' => null,
			'customLabel' => null,
			'underscore_style' => null,
Alexander Makarov committed
199
		], $attributes);
Alexander Makarov committed
200 201 202 203 204 205 206 207

		// unset
		unset($speaker['firstName']);

		// exception isn't expected here
		$this->assertNull($speaker['firstName']);
		$this->assertFalse(isset($speaker['firstName']));
	}
Alexander Makarov committed
208 209 210 211

	public function testDefaults()
	{
		$singer = new Model();
Alexander Makarov committed
212 213
		$this->assertEquals([], $singer->rules());
		$this->assertEquals([], $singer->attributeLabels());
Alexander Makarov committed
214 215 216 217 218
	}

	public function testDefaultScenarios()
	{
		$singer = new Singer();
Alexander Makarov committed
219
		$this->assertEquals(['default' => ['lastName', 'underscore_style']], $singer->scenarios());
220 221 222 223 224 225 226 227 228 229 230 231 232 233

		$scenarios = [
			'default' => ['id', 'name', 'description'],
			'administration' => ['name', 'description', 'is_disabled'],
		];
		$model = new ComplexModel1();
		$this->assertEquals($scenarios, $model->scenarios());
		$scenarios = [
			'default' => ['id', 'name', 'description'],
			'suddenlyUnexpectedScenario' => ['name', 'description'],
			'administration' => ['id', 'name', 'description', 'is_disabled'],
		];
		$model = new ComplexModel2();
		$this->assertEquals($scenarios, $model->scenarios());
Alexander Makarov committed
234 235 236 237 238 239 240 241 242 243 244
	}

	public function testIsAttributeRequired()
	{
		$singer = new Singer();
		$this->assertFalse($singer->isAttributeRequired('firstName'));
		$this->assertTrue($singer->isAttributeRequired('lastName'));
	}

	public function testCreateValidators()
	{
245
		$this->setExpectedException('yii\base\InvalidConfigException', 'Invalid validation rule: a rule must specify both attribute names and validator type.');
Alexander Makarov committed
246 247 248 249

		$invalid = new InvalidRulesModel();
		$invalid->createValidators();
	}
Alexander Makarov committed
250
}
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274

class ComplexModel1 extends Model
{
	public function rules()
	{
		return [
			[['id'], 'required', 'except' => 'administration'],
			[['name', 'description'], 'filter', 'filter' => 'trim'],
			[['is_disabled'], 'boolean', 'on' => 'administration'],
		];
	}
}

class ComplexModel2 extends Model
{
	public function rules()
	{
		return [
			[['id'], 'required', 'except' => 'suddenlyUnexpectedScenario'],
			[['name', 'description'], 'filter', 'filter' => 'trim'],
			[['is_disabled'], 'boolean', 'on' => 'administration'],
		];
	}
}