Files
City10/tests/Feature/WorkerRobotTest.php
T
marcocosta10000 ecf5291027 feat(city): add humanoid worker robots as city agents
Seed five worker robot agents (TR-01 to TR-05) with Portuguese
system prompts and active status. Extend the 3D humanoid renderer
with metallic materials, glowing visor, antenna beacon, and chest
status light for the worker_robot type. Add feature tests covering
payload serialization and city bounds validation.
2026-10-31 22:31:03 -03:00

89 lines
2.9 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\AiAgent;
use App\Models\Character;
use App\Models\User;
use Database\Seeders\CityWorldSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
/**
* Humanoid worker robots: seeded as walkable agents with allow-listed
* models and in-city positions so the viewer spawns them on routes.
*/
class WorkerRobotTest extends TestCase
{
use RefreshDatabase;
/**
* Boot world fixtures.
*/
protected function setUp(): void
{
parent::setUp();
$this->seed(CityWorldSeeder::class);
$user = User::factory()->create(['status' => User::STATUS_ACTIVE, 'is_active' => true]);
Character::ensureForUser($user);
$this->actingAs($user);
}
/**
* The payload carries the five worker robots; their AI personas
* (model/prompt) live only in the database — never in the public
* world payload.
*/
public function test_payload_contains_worker_robots(): void
{
$payload = $this->getJson('/city/data')->assertOk()->json();
$robots = array_values(array_filter(
$payload['agents'],
static fn (array $a): bool => $a['type'] === 'worker_robot'
));
$this->assertCount(5, $robots);
$this->assertSame(
['Robô TR-01', 'Robô TR-02', 'Robô TR-03', 'Robô TR-04', 'Robô TR-05'],
array_column($robots, 'name')
);
foreach ($robots as $robot) {
$this->assertSame('active', $robot['status']);
}
// Personas are stored server-side only.
$this->assertArrayNotHasKey('model', $robots[0]);
$this->assertArrayNotHasKey('system_prompt', $robots[0]);
foreach (AiAgent::where('type', 'worker_robot')->get() as $agent) {
$this->assertContains($agent->model, config('ai.allowed_models'));
$this->assertNotEmpty($agent->system_prompt);
$this->assertStringContainsString('robô', $agent->system_prompt);
}
}
/**
* Robot spawn points sit inside the city bounds (they seed the DB
* row; the viewer re-places them on walking routes).
*/
public function test_robot_positions_stay_inside_city_bounds(): void
{
$payload = $this->getJson('/city/data')->assertOk()->json();
$bounds = $payload['city']['bounds'];
$robots = array_values(array_filter(
$payload['agents'],
static fn (array $a): bool => $a['type'] === 'worker_robot'
));
$this->assertNotEmpty($robots);
foreach ($robots as $robot) {
$this->assertGreaterThanOrEqual($bounds['min_x'], $robot['position'][0]);
$this->assertLessThanOrEqual($bounds['max_x'], $robot['position'][0]);
$this->assertGreaterThanOrEqual($bounds['min_z'], $robot['position'][2]);
$this->assertLessThanOrEqual($bounds['max_z'], $robot['position'][2]);
}
}
}