array( 'url' => 'https://staging.example.test/uploads/hero.jpg', ), 'count' => 3, 'flag' => true, ), $transformer->transformValue( array( 'hero' => array( 'url' => 'https://example.test/uploads/hero.jpg', ), 'count' => 3, 'flag' => true, ), $this->mappings() ) ); } public function test_it_transforms_json_strings(): void { $transformer = new MetadataUrlTransformer( new UrlTransformer() ); $result = $transformer->transformValue( '{"url":"https:\/\/example.test\/uploads\/hero.jpg"}', $this->mappings() ); self::assertSame( '{"url":"https:\/\/staging.example.test\/uploads\/hero.jpg"}', $result ); } public function test_it_preserves_serialized_data_validity(): void { $transformer = new MetadataUrlTransformer( new UrlTransformer() ); // phpcs:ignore -- Test fixture requires native serialized metadata. $serialized = serialize( array( 'url' => 'https://example.test/uploads/hero.jpg', ) ); $result = $transformer->transformValue( $serialized, $this->mappings() ); self::assertSame( array( 'url' => 'https://staging.example.test/uploads/hero.jpg', ), // phpcs:ignore -- Assertion verifies the transformed serialized metadata remains valid. unserialize( $result ) ); } public function test_it_leaves_invalid_serialized_strings_unchanged(): void { $transformer = new MetadataUrlTransformer( new UrlTransformer() ); $value = 'a:1:{s:3:"url";s:37:"https://example.test/uploads/hero.jpg";} trailing'; self::assertSame( $value, $transformer->transformValue( $value, $this->mappings() ) ); } public function test_it_leaves_whitespace_wrapped_serialized_strings_unchanged(): void { $transformer = new MetadataUrlTransformer( new UrlTransformer() ); // phpcs:ignore -- Test fixture requires native serialized metadata. $value = ' ' . serialize( array( 'url' => 'https://example.test/uploads/hero.jpg' ) ) . ' '; self::assertSame( $value, $transformer->transformValue( $value, $this->mappings() ) ); } public function test_it_preserves_serialized_false_and_null_values(): void { $transformer = new MetadataUrlTransformer( new UrlTransformer() ); self::assertSame( 'b:0;', $transformer->transformValue( 'b:0;', $this->mappings() ) ); self::assertSame( 'N;', $transformer->transformValue( 'N;', $this->mappings() ) ); } public function test_it_leaves_serialized_objects_unchanged(): void { $transformer = new MetadataUrlTransformer( new UrlTransformer() ); $value = 'O:8:"stdClass":1:{s:3:"url";s:27:"https://example.test/inside";}'; self::assertSame( $value, $transformer->transformValue( $value, $this->mappings() ) ); } public function test_it_leaves_serialized_payloads_with_nested_objects_unchanged(): void { $transformer = new MetadataUrlTransformer( new UrlTransformer() ); $value = 'a:2:{s:3:"url";s:27:"https://example.test/inside";s:6:"object";O:8:"stdClass":0:{}}'; self::assertSame( $value, $transformer->transformValue( $value, $this->mappings() ) ); } public function test_it_leaves_invalid_json_strings_unchanged(): void { $transformer = new MetadataUrlTransformer( new UrlTransformer() ); $value = '{"url":"https://example.test/missing"'; self::assertSame( $value, $transformer->transformValue( $value, $this->mappings() ) ); } public function test_it_transforms_nested_json_arrays(): void { $transformer = new MetadataUrlTransformer( new UrlTransformer() ); self::assertSame( '[{"url":"https:\/\/staging.example.test\/one"},{"count":2}]', $transformer->transformValue( '[{"url":"https:\/\/example.test\/one"},{"count":2}]', $this->mappings() ) ); } public function test_it_transforms_plain_string_metadata(): void { $transformer = new MetadataUrlTransformer( new UrlTransformer() ); self::assertSame( 'https://staging.example.test/contact', $transformer->transformValue( 'https://example.test/contact', $this->mappings() ) ); } }