diff --git a/app/Http/Controllers/V2/Dashboard/RoadObservationController.php b/app/Http/Controllers/V2/Dashboard/RoadObservationController.php index e2d51822..57847a39 100644 --- a/app/Http/Controllers/V2/Dashboard/RoadObservationController.php +++ b/app/Http/Controllers/V2/Dashboard/RoadObservationController.php @@ -235,7 +235,7 @@ class RoadObservationController extends Controller } $from_date_array = explode('-', verta()->startYear()->format('Y-m-d')); - $from_datetime = implode('-', verta()->getGregorian($from_date_array[0], $from_date_array[1], $from_date_array[2])) . ' 00:00:00'; + $from_datetime = implode('-', verta()->jalaliToGregorian($from_date_array[0], $from_date_array[1], $from_date_array[2])) . ' 00:00:00'; $to_datetime = Carbon::now()->toDateString() . ' 23:59:59'; if (auth()->user()->hasPermissionTo('show-fast-react')) { diff --git a/app/Models/RoadObservationHistory.php b/app/Models/RoadObservationHistory.php index 320353bc..62d1b777 100644 --- a/app/Models/RoadObservationHistory.php +++ b/app/Models/RoadObservationHistory.php @@ -2,10 +2,13 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class RoadObservationHistory extends Model { + use HasFactory; + protected $guarded = []; /** diff --git a/app/Models/RoadObserved.php b/app/Models/RoadObserved.php index 209d9dc0..54fd8c29 100644 --- a/app/Models/RoadObserved.php +++ b/app/Models/RoadObserved.php @@ -2,10 +2,13 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class RoadObserved extends Model { + use HasFactory; + protected $fillable = [ 'AutoID', 'Title', diff --git a/database/factories/RoadObservationHistoryFactory.php b/database/factories/RoadObservationHistoryFactory.php new file mode 100644 index 00000000..355054aa --- /dev/null +++ b/database/factories/RoadObservationHistoryFactory.php @@ -0,0 +1,23 @@ + + */ +class RoadObservationHistoryFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'id' => $this->faker->numberBetween(1, 10), + ]; + } +} diff --git a/database/factories/RoadObservedFactory.php b/database/factories/RoadObservedFactory.php new file mode 100644 index 00000000..d5012361 --- /dev/null +++ b/database/factories/RoadObservedFactory.php @@ -0,0 +1,23 @@ + + */ +class RoadObservedFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'Title' => $this->faker->numerify, + ]; + } +} diff --git a/tests/Feature/V2/Dashboard/RoadObservation/CountTest.php b/tests/Feature/V2/Dashboard/RoadObservation/CountTest.php new file mode 100644 index 00000000..5daa83c5 --- /dev/null +++ b/tests/Feature/V2/Dashboard/RoadObservation/CountTest.php @@ -0,0 +1,232 @@ +has(Permission::factory([ + 'type' => $this->faker->name + ])) + ->create(); + + $response = $this->actingAs($user)->getJson("/v2/road_observations/count"); + + $response->assertForbidden(); + } + + public function test_user_can_see_data_for_fast_react_permission(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'show-fast-react', + 'type' => 'fastreact' + ])) + ->create(); + + $roadObserved = RoadObserved::factory() + ->sequence( + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ) + ->count(7) + ->create(); + + $response = $this->actingAs($user)->getJson("/v2/road_observations/count"); + + $response->assertOk() + ->assertJsonStructure([ + "data" => [ + '*' => [ + "done", + "pending" + ] + ], + "status" + ]); + } + + public function test_user_can__not_see_data_for_fast_react_province_without_province_id(): void + { + $permission = Permission::factory() + ->create([ + 'name' => 'show-fast-react' + ]); + + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'show-fast-react-province', + 'type' => 'fastreact', + ])) + ->create(); + + $roadObserved = RoadObserved::factory() + ->sequence( + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ) + ->count(7) + ->create(); + + $response = $this->actingAs($user)->getJson("/v2/road_observations/count"); + + $response->assertStatus(400) + ->assertExactJson([ + 'message' => 'استانی برای شما در سامانه مشخص نشده است!' + ]); + } + + public function test_user_can_see_data_for_fast_react_province_permission(): void + { + $permission = Permission::factory() + ->create([ + 'name' => 'show-fast-react' + ]); + + $province = Province::factory()->create(); + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'show-fast-react-province', + 'type' => 'fastreact', + ])) + ->create([ + 'province_id' => $province->id + ]); + + $roadObserved = RoadObserved::factory() + ->sequence( + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ) + ->count(7) + ->create(); + + $response = $this->actingAs($user)->getJson("/v2/road_observations/count"); + + $response->assertOk() + ->assertJsonStructure([ + "data" => [ + '*' => [ + "done", + "pending" + ] + ], + "status" + ]); + } + + public function test_user_can__not_see_data_for_fast_react_city_without_city_id(): void + { + $permission = Permission::factory() + ->sequence( + ['name' => 'show-fast-react'], + ['name' => 'show-fast-react-province'], + ) + ->count(2) + ->create(); + + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'show-fast-react-city', + 'type' => 'fastreact', + ])) + ->create(); + + $roadObserved = RoadObserved::factory() + ->sequence( + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ) + ->count(7) + ->create(); + + $response = $this->actingAs($user)->getJson("/v2/road_observations/count"); + + $response->assertStatus(400) + ->assertExactJson([ + 'message' => 'شهری برای شما در سامانه مشخص نشده است!' + ]); + } + + public function test_user_can_see_data_for_fast_react_city_permission(): void + { + $permission = Permission::factory() + ->sequence( + ['name' => 'show-fast-react'], + ['name' => 'show-fast-react-province'], + ) + ->count(2) + ->create(); + + $city = City::factory()->create(); + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'show-fast-react-city', + 'type' => 'fastreact', + ])) + ->create([ + 'city_id' => $city->id + ]); + + $roadObserved = RoadObserved::factory() + ->sequence( + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ['rms_status' => $this->faker->numberBetween(0, 1)], + ) + ->count(7) + ->create(); + + $response = $this->actingAs($user)->getJson("/v2/road_observations/count"); + + $response->assertOk() + ->assertJsonStructure([ + "data" => [ + '*' => [ + "done", + "pending" + ] + ], + "status" + ]); + } +} diff --git a/tests/Feature/V2/Dashboard/RoadObservation/ReferTest.php b/tests/Feature/V2/Dashboard/RoadObservation/ReferTest.php new file mode 100644 index 00000000..74113a8b --- /dev/null +++ b/tests/Feature/V2/Dashboard/RoadObservation/ReferTest.php @@ -0,0 +1,193 @@ +create(); + + $roadObserved = RoadObserved::factory()->create(); + + $response = $this->actingAs($user)->postJson("/v2/road_observations/refer/{$roadObserved->id}"); + + $response->assertUnprocessable() + ->assertInvalid([ + 'edarate_shahri_id' => __('validation.required', ['attribute' => 'edarate shahri id']) + ]); + } + + public function test_start_edarate_shahri_id_should_be_numeric(): void + { + $user = User::factory()->create(); + + $roadObserved = RoadObserved::factory()->create(); + + $response = $this->actingAs($user)->postJson("/v2/road_observations/refer/{$roadObserved->id}", [ + 'edarate_shahri_id' => $this->faker->name + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'edarate_shahri_id' => __('validation.numeric', ['attribute' => 'edarate shahri id']) + ]); + } + + public function test_start_refer_description_is_required(): void + { + $user = User::factory()->create(); + + $roadObserved = RoadObserved::factory()->create(); + + $response = $this->actingAs($user)->postJson("/v2/road_observations/refer/{$roadObserved->id}"); + + $response->assertUnprocessable() + ->assertInvalid([ + 'refer_description' => __('validation.required', ['attribute' => 'refer description']) + ]); + } + + public function test_start_refer_description_should_be_string(): void + { + $user = User::factory()->create(); + + $roadObserved = RoadObserved::factory()->create(); + + $response = $this->actingAs($user)->postJson("/v2/road_observations/refer/{$roadObserved->id}", [ + 'refer_description' => $this->faker->numberBetween(1, 10) + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'refer_description' => __('validation.string', ['attribute' => 'refer description']) + ]); + } + + public function test_rms_status_should_be_0_to_access(): void + { + $user = User::factory()->create(); + + $roadObserved = RoadObserved::factory()->create([ + 'rms_status' => $this->faker->numberBetween(1, 10) + ]); + + $response = $this->actingAs($user)->postJson("/v2/road_observations/refer/{$roadObserved->id}", [ + 'refer_description' => $this->faker->name, + 'edarate_shahri_id' => $this->faker->numberBetween(1, 10) + ]); + + $response->assertForbidden() + ->assertExactJson([ + 'message' => 'access to requested resource is forbidden.' + ]); + } + + public function test_user_can_refer_the_road_observation(): void + { + $user = User::factory()->create(); + + $roadObserved = RoadObserved::factory()->create([ + 'rms_status' => 0 + ]); + + $logList = LogList::factory()->create([ + 'log_unique_code' => 1037 + ]); + + $edarate_shahri = EdarateShahri::factory()->create(); + $refer_description = $this->faker->name; + + $response = $this->actingAs($user)->postJson("/v2/road_observations/refer/{$roadObserved->id}", [ + 'refer_description' => $refer_description, + 'edarate_shahri_id' => $edarate_shahri->id + ]); + + $response->assertOk() + ->assertExactJson([ + 'status' => 'succeed', + 'message' => '', + 'data' => [ + "AutoID" => $roadObserved->AutoID, + "Description" => $roadObserved->Description, + "EndDate" => $roadObserved->EndDate, + "EndTime" => $roadObserved->EndTime, + "EndTime_DateTime" => $roadObserved->EndTime_DateTime, + "EventTypeTitle" => $roadObserved->EventTypeTitle, + "FeatureTypeTitle" => $roadObserved->FeatureTypeTitle, + "MobileForSendEventSms" => $roadObserved->MobileForSendEventSms, + "ProvinceName" => $roadObserved->ProvinceName, + "StartDate" => $roadObserved->StartDate, + "StartTime" => $roadObserved->StartTime, + "StartTime_DateTime" => $roadObserved->StartTime_DateTime, + "StartTime_DateTime_fa" => $roadObserved->StartTime_DateTime_fa, + "Title" => $roadObserved->Title, + "TownName" => $roadObserved->TownName, + "WeatherName" => $roadObserved->WeatherName, + "XLAM" => $roadObserved->XLAM, + "YLAM" => $roadObserved->YLAM, + "city_fa" => $roadObserved->city_fa, + "city_id" => $roadObserved->city_id, + "created_at" => $roadObserved->created_at, + "edarate_shahri_id" => $edarate_shahri->id, + "fk_Country" => $roadObserved->fk_Country, + "fk_EventType" => $roadObserved->fk_EventType, + "fk_FeatureType" => $roadObserved->fk_FeatureType, + "fk_Province" => $roadObserved->fk_Province, + "fk_RegisteredEventMessage" => $roadObserved->fk_RegisteredEventMessage, + "fk_Town" => $roadObserved->fk_Town, + "fk_Weather" => $roadObserved->fk_Weather, + "handling_way_id" => $roadObserved->handling_way_id, + "id" => $roadObserved->id, + "image_after" => $roadObserved->image_after, + "image_before" => $roadObserved->image_before, + "lat" => $roadObserved->lat, + "lng" => $roadObserved->lng, + "observed_way_id" => $roadObserved->observed_way_id, + "province_fa" => $roadObserved->province_fa, + "province_id" => $roadObserved->province_id, + "refer_description" => $roadObserved->refer_description, + "restore_description" => $roadObserved->restore_description, + "rms_city_id" => $roadObserved->rms_city_id, + "rms_description" => $roadObserved->rms_description, + "rms_end_latlng" => $roadObserved->rms_end_latlng, + "rms_last_activity" => $roadObserved->rms_last_activity, + "rms_last_activity_fa" => $roadObserved->rms_last_activity_fa, + "rms_province_id" => $roadObserved->rms_province_id, + "rms_start_latlng" => $roadObserved->rms_start_latlng, + "rms_status" => $roadObserved->rms_status, + "status" => $roadObserved->status, + "status_fa" => $roadObserved->status_fa, + "supervising_time" => $roadObserved->supervising_time, + "supervisor_description" => $roadObserved->supervisor_description, + "supervisor_id" => $roadObserved->supervisor_id, + "supervisor_name" => $roadObserved->supervisor_name, + "updated_at" => $roadObserved->updated_at, + "updated_at_fa" => $roadObserved->updated_at_fa + ] + ]); + + $this->assertDatabaseHas('road_observeds', [ + 'edarate_shahri_id' => $edarate_shahri->id + ]); + + $this->assertDatabaseHas('road_observation_histories', [ + 'id' => $roadObserved->id, + 'user_id' => $user->id, + 'action' => 'refer', + 'description' => $refer_description, + ]); + } +} diff --git a/tests/Feature/V2/Dashboard/RoadObservation/RestoreTest.php b/tests/Feature/V2/Dashboard/RoadObservation/RestoreTest.php new file mode 100644 index 00000000..d70b0f47 --- /dev/null +++ b/tests/Feature/V2/Dashboard/RoadObservation/RestoreTest.php @@ -0,0 +1,175 @@ +create([ + 'name' => 'restore-fast-react' + ]); + + $user = User::factory()->create(); + + $roadObserved = RoadObserved::factory()->create(); + + $response = $this->actingAs($user)->postJson("/v2/road_observations/restore/{$roadObserved->id}"); + + $response->assertForbidden(); + } + + public function test_restore_description_is_required(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'restore-fast-react' + ])) + ->create(); + + $roadObserved = RoadObserved::factory()->create(); + + $response = $this->actingAs($user)->postJson("/v2/road_observations/restore/{$roadObserved->id}"); + + $response->assertUnprocessable() + ->assertInvalid([ + 'restore_description' => __('validation.required', ['attribute' => 'restore description']) + ]); + } + + public function test_restore_description_should_be_string(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'restore-fast-react' + ])) + ->create(); + + $roadObserved = RoadObserved::factory()->create(); + + $response = $this->actingAs($user)->postJson("/v2/road_observations/restore/{$roadObserved->id}", [ + 'restore_description' => $this->faker->numberBetween(0, 1) + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'restore_description' => __('validation.string', ['attribute' => 'restore description']) + ]); + } + + public function test_can_restore_a_road_observation(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'restore-fast-react' + ])) + ->create(); + + $roadObserved = RoadObserved::factory()->create(); + + $logList = LogList::factory()->create([ + 'log_unique_code' => 1141 + ]); + + $restore_description = $this->faker->text; + + $response = $this->actingAs($user)->postJson("/v2/road_observations/restore/{$roadObserved->id}", [ + 'restore_description' => $restore_description + ]); + + $response->assertOk() + ->assertExactJson([ + 'status' => 'succeed', + 'message' => '', + 'data' => [ + "AutoID" => $roadObserved->AutoID, + "Description" => $roadObserved->Description, + "EndDate" => $roadObserved->EndDate, + "EndTime" => $roadObserved->EndTime, + "EndTime_DateTime" => $roadObserved->EndTime_DateTime, + "EventTypeTitle" => $roadObserved->EventTypeTitle, + "FeatureTypeTitle" => $roadObserved->FeatureTypeTitle, + "MobileForSendEventSms" => $roadObserved->MobileForSendEventSms, + "ProvinceName" => $roadObserved->ProvinceName, + "StartDate" => $roadObserved->StartDate, + "StartTime" => $roadObserved->StartTime, + "StartTime_DateTime" => $roadObserved->StartTime_DateTime, + "StartTime_DateTime_fa" => $roadObserved->StartTime_DateTime_fa, + "Title" => $roadObserved->Title, + "TownName" => $roadObserved->TownName, + "WeatherName" => $roadObserved->WeatherName, + "XLAM" => $roadObserved->XLAM, + "YLAM" => $roadObserved->YLAM, + "city_fa" => $roadObserved->city_fa, + "city_id" => $roadObserved->city_id, + "created_at" => $roadObserved->created_at, + "edarate_shahri_id" => null, + "fk_Country" => $roadObserved->fk_Country, + "fk_EventType" => $roadObserved->fk_EventType, + "fk_FeatureType" => $roadObserved->fk_FeatureType, + "fk_Province" => $roadObserved->fk_Province, + "fk_RegisteredEventMessage" => $roadObserved->fk_RegisteredEventMessage, + "fk_Town" => $roadObserved->fk_Town, + "fk_Weather" => $roadObserved->fk_Weather, + "handling_way_id" => $roadObserved->handling_way_id, + "id" => $roadObserved->id, + "image_after" => $roadObserved->image_after, + "image_before" => $roadObserved->image_before, + "lat" => $roadObserved->lat, + "lng" => $roadObserved->lng, + "observed_way_id" => $roadObserved->observed_way_id, + "province_fa" => $roadObserved->province_fa, + "province_id" => $roadObserved->province_id, + "refer_description" => $roadObserved->refer_description, + "restore_description" => $roadObserved->restore_description, + "rms_city_id" => $roadObserved->rms_city_id, + "rms_description" => $roadObserved->rms_description, + "rms_end_latlng" => $roadObserved->rms_end_latlng, + "rms_last_activity" => $roadObserved->rms_last_activity, + "rms_last_activity_fa" => $roadObserved->rms_last_activity_fa, + "rms_province_id" => $roadObserved->rms_province_id, + "rms_start_latlng" => $roadObserved->rms_start_latlng, + "rms_status" => 0, + "status" => $roadObserved->status, + "status_fa" => $roadObserved->status_fa, + "supervising_time" => $roadObserved->supervising_time, + "supervisor_description" => $roadObserved->supervisor_description, + "supervisor_id" => $roadObserved->supervisor_id, + "supervisor_name" => $roadObserved->supervisor_name, + "updated_at" => null, + "updated_at_fa" => $roadObserved->updated_at_fa + ] + ]); + + $this->assertDatabaseHas('road_observeds', [ + 'image_before' => null, + 'image_after' => null, + 'rms_last_activity' => null, + 'rms_last_activity_fa' => null, + 'updated_at_fa' => null, + 'updated_at' => null, + 'rms_status' => 0, + 'status' => null, + 'status_fa' => null, + ]); + + $this->assertDatabaseHas('road_observation_histories', [ + 'id' => $roadObserved->id, + 'user_id' => $user->id, + 'action' => 'restore', + 'description' => $restore_description, + ]); + } +} diff --git a/tests/Feature/V2/Dashboard/RoadObservation/verifyBySupervisorTest.php b/tests/Feature/V2/Dashboard/RoadObservation/verifyBySupervisorTest.php new file mode 100644 index 00000000..637ba070 --- /dev/null +++ b/tests/Feature/V2/Dashboard/RoadObservation/verifyBySupervisorTest.php @@ -0,0 +1,97 @@ +create(); + $roadObserved = RoadObserved::factory()->create(); + + $response = $this->actingAs($user)->postJson("/v2/road_observations/supervisor/cartable/verify/{$roadObserved->id}"); + + $response->assertForbidden(); + } + + public function test_verify_is_required(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'gate-supervise-road-observed' + ])) + ->create(); + $roadObserved = RoadObserved::factory()->create(); + + $response = $this->actingAs($user)->postJson("/v2/road_observations/supervisor/cartable/verify/{$roadObserved->id}"); + + $response->assertUnprocessable() + ->assertInvalid([ + 'verify' => __('validation.required', ['attribute' => 'verify']) + ]); + } + + public function test_verify_should_be_1_or_2(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'gate-supervise-road-observed' + ])) + ->create(); + $roadObserved = RoadObserved::factory()->create(); + + $response = $this->actingAs($user)->postJson("/v2/road_observations/supervisor/cartable/verify/{$roadObserved->id}", [ + 'verify' => $this->faker->numberBetween(3, 7) + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'verify' => __('validation.in', ['attribute' => 'verify']) + ]); + } + + public function test_road_observed_can_be_verified_by_supervisor(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'gate-supervise-road-observed' + ])) + ->create(); + + $roadObserved = RoadObserved::factory()->create(); + + $logList = LogList::factory()->create([ + 'log_unique_code' => 1138 + ]); + + $verify = $this->faker->numberBetween(1, 2); + + $response = $this->actingAs($user)->postJson("/v2/road_observations/supervisor/cartable/verify/{$roadObserved->id}", [ + 'verify' => $verify + ]); + + $response->assertOk() + ->assertExactJson([ + 'status' => 'succeed', + ]); + + $this->assertDatabaseHas('road_observeds', [ + 'status' => $verify, + 'supervisor_id' => $user->id, + 'supervisor_name' => $user->name, + 'supervising_time' => now(), + ]); + } +}