| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- <?php
- namespace Tests\Integration;
- use App\Http\Controllers\admin\User as UserController;
- use Illuminate\Config\Repository;
- use Illuminate\Database\Capsule\Manager;
- use Illuminate\Database\Eloquent\Model;
- use Illuminate\Database\Schema\Blueprint;
- use Illuminate\Foundation\Application;
- use Illuminate\Http\Request;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Facade;
- use Illuminate\Translation\ArrayLoader;
- use Illuminate\Translation\Translator;
- use Illuminate\Validation\Factory;
- use PHPUnit\Framework\TestCase;
- class AdminUserLoginLogTest extends TestCase
- {
- private Application $app;
- protected function setUp(): void
- {
- parent::setUp();
- Facade::clearResolvedInstances();
- Model::clearBootedModels();
- $this->app = new Application(dirname(__DIR__, 2));
- $this->app->instance('config', new Repository(['app' => ['locale' => 'zh', 'timezone' => 'Asia/Shanghai']]));
- $translator = new Translator(new ArrayLoader(), 'zh');
- $this->app->instance('translator', $translator);
- $this->app->instance('validator', new Factory($translator, $this->app));
- $this->app->instance(\Illuminate\Contracts\Routing\ResponseFactory::class, new \Tests\Support\JsonResponseFactory());
- Request::macro('validate', function (array $rules) {
- return app('validator')->make($this->all(), $rules)->validate();
- });
- Facade::setFacadeApplication($this->app);
- $db = new Manager($this->app);
- $db->addConnection($this->connectionConfig());
- $db->setAsGlobal();
- $db->bootEloquent();
- $this->app->instance('db', $db->getDatabaseManager());
- $db->schema()->create('users', function (Blueprint $t) {
- $t->id();
- $t->string('user_id')->nullable();
- $t->string('member_id');
- $t->string('account')->nullable();
- $t->string('from')->nullable();
- $t->string('first_name')->default('');
- $t->string('username')->default('');
- });
- $db->schema()->create('user_login', function (Blueprint $t) {
- $t->id();
- $t->string('user_id')->nullable();
- foreach (['login_account', 'login_ip', 'login_domain', 'country', 'browser', 'os', 'platform', 'user_agent'] as $field) {
- $t->string($field)->default('');
- }
- $t->integer('status');
- $t->dateTime('logout_time')->nullable();
- $t->integer('online_duration')->nullable();
- $t->timestamps();
- });
- foreach ([
- ['1001', 'alice', '1'],
- ['1002', 'tg1002', '-1'],
- ['1003', 'guest1003', '2'],
- ['1004', 'kefu_member', '1'],
- ['1005', 'legacy', null],
- ['9001', 'kefu001', '0'],
- ['9002', 'kefu002', '0'],
- ['9003', 'support-alpha', '0'],
- ['', 'desk-blank-id', '0'],
- [null, 'desk-null-id', '0'],
- ] as [$userId, $account, $from]) {
- DB::table('users')->insert([
- 'user_id' => $userId, 'member_id' => $account, 'account' => $account,
- 'from' => $from, 'first_name' => $account,
- ]);
- }
- }
- protected function tearDown(): void
- {
- DB::disconnect();
- Facade::clearResolvedInstances();
- Model::clearBootedModels();
- parent::tearDown();
- }
- public function test_excludes_customer_service_successes_and_failures_from_list_and_total(): void
- {
- $expected = [];
- foreach (['1001', '1002', '1003', '1004', '1005'] as $userId) {
- $expected[] = $this->log($userId, '', 1);
- }
- foreach (['9001', '9002', '9003'] as $userId) {
- $this->log($userId, '', 1);
- $this->log($userId, '', 0);
- }
- $data = $this->logs();
- $this->assertSame(5, $data['total']);
- $this->assertSame(array_reverse($expected), array_column($data['data'], 'id'));
- $this->assertSame(11, DB::table('user_login')->count());
- }
- public function test_identifies_customer_service_failures_by_account_when_user_id_is_missing(): void
- {
- foreach (['', null, 'deleted-id'] as $userId) {
- foreach (['kefu001', 'kefu002', 'support-alpha', 'desk-blank-id', 'desk-null-id'] as $account) {
- $this->log($userId, $account, 0);
- }
- }
- $expected = [
- $this->log('', 'unknown-account', 0),
- $this->log(null, 'another-unknown', 0),
- $this->log('deleted-member', 'former-member', 0),
- $this->log('', 'kefu_not_staff', 0),
- $this->log('', '', 0),
- ];
- $data = $this->logs(['status' => 0]);
- $this->assertSame(5, $data['total']);
- $this->assertSame(array_reverse($expected), array_column($data['data'], 'id'));
- foreach ($data['data'] as $row) {
- $this->assertNull($row['account']);
- }
- }
- public function test_account_and_user_filters_cannot_restore_customer_service_records(): void
- {
- $this->log('9001', 'kefu001', 1);
- $this->log('', 'kefu001', 0);
- $memberId = $this->log('1004', 'kefu_member', 1);
- $data = $this->logs(['account' => 'kefu']);
- $this->assertSame(1, $data['total']);
- $this->assertSame([$memberId], array_column($data['data'], 'id'));
- foreach ([['account' => 'kefu001'], ['user_id' => '9001'], ['member_id' => '9001'], ['first_name' => 'kefu001']] as $params) {
- $this->assertSame(['total' => 0, 'data' => []], $this->logs($params));
- }
- }
- public function test_member_filters_and_pagination_keep_normal_failed_logins(): void
- {
- $this->log('1001', 'alice', 1);
- $older = $this->log('1001', 'alice', 0);
- $newer = $this->log('1001', 'alice', 0, '2026-11-07 12:00:01');
- $this->log('9001', 'kefu001', 0, '2026-11-07 12:00:02');
- $this->log('1001', 'alice', 0, '2026-11-06 23:59:59');
- $params = ['account' => 'ali', 'user_id' => '1001', 'status' => 0,
- 'start_time' => '2026-11-07', 'end_time' => '2026-11-07', 'limit' => 1];
- $data = $this->logs($params);
- $this->assertSame(2, $data['total']);
- $this->assertSame([$newer], array_column($data['data'], 'id'));
- $this->assertSame('alice', $data['data'][0]['account']);
- $this->assertFalse($data['data'][0]['is_online']);
- $data = $this->logs($params + ['page' => 2]);
- $this->assertSame(2, $data['total']);
- $this->assertSame([$older], array_column($data['data'], 'id'));
- }
- protected function connectionConfig(): array
- {
- return ['driver' => 'sqlite', 'database' => ':memory:', 'prefix' => 'bot_'];
- }
- protected function log(?string $userId, string $account, int $status, string $at = '2026-11-07 12:00:00'): int
- {
- return DB::table('user_login')->insertGetId([
- 'user_id' => $userId, 'login_account' => $account, 'status' => $status,
- 'created_at' => $at, 'updated_at' => $at,
- ]);
- }
- protected function logs(array $params = []): array
- {
- $this->app->instance('request', Request::create('/admin/user/loginLog', 'GET', $params));
- $body = (new UserController())->loginLog()->getData(true);
- $this->assertSame(0, $body['code'], $body['msg']);
- return $body['data'];
- }
- }
|