write test for nominatim usage

This commit is contained in:
2024-03-09 13:59:02 +03:30
parent 797179d021
commit c0d991cdc0
27 changed files with 550 additions and 184 deletions

65
.env.testing Normal file
View File

@@ -0,0 +1,65 @@
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:R0FQ6mq9Ar2n5ToqeseUNN6zh94JGDnECsjF/pLOqaM=
APP_DEBUG=false
APP_URL=https://rms.witel.ir
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=rms_db
DB_USERNAME=root
DB_PASSWORD=password
DB_CONNECTION_2=
DB_HOST_2=
DB_PORT_2=
DB_DATABASE_2=
DB_USERNAME_2=
DB_PASSWORD_2=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
PAYMENT_USERNAME="cspay"
PAYMENT_PASSWORD="cspay123"
PAYMENT_LINK="https://payment.rmto.ir"
RMS_VERSION=3.0
RMS_CTO_PHONE_NUMBER="09380220400"
TELESCOPE_RESPONSE_SIZE_LIMIT=128
DEBUGBAR_ENABLED=false

View File

@@ -2,10 +2,12 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class City extends Model
{
use HasFactory;
/**
* The attributes that should be hidden for arrays.
*

View File

@@ -2,10 +2,12 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class EdarateOstani extends Model
{
use HasFactory;
protected $table = 'edarate_ostani';
public function roadObserved()

View File

@@ -2,10 +2,12 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class EdarateShahri extends Model
{
use HasFactory;
protected $table = 'edarate_shahri';
public function cities()

View File

@@ -2,10 +2,14 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class InfoItem extends Model
{
use HasFactory;
public $timestamps = false;
public function roadItemsProjects()
{

View File

@@ -2,9 +2,12 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class LogList extends Model
{
//
use HasFactory;
public $timestamps = false;
}

12
app/Models/Permission.php Normal file
View File

@@ -0,0 +1,12 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\Permission\Models\Permission as SpatiePermission;
class Permission extends SpatiePermission
{
use HasFactory;
}

View File

@@ -2,10 +2,12 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class UserActivityLog extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*

View File

@@ -0,0 +1,23 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
*/
class CityFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'name_fa' => $this->faker->name
];
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
*/
class EdarateOstaniFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'name_fa' => $this->faker->name
];
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
*/
class EdarateShahriFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'name_fa' => $this->faker->name
];
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
*/
class InfoItemFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'item' => $this->faker->randomNumber()
];
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
*/
class LogListFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'description' => $this->faker->name,
'log_unique_code' => 1134
];
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
*/
class PermissionFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'name' => $this->faker->name
];
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
*/
class UserActivityLogFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'description' => $this->faker->name
];
}
}

View File

@@ -17,7 +17,9 @@ class UserFactory extends Factory
public function definition(): array
{
return [
'username' => $this->faker->name
'username' => $this->faker->name,
'enabled' => true,
'confirmed' => 1
];
}
}

View File

@@ -16,8 +16,8 @@ return new class extends Migration
Schema::create('_geopoints_2', function (Blueprint $table) {
$table->integer('pid', true);
$table->point('geopoint');
$table->spatialIndex(['geopoint'], 'geopoint');
//
// $table->spatialIndex(['geopoint'], 'geopoint');
});
}

View File

@@ -16,8 +16,8 @@ return new class extends Migration
Schema::create('_geopoints', function (Blueprint $table) {
$table->integer('pid', true);
$table->point('geopoint');
$table->spatialIndex(['geopoint'], 'geopoint');
//
// $table->spatialIndex(['geopoint'], 'geopoint');
});
}

View File

@@ -1,40 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('personal_access_tokens', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('tokenable_type');
$table->unsignedBigInteger('tokenable_id');
$table->string('name');
$table->string('token', 64)->unique();
$table->text('abilities')->nullable();
$table->timestamp('last_used_at')->nullable();
$table->timestamp('expires_at')->nullable();
$table->timestamps();
$table->index(['tokenable_type', 'tokenable_id']);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('personal_access_tokens');
}
};

View File

@@ -27,7 +27,7 @@ return new class extends Migration
$table->string('sub_item_fa')->nullable();
$table->longText('sub_item_data')->nullable();
$table->string('sub_items');
$table->longText('sub_items_data')->nullable()->index('road_items_subss');
$table->longText('sub_items_data')->nullable();
$table->timestamps();
$table->unsignedTinyInteger('province_id');
$table->string('province_fa')->nullable();

View File

@@ -1,39 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('telescope_entries', function (Blueprint $table) {
$table->bigIncrements('sequence');
$table->char('uuid', 36)->unique();
$table->char('batch_id', 36)->index();
$table->string('family_hash')->nullable()->index();
$table->boolean('should_display_on_index')->default(true);
$table->string('type', 20);
$table->longText('content');
$table->dateTime('created_at')->nullable()->index();
$table->index(['type', 'should_display_on_index']);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('telescope_entries');
}
};

