<?php

namespace Tests\Tenant;

use App\Facades\Settings;
use App\Models\FilterIndex;
use Carbon\Carbon;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Queue;
use Mtc\Filter\Contracts\FilterInstance;
use Mtc\MercuryDataModels\BodyStyleType;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Franchise;
use Mtc\MercuryDataModels\FuelType;
use Mtc\MercuryDataModels\Label;
use Mtc\MercuryDataModels\TransmissionType;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleAttribute;
use Mtc\MercuryDataModels\VehicleAttributeValue;
use Mtc\MercuryDataModels\VehicleAutoTraderData;
use Mtc\MercuryDataModels\VehicleFinance;
use Mtc\MercuryDataModels\VehicleLabel;
use Mtc\MercuryDataModels\VehicleMake;
use Mtc\MercuryDataModels\VehicleModel;
use Tests\FilterSettingSeed;
use Tests\SortingSettingSeed;
use Tests\TenantTestCase;

class VehicleFiltersTest extends TenantTestCase
{
    protected function setUp(): void
    {
        parent::setUp();
        Queue::fake();
    }

    public function testFilterByMake()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);
        $make = VehicleMake::factory()->create();
        $make2 = VehicleMake::factory()->create();
        Vehicle::factory(5)->create([
            'is_published' => true,
            'make_id' => $make->id,
        ]);
        Vehicle::factory(3)->create([
            'is_published' => true,
            'make_id' => $make2->id,
        ]);
        Vehicle::factory(10)->create([
            'is_published' => true,
            'make_id' => 100,
            ]);

        // No makes specified
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(18, $response->json('results.total'));

        // First Make
        $response2 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'make',
                        'value' => $make->slug,
                    ],
                ]
            ]);
        $response2->assertStatus(200);
        $this->assertEquals(5, $response2->json('results.total'));

        // Second make
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'make',
                        'value' => $make2->slug,
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(3, $response3->json('results.total'));

        // Both Makes
        $response4 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'make',
                        'value' => $make->slug,
                    ],
                    [
                        'type' => 'make',
                        'value' => $make2->slug,
                    ],
                ]
            ]);
        $response4->assertStatus(200);
        $this->assertEquals(8, $response4->json('results.total'));
    }

    public function testFilterByModel()
    {
        $this->seed(FilterSettingSeed::class);
        $model = VehicleModel::factory()->create();
        $model2 = VehicleModel::factory()->create();
        Vehicle::factory(5)->create([
            'is_published' => true,
            'model_id' => $model->id,
        ]);
        Vehicle::factory(3)->create([
            'is_published' => true,
            'model_id' => $model2->id,
        ]);
        Vehicle::factory(10)->create([
            'is_published' => true,
            'model_id' => 100,
        ]);

        // No  specified
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(18, $response->json('results.total'));

        // First
        $response2 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'model',
                        'value' => $model->slug,
                    ],
                ]
            ]);
        $response2->assertStatus(200);
        $this->assertEquals(5, $response2->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'model',
                        'value' => $model2->slug,
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(3, $response3->json('results.total'));

        // Both
        $response4 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'model',
                        'value' => $model->slug,
                    ],
                    [
                        'type' => 'model',
                        'value' => $model2->slug,
                    ],
                ]
            ]);
        $response4->assertStatus(200);
        $this->assertEquals(8, $response4->json('results.total'));
    }

    public function testFilterByCategory()
    {
        $this->seed(FilterSettingSeed::class);

        $vehicle1 = Vehicle::factory()->create([
            'is_published' => true
        ]);

        $vehicle2 = Vehicle::factory()->create([
            'is_published' => true
        ]);

        $vehicle3 = Vehicle::factory()->create([
            'is_published' => true
        ]);

        $vehicle_attribute = VehicleAttribute::query()
            ->firstOrCreate(
                [
                    'model' => 'vehicle',
                    'name' => 'vehicle_category',
                ],
                [
                    'slug' => 'vehicle_category',
                    'type' => 'text',
                    'validation' => [],
                    'data' => []
                ]
            );

        VehicleAttributeValue::query()->updateOrCreate(
            [
                'attribute_id' => $vehicle_attribute->id,
                'owner_id' => $vehicle1->id,
                'owner_type' => 'vehicle',
            ],
            [
                'value' => 'foo',
                'slug' => $vehicle_attribute->slug,
                'type' => 'text'
            ]
        );

        VehicleAttributeValue::query()->updateOrCreate(
            [
                'attribute_id' => $vehicle_attribute->id,
                'owner_id' => $vehicle2->id,
                'owner_type' => 'vehicle',
            ],
            [
                'value' => 'baz',
                'slug' => $vehicle_attribute->slug,
                'type' => 'text'
            ]
        );

        VehicleAttributeValue::query()->updateOrCreate(
            [
                'attribute_id' => $vehicle_attribute->id,
                'owner_id' => $vehicle3->id,
                'owner_type' => 'vehicle',
            ],
            [
                'value' => 'baz',
                'slug' => $vehicle_attribute->slug,
                'type' => 'text'
            ]
        );

        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'vehicle_category',
                        'value' => 'foo',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(1, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'vehicle_category',
                        'value' => 'baz',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(2, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'vehicle_category',
                        'value' => 'foo',
                    ],
                    [
                        'type' => 'vehicle_category',
                        'value' => 'baz',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));
    }

    public function testFilterByAge()
    {
        $this->seed(FilterSettingSeed::class);
        Vehicle::factory(5)->create([
            'is_published' => true,
            'manufacture_year' => 2021,
        ]);
        Vehicle::factory(3)->create([
            'is_published' => true,
            'manufacture_year' => 2015,
        ]);
        Vehicle::factory(10)->create([
            'is_published' => true,
            'manufacture_year' => 2009,
        ]);

        // No makes specified
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(18, $response->json('results.total'));

        // First
        $response2 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'age',
                        'value' => 2020,
                    ],
                    [
                        'type' => 'age',
                        'value' => 2021,
                    ],
                    [
                        'type' => 'age',
                        'value' => 2022,
                    ],
                ]
            ]);
        $response2->assertStatus(200);
        $this->assertEquals(5, $response2->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'age',
                        'value' => 2015,
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(3, $response3->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'age',
                        'value' => 2021
                    ],
                    [
                        'type' => 'age',
                        'value' => 2015
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(8, $response3->json('results.total'));
    }

    public function testFilterByBodyStyle()
    {
        $this->seed(FilterSettingSeed::class);
        $body_style = BodyStyleType::factory()->create();
        $body_style->filterIndex()->updateOrCreate(['slug' => $body_style->slug]);
        $body_style2 = BodyStyleType::factory()->create();
        $body_style2->filterIndex()->updateOrCreate(['slug' => $body_style2->slug]);

        Vehicle::factory(5)->create([
            'is_published' => true,
            'body_style_id' => $body_style->id,
        ]);
        Vehicle::factory(3)->create([
            'is_published' => true,
            'body_style_id' => $body_style2->id,
        ]);
        Vehicle::factory(10)->create([
            'is_published' => true,
            'body_style_id' => 100,
        ]);

        // No specified
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(18, $response->json('results.total'));

        // First
        $response2 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'body_type',
                        'value' => $body_style->slug,
                    ],
                ]
            ]);
        $response2->assertStatus(200);
        $this->assertEquals(5, $response2->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'body_type',
                        'value' => $body_style2->slug,
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(3, $response3->json('results.total'));

        // Both
        $response4 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'body_type',
                        'value' => $body_style->slug,
                    ],
                    [
                        'type' => 'body_type',
                        'value' => $body_style2->slug,
                    ],
                ]
            ]);
        $response4->assertStatus(200);
        $this->assertEquals(8, $response4->json('results.total'));
    }

    public function testFilterByColour()
    {
        $this->seed(FilterSettingSeed::class);

        // Adding filter index for matching, due to queue fake it is not created automatically
        FilterIndex::create([
            'slug' => 'red',
            'name' => 'red',
            'filter_type' => 'colour',
            'filter_id' => 'red',
        ]);
        FilterIndex::create([
            'slug' => 'black',
            'name' => 'black',
            'filter_type' => 'colour',
            'filter_id' => 'black',
        ]);

        Vehicle::factory(5)->create([
            'is_published' => true,
            'colour' => 'red',
        ]);
        Vehicle::factory(3)->create([
            'is_published' => true,
            'colour' => 'black',
        ]);
        Vehicle::factory(10)->create([
            'is_published' => true,
            'colour' => 'silver',
        ]);

        // No makes specified
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(18, $response->json('results.total'));

        // First
        $response2 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'colour',
                        'value' => 'red',
                    ],
                ]
            ]);
        $response2->assertStatus(200);
        $this->assertEquals(5, $response2->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'colour',
                        'value' => 'black',
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(3, $response3->json('results.total'));

        // Both
        $response4 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'colour',
                        'value' => 'red',
                    ],
                    [
                        'type' => 'colour',
                        'value' => 'black',
                    ],
                ]
            ]);
        $response4->assertStatus(200);
        $this->assertEquals(8, $response4->json('results.total'));
    }

    /*
     * commenting out this test, as the filter is not currently included in config
    public function testFilterByDoorCount()
    {
        $this->seed(FilterSettingSeed::class);
        Vehicle::factory(5)->create([
            'is_published' => true,
            'door_count' => 4,
        ]);
        Vehicle::factory(3)->create([
            'is_published' => true,
            'door_count' => 5,
        ]);
        Vehicle::factory(10)->create([
            'is_published' => true,
            'door_count' => 3,
        ]);

        // No makes specified
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(18, $response->json('results.total'));

        // First
        $response2 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'door_count',
                        'value' => 4,
                    ],
                ]
            ]);
        $response2->assertStatus(200);
        $this->assertEquals(5, $response2->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'door_count',
                        'value' => 5,
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(3, $response3->json('results.total'));

        // Both
        $response4 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'door_count',
                        'value' => 4,
                    ],
                    [
                        'type' => 'door_count',
                        'value' => 5,
                    ],
                ]
            ]);
        $response4->assertStatus(200);
        $this->assertEquals(8, $response4->json('results.total'));
    }
    */

    /*
     * commenting out this test, as the filter is not currently included in config
    public function testFilterByEngineSize()
    {
        $this->seed(FilterSettingSeed::class);
        Vehicle::factory(5)->create([
            'is_published' => true,
            'engine_size_cc' => 1400,
        ]);
        Vehicle::factory(3)->create([
            'is_published' => true,
            'engine_size_cc' => 1999,
        ]);
        Vehicle::factory(10)->create([
            'is_published' => true,
            'engine_size_cc' => 2500,
        ]);

        // No makes specified
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(18, $response->json('results.total'));

        // First
        $response2 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'engine_size',
                        'value' =>  1500,
                    ],
                ]
            ]);
        $response2->assertStatus(200);
        $this->assertEquals(5, $response2->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'engine_size',
                        'value' => 2000,
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(8, $response3->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'engine_size',
                        'value' =>  2000,
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(8, $response3->json('results.total'));
    }
    */

    public function testFilterByFuelType()
    {
        $this->seed(FilterSettingSeed::class);
        $fuel_type = FuelType::factory()->create();
        $fuel_type->filterIndex()->updateOrCreate(['slug' => $fuel_type->slug]);
        $fuel_type2 = FuelType::factory()->create();
        $fuel_type2->filterIndex()->updateOrCreate(['slug' => $fuel_type2->slug]);
        Vehicle::factory(5)->create([
            'is_published' => true,
            'fuel_type_id' => $fuel_type->id,
        ]);
        Vehicle::factory(3)->create([
            'is_published' => true,
            'fuel_type_id' => $fuel_type2->id,
        ]);
        Vehicle::factory(10)->create([
            'is_published' => true,
            'fuel_type_id' => 100,
        ]);

        // No makes specified
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(18, $response->json('results.total'));

        // First Make
        $response2 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'fuel_type',
                        'value' => $fuel_type->slug,
                    ],
                ]
            ]);
        $response2->assertStatus(200);
        $this->assertEquals(5, $response2->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'fuel_type',
                        'value' => $fuel_type2->slug,
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(3, $response3->json('results.total'));

        // Both
        $response4 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'fuel_type',
                        'value' => $fuel_type->slug,
                    ],
                    [
                        'type' => 'fuel_type',
                        'value' => $fuel_type2->slug,
                    ],
                ]
            ]);
        $response4->assertStatus(200);
        $this->assertEquals(8, $response4->json('results.total'));
    }

    public function testFilterByLocation()
    {
        $this->seed(FilterSettingSeed::class);
        $location = Dealership::factory()->create();
        $location2 = Dealership::factory()->create();
        Vehicle::factory(5)->create([
            'is_published' => true,
            'dealership_id' => $location->id,
        ]);
        Vehicle::factory(3)->create([
            'is_published' => true,
            'dealership_id' => $location2->id,
        ]);
        Vehicle::factory(10)->create([
            'is_published' => true,
            'dealership_id' => 100,
        ]);

        // No makes specified
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(18, $response->json('results.total'));

        // First
        $response2 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'location',
                        'value' => $location->slug,
                    ],
                ]
            ]);
        $response2->assertStatus(200);
        $this->assertEquals(5, $response2->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'location',
                        'value' => $location2->slug,
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(3, $response3->json('results.total'));

        // Both
        $response4 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'location',
                        'value' => $location->slug,
                    ],
                    [
                        'type' => 'location',
                        'value' => $location2->slug,
                    ],
                ]
            ]);
        $response4->assertStatus(200);
        $this->assertEquals(8, $response4->json('results.total'));
    }

    /*
     * commenting out this test, as the filter is not currently included in config
    public function testFilterByMileage()
    {
        $this->seed(FilterSettingSeed::class);
        Settings::make([
            'tab' => 'foo',
            'section' => 'automotive',
            'group' => 'General',
            'name' => 'Distance measurement',
            'config_key' => 'automotive-distance_measurement',
            'type' => 'string',
            'value' => 'mi',
        ]);
        Vehicle::factory(5)->create([
            'is_published' => true,
            'odometer_mi' => 60000,
        ]);
        Vehicle::factory(3)->create([
            'is_published' => true,
            'odometer_mi' => 45000,
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'odometer_mi' => 48000,
        ]);
        Vehicle::factory(10)->create([
            'is_published' => true,
            'odometer_mi' => 25000,
        ]);

        // No makes specified
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(19, $response->json('results.total'));

        // First
        $response2 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'mileage',
                        'value' =>  30000,
                    ],
                ]
            ]);
        $response2->assertStatus(200);
        $this->assertEquals(10, $response2->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'mileage',
                        'value' => 47500,
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(13, $response3->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'mileage',
                        'value' => 50000,
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(14, $response3->json('results.total'));
    }
    */

    /*
     * commenting out this test, as the filter is not currently included in config
    public function testFilterByPrice()
    {
        $this->seed(FilterSettingSeed::class);
        Vehicle::factory(5)->create([
            'is_published' => true,
            'price' => 10200,
            'monthly_price' => 250,
        ]);
        Vehicle::factory(3)->create([
            'is_published' => true,
            'price' => 8500,
            'monthly_price' => 170,
        ]);
        Vehicle::factory(10)->create([
            'is_published' => true,
            'price' => 5000,
            'monthly_price' => 130,
        ]);

        // No makes specified
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(18, $response->json('results.total'));

        // First
        $response2 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'price',
                        'value' => [
                            'payment_type' => 'full',
                            'min' => 10000,
                            'max' => 12500,
                        ],
                    ],
                ]
            ]);
        $response2->assertStatus(200);
        $this->assertEquals(5, $response2->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'price',
                        'value' => [
                            'payment_type' => 'full',
                            'min' => 7500,
                            'max' => 10000,
                        ],
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(3, $response3->json('results.total'));

    }
    */

    /*
     * commenting out this test, as the filter is not currently included in config
    public function testFilterBySeatCount()
    {
        $this->seed(FilterSettingSeed::class);
        Vehicle::factory(5)->create([
            'is_published' => true,
            'seats' => 4,
        ]);
        Vehicle::factory(3)->create([
            'is_published' => true,
            'seats' => 2,
        ]);
        Vehicle::factory(10)->create([
            'is_published' => true,
            'seats' => 5,
        ]);

        // No makes specified
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(18, $response->json('results.total'));

        // First
        $response2 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'seats',
                        'value' => 4,
                    ],
                ]
            ]);
        $response2->assertStatus(200);
        $this->assertEquals(5, $response2->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'seats',
                        'value' => 2,
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(3, $response3->json('results.total'));

        // Both
        $response4 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'seats',
                        'value' => 4,
                    ],
                    [
                        'type' => 'seats',
                        'value' => 2,
                    ],
                ]
            ]);
        $response4->assertStatus(200);
        $this->assertEquals(8, $response4->json('results.total'));
    }
    */

    public function testFilterByTransmission()
    {
        $this->seed(FilterSettingSeed::class);
        $transmission = TransmissionType::factory()->create(['slug' => 'foo']);
        $transmission->filterIndex()->updateOrCreate(['slug' => $transmission->slug]);
        $transmission2 = TransmissionType::factory()->create(['slug' => 'faz']);
        $transmission2->filterIndex()->updateOrCreate(['slug' => $transmission2->slug]);
        Vehicle::factory(5)->create([
            'is_published' => true,
            'transmission_id' => $transmission->id,
        ]);
        Vehicle::factory(3)->create([
            'is_published' => true,
            'transmission_id' => $transmission2->id,
        ]);
        Vehicle::factory(10)->create([
            'is_published' => true,
            'transmission_id' => 100,
        ]);

        // No makes specified
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(18, $response->json('results.total'));

        // First
        $response2 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'transmission',
                        'value' => $transmission->slug,
                    ],
                ]
            ]);
        $response2->assertStatus(200);
        $this->assertEquals(5, $response2->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'transmission',
                        'value' => $transmission2->slug,
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(3, $response3->json('results.total'));

        // Both
        $response4 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'transmission',
                        'value' => $transmission->slug,
                    ],
                    [
                        'type' => 'transmission',
                        'value' => $transmission2->slug,
                    ],
                ]
            ]);
        $response4->assertStatus(200);
        $this->assertEquals(8, $response4->json('results.total'));
    }

    public function testFilterBySearchTerm()
    {
        $this->markTestSkipped('Unable to test fulltext search in sqlite');
    }

    public function testFilterByMultipleFilters()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);
        $transmission = TransmissionType::factory()->create();
        $transmission->filterIndex()->updateOrCreate(['slug' => $transmission->slug]);
        $transmission2 = TransmissionType::factory()->create();
        $transmission2->filterIndex()->updateOrCreate(['slug' => $transmission2->slug]);
        Vehicle::factory(3)->create([
            'transmission_id' => $transmission->id,
            'colour' => 'blue',
            'is_published' => true,
        ]);
        Vehicle::factory(4)->create([
            'transmission_id' => $transmission->id,
            'colour' => 'red',
            'is_published' => true,
        ]);
        Vehicle::factory(5)->create([
            'transmission_id' => $transmission2->id,
            'colour' => 'blue',
            'is_published' => true,
        ]);
        Vehicle::factory(6)->create([
            'transmission_id' => $transmission2->id,
            'colour' => 'red',
            'is_published' => true,
        ]);
        Vehicle::factory(10)->create([
            'is_published' => true,
            'transmission_id' => 100,
        ]);
        // Adding filter index for matching, due to queue fake it is not created automatically
        FilterIndex::create([
            'slug' => 'red',
            'name' => 'red',
            'filter_type' => 'colour',
            'filter_id' => 'red',
        ]);
        FilterIndex::create([
            'slug' => 'blue',
            'name' => 'blue',
            'filter_type' => 'colour',
            'filter_id' => 'blue',
        ]);


        // No makes specified
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(28, $response->json('results.total'));

        // First
        $response2 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'transmission',
                        'value' => $transmission->slug,
                    ],
                    [
                        'type' => 'colour',
                        'value' => 'red',
                    ],
                ]
            ]);
        $response2->assertStatus(200);
        $this->assertEquals(4, $response2->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'transmission',
                        'value' => $transmission->slug,
                    ],
                    [
                        'type' => 'colour',
                        'value' => 'blue',
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(3, $response3->json('results.total'));

        // Both
        $response4 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'transmission',
                        'value' => $transmission->slug,
                    ],
                    [
                        'type' => 'transmission',
                        'value' => $transmission2->slug,
                    ],
                    [
                        'type' => 'colour',
                        'value' => 'red',
                    ],
                ]
            ]);
        $response4->assertStatus(200);
        $this->assertEquals(10, $response4->json('results.total'));
    }
    public function testFilterByConsumption()
    {
        $this->seed(FilterSettingSeed::class);
        Vehicle::factory(5)->create([
            'is_published' => true,
            'mpg' => 21,
        ]);
        Vehicle::factory(3)->create([
            'is_published' => true,
            'mpg' => 40,
        ]);
        Vehicle::factory(10)->create([
            'is_published' => true,
            'mpg' => 55,
        ]);

        // No makes specified
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(18, $response->json('results.total'));

        // First
        $response2 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'consumption',
                        'value' => 50,
                    ],
                ]
            ]);
        $response2->assertStatus(200);
        $this->assertEquals(10, $response2->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'consumption',
                        'value' => 25,
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(13, $response3->json('results.total'));

        // Second
        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'consumption',
                        'value' => 20
                    ],
                    [
                        'type' => 'consumption',
                        'value' => 40
                    ],
                ]
            ]);
        $response3->assertStatus(200);
        $this->assertEquals(18, $response3->json('results.total'));
    }

    public function testFiltersAreEnabledBySettings()
    {
        $this->seed(FilterSettingSeed::class);
        $filters = App::make(FilterInstance::class)->getFilters();
        $this->assertEquals(31, $filters->count());

        Settings::update('automotive-vehicle-filters-colour', false);
        Settings::update('automotive-vehicle-filters-fuel_type', false);
        $filters = App::make(FilterInstance::class)->getFilters();
        $this->assertEquals(29, $filters->count());
        $this->assertArrayNotHasKey('colour', $filters);
        $this->assertArrayNotHasKey('fuel_type', $filters);
    }

    public function testFilteWidget()
    {
        $this->seed(FilterSettingSeed::class);
        $make = VehicleMake::factory()->create();
        $make2 = VehicleMake::factory()->create();
        Vehicle::factory(5)->create([
            'is_published' => true,
            'make_id' => $make->id,
        ]);
        Vehicle::factory(3)->create([
            'is_published' => true,
            'make_id' => $make2->id,
        ]);
        Vehicle::factory(10)->create([
            'is_published' => true,
            'make_id' => 100,
        ]);

        // No makes specified
        $response = $this
            ->postJson(route('vehicles.widget'));

        $response->assertStatus(200);
        $this->assertTrue(count($response->json('filters')) > 1);

        $response = $this
            ->postJson(route('vehicles.widget'), [
                'only_filters' => [
                    'make'
                ]
            ]);
        $response->assertStatus(200);
        $this->assertArrayHasKey('make', $response->json('filters'));
    }

    public function testPricePointFilter()
    {
        $this->seed(FilterSettingSeed::class);


        // create some testing data

        Vehicle::factory()->create([
            'id' => 123,
            'is_published' => true,
        ]);

        Vehicle::factory()->create([
            'id' => 111,
            'is_published' => true
        ]);

        VehicleAutoTraderData::factory()->create([
           'vehicle_id' => 123,
           'price_point' => 'Fair'
        ]);

        VehicleAutoTraderData::factory()->create([
            'vehicle_id' => 111,
            'price_point' => 'Good'
        ]);

        // try search with no filters. Should bring back all of our example vehicles.
        $response = $this
            ->postJson(route('vehicles.index'));

        // test that call worked and brought back results
        $response->assertStatus(200);
        $this->assertEquals(2, $response->json('results.total'));

        $selected_price_point_filters = 0;

        foreach ($response->json('filters.price_point.results') as $filter_option) {
            if ($filter_option['selected']) {
                $selected_price_point_filters++;
            }
        }

        $this->assertEquals(0, $selected_price_point_filters);

        // search with a filter for one of the vehicles.
        // should return filtered vehicles.
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'price_point',
                        'value' => 'Good'
                    ]
                ]
            ]);

        // assert that the price point filter results match what we expect
        $response->assertStatus(200);
        $this->assertEquals(1, $response->json('results.total'));

        $selected_price_point_filters = 0;

        foreach ($response->json('filters.price_point.results') as $filter_option) {
            if ($filter_option['selected']) {
                $selected_price_point_filters++;
            }
        }

        $this->assertEquals(1, $selected_price_point_filters);

        // filter on a price point that does not belong to any vehicles.
        // should not return vehicles.
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'price_point',
                        'value' => 'Poor'
                    ]
                ]
            ]);

        // assert that the price point filter results match what we expect
        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));

        // test multiple filter selections
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'price_point',
                        'value' => 'Good'
                    ],
                    [
                        'type' => 'price_point',
                        'value' => 'Fair'
                    ]
                ]
            ]);

        // assert that the price point filter results match what we expect
        $response->assertStatus(200);
        $this->assertEquals(2, $response->json('results.total'));

        $selected_price_point_filters = 0;

        foreach ($response->json('filters.price_point.results') as $filter_option) {
            if ($filter_option['selected']) {
                $selected_price_point_filters++;
            }
        }

        $this->assertEquals(2, $selected_price_point_filters);
    }

    public function testMinimumPricePointFilter()
    {
        $this->seed(FilterSettingSeed::class);

        // create our testing data
        Vehicle::factory()->create([
            'id' => 123,
            'is_published' => true,
        ]);

        Vehicle::factory()->create([
            'id' => 456,
            'is_published' => true
        ]);

        Vehicle::factory()->create([
            'id' => 789,
            'is_published' => true
        ]);

        VehicleAutoTraderData::factory()->create([
            'vehicle_id' => 123,
            'price_point' => 'Fair'
        ]);

        VehicleAutoTraderData::factory()->create([
            'vehicle_id' => 456,
            'price_point' => 'Good'
        ]);

        VehicleAutoTraderData::factory()->create([
            'vehicle_id' => 789,
            'price_point' => 'Great'
        ]);

        Settings::make([
            'tab' => 'automotive',
            'section' => 'AutoTrader',
            'group' => 'Enriched vehicle data',
            'name' => 'Display price indicator when value is equal or better than',
            'config_key' => 'autotrader-show-price-indicator-min-value',
            'type' => 'string',
            'value' => 'Good',
            'min_tier' => 'pro',
            'order' => 22,
        ]);

        // try search with no filters. Should bring back all of our example vehicles.
        $response = $this
            ->postJson(route('vehicles.index'));

        // test that call worked and brought back results
        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));

        // get the list of price point filters returned by the search
        $available_price_point_selections = [];

        foreach ($response->json('filters.price_point.results') as $filter_option) {
            $available_price_point_selections[$filter_option['name']] = $filter_option['name'];
        }

        // assert that unwanted values were not returned (case sensitive)
        $this->assertArrayHasKey('Good', $available_price_point_selections);
        $this->assertArrayHasKey('Great', $available_price_point_selections);
        $this->assertArrayNotHasKey('Fair', $available_price_point_selections);
    }

    public function testPricePointFilterOptionOrder()
    {
        $this->seed(FilterSettingSeed::class);

        // create our testing data
        Vehicle::factory()->create([
            'id' => 123,
            'is_published' => true,
        ]);

        Vehicle::factory()->create([
            'id' => 456,
            'is_published' => true
        ]);

        Vehicle::factory()->create([
            'id' => 789,
            'is_published' => true
        ]);

        Vehicle::factory()->create([
            'id' => 999,
            'is_published' => true
        ]);

        VehicleAutoTraderData::factory()->create([
            'vehicle_id' => 123,
            'price_point' => 'Fair'
        ]);

        VehicleAutoTraderData::factory()->create([
            'vehicle_id' => 456,
            'price_point' => 'Good'
        ]);

        VehicleAutoTraderData::factory()->create([
            'vehicle_id' => 789,
            'price_point' => 'Great'
        ]);

        Settings::make([
            'tab' => 'automotive',
            'section' => 'AutoTrader',
            'group' => 'Enriched vehicle data',
            'name' => 'Display price indicator when value is equal or better than',
            'config_key' => 'autotrader-show-price-indicator-min-value',
            'type' => 'string',
            'value' => 'Fair',
            'min_tier' => 'pro',
            'order' => 22,
        ]);

        // try search with no filters. Should bring back all of our example vehicles.
        $response = $this
            ->postJson(route('vehicles.index'));

        // test that call worked and brought back results
        $response->assertStatus(200);
        $this->assertEquals(4, $response->json('results.total'));

        // get the list of price point filters returned by the search
        $available_price_point_selections = [];

        foreach ($response->json('filters.price_point.results') as $filter_option) {
            $available_price_point_selections[] = $filter_option['name'];
        }

        $this->assertEquals(3, count($available_price_point_selections));

        $this->assertEquals('Great', $available_price_point_selections[0]);
        $this->assertEquals('Good', $available_price_point_selections[1]);
        $this->assertEquals('Fair', $available_price_point_selections[2]);
    }

    public function testVehicleData()
    {
        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'autotrader-advert-performance',
            'value' => true,
            'type' => 'bool',
        ]);
        $this->seed();
        $this->seed(FilterSettingSeed::class);


        Vehicle::factory(5)->create([
            'is_published' => true,
            'available_date' => Carbon::now()->addDays(5)
        ]);

        // No makes specified
        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);
        $this->assertEquals(5, $response->json('results.total'));

        $this->assertArrayHasKey('autoTraderData', $response->json('results.data.0'));
        $this->assertArrayHasKey('dealership', $response->json('results.data.0'));
        $this->assertArrayHasKey('derivative', $response->json('results.data.0'));
        $this->assertArrayHasKey('finance_example', $response->json('results.data.0'));
        $this->assertArrayHasKey('fuel_type', $response->json('results.data.0'));
        $this->assertArrayHasKey('is_vat_applicable', $response->json('results.data.0'));
        $this->assertArrayHasKey('make', $response->json('results.data.0'));
        $this->assertArrayHasKey('manufacture_year', $response->json('results.data.0'));
        $this->assertArrayHasKey('model', $response->json('results.data.0'));
        $this->assertArrayHasKey('odometer_mi', $response->json('results.data.0'));
        $this->assertArrayHasKey('odometer_km', $response->json('results.data.0'));
        $this->assertArrayHasKey('original_price', $response->json('results.data.0'));
        $this->assertArrayHasKey('previous_price', $response->json('results.data.0'));
        $this->assertArrayHasKey('price', $response->json('results.data.0'));
        $this->assertArrayHasKey('rrp_price', $response->json('results.data.0'));
        $this->assertArrayHasKey('title', $response->json('results.data.0'));
        $this->assertArrayHasKey('transmission', $response->json('results.data.0'));
        $this->assertArrayHasKey('type', $response->json('results.data.0'));
        $this->assertArrayHasKey('custom', $response->json('results.data.0'));
        $this->assertArrayHasKey('age_identifier', $response->json('results.data.0'));
        $this->assertArrayHasKey('coming_soon', $response->json('results.data.0'));
        $this->assertArrayHasKey('reservation_amount', $response->json('results.data.0'));

        $this->assertTrue($response->json('results.data.0.coming_soon'));
    }

    public function testVehicleSavings()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'vehicle-savings-enabled-previous-price',
            'value' => true,
            'type' => 'bool',
        ]);

        Settings::make([
            'tab' => 'foo',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'vehicle-savings-enabled',
            'value' => true,
            'type' => 'boolean',
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'vehicle-savings-type',
            'value' => 'peter-vardy',
            'type' => 'string',
        ]);

        $dealership = Dealership::factory()->create([
            'id' => 1,
            'location_stock' => 'VE',
            'name' => 'Carz Edinburgh'
        ]);

        Vehicle::factory()->create([
            'id' => 123,
            'is_published' => true,
            'type' => 'car',
            'price' => 8000,
            'original_price' => 8000,
            'previous_price' => 9000,
            'dealership_id' => $dealership->id,
        ]);

        // No makes specified
        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);

        $this->assertEquals(1, $response->json('results.total'));
        $this->assertEquals(1000, $response->json('results.data.0.extra.saving_original_price'));
    }

    public function testPvEmptyPriceSavings()
    {
        Settings::make([
            'tab' => 'foo',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'vehicle-savings-enabled',
            'value' => true,
            'type' => 'boolean',
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'vehicle-savings-type',
            'value' => 'peter-vardy',
            'type' => 'string',
        ]);

        $dealership = Dealership::factory()->create([
            'id' => 1,
            'location_stock' => 'VE',
            'name' => 'Carz Edinburgh'
        ]);

        Vehicle::factory()->create([
            'is_published' => true,
            'type' => 'car',
            'price' => null,
            'dealership_id' => $dealership->id,
        ]);

        // No makes specified
        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);
    }

    public function testVehicleFinanceExample()
    {
        Settings::make([
            'tab' => 'Automotive',
            'section' => 'Filter',
            'group' => 'General',
            'name' => 'Load finance example for vehicle listing',
            'config_key' => 'vehicle-list-load-finance-example',
            'type' => 'boolean',
            'value' => true,
            'superadmin' => true,
            'min_tier' => 'standard',
            'description' => 'Enable loading finance example for lists of vehicles, such as search result page.<br/>',
            'order' => 0,
        ]);

        $vehicle = Vehicle::factory()->create([
            'is_published' => true,
        ]);

        VehicleFinance::factory()->create([
            'vehicle_id' => $vehicle->id,
            'finance_type' => 'HP',
            'monthly_price' => 123
        ]);

        VehicleFinance::factory()->create([
            'vehicle_id' => $vehicle->id,
            'finance_type' => 'PCP',
            'monthly_price' => 456
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);

        $this->assertEquals('HP', $response->json('results.data.0.finance_example.finance_type'));
        $this->assertEquals(123, $response->json('results.data.0.finance_example.monthly_price'));

        $this->assertArrayHasKey('monthly_price', $response->json('results.data.0.finance_example'));
        $this->assertArrayHasKey('apr', $response->json('results.data.0.finance_example'));
        $this->assertArrayHasKey('term', $response->json('results.data.0.finance_example'));
        $this->assertArrayHasKey('annual_mileage', $response->json('results.data.0.finance_example'));
        $this->assertArrayHasKey('cash_price', $response->json('results.data.0.finance_example'));
        $this->assertArrayHasKey('dealer_deposit', $response->json('results.data.0.finance_example'));
        $this->assertArrayHasKey('customer_deposit', $response->json('results.data.0.finance_example'));
        $this->assertArrayHasKey('total_deposit', $response->json('results.data.0.finance_example'));
        $this->assertArrayHasKey('payable_amount', $response->json('results.data.0.finance_example'));
        $this->assertArrayHasKey('option_to_purchase_fee', $response->json('results.data.0.finance_example'));
        $this->assertArrayHasKey('documentation_fee', $response->json('results.data.0.finance_example'));
    }

    public function testVehicleFinanceDisabled()
    {
        $vehicle = Vehicle::factory()->create([
            'is_published' => true,
        ]);

        VehicleFinance::factory()->create([
            'vehicle_id' => $vehicle->id,
            'finance_type' => 'HP',
            'monthly_price' => 123
        ]);

        VehicleFinance::factory()->create([
            'vehicle_id' => $vehicle->id,
            'finance_type' => 'PCP',
            'monthly_price' => 456
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);

        $this->assertEmpty($response->json('results.data.0.finance_example'));
    }

    public function testVehicleResultFranchise()
    {
        $this->seed(SortingSettingSeed::class);

        $franchise = Franchise::factory()->create([
            'name' => 'foo'
        ]);

        $dealership = Dealership::factory()->create([
            'franchise_id' => $franchise->id,
        ]);

        $dealership2 = Dealership::factory()->create();

        Vehicle::factory()->create([
            'dealership_id' => $dealership2->id,
            'is_published' => true,
            'price' => 456,
        ]);

        Vehicle::factory()->create([
            'is_published' => true,
            'price' => 789,
        ]);

        Vehicle::factory()->create([
            'dealership_id' => $dealership->id,
            'is_published' => true,
            'price' => 123,
        ]);

        $response = $this
            ->postJson(route('vehicles.index'), [
                'sort_by' => 'price-asc',
            ]);

        $response->assertStatus(200);

        $this->assertEmpty($response->json('results.data.0.finance_example'));
        $this->assertEquals(3, $response->json('results.total'));
        $this->assertEquals(123, $response->json('results.data.0.price'));
        $this->assertNotNull($response->json('results.data.0.dealership'));
        $this->assertNotNull($response->json('results.data.0.dealership.franchise'));
        $this->assertNotNull($response->json('results.data.0.dealership.franchise.name'));
        $this->assertEquals($franchise->name, $response->json('results.data.0.dealership.franchise.name'));
        $this->assertArrayNotHasKey('franchise', $response->json('results.data.1.dealership'));
    }

    public function testLabelsNullType()
    {
        Settings::make([
            'tab' => 'foo',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'vehicle-labels-enabled',
            'value' => true,
            'type' => 'boolean',
        ]);

        $this->seed();
        $this->seed(FilterSettingSeed::class);

        $label_applicable = Label::factory()->create([
            'name' => 'applicable',
            'type' => null
        ]);

        $vehicle_applicable = Vehicle::factory()->create([
            'is_published' => true,
            'price' => 123
        ]);

        VehicleLabel::create([
            'vehicle_id' => $vehicle_applicable->id,
            'label_id' => $label_applicable->id
        ]);

        $response = $this
            ->postJson(route('vehicles.index'), [
                'sort_by' => 'price-asc',
        ]);

        $response->assertStatus(200);

        $this->assertEquals(1, $response->json('results.total'));
        $this->assertCount(1, VehicleLabel::all());
        $this->assertNotNull($response->json('results.data.0.labels'));
        $this->assertCount(1, $response->json('results.data.0.labels'));

        $this->assertArrayHasKey('name', $response->json('results.data.0.labels.0'));
        $this->assertArrayHasKey('content', $response->json('results.data.0.labels.0'));
        $this->assertArrayNotHasKey('data', $response->json('results.data.0.labels.0'));
        $this->assertEquals($label_applicable->name, $response->json('results.data.0.labels.0.name'));
        $this->assertEquals($label_applicable->id, $response->json('results.data.0.labels.0.id'));
        $this->assertEquals($label_applicable->type, $response->json('results.data.0.labels.0.type'));
    }

    public function testLabelsEmptyType()
    {
        Settings::make([
            'tab' => 'foo',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'vehicle-labels-enabled',
            'value' => true,
            'type' => 'boolean',
        ]);

        $this->seed();
        $this->seed(FilterSettingSeed::class);

        $label_applicable = Label::factory()->create([
            'name' => 'applicable',
            'type' => ''
        ]);

        $vehicle_applicable = Vehicle::factory()->create([
            'is_published' => true,
            'price' => 123
        ]);

        VehicleLabel::create([
            'vehicle_id' => $vehicle_applicable->id,
            'label_id' => $label_applicable->id
        ]);

        $response = $this
            ->postJson(route('vehicles.index'), [
                'sort_by' => 'price-asc',
            ]);

        $response->assertStatus(200);

        $this->assertEquals(1, $response->json('results.total'));
        $this->assertCount(1, VehicleLabel::all());
        $this->assertNotNull($response->json('results.data.0.labels'));
        $this->assertCount(1, $response->json('results.data.0.labels'));
    }

    public function testLabelsAllType()
    {
        Settings::make([
            'tab' => 'foo',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'vehicle-labels-enabled',
            'value' => true,
            'type' => 'boolean',
        ]);

        $this->seed();
        $this->seed(FilterSettingSeed::class);

        $label_applicable = Label::factory()->create([
            'name' => 'applicable',
            'type' => 'all'
        ]);

        $vehicle_applicable = Vehicle::factory()->create([
            'is_published' => true,
            'price' => 123
        ]);

        VehicleLabel::create([
            'vehicle_id' => $vehicle_applicable->id,
            'label_id' => $label_applicable->id
        ]);

        $response = $this
            ->postJson(route('vehicles.index'), [
                'sort_by' => 'price-asc',
            ]);

        $response->assertStatus(200);

        $this->assertEquals(1, $response->json('results.total'));
        $this->assertCount(1, VehicleLabel::all());
        $this->assertNotNull($response->json('results.data.0.labels'));
        $this->assertCount(1, $response->json('results.data.0.labels'));
    }

    public function testLabelsSRPType()
    {
        Settings::make([
            'tab' => 'foo',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'vehicle-labels-enabled',
            'value' => true,
            'type' => 'boolean',
        ]);

        $this->seed();
        $this->seed(FilterSettingSeed::class);

        $label_applicable = Label::factory()->create([
            'name' => 'applicable',
            'type' => 'srp'
        ]);

        $vehicle_applicable = Vehicle::factory()->create([
            'is_published' => true,
            'price' => 123
        ]);

        VehicleLabel::create([
            'vehicle_id' => $vehicle_applicable->id,
            'label_id' => $label_applicable->id
        ]);

        $response = $this
            ->postJson(route('vehicles.index'), [
                'sort_by' => 'price-asc',
            ]);

        $response->assertStatus(200);

        $this->assertEquals(1, $response->json('results.total'));
        $this->assertCount(1, VehicleLabel::all());
        $this->assertNotNull($response->json('results.data.0.labels'));
        $this->assertCount(1, $response->json('results.data.0.labels'));
    }

    public function testLabelsFPAType()
    {
        Settings::make([
            'tab' => 'foo',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'vehicle-labels-enabled',
            'value' => true,
            'type' => 'boolean',
        ]);

        $this->seed();
        $this->seed(FilterSettingSeed::class);

        $label_applicable = Label::factory()->create([
            'name' => 'applicable',
            'type' => 'fpa'
        ]);

        $vehicle_applicable = Vehicle::factory()->create([
            'is_published' => true,
            'price' => 123
        ]);

        VehicleLabel::create([
            'vehicle_id' => $vehicle_applicable->id,
            'label_id' => $label_applicable->id
        ]);

        $response = $this
            ->postJson(route('vehicles.index'), [
                'sort_by' => 'price-asc',
            ]);

        $response->assertStatus(200);

        $this->assertEquals(1, $response->json('results.total'));
        $this->assertCount(1, VehicleLabel::all());
        $this->assertNotNull($response->json('results.data.0.labels'));
        $this->assertCount(0, $response->json('results.data.0.labels'));
    }

    public function testLabelsDisabled()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);

        $label_applicable = Label::factory()->create([
            'name' => 'applicable',
            'type' => 'srp'
        ]);

        $vehicle_applicable = Vehicle::factory()->create([
            'is_published' => true,
            'price' => 123
        ]);

        VehicleLabel::create([
            'vehicle_id' => $vehicle_applicable->id,
            'label_id' => $label_applicable->id
        ]);

        $response = $this
            ->postJson(route('vehicles.index'), [
                'sort_by' => 'price-asc',
            ]);

        $response->assertStatus(200);

        $this->assertEquals(1, $response->json('results.total'));
        $this->assertCount(1, VehicleLabel::all());
        $this->assertNotNull($response->json('results.data.0.labels'));
        $this->assertCount(0, $response->json('results.data.0.labels'));
    }

    public function testLabelContent()
    {
        Settings::make([
            'tab' => 'foo',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'vehicle-labels-enabled',
            'value' => true,
            'type' => 'boolean',
        ]);

        $this->seed();
        $this->seed(FilterSettingSeed::class);

        $label_applicable = Label::factory()->create([
            'name' => 'applicable',
            'type' => 'srp',
            'content' => 'test',
        ]);

        $vehicle_applicable = Vehicle::factory()->create([
            'is_published' => true,
            'price' => 123
        ]);

        VehicleLabel::create([
            'vehicle_id' => $vehicle_applicable->id,
            'label_id' => $label_applicable->id
        ]);

        $response = $this
            ->postJson(route('vehicles.index'), [
                'sort_by' => 'price-asc',
            ]);

        $response->assertStatus(200);

        $this->assertEquals(1, $response->json('results.total'));
        $this->assertCount(1, VehicleLabel::all());
        $this->assertNotNull($response->json('results.data.0.labels'));
        $this->assertCount(1, $response->json('results.data.0.labels'));
        $this->assertArrayHasKey('content', $response->json('results.data.0.labels.0'));
        $this->assertEquals('test', $response->json('results.data.0.labels.0.content'));
    }

    public function testPriceSelectFilters()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);
        Vehicle::factory()->create([
            'is_published' => true,
            'price' => 12000
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'price' => 23000
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'price' => 45000
        ]);
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));
        $this->assertArrayHasKey('price', $response->json('filters'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'price_min',
                        'value' => 18000,
                    ],
                    [
                        'type' => 'price_max',
                        'value' => 31000,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(1, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'price_max',
                        'value' => 5000,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'price_max',
                        'value' => 99000,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'price_min',
                        'value' => 99000,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));
    }

    public function testMonthlyPriceSelectFilters()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);
        Vehicle::factory()->create([
            'is_published' => true,
            'monthly_price' => 12000
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'monthly_price' => 23000
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'monthly_price' => 45000
        ]);
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));
        $this->assertArrayHasKey('monthly_price', $response->json('filters'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'price_monthly_min',
                        'value' => 18000,
                    ],
                    [
                        'type' => 'price_monthly_max',
                        'value' => 31000,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(1, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'price_monthly_max',
                        'value' => 5000,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'price_monthly_max',
                        'value' => 99000,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'price_monthly_min',
                        'value' => 99000,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));
    }

    public function testDoorRangeFilters()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);
        Vehicle::factory()->create([
            'is_published' => true,
            'door_count' => 2
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'door_count' => 4
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'door_count' => 5
        ]);
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'doors_min',
                        'value' => 2,
                    ],
                    [
                        'type' => 'doors_max',
                        'value' => 3,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(1, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'doors_max',
                        'value' => 1,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'doors_max',
                        'value' => 8,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'doors_min',
                        'value' => 99,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));
    }

    public function testSeatRangeFilters()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);
        Vehicle::factory()->create([
            'is_published' => true,
            'seats' => 2
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'seats' => 4
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'seats' => 5
        ]);
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'seats_min',
                        'value' => 2,
                    ],
                    [
                        'type' => 'seats_max',
                        'value' => 3,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(1, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'seats_max',
                        'value' => 1,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'seats_max',
                        'value' => 8,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'seats_min',
                        'value' => 99,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));
    }

    public function testEngineSizeFilter()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);
        Vehicle::factory()->create([
            'is_published' => true,
            'engine_size_cc' => 1234,
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'engine_size_cc' => 2345,
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'engine_size_cc' => 3456,
        ]);
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));
        $this->assertArrayHasKey('engine_size', $response->json('filters'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'engine_size_min',
                        'value' => 2000,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(2, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'engine_size_min',
                        'value' => 456789,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'engine_size_max',
                        'value' => 1,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'engine_size_min',
                        'value' => 1000,
                    ],
                    [
                        'type' => 'engine_size_max',
                        'value' => 2100,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(1, $response->json('results.total'));
    }
    public function testMileageFilter()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);
        Settings::make([
            'tab' => 'foo',
            'section' => 'automotive',
            'group' => 'General',
            'name' => 'Distance measurement',
            'config_key' => 'automotive-distance_measurement',
            'type' => 'string',
            'value' => 'mi',
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'odometer_mi' => 12000,
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'odometer_mi' => 45000,
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'odometer_mi' => 99000,
        ]);
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));
        $this->assertArrayHasKey('mileage', $response->json('filters'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'mileage_min',
                        'value' => 15000,
                    ],
                    [
                        'type' => 'mileage_max',
                        'value' => 75000,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(1, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'mileage_min',
                        'value' => 15000,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(2, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'mileage_max',
                        'value' => 75000,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(2, $response->json('results.total'));
    }

    public function testVehicleTypeFilter()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);

        Vehicle::factory(3)->create([
            'is_published' => true,
            'type' => 'car',
        ]);

        Vehicle::factory(2)->create([
            'is_published' => true,
            'type' => 'lcv',
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(5, $response->json('results.total'));
        $this->assertArrayHasKey('vehicle_type', $response->json('filters'));
        $this->assertCount(2, $response->json('filters.vehicle_type.results'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'vehicle_type',
                        'value' => 'car',
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'vehicle_type',
                        'value' => 'lcv',
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(2, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'vehicle_type',
                        'value' => 'bike',
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'vehicle_type',
                        'value' => 'car',
                    ],
                    [
                        'type' => 'vehicle_type',
                        'value' => 'lcv',
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(5, $response->json('results.total'));
    }

    public function testManufactureYearFilter()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);
        Vehicle::factory()->create([
            'is_published' => true,
            'manufacture_year' => 2010,
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'manufacture_year' => 2015,
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'manufacture_year' => 2020,
        ]);
        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));
        $this->assertArrayHasKey('manufacture_year', $response->json('filters'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'manufacture_year_min',
                        'value' => 2012,
                    ],
                    [
                        'type' => 'manufacture_year_max',
                        'value' => 2018,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(1, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'manufacture_year_min',
                        'value' => 2012,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(2, $response->json('results.total'));
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'manufacture_year_max',
                        'value' => 2018,
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(2, $response->json('results.total'));
    }

    public function testFilterReturnsSlugs()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);

        $dealership = Dealership::factory()->create();

        Vehicle::factory(5)->create([
            'is_published' => true,
            'dealership_id' => $dealership->id
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);

        $filters = [
            'make',
            'model',
            'gearbox',
            'fuel type',
            'body types',
            'colour',
            'location',
        ];
        collect($response->json('filters'))->each(function ($filter) use ($filters) {
            if (in_array(strtolower($filter['title']), $filters) && !empty($filters['results'])) {
                $this->assertArrayHasKey('slug', $filter['results'][0]);
                $this->assertNotEmpty($filter['results'][0]['slug']);
            }
        });
    }

    public function testFilterModelSlugs()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);

        $model = VehicleModel::factory()->create();

        VehicleModel::factory(5)->create([
            'make_id' => $model->make->id
        ]);

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'make',
                        'value' => $model->make->name
                    ]
                ]
            ]);

        $response->assertStatus(200);
        $this->assertArrayHasKey('model', $response->json('filters'));
        $this->assertGreaterThan(0, count($response->json('filters.model')));
    }

    public function testFilterAcceptsSlugsForFuel()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);

        $fuel_type_petrol = FuelType::factory()->create([
            'name' => 'petrol',
            'slug' => 'petrol'
        ]);

        $fuel_type_diesel = FuelType::factory()->create([
            'name' => 'diesel',
            'slug' => 'diesel'
        ]);

        $fuel_type_electric = FuelType::factory()->create([
            'name' => 'electric',
            'slug' => 'electric'
        ]);

        Vehicle::factory(3)->create([
            'is_published' => true,
            'fuel_type_id' => $fuel_type_petrol->id
        ]);

        Vehicle::factory(5)->create([
            'is_published' => true,
            'fuel_type_id' => $fuel_type_diesel->id
        ]);

        Vehicle::factory(1)->create([
            'is_published' => true,
            'fuel_type_id' => $fuel_type_electric->id
        ]);

        // test search with no filters
        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);
        $this->assertEquals(9, $response->json('results.total'));

        // test fuel type filter
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'fuel_type',
                        'value' => 'petrol',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));

        // test fuel type filter
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'fuel_type',
                        'value' => 'diesel',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(5, $response->json('results.total'));

        // test multiple selections
        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'fuel_type',
                        'value' => 'diesel',
                    ],
                    [
                        'type' => 'fuel_type',
                        'value' => 'petrol',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(8, $response->json('results.total'));
    }

    public function testFilterAcceptsSlugsForTransmission()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);

        $transmission_type_manual = TransmissionType::factory()->create([
            'name' => 'manual',
            'slug' => 'manual',
        ]);

        $transmission_type_automatic = TransmissionType::factory()->create([
            'name' => 'automatic',
            'slug' => 'automatic',
        ]);

        Vehicle::factory(3)->create([
            'is_published' => true,
            'transmission_id' => $transmission_type_manual->id
        ]);

        Vehicle::factory(5)->create([
            'is_published' => true,
            'transmission_id' => $transmission_type_automatic->id
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);
        $this->assertEquals(8, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'transmission',
                        'value' => 'manual',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'transmission',
                        'value' => 'automatic',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(5, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'transmission',
                        'value' => 'automatic',
                    ],
                    [
                        'type' => 'transmission',
                        'value' => 'manual',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(8, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'transmission',
                        'value' => 'foo',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));
    }

    public function testFilterAcceptsSlugsForMake()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);

        $make_audi = VehicleMake::factory()->create([
            'name' => 'audi'
        ]);

        $make_bmw = VehicleMake::factory()->create([
            'name' => 'bmw'
        ]);

        Vehicle::factory(3)->create([
            'is_published' => true,
            'make_id' => $make_audi->id
        ]);

        Vehicle::factory(5)->create([
            'is_published' => true,
            'make_id' => $make_bmw->id
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);
        $this->assertEquals(8, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'make',
                        'value' => 'audi',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'make',
                        'value' => 'bmw',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(5, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'make',
                        'value' => 'audi',
                    ],
                    [
                        'type' => 'make',
                        'value' => 'bmw',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(8, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'make',
                        'value' => 'foo',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));
    }

    public function testFilterAcceptsSlugsForModel()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);

        $model_one = VehicleModel::factory()->create([
            'name' => 'one'
        ]);

        $model_two = VehicleModel::factory()->create([
            'name' => 'two'
        ]);

        Vehicle::factory(3)->create([
            'is_published' => true,
            'make_id' => $model_one->make->id,
            'model_id' => $model_one->id,
        ]);

        Vehicle::factory(5)->create([
            'is_published' => true,
            'make_id' => $model_two->make->id,
            'model_id' => $model_two->id,
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);
        $this->assertEquals(8, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'model',
                        'value' => 'one',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'model',
                        'value' => 'two',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(5, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'model',
                        'value' => 'one',
                    ],
                    [
                        'type' => 'model',
                        'value' => 'two',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(8, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'model',
                        'value' => 'foo',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));
    }

    public function testFilterAcceptsSlugsForBodyType()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);

        $body_coupe = BodyStyleType::factory()->create([
            'name' => 'coupe'
        ]);

        $body_saloon = BodyStyleType::factory()->create([
            'name' => 'saloon'
        ]);
        // Adding filter index for matching, due to queue fake it is not created automatically
        FilterIndex::create([
            'slug' => 'coupe',
            'name' => 'coupe',
            'filter_type' => 'body_type',
            'filter_id' => $body_coupe->id,
        ]);
        FilterIndex::create([
            'slug' => 'saloon',
            'name' => 'saloon',
            'filter_type' => 'body_type',
            'filter_id' => $body_saloon->id,
        ]);


        Vehicle::factory(3)->create([
            'is_published' => true,
            'body_style_id' => $body_coupe->id
        ]);

        Vehicle::factory(5)->create([
            'is_published' => true,
            'body_style_id' => $body_saloon->id
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);
        $this->assertEquals(8, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'body_type',
                        'value' => 'coupe',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'body_type',
                        'value' => 'saloon',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(5, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'body_type',
                        'value' => 'coupe',
                    ],
                    [
                        'type' => 'body_type',
                        'value' => 'saloon',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(8, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'body_type',
                        'value' => 'foo',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));
    }

    public function testFranchiseFilter()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);

        $franchise_one = Franchise::factory()->create([
            'slug' => 'foo'
        ]);

        $franchise_two = Franchise::factory()->create([
            'slug' => 'baz'
        ]);

        $dealer_one = Dealership::factory()->create([
            'franchise_id' => $franchise_one->id
        ]);

        $dealer_two = Dealership::factory()->create([
            'franchise_id' => $franchise_two->id
        ]);

        Vehicle::factory(3)->create([
            'is_published' => true,
            'dealership_id' => $dealer_one->id
        ]);

        Vehicle::factory(5)->create([
            'is_published' => true,
            'dealership_id' => $dealer_two->id
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);
        $this->assertEquals(8, $response->json('results.total'));

        $response2 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'franchise',
                        'value' => 'foo',
                    ],
                ]
            ]);

        $response2->assertStatus(200);
        $this->assertEquals(3, $response2->json('results.total'));

        $response3 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'franchise',
                        'value' => 'baz',
                    ],
                ]
            ]);

        $response3->assertStatus(200);
        $this->assertEquals(5, $response3->json('results.total'));

        $response4 = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'franchise',
                        'value' => 'foo',
                    ],
                    [
                        'type' => 'franchise',
                        'value' => 'baz',
                    ],
                ]
            ]);

        $response4->assertStatus(200);
        $this->assertEquals(8, $response4->json('results.total'));
    }

    public function testFilterAcceptsSlugsForDealership()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);

        $dealer_one = Dealership::factory()->create([
            'name' => 'one'
        ]);

        $dealer_two = Dealership::factory()->create([
            'name' => 'two'
        ]);

        Vehicle::factory(3)->create([
            'is_published' => true,
            'dealership_id' => $dealer_one->id
        ]);

        Vehicle::factory(5)->create([
            'is_published' => true,
            'dealership_id' => $dealer_two->id
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);
        $this->assertEquals(8, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'location',
                        'value' => 'one',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'location',
                        'value' => 'two',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(5, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'location',
                        'value' => 'one',
                    ],
                    [
                        'type' => 'location',
                        'value' => 'two',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(8, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'location',
                        'value' => 'foo',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));
    }

    public function testFilterAcceptsSlugsForColour()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);

        Vehicle::factory(3)->create([
            'is_published' => true,
            'colour' => 'red'
        ]);

        Vehicle::factory(5)->create([
            'is_published' => true,
            'colour' => 'Midnight Blue'
        ]);

        // Adding filter index for matching, due to queue fake it is not created automatically
        FilterIndex::create([
            'slug' => 'red',
            'name' => 'red',
            'filter_type' => 'colour',
            'filter_id' => 'red',
        ]);
        FilterIndex::create([
            'slug' => 'midnight-blue',
            'name' => 'Midnight Blue',
            'filter_type' => 'colour',
            'filter_id' => 'midnight-blue',
        ]);


        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);
        $this->assertEquals(8, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'colour',
                        'value' => 'red',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'colour',
                        'value' => 'midnight-blue',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(5, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'colour',
                        'value' => 'red',
                    ],
                    [
                        'type' => 'colour',
                        'value' => 'midnight-blue',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(8, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'colour',
                        'value' => 'yellow',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(0, $response->json('results.total'));
    }

    public function testMakeSlug()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);

        Settings::make([
            'tab' => 'foo',
            'section' => 'automotive',
            'group' => 'General',
            'name' => 'Vehicle Brand',
            'config_key' => 'automotive-vehicle-brand-on-filter-card',
            'type' => 'boolean',
            'value' => 'true',
        ]);

        $make = VehicleMake::factory()->create();

        Vehicle::factory()->create([
            'is_published' => true,
            'make_id' => $make->id,
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);
        $this->assertEquals(1, $response->json('results.total'));
        $this->assertEquals($make->name, $response->json('results.data.0.make.name'));
        $this->assertEquals($make->slug, $response->json('results.data.0.make.slug'));
    }

    public function testModelSlug()
    {
        $this->seed();
        $this->seed(FilterSettingSeed::class);

        Settings::make([
            'tab' => 'foo',
            'section' => 'automotive',
            'group' => 'General',
            'name' => 'Vehicle Brand',
            'config_key' => 'automotive-vehicle-model-on-filter-card',
            'type' => 'boolean',
            'value' => 'true',
        ]);

        $model = VehicleModel::factory()->create();

        Vehicle::factory()->create([
            'is_published' => true,
            'make_id' => $model->make_id,
            'model_id' => $model->id,
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);
        $this->assertEquals(1, $response->json('results.total'));
        $this->assertEquals($model->name, $response->json('results.data.0.model.name'));
        $this->assertEquals($model->slug, $response->json('results.data.0.model.slug'));
    }

    public function testRepresentativeFinanceExample()
    {
        Settings::make([
            'tab' => 'foo',
            'section' => 'automotive',
            'group' => 'General',
            'name' => 'foo',
            'config_key' => 'vehicle-list-load-finance-example',
            'type' => 'boolean',
            'value' => 'true',
        ]);

        $this->seed();
        $this->seed(FilterSettingSeed::class);

        $vehicle = Vehicle::factory()->create([
            'is_published' => true
        ]);

        $finance = VehicleFinance::factory()->create([
            'vehicle_id' => $vehicle->id,
            'monthly_price' => 123,
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);
        $this->assertEquals(1, $response->json('results.total'));
        $this->assertArrayHasKey('finance_example', $response->json());
        $this->assertEquals($finance->monthly_price, $response->json('finance_example.monthly_price'));
    }

    public function testMissingFinanceExample()
    {
        Settings::make([
            'tab' => 'foo',
            'section' => 'automotive',
            'group' => 'General',
            'name' => 'foo',
            'config_key' => 'vehicle-list-load-finance-example',
            'type' => 'boolean',
            'value' => 'true',
        ]);

        $this->seed();
        $this->seed(FilterSettingSeed::class);

        Vehicle::factory()->create([
            'is_published' => true
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);
        $this->assertEquals(1, $response->json('results.total'));
        $this->assertArrayHasKey('finance_example', $response->json());
        $this->assertEmpty($response->json('finance_example'));
    }

    public function testRangeFilterSelections()
    {
        $this->seed(FilterSettingSeed::class);

        // try search with no filters. Should bring back all of our example vehicles.
        $response = $this
            ->postJson(route('vehicles.index'));

        // test that call worked and brought back results
        $response->assertStatus(200);

        $this->assertArrayHasKey('price', $response->json('filters'));
        $this->assertArrayHasKey('filter_min', $response->json('filters.price.results'));
        $this->assertArrayHasKey('filter_max', $response->json('filters.price.results'));

        $this->assertArrayHasKey('monthly_price', $response->json('filters'));
        $this->assertArrayHasKey('filter_min', $response->json('filters.monthly_price.results'));
        $this->assertArrayHasKey('filter_max', $response->json('filters.monthly_price.results'));

        $this->assertArrayHasKey('doors', $response->json('filters'));
        $this->assertArrayHasKey('filter_min', $response->json('filters.doors.results'));
        $this->assertArrayHasKey('filter_max', $response->json('filters.doors.results'));

        $this->assertArrayHasKey('engine_size', $response->json('filters'));
        $this->assertArrayHasKey('filter_min', $response->json('filters.engine_size.results'));
        $this->assertArrayHasKey('filter_max', $response->json('filters.engine_size.results'));

        $this->assertArrayHasKey('manufacture_year', $response->json('filters'));
        $this->assertArrayHasKey('filter_min', $response->json('filters.manufacture_year.results'));
        $this->assertArrayHasKey('filter_max', $response->json('filters.manufacture_year.results'));

        $this->assertArrayHasKey('mileage', $response->json('filters'));
        $this->assertArrayHasKey('filter_min', $response->json('filters.mileage.results'));
        $this->assertArrayHasKey('filter_max', $response->json('filters.mileage.results'));

        $this->assertArrayHasKey('seats', $response->json('filters'));
        $this->assertArrayHasKey('filter_min', $response->json('filters.seats.results'));
        $this->assertArrayHasKey('filter_max', $response->json('filters.seats.results'));
    }

    public function testMissingColourIndex()
    {
        $this->seed(FilterSettingSeed::class);
        Vehicle::factory(5)->create([
            'is_published' => true,
            'colour' => 'red',
        ]);

        // delete the filter indexes, to simulate us not having a filter index for a colour
        FilterIndex::query()->where('filter_type', '=', 'colour')->delete();

        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(5, $response->json('results.total'));
    }

    public function testIsNewFilter()
    {
        $this->seed(FilterSettingSeed::class);

        Vehicle::factory(2)->create([
            'is_published' => true,
            'is_demo' => false,
            'is_new' => false
        ]);

        Vehicle::factory(3)->create([
            'is_published' => true,
            'is_demo' => false,
            'is_new' => true
        ]);

        Vehicle::factory(1)->create([
            'is_published' => true,
            'is_demo' => true,
            'is_new' => false
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(6, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'is_new',
                        'value' => 'new',
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'is_new',
                        'value' => 'used',
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(2, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'is_new',
                        'value' => 'used',
                    ],
                    [
                        'type' => 'is_new',
                        'value' => 'new',
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(5, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'is_new',
                        'value' => 'ex_demo',
                    ],
                ]
            ]);
        $response->assertStatus(200);
        $this->assertEquals(1, $response->json('results.total'));
    }

    public function testFilterByStockStatus()
    {
        $this->seed(FilterSettingSeed::class);

        $vehicle1 = Vehicle::factory()->create([
            'is_published' => true
        ]);

        $vehicle2 = Vehicle::factory()->create([
            'is_published' => true
        ]);

        $vehicle3 = Vehicle::factory()->create([
            'is_published' => true
        ]);

        $vehicle_attribute = VehicleAttribute::query()
            ->firstOrCreate(
                [
                    'name' => 'stock_status',
                    'model' => 'vehicle'
                ],
                [
                    'slug' => 'stock_status',
                    'type' => 'text',
                    'validation' => [],
                    'data' => []
                ]
            );

        VehicleAttributeValue::query()->updateOrCreate(
            [
                'attribute_id' => $vehicle_attribute->id,
                'owner_id' => $vehicle1->id,
                'owner_type' => 'vehicle',
            ],
            [
                'value' => 'foo',
                'slug' => $vehicle_attribute->slug,
                'type' => 'text'
            ]
        );

        VehicleAttributeValue::query()->updateOrCreate(
            [
                'attribute_id' => $vehicle_attribute->id,
                'owner_id' => $vehicle2->id,
                'owner_type' => 'vehicle'
            ],
            [
                'value' => 'baz',
                'slug' => $vehicle_attribute->slug,
                'type' => 'text'
            ]
        );

        VehicleAttributeValue::query()->updateOrCreate(
            [
                'attribute_id' => $vehicle_attribute->id,
                'owner_id' => $vehicle3->id,
                'owner_type' => 'vehicle'
            ],
            [
                'value' => 'baz',
                'slug' => $vehicle_attribute->slug,
                'type' => 'text'
            ]
        );

        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'stock_status',
                        'value' => 'foo',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(1, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'stock_status',
                        'value' => 'baz',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(2, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'stock_status',
                        'value' => 'foo',
                    ],
                    [
                        'type' => 'stock_status',
                        'value' => 'baz',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));
    }

    public function testTrimFilter()
    {
        $this->seed(FilterSettingSeed::class);

        Vehicle::factory(2)->create([
            'is_published' => true,
            'trim' => 'foo'
        ]);

        Vehicle::factory(3)->create([
            'is_published' => true,
            'trim' => 'bar'
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));

        $response->assertStatus(200);
        $this->assertEquals(5, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'trim',
                        'value' => 'foo',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(2, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'trim',
                        'value' => 'bar',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(3, $response->json('results.total'));

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => 'trim',
                        'value' => 'foo',
                    ],
                    [
                        'type' => 'trim',
                        'value' => 'bar',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(5, $response->json('results.total'));
    }

    public function testAttributeFilter()
    {
        Settings::make([
            'tab' => 'Automotive',
            'section' => 'Filter',
            'group' => 'Filtering',
            'name' => 'Trim',
            'config_key' => 'automotive-vehicle-filters-too-good-to-trade',
            'type' => 'boolean',
            'value' => true,
        ]);
        $vehicle1 = Vehicle::factory()->create([
            'is_published' => true
        ]);
        Vehicle::factory()->create([
            'is_published' => true
        ]);

        // try setting attribute
        $vehicle_attribute = VehicleAttribute::query()
            ->firstOrCreate(
                [
                    'model' => 'vehicle',
                    'name' => 'too-good-to-trade',
                ],
                [
                    'slug' => 'too-good-to-trade',
                    'type' => 'boolean',
                    'validation' => [],
                    'data' => [],
                    'filterable' => 1
                ]
            );

        // add an attribute value for the vehicle
        $vehicle_attribute_value = VehicleAttributeValue::query()->updateOrCreate(
            [
                'attribute_id' => $vehicle_attribute->id,
                'owner_id' => $vehicle1->id,
                'owner_type' => 'vehicle',
            ],
            [
                'value' => true,
                'value_integer' => 1,
                'slug' => $vehicle_attribute->slug,
                'type' => 'boolean'
            ]
        );

        $response = $this
            ->postJson(route('vehicles.index'), [
                'selections' => [
                    [
                        'type' => $vehicle_attribute->slug,
                        'value' => 'yes',
                    ],
                ]
            ]);

        $response->assertStatus(200);
        $this->assertEquals(1, $response->json('results.total'));
    }

    public function testReservationAmount()
    {
        Settings::make([
            'tab' => 'foo',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'sales-reserve_price',
            'type' => 'number',
            'value' => 100,
        ]);

        Settings::make([
            'tab' => 'foo',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'sales-reserve_price_lcv',
            'type' => 'number',
            'value' => 500,
        ]);

        Vehicle::factory(10)->create([
            'is_published' => true,
            'type' => 'car',
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);

        $this->assertEquals(100, $response->json('results.data.0.reservation_amount'));
    }

    public function testReservationAmountLcv()
    {
        Settings::make([
            'tab' => 'foo',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'sales-reserve_price',
            'type' => 'number',
            'value' => 100,
        ]);

        Settings::make([
            'tab' => 'foo',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'sales-reserve_price_lcv',
            'type' => 'number',
            'value' => 500,
        ]);

        Vehicle::factory(10)->create([
            'is_published' => true,
            'type' => 'lcv',
        ]);

        $response = $this
            ->postJson(route('vehicles.index'));
        $response->assertStatus(200);

        $this->assertEquals(500, $response->json('results.data.0.reservation_amount'));
    }
}
