seed(CityWorldSeeder::class); } /** * Friendship request flows from pending to accepted. */ public function test_friend_request_and_accept(): void { $a = Character::factory()->create(); $b = Character::factory()->create(); $userA = User::factory()->create(['status' => User::STATUS_ACTIVE, 'is_active' => true]); $a->user_id = $userA->id; $a->save(); $this->actingAs($userA) ->postJson('/city/social/friend', ['character_id' => $b->id]) ->assertOk(); $rel = Relationship::where('type', Relationship::TYPE_FRIEND) ->where('character_a_id', $a->id) ->where('character_b_id', $b->id) ->first(); $this->assertNotNull($rel); $this->assertSame(Relationship::STATUS_PENDING, $rel->status); $userB = User::factory()->create(['status' => User::STATUS_ACTIVE, 'is_active' => true]); $b->user_id = $userB->id; $b->save(); $this->actingAs($userB) ->postJson('/city/social/accept-friend', ['relationship_id' => $rel->id]) ->assertOk(); $this->assertSame(Relationship::STATUS_ACCEPTED, $rel->fresh()->status); } /** * Marriage requires an accepted friendship. */ public function test_marry_requires_friendship(): void { $userA = User::factory()->create(['status' => User::STATUS_ACTIVE, 'is_active' => true]); $a = Character::ensureForUser($userA); $b = Character::factory()->create(['city_id' => $a->city_id]); $this->actingAs($userA) ->postJson('/city/social/marry', ['character_id' => $b->id]) ->assertStatus(422); } /** * Spouses can have an NPC child linked to both parents. */ public function test_child_creates_npc_character(): void { $userA = User::factory()->create(['status' => User::STATUS_ACTIVE, 'is_active' => true]); $a = Character::ensureForUser($userA); $b = Character::factory()->create(['city_id' => $a->city_id, 'name' => 'Parceiro']); Relationship::create([ 'character_a_id' => $a->id, 'character_b_id' => $b->id, 'type' => Relationship::TYPE_FRIEND, 'status' => Relationship::STATUS_ACCEPTED, ]); Relationship::create([ 'character_a_id' => $a->id, 'character_b_id' => $b->id, 'type' => Relationship::TYPE_SPOUSE, 'status' => Relationship::STATUS_ACCEPTED, ]); $before = Character::count(); $this->actingAs($userA) ->postJson('/city/social/child', ['character_id' => $b->id]) ->assertOk(); $this->assertSame($before + 1, Character::count()); $child = Character::orderByDesc('id')->first(); $this->assertNull($child->user_id); $this->assertSame(2, Relationship::where('type', Relationship::TYPE_PARENT_CHILD) ->where('character_a_id', $child->id)->count()); } /** * Messages persist between characters. */ public function test_character_chat_persists(): void { $userA = User::factory()->create(['status' => User::STATUS_ACTIVE, 'is_active' => true]); $a = Character::ensureForUser($userA); $b = Character::factory()->create(['city_id' => $a->city_id]); $this->actingAs($userA) ->postJson("/city/messages/{$b->id}", ['body' => 'Olá vizinho!']) ->assertOk(); $this->assertSame(1, CharacterMessage::count()); $this->actingAs($userA) ->getJson("/city/messages/{$b->id}") ->assertOk() ->assertJsonPath('me', $a->id) ->assertJsonPath('messages.0.body', 'Olá vizinho!'); } }