You are here

public function WorkflowUiTest::testWorkflowCreation in Drupal 9

Same name and namespace in other branches
  1. 8 core/modules/workflows/tests/src/Functional/WorkflowUiTest.php \Drupal\Tests\workflows\Functional\WorkflowUiTest::testWorkflowCreation()

Tests the creation of a workflow through the UI.

File

core/modules/workflows/tests/src/Functional/WorkflowUiTest.php, line 118

Class

WorkflowUiTest
Tests workflow creation UI.

Namespace

Drupal\Tests\workflows\Functional

Code

public function testWorkflowCreation() {
  $workflow_storage = $this->container
    ->get('entity_type.manager')
    ->getStorage('workflow');

  /** @var \Drupal\workflows\WorkflowInterface $workflow */
  $this
    ->drupalLogin($this
    ->createUser([
    'access administration pages',
    'administer workflows',
  ]));
  $this
    ->drupalGet('admin/config/workflow');
  $this
    ->assertSession()
    ->linkByHrefExists('admin/config/workflow/workflows');
  $this
    ->clickLink('Workflows');
  $this
    ->assertSession()
    ->pageTextContains('Workflows');
  $this
    ->assertSession()
    ->pageTextContains('There are no workflows yet.');
  $this
    ->clickLink('Add workflow');
  $this
    ->submitForm([
    'label' => 'Test',
    'id' => 'test',
    'workflow_type' => 'workflow_type_test',
  ], 'Save');
  $this
    ->assertSession()
    ->pageTextContains('Created the Test Workflow.');
  $this
    ->assertSession()
    ->addressEquals('admin/config/workflow/workflows/manage/test/add_state');
  $this
    ->drupalGet('/admin/config/workflow/workflows/manage/test');
  $this
    ->assertSession()
    ->pageTextContains('This workflow has no states and will be disabled until there is at least one, add a new state.');
  $this
    ->assertSession()
    ->pageTextContains('There are no states yet.');
  $this
    ->clickLink('Add a new state');
  $this
    ->submitForm([
    'label' => 'Published',
    'id' => 'published',
  ], 'Save');
  $this
    ->assertSession()
    ->pageTextContains('Created Published state.');
  $workflow = $workflow_storage
    ->loadUnchanged('test');
  $this
    ->assertFalse($workflow
    ->getTypePlugin()
    ->getState('published')
    ->canTransitionTo('published'), 'No default transition from published to published exists.');
  $this
    ->clickLink('Add a new state');

  // Don't create a draft to draft transition by default.
  $this
    ->submitForm([
    'label' => 'Draft',
    'id' => 'draft',
  ], 'Save');
  $this
    ->assertSession()
    ->pageTextContains('Created Draft state.');
  $workflow = $workflow_storage
    ->loadUnchanged('test');
  $this
    ->assertFalse($workflow
    ->getTypePlugin()
    ->getState('draft')
    ->canTransitionTo('draft'), 'Can not transition from draft to draft');
  $this
    ->clickLink('Add a new transition');
  $this
    ->submitForm([
    'id' => 'publish',
    'label' => 'Publish',
    'from[draft]' => 'draft',
    'to' => 'published',
  ], 'Save');
  $this
    ->assertSession()
    ->pageTextContains('Created Publish transition.');
  $workflow = $workflow_storage
    ->loadUnchanged('test');
  $this
    ->assertTrue($workflow
    ->getTypePlugin()
    ->getState('draft')
    ->canTransitionTo('published'), 'Can transition from draft to published');
  $this
    ->clickLink('Add a new transition');
  $this
    ->assertCount(2, $this
    ->cssSelect('input[name="to"][type="radio"]'));
  $this
    ->assertCount(0, $this
    ->cssSelect('input[name="to"][checked="checked"][type="radio"]'));
  $this
    ->submitForm([
    'id' => 'create_new_draft',
    'label' => 'Create new draft',
    'from[draft]' => 'draft',
    'to' => 'draft',
  ], 'Save');
  $this
    ->assertSession()
    ->pageTextContains('Created Create new draft transition.');
  $workflow = $workflow_storage
    ->loadUnchanged('test');
  $this
    ->assertTrue($workflow
    ->getTypePlugin()
    ->getState('draft')
    ->canTransitionTo('draft'), 'Can transition from draft to draft');

  // The fist state to edit on the page should be published.
  $this
    ->clickLink('Edit');
  $this
    ->assertSession()
    ->fieldValueEquals('label', 'Published');

  // Change the label.
  $this
    ->submitForm([
    'label' => 'Live',
  ], 'Save');
  $this
    ->assertSession()
    ->pageTextContains('Saved Live state.');

  // Allow published to draft.
  $this
    ->clickLink('Edit', 3);
  $this
    ->submitForm([
    'from[published]' => 'published',
  ], 'Save');
  $this
    ->assertSession()
    ->pageTextContains('Saved Create new draft transition.');
  $workflow = $workflow_storage
    ->loadUnchanged('test');
  $this
    ->assertTrue($workflow
    ->getTypePlugin()
    ->getState('published')
    ->canTransitionTo('draft'), 'Can transition from published to draft');

  // Try creating a duplicate transition.
  $this
    ->clickLink('Add a new transition');
  $this
    ->submitForm([
    'id' => 'create_new_draft',
    'label' => 'Create new draft',
    'from[published]' => 'published',
    'to' => 'draft',
  ], 'Save');
  $this
    ->assertSession()
    ->pageTextContains('The machine-readable name is already in use. It must be unique.');

  // Try creating a transition which duplicates the states of another.
  $this
    ->submitForm([
    'id' => 'create_new_draft2',
    'label' => 'Create new draft again',
    'from[published]' => 'published',
    'to' => 'draft',
  ], 'Save');
  $this
    ->assertSession()
    ->pageTextContains('The transition from Live to Draft already exists.');

  // Create a new transition.
  $this
    ->submitForm([
    'id' => 'save_and_publish',
    'label' => 'Save and publish',
    'from[published]' => 'published',
    'to' => 'published',
  ], 'Save');
  $this
    ->assertSession()
    ->pageTextContains('Created Save and publish transition.');

  // Edit the new transition and try to add an existing transition.
  $this
    ->clickLink('Edit', 4);
  $this
    ->submitForm([
    'from[draft]' => 'draft',
  ], 'Save');
  $this
    ->assertSession()
    ->pageTextContains('The transition from Draft to Live already exists.');

  // Delete the transition.
  $workflow = $workflow_storage
    ->loadUnchanged('test');
  $this
    ->assertTrue($workflow
    ->getTypePlugin()
    ->hasTransitionFromStateToState('published', 'published'), 'Can transition from published to published');
  $this
    ->clickLink('Delete');
  $this
    ->assertSession()
    ->pageTextContains('Are you sure you want to delete Save and publish from Test?');
  $this
    ->submitForm([], 'Delete');
  $workflow = $workflow_storage
    ->loadUnchanged('test');
  $this
    ->assertFalse($workflow
    ->getTypePlugin()
    ->hasTransitionFromStateToState('published', 'published'), 'Cannot transition from published to published');

  // Try creating a duplicate state.
  $this
    ->drupalGet('admin/config/workflow/workflows/manage/test');
  $this
    ->clickLink('Add a new state');
  $this
    ->submitForm([
    'label' => 'Draft',
    'id' => 'draft',
  ], 'Save');
  $this
    ->assertSession()
    ->pageTextContains('The machine-readable name is already in use. It must be unique.');

  // Ensure that weight changes the state ordering.
  $workflow = $workflow_storage
    ->loadUnchanged('test');
  $this
    ->assertEquals('published', $workflow
    ->getTypePlugin()
    ->getInitialState()
    ->id());
  $this
    ->drupalGet('admin/config/workflow/workflows/manage/test');
  $this
    ->submitForm([
    'states[draft][weight]' => '-1',
  ], 'Save');
  $workflow = $workflow_storage
    ->loadUnchanged('test');
  $this
    ->assertEquals('draft', $workflow
    ->getTypePlugin()
    ->getInitialState()
    ->id());

  // Verify that we are still on the workflow edit page.
  $this
    ->assertSession()
    ->addressEquals('admin/config/workflow/workflows/manage/test');

  // Ensure that weight changes the transition ordering.
  $this
    ->assertEquals([
    'publish',
    'create_new_draft',
  ], array_keys($workflow
    ->getTypePlugin()
    ->getTransitions()));
  $this
    ->drupalGet('admin/config/workflow/workflows/manage/test');
  $this
    ->submitForm([
    'transitions[create_new_draft][weight]' => '-1',
  ], 'Save');
  $workflow = $workflow_storage
    ->loadUnchanged('test');
  $this
    ->assertEquals([
    'create_new_draft',
    'publish',
  ], array_keys($workflow
    ->getTypePlugin()
    ->getTransitions()));

  // Verify that we are still on the workflow edit page.
  $this
    ->assertSession()
    ->addressEquals('admin/config/workflow/workflows/manage/test');

  // Ensure that a delete link for the published state exists before deleting
  // the draft state.
  $published_delete_link = Url::fromRoute('entity.workflow.delete_state_form', [
    'workflow' => $workflow
      ->id(),
    'workflow_state' => 'published',
  ])
    ->toString();
  $draft_delete_link = Url::fromRoute('entity.workflow.delete_state_form', [
    'workflow' => $workflow
      ->id(),
    'workflow_state' => 'draft',
  ])
    ->toString();
  $this
    ->assertSession()
    ->elementContains('css', 'tr[data-drupal-selector="edit-states-published"]', 'Delete');
  $this
    ->assertSession()
    ->linkByHrefExists($published_delete_link);
  $this
    ->assertSession()
    ->linkByHrefExists($draft_delete_link);

  // Make the published state a default state and ensure it is no longer
  // linked.
  \Drupal::state()
    ->set('workflow_type_test.required_states', [
    'published',
  ]);
  $this
    ->getSession()
    ->reload();
  $this
    ->assertSession()
    ->linkByHrefNotExists($published_delete_link);
  $this
    ->assertSession()
    ->linkByHrefExists($draft_delete_link);
  $this
    ->assertSession()
    ->elementNotContains('css', 'tr[data-drupal-selector="edit-states-published"]', 'Delete');
  \Drupal::state()
    ->set('workflow_type_test.required_states', []);
  $this
    ->getSession()
    ->reload();
  $this
    ->assertSession()
    ->elementContains('css', 'tr[data-drupal-selector="edit-states-published"]', 'Delete');
  $this
    ->assertSession()
    ->linkByHrefExists($published_delete_link);
  $this
    ->assertSession()
    ->linkByHrefExists($draft_delete_link);

  // Delete the Draft state.
  $this
    ->clickLink('Delete');
  $this
    ->assertSession()
    ->pageTextContains('Are you sure you want to delete Draft from Test?');
  $this
    ->submitForm([], 'Delete');
  $this
    ->assertSession()
    ->pageTextContains('State Draft deleted.');
  $workflow = $workflow_storage
    ->loadUnchanged('test');
  $this
    ->assertFalse($workflow
    ->getTypePlugin()
    ->hasState('draft'), 'Draft state deleted');
  $this
    ->assertTrue($workflow
    ->getTypePlugin()
    ->hasState('published'), 'Workflow still has published state');

  // The last state cannot be deleted so the only delete link on the page will
  // be for the workflow.
  $this
    ->assertSession()
    ->linkByHrefNotExists($published_delete_link);
  $this
    ->clickLink('Delete');
  $this
    ->assertSession()
    ->pageTextContains('Are you sure you want to delete Test?');
  $this
    ->submitForm([], 'Delete');
  $this
    ->assertSession()
    ->pageTextContains('Workflow Test deleted.');
  $this
    ->assertSession()
    ->pageTextContains('There are no workflows yet.');
  $this
    ->assertNull($workflow_storage
    ->loadUnchanged('test'), 'The test workflow has been deleted');

  // Ensure that workflow types with default configuration are initialized
  // correctly.
  $this
    ->drupalGet('admin/config/workflow/workflows');
  $this
    ->clickLink('Add workflow');
  $this
    ->submitForm([
    'label' => 'Test 2',
    'id' => 'test2',
    'workflow_type' => 'workflow_type_required_state_test',
  ], 'Save');
  $this
    ->assertSession()
    ->addressEquals('admin/config/workflow/workflows/manage/test2');
  $workflow = $workflow_storage
    ->loadUnchanged('test2');
  $this
    ->assertTrue($workflow
    ->getTypePlugin()
    ->hasState('fresh'), 'The workflow has the "fresh" state');
  $this
    ->assertTrue($workflow
    ->getTypePlugin()
    ->hasState('rotten'), 'The workflow has the "rotten" state');
  $this
    ->assertTrue($workflow
    ->getTypePlugin()
    ->hasTransition('rot'), 'The workflow has the "rot" transition');
  $this
    ->assertSession()
    ->pageTextContains('Fresh');
  $this
    ->assertSession()
    ->pageTextContains('Rotten');
}