Pruebas de integracion con seeds

This commit is contained in:
Juan Pablo Vial
2025-06-24 21:55:02 -04:00
parent 360537c638
commit ca1ed3f870
26 changed files with 1133 additions and 418 deletions

View File

@ -0,0 +1,147 @@
<?php
namespace Tests\Extension;
use PDO;
use PDOException;
use Faker;
use Tests\Extension\Faker\Provider\Rut;
abstract class AbstractSeed implements SeedInterface
{
public function __construct(PDO $connection)
{
$this->setConnection($connection);
$this->faker = Faker\Factory::create('es_AR');
$this->faker->addProvider(new Rut($this->faker));
}
protected PDO $connection;
protected Faker\Generator $faker;
public function setConnection(PDO $connection): SeedInterface
{
$this->connection = $connection;
return $this;
}
public function getConnection(): PDO
{
return $this->connection;
}
public function getDependencies(): array
{
return [];
}
protected string $table;
protected function table(string $table): self
{
$this->table = $table;
return $this;
}
protected array $queryQueue = [];
protected function insertValues(array $valueRows): self
{
$columns = array_keys($valueRows[0]);
$columnsString = implode(', ', array_map(fn($column) => "`{$column}`", $columns));
$placeholderArray = array_map(fn($column) => ":{$column}", $columns);
$placeholders = implode(', ', $placeholderArray);
$query = "INSERT INTO `{$this->table}` ({$columnsString}) VALUES ({$placeholders})";
$this->queryQueue []= ['query' => $query, 'values' => $valueRows];
return $this;
}
protected function save(): self
{
foreach ($this->queryQueue as $entry) {
$query = $entry['query'];
$valueRows = $entry['values'];
foreach ($valueRows as $valueRow) {
try {
$this->connection->beginTransaction();
$statement = $this->connection->prepare($query);
if ($statement === false) {
$this->connection->rollBack();
continue;
}
$statement->execute($valueRow);
$this->connection->commit();
} catch (PDOException | \Throwable $exception) {
$this->connection->rollBack();
}
}
}
return $this;
}
protected function loadValues(string $table, array $conditions = [], string|array $columns = '*'): array
{
$columns = $this->processColumns($columns);
$query = "SELECT {$columns} FROM `{$table}`";
if (count($conditions) > 0) {
$conditionsString = $this->processConditions($conditions);
$query = "{$query} WHERE {$conditionsString}";
}
try {
$statement = $this->connection->prepare($query);
$statement->execute();
} catch (PDOException) {
return [];
}
try {
if ($columns !== '*' and !str_contains($columns, ',')) {
return $statement->fetchAll(PDO::FETCH_COLUMN);
}
return $statement->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException) {
return [];
}
}
protected function processColumns(string|array $columns): string
{
if (is_array($columns)) {
$columns = implode(',', array_map(fn($column) => "`{$column}`", $columns));
}
if ($columns === '*') {
return $columns;
}
$columns = array_map(fn($column) => trim($column), explode(',', $columns));
return implode(', ', array_map(function($column) {
if (!str_contains($column, '`')) {
return "`{$column}`";
}
return $column;
}, $columns));
}
protected function processConditions(array $conditions): array
{
$processedConditions = [];
$processedValues = [];
foreach ($conditions as $condition) {
if (is_string($condition) and (str_starts_with(strtolower($condition), 'and') or str_starts_with(strtolower($condition), 'or'))) {
$processedConditions[] = $condition;
continue;
}
$column = $condition['column'];
$value = $condition['value'];
$match = $condition['match'] ?? 'AND';
$operator = $condition['operator'] ?? '=';
$columnValue = ":{$column}";
if (is_array($value)) {
$columnString = [];
foreach ($value as $idx => $val) {
$columnValue = ":{$column}_{$idx}";
$columnString[] = $columnValue;
$processedValues["{$column}_{$idx}"] = $val;
}
$columnValue = '(' . implode(', ', $columnString) . ')';
if (!str_contains($operator, 'IN')) {
$operator = 'IN';
}
} else {
$processedValues[$column] = $value;
}
$processedConditions[] = "{$match} `{$column}` {$operator} {$columnValue}";
}
return ['query' => implode(' ', $processedConditions), 'values' => $processedValues];
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace Tests\Extension\Faker\Provider;
use Faker\Provider\Base;
class Rut extends Base
{
public function rut(bool $withDigito = true, bool $withDotsAndSlash = true): string
{
$base = self::numberBetween(1000000, 99999999);
$rut = $base;
if ($withDotsAndSlash) {
$rut = number_format($rut, 0, ',', '.');
}
if ($withDigito) {
$digito = $this->getDigito($base);
if ($withDotsAndSlash) {
return "{$digito}-{$rut}";
}
return "{$digito}{$rut}";
}
return $rut;
}
public function digitoVerificador(string $rut): bool|string
{
if ( !preg_match("/^[0-9.]+/",$rut)) return false;
$rut = str_replace('.','',$rut);
return $this->getDigito($rut);
}
protected function getDigito(string $rut): string
{
$M=0;$S=1;
for(;$rut;$rut=floor($rut/10))
$S=($S+$rut%10*(9-$M++%6))%11;
return $S?$S-1:'K';
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Tests\Extension;
use PDO;
interface SeedInterface
{
/**
* @param PDO $connection
* @return self
*/
public function setConnection(PDO $connection): self;
/**
* @return PDO
*/
public function getConnection(): PDO;
/**
* @return array
*/
public function getDependencies(): array;
/**
* @return void
*/
public function run(): void;
}

View File

@ -0,0 +1,33 @@
<?php
namespace Tests\Extension\Seeds;
use Tests\Extension\AbstractSeed;
class Direcciones extends AbstractSeed
{
public function run(): void
{
$comunas = $this->loadValues('comuna', columns: 'id');
$n = 50;
$data = [];
for ($i = 0; $i < $n; $i++) {
$row = [
'calle' => $this->faker->streetName,
'numero' => $this->faker->randomNumber(5),
'comuna' => $this->faker->randomElement($comunas),
'extra' => '',
];
$extraRand = ((int) round(rand() / getrandmax())) === 1;
if ($extraRand) {
$nExtra = (int) round(rand(1, 3));
$row['extra'] = $this->faker->words($nExtra, true);
}
$data[] = $row;
}
$this->table('direccion')
->insertValues($data)
->save();
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace Tests\Extension\Seeds;
use Tests\Extension\AbstractSeed;
class Inmobiliarias extends AbstractSeed
{
public function run(): void
{
$tipos = $this->loadValues('tipo_sociedad', columns: 'id');
$suffixes = [
'Inmobiliaria ',
'Administradora ',
'Asesorías ',
''
];
$n = 5;
$data = [];
for ($i = 0; $i < $n; $i++) {
$rut = $this->faker->rut(false, false);
$abreviacion = $this->faker->streetName;
$suffix = $this->faker->randomElement($suffixes);
$razon = "{$suffix}{$abreviacion}";
$sigla = strtoupper(substr($abreviacion, 0, 3));
$data []= [
'rut' => $rut,
'dv' => $this->faker->digitoVerificador($rut),
'razon' => $razon,
'abreviacion' => $abreviacion,
'sigla' => $sigla,
'sociedad' => $this->faker->randomElement($tipos),
];
}
$this->table('inmobiliaria')
->insertValues($data)
->save();
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace Tests\Extension\Seeds;
use Tests\Extension\AbstractSeed;
class Proyectos extends AbstractSeed
{
public function getDependencies(): array
{
return [
Inmobiliarias::class,
Direcciones::class
];
}
public function run(): void
{
$inmobiliarias = $this->loadValues('inmobiliaria', columns: 'rut');
$direcciones = $this->loadValues('direccion', columns: 'id');
$n = 10;
$data = [];
for ($i = 0; $i < $n; $i++) {
$data[] = [
'inmobiliaria' => $this->faker->randomElement($inmobiliarias),
'descripcion' => $this->faker->words(2, true),
'direccion' => $this->faker->randomElement($direcciones),
'superficie_sobre_nivel' => $this->faker->randomFloat(2, 1000, 10000),
'superficie_bajo_nivel' => $this->faker->randomFloat(2, 0, 5000),
'pisos' => $this->faker->randomNumber(2),
'subterraneos' => $this->faker->randomNumber(2),
'corredor' => $this->faker->randomFloat(4, 0, 1)
];
}
$this->table('proyecto')
->insertValues($data)
->save();
}
}

View File

@ -0,0 +1,70 @@
<?php
namespace Tests\Extension;
use FilesystemIterator;
use PDO;
use PDOException;
class TestSeeder
{
public function __construct(protected PDO $connection) {}
public function run(): void
{
$seedClasses = $this->getSeedClasses();
$orderedSeeds = $this->orderedSeeds($seedClasses);
foreach ($orderedSeeds as $seed) {
$seed->run();
}
}
protected function getSeedClasses(): array
{
$seedsFolder = implode(DIRECTORY_SEPARATOR, [__DIR__, 'Seeds']);
$files = new FilesystemIterator($seedsFolder, FilesystemIterator::SKIP_DOTS);
$seeds = [];
foreach ($files as $file) {
$seeds []= $this->buildClassName($file->getBasename('.php'));
}
return $seeds;
}
protected function getSeed(string $seedClassName): SeedInterface
{
return new $seedClassName($this->connection);
}
protected function buildClassName(string $fileBaseName): string
{
$namespace = implode('\\', [__NAMESPACE__, 'Seeds']);
return implode('\\', [$namespace, $fileBaseName]);
}
protected function orderedSeeds(array $seedClasses): array
{
$orderedSeeds = [];
foreach ($seedClasses as $seedClassName) {
$seed = $this->getSeed($seedClassName);
if ($seed->getDependencies() === []) {
$orderedSeeds[$seedClassName] = $seed;
continue;
}
$orderedSeeds = array_merge($orderedSeeds, $this->orderedDependencies($orderedSeeds, $seedClasses, $seedClassName));
}
return $orderedSeeds;
}
protected function orderedDependencies(array $orderedSeeds, array $seedClasses, string $seedClassName): array
{
$seed = $this->getSeed($seedClassName);
$dependencies = $seed->getDependencies();
foreach ($dependencies as $dependencyClass) {
if (!array_key_exists($dependencyClass, $orderedSeeds)) {
$orderedSeeds = array_merge($orderedSeeds, $this->orderedDependencies($orderedSeeds, $seedClasses, $dependencyClass));
}
}
if (!array_key_exists($seedClassName, $orderedSeeds)) {
$orderedSeeds[$seedClassName] = $seed;
}
return $orderedSeeds;
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Tests\Integration\API\Ventas\MediosPago;
use Tests\Extension\AbstractIntegration;
class TokuTest extends AbstractIntegration
{
public function testCuotas()
{
}
public function testSuccess()
{
}
public function testTest()
{
}
public function testReset()
{
}
public function testEnqueue()
{
}
}

View File

@ -1,13 +1,17 @@
<?php
namespace Incoviba\Test\Integration;
use DateInterval;
use DateTimeImmutable;
use Psr\Container\ContainerInterface;
use PHPUnit\Framework\TestCase;
use Faker;
use Incoviba\Common\Define;
use Incoviba\Common\Implement;
use Incoviba\Common\Ideal;
use Incoviba\Service;
use Incoviba\Repository;
use Tests\Extension\Faker\Provider\Rut;
class QueueTest extends TestCase
{
@ -22,6 +26,7 @@ class QueueTest extends TestCase
public function testServiceWorker(): void
{
$faker = Faker\Factory::create();
$faker->addProvider(new Rut($faker));
$pagoData = [
'fecha' => '2022-01-01',
'valor' => 10000,
@ -37,31 +42,65 @@ class QueueTest extends TestCase
$pago = $pagoService->getById($pago->id);
$this->assertNotEquals(0.0, $pago->uf);
$comunaRepository = $this->container->get(Repository\Comuna::class);
$comunas = $comunaRepository->fetchAll();
$id = $faker->numberBetween(0, count($comunas) - 1);
$comuna = $comunas[$id];
$direccionData = [
'calle' => $faker->streetName,
'numero' => $faker->buildingNumber,
'comuna' => $comuna->id
];
$direccionRepository = $this->container->get(Repository\Direccion::class);
$direcciones = $direccionRepository->fetchAll();
$direccion = $faker->randomElement($direcciones);
$rut = $faker->rut(false, false);
$propietarioData = [
'rut' => $faker->numberBetween(10000000, 99999999),
'nombre' => $faker->name,
'rut' => $rut,
'dv' => $faker->digitoVerificador($rut),
'direccion' => $direccion->id,
'nombres' => $faker->firstName,
'apellido_paterno' => $faker->lastName,
'apellido_materno' => $faker->lastName,
'email' => $faker->email,
'telefono' => $faker->randomNumber(9),
];
$propietarioRepository = $this->container->get(Repository\Venta\Propietario::class);
$propietario = $propietarioRepository->create($propietarioData);
$propietario = $propietarioRepository->save($propietario);
$proyectoRepository = $this->container->get(Repository\Proyecto::class);
$proyectos = $proyectoRepository->fetchAll();
$proyecto = $faker->randomElement($proyectos);
$tipoUnidadRepository = $this->container->get(Repository\Proyecto\TipoUnidad::class);
$tiposUnidades = $tipoUnidadRepository->fetchAll();
$tipoUnidad = $faker->randomElement($tiposUnidades);
$proyectoTipoUnidadData = [
'proyecto' => $proyecto->id,
'tipo' => $tipoUnidad->id,
'nombre' => $faker->word,
'descripcion' => $faker->sentence,
'abreviacion' => substr($faker->word, 0, 1),
'logia' => $faker->randomFloat(2, 1, 20),
'terraza' => $faker->randomFloat(2, 1, 20),
'm2' => $faker->randomFloat(2, 20, 100),
];
$proyectoTipoUnidadRepository = $this->container->get(Repository\Proyecto\ProyectoTipoUnidad::class);
$proyectoTipoUnidad = $proyectoTipoUnidadRepository->create($proyectoTipoUnidadData);
$proyectoTipoUnidad = $proyectoTipoUnidadRepository->save($proyectoTipoUnidad);
$unidadData = [
'proyecto' => $proyecto->id,
'tipo' => $tipoUnidad->id,
'piso' => $faker->numberBetween(1, 300),
'descripcion' => "{$tipoUnidad->descripcion} {$faker->numberBetween(1, 300)}",
'orientacion' => $faker->randomElement(['N', 'NE', 'NO', 'S', 'SE', 'SO', 'E', 'O']),
'pt' => $proyectoTipoUnidad->id,
];
$unidadRepository = $this->container->get(Repository\Venta\Unidad::class);
$unidad = $unidadRepository->create($unidadData);
$unidad = $unidadRepository->save($unidad);
$propiedadData = [
'unidad_principal' => $unidad->id,
];
$propiedadRepository = $this->container->get(Repository\Venta\Propiedad::class);
$propiedad = $propiedadRepository->create();
$propiedad = $propiedadRepository->create($propiedadData);
$propiedad = $propiedadRepository->save($propiedad);
$fecha = $faker->date;
$ventaData = [
'fecha' => '2022-01-01',
'fecha' => $fecha,
'propietario' => $propietario->rut,
'propiedad' => $propiedad->id,
'fecha_ingreso' => new DateTimeImmutable($fecha)->add(new DateInterval('P3D'))->format('Y-m-d'),
];
$ventaRepository = $this->container->get(Repository\Venta::class);
$venta = $ventaRepository->create($ventaData);
@ -83,4 +122,4 @@ class QueueTest extends TestCase
$cuota = $cuotaService->getById($cuota->id);
$this->assertNotEquals(0.0, $cuota->pago->uf);
}
}
}