View File

@@ -1,33 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('telescope_entries_tags', function (Blueprint $table) {
$table->char('entry_uuid', 36);
$table->string('tag')->index();
$table->primary(['entry_uuid', 'tag']);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('telescope_entries_tags');
}
};

View File

@@ -1,30 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('telescope_monitoring', function (Blueprint $table) {
$table->string('tag')->primary();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('telescope_monitoring');
}
};

View File

@@ -1,32 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('telescope_entries_tags', function (Blueprint $table) {
$table->foreign(['entry_uuid'])->references(['uuid'])->on('telescope_entries')->onUpdate('no action')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('telescope_entries_tags', function (Blueprint $table) {
$table->dropForeign('telescope_entries_tags_entry_uuid_foreign');
});
}
};

View File

@@ -21,8 +21,11 @@
<env name="APP_ENV" value="testing"/>
<env name="BCRYPT_ROUNDS" value="4"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="DB_CONNECTION" value="mysql"/>
<env name="DB_HOST" value="localhost"/>
<env name="DB_DATABASE" value="rms_db"/>
<env name="DB_USERNAME" value="root"/>
<env name="DB_PASSWORD" value="password"/>
<env name="MAIL_MAILER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="SESSION_DRIVER" value="array"/>

View File

@@ -341,6 +341,7 @@ Route::prefix('safety_and_privacy')->group(function () {
/** TEST routes begin */
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
if (App::environment('local')) {
Route::get('otp', function (Request $request) {

View File

@@ -2,9 +2,17 @@
namespace Tests\Feature\V2\Dashboard\SafetyAndPrivacy;
use App\Models\City;
use App\Models\EdarateOstani;
use App\Models\EdarateShahri;
use App\Models\InfoItem;
use App\Models\LogList;
use App\Models\Permission;
use App\Models\User;
use App\Models\UserActivityLog;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Http\UploadedFile;
use Tests\TestCase;
class operatorFirstStepStoreTest extends TestCase
@@ -17,8 +25,280 @@ class operatorFirstStepStoreTest extends TestCase
{
$user = User::factory()->create();
$response = $this->post('v2/safety_and_privacy/operator/first_step');
$response = $this->actingAs($user)->postJson('v2/safety_and_privacy/operator/first_step');
$response->assertForbidden();
}
public function test_user_should_not_have_city_id(): void
{
$edarateOstani = EdarateOstani::factory()->create();
$user = User::factory()
->has(Permission::factory([
'name' => 'add-safety-and-privacy'
]))
->create([
'edarate_ostani_id' => $edarateOstani->id
]);
$response = $this->actingAs($user)->postJson('v2/safety_and_privacy/operator/first_step');
$response->assertStatus(400)
->assertExactJson([
'message' => 'امکان ثبت این مورد برای ادارات استانی و ستادی وجود ندارد!'
]);
}
public function test_user_should_not_have_edarate_shahri_id(): void
{
$city = City::factory()->create();
$user = User::factory()
->has(Permission::factory([
'name' => 'add-safety-and-privacy'
]))
->create([
'city_id' => $city->id
]);
$response = $this->actingAs($user)->postJson('v2/safety_and_privacy/operator/first_step');
$response->assertStatus(400)
->assertExactJson([
'message' => 'اداره شهری برای شما در سامانه ثبت نشده است!'
]);
}
public function test_point_is_required(): void
{
$city = City::factory()->create();
$edarateShari = EdarateShahri::factory()->create();
$user = User::factory()
->has(Permission::factory([
'name' => 'add-safety-and-privacy'
]))
->create([
'city_id' => $city->id,
'edarate_shahri_id' => $edarateShari->id
]);
$response = $this->actingAs($user)->postJson('v2/safety_and_privacy/operator/first_step');
$response->assertUnprocessable()
->assertInvalid([
'point' => __('validation.required', ['attribute' => 'point'])
]);
}
public function test_info_id_is_required(): void
{
$city = City::factory()->create();
$edarateShari = EdarateShahri::factory()->create();
$user = User::factory()
->has(Permission::factory([
'name' => 'add-safety-and-privacy'
]))
->create([
'city_id' => $city->id,
'edarate_shahri_id' => $edarateShari->id
]);
$response = $this->actingAs($user)->postJson('v2/safety_and_privacy/operator/first_step');
$response->assertUnprocessable()
->assertInvalid([
'info_id' => __('validation.required', ['attribute' => 'info id'])
]);
}
public function test_activity_date_is_required(): void
{
$city = City::factory()->create();
$edarateShari = EdarateShahri::factory()->create();
$user = User::factory()
->has(Permission::factory([
'name' => 'add-safety-and-privacy'
]))
->create([
'city_id' => $city->id,
'edarate_shahri_id' => $edarateShari->id
]);
$response = $this->actingAs($user)->postJson('v2/safety_and_privacy/operator/first_step');
$response->assertUnprocessable()
->assertInvalid([
'activity_date' => __('validation.required', ['attribute' => 'تاریخ فعالیت'])
]);
}
public function test_activity_date_should_match_the_format(): void
{
$city = City::factory()->create();
$edarateShari = EdarateShahri::factory()->create();
$user = User::factory()
->has(Permission::factory([
'name' => 'add-safety-and-privacy'
]))
->create([
'city_id' => $city->id,
'edarate_shahri_id' => $edarateShari->id
]);
$response = $this->actingAs($user)->postJson('v2/safety_and_privacy/operator/first_step', [
'activity_date' => $this->faker->date('d-m-Y-H-i-s')
]);
$response->assertUnprocessable()
->assertInvalid([
'activity_date' => __('validation.date_format', ['attribute' => 'تاریخ فعالیت', 'format' => 'Y-m-d'])
]);
}
public function test_activity_time_is_required(): void
{
$city = City::factory()->create();
$edarateShari = EdarateShahri::factory()->create();
$user = User::factory()
->has(Permission::factory([
'name' => 'add-safety-and-privacy'
]))
->create([
'city_id' => $city->id,
'edarate_shahri_id' => $edarateShari->id
]);
$response = $this->actingAs($user)->postJson('v2/safety_and_privacy/operator/first_step');
$response->assertUnprocessable()
->assertInvalid([
'activity_time' => __('validation.required', ['attribute' => 'ساعت فعالیت'])
]);
}
public function test_activity_time_should_match_the_format(): void
{
$city = City::factory()->create();
$edarateShari = EdarateShahri::factory()->create();
$user = User::factory()
->has(Permission::factory([
'name' => 'add-safety-and-privacy'
]))
->create([
'city_id' => $city->id,
'edarate_shahri_id' => $edarateShari->id
]);
$response = $this->actingAs($user)->postJson('v2/safety_and_privacy/operator/first_step', [
'activity_time' => $this->faker->date('d-m-Y-H-i-s')
]);
$response->assertUnprocessable()
->assertInvalid([
'activity_time' => __('validation.date_format', ['attribute' => 'ساعت فعالیت', 'format' => 'H:i'])
]);
}
public function test_recognize_picture_is_required(): void
{
$city = City::factory()->create();
$edarateShari = EdarateShahri::factory()->create();
$user = User::factory()
->has(Permission::factory([
'name' => 'add-safety-and-privacy'
]))
->create([
'city_id' => $city->id,
'edarate_shahri_id' => $edarateShari->id
]);
$response = $this->actingAs($user)->postJson('v2/safety_and_privacy/operator/first_step');
$response->assertUnprocessable()
->assertInvalid([
'recognize_picture' => __('validation.required', ['attribute' => 'recognize picture'])
]);
}
public function test_recognize_picture_should_be_image(): void
{
$city = City::factory()->create();
$edarateShari = EdarateShahri::factory()->create();
$user = User::factory()
->has(Permission::factory([
'name' => 'add-safety-and-privacy'
]))
->create([
'city_id' => $city->id,
'edarate_shahri_id' => $edarateShari->id
]);
$response = $this->actingAs($user)->postJson('v2/safety_and_privacy/operator/first_step', [
'recognize_picture' => $this->faker->name
]);
$response->assertUnprocessable()
->assertInvalid([
'recognize_picture' => __('validation.image', ['attribute' => 'recognize picture'])
]);
}
public function test_new_safety_and_privacy_can_be_stored(): void
{
$this->withOutExceptionHandling();
$infoItem = InfoItem::factory()->create([
'item' => 17
]);
$city = City::factory()->create();
$edarateShari = EdarateShahri::factory()->create();
$logList = LogList::factory()->create();
$userActivityLog = UserActivityLog::factory()->create();
$image = UploadedFile::fake()->create('image.jpg', 10);
$user = User::factory()
->has(Permission::factory([
'name' => 'add-safety-and-privacy'
]))
->create([
'city_id' => $city->id,
'edarate_shahri_id' => $edarateShari->id
]);
$data = [
'point' => '12,12',
'info_id' => $infoItem->id,
'activity_date' => $this->faker->date('Y-m-d'),
'activity_time' => $this->faker->date('H:i'),
'recognize_picture' => $image
];
$response = $this->actingAs($user)->postJson('v2/safety_and_privacy/operator/first_step', $data);
$response->assertOk();
$this->assertDatabaseHas('safety_and_privacy', [
'lat' => 12,
'lon' => 12,
'operator_id' => $user->id,
'operator_name' => $user->name,
'province_id' => $user->province_id,
'province_fa' => $user->province_fa,
'info_id' => $infoItem->id,
'city_id' => $city->id,
'city_fa' => $user->city_fa,
'activity_date_time' => $data['activity_date']." ".$data['activity_time'],
'edare_shahri_id' => $edarateShari->id,
'edare_shahri_name' => $edarateShari->name,
]);
}
}