create(); $store = StoreModel::factory()->withPassword('abc12345')->create([ 'username' => 'store_login_1', 'level_id' => $level->id, ]); $response = $this->postJson('/mini/auth/login', [ 'username' => 'store_login_1', 'password' => 'abc12345', ]); $response->assertOk() ->assertJsonPath('success', true) ->assertJsonStructure(['data' => ['token', 'user' => ['id', 'name', 'code', 'level']]]); $this->assertNotEmpty($response->json('data.token')); $this->assertSame($store->id, $response->json('data.user.id')); // 密码永不回显 $this->assertArrayNotHasKey('password', $response->json('data.user')); $this->assertNotNull($store->refresh()->last_login_at); } /** 密码错误 → 拒绝 */ public function test_login_rejects_wrong_password(): void { StoreModel::factory()->withPassword('abc12345')->create(['username' => 'store_login_2']); $this->postJson('/mini/auth/login', [ 'username' => 'store_login_2', 'password' => 'wrong_pwd', ])->assertOk() ->assertJsonPath('success', false); } /** 账号不存在 → 拒绝 */ public function test_login_rejects_unknown_username(): void { $this->postJson('/mini/auth/login', [ 'username' => 'not_exist', 'password' => 'abc12345', ])->assertOk() ->assertJsonPath('success', false); } /** 停用门店拒绝登录 */ public function test_disabled_store_cannot_login(): void { StoreModel::factory()->disabled()->withPassword('abc12345')->create(['username' => 'store_login_3']); $this->postJson('/mini/auth/login', [ 'username' => 'store_login_3', 'password' => 'abc12345', ])->assertOk() ->assertJsonPath('success', false); } /** 登录参数缺失 → 校验失败 */ public function test_login_validates_required_params(): void { $this->postJson('/mini/auth/login', []) ->assertOk() ->assertJsonPath('success', false); } /** 登录签发的 token 可访问受保护接口,auth/info 返回当前门店 */ public function test_login_token_accesses_protected_routes(): void { $store = StoreModel::factory()->withPassword('abc12345')->create(['username' => 'store_login_4']); $login = $this->postJson('/mini/auth/login', [ 'username' => 'store_login_4', 'password' => 'abc12345', ]); $token = $login->json('data.token'); $this->withToken($token)->getJson('/mini/auth/info') ->assertOk() ->assertJsonPath('success', true) ->assertJsonPath('data.id', $store->id); } /** 修改密码:原密码正确 → 新密码可登录 */ public function test_set_password_succeeds(): void { $store = StoreModel::factory()->withPassword('old_pwd_1')->create(); $this->actingAsMiniStore($store); $this->putJson('/mini/auth/password', [ 'oldPassword' => 'old_pwd_1', 'newPassword' => 'new_pwd_1', 'rePassword' => 'new_pwd_1', ])->assertOk() ->assertJsonPath('success', true); $this->postJson('/mini/auth/login', [ 'username' => $store->username, 'password' => 'new_pwd_1', ])->assertOk() ->assertJsonPath('success', true); } /** 修改密码:原密码错误 → 拒绝 */ public function test_set_password_rejects_wrong_old_password(): void { $store = StoreModel::factory()->withPassword('old_pwd_2')->create(); $this->actingAsMiniStore($store); $this->putJson('/mini/auth/password', [ 'oldPassword' => 'bad_old', 'newPassword' => 'new_pwd_2', 'rePassword' => 'new_pwd_2', ])->assertOk() ->assertJsonPath('success', false); } /** 修改密码:两次输入不一致 → 校验失败 */ public function test_set_password_validates_confirmation(): void { $store = StoreModel::factory()->create(); $this->actingAsMiniStore($store); $this->putJson('/mini/auth/password', [ 'oldPassword' => '123456', 'newPassword' => 'new_pwd_3', 'rePassword' => 'different', ])->assertOk() ->assertJsonPath('success', false); } /** 跨端隔离:后台 token 访问小程序接口 → 401 */ public function test_sys_token_cannot_access_mini(): void { $this->actingAsSysUser(); $this->getJson('/mini/auth/info')->assertStatus(401); } /** 跨端隔离:小程序 token 访问后台接口 → 401 */ public function test_mini_token_cannot_access_admin_api(): void { $this->actingAsMiniStore(StoreModel::factory()->create()); $this->getJson('/customer/level')->assertStatus(401); } }