class JsonEncoderTest

Same name in this branch
  1. main core/modules/jsonapi/tests/src/Unit/Encoder/JsonEncoderTest.php \Drupal\Tests\jsonapi\Unit\Encoder\JsonEncoderTest
Same name and namespace in other branches
  1. 11.x core/modules/serialization/tests/src/Unit/Encoder/JsonEncoderTest.php \Drupal\Tests\serialization\Unit\Encoder\JsonEncoderTest
  2. 10 core/modules/serialization/tests/src/Unit/Encoder/JsonEncoderTest.php \Drupal\Tests\serialization\Unit\Encoder\JsonEncoderTest
  3. 9 core/modules/serialization/tests/src/Unit/Encoder/JsonEncoderTest.php \Drupal\Tests\serialization\Unit\Encoder\JsonEncoderTest
  4. 8.9.x core/modules/serialization/tests/src/Unit/Encoder/JsonEncoderTest.php \Drupal\Tests\serialization\Unit\Encoder\JsonEncoderTest
  5. 11.x core/modules/jsonapi/tests/src/Unit/Encoder/JsonEncoderTest.php \Drupal\Tests\jsonapi\Unit\Encoder\JsonEncoderTest

Tests Drupal\serialization\Encoder\JsonEncoder.

Attributes

#[CoversClass(JsonEncoder::class)] #[Group('serialization')]

Hierarchy

Expanded class hierarchy of JsonEncoderTest

File

core/modules/serialization/tests/src/Unit/Encoder/JsonEncoderTest.php, line 15

Namespace

Drupal\Tests\serialization\Unit\Encoder
View source
class JsonEncoderTest extends UnitTestCase {
  
  /**
   * The encoder under test.
   */
  protected JsonEncoder $encoder;
  
  /**
   * {@inheritdoc}
   */
  protected function setUp() : void {
    parent::setUp();
    $this->encoder = new JsonEncoder();
  }
  
  /**
   * Tests the supportsEncoding() method.
   */
  public function testSupportsEncoding() : void {
    $this->assertTrue($this->encoder
      ->supportsEncoding('json'));
    $this->assertTrue($this->encoder
      ->supportsEncoding('ajax'));
    $this->assertFalse($this->encoder
      ->supportsEncoding('xml'));
  }
  
  /**
   * Tests that invalid UTF-8 is handled via JSON_INVALID_UTF8_SUBSTITUTE.
   *
   * @see https://www.drupal.org/project/drupal/issues/3549107
   */
  public function testEncodeInvalidUtf8IsSubstituted() : void {
    // A representative invalid UTF-8 sequence that would previously cause
    // json_encode() to fail.
    $input = "Test\x80Data";
    $encoded = $this->encoder
      ->encode($input, 'json');
    // Verify it's valid JSON (would fail without the flag).
    $this->assertJson($encoded, 'Encoded output should be valid JSON even with invalid UTF-8.');
    // Verify the replacement character is present.
    $this->assertStringContainsString('\\ufffd', $encoded, 'Invalid UTF-8 should be replaced with U+FFFD.');
    // Verify it can be decoded.
    json_decode($encoded);
    $this->assertSame(JSON_ERROR_NONE, json_last_error(), 'Encoded JSON should be decodable without errors.');
  }
  
  /**
   * Tests that HTML-unsafe characters are still escaped.
   *
   * This ensures that existing JSON_HEX_* behavior is preserved after adding
   * JSON_INVALID_UTF8_SUBSTITUTE.
   */
  public function testHtmlUnsafeCharactersAreEscaped() : void {
    $input = "<script>alert('test & \"hack\"');</script>";
    $encoded = $this->encoder
      ->encode($input, 'json');
    // Verify it's valid JSON.
    $this->assertJson($encoded, 'HTML-unsafe characters should produce valid JSON.');
    // Verify HTML-unsafe characters are escaped as hex codes.
    $this->assertStringContainsString('\\u003C', $encoded, '< should be escaped to \\u003C.');
    $this->assertStringContainsString('\\u003E', $encoded, '> should be escaped to \\u003E.');
    $this->assertStringContainsString('\\u0027', $encoded, "' should be escaped to \\u0027.");
    $this->assertStringContainsString('\\u0026', $encoded, '& should be escaped to \\u0026.');
    $this->assertStringContainsString('\\u0022', $encoded, '" should be escaped to \\u0022.');
  }
  
  /**
   * Simple structured data smoke test.
   *
   * This verifies that the encoder works for nested arrays and that invalid
   * UTF-8 inside the structure is still handled correctly.
   */
  public function testStructuredDataSmokeTest() : void {
    $data = [
      'title' => 'Example',
      'body' => "Content with invalid UTF-8: \x80",
      'metadata' => [
        'tags' => [
          'one',
          'two',
        ],
      ],
    ];
    $encoded = $this->encoder
      ->encode($data, 'json');
    $this->assertJson($encoded, 'Structured data should produce valid JSON.');
    $this->assertStringContainsString('\\ufffd', $encoded, 'Invalid UTF-8 in nested data should be replaced.');
    $decoded = json_decode($encoded, TRUE);
    $this->assertSame(JSON_ERROR_NONE, json_last_error(), 'Structured data should be decodable.');
    $this->assertIsArray($decoded, 'Decoded data should be an array.');
    $this->assertArrayHasKey('title', $decoded, 'Decoded data should have title key.');
    $this->assertArrayHasKey('metadata', $decoded, 'Decoded data should have metadata key.');
  }

}

Members

Title Sort descending Deprecated Modifiers Object type Summary Overriden Title
DrupalTestCaseTrait::checkErrorHandlerOnTearDown public function Checks the test error handler after test execution.
ExpectDeprecationTrait::expectDeprecation Deprecated public function Adds an expected deprecation.
ExpectDeprecationTrait::regularExpressionForFormatDescription private function
JsonEncoderTest::$encoder protected property The encoder under test.
JsonEncoderTest::setUp protected function Overrides UnitTestCase::setUp
JsonEncoderTest::testEncodeInvalidUtf8IsSubstituted public function Tests that invalid UTF-8 is handled via JSON_INVALID_UTF8_SUBSTITUTE.
JsonEncoderTest::testHtmlUnsafeCharactersAreEscaped public function Tests that HTML-unsafe characters are still escaped.
JsonEncoderTest::testStructuredDataSmokeTest public function Simple structured data smoke test.
JsonEncoderTest::testSupportsEncoding public function Tests the supportsEncoding() method.
RandomGeneratorTrait::getRandomGenerator protected function Gets the random generator for the utility methods.
RandomGeneratorTrait::randomMachineName protected function Generates a unique random string containing letters and numbers.
RandomGeneratorTrait::randomObject public function Generates a random PHP object.
RandomGeneratorTrait::randomString public function Generates a pseudo-random string of ASCII characters of codes 32 to 126.
UnitTestCase::$root protected property The app root.
UnitTestCase::getClassResolverStub protected function Returns a stub class resolver.
UnitTestCase::getConfigFactoryStub public function Returns a stub config factory that behaves according to the passed array.
UnitTestCase::getContainerWithCacheTagsInvalidator protected function Sets up a container with a cache tags invalidator.
UnitTestCase::getStringTranslationStub public function Returns a stub translation manager that just returns the passed string.
UnitTestCase::setDebugDumpHandler public static function Registers the dumper CLI handler when the DebugDump extension is enabled.
UnitTestCase::setupMockIterator protected function Set up a traversable class mock to return specific items when iterated.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.