feat(migrations): add migration for grouping Pyme Rural tenants and updating client associations
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
private const CLIENT_CODE = 'pyme_rural';
|
||||
|
||||
private const CLIENT_NAME = 'Pyme Rural';
|
||||
|
||||
private const PREVIOUS_CLIENT_CODE = 'onticket';
|
||||
|
||||
private const TENANT_CODES = [
|
||||
'fiesta_futbol_infantil',
|
||||
'desfile_pura_tendencia',
|
||||
];
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
DB::transaction(function (): void {
|
||||
$clientId = $this->clientId(self::CLIENT_CODE, self::CLIENT_NAME);
|
||||
$sourceClientIds = DB::table('tenants')
|
||||
->whereIn('codigo', self::TENANT_CODES)
|
||||
->pluck('client_id')
|
||||
->unique();
|
||||
|
||||
$this->copyIntegrations($sourceClientIds, $clientId);
|
||||
|
||||
DB::table('tenants')
|
||||
->whereIn('codigo', self::TENANT_CODES)
|
||||
->update(['client_id' => $clientId]);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::transaction(function (): void {
|
||||
$previousClientId = $this->clientId(self::PREVIOUS_CLIENT_CODE, 'OnTicket');
|
||||
$pymeRuralClientId = DB::table('clients')
|
||||
->where('code', self::CLIENT_CODE)
|
||||
->value('id');
|
||||
|
||||
if ($pymeRuralClientId !== null) {
|
||||
$this->copyIntegrations(collect([$pymeRuralClientId]), $previousClientId);
|
||||
}
|
||||
|
||||
DB::table('tenants')
|
||||
->whereIn('codigo', self::TENANT_CODES)
|
||||
->update(['client_id' => $previousClientId]);
|
||||
});
|
||||
}
|
||||
|
||||
private function clientId(string $code, string $name): int
|
||||
{
|
||||
$clientId = DB::table('clients')->where('code', $code)->value('id');
|
||||
|
||||
if ($clientId === null) {
|
||||
return (int) DB::table('clients')->insertGetId([
|
||||
'code' => $code,
|
||||
'name' => $name,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
DB::table('clients')->where('id', $clientId)->update([
|
||||
'name' => $name,
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
return (int) $clientId;
|
||||
}
|
||||
|
||||
private function copyIntegrations(iterable $sourceClientIds, int $targetClientId): void
|
||||
{
|
||||
foreach ($sourceClientIds as $sourceClientId) {
|
||||
DB::table('client_integrations')
|
||||
->where('client_id', $sourceClientId)
|
||||
->orderBy('id')
|
||||
->get()
|
||||
->each(function (object $integration) use ($targetClientId): void {
|
||||
DB::table('client_integrations')->insertOrIgnore([
|
||||
'client_id' => $targetClientId,
|
||||
'integration_code' => $integration->integration_code,
|
||||
'integration_instance_id' => $integration->integration_instance_id,
|
||||
'created_at' => $integration->created_at,
|
||||
'updated_at' => $integration->updated_at,
|
||||
]);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -12,9 +12,9 @@ use App\Domains\Commerce\Catalog\Models\CatalogItem;
|
||||
use App\Domains\Commerce\Catalog\Models\FeaturedGroup;
|
||||
use App\Domains\Commerce\Catalog\Services\CatalogService;
|
||||
use App\Domains\Core\Client\Models\Client;
|
||||
use App\Domains\Ticketing\Desfile\Services\InvitationPurchaseProvisioner;
|
||||
use App\Domains\Core\Tenant\Models\Tenant;
|
||||
use App\Domains\Core\Tenant\Services\TenantService;
|
||||
use App\Domains\Ticketing\Desfile\Services\InvitationPurchaseProvisioner;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -22,7 +22,7 @@ use RuntimeException;
|
||||
|
||||
class DesfilePuraTendenciaSeeder extends Seeder
|
||||
{
|
||||
private const ONTICKET_CLIENT_CODE = 'onticket';
|
||||
private const PYME_RURAL_CLIENT_CODE = 'pyme_rural';
|
||||
|
||||
private const TENANT_CODE = 'desfile_pura_tendencia';
|
||||
|
||||
@@ -34,9 +34,9 @@ class DesfilePuraTendenciaSeeder extends Seeder
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$client = Client::query()->firstOrCreate(
|
||||
['code' => self::ONTICKET_CLIENT_CODE],
|
||||
['name' => 'OnTicket'],
|
||||
$client = Client::query()->updateOrCreate(
|
||||
['code' => self::PYME_RURAL_CLIENT_CODE],
|
||||
['name' => 'Pyme Rural'],
|
||||
);
|
||||
|
||||
$tenant = Tenant::query()->where('codigo', self::TENANT_CODE)->first();
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Shared\Attachable\Models\Attachment;
|
||||
use App\Shared\Attachable\Services\AttachmentService;
|
||||
use App\Domains\Core\Client\Models\Client;
|
||||
use App\Domains\Core\Tenant\Models\Tenant;
|
||||
use App\Domains\Core\Tenant\Models\AdminWebsiteType;
|
||||
use App\Domains\Core\Tenant\Models\Tenant;
|
||||
use App\Domains\Core\Tenant\Services\TenantService;
|
||||
use App\Domains\Core\Tenant\Services\WebsiteExtraService;
|
||||
use App\Shared\Attachable\Models\Attachment;
|
||||
use App\Shared\Attachable\Services\AttachmentService;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use RuntimeException;
|
||||
@@ -18,6 +18,8 @@ class TenantSeeder extends Seeder
|
||||
{
|
||||
private const ONTICKET_CLIENT_CODE = 'onticket';
|
||||
|
||||
private const PYME_RURAL_CLIENT_CODE = 'pyme_rural';
|
||||
|
||||
private const SONDER_CLIENT_CODE = 'sonder';
|
||||
|
||||
private const SOCIAL_MEDIA = [
|
||||
@@ -60,6 +62,11 @@ class TenantSeeder extends Seeder
|
||||
['name' => 'OnTicket'],
|
||||
);
|
||||
|
||||
$pymeRuralClient = Client::query()->updateOrCreate(
|
||||
['code' => self::PYME_RURAL_CLIENT_CODE],
|
||||
['name' => 'Pyme Rural'],
|
||||
);
|
||||
|
||||
$onTicketType = AdminWebsiteType::query()->where('codigo', 'onticket')->firstOrFail();
|
||||
|
||||
$onTicketTenant = Tenant::query()->where('codigo', 'onticket')->first();
|
||||
@@ -199,7 +206,7 @@ class TenantSeeder extends Seeder
|
||||
->delete();
|
||||
|
||||
$this->tenantService->create([
|
||||
'client_id' => $onTicketClient->id,
|
||||
'client_id' => $pymeRuralClient->id,
|
||||
'codigo' => 'fiesta_futbol_infantil',
|
||||
'nombre' => 'Fiesta Fútbol Infantil',
|
||||
'dominio' => $fiestaDomain,
|
||||
|
||||
130
storage/framework/lsp-52251fd8d9839a2d.php
Normal file
130
storage/framework/lsp-52251fd8d9839a2d.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
error_reporting(error_reporting() & ~(E_WARNING | E_CORE_WARNING | E_COMPILE_WARNING | E_USER_WARNING | E_DEPRECATED | E_USER_DEPRECATED));
|
||||
class LspHelper
|
||||
{
|
||||
public static function relativePath($path)
|
||||
{
|
||||
if (!str_contains($path, base_path())) {
|
||||
return (string) $path;
|
||||
}
|
||||
|
||||
return ltrim(str_replace(base_path(), '', realpath($path) ?: $path), DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
public static function isVendor($path)
|
||||
{
|
||||
return str_contains($path, base_path('vendor'));
|
||||
}
|
||||
|
||||
public static function propertyDefault(ReflectionProperty $property, ?ReflectionParameter $parameter = null): array
|
||||
{
|
||||
if ($property->hasDefaultValue()) {
|
||||
return ['default' => $property->getDefaultValue()];
|
||||
}
|
||||
|
||||
if ($parameter?->isDefaultValueAvailable()) {
|
||||
return ['default' => $parameter->getDefaultValue()];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public static function formatDefaultValue(mixed $value): mixed
|
||||
{
|
||||
return match (true) {
|
||||
is_array($value) => 'array(...)',
|
||||
$value instanceof UnitEnum => get_class($value) . '::' . $value->name,
|
||||
$value instanceof Closure => 'Closure',
|
||||
is_object($value) => get_class($value),
|
||||
is_string($value) => var_export($value, true),
|
||||
is_null($value) => 'null',
|
||||
is_bool($value) => $value ? 'true' : 'false',
|
||||
default => $value,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
use Pest\Expectation;
|
||||
use Pest\TestSuite;
|
||||
|
||||
$pest = new class
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
if ($this->isInstalled()) {
|
||||
$this->boot();
|
||||
}
|
||||
}
|
||||
|
||||
public function isInstalled(): bool
|
||||
{
|
||||
return class_exists(TestSuite::class);
|
||||
}
|
||||
|
||||
protected function boot(): void
|
||||
{
|
||||
require_once base_path('vendor/pestphp/pest/overrides/Runner/TestSuiteLoader.php');
|
||||
|
||||
TestSuite::getInstance(base_path(), 'tests');
|
||||
|
||||
if (file_exists($pestFile = base_path('tests/Pest.php'))) {
|
||||
require_once $pestFile;
|
||||
}
|
||||
}
|
||||
|
||||
public function config(): ?array
|
||||
{
|
||||
if (!$this->isInstalled()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'uses' => $this->uses(),
|
||||
'expectations' => $this->expectations(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function uses(): array
|
||||
{
|
||||
if (is_null($instance = TestSuite::getInstance())) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$reflection = new ReflectionProperty($instance->tests, 'uses');
|
||||
$uses = $reflection->getValue($instance->tests);
|
||||
|
||||
return collect($uses)->map(function (array $use, string $path) {
|
||||
[$classOrTraits] = $use;
|
||||
|
||||
return [
|
||||
'path' => LspHelper::relativePath($path),
|
||||
'classes' => array_values(array_filter($classOrTraits, fn ($c) => class_exists($c))),
|
||||
'traits' => array_values(array_filter($classOrTraits, fn ($c) => trait_exists($c))),
|
||||
];
|
||||
})->values()->all();
|
||||
}
|
||||
|
||||
protected function expectations(): array
|
||||
{
|
||||
$reflection = new ReflectionProperty(Expectation::class, 'extends');
|
||||
$extends = $reflection->getValue();
|
||||
|
||||
return collect($extends)->map(function (Closure $closure, string $name) {
|
||||
$parameters = collect((new ReflectionFunction($closure))->getParameters())
|
||||
->map(function (ReflectionParameter $param) {
|
||||
$type = $param->hasType() ? $param->getType() . ' ' : '';
|
||||
|
||||
$default = $param->isOptional() && $param->isDefaultValueAvailable()
|
||||
? ' = ' . var_export($param->getDefaultValue(), true)
|
||||
: '';
|
||||
|
||||
return $type . '$' . $param->getName() . $default;
|
||||
})
|
||||
->join(', ');
|
||||
|
||||
return compact('name', 'parameters');
|
||||
})->values()->all();
|
||||
}
|
||||
};
|
||||
|
||||
echo json_encode($pest->config());
|
||||
130
storage/framework/lsp-cd371f347782ba98.php
Normal file
130
storage/framework/lsp-cd371f347782ba98.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
error_reporting(error_reporting() & ~(E_WARNING | E_CORE_WARNING | E_COMPILE_WARNING | E_USER_WARNING | E_DEPRECATED | E_USER_DEPRECATED));
|
||||
class LspHelper
|
||||
{
|
||||
public static function relativePath($path)
|
||||
{
|
||||
if (!str_contains($path, base_path())) {
|
||||
return (string) $path;
|
||||
}
|
||||
|
||||
return ltrim(str_replace(base_path(), '', realpath($path) ?: $path), DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
public static function isVendor($path)
|
||||
{
|
||||
return str_contains($path, base_path('vendor'));
|
||||
}
|
||||
|
||||
public static function propertyDefault(ReflectionProperty $property, ?ReflectionParameter $parameter = null): array
|
||||
{
|
||||
if ($property->hasDefaultValue()) {
|
||||
return ['default' => $property->getDefaultValue()];
|
||||
}
|
||||
|
||||
if ($parameter?->isDefaultValueAvailable()) {
|
||||
return ['default' => $parameter->getDefaultValue()];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public static function formatDefaultValue(mixed $value): mixed
|
||||
{
|
||||
return match (true) {
|
||||
is_array($value) => 'array(...)',
|
||||
$value instanceof UnitEnum => get_class($value) . '::' . $value->name,
|
||||
$value instanceof Closure => 'Closure',
|
||||
is_object($value) => get_class($value),
|
||||
is_string($value) => var_export($value, true),
|
||||
is_null($value) => 'null',
|
||||
is_bool($value) => $value ? 'true' : 'false',
|
||||
default => $value,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
use Pest\Expectation;
|
||||
use Pest\TestSuite;
|
||||
|
||||
$pest = new class
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
if ($this->isInstalled()) {
|
||||
$this->boot();
|
||||
}
|
||||
}
|
||||
|
||||
public function isInstalled(): bool
|
||||
{
|
||||
return class_exists(TestSuite::class);
|
||||
}
|
||||
|
||||
protected function boot(): void
|
||||
{
|
||||
require_once base_path('vendor/pestphp/pest/overrides/Runner/TestSuiteLoader.php');
|
||||
|
||||
TestSuite::getInstance(base_path(), 'tests');
|
||||
|
||||
if (file_exists($pestFile = base_path('tests/Pest.php'))) {
|
||||
require_once $pestFile;
|
||||
}
|
||||
}
|
||||
|
||||
public function config(): ?array
|
||||
{
|
||||
if (!$this->isInstalled()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'uses' => $this->uses(),
|
||||
'expectations' => $this->expectations(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function uses(): array
|
||||
{
|
||||
if (is_null($instance = TestSuite::getInstance())) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$reflection = new ReflectionProperty($instance->tests, 'uses');
|
||||
$uses = $reflection->getValue($instance->tests);
|
||||
|
||||
return collect($uses)->map(function (array $use, string $path) {
|
||||
[$classOrTraits] = $use;
|
||||
|
||||
return [
|
||||
'path' => LspHelper::relativePath($path),
|
||||
'classes' => array_values(array_filter($classOrTraits, fn ($c) => class_exists($c))),
|
||||
'traits' => array_values(array_filter($classOrTraits, fn ($c) => trait_exists($c))),
|
||||
];
|
||||
})->values()->all();
|
||||
}
|
||||
|
||||
protected function expectations(): array
|
||||
{
|
||||
$reflection = new ReflectionProperty(Expectation::class, 'extends');
|
||||
$extends = $reflection->getValue();
|
||||
|
||||
return collect($extends)->map(function (Closure $closure, string $name) {
|
||||
$parameters = collect((new ReflectionFunction($closure))->getParameters())
|
||||
->map(function (ReflectionParameter $param) {
|
||||
$type = $param->hasType() ? $param->getType() . ' ' : '';
|
||||
|
||||
$default = $param->isOptional() && $param->isDefaultValueAvailable()
|
||||
? ' = ' . var_export($param->getDefaultValue(), true)
|
||||
: '';
|
||||
|
||||
return $type . '$' . $param->getName() . $default;
|
||||
})
|
||||
->join(', ');
|
||||
|
||||
return compact('name', 'parameters');
|
||||
})->values()->all();
|
||||
}
|
||||
};
|
||||
|
||||
echo json_encode($pest->config());
|
||||
109
tests/Feature/Migrations/GroupPymeRuralTenantsTest.php
Normal file
109
tests/Feature/Migrations/GroupPymeRuralTenantsTest.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Migrations;
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Tests\TestCase;
|
||||
|
||||
class GroupPymeRuralTenantsTest extends TestCase
|
||||
{
|
||||
public function test_it_groups_the_futbol_and_desfile_tenants_under_pyme_rural(): void
|
||||
{
|
||||
$this->createSchema();
|
||||
|
||||
$now = now();
|
||||
$onTicketClientId = DB::table('clients')->insertGetId([
|
||||
'code' => 'onticket',
|
||||
'name' => 'OnTicket',
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
DB::table('tenants')->insert([
|
||||
['client_id' => $onTicketClientId, 'codigo' => 'onticket'],
|
||||
['client_id' => $onTicketClientId, 'codigo' => 'fiesta_futbol_infantil'],
|
||||
['client_id' => $onTicketClientId, 'codigo' => 'desfile_pura_tendencia'],
|
||||
]);
|
||||
DB::table('integrations')->insert([
|
||||
'integration_code' => 'email',
|
||||
'name' => 'Email',
|
||||
]);
|
||||
$instanceId = DB::table('integration_instances')->insertGetId([
|
||||
'integration_code' => 'email',
|
||||
'name' => 'OnTicket email',
|
||||
'integration_data' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
DB::table('client_integrations')->insert([
|
||||
'client_id' => $onTicketClientId,
|
||||
'integration_code' => 'email',
|
||||
'integration_instance_id' => $instanceId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
|
||||
$migration = require database_path(
|
||||
'migrations/2026_09_21_020000_group_pyme_rural_tenants.php'
|
||||
);
|
||||
$migration->up();
|
||||
|
||||
$pymeRuralClient = DB::table('clients')->where('code', 'pyme_rural')->sole();
|
||||
$this->assertSame('Pyme Rural', $pymeRuralClient->name);
|
||||
$this->assertSame(2, DB::table('tenants')
|
||||
->whereIn('codigo', ['fiesta_futbol_infantil', 'desfile_pura_tendencia'])
|
||||
->where('client_id', $pymeRuralClient->id)
|
||||
->count());
|
||||
$this->assertSame($onTicketClientId, DB::table('tenants')
|
||||
->where('codigo', 'onticket')
|
||||
->value('client_id'));
|
||||
|
||||
$this->assertDatabaseHas('client_integrations', [
|
||||
'client_id' => $pymeRuralClient->id,
|
||||
'integration_code' => 'email',
|
||||
'integration_instance_id' => $instanceId,
|
||||
]);
|
||||
|
||||
$migration->down();
|
||||
|
||||
$this->assertSame(2, DB::table('tenants')
|
||||
->whereIn('codigo', ['fiesta_futbol_infantil', 'desfile_pura_tendencia'])
|
||||
->where('client_id', $onTicketClientId)
|
||||
->count());
|
||||
}
|
||||
|
||||
private function createSchema(): void
|
||||
{
|
||||
Schema::create('clients', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string('code')->unique();
|
||||
$table->string('name');
|
||||
$table->timestamps();
|
||||
});
|
||||
Schema::create('tenants', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('client_id');
|
||||
$table->string('codigo')->unique();
|
||||
});
|
||||
Schema::create('integrations', function (Blueprint $table): void {
|
||||
$table->string('integration_code')->unique();
|
||||
$table->string('name');
|
||||
});
|
||||
Schema::create('integration_instances', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string('integration_code');
|
||||
$table->string('name');
|
||||
$table->longText('integration_data')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
Schema::create('client_integrations', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('client_id');
|
||||
$table->string('integration_code');
|
||||
$table->foreignId('integration_instance_id');
|
||||
$table->timestamps();
|
||||
$table->unique(['client_id', 'integration_code']);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,14 @@ class DesfilePuraTendenciaSeederTest extends TestCase
|
||||
'site_title' => 'Fiesta Fútbol Infantil',
|
||||
]);
|
||||
|
||||
$pymeRuralClientId = DB::table('clients')->where('code', 'pyme_rural')->value('id');
|
||||
$this->assertNotNull($pymeRuralClientId);
|
||||
$this->assertSame('Pyme Rural', DB::table('clients')->where('id', $pymeRuralClientId)->value('name'));
|
||||
$this->assertSame(2, DB::table('tenants')
|
||||
->whereIn('codigo', ['fiesta_futbol_infantil', 'desfile_pura_tendencia'])
|
||||
->where('client_id', $pymeRuralClientId)
|
||||
->count());
|
||||
|
||||
foreach ([
|
||||
'fiesta_futbol_infantil' => 'futbol_infantil_favicon.png',
|
||||
'desfile_pura_tendencia' => 'pura_tendencia_favicon.png',
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
namespace Tests\Feature\Seeders;
|
||||
|
||||
use App\Shared\Attachable\Models\Attachment;
|
||||
use App\Domains\Core\Tenant\Models\Tenant;
|
||||
use App\Domains\Core\Tenant\Models\AdminWebsiteType;
|
||||
use App\Domains\Core\Tenant\Models\Tenant;
|
||||
use App\Shared\Attachable\Models\Attachment;
|
||||
use Database\Seeders\SocialMediaSeeder;
|
||||
use Database\Seeders\TenantSeeder;
|
||||
use Database\Seeders\WebsiteTypeSeeder;
|
||||
@@ -150,6 +150,8 @@ class TenantSeederTest extends TestCase
|
||||
->with('websiteExtras.websiteTypeExtra')
|
||||
->sole();
|
||||
|
||||
$this->assertSame('pyme_rural', $fiesta->client->code);
|
||||
$this->assertSame('Pyme Rural', $fiesta->client->name);
|
||||
$this->assertSame('onticket', $fiesta->storefront_website_type_code);
|
||||
$this->assertSame('onticket', $fiesta->admin_website_type_code);
|
||||
$this->assertSame('full', $fiesta->cart_editing_policy->value);
|
||||
|
||||
Reference in New Issue
Block a user