You are here

public function WorkspaceIntegrationTest::testWorkspaces in Drupal 9

Same name and namespace in other branches
  1. 8 core/modules/workspaces/tests/src/Kernel/WorkspaceIntegrationTest.php \Drupal\Tests\workspaces\Kernel\WorkspaceIntegrationTest::testWorkspaces()

Tests various scenarios for creating and publishing content in workspaces.

File

core/modules/workspaces/tests/src/Kernel/WorkspaceIntegrationTest.php, line 115

Class

WorkspaceIntegrationTest
Tests a complete publishing scenario across different workspaces.

Namespace

Drupal\Tests\workspaces\Kernel

Code

public function testWorkspaces() {
  $this
    ->initializeWorkspacesModule();

  // Notes about the structure of the test scenarios:
  // - a multi-dimensional array keyed by the workspace ID, then by the entity
  //   ID and finally by the revision ID.
  // - 'default_revision' indicates the entity revision that should be
  //   returned when loading an entity, non-revision entity queries and
  //   non-revision views *in a given workspace*, it does not indicate what is
  //   actually stored in the base and data entity tables.
  $test_scenarios = [];

  // The $expected_workspace_association array holds the revision IDs which
  // should be tracked by the Workspace Association entity type in each test
  // scenario, keyed by workspace ID.
  $expected_workspace_association = [];

  // In the initial state we have only the two revisions that were created
  // before the Workspaces module was installed.
  $revision_state = [
    'live' => [
      1 => [
        1 => [
          'title' => 'live - 1 - r1 - published',
          'status' => TRUE,
          'default_revision' => TRUE,
        ],
      ],
      2 => [
        2 => [
          'title' => 'live - 2 - r2 - unpublished',
          'status' => FALSE,
          'default_revision' => TRUE,
        ],
      ],
    ],
    'stage' => [
      1 => [
        1 => [
          'title' => 'live - 1 - r1 - published',
          'status' => TRUE,
          'default_revision' => TRUE,
        ],
      ],
      2 => [
        2 => [
          'title' => 'live - 2 - r2 - unpublished',
          'status' => FALSE,
          'default_revision' => TRUE,
        ],
      ],
    ],
  ];
  $test_scenarios['initial_state'] = $revision_state;
  $expected_workspace_association['initial_state'] = [
    'stage' => [],
  ];

  // Unpublish node 1 in 'stage'. The new revision is also added to 'live' but
  // it is not the default revision.
  $revision_state = array_replace_recursive($revision_state, [
    'live' => [
      1 => [
        3 => [
          'title' => 'stage - 1 - r3 - unpublished',
          'status' => FALSE,
          'default_revision' => FALSE,
        ],
      ],
    ],
    'stage' => [
      1 => [
        1 => [
          'default_revision' => FALSE,
        ],
        3 => [
          'title' => 'stage - 1 - r3 - unpublished',
          'status' => FALSE,
          'default_revision' => TRUE,
        ],
      ],
    ],
  ]);
  $test_scenarios['unpublish_node_1_in_stage'] = $revision_state;
  $expected_workspace_association['unpublish_node_1_in_stage'] = [
    'stage' => [
      3,
    ],
  ];

  // Publish node 2 in 'stage'. The new revision is also added to 'live' but
  // it is not the default revision.
  $revision_state = array_replace_recursive($revision_state, [
    'live' => [
      2 => [
        4 => [
          'title' => 'stage - 2 - r4 - published',
          'status' => TRUE,
          'default_revision' => FALSE,
        ],
      ],
    ],
    'stage' => [
      2 => [
        2 => [
          'default_revision' => FALSE,
        ],
        4 => [
          'title' => 'stage - 2 - r4 - published',
          'status' => TRUE,
          'default_revision' => TRUE,
        ],
      ],
    ],
  ]);
  $test_scenarios['publish_node_2_in_stage'] = $revision_state;
  $expected_workspace_association['publish_node_2_in_stage'] = [
    'stage' => [
      3,
      4,
    ],
  ];

  // Adding a new unpublished node on 'stage' should create a single
  // unpublished revision on both 'stage' and 'live'.
  $revision_state = array_replace_recursive($revision_state, [
    'live' => [
      3 => [
        5 => [
          'title' => 'stage - 3 - r5 - unpublished',
          'status' => FALSE,
          'default_revision' => TRUE,
        ],
      ],
    ],
    'stage' => [
      3 => [
        5 => [
          'title' => 'stage - 3 - r5 - unpublished',
          'status' => FALSE,
          'default_revision' => TRUE,
        ],
      ],
    ],
  ]);
  $test_scenarios['add_unpublished_node_in_stage'] = $revision_state;
  $expected_workspace_association['add_unpublished_node_in_stage'] = [
    'stage' => [
      3,
      4,
      5,
    ],
  ];

  // Adding a new published node on 'stage' should create two revisions, an
  // unpublished revision on 'live' and a published one on 'stage'.
  $revision_state = array_replace_recursive($revision_state, [
    'live' => [
      4 => [
        6 => [
          'title' => 'stage - 4 - r6 - published',
          'status' => FALSE,
          'default_revision' => TRUE,
        ],
        7 => [
          'title' => 'stage - 4 - r6 - published',
          'status' => TRUE,
          'default_revision' => FALSE,
        ],
      ],
    ],
    'stage' => [
      4 => [
        6 => [
          'title' => 'stage - 4 - r6 - published',
          'status' => FALSE,
          'default_revision' => FALSE,
        ],
        7 => [
          'title' => 'stage - 4 - r6 - published',
          'status' => TRUE,
          'default_revision' => TRUE,
        ],
      ],
    ],
  ]);
  $test_scenarios['add_published_node_in_stage'] = $revision_state;
  $expected_workspace_association['add_published_node_in_stage'] = [
    'stage' => [
      3,
      4,
      5,
      7,
    ],
  ];

  // Publishing 'stage' to 'live' should simply make the latest revisions in
  // 'stage' the default ones in 'live'.
  $revision_state = array_replace_recursive($revision_state, [
    'live' => [
      1 => [
        1 => [
          'default_revision' => FALSE,
        ],
        3 => [
          'default_revision' => TRUE,
        ],
      ],
      2 => [
        2 => [
          'default_revision' => FALSE,
        ],
        4 => [
          'default_revision' => TRUE,
        ],
      ],
      // Node 3 has a single revision for both 'stage' and 'live' and it is
      // already the default revision in both of them.
      4 => [
        6 => [
          'default_revision' => FALSE,
        ],
        7 => [
          'default_revision' => TRUE,
        ],
      ],
    ],
  ]);
  $test_scenarios['push_stage_to_live'] = $revision_state;
  $expected_workspace_association['push_stage_to_live'] = [
    'stage' => [],
  ];

  // Check the initial state after the module was installed.
  $this
    ->assertWorkspaceStatus($test_scenarios['initial_state'], 'node');
  $this
    ->assertWorkspaceAssociation($expected_workspace_association['initial_state'], 'node');

  // Unpublish node 1 in 'stage'.
  $this
    ->switchToWorkspace('stage');
  $node = $this->entityTypeManager
    ->getStorage('node')
    ->load(1);
  $node
    ->setTitle('stage - 1 - r3 - unpublished');
  $node
    ->setUnpublished();
  $node
    ->save();
  $this
    ->assertWorkspaceStatus($test_scenarios['unpublish_node_1_in_stage'], 'node');
  $this
    ->assertWorkspaceAssociation($expected_workspace_association['unpublish_node_1_in_stage'], 'node');

  // Publish node 2 in 'stage'.
  $this
    ->switchToWorkspace('stage');
  $node = $this->entityTypeManager
    ->getStorage('node')
    ->load(2);
  $node
    ->setTitle('stage - 2 - r4 - published');
  $node
    ->setPublished();
  $node
    ->save();
  $this
    ->assertWorkspaceStatus($test_scenarios['publish_node_2_in_stage'], 'node');
  $this
    ->assertWorkspaceAssociation($expected_workspace_association['publish_node_2_in_stage'], 'node');

  // Add a new unpublished node on 'stage'.
  $this
    ->switchToWorkspace('stage');
  $this
    ->createNode([
    'title' => 'stage - 3 - r5 - unpublished',
    'created' => $this->createdTimestamp++,
    'status' => FALSE,
  ]);
  $this
    ->assertWorkspaceStatus($test_scenarios['add_unpublished_node_in_stage'], 'node');
  $this
    ->assertWorkspaceAssociation($expected_workspace_association['add_unpublished_node_in_stage'], 'node');

  // Add a new published node on 'stage'.
  $this
    ->switchToWorkspace('stage');
  $this
    ->createNode([
    'title' => 'stage - 4 - r6 - published',
    'created' => $this->createdTimestamp++,
    'status' => TRUE,
  ]);
  $this
    ->assertWorkspaceStatus($test_scenarios['add_published_node_in_stage'], 'node');
  $this
    ->assertWorkspaceAssociation($expected_workspace_association['add_published_node_in_stage'], 'node');

  // Publish 'stage' to 'live'.

  /** @var \Drupal\workspaces\WorkspacePublisher $workspace_publisher */
  $workspace_publisher = \Drupal::service('workspaces.operation_factory')
    ->getPublisher($this->workspaces['stage']);

  // Check which revisions need to be pushed.
  $expected = [
    'node' => [
      3 => 1,
      4 => 2,
      5 => 3,
      7 => 4,
    ],
  ];
  $this
    ->assertEquals($expected, $workspace_publisher
    ->getDifferringRevisionIdsOnSource());
  $this->workspaces['stage']
    ->publish();
  $this
    ->assertWorkspaceStatus($test_scenarios['push_stage_to_live'], 'node');
  $this
    ->assertWorkspaceAssociation($expected_workspace_association['push_stage_to_live'], 'node');

  // Check that there are no more revisions to push.
  $this
    ->assertEmpty($workspace_publisher
    ->getDifferringRevisionIdsOnSource());
}