diff --git a/.codeclimate.yml b/.codeclimate.yml new file mode 100644 index 0000000..cb10bab --- /dev/null +++ b/.codeclimate.yml @@ -0,0 +1,9 @@ +versoin: 2 +languages: + PHP: true +ratings: + paths: + - "**.php" +exclude_paths: + - tests + - vendor diff --git a/.gitignore b/.gitignore index fe8a4b4..723cd2f 100755 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ /vendor/ /.idea/ /composer.lock +/.phpunit.result.cache +/.php_cs.cache +/phpunit \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..6a56d89 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,45 @@ +language: php +php: + - 7.2 + - 7.3 + - 7.4 +env: + - ILLUMINATE_DATABASE=5.6 + - ILLUMINATE_DATABASE=~5.0 + - ILLUMINATE_DATABASE=~6.0 + - ILLUMINATE_DATABASE=~7.0 + - ILLUMINATE_DATABASE=~8.0 +jobs: + include: + - php: 7.1 + env: ILLUMINATE_DATABASE=5.6 + - php: 7.1 + env: ILLUMINATE_DATABASE=~5.0 + exclude: + - php: 7.2 + env: ILLUMINATE_DATABASE=~8.0 + allow_failures: + - php: 7.3 + env: ILLUMINATE_DATABASE=5.6 + - php: 7.4 + env: ILLUMINATE_DATABASE=5.6 +git: + depth: 3 + submodules: false +dist: xenial +os: linux +install: + - composer require "illuminate/database:$ILLUMINATE_DATABASE" + - composer update + - if [[ ${TRAVIS_PHP_VERSION:0:3} == "7.0" ]] || [[ ${TRAVIS_PHP_VERSION:0:3} == "7.1" ]]; then wget -O vendor/bin/phpunit https://phar.phpunit.de/phpunit-6.phar; fi + - if [ ! -f "vendor/bin/phpunit" ]; then wget -O vendor/bin/phpunit https://phar.phpunit.de/phpunit-8.phar; fi + - chmod +x vendor/bin/phpunit +before_script: + - wget -O cc-test-reporter https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 + - chmod +x cc-test-reporter + - if [[ ${TRAVIS_PHP_VERSION:0:3} == "7.2" ]] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then ./cc-test-reporter before-build; fi +script: + - ./vendor/bin/phpunit --version + - ./vendor/bin/phpunit --coverage-text --coverage-clover build/logs/clover.xml +after_script: + - if [[ ${TRAVIS_PHP_VERSION:0:3} == "7.2" ]] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT; fi \ No newline at end of file diff --git a/README.md b/README.md index e293f99..68ffad0 100755 --- a/README.md +++ b/README.md @@ -170,18 +170,19 @@ We use [SemVer](http://semver.org/) for versioning. For the versions available, ## Unit Tests -In order to run the test suite, install the development dependencies: +To run unit tests you have to obtain manually proper version of PHPUnit -```bash -$ composer install --dev -``` - -Then, run the following command: +* if you have PHP version 7.0 or 7.1 please get [PHPUnit 6](https://phar.phpunit.de/phpunit-6.phar) +* if you have PHP version 7.2 and higher please get [PHPUnit 8](https://phar.phpunit.de/phpunit-8.phar) +Example ```bash -$ vendor/bin/phpunit +wget -O phpunit https://phar.phpunit.de/phpunit-8.phar +chmod +x phpunit +./phpunit ``` + ## Authors * [Claudin J. Daniel](https://github.com/topclaudy) - *Initial work* diff --git a/composer.json b/composer.json index e6d9e4e..f0c63eb 100755 --- a/composer.json +++ b/composer.json @@ -14,29 +14,19 @@ } ], "require": { - "php": ">=5.6.4", - "illuminate/database": "^7.27|~8.0", - "illuminate/console": "~5.4|~6.0|~7.0|~8.0", - "illuminate/support": "~5.4|~6.0|~7.0|~8.0", - "illuminate/cache": "~5.4|~6.0|~7.0|~8.0" + "illuminate/database": ">=5.6 <9.0" }, "require-dev": { - "phpunit/phpunit": "5.*", - "laravel/laravel": "~5.4|~6.0|~7.0|~8.0", - "fzaninotto/faker": "^1.8" + "ext-sqlite3": "*" }, "autoload": { "psr-4": { "Awobaz\\Compoships\\": "src" - }, - "files": [ - ] + } }, - "extra": { - "laravel": { - "providers": [ - "Awobaz\\Compoships\\ComposhipsServiceProvider" - ] + "autoload-dev": { + "psr-4": { + "Awobaz\\Compoships\\Tests\\": "tests" } }, "suggest": { diff --git a/phpunit.xml b/phpunit.xml deleted file mode 100644 index f994f39..0000000 --- a/phpunit.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - ./tests/ - - - \ No newline at end of file diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..1955fe8 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,29 @@ + + + + + ./tests + + + + + src + + + \ No newline at end of file diff --git a/src/ComposhipsServiceProvider.php b/src/ComposhipsServiceProvider.php deleted file mode 100755 index 3a0eae8..0000000 --- a/src/ComposhipsServiceProvider.php +++ /dev/null @@ -1,26 +0,0 @@ -ownerKey)) { - - $ownerKey = $model instanceof Model ? $model->getAttribute($this->ownerKey) : $model; - for ($i = 0; $i < count($this->foreignKey); $i++) { - $foreignKey = $this->foreignKey[$i]; - $value = $ownerKey[$i]; - $this->child->setAttribute($foreignKey, $value); - } - - if ($model instanceof Model) { - $this->child->setRelation($this->relationName, $model); - } else { - $this->child->unsetRelation($this->relationName); - } - - return $this->child; - - } else { + if (!is_array($this->ownerKey)) { return parent::associate($model); } + + $ownerKey = $model instanceof Model ? $model->getAttribute($this->ownerKey) : $model; + for ($i = 0; $i < count($this->foreignKey); $i++) { + $foreignKey = $this->foreignKey[$i]; + $value = $ownerKey[$i]; + $this->child->setAttribute($foreignKey, $value); + } + // BC break in 5.8 : https://github.com/illuminate/database/commit/87b9833019f48b88d98a6afc46f38ce37f08237d + $relationName = property_exists($this, 'relationName') ? $this->relationName : $this->relation; + if ($model instanceof Model) { + $this->child->setRelation($relationName, $model); + // proper unset // https://github.com/illuminate/database/commit/44411c7288fc7b7d4e5680cfcdaa46d348b5c981 + } elseif ($this->child->isDirty($this->foreignKey)) { + $this->child->unsetRelation($relationName); + } + + return $this->child; } /** @@ -107,6 +107,9 @@ public function addEagerConstraints(array $models) $keys[] = $this->related->getTable().'.'.$key; } + // method \Awobaz\Compoships\Database\Eloquent\Relations\HasOneOrMany::whereInMethod + // 5.6 - does not exist + // 5.7 - added in 5.7.17 / https://github.com/illuminate/database/commit/9af300d1c50c9ec526823c1e6548daa3949bf9a9 $this->query->whereIn($keys, $this->getEagerModelKeys($models)); } else { parent::addEagerConstraints($models); diff --git a/src/Database/Eloquent/Relations/HasOneOrMany.php b/src/Database/Eloquent/Relations/HasOneOrMany.php index 239504f..ebccc76 100755 --- a/src/Database/Eloquent/Relations/HasOneOrMany.php +++ b/src/Database/Eloquent/Relations/HasOneOrMany.php @@ -44,9 +44,12 @@ public function addConstraints() * Get the name of the "where in" method for eager loading. * * @param \Illuminate\Database\Eloquent\Model $model - * @param string|array $key + * @param string|array $key * * @return string + * + * 5.6 - no method \Awobaz\Compoships\Database\Eloquent\Relations\HasOneOrMany::whereInMethod + * added in this commit (5.7.17) https://github.com/illuminate/database/commit/9af300d1c50c9ec526823c1e6548daa3949bf9a9 */ protected function whereInMethod(Model $model, $key) { diff --git a/tests/.gitkeep b/tests/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/tests/ComposhipsTest.php b/tests/ComposhipsTest.php index ddb474c..af8dfa5 100644 --- a/tests/ComposhipsTest.php +++ b/tests/ComposhipsTest.php @@ -1,24 +1,26 @@ booking_id = 1; - $allocation->vehicle_id = 1; - $allocation->save(); - - $allocation->trackingTasks() - ->saveMany([ - new TrackingTask(), - new TrackingTask(), - new TrackingTask(), - ]); - - $this->assertNotNull($allocation->trackingTasks); - $this->assertEquals($allocation->trackingTasks->count(), 3); - $this->assertInstanceOf(Allocation::class, $allocation->trackingTasks->first()->allocation); - - Model::reguard(); - } /** * Test the save method on a relationship with a null value. - * - * @return void */ public function testSaveWithANullValue() { @@ -114,8 +85,6 @@ public function testSaveWithANullValue() /** * Test a relationship with only null values is not supported. - * - * @return void */ public function testARelationshipWithOnlyNullValuesIsNotSupported() { @@ -138,8 +107,6 @@ public function testARelationshipWithOnlyNullValuesIsNotSupported() /** * Test a relationship with a foreign key is empty on a new instance. - * - * @return void */ public function testARelationshipWithAForeignKeyIsEmptyOnANewInstance() { @@ -159,8 +126,6 @@ public function testARelationshipWithAForeignKeyIsEmptyOnANewInstance() /** * Test the create method on a relationship. - * - * @return void */ public function testCreate() { @@ -182,19 +147,12 @@ public function testCreate() /** * Test the make method on a relationship. - * - * @return void */ public function testMake() { Model::unguard(); $allocation = new Allocation(); - - if (!method_exists($allocation->trackingTasks(), 'make')) { - return; - } - $allocation->booking_id = 1; $allocation->vehicle_id = 1; $allocation->save(); @@ -214,13 +172,11 @@ public function testHas() ->get() ->toArray(); - $this->assertInternalType('array', $allocations); + $this->assertIsArray($allocations); } /** * A basic test example. - * - * @return void */ public function testWhereHas() { @@ -228,14 +184,14 @@ public function testWhereHas() ->get() ->toArray(); - $this->assertInternalType('array', $allocations); + $this->assertIsArray($allocations); $allocations = Allocation::query() ->has('trackingTasks') ->get() ->toArray(); - $this->assertInternalType('array', $allocations); + $this->assertIsArray($allocations); } public function testWhereHasCallback() @@ -246,7 +202,7 @@ public function testWhereHasCallback() ->get() ->toArray(); - $this->assertInternalType('array', $allocations); + $this->assertIsArray($allocations); } public function testMixedTypeCompositeKey() @@ -260,7 +216,7 @@ public function testMixedTypeCompositeKey() $pickupPoint->pickupTimes() ->create([ - 'days' => 'mon tue', + 'days' => 'mon tue', 'pickup_time' => '08:00:00', ]); @@ -269,52 +225,13 @@ public function testMixedTypeCompositeKey() Model::reguard(); } - public function testFactories() - { - if (class_exists('\Illuminate\Database\Eloquent\Factory')) { - //Laravel 7 and below - $factory = app(\Illuminate\Database\Eloquent\Factory::class); - - $factory->define(Allocation::class, function (Faker $faker) { - return [ - 'booking_id' => rand(1, 100), - 'vehicle_id' => rand(1, 100), - ]; - }); - - $factory->define(TrackingTask::class, function (Faker $faker) { - return [ - - ]; - }); - - factory(Allocation::class) - ->create() - ->each(function ($a) { - $a->trackingTasks() - ->save(factory(TrackingTask::class)->make()); - }); - } else { - //Laravel 8 and above - - AllocationFactory::new()->create()->each(function ($a) { - $a->trackingTasks() - ->save(TrackingTaskFactory::new()->make()); - }); - } - - $allocation = Allocation::firstOrFail(); - - $this->assertNotNull($allocation->trackingTasks); - } - public function testHasForSelfRelation() { $trackingTask = TrackingTask::has('subTasks') ->get() ->toArray(); - $this->assertInternalType('array', $trackingTask); + $this->assertIsArray($trackingTask); } public function testHasWithBelongsToRelation() @@ -323,15 +240,10 @@ public function testHasWithBelongsToRelation() ->get() ->toArray(); - $this->assertInternalType('array', $pickup_times); + $this->assertIsArray($pickup_times); } - /** - * Test the associate method on a belongsTo relationship - * - * @return void - */ - public function testAssociate() + public function testAssociateOnbelongsTo() { Model::unguard(); diff --git a/tests/Factories/AllocationFactory.php b/tests/Factories/AllocationFactory.php deleted file mode 100644 index 65de32f..0000000 --- a/tests/Factories/AllocationFactory.php +++ /dev/null @@ -1,24 +0,0 @@ - rand(1, 100), - 'vehicle_id' => rand(1, 100), - ]; - } -} diff --git a/tests/Factories/TrackingTaskFactory.php b/tests/Factories/TrackingTaskFactory.php deleted file mode 100644 index ff00cb5..0000000 --- a/tests/Factories/TrackingTaskFactory.php +++ /dev/null @@ -1,23 +0,0 @@ -create('allocations', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id') ->unsigned() @@ -27,14 +29,26 @@ public function up() $table->timestamps(); }); - Schema::create('spaces', function (Blueprint $table) { + // contains original single PK relations + Capsule::schema()->create('original_packages', function (Blueprint $table) { + $table->increments('id'); + $table->string('name')->nullable(); + $table->integer('allocation_id'); + $table->foreign('allocation_id') + ->references('id') + ->on('allocations') + ->onUpdate('cascade') + ->onDelete('cascade'); + }); + + Capsule::schema()->create('spaces', function (Blueprint $table) { $table->increments('id'); $table->integer('booking_id') ->unsigned(); $table->timestamps(); }); - Schema::create('tracking_tasks', function (Blueprint $table) { + Capsule::schema()->create('tracking_tasks', function (Blueprint $table) { $table->increments('id'); $table->integer('booking_id') ->unsigned() @@ -58,14 +72,14 @@ public function up() $table->softDeletes(); }); - Schema::create('pickup_points', function (Blueprint $table) { + Capsule::schema()->create('pickup_points', function (Blueprint $table) { $table->string('contract_number'); $table->integer('pickup_index') ->unsigned(); $table->timestamps(); }); - Schema::create('pickup_times', function (Blueprint $table) { + Capsule::schema()->create('pickup_times', function (Blueprint $table) { $table->string('contract_number'); $table->integer('pickup_index') ->unsigned(); @@ -83,7 +97,7 @@ public function up() $table->timestamps(); }); - Schema::create('users', function (Blueprint $table) { + Capsule::schema()->create('users', function (Blueprint $table) { $table->increments('id'); $table->integer('booking_id') ->unsigned() @@ -91,15 +105,4 @@ public function up() $table->timestamps(); }); } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('tracking_tasks'); - Schema::drop('allocations'); - } } diff --git a/tests/Models/Allocation.php b/tests/Models/Allocation.php index 284447a..566698e 100644 --- a/tests/Models/Allocation.php +++ b/tests/Models/Allocation.php @@ -1,21 +1,63 @@ 'datetime:Y-m-d H:i:s', + 'updated_at' => 'datetime:Y-m-d H:i:s', + ]; + + /** + * @return \Awobaz\Compoships\Database\Eloquent\Relations\HasMany + */ public function trackingTasks() { return $this->hasMany(TrackingTask::class, ['booking_id', 'vehicle_id'], ['booking_id', 'vehicle_id']); } + /** + * @return \Awobaz\Compoships\Database\Eloquent\Relations\HasMany + */ + public function originalPackages() + { + return $this->hasMany(OriginalPackage::class); + } + + /** + * @return \Awobaz\Compoships\Database\Eloquent\Relations\HasOne + */ public function space() { return $this->hasOne(Space::class, 'booking_id', 'booking_id'); } + /** + * @return \Awobaz\Compoships\Database\Eloquent\Relations\BelongsTo + */ public function user() { return $this->belongsTo(User::class, ['user_id', 'booking_id'], ['id', 'booking_id']); diff --git a/tests/Models/OriginalPackage.php b/tests/Models/OriginalPackage.php new file mode 100644 index 0000000..4eb5ccc --- /dev/null +++ b/tests/Models/OriginalPackage.php @@ -0,0 +1,30 @@ +belongsTo(Allocation::class); + } +} \ No newline at end of file diff --git a/tests/Models/PickupPoint.php b/tests/Models/PickupPoint.php index 8a3bb77..ccdd80f 100644 --- a/tests/Models/PickupPoint.php +++ b/tests/Models/PickupPoint.php @@ -1,11 +1,30 @@ 'datetime:Y-m-d H:i:s', + 'updated_at' => 'datetime:Y-m-d H:i:s', + ]; + public function pickupTimes() { return $this->hasMany(PickupTime::class, ['contract_number', 'pickup_index'], [ diff --git a/tests/Models/PickupTime.php b/tests/Models/PickupTime.php index c8b7778..0c89a47 100644 --- a/tests/Models/PickupTime.php +++ b/tests/Models/PickupTime.php @@ -1,11 +1,23 @@ belongsTo(PickupPoint::class, ['contract_number', 'pickup_index'], [ diff --git a/tests/Models/Space.php b/tests/Models/Space.php index 0707827..e474f53 100644 --- a/tests/Models/Space.php +++ b/tests/Models/Space.php @@ -1,9 +1,23 @@ 'datetime:Y-m-d H:i:s', + 'updated_at' => 'datetime:Y-m-d H:i:s', + ]; } \ No newline at end of file diff --git a/tests/Models/TrackingTask.php b/tests/Models/TrackingTask.php index 96713a7..25fec45 100644 --- a/tests/Models/TrackingTask.php +++ b/tests/Models/TrackingTask.php @@ -1,13 +1,34 @@ 'datetime:Y-m-d H:i:s', + 'updated_at' => 'datetime:Y-m-d H:i:s', + ]; public function allocation() { diff --git a/tests/Models/User.php b/tests/Models/User.php index 108591c..c6ba022 100644 --- a/tests/Models/User.php +++ b/tests/Models/User.php @@ -1,11 +1,30 @@ 'datetime:Y-m-d H:i:s', + 'updated_at' => 'datetime:Y-m-d H:i:s', + ]; + public function allocations() { return $this->hasMany(Allocation::class, ['user_id', 'booking_id'], ['id', 'booking_id']); diff --git a/tests/TestCase.php b/tests/TestCase.php deleted file mode 100644 index 3f43796..0000000 --- a/tests/TestCase.php +++ /dev/null @@ -1,53 +0,0 @@ -make('Illuminate\Contracts\Console\Kernel') - ->bootstrap(); - - return $app; - } - - /** - * Setup DB before each test. - * - * @return void - */ - protected function setUp(): void - { - parent::setUp(); - - $this->app['config']->set('database.default', 'sqlite'); - $this->app['config']->set('database.connections.sqlite.database', ':memory:'); - - DB::statement("PRAGMA foreign_keys = OFF"); //Prevent weird "1 foreign key mismatch" error - - $this->migrate(); - } - - /** - * run package database migrations - * - * @return void - */ - public function migrate() - { - $fileSystem = new Filesystem; - $fileSystem->requireOnce(__DIR__."/migrations.php"); - - (new Migration())->up(); - } -} \ No newline at end of file diff --git a/tests/TestCase/AbstractTestCase.php b/tests/TestCase/AbstractTestCase.php new file mode 100644 index 0000000..19dff34 --- /dev/null +++ b/tests/TestCase/AbstractTestCase.php @@ -0,0 +1,29 @@ +addConnection([ + 'driver' => 'sqlite', + 'database' => ':memory:', + 'charset' => 'utf8', + 'collation' => 'utf8_unicode_ci', + 'prefix' => '', + ]); + $capsuleManager->setAsGlobal(); + $capsuleManager->bootEloquent(); + + (new Migration())->up(); + } + +} diff --git a/tests/TestCase/TestCase6.php b/tests/TestCase/TestCase6.php new file mode 100644 index 0000000..79b7d60 --- /dev/null +++ b/tests/TestCase/TestCase6.php @@ -0,0 +1,30 @@ +setupDatabase(); + } + + /** + * Asserts that a variable is of type array. + */ + public static function assertIsArray($actual, string $message = '') + { + Assert::assertInternalType('array', $actual, $message); + } +} diff --git a/tests/TestCase/TestCase8.php b/tests/TestCase/TestCase8.php new file mode 100644 index 0000000..430bb2c --- /dev/null +++ b/tests/TestCase/TestCase8.php @@ -0,0 +1,21 @@ +setupDatabase(); + } +} \ No newline at end of file diff --git a/tests/Unit/BuilderTest.php b/tests/Unit/BuilderTest.php new file mode 100644 index 0000000..3e04e57 --- /dev/null +++ b/tests/Unit/BuilderTest.php @@ -0,0 +1,58 @@ +insertGetId([ + 'booking_id' => 1, + 'vehicle_id' => 1, + ]); + $allocationId2 = Capsule::table('allocations')->insertGetId([ + 'booking_id' => 2, + 'vehicle_id' => 2, + ]); + $package1 = Capsule::table('original_packages')->insertGetId([ + 'name' => 'name 1', + 'allocation_id' => 1, + ]); + $package2 = Capsule::table('original_packages')->insertGetId([ + 'name' => 'name 2', + 'allocation_id' => 1, + ]); + + /** @var Allocation[] $allocations */ + $allocations = Allocation::query()->whereHas('originalPackages', function ($query) { + $query->where('id', 123); + })->get(); + $this->assertCount(0, $allocations); + + /** @var Allocation[] $allocations */ + $allocations = Allocation::query()->whereHas('originalPackages', function ($query) { + $query->where('id', 2); + })->get(); + $this->assertCount(1, $allocations); + $this->assertCount(2, $allocations[0]->originalPackages); + } + +} \ No newline at end of file diff --git a/tests/Unit/HasManyTest.php b/tests/Unit/HasManyTest.php new file mode 100644 index 0000000..52e8f4f --- /dev/null +++ b/tests/Unit/HasManyTest.php @@ -0,0 +1,360 @@ +markAsRisky(); + $this->markTestIncomplete('This test is broken, because relation columns are required on selections!'); + $allocation = $this->createAllocation(); + $allocation->trackingTasks() + ->saveMany([ + new TrackingTask(), + new TrackingTask(), + new TrackingTask(), + ]); + + $trackingTasks = Allocation::where('id', $allocation->id)->with(['trackingTasks' => function (HasMany $query) { + // missing 'vehicle column' + $query->select('booking_id'); + }] + )->first()->trackingTasks; + $this->assertCount(1, $trackingTasks); // TODO: must be error or 3 items? + } + + /** + * @covers \Awobaz\Compoships\Database\Eloquent\Concerns\HasRelationships::belongsTo + * @covers \Awobaz\Compoships\Database\Eloquent\Concerns\HasRelationships::newBelongsTo + * @covers \Awobaz\Compoships\Database\Eloquent\Relations\BelongsTo::addConstraints + * @covers \Awobaz\Compoships\Database\Eloquent\Relations\BelongsTo::getResults + */ + public function test_Compoships_hasOneOrMany_saveMany() + { + $expectedData = [ + [ + 'id' => (string)1, + 'booking_id' => (string)1, + 'vehicle_id' => (string)1, + 'updated_at' => Carbon::now()->toDateTimeString(), + 'created_at' => Carbon::now()->toDateTimeString(), + 'deleted_at' => null + ], + [ + 'id' => (string)2, + 'booking_id' => (string)1, + 'vehicle_id' => (string)1, + 'updated_at' => Carbon::now()->toDateTimeString(), + 'created_at' => Carbon::now()->toDateTimeString(), + 'deleted_at' => null + ], + [ + 'id' => (string)3, + 'booking_id' => (string)1, + 'vehicle_id' => (string)1, + 'updated_at' => Carbon::now()->toDateTimeString(), + 'created_at' => Carbon::now()->toDateTimeString(), + 'deleted_at' => null + ], + ]; + + $allocation = $this->createAllocation(); + $allocation->trackingTasks()->saveMany([ + new TrackingTask(), + new TrackingTask(), + new TrackingTask(), + ]); + $this->assertNotNull($allocation->trackingTasks); + $this->assertEquals(count($expectedData), $allocation->trackingTasks->count()); + $this->assertEquals($expectedData, $allocation->trackingTasks->toArray()); + $this->assertEquals($expectedData, array_map(function ($item) { + return (array)$item; + }, Capsule::table('tracking_tasks')->get()->all())); + } + + public function test_Compoships_hasOneOrMany_create__empty() + { + $allocation = $this->createAllocation(); + $trackingTask = $allocation->trackingTasks()->create(); + $this->assertEquals([ + 'id' => 1, + 'booking_id' => 1, + 'vehicle_id' => 1, + 'updated_at' => Carbon::now()->toDateTimeString(), + 'created_at' => Carbon::now()->toDateTimeString(), + ], $trackingTask->toArray()); + + $this->assertEquals(1, Capsule::table('tracking_tasks')->count()); + $this->AssertEquals([ + 'id' => (string)1, + 'booking_id' => (string)1, + 'vehicle_id' => (string)1, + 'updated_at' => Carbon::now()->toDateTimeString(), + 'created_at' => Carbon::now()->toDateTimeString(), + 'deleted_at' => null + ], (array)Capsule::table('tracking_tasks')->select()->first()); + + $trackingTask->refresh(); + $this->assertEquals([ + 'id' => (string)1, + 'booking_id' => (string)1, + 'vehicle_id' => (string)1, + 'updated_at' => Carbon::now()->toDateTimeString(), + 'created_at' => Carbon::now()->toDateTimeString(), + 'deleted_at' => null + ], $trackingTask->toArray()); + } + + public function test_Compoships_hasOneOrMany_create__fail_set_unguarded() + { + $this->expectException(\Illuminate\Database\Eloquent\MassAssignmentException::class); + $this->expectExceptionMessage('Add [created_at] to fillable property to allow mass assignment'); + $allocation = $this->createAllocation(); + $trackingTask = $allocation->trackingTasks()->create(['created_at' => Carbon::now()]); + } + + public function test_Compoships_hasOneOrMany_create__change_relation_columns() + { + $allocation = $this->createAllocation(); + $allocation::unguard(true); + $package = $allocation->trackingTasks()->create(['booking_id' => 123]); + $allocation::unguard(false); + $package->refresh(); + $this->assertEquals([ + 'id' => (string)1, + 'booking_id' => (string)1, // correct, as it was not changed + 'vehicle_id' => (string)1, + 'updated_at' => Carbon::now()->toDateTimeString(), + 'created_at' => Carbon::now()->toDateTimeString(), + 'deleted_at' => null + ], $package->toArray()); + } + + public function test_Compoships_hasOneOrMany_create__normal() + { + $allocation = $this->createAllocation(); + $allocation::unguard(true); + $trackingTask = $allocation->trackingTasks()->create(['created_at' => Carbon::now()->addDay()]); + $allocation::unguard(false); + $trackingTask->refresh(); + $this->assertEquals([ + 'id' => (string)1, + 'booking_id' => (string)1, + 'vehicle_id' => (string)1, + 'updated_at' => Carbon::now()->toDateTimeString(), + 'created_at' => Carbon::now()->addDay()->toDateTimeString(), + 'deleted_at' => null + ], $trackingTask->toArray()); + } + + /** + * @covers \Awobaz\Compoships\Database\Query\Builder::whereIn + */ + public function test_Compoships_eagerLoading() + { + $allocationId1 = Capsule::table('allocations')->insertGetId([ + 'booking_id' => 1, + 'vehicle_id' => 1, + ]); + $allocationId2 = Capsule::table('allocations')->insertGetId([ + 'booking_id' => 2, + 'vehicle_id' => 2, + ]); + $trackingTaskId1 = Capsule::table('tracking_tasks')->insertGetId([ + 'booking_id' => 1, + 'vehicle_id' => 1, + 'created_at' => Carbon::now()->toDateTimeString(), + 'updated_at' => Carbon::now()->toDateTimeString(), + 'deleted_at' => null + ]); + $trackingTaskId2 = Capsule::table('tracking_tasks')->insertGetId([ + 'booking_id' => 1, + 'vehicle_id' => 1, + 'created_at' => Carbon::now()->toDateTimeString(), + 'updated_at' => Carbon::now()->toDateTimeString(), + 'deleted_at' => null + ]); + + $allocations1 = Allocation::where('id', $allocationId1)->with('trackingTasks')->get()->all(); + $allocations2 = Allocation::where('id', $allocationId2)->with('trackingTasks')->get()->all(); + + $this->assertCount(1, $allocations1); + $this->assertCount(2, $allocations1[0]->trackingTasks); + $this->assertEquals(1, $allocations1[0]->trackingTasks[0]->id); + $this->assertEquals(2, $allocations1[0]->trackingTasks[1]->id); + + $this->assertCount(1, $allocations2); + $this->assertCount(0, $allocations2[0]->trackingTasks); + } + + + /** + * @covers \Awobaz\Compoships\Database\Query\Builder::whereIn + */ + public function test_Illuminate_eagerLoading() + { + $allocationId1 = Capsule::table('allocations')->insertGetId([ + 'booking_id' => 1, + 'vehicle_id' => 1, + ]); + + $allocationId2 = Capsule::table('allocations')->insertGetId([ + 'booking_id' => 2, + 'vehicle_id' => 2, + ]); + $package1 = Capsule::table('original_packages')->insertGetId([ + 'name' => 'name 1', + 'allocation_id' => 1, + ]); + $package2 = Capsule::table('original_packages')->insertGetId([ + 'name' => 'name 2', + 'allocation_id' => 1, + ]); + + $allocations1 = Allocation::where('id', $allocationId1)->with('originalPackages')->get()->all(); + $this->assertCount(1, $allocations1); + $this->assertCount(2, $allocations1[0]->originalPackages); + $this->assertEquals(1, $allocations1[0]->originalPackages[0]->id); + $this->assertEquals(2, $allocations1[0]->originalPackages[1]->id); + + $allocations2 = Allocation::where('id', $allocationId2)->with('originalPackages')->get()->all(); + $this->assertCount(1, $allocations2); + $this->assertCount(0, $allocations2[0]->originalPackages); + } + + public function test_Illuminate_hasOneOrMany_create__normal() + { + $allocation = $this->createAllocation(); + $allocation::unguard(true); + $package = $allocation->originalPackages()->create(['name' => 'some name']); + $allocation::unguard(false); + $package->refresh(); + $this->assertEquals([ + 'id' => (string)1, + 'allocation_id' => (string)1, + 'name' => 'some name' + ], $package->toArray()); + } + + public function test_Illuminate_hasOneOrMany_create__change_relation_columns() + { + $allocation = $this->createAllocation(); + $allocation::unguard(true); + $package = $allocation->originalPackages()->create(['allocation_id' => 123]); + $allocation::unguard(false); + $package->refresh(); + $this->assertEquals([ + 'id' => (string)1, + 'allocation_id' => (string)1, // correct, as it was not changed + 'name' => null, + ], $package->toArray()); + } + + public function test_Illuminate_hasOneOrMany_create__empty() + { + $allocation = $this->createAllocation(); + $package = $allocation->originalPackages()->create(); + $package->refresh(); + $this->assertEquals([ + 'id' => (string)1, + 'allocation_id' => (string)1, + 'name' => null + ], $package->toArray()); + } + + public function test_Illuminate_hasOneOrMany_create__fail_set_unguarded() + { + $this->expectException(\Illuminate\Database\Eloquent\MassAssignmentException::class); + $this->expectExceptionMessage('Add [name] to fillable property to allow mass assignment'); + $allocation = $this->createAllocation(); + $package = $allocation->originalPackages()->create(['name' => 'some name']); + } + + public function test_Illuminate_hasOneOrMany_saveMany() + { + $expectedData = [ + [ + 'id' => (string)1, + 'allocation_id' => (string)1, + 'name' => 'name 1' + ], + [ + 'id' => (string)2, + 'allocation_id' => (string)1, + 'name' => 'name 2' + ], + [ + 'id' => (string)3, + 'allocation_id' => (string)1, + 'name' => 'name 3' + ], + ]; + + $allocation = $this->createAllocation(1, 1); + $allocation::unguard(true); + $allocation->originalPackages()->saveMany([ + new OriginalPackage(['name' => 'name 1']), + new OriginalPackage(['name' => 'name 2']), + new OriginalPackage(['name' => 'name 3']), + ]); + $allocation::unguard(false); + $allocation->refresh(); + $this->assertNotNull($allocation->originalPackages); + $this->assertEquals(count($expectedData), $allocation->originalPackages->count()); + $this->assertEquals($expectedData, $allocation->originalPackages->toArray()); + $this->assertEquals($expectedData, array_map(function ($item) { + return (array)$item; + }, Capsule::table('original_packages')->get()->all())); + } + + + /** + * @param int $bookingId + * @param int $vehicleId + * @return Allocation + */ + protected function createAllocation($bookingId = 1, $vehicleId = 1) + { + $allocation = new Allocation(); + $allocation->booking_id = $bookingId; + $allocation->vehicle_id = $vehicleId; + $allocation->save(); + $this->assertEquals(1, Capsule::table('allocations')->count()); + $this->assertEquals([ + 'id' => (string)1, + 'booking_id' => (string)$allocation->booking_id, + 'vehicle_id' => (string)$allocation->vehicle_id, + 'created_at' => Carbon::now()->toDateTimeString(), + 'updated_at' => Carbon::now()->toDateTimeString(), + 'user_id' => null + ], (array)Capsule::table('allocations')->first()); + + return $allocation; + } + +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..6c44c71 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,13 @@ +addClassMap([ + \Awobaz\Compoships\Tests\TestCase\TestCase::class => $mappedTestCaseFilename +]);