name = 'foo'; $this->assertSame('foo', $model->name); $this->assertTrue(isset($model->name)); unset($model->name); $this->assertFalse(isset($model->name)); // test mutation $model->list_items = ['name' => 'taylor']; $this->assertEquals(['name' => 'taylor'], $model->list_items); $attributes = $model->getAttributes(); $this->assertSame(json_encode(['name' => 'taylor']), $attributes['list_items']); } public function testSetAttributeWithNumericKey() { $model = new EloquentDateModelStub; $model->setAttribute(0, 'value'); $this->assertEquals([0 => 'value'], $model->getAttributes()); } public function testDirtyAttributes() { $model = new EloquentModelStub(['foo' => '1', 'bar' => 2, 'baz' => 3]); $model->syncOriginal(); $model->foo = 1; $model->bar = 20; $model->baz = 30; $this->assertTrue($model->isDirty()); $this->assertFalse($model->isDirty('foo')); $this->assertTrue($model->isDirty('bar')); $this->assertTrue($model->isDirty('foo', 'bar')); $this->assertTrue($model->isDirty(['foo', 'bar'])); } public function testIntAndNullComparisonWhenDirty() { $model = new EloquentModelCastingStub; $model->intAttribute = null; $model->syncOriginal(); $this->assertFalse($model->isDirty('intAttribute')); $model->forceFill(['intAttribute' => 0]); $this->assertTrue($model->isDirty('intAttribute')); } public function testFloatAndNullComparisonWhenDirty() { $model = new EloquentModelCastingStub; $model->floatAttribute = null; $model->syncOriginal(); $this->assertFalse($model->isDirty('floatAttribute')); $model->forceFill(['floatAttribute' => 0.0]); $this->assertTrue($model->isDirty('floatAttribute')); } public function testDirtyOnCastOrDateAttributes() { $model = new EloquentModelCastingStub; $model->setDateFormat('Y-m-d H:i:s'); $model->boolAttribute = 1; $model->foo = 1; $model->bar = '2017-03-18'; $model->dateAttribute = '2017-03-18'; $model->datetimeAttribute = '2017-03-23 22:17:00'; $model->syncOriginal(); $model->boolAttribute = true; $model->foo = true; $model->bar = '2017-03-18 00:00:00'; $model->dateAttribute = '2017-03-18 00:00:00'; $model->datetimeAttribute = null; $this->assertTrue($model->isDirty()); $this->assertTrue($model->isDirty('foo')); $this->assertTrue($model->isDirty('bar')); $this->assertFalse($model->isDirty('boolAttribute')); $this->assertFalse($model->isDirty('dateAttribute')); $this->assertTrue($model->isDirty('datetimeAttribute')); } public function testDirtyOnCastedObjects() { $model = new EloquentModelCastingStub; $model->setRawAttributes([ 'objectAttribute' => '["one", "two", "three"]', 'collectionAttribute' => '["one", "two", "three"]', ]); $model->syncOriginal(); $model->objectAttribute = ['one', 'two', 'three']; $model->collectionAttribute = ['one', 'two', 'three']; $this->assertFalse($model->isDirty()); $this->assertFalse($model->isDirty('objectAttribute')); $this->assertFalse($model->isDirty('collectionAttribute')); } public function testDirtyOnCastedArrayObject() { $model = new EloquentModelCastingStub; $model->setRawAttributes([ 'asarrayobjectAttribute' => '{"foo": "bar"}', ]); $model->syncOriginal(); $this->assertInstanceOf(ArrayObject::class, $model->asarrayobjectAttribute); $this->assertFalse($model->isDirty('asarrayobjectAttribute')); $model->asarrayobjectAttribute = ['foo' => 'bar']; $this->assertFalse($model->isDirty('asarrayobjectAttribute')); $model->asarrayobjectAttribute = ['foo' => 'baz']; $this->assertTrue($model->isDirty('asarrayobjectAttribute')); } public function testDirtyOnCastedCollection() { $model = new EloquentModelCastingStub; $model->setRawAttributes([ 'ascollectionAttribute' => '{"foo": "bar"}', ]); $model->syncOriginal(); $this->assertInstanceOf(BaseCollection::class, $model->ascollectionAttribute); $this->assertFalse($model->isDirty('ascollectionAttribute')); $model->ascollectionAttribute = ['foo' => 'bar']; $this->assertFalse($model->isDirty('ascollectionAttribute')); $model->ascollectionAttribute = ['foo' => 'baz']; $this->assertTrue($model->isDirty('ascollectionAttribute')); } public function testDirtyOnCastedStringable() { $model = new EloquentModelCastingStub; $model->setRawAttributes([ 'asStringableAttribute' => 'foo bar', ]); $model->syncOriginal(); $this->assertInstanceOf(Stringable::class, $model->asStringableAttribute); $this->assertFalse($model->isDirty('asStringableAttribute')); $model->asStringableAttribute = Str::of('foo bar'); $this->assertFalse($model->isDirty('asStringableAttribute')); $model->asStringableAttribute = Str::of('foo baz'); $this->assertTrue($model->isDirty('asStringableAttribute')); } public function testCleanAttributes() { $model = new EloquentModelStub(['foo' => '1', 'bar' => 2, 'baz' => 3]); $model->syncOriginal(); $model->foo = 1; $model->bar = 20; $model->baz = 30; $this->assertFalse($model->isClean()); $this->assertTrue($model->isClean('foo')); $this->assertFalse($model->isClean('bar')); $this->assertFalse($model->isClean('foo', 'bar')); $this->assertFalse($model->isClean(['foo', 'bar'])); } public function testCleanWhenFloatUpdateAttribute() { // test is equivalent $model = new EloquentModelStub(['castedFloat' => 8 - 6.4]); $model->syncOriginal(); $model->castedFloat = 1.6; $this->assertTrue($model->originalIsEquivalent('castedFloat')); // test is not equivalent $model = new EloquentModelStub(['castedFloat' => 5.6]); $model->syncOriginal(); $model->castedFloat = 5.5; $this->assertFalse($model->originalIsEquivalent('castedFloat')); } public function testCalculatedAttributes() { $model = new EloquentModelStub; $model->password = 'secret'; $attributes = $model->getAttributes(); // ensure password attribute was not set to null $this->assertArrayNotHasKey('password', $attributes); $this->assertSame('******', $model->password); $hash = 'e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4'; $this->assertEquals($hash, $attributes['password_hash']); $this->assertEquals($hash, $model->password_hash); } public function testArrayAccessToAttributes() { $model = new EloquentModelStub(['attributes' => 1, 'connection' => 2, 'table' => 3]); unset($model['table']); $this->assertTrue(isset($model['attributes'])); $this->assertEquals(1, $model['attributes']); $this->assertTrue(isset($model['connection'])); $this->assertEquals(2, $model['connection']); $this->assertFalse(isset($model['table'])); $this->assertEquals(null, $model['table']); $this->assertFalse(isset($model['with'])); } public function testOnly() { $model = new EloquentModelStub; $model->first_name = 'taylor'; $model->last_name = 'otwell'; $model->project = 'laravel'; $this->assertEquals(['project' => 'laravel'], $model->only('project')); $this->assertEquals(['first_name' => 'taylor', 'last_name' => 'otwell'], $model->only('first_name', 'last_name')); $this->assertEquals(['first_name' => 'taylor', 'last_name' => 'otwell'], $model->only(['first_name', 'last_name'])); } public function testNewInstanceReturnsNewInstanceWithAttributesSet() { $model = new EloquentModelStub; $instance = $model->newInstance(['name' => 'taylor']); $this->assertInstanceOf(EloquentModelStub::class, $instance); $this->assertSame('taylor', $instance->name); } public function testNewInstanceReturnsNewInstanceWithTableSet() { $model = new EloquentModelStub; $model->setTable('test'); $newInstance = $model->newInstance(); $this->assertSame('test', $newInstance->getTable()); } public function testNewInstanceReturnsNewInstanceWithMergedCasts() { $model = new EloquentModelStub; $model->mergeCasts(['foo' => 'date']); $newInstance = $model->newInstance(); $this->assertArrayHasKey('foo', $newInstance->getCasts()); $this->assertSame('date', $newInstance->getCasts()['foo']); } public function testCreateMethodSavesNewModel() { $_SERVER['__eloquent.saved'] = false; $model = EloquentModelSaveStub::create(['name' => 'taylor']); $this->assertTrue($_SERVER['__eloquent.saved']); $this->assertSame('taylor', $model->name); } public function testMakeMethodDoesNotSaveNewModel() { $_SERVER['__eloquent.saved'] = false; $model = EloquentModelSaveStub::make(['name' => 'taylor']); $this->assertFalse($_SERVER['__eloquent.saved']); $this->assertSame('taylor', $model->name); } public function testForceCreateMethodSavesNewModelWithGuardedAttributes() { $_SERVER['__eloquent.saved'] = false; $model = EloquentModelSaveStub::forceCreate(['id' => 21]); $this->assertTrue($_SERVER['__eloquent.saved']); $this->assertEquals(21, $model->id); } public function testFindMethodUseWritePdo() { EloquentModelFindWithWritePdoStub::onWriteConnection()->find(1); } public function testDestroyMethodCallsQueryBuilderCorrectly() { EloquentModelDestroyStub::destroy(1, 2, 3); } public function testDestroyMethodCallsQueryBuilderCorrectlyWithCollection() { EloquentModelDestroyStub::destroy(new BaseCollection([1, 2, 3])); } public function testDestroyMethodCallsQueryBuilderCorrectlyWithEloquentCollection() { EloquentModelDestroyStub::destroy(new Collection([ new EloquentModelDestroyStub(['id' => 1]), new EloquentModelDestroyStub(['id' => 2]), new EloquentModelDestroyStub(['id' => 3]), ])); } public function testDestroyMethodCallsQueryBuilderCorrectlyWithMultipleArgs() { EloquentModelDestroyStub::destroy(1, 2, 3); } public function testDestroyMethodCallsQueryBuilderCorrectlyWithEmptyIds() { $count = EloquentModelEmptyDestroyStub::destroy([]); $this->assertSame(0, $count); } public function testWithMethodCallsQueryBuilderCorrectly() { $result = EloquentModelWithStub::with('foo', 'bar'); $this->assertSame('foo', $result); } public function testWithoutMethodRemovesEagerLoadedRelationshipCorrectly() { $model = new EloquentModelWithoutRelationStub; $this->addMockConnection($model); $instance = $model->newInstance()->newQuery()->without('foo'); $this->assertEmpty($instance->getEagerLoads()); } public function testWithOnlyMethodLoadsRelationshipCorrectly() { $model = new EloquentModelWithoutRelationStub(); $this->addMockConnection($model); $instance = $model->newInstance()->newQuery()->withOnly('taylor'); $this->assertNotNull($instance->getEagerLoads()['taylor']); $this->assertArrayNotHasKey('foo', $instance->getEagerLoads()); } public function testEagerLoadingWithColumns() { $model = new EloquentModelWithoutRelationStub; $instance = $model->newInstance()->newQuery()->with('foo:bar,baz', 'hadi'); $builder = m::mock(Builder::class); $builder->shouldReceive('select')->once()->with(['bar', 'baz']); $this->assertNotNull($instance->getEagerLoads()['hadi']); $this->assertNotNull($instance->getEagerLoads()['foo']); $closure = $instance->getEagerLoads()['foo']; $closure($builder); } public function testWithMethodCallsQueryBuilderCorrectlyWithArray() { $result = EloquentModelWithStub::with(['foo', 'bar']); $this->assertSame('foo', $result); } public function testUpdateProcess() { $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps'])->getMock(); $query = m::mock(Builder::class); $query->shouldReceive('where')->once()->with('id', '=', 1); $query->shouldReceive('update')->once()->with(['name' => 'taylor'])->andReturn(1); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $model->expects($this->once())->method('updateTimestamps'); $model->setEventDispatcher($events = m::mock(Dispatcher::class)); $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true); $events->shouldReceive('until')->once()->with('eloquent.updating: '.get_class($model), $model)->andReturn(true); $events->shouldReceive('dispatch')->once()->with('eloquent.updated: '.get_class($model), $model)->andReturn(true); $events->shouldReceive('dispatch')->once()->with('eloquent.saved: '.get_class($model), $model)->andReturn(true); $model->id = 1; $model->foo = 'bar'; // make sure foo isn't synced so we can test that dirty attributes only are updated $model->syncOriginal(); $model->name = 'taylor'; $model->exists = true; $this->assertTrue($model->save()); } public function testUpdateProcessDoesntOverrideTimestamps() { $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery'])->getMock(); $query = m::mock(Builder::class); $query->shouldReceive('where')->once()->with('id', '=', 1); $query->shouldReceive('update')->once()->with(['created_at' => 'foo', 'updated_at' => 'bar'])->andReturn(1); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $model->setEventDispatcher($events = m::mock(Dispatcher::class)); $events->shouldReceive('until'); $events->shouldReceive('dispatch'); $model->id = 1; $model->syncOriginal(); $model->created_at = 'foo'; $model->updated_at = 'bar'; $model->exists = true; $this->assertTrue($model->save()); } public function testSaveIsCanceledIfSavingEventReturnsFalse() { $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery'])->getMock(); $query = m::mock(Builder::class); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $model->setEventDispatcher($events = m::mock(Dispatcher::class)); $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(false); $model->exists = true; $this->assertFalse($model->save()); } public function testUpdateIsCanceledIfUpdatingEventReturnsFalse() { $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery'])->getMock(); $query = m::mock(Builder::class); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $model->setEventDispatcher($events = m::mock(Dispatcher::class)); $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true); $events->shouldReceive('until')->once()->with('eloquent.updating: '.get_class($model), $model)->andReturn(false); $model->exists = true; $model->foo = 'bar'; $this->assertFalse($model->save()); } public function testEventsCanBeFiredWithCustomEventObjects() { $model = $this->getMockBuilder(EloquentModelEventObjectStub::class)->onlyMethods(['newModelQuery'])->getMock(); $query = m::mock(Builder::class); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $model->setEventDispatcher($events = m::mock(Dispatcher::class)); $events->shouldReceive('until')->once()->with(m::type(EloquentModelSavingEventStub::class))->andReturn(false); $model->exists = true; $this->assertFalse($model->save()); } public function testUpdateProcessWithoutTimestamps() { $model = $this->getMockBuilder(EloquentModelEventObjectStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'fireModelEvent'])->getMock(); $model->timestamps = false; $query = m::mock(Builder::class); $query->shouldReceive('where')->once()->with('id', '=', 1); $query->shouldReceive('update')->once()->with(['name' => 'taylor'])->andReturn(1); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $model->expects($this->never())->method('updateTimestamps'); $model->expects($this->any())->method('fireModelEvent')->willReturn(true); $model->id = 1; $model->syncOriginal(); $model->name = 'taylor'; $model->exists = true; $this->assertTrue($model->save()); } public function testUpdateUsesOldPrimaryKey() { $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps'])->getMock(); $query = m::mock(Builder::class); $query->shouldReceive('where')->once()->with('id', '=', 1); $query->shouldReceive('update')->once()->with(['id' => 2, 'foo' => 'bar'])->andReturn(1); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $model->expects($this->once())->method('updateTimestamps'); $model->setEventDispatcher($events = m::mock(Dispatcher::class)); $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true); $events->shouldReceive('until')->once()->with('eloquent.updating: '.get_class($model), $model)->andReturn(true); $events->shouldReceive('dispatch')->once()->with('eloquent.updated: '.get_class($model), $model)->andReturn(true); $events->shouldReceive('dispatch')->once()->with('eloquent.saved: '.get_class($model), $model)->andReturn(true); $model->id = 1; $model->syncOriginal(); $model->id = 2; $model->foo = 'bar'; $model->exists = true; $this->assertTrue($model->save()); } public function testTimestampsAreReturnedAsObjects() { $model = $this->getMockBuilder(EloquentDateModelStub::class)->onlyMethods(['getDateFormat'])->getMock(); $model->expects($this->any())->method('getDateFormat')->willReturn('Y-m-d'); $model->setRawAttributes([ 'created_at' => '2012-12-04', 'updated_at' => '2012-12-05', ]); $this->assertInstanceOf(Carbon::class, $model->created_at); $this->assertInstanceOf(Carbon::class, $model->updated_at); } public function testTimestampsAreReturnedAsObjectsFromPlainDatesAndTimestamps() { $model = $this->getMockBuilder(EloquentDateModelStub::class)->onlyMethods(['getDateFormat'])->getMock(); $model->expects($this->any())->method('getDateFormat')->willReturn('Y-m-d H:i:s'); $model->setRawAttributes([ 'created_at' => '2012-12-04', 'updated_at' => $this->currentTime(), ]); $this->assertInstanceOf(Carbon::class, $model->created_at); $this->assertInstanceOf(Carbon::class, $model->updated_at); } public function testTimestampsAreReturnedAsObjectsOnCreate() { $timestamps = [ 'created_at' => Carbon::now(), 'updated_at' => Carbon::now(), ]; $model = new EloquentDateModelStub; Model::setConnectionResolver($resolver = m::mock(ConnectionResolverInterface::class)); $resolver->shouldReceive('connection')->andReturn($mockConnection = m::mock(stdClass::class)); $mockConnection->shouldReceive('getQueryGrammar')->andReturn($mockConnection); $mockConnection->shouldReceive('getDateFormat')->andReturn('Y-m-d H:i:s'); $instance = $model->newInstance($timestamps); $this->assertInstanceOf(Carbon::class, $instance->updated_at); $this->assertInstanceOf(Carbon::class, $instance->created_at); } public function testDateTimeAttributesReturnNullIfSetToNull() { $timestamps = [ 'created_at' => Carbon::now(), 'updated_at' => Carbon::now(), ]; $model = new EloquentDateModelStub; Model::setConnectionResolver($resolver = m::mock(ConnectionResolverInterface::class)); $resolver->shouldReceive('connection')->andReturn($mockConnection = m::mock(stdClass::class)); $mockConnection->shouldReceive('getQueryGrammar')->andReturn($mockConnection); $mockConnection->shouldReceive('getDateFormat')->andReturn('Y-m-d H:i:s'); $instance = $model->newInstance($timestamps); $instance->created_at = null; $this->assertNull($instance->created_at); } public function testTimestampsAreCreatedFromStringsAndIntegers() { $model = new EloquentDateModelStub; $model->created_at = '2013-05-22 00:00:00'; $this->assertInstanceOf(Carbon::class, $model->created_at); $model = new EloquentDateModelStub; $model->created_at = $this->currentTime(); $this->assertInstanceOf(Carbon::class, $model->created_at); $model = new EloquentDateModelStub; $model->created_at = 0; $this->assertInstanceOf(Carbon::class, $model->created_at); $model = new EloquentDateModelStub; $model->created_at = '2012-01-01'; $this->assertInstanceOf(Carbon::class, $model->created_at); } public function testFromDateTime() { $model = new EloquentModelStub; $value = Carbon::parse('2015-04-17 22:59:01'); $this->assertSame('2015-04-17 22:59:01', $model->fromDateTime($value)); $value = new DateTime('2015-04-17 22:59:01'); $this->assertInstanceOf(DateTime::class, $value); $this->assertInstanceOf(DateTimeInterface::class, $value); $this->assertSame('2015-04-17 22:59:01', $model->fromDateTime($value)); $value = new DateTimeImmutable('2015-04-17 22:59:01'); $this->assertInstanceOf(DateTimeImmutable::class, $value); $this->assertInstanceOf(DateTimeInterface::class, $value); $this->assertSame('2015-04-17 22:59:01', $model->fromDateTime($value)); $value = '2015-04-17 22:59:01'; $this->assertSame('2015-04-17 22:59:01', $model->fromDateTime($value)); $value = '2015-04-17'; $this->assertSame('2015-04-17 00:00:00', $model->fromDateTime($value)); $value = '2015-4-17'; $this->assertSame('2015-04-17 00:00:00', $model->fromDateTime($value)); $value = '1429311541'; $this->assertSame('2015-04-17 22:59:01', $model->fromDateTime($value)); $this->assertNull($model->fromDateTime(null)); } public function testFromDateTimeMilliseconds() { $model = $this->getMockBuilder('Illuminate\Tests\Database\EloquentDateModelStub')->onlyMethods(['getDateFormat'])->getMock(); $model->expects($this->any())->method('getDateFormat')->willReturn('Y-m-d H:s.vi'); $model->setRawAttributes([ 'created_at' => '2012-12-04 22:59.32130', ]); $this->assertInstanceOf(Carbon::class, $model->created_at); $this->assertSame('22:30:59.321000', $model->created_at->format('H:i:s.u')); } public function testInsertProcess() { $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock(); $query = m::mock(Builder::class); $query->shouldReceive('insertGetId')->once()->with(['name' => 'taylor'], 'id')->andReturn(1); $query->shouldReceive('getConnection')->once(); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $model->expects($this->once())->method('updateTimestamps'); $model->setEventDispatcher($events = m::mock(Dispatcher::class)); $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true); $events->shouldReceive('until')->once()->with('eloquent.creating: '.get_class($model), $model)->andReturn(true); $events->shouldReceive('dispatch')->once()->with('eloquent.created: '.get_class($model), $model); $events->shouldReceive('dispatch')->once()->with('eloquent.saved: '.get_class($model), $model); $model->name = 'taylor'; $model->exists = false; $this->assertTrue($model->save()); $this->assertEquals(1, $model->id); $this->assertTrue($model->exists); $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock(); $query = m::mock(Builder::class); $query->shouldReceive('insert')->once()->with(['name' => 'taylor']); $query->shouldReceive('getConnection')->once(); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $model->expects($this->once())->method('updateTimestamps'); $model->setIncrementing(false); $model->setEventDispatcher($events = m::mock(Dispatcher::class)); $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true); $events->shouldReceive('until')->once()->with('eloquent.creating: '.get_class($model), $model)->andReturn(true); $events->shouldReceive('dispatch')->once()->with('eloquent.created: '.get_class($model), $model); $events->shouldReceive('dispatch')->once()->with('eloquent.saved: '.get_class($model), $model); $model->name = 'taylor'; $model->exists = false; $this->assertTrue($model->save()); $this->assertNull($model->id); $this->assertTrue($model->exists); } public function testInsertIsCanceledIfCreatingEventReturnsFalse() { $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery'])->getMock(); $query = m::mock(Builder::class); $query->shouldReceive('getConnection')->once(); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $model->setEventDispatcher($events = m::mock(Dispatcher::class)); $events->shouldReceive('until')->once()->with('eloquent.saving: '.get_class($model), $model)->andReturn(true); $events->shouldReceive('until')->once()->with('eloquent.creating: '.get_class($model), $model)->andReturn(false); $this->assertFalse($model->save()); $this->assertFalse($model->exists); } public function testDeleteProperlyDeletesModel() { $model = $this->getMockBuilder(Model::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'touchOwners'])->getMock(); $query = m::mock(Builder::class); $query->shouldReceive('where')->once()->with('id', '=', 1)->andReturn($query); $query->shouldReceive('delete')->once(); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $model->expects($this->once())->method('touchOwners'); $model->exists = true; $model->id = 1; $model->delete(); } public function testPushNoRelations() { $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock(); $query = m::mock(Builder::class); $query->shouldReceive('insertGetId')->once()->with(['name' => 'taylor'], 'id')->andReturn(1); $query->shouldReceive('getConnection')->once(); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $model->expects($this->once())->method('updateTimestamps'); $model->name = 'taylor'; $model->exists = false; $this->assertTrue($model->push()); $this->assertEquals(1, $model->id); $this->assertTrue($model->exists); } public function testPushEmptyOneRelation() { $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock(); $query = m::mock(Builder::class); $query->shouldReceive('insertGetId')->once()->with(['name' => 'taylor'], 'id')->andReturn(1); $query->shouldReceive('getConnection')->once(); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $model->expects($this->once())->method('updateTimestamps'); $model->name = 'taylor'; $model->exists = false; $model->setRelation('relationOne', null); $this->assertTrue($model->push()); $this->assertEquals(1, $model->id); $this->assertTrue($model->exists); $this->assertNull($model->relationOne); } public function testPushOneRelation() { $related1 = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock(); $query = m::mock(Builder::class); $query->shouldReceive('insertGetId')->once()->with(['name' => 'related1'], 'id')->andReturn(2); $query->shouldReceive('getConnection')->once(); $related1->expects($this->once())->method('newModelQuery')->willReturn($query); $related1->expects($this->once())->method('updateTimestamps'); $related1->name = 'related1'; $related1->exists = false; $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock(); $query = m::mock(Builder::class); $query->shouldReceive('insertGetId')->once()->with(['name' => 'taylor'], 'id')->andReturn(1); $query->shouldReceive('getConnection')->once(); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $model->expects($this->once())->method('updateTimestamps'); $model->name = 'taylor'; $model->exists = false; $model->setRelation('relationOne', $related1); $this->assertTrue($model->push()); $this->assertEquals(1, $model->id); $this->assertTrue($model->exists); $this->assertEquals(2, $model->relationOne->id); $this->assertTrue($model->relationOne->exists); $this->assertEquals(2, $related1->id); $this->assertTrue($related1->exists); } public function testPushEmptyManyRelation() { $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock(); $query = m::mock(Builder::class); $query->shouldReceive('insertGetId')->once()->with(['name' => 'taylor'], 'id')->andReturn(1); $query->shouldReceive('getConnection')->once(); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $model->expects($this->once())->method('updateTimestamps'); $model->name = 'taylor'; $model->exists = false; $model->setRelation('relationMany', new Collection([])); $this->assertTrue($model->push()); $this->assertEquals(1, $model->id); $this->assertTrue($model->exists); $this->assertCount(0, $model->relationMany); } public function testPushManyRelation() { $related1 = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock(); $query = m::mock(Builder::class); $query->shouldReceive('insertGetId')->once()->with(['name' => 'related1'], 'id')->andReturn(2); $query->shouldReceive('getConnection')->once(); $related1->expects($this->once())->method('newModelQuery')->willReturn($query); $related1->expects($this->once())->method('updateTimestamps'); $related1->name = 'related1'; $related1->exists = false; $related2 = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock(); $query = m::mock(Builder::class); $query->shouldReceive('insertGetId')->once()->with(['name' => 'related2'], 'id')->andReturn(3); $query->shouldReceive('getConnection')->once(); $related2->expects($this->once())->method('newModelQuery')->willReturn($query); $related2->expects($this->once())->method('updateTimestamps'); $related2->name = 'related2'; $related2->exists = false; $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock(); $query = m::mock(Builder::class); $query->shouldReceive('insertGetId')->once()->with(['name' => 'taylor'], 'id')->andReturn(1); $query->shouldReceive('getConnection')->once(); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $model->expects($this->once())->method('updateTimestamps'); $model->name = 'taylor'; $model->exists = false; $model->setRelation('relationMany', new Collection([$related1, $related2])); $this->assertTrue($model->push()); $this->assertEquals(1, $model->id); $this->assertTrue($model->exists); $this->assertCount(2, $model->relationMany); $this->assertEquals([2, 3], $model->relationMany->pluck('id')->all()); } public function testNewQueryReturnsEloquentQueryBuilder() { $conn = m::mock(Connection::class); $grammar = m::mock(Grammar::class); $processor = m::mock(Processor::class); EloquentModelStub::setConnectionResolver($resolver = m::mock(ConnectionResolverInterface::class)); $conn->shouldReceive('query')->andReturnUsing(function () use ($conn, $grammar, $processor) { return new BaseBuilder($conn, $grammar, $processor); }); $resolver->shouldReceive('connection')->andReturn($conn); $model = new EloquentModelStub; $builder = $model->newQuery(); $this->assertInstanceOf(Builder::class, $builder); } public function testGetAndSetTableOperations() { $model = new EloquentModelStub; $this->assertSame('stub', $model->getTable()); $model->setTable('foo'); $this->assertSame('foo', $model->getTable()); } public function testGetKeyReturnsValueOfPrimaryKey() { $model = new EloquentModelStub; $model->id = 1; $this->assertEquals(1, $model->getKey()); $this->assertSame('id', $model->getKeyName()); } public function testConnectionManagement() { EloquentModelStub::setConnectionResolver($resolver = m::mock(ConnectionResolverInterface::class)); $model = m::mock(EloquentModelStub::class.'[getConnectionName,connection]'); $retval = $model->setConnection('foo'); $this->assertEquals($retval, $model); $this->assertSame('foo', $model->connection); $model->shouldReceive('getConnectionName')->once()->andReturn('somethingElse'); $resolver->shouldReceive('connection')->once()->with('somethingElse')->andReturn('bar'); $this->assertSame('bar', $model->getConnection()); } public function testToArray() { $model = new EloquentModelStub; $model->name = 'foo'; $model->age = null; $model->password = 'password1'; $model->setHidden(['password']); $model->setRelation('names', new BaseCollection([ new EloquentModelStub(['bar' => 'baz']), new EloquentModelStub(['bam' => 'boom']), ])); $model->setRelation('partner', new EloquentModelStub(['name' => 'abby'])); $model->setRelation('group', null); $model->setRelation('multi', new BaseCollection); $array = $model->toArray(); $this->assertIsArray($array); $this->assertSame('foo', $array['name']); $this->assertSame('baz', $array['names'][0]['bar']); $this->assertSame('boom', $array['names'][1]['bam']); $this->assertSame('abby', $array['partner']['name']); $this->assertNull($array['group']); $this->assertEquals([], $array['multi']); $this->assertFalse(isset($array['password'])); $model->setAppends(['appendable']); $array = $model->toArray(); $this->assertSame('appended', $array['appendable']); } public function testVisibleCreatesArrayWhitelist() { $model = new EloquentModelStub; $model->setVisible(['name']); $model->name = 'Taylor'; $model->age = 26; $array = $model->toArray(); $this->assertEquals(['name' => 'Taylor'], $array); } public function testHiddenCanAlsoExcludeRelationships() { $model = new EloquentModelStub; $model->name = 'Taylor'; $model->setRelation('foo', ['bar']); $model->setHidden(['foo', 'list_items', 'password']); $array = $model->toArray(); $this->assertEquals(['name' => 'Taylor'], $array); } public function testGetArrayableRelationsFunctionExcludeHiddenRelationships() { $model = new EloquentModelStub; $class = new ReflectionClass($model); $method = $class->getMethod('getArrayableRelations'); $method->setAccessible(true); $model->setRelation('foo', ['bar']); $model->setRelation('bam', ['boom']); $model->setHidden(['foo']); $array = $method->invokeArgs($model, []); $this->assertSame(['bam' => ['boom']], $array); } public function testToArraySnakeAttributes() { $model = new EloquentModelStub; $model->setRelation('namesList', new BaseCollection([ new EloquentModelStub(['bar' => 'baz']), new EloquentModelStub(['bam' => 'boom']), ])); $array = $model->toArray(); $this->assertSame('baz', $array['names_list'][0]['bar']); $this->assertSame('boom', $array['names_list'][1]['bam']); $model = new EloquentModelCamelStub; $model->setRelation('namesList', new BaseCollection([ new EloquentModelStub(['bar' => 'baz']), new EloquentModelStub(['bam' => 'boom']), ])); $array = $model->toArray(); $this->assertSame('baz', $array['namesList'][0]['bar']); $this->assertSame('boom', $array['namesList'][1]['bam']); } public function testToArrayUsesMutators() { $model = new EloquentModelStub; $model->list_items = [1, 2, 3]; $array = $model->toArray(); $this->assertEquals([1, 2, 3], $array['list_items']); } public function testHidden() { $model = new EloquentModelStub(['name' => 'foo', 'age' => 'bar', 'id' => 'baz']); $model->setHidden(['age', 'id']); $array = $model->toArray(); $this->assertArrayHasKey('name', $array); $this->assertArrayNotHasKey('age', $array); } public function testVisible() { $model = new EloquentModelStub(['name' => 'foo', 'age' => 'bar', 'id' => 'baz']); $model->setVisible(['name', 'id']); $array = $model->toArray(); $this->assertArrayHasKey('name', $array); $this->assertArrayNotHasKey('age', $array); } public function testDynamicHidden() { $model = new EloquentModelDynamicHiddenStub(['name' => 'foo', 'age' => 'bar', 'id' => 'baz']); $array = $model->toArray(); $this->assertArrayHasKey('name', $array); $this->assertArrayNotHasKey('age', $array); } public function testWithHidden() { $model = new EloquentModelStub(['name' => 'foo', 'age' => 'bar', 'id' => 'baz']); $model->setHidden(['age', 'id']); $model->makeVisible('age'); $array = $model->toArray(); $this->assertArrayHasKey('name', $array); $this->assertArrayHasKey('age', $array); $this->assertArrayNotHasKey('id', $array); } public function testMakeHidden() { $model = new EloquentModelStub(['name' => 'foo', 'age' => 'bar', 'address' => 'foobar', 'id' => 'baz']); $array = $model->toArray(); $this->assertArrayHasKey('name', $array); $this->assertArrayHasKey('age', $array); $this->assertArrayHasKey('address', $array); $this->assertArrayHasKey('id', $array); $array = $model->makeHidden('address')->toArray(); $this->assertArrayNotHasKey('address', $array); $this->assertArrayHasKey('name', $array); $this->assertArrayHasKey('age', $array); $this->assertArrayHasKey('id', $array); $array = $model->makeHidden(['name', 'age'])->toArray(); $this->assertArrayNotHasKey('name', $array); $this->assertArrayNotHasKey('age', $array); $this->assertArrayNotHasKey('address', $array); $this->assertArrayHasKey('id', $array); } public function testDynamicVisible() { $model = new EloquentModelDynamicVisibleStub(['name' => 'foo', 'age' => 'bar', 'id' => 'baz']); $array = $model->toArray(); $this->assertArrayHasKey('name', $array); $this->assertArrayNotHasKey('age', $array); } public function testMakeVisibleIf() { $model = new EloquentModelStub(['name' => 'foo', 'age' => 'bar', 'id' => 'baz']); $model->setHidden(['age', 'id']); $model->makeVisibleIf(true, 'age'); $array = $model->toArray(); $this->assertArrayHasKey('name', $array); $this->assertArrayHasKey('age', $array); $this->assertArrayNotHasKey('id', $array); $model->setHidden(['age', 'id']); $model->makeVisibleIf(false, 'age'); $array = $model->toArray(); $this->assertArrayHasKey('name', $array); $this->assertArrayNotHasKey('age', $array); $this->assertArrayNotHasKey('id', $array); $model->setHidden(['age', 'id']); $model->makeVisibleIf(function ($model) { return ! is_null($model->name); }, 'age'); $array = $model->toArray(); $this->assertArrayHasKey('name', $array); $this->assertArrayHasKey('age', $array); $this->assertArrayNotHasKey('id', $array); } public function testMakeHiddenIf() { $model = new EloquentModelStub(['name' => 'foo', 'age' => 'bar', 'address' => 'foobar', 'id' => 'baz']); $array = $model->toArray(); $this->assertArrayHasKey('name', $array); $this->assertArrayHasKey('age', $array); $this->assertArrayHasKey('address', $array); $this->assertArrayHasKey('id', $array); $array = $model->makeHiddenIf(true, 'address')->toArray(); $this->assertArrayNotHasKey('address', $array); $this->assertArrayHasKey('name', $array); $this->assertArrayHasKey('age', $array); $this->assertArrayHasKey('id', $array); $model->makeVisible('address'); $array = $model->makeHiddenIf(false, ['name', 'age'])->toArray(); $this->assertArrayHasKey('name', $array); $this->assertArrayHasKey('age', $array); $this->assertArrayHasKey('address', $array); $this->assertArrayHasKey('id', $array); $array = $model->makeHiddenIf(function ($model) { return ! is_null($model->id); }, ['name', 'age'])->toArray(); $this->assertArrayHasKey('address', $array); $this->assertArrayNotHasKey('name', $array); $this->assertArrayNotHasKey('age', $array); $this->assertArrayHasKey('id', $array); } public function testFillable() { $model = new EloquentModelStub; $model->fillable(['name', 'age']); $model->fill(['name' => 'foo', 'age' => 'bar']); $this->assertSame('foo', $model->name); $this->assertSame('bar', $model->age); } public function testQualifyColumn() { $model = new EloquentModelStub; $this->assertSame('stub.column', $model->qualifyColumn('column')); } public function testForceFillMethodFillsGuardedAttributes() { $model = (new EloquentModelSaveStub)->forceFill(['id' => 21]); $this->assertEquals(21, $model->id); } public function testFillingJSONAttributes() { $model = new EloquentModelStub; $model->fillable(['meta->name', 'meta->price', 'meta->size->width']); $model->fill(['meta->name' => 'foo', 'meta->price' => 'bar', 'meta->size->width' => 'baz']); $this->assertEquals( ['meta' => json_encode(['name' => 'foo', 'price' => 'bar', 'size' => ['width' => 'baz']])], $model->toArray() ); $model = new EloquentModelStub(['meta' => json_encode(['name' => 'Taylor'])]); $model->fillable(['meta->name', 'meta->price', 'meta->size->width']); $model->fill(['meta->name' => 'foo', 'meta->price' => 'bar', 'meta->size->width' => 'baz']); $this->assertEquals( ['meta' => json_encode(['name' => 'foo', 'price' => 'bar', 'size' => ['width' => 'baz']])], $model->toArray() ); } public function testUnguardAllowsAnythingToBeSet() { $model = new EloquentModelStub; EloquentModelStub::unguard(); $model->guard(['*']); $model->fill(['name' => 'foo', 'age' => 'bar']); $this->assertSame('foo', $model->name); $this->assertSame('bar', $model->age); EloquentModelStub::unguard(false); } public function testUnderscorePropertiesAreNotFilled() { $model = new EloquentModelStub; $model->fill(['_method' => 'PUT']); $this->assertEquals([], $model->getAttributes()); } public function testGuarded() { $model = new EloquentModelStub; EloquentModelStub::setConnectionResolver($resolver = m::mock(Resolver::class)); $resolver->shouldReceive('connection')->andReturn($connection = m::mock(stdClass::class)); $connection->shouldReceive('getSchemaBuilder->getColumnListing')->andReturn(['name', 'age', 'foo']); $model->guard(['name', 'age']); $model->fill(['name' => 'foo', 'age' => 'bar', 'foo' => 'bar']); $this->assertFalse(isset($model->name)); $this->assertFalse(isset($model->age)); $this->assertSame('bar', $model->foo); $model = new EloquentModelStub; $model->guard(['name', 'age']); $model->fill(['Foo' => 'bar']); $this->assertFalse(isset($model->Foo)); } public function testFillableOverridesGuarded() { $model = new EloquentModelStub; $model->guard([]); $model->fillable(['age', 'foo']); $model->fill(['name' => 'foo', 'age' => 'bar', 'foo' => 'bar']); $this->assertFalse(isset($model->name)); $this->assertSame('bar', $model->age); $this->assertSame('bar', $model->foo); } public function testGlobalGuarded() { $this->expectException(MassAssignmentException::class); $this->expectExceptionMessage('name'); $model = new EloquentModelStub; $model->guard(['*']); $model->fill(['name' => 'foo', 'age' => 'bar', 'votes' => 'baz']); } public function testUnguardedRunsCallbackWhileBeingUnguarded() { $model = Model::unguarded(function () { return (new EloquentModelStub)->guard(['*'])->fill(['name' => 'Taylor']); }); $this->assertSame('Taylor', $model->name); $this->assertFalse(Model::isUnguarded()); } public function testUnguardedCallDoesNotChangeUnguardedState() { Model::unguard(); $model = Model::unguarded(function () { return (new EloquentModelStub)->guard(['*'])->fill(['name' => 'Taylor']); }); $this->assertSame('Taylor', $model->name); $this->assertTrue(Model::isUnguarded()); Model::reguard(); } public function testUnguardedCallDoesNotChangeUnguardedStateOnException() { try { Model::unguarded(function () { throw new Exception; }); } catch (Exception $e) { // ignore the exception } $this->assertFalse(Model::isUnguarded()); } public function testHasOneCreatesProperRelation() { $model = new EloquentModelStub; $this->addMockConnection($model); $relation = $model->hasOne(EloquentModelSaveStub::class); $this->assertSame('save_stub.eloquent_model_stub_id', $relation->getQualifiedForeignKeyName()); $model = new EloquentModelStub; $this->addMockConnection($model); $relation = $model->hasOne(EloquentModelSaveStub::class, 'foo'); $this->assertSame('save_stub.foo', $relation->getQualifiedForeignKeyName()); $this->assertSame($model, $relation->getParent()); $this->assertInstanceOf(EloquentModelSaveStub::class, $relation->getQuery()->getModel()); } public function testMorphOneCreatesProperRelation() { $model = new EloquentModelStub; $this->addMockConnection($model); $relation = $model->morphOne(EloquentModelSaveStub::class, 'morph'); $this->assertSame('save_stub.morph_id', $relation->getQualifiedForeignKeyName()); $this->assertSame('save_stub.morph_type', $relation->getQualifiedMorphType()); $this->assertEquals(EloquentModelStub::class, $relation->getMorphClass()); } public function testCorrectMorphClassIsReturned() { Relation::morphMap(['alias' => 'AnotherModel']); $model = new EloquentModelStub; try { $this->assertEquals(EloquentModelStub::class, $model->getMorphClass()); } finally { Relation::morphMap([], false); } } public function testHasManyCreatesProperRelation() { $model = new EloquentModelStub; $this->addMockConnection($model); $relation = $model->hasMany(EloquentModelSaveStub::class); $this->assertSame('save_stub.eloquent_model_stub_id', $relation->getQualifiedForeignKeyName()); $model = new EloquentModelStub; $this->addMockConnection($model); $relation = $model->hasMany(EloquentModelSaveStub::class, 'foo'); $this->assertSame('save_stub.foo', $relation->getQualifiedForeignKeyName()); $this->assertSame($model, $relation->getParent()); $this->assertInstanceOf(EloquentModelSaveStub::class, $relation->getQuery()->getModel()); } public function testMorphManyCreatesProperRelation() { $model = new EloquentModelStub; $this->addMockConnection($model); $relation = $model->morphMany(EloquentModelSaveStub::class, 'morph'); $this->assertSame('save_stub.morph_id', $relation->getQualifiedForeignKeyName()); $this->assertSame('save_stub.morph_type', $relation->getQualifiedMorphType()); $this->assertEquals(EloquentModelStub::class, $relation->getMorphClass()); } public function testBelongsToCreatesProperRelation() { $model = new EloquentModelStub; $this->addMockConnection($model); $relation = $model->belongsToStub(); $this->assertSame('belongs_to_stub_id', $relation->getForeignKeyName()); $this->assertSame($model, $relation->getParent()); $this->assertInstanceOf(EloquentModelSaveStub::class, $relation->getQuery()->getModel()); $model = new EloquentModelStub; $this->addMockConnection($model); $relation = $model->belongsToExplicitKeyStub(); $this->assertSame('foo', $relation->getForeignKeyName()); } public function testMorphToCreatesProperRelation() { $model = new EloquentModelStub; $this->addMockConnection($model); // $this->morphTo(); $model->setAttribute('morph_to_stub_type', EloquentModelSaveStub::class); $relation = $model->morphToStub(); $this->assertSame('morph_to_stub_id', $relation->getForeignKeyName()); $this->assertSame('morph_to_stub_type', $relation->getMorphType()); $this->assertSame('morphToStub', $relation->getRelationName()); $this->assertSame($model, $relation->getParent()); $this->assertInstanceOf(EloquentModelSaveStub::class, $relation->getQuery()->getModel()); // $this->morphTo(null, 'type', 'id'); $relation2 = $model->morphToStubWithKeys(); $this->assertSame('id', $relation2->getForeignKeyName()); $this->assertSame('type', $relation2->getMorphType()); $this->assertSame('morphToStubWithKeys', $relation2->getRelationName()); // $this->morphTo('someName'); $relation3 = $model->morphToStubWithName(); $this->assertSame('some_name_id', $relation3->getForeignKeyName()); $this->assertSame('some_name_type', $relation3->getMorphType()); $this->assertSame('someName', $relation3->getRelationName()); // $this->morphTo('someName', 'type', 'id'); $relation4 = $model->morphToStubWithNameAndKeys(); $this->assertSame('id', $relation4->getForeignKeyName()); $this->assertSame('type', $relation4->getMorphType()); $this->assertSame('someName', $relation4->getRelationName()); } public function testBelongsToManyCreatesProperRelation() { $model = new EloquentModelStub; $this->addMockConnection($model); $relation = $model->belongsToMany(EloquentModelSaveStub::class); $this->assertSame('eloquent_model_save_stub_eloquent_model_stub.eloquent_model_stub_id', $relation->getQualifiedForeignPivotKeyName()); $this->assertSame('eloquent_model_save_stub_eloquent_model_stub.eloquent_model_save_stub_id', $relation->getQualifiedRelatedPivotKeyName()); $this->assertSame($model, $relation->getParent()); $this->assertInstanceOf(EloquentModelSaveStub::class, $relation->getQuery()->getModel()); $this->assertEquals(__FUNCTION__, $relation->getRelationName()); $model = new EloquentModelStub; $this->addMockConnection($model); $relation = $model->belongsToMany(EloquentModelSaveStub::class, 'table', 'foreign', 'other'); $this->assertSame('table.foreign', $relation->getQualifiedForeignPivotKeyName()); $this->assertSame('table.other', $relation->getQualifiedRelatedPivotKeyName()); $this->assertSame($model, $relation->getParent()); $this->assertInstanceOf(EloquentModelSaveStub::class, $relation->getQuery()->getModel()); } public function testRelationsWithVariedConnections() { // Has one $model = new EloquentModelStub; $model->setConnection('non_default'); $this->addMockConnection($model); $relation = $model->hasOne(EloquentNoConnectionModelStub::class); $this->assertSame('non_default', $relation->getRelated()->getConnectionName()); $model = new EloquentModelStub; $model->setConnection('non_default'); $this->addMockConnection($model); $relation = $model->hasOne(EloquentDifferentConnectionModelStub::class); $this->assertSame('different_connection', $relation->getRelated()->getConnectionName()); // Morph One $model = new EloquentModelStub; $model->setConnection('non_default'); $this->addMockConnection($model); $relation = $model->morphOne(EloquentNoConnectionModelStub::class, 'type'); $this->assertSame('non_default', $relation->getRelated()->getConnectionName()); $model = new EloquentModelStub; $model->setConnection('non_default'); $this->addMockConnection($model); $relation = $model->morphOne(EloquentDifferentConnectionModelStub::class, 'type'); $this->assertSame('different_connection', $relation->getRelated()->getConnectionName()); // Belongs to $model = new EloquentModelStub; $model->setConnection('non_default'); $this->addMockConnection($model); $relation = $model->belongsTo(EloquentNoConnectionModelStub::class); $this->assertSame('non_default', $relation->getRelated()->getConnectionName()); $model = new EloquentModelStub; $model->setConnection('non_default'); $this->addMockConnection($model); $relation = $model->belongsTo(EloquentDifferentConnectionModelStub::class); $this->assertSame('different_connection', $relation->getRelated()->getConnectionName()); // has many $model = new EloquentModelStub; $model->setConnection('non_default'); $this->addMockConnection($model); $relation = $model->hasMany(EloquentNoConnectionModelStub::class); $this->assertSame('non_default', $relation->getRelated()->getConnectionName()); $model = new EloquentModelStub; $model->setConnection('non_default'); $this->addMockConnection($model); $relation = $model->hasMany(EloquentDifferentConnectionModelStub::class); $this->assertSame('different_connection', $relation->getRelated()->getConnectionName()); // has many through $model = new EloquentModelStub; $model->setConnection('non_default'); $this->addMockConnection($model); $relation = $model->hasManyThrough(EloquentNoConnectionModelStub::class, EloquentModelSaveStub::class); $this->assertSame('non_default', $relation->getRelated()->getConnectionName()); $model = new EloquentModelStub; $model->setConnection('non_default'); $this->addMockConnection($model); $relation = $model->hasManyThrough(EloquentDifferentConnectionModelStub::class, EloquentModelSaveStub::class); $this->assertSame('different_connection', $relation->getRelated()->getConnectionName()); // belongs to many $model = new EloquentModelStub; $model->setConnection('non_default'); $this->addMockConnection($model); $relation = $model->belongsToMany(EloquentNoConnectionModelStub::class); $this->assertSame('non_default', $relation->getRelated()->getConnectionName()); $model = new EloquentModelStub; $model->setConnection('non_default'); $this->addMockConnection($model); $relation = $model->belongsToMany(EloquentDifferentConnectionModelStub::class); $this->assertSame('different_connection', $relation->getRelated()->getConnectionName()); } public function testModelsAssumeTheirName() { require_once __DIR__.'/stubs/EloquentModelNamespacedStub.php'; $model = new EloquentModelWithoutTableStub; $this->assertSame('eloquent_model_without_table_stubs', $model->getTable()); $namespacedModel = new EloquentModelNamespacedStub; $this->assertSame('eloquent_model_namespaced_stubs', $namespacedModel->getTable()); } public function testTheMutatorCacheIsPopulated() { $class = new EloquentModelStub; $expectedAttributes = [ 'list_items', 'password', 'appendable', ]; $this->assertEquals($expectedAttributes, $class->getMutatedAttributes()); } public function testRouteKeyIsPrimaryKey() { $model = new EloquentModelNonIncrementingStub; $model->id = 'foo'; $this->assertSame('foo', $model->getRouteKey()); } public function testRouteNameIsPrimaryKeyName() { $model = new EloquentModelStub; $this->assertSame('id', $model->getRouteKeyName()); } public function testCloneModelMakesAFreshCopyOfTheModel() { $class = new EloquentModelStub; $class->id = 1; $class->exists = true; $class->first = 'taylor'; $class->last = 'otwell'; $class->created_at = $class->freshTimestamp(); $class->updated_at = $class->freshTimestamp(); $class->setRelation('foo', ['bar']); $clone = $class->replicate(); $this->assertNull($clone->id); $this->assertFalse($clone->exists); $this->assertSame('taylor', $clone->first); $this->assertSame('otwell', $clone->last); $this->assertArrayNotHasKey('created_at', $clone->getAttributes()); $this->assertArrayNotHasKey('updated_at', $clone->getAttributes()); $this->assertEquals(['bar'], $clone->foo); } public function testModelObserversCanBeAttachedToModels() { EloquentModelStub::setEventDispatcher($events = m::mock(Dispatcher::class)); $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\Tests\Database\EloquentModelStub', EloquentTestObserverStub::class.'@creating'); $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\Tests\Database\EloquentModelStub', EloquentTestObserverStub::class.'@saved'); $events->shouldReceive('forget'); EloquentModelStub::observe(new EloquentTestObserverStub); EloquentModelStub::flushEventListeners(); } public function testModelObserversCanBeAttachedToModelsWithString() { EloquentModelStub::setEventDispatcher($events = m::mock(Dispatcher::class)); $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\Tests\Database\EloquentModelStub', EloquentTestObserverStub::class.'@creating'); $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\Tests\Database\EloquentModelStub', EloquentTestObserverStub::class.'@saved'); $events->shouldReceive('forget'); EloquentModelStub::observe(EloquentTestObserverStub::class); EloquentModelStub::flushEventListeners(); } public function testModelObserversCanBeAttachedToModelsThroughAnArray() { EloquentModelStub::setEventDispatcher($events = m::mock(Dispatcher::class)); $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\Tests\Database\EloquentModelStub', EloquentTestObserverStub::class.'@creating'); $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\Tests\Database\EloquentModelStub', EloquentTestObserverStub::class.'@saved'); $events->shouldReceive('forget'); EloquentModelStub::observe([EloquentTestObserverStub::class]); EloquentModelStub::flushEventListeners(); } public function testThrowExceptionOnAttachingNotExistsModelObserverWithString() { $this->expectException(InvalidArgumentException::class); EloquentModelStub::observe(NotExistClass::class); } public function testThrowExceptionOnAttachingNotExistsModelObserversThroughAnArray() { $this->expectException(InvalidArgumentException::class); EloquentModelStub::observe([NotExistClass::class]); } public function testModelObserversCanBeAttachedToModelsThroughCallingObserveMethodOnlyOnce() { EloquentModelStub::setEventDispatcher($events = m::mock(Dispatcher::class)); $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\Tests\Database\EloquentModelStub', EloquentTestObserverStub::class.'@creating'); $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\Tests\Database\EloquentModelStub', EloquentTestObserverStub::class.'@saved'); $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\Tests\Database\EloquentModelStub', EloquentTestAnotherObserverStub::class.'@creating'); $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\Tests\Database\EloquentModelStub', EloquentTestAnotherObserverStub::class.'@saved'); $events->shouldReceive('forget'); EloquentModelStub::observe([ EloquentTestObserverStub::class, EloquentTestAnotherObserverStub::class, ]); EloquentModelStub::flushEventListeners(); } public function testWithoutEventDispatcher() { EloquentModelSaveStub::setEventDispatcher($events = m::mock(Dispatcher::class)); $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\Tests\Database\EloquentModelSaveStub', EloquentTestObserverStub::class.'@creating'); $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\Tests\Database\EloquentModelSaveStub', EloquentTestObserverStub::class.'@saved'); $events->shouldNotReceive('until'); $events->shouldNotReceive('dispatch'); $events->shouldReceive('forget'); EloquentModelSaveStub::observe(EloquentTestObserverStub::class); $model = EloquentModelSaveStub::withoutEvents(function () { $model = new EloquentModelSaveStub; $model->save(); return $model; }); $model->withoutEvents(function () use ($model) { $model->first_name = 'Taylor'; $model->save(); }); $events->shouldReceive('until')->once()->with('eloquent.saving: Illuminate\Tests\Database\EloquentModelSaveStub', $model); $events->shouldReceive('dispatch')->once()->with('eloquent.saved: Illuminate\Tests\Database\EloquentModelSaveStub', $model); $model->last_name = 'Otwell'; $model->save(); EloquentModelSaveStub::flushEventListeners(); } public function testSetObservableEvents() { $class = new EloquentModelStub; $class->setObservableEvents(['foo']); $this->assertContains('foo', $class->getObservableEvents()); } public function testAddObservableEvent() { $class = new EloquentModelStub; $class->addObservableEvents('foo'); $this->assertContains('foo', $class->getObservableEvents()); } public function testAddMultipleObserveableEvents() { $class = new EloquentModelStub; $class->addObservableEvents('foo', 'bar'); $this->assertContains('foo', $class->getObservableEvents()); $this->assertContains('bar', $class->getObservableEvents()); } public function testRemoveObservableEvent() { $class = new EloquentModelStub; $class->setObservableEvents(['foo', 'bar']); $class->removeObservableEvents('bar'); $this->assertNotContains('bar', $class->getObservableEvents()); } public function testRemoveMultipleObservableEvents() { $class = new EloquentModelStub; $class->setObservableEvents(['foo', 'bar']); $class->removeObservableEvents('foo', 'bar'); $this->assertNotContains('foo', $class->getObservableEvents()); $this->assertNotContains('bar', $class->getObservableEvents()); } public function testGetModelAttributeMethodThrowsExceptionIfNotRelation() { $this->expectException(LogicException::class); $this->expectExceptionMessage('Illuminate\Tests\Database\EloquentModelStub::incorrectRelationStub must return a relationship instance.'); $model = new EloquentModelStub; $model->incorrectRelationStub; } public function testModelIsBootedOnUnserialize() { $model = new EloquentModelBootingTestStub; $this->assertTrue(EloquentModelBootingTestStub::isBooted()); $model->foo = 'bar'; $string = serialize($model); $model = null; EloquentModelBootingTestStub::unboot(); $this->assertFalse(EloquentModelBootingTestStub::isBooted()); unserialize($string); $this->assertTrue(EloquentModelBootingTestStub::isBooted()); } public function testModelsTraitIsInitialized() { $model = new EloquentModelStubWithTrait; $this->assertTrue($model->fooBarIsInitialized); } public function testAppendingOfAttributes() { $model = new EloquentModelAppendsStub; $this->assertTrue(isset($model->is_admin)); $this->assertTrue(isset($model->camelCased)); $this->assertTrue(isset($model->StudlyCased)); $this->assertSame('admin', $model->is_admin); $this->assertSame('camelCased', $model->camelCased); $this->assertSame('StudlyCased', $model->StudlyCased); $this->assertTrue($model->hasAppended('is_admin')); $this->assertTrue($model->hasAppended('camelCased')); $this->assertTrue($model->hasAppended('StudlyCased')); $this->assertFalse($model->hasAppended('not_appended')); $model->setHidden(['is_admin', 'camelCased', 'StudlyCased']); $this->assertEquals([], $model->toArray()); $model->setVisible([]); $this->assertEquals([], $model->toArray()); } public function testGetMutatedAttributes() { $model = new EloquentModelGetMutatorsStub; $this->assertEquals(['first_name', 'middle_name', 'last_name'], $model->getMutatedAttributes()); EloquentModelGetMutatorsStub::resetMutatorCache(); EloquentModelGetMutatorsStub::$snakeAttributes = false; $this->assertEquals(['firstName', 'middleName', 'lastName'], $model->getMutatedAttributes()); } public function testReplicateCreatesANewModelInstanceWithSameAttributeValues() { $model = new EloquentModelStub; $model->id = 'id'; $model->foo = 'bar'; $model->created_at = new DateTime; $model->updated_at = new DateTime; $replicated = $model->replicate(); $this->assertNull($replicated->id); $this->assertSame('bar', $replicated->foo); $this->assertNull($replicated->created_at); $this->assertNull($replicated->updated_at); } public function testReplicatingEventIsFiredWhenReplicatingModel() { $model = new EloquentModelStub; $model->setEventDispatcher($events = m::mock(Dispatcher::class)); $events->shouldReceive('dispatch')->once()->with('eloquent.replicating: '.get_class($model), m::on(function ($m) use ($model) { return $model->is($m); })); $model->replicate(); } public function testIncrementOnExistingModelCallsQueryAndSetsAttribute() { $model = m::mock(EloquentModelStub::class.'[newQueryWithoutRelationships]'); $model->exists = true; $model->id = 1; $model->syncOriginalAttribute('id'); $model->foo = 2; $model->shouldReceive('newQueryWithoutRelationships')->andReturn($query = m::mock(stdClass::class)); $query->shouldReceive('where')->andReturn($query); $query->shouldReceive('increment'); $model->publicIncrement('foo', 1); $this->assertFalse($model->isDirty()); $model->publicIncrement('foo', 1, ['category' => 1]); $this->assertEquals(4, $model->foo); $this->assertEquals(1, $model->category); $this->assertTrue($model->isDirty('category')); } public function testRelationshipTouchOwnersIsPropagated() { $relation = $this->getMockBuilder(BelongsTo::class)->onlyMethods(['touch'])->disableOriginalConstructor()->getMock(); $relation->expects($this->once())->method('touch'); $model = m::mock(EloquentModelStub::class.'[partner]'); $this->addMockConnection($model); $model->shouldReceive('partner')->once()->andReturn($relation); $model->setTouchedRelations(['partner']); $mockPartnerModel = m::mock(EloquentModelStub::class.'[touchOwners]'); $mockPartnerModel->shouldReceive('touchOwners')->once(); $model->setRelation('partner', $mockPartnerModel); $model->touchOwners(); } public function testRelationshipTouchOwnersIsNotPropagatedIfNoRelationshipResult() { $relation = $this->getMockBuilder(BelongsTo::class)->onlyMethods(['touch'])->disableOriginalConstructor()->getMock(); $relation->expects($this->once())->method('touch'); $model = m::mock(EloquentModelStub::class.'[partner]'); $this->addMockConnection($model); $model->shouldReceive('partner')->once()->andReturn($relation); $model->setTouchedRelations(['partner']); $model->setRelation('partner', null); $model->touchOwners(); } public function testModelAttributesAreCastedWhenPresentInCastsArray() { $model = new EloquentModelCastingStub; $model->setDateFormat('Y-m-d H:i:s'); $model->intAttribute = '3'; $model->floatAttribute = '4.0'; $model->stringAttribute = 2.5; $model->boolAttribute = 1; $model->booleanAttribute = 0; $model->objectAttribute = ['foo' => 'bar']; $obj = new stdClass; $obj->foo = 'bar'; $model->arrayAttribute = $obj; $model->jsonAttribute = ['foo' => 'bar']; $model->dateAttribute = '1969-07-20'; $model->datetimeAttribute = '1969-07-20 22:56:00'; $model->timestampAttribute = '1969-07-20 22:56:00'; $model->collectionAttribute = new BaseCollection; $this->assertIsInt($model->intAttribute); $this->assertIsFloat($model->floatAttribute); $this->assertIsString($model->stringAttribute); $this->assertIsBool($model->boolAttribute); $this->assertIsBool($model->booleanAttribute); $this->assertIsObject($model->objectAttribute); $this->assertIsArray($model->arrayAttribute); $this->assertIsArray($model->jsonAttribute); $this->assertTrue($model->boolAttribute); $this->assertFalse($model->booleanAttribute); $this->assertEquals($obj, $model->objectAttribute); $this->assertEquals(['foo' => 'bar'], $model->arrayAttribute); $this->assertEquals(['foo' => 'bar'], $model->jsonAttribute); $this->assertSame('{"foo":"bar"}', $model->jsonAttributeValue()); $this->assertInstanceOf(Carbon::class, $model->dateAttribute); $this->assertInstanceOf(Carbon::class, $model->datetimeAttribute); $this->assertInstanceOf(BaseCollection::class, $model->collectionAttribute); $this->assertSame('1969-07-20', $model->dateAttribute->toDateString()); $this->assertSame('1969-07-20 22:56:00', $model->datetimeAttribute->toDateTimeString()); $this->assertEquals(-14173440, $model->timestampAttribute); $arr = $model->toArray(); $this->assertIsInt($arr['intAttribute']); $this->assertIsFloat($arr['floatAttribute']); $this->assertIsString($arr['stringAttribute']); $this->assertIsBool($arr['boolAttribute']); $this->assertIsBool($arr['booleanAttribute']); $this->assertIsObject($arr['objectAttribute']); $this->assertIsArray($arr['arrayAttribute']); $this->assertIsArray($arr['jsonAttribute']); $this->assertIsArray($arr['collectionAttribute']); $this->assertTrue($arr['boolAttribute']); $this->assertFalse($arr['booleanAttribute']); $this->assertEquals($obj, $arr['objectAttribute']); $this->assertEquals(['foo' => 'bar'], $arr['arrayAttribute']); $this->assertEquals(['foo' => 'bar'], $arr['jsonAttribute']); $this->assertSame('1969-07-20 00:00:00', $arr['dateAttribute']); $this->assertSame('1969-07-20 22:56:00', $arr['datetimeAttribute']); $this->assertEquals(-14173440, $arr['timestampAttribute']); } public function testModelDateAttributeCastingResetsTime() { $model = new EloquentModelCastingStub; $model->setDateFormat('Y-m-d H:i:s'); $model->dateAttribute = '1969-07-20 22:56:00'; $this->assertSame('1969-07-20 00:00:00', $model->dateAttribute->toDateTimeString()); $arr = $model->toArray(); $this->assertSame('1969-07-20 00:00:00', $arr['dateAttribute']); } public function testModelAttributeCastingPreservesNull() { $model = new EloquentModelCastingStub; $model->intAttribute = null; $model->floatAttribute = null; $model->stringAttribute = null; $model->boolAttribute = null; $model->booleanAttribute = null; $model->objectAttribute = null; $model->arrayAttribute = null; $model->jsonAttribute = null; $model->dateAttribute = null; $model->datetimeAttribute = null; $model->timestampAttribute = null; $model->collectionAttribute = null; $attributes = $model->getAttributes(); $this->assertNull($attributes['intAttribute']); $this->assertNull($attributes['floatAttribute']); $this->assertNull($attributes['stringAttribute']); $this->assertNull($attributes['boolAttribute']); $this->assertNull($attributes['booleanAttribute']); $this->assertNull($attributes['objectAttribute']); $this->assertNull($attributes['arrayAttribute']); $this->assertNull($attributes['jsonAttribute']); $this->assertNull($attributes['dateAttribute']); $this->assertNull($attributes['datetimeAttribute']); $this->assertNull($attributes['timestampAttribute']); $this->assertNull($attributes['collectionAttribute']); $this->assertNull($model->intAttribute); $this->assertNull($model->floatAttribute); $this->assertNull($model->stringAttribute); $this->assertNull($model->boolAttribute); $this->assertNull($model->booleanAttribute); $this->assertNull($model->objectAttribute); $this->assertNull($model->arrayAttribute); $this->assertNull($model->jsonAttribute); $this->assertNull($model->dateAttribute); $this->assertNull($model->datetimeAttribute); $this->assertNull($model->timestampAttribute); $this->assertNull($model->collectionAttribute); $array = $model->toArray(); $this->assertNull($array['intAttribute']); $this->assertNull($array['floatAttribute']); $this->assertNull($array['stringAttribute']); $this->assertNull($array['boolAttribute']); $this->assertNull($array['booleanAttribute']); $this->assertNull($array['objectAttribute']); $this->assertNull($array['arrayAttribute']); $this->assertNull($array['jsonAttribute']); $this->assertNull($array['dateAttribute']); $this->assertNull($array['datetimeAttribute']); $this->assertNull($array['timestampAttribute']); $this->assertNull($attributes['collectionAttribute']); } public function testModelAttributeCastingFailsOnUnencodableData() { $this->expectException(JsonEncodingException::class); $this->expectExceptionMessage('Unable to encode attribute [objectAttribute] for model [Illuminate\Tests\Database\EloquentModelCastingStub] to JSON: Malformed UTF-8 characters, possibly incorrectly encoded.'); $model = new EloquentModelCastingStub; $model->objectAttribute = ['foo' => "b\xF8r"]; $obj = new stdClass; $obj->foo = "b\xF8r"; $model->arrayAttribute = $obj; $model->jsonAttribute = ['foo' => "b\xF8r"]; $model->getAttributes(); } public function testModelAttributeCastingWithSpecialFloatValues() { $model = new EloquentModelCastingStub; $model->floatAttribute = 0; $this->assertSame(0.0, $model->floatAttribute); $model->floatAttribute = 'Infinity'; $this->assertSame(INF, $model->floatAttribute); $model->floatAttribute = INF; $this->assertSame(INF, $model->floatAttribute); $model->floatAttribute = '-Infinity'; $this->assertSame(-INF, $model->floatAttribute); $model->floatAttribute = -INF; $this->assertSame(-INF, $model->floatAttribute); $model->floatAttribute = 'NaN'; $this->assertNan($model->floatAttribute); $model->floatAttribute = NAN; $this->assertNan($model->floatAttribute); } public function testMergeCastsMergesCasts() { $model = new EloquentModelCastingStub; $castCount = count($model->getCasts()); $this->assertArrayNotHasKey('foo', $model->getCasts()); $model->mergeCasts(['foo' => 'date']); $this->assertCount($castCount + 1, $model->getCasts()); $this->assertArrayHasKey('foo', $model->getCasts()); } public function testUpdatingNonExistentModelFails() { $model = new EloquentModelStub; $this->assertFalse($model->update()); } public function testIssetBehavesCorrectlyWithAttributesAndRelationships() { $model = new EloquentModelStub; $this->assertFalse(isset($model->nonexistent)); $model->some_attribute = 'some_value'; $this->assertTrue(isset($model->some_attribute)); $model->setRelation('some_relation', 'some_value'); $this->assertTrue(isset($model->some_relation)); } public function testNonExistingAttributeWithInternalMethodNameDoesntCallMethod() { $model = m::mock(EloquentModelStub::class.'[delete,getRelationValue]'); $model->name = 'Spark'; $model->shouldNotReceive('delete'); $model->shouldReceive('getRelationValue')->once()->with('belongsToStub')->andReturn('relation'); // Can return a normal relation $this->assertSame('relation', $model->belongsToStub); // Can return a normal attribute $this->assertSame('Spark', $model->name); // Returns null for a Model.php method name $this->assertNull($model->delete); $model = m::mock(EloquentModelStub::class.'[delete]'); $model->delete = 123; $this->assertEquals(123, $model->delete); } public function testIntKeyTypePreserved() { $model = $this->getMockBuilder(EloquentModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock(); $query = m::mock(Builder::class); $query->shouldReceive('insertGetId')->once()->with([], 'id')->andReturn(1); $query->shouldReceive('getConnection')->once(); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $this->assertTrue($model->save()); $this->assertEquals(1, $model->id); } public function testStringKeyTypePreserved() { $model = $this->getMockBuilder(EloquentKeyTypeModelStub::class)->onlyMethods(['newModelQuery', 'updateTimestamps', 'refresh'])->getMock(); $query = m::mock(Builder::class); $query->shouldReceive('insertGetId')->once()->with([], 'id')->andReturn('string id'); $query->shouldReceive('getConnection')->once(); $model->expects($this->once())->method('newModelQuery')->willReturn($query); $this->assertTrue($model->save()); $this->assertSame('string id', $model->id); } public function testScopesMethod() { $model = new EloquentModelStub; $this->addMockConnection($model); Carbon::setTestNow(); $scopes = [ 'published', 'category' => 'Laravel', 'framework' => ['Laravel', '5.3'], 'date' => Carbon::now(), ]; $this->assertInstanceOf(Builder::class, $model->scopes($scopes)); $this->assertSame($scopes, $model->scopesCalled); } public function testScopesMethodWithString() { $model = new EloquentModelStub; $this->addMockConnection($model); $this->assertInstanceOf(Builder::class, $model->scopes('published')); $this->assertSame(['published'], $model->scopesCalled); } public function testIsWithNull() { $firstInstance = new EloquentModelStub(['id' => 1]); $secondInstance = null; $this->assertFalse($firstInstance->is($secondInstance)); } public function testIsWithTheSameModelInstance() { $firstInstance = new EloquentModelStub(['id' => 1]); $secondInstance = new EloquentModelStub(['id' => 1]); $result = $firstInstance->is($secondInstance); $this->assertTrue($result); } public function testIsWithAnotherModelInstance() { $firstInstance = new EloquentModelStub(['id' => 1]); $secondInstance = new EloquentModelStub(['id' => 2]); $result = $firstInstance->is($secondInstance); $this->assertFalse($result); } public function testIsWithAnotherTable() { $firstInstance = new EloquentModelStub(['id' => 1]); $secondInstance = new EloquentModelStub(['id' => 1]); $secondInstance->setTable('foo'); $result = $firstInstance->is($secondInstance); $this->assertFalse($result); } public function testIsWithAnotherConnection() { $firstInstance = new EloquentModelStub(['id' => 1]); $secondInstance = new EloquentModelStub(['id' => 1]); $secondInstance->setConnection('foo'); $result = $firstInstance->is($secondInstance); $this->assertFalse($result); } public function testWithoutTouchingCallback() { new EloquentModelStub(['id' => 1]); $called = false; EloquentModelStub::withoutTouching(function () use (&$called) { $called = true; }); $this->assertTrue($called); } public function testWithoutTouchingOnCallback() { new EloquentModelStub(['id' => 1]); $called = false; Model::withoutTouchingOn([EloquentModelStub::class], function () use (&$called) { $called = true; }); $this->assertTrue($called); } protected function addMockConnection($model) { $model->setConnectionResolver($resolver = m::mock(ConnectionResolverInterface::class)); $resolver->shouldReceive('connection')->andReturn($connection = m::mock(Connection::class)); $connection->shouldReceive('getQueryGrammar')->andReturn($grammar = m::mock(Grammar::class)); $grammar->shouldReceive('getBitwiseOperators')->andReturn([]); $connection->shouldReceive('getPostProcessor')->andReturn($processor = m::mock(Processor::class)); $connection->shouldReceive('query')->andReturnUsing(function () use ($connection, $grammar, $processor) { return new BaseBuilder($connection, $grammar, $processor); }); } public function testTouchingModelWithTimestamps() { $this->assertFalse( Model::isIgnoringTouch(Model::class) ); } public function testNotTouchingModelWithUpdatedAtNull() { $this->assertTrue( Model::isIgnoringTouch(EloquentModelWithUpdatedAtNull::class) ); } public function testNotTouchingModelWithoutTimestamps() { $this->assertTrue( Model::isIgnoringTouch(EloquentModelWithoutTimestamps::class) ); } public function testGetOriginalCastsAttributes() { $model = new EloquentModelCastingStub; $model->intAttribute = '1'; $model->floatAttribute = '0.1234'; $model->stringAttribute = 432; $model->boolAttribute = '1'; $model->booleanAttribute = '0'; $stdClass = new stdClass; $stdClass->json_key = 'json_value'; $model->objectAttribute = $stdClass; $array = [ 'foo' => 'bar', ]; $collection = collect($array); $model->arrayAttribute = $array; $model->jsonAttribute = $array; $model->collectionAttribute = $collection; $model->syncOriginal(); $model->intAttribute = 2; $model->floatAttribute = 0.443; $model->stringAttribute = '12'; $model->boolAttribute = true; $model->booleanAttribute = false; $model->objectAttribute = $stdClass; $model->arrayAttribute = [ 'foo' => 'bar2', ]; $model->jsonAttribute = [ 'foo' => 'bar2', ]; $model->collectionAttribute = collect([ 'foo' => 'bar2', ]); $this->assertIsInt($model->getOriginal('intAttribute')); $this->assertEquals(1, $model->getOriginal('intAttribute')); $this->assertEquals(2, $model->intAttribute); $this->assertEquals(2, $model->getAttribute('intAttribute')); $this->assertIsFloat($model->getOriginal('floatAttribute')); $this->assertEquals(0.1234, $model->getOriginal('floatAttribute')); $this->assertEquals(0.443, $model->floatAttribute); $this->assertIsString($model->getOriginal('stringAttribute')); $this->assertSame('432', $model->getOriginal('stringAttribute')); $this->assertSame('12', $model->stringAttribute); $this->assertIsBool($model->getOriginal('boolAttribute')); $this->assertTrue($model->getOriginal('boolAttribute')); $this->assertTrue($model->boolAttribute); $this->assertIsBool($model->getOriginal('booleanAttribute')); $this->assertFalse($model->getOriginal('booleanAttribute')); $this->assertFalse($model->booleanAttribute); $this->assertEquals($stdClass, $model->getOriginal('objectAttribute')); $this->assertEquals($model->getAttribute('objectAttribute'), $model->getOriginal('objectAttribute')); $this->assertEquals($array, $model->getOriginal('arrayAttribute')); $this->assertEquals(['foo' => 'bar'], $model->getOriginal('arrayAttribute')); $this->assertEquals(['foo' => 'bar2'], $model->getAttribute('arrayAttribute')); $this->assertEquals($array, $model->getOriginal('jsonAttribute')); $this->assertEquals(['foo' => 'bar'], $model->getOriginal('jsonAttribute')); $this->assertEquals(['foo' => 'bar2'], $model->getAttribute('jsonAttribute')); $this->assertEquals(['foo' => 'bar'], $model->getOriginal('collectionAttribute')->toArray()); $this->assertEquals(['foo' => 'bar2'], $model->getAttribute('collectionAttribute')->toArray()); } public function testUnsavedModel() { $user = new UnsavedModel; $user->name = null; $this->assertNull($user->name); } } class EloquentTestObserverStub { public function creating() { // } public function saved() { // } } class EloquentTestAnotherObserverStub { public function creating() { // } public function saved() { // } } class EloquentModelStub extends Model { public $connection; public $scopesCalled = []; protected $table = 'stub'; protected $guarded = []; protected $casts = ['castedFloat' => 'float']; public function getListItemsAttribute($value) { return json_decode($value, true); } public function setListItemsAttribute($value) { $this->attributes['list_items'] = json_encode($value); } public function getPasswordAttribute() { return '******'; } public function setPasswordAttribute($value) { $this->attributes['password_hash'] = sha1($value); } public function publicIncrement($column, $amount = 1, $extra = []) { return $this->increment($column, $amount, $extra); } public function belongsToStub() { return $this->belongsTo(EloquentModelSaveStub::class); } public function morphToStub() { return $this->morphTo(); } public function morphToStubWithKeys() { return $this->morphTo(null, 'type', 'id'); } public function morphToStubWithName() { return $this->morphTo('someName'); } public function morphToStubWithNameAndKeys() { return $this->morphTo('someName', 'type', 'id'); } public function belongsToExplicitKeyStub() { return $this->belongsTo(EloquentModelSaveStub::class, 'foo'); } public function incorrectRelationStub() { return 'foo'; } public function getDates() { return []; } public function getAppendableAttribute() { return 'appended'; } public function scopePublished(Builder $builder) { $this->scopesCalled[] = 'published'; } public function scopeCategory(Builder $builder, $category) { $this->scopesCalled['category'] = $category; } public function scopeFramework(Builder $builder, $framework, $version) { $this->scopesCalled['framework'] = [$framework, $version]; } public function scopeDate(Builder $builder, Carbon $date) { $this->scopesCalled['date'] = $date; } } trait FooBarTrait { public $fooBarIsInitialized = false; public function initializeFooBarTrait() { $this->fooBarIsInitialized = true; } } class EloquentModelStubWithTrait extends EloquentModelStub { use FooBarTrait; } class EloquentModelCamelStub extends EloquentModelStub { public static $snakeAttributes = false; } class EloquentDateModelStub extends EloquentModelStub { public function getDates() { return ['created_at', 'updated_at']; } } class EloquentModelSaveStub extends Model { protected $table = 'save_stub'; protected $guarded = []; public function save(array $options = []) { if ($this->fireModelEvent('saving') === false) { return false; } $_SERVER['__eloquent.saved'] = true; $this->fireModelEvent('saved', false); } public function setIncrementing($value) { $this->incrementing = $value; } public function getConnection() { $mock = m::mock(Connection::class); $mock->shouldReceive('getQueryGrammar')->andReturn($grammar = m::mock(Grammar::class)); $grammar->shouldReceive('getBitwiseOperators')->andReturn([]); $mock->shouldReceive('getPostProcessor')->andReturn($processor = m::mock(Processor::class)); $mock->shouldReceive('getName')->andReturn('name'); $mock->shouldReceive('query')->andReturnUsing(function () use ($mock, $grammar, $processor) { return new BaseBuilder($mock, $grammar, $processor); }); return $mock; } } class EloquentKeyTypeModelStub extends EloquentModelStub { protected $keyType = 'string'; } class EloquentModelFindWithWritePdoStub extends Model { public function newQuery() { $mock = m::mock(Builder::class); $mock->shouldReceive('useWritePdo')->once()->andReturnSelf(); $mock->shouldReceive('find')->once()->with(1)->andReturn('foo'); return $mock; } } class EloquentModelDestroyStub extends Model { protected $fillable = [ 'id', ]; public function newQuery() { $mock = m::mock(Builder::class); $mock->shouldReceive('whereIn')->once()->with('id', [1, 2, 3])->andReturn($mock); $mock->shouldReceive('get')->once()->andReturn([$model = m::mock(stdClass::class)]); $model->shouldReceive('delete')->once(); return $mock; } } class EloquentModelEmptyDestroyStub extends Model { public function newQuery() { $mock = m::mock(Builder::class); $mock->shouldReceive('whereIn')->never(); return $mock; } } class EloquentModelHydrateRawStub extends Model { public static function hydrate(array $items, $connection = null) { return 'hydrated'; } public function getConnection() { $mock = m::mock(Connection::class); $mock->shouldReceive('select')->once()->with('SELECT ?', ['foo'])->andReturn([]); return $mock; } } class EloquentModelWithStub extends Model { public function newQuery() { $mock = m::mock(Builder::class); $mock->shouldReceive('with')->once()->with(['foo', 'bar'])->andReturn('foo'); return $mock; } } class EloquentModelWithoutRelationStub extends Model { public $with = ['foo']; protected $guarded = []; public function getEagerLoads() { return $this->eagerLoads; } } class EloquentModelWithoutTableStub extends Model { // } class EloquentModelBootingTestStub extends Model { public static function unboot() { unset(static::$booted[static::class]); } public static function isBooted() { return array_key_exists(static::class, static::$booted); } } class EloquentModelAppendsStub extends Model { protected $appends = ['is_admin', 'camelCased', 'StudlyCased']; public function getIsAdminAttribute() { return 'admin'; } public function getCamelCasedAttribute() { return 'camelCased'; } public function getStudlyCasedAttribute() { return 'StudlyCased'; } } class EloquentModelGetMutatorsStub extends Model { public static function resetMutatorCache() { static::$mutatorCache = []; } public function getFirstNameAttribute() { // } public function getMiddleNameAttribute() { // } public function getLastNameAttribute() { // } public function doNotgetFirstInvalidAttribute() { // } public function doNotGetSecondInvalidAttribute() { // } public function doNotgetThirdInvalidAttributeEither() { // } public function doNotGetFourthInvalidAttributeEither() { // } } class EloquentModelCastingStub extends Model { protected $casts = [ 'intAttribute' => 'int', 'floatAttribute' => 'float', 'stringAttribute' => 'string', 'boolAttribute' => 'bool', 'booleanAttribute' => 'boolean', 'objectAttribute' => 'object', 'arrayAttribute' => 'array', 'jsonAttribute' => 'json', 'collectionAttribute' => 'collection', 'dateAttribute' => 'date', 'datetimeAttribute' => 'datetime', 'timestampAttribute' => 'timestamp', 'asarrayobjectAttribute' => AsArrayObject::class, 'ascollectionAttribute' => AsCollection::class, 'asStringableAttribute' => AsStringable::class, ]; public function jsonAttributeValue() { return $this->attributes['jsonAttribute']; } protected function serializeDate(DateTimeInterface $date) { return $date->format('Y-m-d H:i:s'); } } class EloquentModelDynamicHiddenStub extends Model { protected $table = 'stub'; protected $guarded = []; public function getHidden() { return ['age', 'id']; } } class EloquentModelDynamicVisibleStub extends Model { protected $table = 'stub'; protected $guarded = []; public function getVisible() { return ['name', 'id']; } } class EloquentModelNonIncrementingStub extends Model { protected $table = 'stub'; protected $guarded = []; public $incrementing = false; } class EloquentNoConnectionModelStub extends EloquentModelStub { // } class EloquentDifferentConnectionModelStub extends EloquentModelStub { public $connection = 'different_connection'; } class EloquentModelSavingEventStub { // } class EloquentModelEventObjectStub extends Model { protected $dispatchesEvents = [ 'saving' => EloquentModelSavingEventStub::class, ]; } class EloquentModelWithoutTimestamps extends Model { protected $table = 'stub'; public $timestamps = false; } class EloquentModelWithUpdatedAtNull extends Model { protected $table = 'stub'; const UPDATED_AT = null; } class UnsavedModel extends Model { protected $casts = ['name' => Uppercase::class]; } class Uppercase implements CastsInboundAttributes { public function set($model, string $key, $value, array $attributes) { return is_string($value) ? strtoupper($value) : $value; } }