? crud_simpletest.patch Index: content.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/cck/content.module,v retrieving revision 1.245 diff -u -p -r1.245 content.module --- content.module 27 Jan 2008 18:52:05 -0000 1.245 +++ content.module 28 Jan 2008 20:47:36 -0000 @@ -1861,3 +1861,13 @@ function content_extra_field_weight($typ return $type['extra'][$pseudo_field_name]['weight']; } } + +/** + * Implementation of hook_simpletest(). + */ +function content_simpletest() { + $module_name = 'content'; + $dir = drupal_get_path('module', $module_name). '/tests'; + $tests = file_scan_directory($dir, '\.test$'); + return array_keys($tests); +} Index: tests/content_crud.test =================================================================== RCS file: tests/content_crud.test diff -N tests/content_crud.test --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ tests/content_crud.test 28 Jan 2008 20:47:37 -0000 @@ -0,0 +1,268 @@ + t('CCK CRUD API'), + 'desc' => t('Tests the CRUD (create, read, update, delete) API for content types.'), + 'group' => t('CCK'), + ); + } + + var $enabled_schema = FALSE; + var $previous_node_changes; + var $previous_node_changes_nid; + var $content_types = array(); + var $nodes = array(); + var $last_field; + + /** + * Checks that the given database table does NOT exist + * @param $table Name of the table to check + * @param $message The translated message to describe the assertion + */ + function assertTableNotExists($table) { + $this->assertFalse(db_table_exists($table), t('Table !table should not exist', array('!table' => $table))); + } + + function assertSchemaMatches($table, $columns) { + $schema = drupal_get_schema($table, TRUE); + $mismatches = array(); + if ($schema === FALSE) { + $mismatches[] = t('table does not exist'); + } + else { + $fields = $schema['fields']; + $fields_count = count($columns); + foreach ($columns as $field) { + if (!isset($fields[$field])) { + $mismatches[] = t('field !field is missing', array('!field' => $field)); + } + else { + --$fields_count; + } + } + if ($fields_count != 0) { + $mismatches[] = t('table contains unexpected fields'); + } + } + $this->assertEqual(count($mismatches), 0, t('Table !table matches schema: !details', + array('!table' => $table, '!details' => implode($mismatches, ', ')))); + + if (!$this->enabled_schema) { + $this->enabled_schema = $this->drupalModuleEnable('schema'); + } + if ($this->enabled_schema) { + // Clunky workaround for http://drupal.org/node/215198 + $table = db_prefix_tables('{'. $table .'}'); + $inspect = schema_invoke('inspect', $table); + $inspect = isset($inspect[$table]) ? $inspect[$table] : NULL; + $compare = schema_compare_table($schema, $inspect); + if ($compare['status'] == 'missing') { + $compare['reasons'] = array(t('table does not exist')); + } + } + else { + $compare = array('status' => 'unknown', 'reasons' => array(t('cannot enable schema module'))); + } + $this->assertEqual($compare['status'], 'same', t('Table schema for !table matches database: !details', + array('!table' => $table, '!details' => implode($compare['reasons'], ', ')))); + } + + /** + * Helper function for assertNodeSaveLoadUnchanged. Recursively checks that + * all the keys of a table are present in a second and have the same value + */ + function _compareArrayForChanges($fields, $data, $message, $prefix = '') { + foreach ($fields as $key => $value) { + $newprefix = ($prefix == '') ? $key : $prefix .']['. $key; + if (is_array($value)) { + $compare_to = isset($data[$key]) ? $data[$key] : array(); + $this->_compareArrayForChanges($value, $compare_to, $message, $newprefix); + } + else { + $this->assertEqual($value, $data[$key], t($message, array('!key' => $newprefix))); + } + } + } + + /** + * Checks that changes can be made to a node through the web interface, and that + * these changes are saved to the database and can be retrieved by node_load. + */ + function assertNodeSaveLoadUnchanged($node, $fields) { + if (isset($this->nodes[$node])) { + $node = $this->nodes[$node]; + } + $node = $fields + (array)$node; + $node = (object)$node; + node_save($node); + $this->previous_node_changes_nid = $node->nid; + $this->previous_node_changes = $fields; + $this->assertNodeStillUnchanged($node->nid); + } + + function assertNodeStillUnchanged() { + $node = node_load($this->previous_node_changes_nid, NULL, TRUE); + $this->_compareArrayForChanges($this->previous_node_changes, (array)$node, 'data !key'); + } + + function assertNodeMissingFields($nid, $fields) { + $node = (array)node_load($nid, NULL, TRUE); + foreach ($fields as $field) { + $this->assertFalse(isset($node[$field]), t('Node should be lacking field !key', array('!key' => $field))); + } + } + + function loginWithPermissions($permissions = NULL) { + if (!isset($permissions)) { + $permissions = array( + 'access content', + 'administer content types', + 'administer nodes', + 'administer filters', + ); + } + $user = $this->drupalCreateUserRolePerm($permissions); + $this->drupalLoginUser($user); + } + + function acquireContentTypes($count) { + $this->content_types = array(); + for($i = 0; $i < $count; $i++) { + $this->content_types[$i] = $this->drupalCreateContentType(); + } + content_clear_type_cache(); + } + + function acquireNodes($count = NULL) { + $this->nodes = array(); + $content_types_count = count($this->content_types); + if (!isset($count)) { + $count = $content_types_count; + } + for($i = 0; $i < $count; $i++) { + $type = $this->content_types[$i % $content_types_count]; + $this->nodes[$i] = $this->drupalCreateNode(array('type' => $type->type)); + } + } + + function createField($settings, $typeindex = 0) { + $defaults = array( + 'field_name' => $this->randomName(4, 'field_'), + 'type_name' => $this->content_types[$typeindex]->type, + ); + $settings = $settings + $defaults; + $this->last_field = content_field_instance_create($settings); + return $this->last_field; + } + + function updateField($settings, $field = NULL) { + if (!isset($field)) { + $field = $this->last_field; + } + $defaults = array( + 'field_name' => $field['field_name'], + 'type_name' => $field['type_name'] , + ); + $settings = $settings + $defaults; + $this->last_field = content_field_instance_update($settings); + return $this->last_field; + } + + function shareField($new_content_type, $field = NULL) { + if (!isset($field)) { + $field = $this->last_field; + } + if (isset($this->content_types[$new_content_type])) { + $new_content_type = $this->content_types[$new_content_type]; + } + $field['type_name'] = $new_content_type->type; + $this->last_field = content_field_instance_create($field); + return $this->last_field; + } + + function deleteField($content_type, $field = NULL) { + if (!isset($field)) { + $field = $this->last_field; + } + if (isset($this->content_types[$content_type])) { + $content_type = $this->content_types[$content_type]; + } + content_field_instance_delete($field['field_name'], $content_type->type); + } + + function testSingleToMultiple() { + // Acquire the context + $this->loginWithPermissions(); + $this->acquireContentTypes(3); + $this->acquireNodes(); + + // Create a simple text field + $field = $this->createField(array( + 'type' => 'text', + 'widget_type' => 'text_textfield', + 'text_processing' => 1, + )); + $field_name = $field['field_name']; + $this->assertSchemaMatches('content_type_'. $this->content_types[0]->type, array( + 'nid', + 'vid', + $field_name .'_value', + $field_name .'_format', + )); + $this->assertNodeSaveLoadUnchanged(0, array( + $field_name => array( + 0 => array( + 'value' => '!SimpleTest! test value' . $this->randomName(60), + 'format' => 2, + ) + ) + )); + + // Change the text field to allow multiple values + $this->updateField(array('multiple' => 1)); + $this->assertSchemaMatches('content_type_'. $this->content_types[0]->type, array( + 'nid', + 'vid', + )); + $this->assertSchemaMatches('content_'. $field_name, array( + 'vid', + 'nid', + 'delta', + $field_name .'_value', + $field_name .'_format', + )); + $this->assertNodeStillUnchanged(); + + // Share the text field with other content types + for ($share_with = 1; $share_with <= 2; $share_with++) { + $this->shareField($share_with); + $this->assertSchemaMatches('content_type_'. $this->content_types[$share_with]->type, array( + 'nid', + 'vid', + )); + $this->assertNodeSaveLoadUnchanged($share_with, array( + $field_name => array( + 0 => array( + 'value' => '!SimpleTest! test value' . $this->randomName(60), + 'format' => 2, + ) + ) + )); + } + + // Delete the text field from all content types + for ($delete_from = 2; $delete_from >= 0; $delete_from--) { + $this->deleteField($delete_from); + $this->assertTableNotExists('content_type_'. $this->content_types[$delete_from]->type); + $this->assertNodeMissingFields($this->nodes[$delete_from], array($field_name)); + } + } + + function testMultipleToSingle() { + + } + +}