dootask/tests/Feature/UserTransferOwnerRoleTest.php

181 lines
6.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Tests\Feature;
use App\Models\User;
use App\Models\UserTransfer;
use App\Models\WebSocketDialog;
use App\Models\WebSocketDialogUser;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\TestCase;
/**
* P0-B离职转移普通群群主时 role/deputy_ids 必须同步
*/
class UserTransferOwnerRoleTest extends TestCase
{
use DatabaseTransactions;
private function isSwooleInfraFailure(\Throwable $e): bool
{
$msg = $e->getMessage();
return str_contains($msg, 'swoole')
|| str_contains($msg, 'Swoole')
|| str_contains($msg, 'AbstractData::__wakeup')
|| str_contains($msg, 'Undefined array key');
}
private function makeUser(string $email): User
{
$user = User::createInstance([
'email' => $email,
'userimg' => '',
'nickname' => 'TestUser_' . substr(md5($email), 0, 6),
'profession' => '',
'password' => md5('123456'),
]);
$user->save();
return $user;
}
/**
* 离职移交后:接收人 role=1且 deputy_ids 不再包含他(哪怕之前是群管理员)
*/
public function test_transfer_promotes_deputy_receiver_to_owner_role_one()
{
$original = $this->makeUser('orig_owner@test.local');
$receiver = $this->makeUser('xfer_receiver@test.local');
// original 为群主、receiver 为群管理员role=2的普通 user 群
$dialog = WebSocketDialog::createGroup(
'XferUserGroup',
[$original->userid, $receiver->userid],
'user',
$original->userid
);
WebSocketDialogUser::where('dialog_id', $dialog->id)
->where('userid', $receiver->userid)
->update(['role' => 2]);
// 移交前断言
$this->assertContains((int)$receiver->userid, $dialog->fresh()->deputy_ids);
// 触发离职移交exitDialog 路径)
$transfer = new UserTransfer();
$transfer->original_userid = $original->userid;
$transfer->new_userid = $receiver->userid;
try {
$transfer->exitDialog();
} catch (\Throwable $e) {
if (str_contains($e->getMessage(), 'swoole')) {
$this->markTestSkipped('Swoole runtime 不可用UserTransfer::exitDialog 无法在当前环境中端到端验证:' . $e->getMessage());
}
throw $e;
}
// 群主已切换
$dialog = WebSocketDialog::find($dialog->id);
$this->assertEquals($receiver->userid, (int)$dialog->owner_id, '群主应转移为接收人');
// original 已退群
$this->assertFalse(
WebSocketDialogUser::where('dialog_id', $dialog->id)
->where('userid', $original->userid)
->exists(),
'原群主应已退出群组'
);
// receiver role=1从 deputy 升级为 primary owner
$receiverDu = WebSocketDialogUser::where('dialog_id', $dialog->id)
->where('userid', $receiver->userid)
->first();
$this->assertNotNull($receiverDu);
$this->assertEquals(1, (int)$receiverDu->role, '接收人 role 应升级为 1primary owner');
// deputy_ids 不再包含 receiver
$this->assertNotContains((int)$receiver->userid, $dialog->fresh()->deputy_ids,
'接收人升为群主后 deputy_ids 不应再包含他');
}
/**
* 离职移交接收人不在群中exitDialog 把他作为新成员加入role 也应被设为 1
*/
public function test_transfer_adds_new_receiver_with_owner_role_one()
{
$original = $this->makeUser('orig2_owner@test.local');
$receiver = $this->makeUser('xfer2_receiver@test.local');
// 群里只有 original
$dialog = WebSocketDialog::createGroup(
'XferUserGroup2',
[$original->userid],
'user',
$original->userid
);
$transfer = new UserTransfer();
$transfer->original_userid = $original->userid;
$transfer->new_userid = $receiver->userid;
try {
$transfer->exitDialog();
} catch (\Throwable $e) {
if ($this->isSwooleInfraFailure($e)) {
$this->markTestSkipped('Swoole/PushTask 运行时不可用:' . $e->getMessage());
}
throw $e;
}
$dialog = WebSocketDialog::find($dialog->id);
$this->assertEquals($receiver->userid, (int)$dialog->owner_id);
$receiverDu = WebSocketDialogUser::where('dialog_id', $dialog->id)
->where('userid', $receiver->userid)
->first();
$this->assertNotNull($receiverDu, '接收人应被 joinGroup 加入群组');
$this->assertEquals(1, (int)$receiverDu->role, '接收人 role 应为 1');
}
/**
* 离职移交original 不是群主时(普通成员),不触发 owner 转移逻辑
*/
public function test_transfer_does_not_promote_when_original_not_owner()
{
$owner = $this->makeUser('grp_owner@test.local');
$original = $this->makeUser('orig3_member@test.local');
$receiver = $this->makeUser('xfer3_receiver@test.local');
$dialog = WebSocketDialog::createGroup(
'XferUserGroup3',
[$owner->userid, $original->userid, $receiver->userid],
'user',
$owner->userid
);
// receiver 是 role=2 的群管理员
WebSocketDialogUser::where('dialog_id', $dialog->id)
->where('userid', $receiver->userid)
->update(['role' => 2]);
$transfer = new UserTransfer();
$transfer->original_userid = $original->userid;
$transfer->new_userid = $receiver->userid;
try {
$transfer->exitDialog();
} catch (\Throwable $e) {
if ($this->isSwooleInfraFailure($e)) {
$this->markTestSkipped('Swoole/PushTask 运行时不可用:' . $e->getMessage());
}
throw $e;
}
// 原群主未变
$dialog = WebSocketDialog::find($dialog->id);
$this->assertEquals($owner->userid, (int)$dialog->owner_id);
// receiver 仍然是群管理员role=2
$receiverDu = WebSocketDialogUser::where('dialog_id', $dialog->id)
->where('userid', $receiver->userid)
->first();
$this->assertEquals(2, (int)$receiverDu->role);
}
}