Skip to content

Add comprehensive unit tests for ContextNormalizerService #35

@e0ipso

Description

@e0ipso

Summary

This issue tracks the creation of comprehensive unit tests for the new ContextNormalizerService that will be introduced in issue #34. The tests should ensure the service correctly handles all supported context types and edge cases.

Parent Issue

This issue is a child of #34 - "Refactor: Extract context serialization/deserialization into dedicated service for ab_blocks"

Test Coverage Requirements

Core Functionality Tests

Normalization Tests

  • EntityAdapter contexts: Test serialization of entity contexts to entity:{type}={id} format
  • PrimitiveInterface contexts: Test JSON encoding of primitive values (string, int, bool, float)
  • Language contexts: Test serialization of language objects to language ID
  • Mixed context arrays: Test normalization of arrays containing multiple context types
  • Empty contexts: Test handling of empty context arrays

Denormalization Tests

  • Entity reconstruction: Test recreation of EntityContext objects from serialized format
  • Primitive reconstruction: Test recreation of primitive Context objects with proper casting
  • Language reconstruction: Test recreation of Language contexts from language IDs
  • Invalid data handling: Test graceful handling of malformed serialized data
  • Missing entities: Test handling when referenced entities don't exist

Transport Encoding/Decoding Tests

  • Base64 encoding roundtrip: Test encodeForTransport()decodeFromTransport() roundtrips
  • JSON error handling: Test handling of invalid JSON during encoding/decoding
  • Large data sets: Test performance with large context arrays
  • Special characters: Test handling of contexts with special characters or unicode

Edge Cases and Error Handling

Invalid Input Tests

  • Null contexts: Test handling of null context values
  • Invalid context types: Test handling of unsupported context types
  • Corrupted serialized data: Test handling of corrupted serialization strings
  • Invalid entity IDs: Test handling of non-existent entity references
  • Invalid language codes: Test handling of invalid language identifiers

Boundary Condition Tests

  • Empty string values: Test contexts with empty string values
  • Zero/false values: Test primitive contexts with falsy values
  • Very long strings: Test contexts with extremely long string values
  • Special entity types: Test with various entity types (node, user, taxonomy_term, etc.)

Integration with Drupal Services

Mock Dependencies Tests

  • TypedDataManager: Mock typed data manager for isolated testing
  • EntityTypeManager: Mock entity type manager and storage services
  • LanguageManager: Mock language manager for language context tests
  • Error scenarios: Test behavior when dependencies throw exceptions

Service Interface Compliance

  • NormalizerInterface: Verify proper implementation of normalizer methods
  • DenormalizerInterface: Verify proper implementation of denormalizer methods
  • Method signatures: Ensure all interface methods have correct signatures
  • Return types: Verify correct return types for all methods

Test File Structure

tests/src/Unit/Service/ContextNormalizerServiceTest.php
├── testNormalizeEntityContexts()
├── testNormalizePrimitiveContexts()  
├── testNormalizeLanguageContexts()
├── testNormalizeMixedContexts()
├── testNormalizeEmptyContexts()
├── testDenormalizeEntityContexts()
├── testDenormalizePrimitiveContexts()
├── testDenormalizeLanguageContexts()
├── testDenormalizeInvalidData()
├── testEncodeDecodeTransportRoundtrip()
├── testTransportEncodingEdgeCases()
├── testSupportsNormalization()
├── testSupportsDenormalization()
├── testErrorHandlingWithMissingEntities()
├── testErrorHandlingWithInvalidJson()
└── testBoundaryConditions()

Mock Objects Required

Entity Mocks

// Mock ContentEntityInterface objects
$mockNode = $this->createMock(ContentEntityInterface::class);
$mockUser = $this->createMock(ContentEntityInterface::class);

// Mock EntityStorageInterface
$mockStorage = $this->createMock(EntityStorageInterface::class);

// Mock EntityTypeManagerInterface  
$mockEntityTypeManager = $this->createMock(EntityTypeManagerInterface::class);

Context Mocks

// Mock ContextInterface objects
$mockEntityContext = $this->createMock(ContextInterface::class);
$mockPrimitiveContext = $this->createMock(ContextInterface::class);

// Mock TypedData objects
$mockEntityAdapter = $this->createMock(EntityAdapter::class);
$mockPrimitive = $this->createMock(PrimitiveInterface::class);

Test Data Fixtures

Sample Context Arrays

  • Node context: Entity context with node ID 123
  • User context: Entity context with user ID 456
  • String context: Primitive context with string value "test"
  • Integer context: Primitive context with integer value 42
  • Boolean context: Primitive context with boolean value true
  • Language context: Language context with "en" language code

Expected Serialization Formats

$expectedEntitySerialization = ['entity:node=123'];
$expectedPrimitiveSerialization = ['"test"', '42', 'true'];
$expectedLanguageSerialization = ['"en"'];

Performance Testing

Memory Usage Tests

  • Test memory consumption with large context arrays
  • Verify no memory leaks during repeated operations
  • Test garbage collection of temporary objects

Execution Time Tests

  • Benchmark normalization/denormalization performance
  • Test with realistic Layout Builder context loads
  • Ensure acceptable performance for Ajax requests

Code Coverage Goals

  • Line Coverage: 100% of service methods
  • Branch Coverage: All conditional paths tested
  • Exception Coverage: All exception scenarios tested
  • Integration Points: All service dependencies tested

Acceptance Criteria

  • All normalization methods have comprehensive unit tests
  • All denormalization methods have comprehensive unit tests
  • All edge cases and error conditions are tested
  • Test coverage meets or exceeds 95%
  • All tests pass in isolation and as a suite
  • Mock objects properly isolate the service under test
  • Performance tests validate acceptable execution times
  • Tests follow Drupal testing conventions and standards

Implementation Notes

PHPUnit Annotations

/**
 * Tests the ContextNormalizerService.
 *
 * @group ab_blocks
 * @group ab_tests
 * 
 * @coversDefaultClass \Drupal\ab_blocks\Service\ContextNormalizerService
 */
class ContextNormalizerServiceTest extends UnitTestCase {

Test Dependencies

  • Extend UnitTestCase for isolated testing
  • Use @covers annotations for accurate coverage reporting
  • Mock all external dependencies
  • Use data providers for parameterized tests

Metadata

Metadata

Assignees

No one assigned

    Labels

    🏷️ type:testingTest files, test infrastructure, PHPUnit tests📂 area:blocksLayout Builder block A/B testing features🔥 priority:mediumStandard feature requests, moderate bugs with workarounds

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions