From 722e4f1cad3cddf8b1db444f32c120f68e34b935 Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Thu, 30 May 2013 01:41:45 +0200 Subject: [PATCH 1/3] Integration tests for ingest steps plus some fixes. Tests ingest forms by using a shared variable 'models'. Additional stuff: 'models' is no longer a required config for ingest steps, now its set from the given objects. No longer need to rebuild steps from within a form step when the shared_storage gets changed, we now detect if changes have been made then we rebuild if necessary. Fixed POST requests in WebTestCases previously the user was always anonymous so interactions with fedora would fail via post requests. --- includes/ingest.form.inc | 14 ++- islandora.info | 1 + tests/ingest.test | 117 ++++++++++++++++++++ tests/islandora_ingest_test.info | 7 ++ tests/islandora_ingest_test.module | 166 +++++++++++++++++++++++++++++ tests/islandora_web_test_case.inc | 21 ++-- 6 files changed, 317 insertions(+), 9 deletions(-) create mode 100644 tests/ingest.test create mode 100644 tests/islandora_ingest_test.info create mode 100644 tests/islandora_ingest_test.module diff --git a/includes/ingest.form.inc b/includes/ingest.form.inc index 3ef3f847..943202ce 100644 --- a/includes/ingest.form.inc +++ b/includes/ingest.form.inc @@ -78,6 +78,7 @@ function islandora_ingest_form_init_form_state_storage(array &$form_state, array if (empty($objects)) { $objects[] = islandora_ingest_form_prepare_new_object($configuration); } + $configuration['models'] = isset($configuration['models']) ? $configuration['models'] : array(); // Make sure the models actually exist. foreach ($configuration['models'] as $key => $model) { if (!islandora_object_load($model)) { @@ -87,7 +88,6 @@ function islandora_ingest_form_init_form_state_storage(array &$form_state, array // No need to persist the 'objects' within the configuration. unset($configuration['objects']); // Required for step hooks. - $configuration['models'] = isset($configuration['models']) ? $configuration['models'] : array(); $form_state['islandora'] = array( 'step_id' => NULL, 'objects' => $objects, @@ -370,7 +370,15 @@ function islandora_ingest_form_execute_step(array $form, array &$form_state, $st function islandora_ingest_form_execute_form_step(array $form, array &$form_state, array $step) { $args = array($form, &$form_state); $args = isset($step['args']) ? array_merge($args, $step['args']) : $args; + $shared_storage = islandora_ingest_form_get_shared_storage($form_state); + // Build the form step. $form = call_user_func_array($step['form_id'], $args); + // Since the list of steps depends on the shared storage we will rebuild the + // list of steps if the shared storage has changed. This must be done before + // stepifying, so the prev/next buttons get updated. + if ($shared_storage != islandora_ingest_form_get_shared_storage($form_state)) { + drupal_static_reset('islandora_ingest_form_get_steps'); + } return islandora_ingest_form_stepify($form, $form_state, $step); } @@ -456,6 +464,10 @@ function islandora_ingest_form_undo_callback_step(array $form, array &$form_stat function islandora_ingest_form_stepify(array $form, array &$form_state, $step) { $first_form_step = islandora_ingest_form_on_first_form_step($form_state); $last_form_step = islandora_ingest_form_on_last_form_step($form_state); + $form['form_step_id'] = array( + '#type' => 'hidden', + '#value' => islandora_ingest_form_get_current_step_id($form_state), + ); $form['prev'] = $first_form_step ? NULL : islandora_ingest_form_previous_button($form_state); $form['next'] = $last_form_step ? islandora_ingest_form_ingest_button($form_state) : islandora_ingest_form_next_button($form_state); // Allow for a hook_form_FORM_ID_alter(). diff --git a/islandora.info b/islandora.info index 54f62c05..4f6a5858 100644 --- a/islandora.info +++ b/islandora.info @@ -14,5 +14,6 @@ files[] = includes/object.entity_controller.inc files[] = tests/islandora_web_test_case.inc files[] = tests/authtokens.test files[] = tests/hooks.test +files[] = tests/ingest.test files[] = tests/islandora_manage_permissions.test php = 5.3 diff --git a/tests/ingest.test b/tests/ingest.test new file mode 100644 index 00000000..0878076b --- /dev/null +++ b/tests/ingest.test @@ -0,0 +1,117 @@ + 'Islandora Ingestion', + 'description' => 'Ensure that the ingest forms function correctly.', + 'group' => 'Islandora', + ); + } + + /** + * Creates an admin user and a connection to a fedora repository. + * + * @see IslandoraWebTestCase::setUp() + */ + public function setUp() { + parent::setUp('islandora_ingest_test'); + $this->repository = $this->admin->repository; + $this->purgeTestObjects(); + + } + + /** + * Free any objects/resources created for this test. + * + * @see IslandoraWebTestCase::tearDown() + */ + public function tearDown() { + $this->purgeTestObjects(); + unset($this->repository); + parent::tearDown(); + } + + /** + * Purge any objects created by the test's in this class. + */ + public function purgeTestObjects() { + $objects = array( + 'test:test', + ); + foreach ($objects as $object) { + try { + $object = $this->repository->getObject($object); + $this->repository->purgeObject($object->id); + } + catch (Exception $e) { + // Meh... Either it didn't exist or the purge failed. + } + } + } + + /** + * Test Ingest Steps. + */ + public function testIngest() { + global $user; + // First step in form. + $this->drupalGet('test/ingest'); + // Default model selected, has no additional steps. + $this->assertFieldByName('ingest', 'Ingest'); + // Select a model with additional steps. + $edit = array( + 'model' => 'test:testcmodel', + ); + $this->drupalPostAJAX(NULL, $edit, 'model'); + // Form now reflexts multiple steps. + $this->assertFieldByName('label', ''); + $this->assertFieldByName('next', 'Next'); + // Move to next step. + $edit = array( + 'label' => 'foobar', + 'model' => 'test:testcmodel', + ); + $this->drupalPost(NULL, $edit, t('Next')); + $this->assertFieldByName('form_step_id', 'islandora_ingest_test_testcmodel'); + $this->assertFieldByName('ingest', 'Ingest'); + // Move back to first step. + $this->drupalPost(NULL, array(), t('Previous')); + // Try a different model that has an additional step. + $edit = array( + 'model' => 'test:testcmodel2', + ); + $this->drupalPostAJAX(NULL, $edit, 'model'); + $edit = array( + 'label' => 'foobar', + 'model' => 'test:testcmodel2', + ); + $this->drupalPost(NULL, $edit, t('Next')); + $this->assertFieldByName('form_step_id', 'islandora_ingest_test_testcmodel2'); + $this->assertFieldByName('ingest', 'Ingest'); + // Ingest the thing. + $this->drupalPost(NULL, array(), t('Ingest')); + // Test that the thing got made. + $object = islandora_object_load('test:test'); + $this->assertEqual($object->label, 'foobar', 'Ingest Object matches submitted form values.'); + $this->assertEqual($object->models, array('test:testcmodel2', 'fedora-system:FedoraObject-3.0'), 'Ingest Object matches submitted form values.'); + } + +} diff --git a/tests/islandora_ingest_test.info b/tests/islandora_ingest_test.info new file mode 100644 index 00000000..974a60f2 --- /dev/null +++ b/tests/islandora_ingest_test.info @@ -0,0 +1,7 @@ +name = Islandora Testing +description = Required for testing islandora web-test case. +core = 7.x +package = Testing +hidden = TRUE +dependencies[] = islandora +files[] = islandora_test.module diff --git a/tests/islandora_ingest_test.module b/tests/islandora_ingest_test.module new file mode 100644 index 00000000..d414c717 --- /dev/null +++ b/tests/islandora_ingest_test.module @@ -0,0 +1,166 @@ + array( + 'title' => 'Ingest Form', + 'page callback' => 'islandora_ingest_test_ingest', + 'type' => MENU_LOCAL_ACTION, + 'access callback' => TRUE, + ), + ); +} + +/** + * Render the ingest form. + */ +function islandora_ingest_test_ingest() { + $connection = islandora_get_tuque_connection(); + $object = $connection->repository->constructObject('test:test'); + $object->label = 'New Object'; + $configuration = array( + 'objects' => array($object), + ); + module_load_include('inc', 'islandora', 'includes/ingest.form'); + return drupal_get_form('islandora_ingest_form', $configuration); +} + +/** + * Implements hook_islandora_ingest_steps(). + */ +function islandora_ingest_test_islandora_ingest_steps(array &$form_state) { + return array( + 'islandora_ingest_test' => array( + 'type' => 'form', + 'form_id' => 'islandora_ingest_test_set_label_form', + 'weight' => -50, + 'module' => 'islandora_ingest_test', + ), + ); +} + +/** + * Implements hook_MODEL_PID_islandora_ingest_steps(). + */ +function islandora_ingest_test_test_testcmodel_islandora_ingest_steps(array &$form_state) { + return array( + 'islandora_ingest_test_testcmodel' => array( + 'type' => 'form', + 'form_id' => 'islandora_ingest_test_testcmodel_form', + 'weight' => -30, + 'module' => 'islandora_ingest_test', + ), + ); +} + +/** + * Implements hook_MODEL_PID_islandora_ingest_steps(). + */ +function islandora_ingest_test_test_testcmodel2_islandora_ingest_steps(array &$form_state) { + return array( + 'islandora_ingest_test_testcmodel2' => array( + 'type' => 'form', + 'form_id' => 'islandora_ingest_test_testcmodel2_form', + 'weight' => -40, + 'module' => 'islandora_ingest_test', + ), + ); +} + +/** + * Sets the label of the ingestable object. + * + * @param array $form + * The Drupal form. + * @param array $form_state + * The Drupal form state. + * + * @return array + * The Drupal form definition. + */ +function islandora_ingest_test_set_label_form(array $form, array &$form_state) { + $models = array('test:nomorestepscmodel', 'test:testcmodel', 'test:testcmodel2'); + $model = isset($form_state['values']['model']) ? $form_state['values']['model'] : reset($models); + $shared_storage = &islandora_ingest_form_get_shared_storage($form_state); + $shared_storage['models'] = array($model); + return array( + '#prefix' => '
', + '#suffix' => '
', + 'label' => array( + '#type' => 'textfield', + '#title' => t('Label'), + ), + 'model' => array( + '#type' => 'select', + '#title' => t('Select a Content Model to Ingest'), + '#options' => array_combine($models, $models), + '#default' => $model, + '#ajax' => array( + 'callback' => 'islandora_ingest_test_model_ajax_callback', + 'wrapper' => 'islandora-select-content-model-wrapper', + 'method' => 'replace', + 'effect' => 'fade', + ), + ), + ); +} + +/** + * Updates the model field. + */ +function islandora_ingest_test_model_ajax_callback(array $form, array &$form_state) { + return $form; +} + +/** + * Sets the label of the ingestable object. + * + * @param array $form + * The Drupal form. + * @param array $form_state + * The Drupal form state. + */ +function islandora_ingest_test_set_label_form_submit(array $form, array &$form_state) { + $object = islandora_ingest_form_get_object($form_state); + $object->label = $form_state['values']['label']; + unset($object->models); + $object->models = array($form_state['values']['model']); +} + +/** + * Test the First content model. + */ +function islandora_ingest_test_testcmodel_form(array $form, array &$form_state) { + return array( + ); +} + +/** + * Test the CModel submit. + */ +function islandora_ingest_test_testcmodel_form_submit(array $form, array &$form_state) { + +} + +/** + * Test the second content model. + */ +function islandora_ingest_test_testcmodel2_form(array $form, array &$form_state) { + return array( + ); +} + +/** + * Test the CModel submit. + */ +function islandora_ingest_test_testcmodel2_form_submit(array $form, array &$form_state) { + +} diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc index a5117695..2967280d 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -28,7 +28,7 @@ class IslandoraWebTestCase extends DrupalWebTestCase { $this->backUpDrupalFilter(); $this->setUpDrupalFilter(); } - $this->createAdminUser(); + $this->admin = $this->createAdminUser(); } /** @@ -90,15 +90,20 @@ class IslandoraWebTestCase extends DrupalWebTestCase { * Creates the a full fedora admin user with a repository connection. */ protected function createAdminUser() { - $this->admin = new stdClass(); - $this->admin->uid = 1; - $this->admin->name = $this->configuration['admin_user']; - $this->admin->pass = $this->configuration['admin_pass']; + $roles = user_roles(); + $index = array_search('administrator', $roles); + $user = $this->drupalCreateUser(); + $this->drupalLogin($user); + $user->roles[$index] = 'administrator'; + $user->name = $this->configuration['admin_user']; + $user->pass = $this->configuration['admin_pass']; + $user = user_save($user); $url = variable_get('islandora_base_url', $this->configuration['fedora_url']); - $connection = islandora_get_tuque_connection($this->admin, $url); - $this->admin->repository = $connection->repository; - return $this->admin; + $connection = islandora_get_tuque_connection($user, $url); + $user->repository = $connection->repository; + return $user; } + /** * Stores the content of the Drupal Filter for later restoration. */ From 054278bc8507bab875ad16853441612468a8706a Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Sun, 2 Jun 2013 21:51:23 +0200 Subject: [PATCH 2/3] No longer auto login the admin user breaks other tests that expect the anon user to be logged in. --- tests/{README.txt => README.md} | 4 ++-- tests/ingest.test | 3 ++- tests/islandora_web_test_case.inc | 26 +++++++++++++++++++++++++- 3 files changed, 29 insertions(+), 4 deletions(-) rename tests/{README.txt => README.md} (54%) diff --git a/tests/README.txt b/tests/README.md similarity index 54% rename from tests/README.txt rename to tests/README.md index c03004ae..c4a0ae1a 100644 --- a/tests/README.txt +++ b/tests/README.md @@ -1,4 +1,4 @@ You can define your own configurations specific to your enviroment by copying default.test_config.ini to test_config.ini, making your changes in the copied -file. These test need write access to the system's $FEDORA_HOME/server/config -directory as well as the filter-drupal.xml file. \ No newline at end of file +file. These test need write access to the system's $FEDORA_HOME/server/config +directory as well as the filter-drupal.xml file. diff --git a/tests/ingest.test b/tests/ingest.test index 0878076b..173b926f 100644 --- a/tests/ingest.test +++ b/tests/ingest.test @@ -71,7 +71,8 @@ class IslandoraIngestsTestCase extends IslandoraWebTestCase { * Test Ingest Steps. */ public function testIngest() { - global $user; + // Login the Admin user. + $this->drupalLogin($this->admin); // First step in form. $this->drupalGet('test/ingest'); // Default model selected, has no additional steps. diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc index 2967280d..a39e9a45 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -93,7 +93,6 @@ class IslandoraWebTestCase extends DrupalWebTestCase { $roles = user_roles(); $index = array_search('administrator', $roles); $user = $this->drupalCreateUser(); - $this->drupalLogin($user); $user->roles[$index] = 'administrator'; $user->name = $this->configuration['admin_user']; $user->pass = $this->configuration['admin_pass']; @@ -104,6 +103,31 @@ class IslandoraWebTestCase extends DrupalWebTestCase { return $user; } + /** + * Logs in the given user, handles the special case where the user is admin. + * + * @see DrupalWebTestCase::drupalLogin() + */ + protected function drupalLogin(stdClass &$account) { + if ($account->uid == $this->admin->uid) { + // Create password for Drupal. + $edit = array('pass' => user_password()); + $account = user_save($account, $edit); + // Raw password is used to login. + $account->pass_raw = $edit['pass']; + // We must login before changing the password for fedora. + parent::drupalLogin($account); + $account->name = $this->configuration['admin_user']; + $account->pass = $this->configuration['admin_pass']; + // Save the fedora admin credentials for later GET/POST requests. + $account = user_save($account); + } + else { + parent::drupalLogin($account); + } + } + + /** * Stores the content of the Drupal Filter for later restoration. */ From ca7d099144696065d455bd8f078f8bcdfd30234e Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Mon, 3 Jun 2013 14:45:03 +0200 Subject: [PATCH 3/3] Fix strict warning. --- tests/islandora_web_test_case.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc index a39e9a45..de414c17 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -108,7 +108,7 @@ class IslandoraWebTestCase extends DrupalWebTestCase { * * @see DrupalWebTestCase::drupalLogin() */ - protected function drupalLogin(stdClass &$account) { + protected function drupalLogin(stdClass $account) { if ($account->uid == $this->admin->uid) { // Create password for Drupal. $edit = array('pass' => user_password());