summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Barth2009-07-25 19:02:13 (GMT)
committer Alex Barth2009-07-25 19:02:13 (GMT)
commit19aba4f356b1c4f36165c72af9b37d081d1a8cf6 (patch)
tree5b5a6c1574d213c76fd4a79cbc7ba3f0812f6090
parent10d9f5e66fe164d2171738f2b8107689ba723b31 (diff)
Add CRUD tests for UI. Adjust field type handling.
-rw-r--r--data.module77
-rw-r--r--data_ui/data_ui.admin.inc22
-rw-r--r--data_ui/data_ui.module1
-rw-r--r--data_ui/tests/data_ui.test152
4 files changed, 225 insertions, 27 deletions
diff --git a/data.module b/data.module
index 058b920..7945e36 100644
--- a/data.module
+++ b/data.module
@@ -76,12 +76,20 @@ function data_drop_table($name) {
/**
* Internal singleton/factory function for creating a single instance of a DataTable class.
*
+ * Don't use this function directly. Call data_create_table() or data_get_table() instead.
+ *
* If a schema is given, _data_get_table() creates the table objects DB structure.
*
- * Don't use this function directly. Call data_create_table() or data_get_table() instead.
+ * The purpose of this function is to make sure that
+ *
+ * a) there is only a single DataTable object for accessing a specific DataTable.
+ * b) there is no DataTable object that does not have an existing table.
*/
function _data_get_table($name, $schema = NULL, $title = NULL, $reset = FALSE) {
static $tables;
+ // Simple way of having a way to override the class being used.
+ // This could be refined with a $type parameter in _data_get_table() and depending
+ // functions.
$class = variable_get('data_table_class', 'DataTable');
if ($reset) {
unset($tables[$name]);
@@ -126,13 +134,13 @@ function data_get_all_tables() {
}
/**
- * Get a list of available, simplified field types.
+ * Get a list of supported field definitions.
*
* This list is a sub set of Schema API data types
* http://drupal.org/node/159605
* The keys are simplified handles.
*/
-function data_get_field_types() {
+function data_get_field_definitions() {
return array(
'int' => array(
'type' => 'int',
@@ -156,19 +164,56 @@ function data_get_field_types() {
}
/**
- * Translate a simplified handle into a schema API type definition.
+ * Get a definition key into a schema API type definition.
*
* If no type can be found, FALSE will be returned.
*/
-function data_translate_field_type($type) {
- $types = data_get_field_types();
- if (isset($types[$type])) {
- return $types[$type];
+function data_get_field_definition($key) {
+ $definitions = data_get_field_definitions();
+ if (isset($definitions[$key])) {
+ return $definitions[$key];
}
return FALSE;
}
/**
+ * Get schema API field types supported by Data module.
+ */
+function data_get_field_types() {
+ $definitions = data_get_field_definitions();
+ $types = array();
+ foreach ($definitions as $def) {
+ $types[$def['type']] = $def['type'];
+ }
+ return $types;
+}
+
+/**
+ * Get a Schema API PK definition for a given field type.
+ */
+function data_get_pk_definition($name, $type) {
+ if ($type == 'text') {
+ return array($name, 255);
+ }
+ else {
+ return $name;
+ }
+}
+
+/**
+ * Get a Schema API index definition for a given field type.
+ * @todo: support multiple name/type combinations.
+ */
+function data_get_index_definition($name, $type) {
+ if ($type == 'text') {
+ return array(array($name, 255));
+ }
+ else {
+ return array($name);
+ }
+}
+
+/**
* Create a table name in the data namespace.
* @todo: make overridable.
*/
@@ -234,17 +279,15 @@ function data_get_default_path($name) {
* @todo: may be add option to add a full fledged schema here?
*/
function data_build_schema($keys) {
- $fields = $schema = array();
- $field_types = data_get_field_types();
-
// Build the table definition.
// Fall back to varchar if no valid type is given.
- foreach ($keys as $k => $type) {
- if ($type = data_translate_field_type($type)) {
- $fields[data_safe_name($k)] = $type;
+ $fields = $schema = array();
+ foreach ($keys as $k => $key) {
+ if ($definition = data_get_field_definition($key)) {
+ $fields[data_safe_name($k)] = $definition;
}
else {
- $fields[data_safe_name($k)] = $field_types['varchar'];
+ $fields[data_safe_name($k)] = data_get_field_definition('varchar');
}
}
@@ -254,12 +297,12 @@ function data_build_schema($keys) {
}
/**
- * Build a full schema api field spec.
+ * Build a full schema api field definition.
*
* @param $stub
* Array with at least one key 'type'.
*/
-function data_build_field_spec($stub) {
+function data_build_field_definition($stub) {
$spec = array();
$spec['type'] = $stub['type'];
if ($spec['type'] == 'int') {
diff --git a/data_ui/data_ui.admin.inc b/data_ui/data_ui.admin.inc
index 12f2fdd..daa5ba6 100644
--- a/data_ui/data_ui.admin.inc
+++ b/data_ui/data_ui.admin.inc
@@ -105,30 +105,38 @@ function data_ui_add_form_validate($form, &$form_state) {
* Submit handler for add table form.
*/
function data_ui_add_form_submit($form, &$form_state) {
+
if (isset($form_state['values']['field_num'])) {
$form_state['storage'] = $form_state['values'];
}
elseif (isset($form_state['values']['fields'])) {
// Create a schema from user input.
- $schema = $index = $primary = array();
+ $schema = $index = $primary = $meta = array();
foreach ($form_state['values']['fields'] as $field) {
- $schema['fields'][$field['name']] = data_build_field_spec($field);
+ $schema['fields'][$field['name']] = data_build_field_definition($field);
+ $meta['fields'][$field['name']]['label'] = $field['label'];
+
+ // Limit index if field type is text.
if (!empty($field['index'])) {
- $index[$field['name']] = array($field['name']);
+ $index[$field['name']] = data_get_index_definition($field['name'], $field['type']);
}
if (!empty($field['primary'])) {
- $primary[] = $field['name'];
+ $primary[] = data_get_pk_definition($field['name'], $field['type']);
}
}
$schema['indexes'] = $index;
$schema['primary key'] = $primary;
+
+ // Create table.
if ($table = data_create_table(data_name(trim($form_state['storage']['name'])), $schema, trim($form_state['storage']['title']))) {
+ $meta = $table->update(array('meta' => $meta));
drupal_set_message(t('Created table !table', array('!table' => $table->get('name'))));
}
else {
drupal_set_message(t('Error creating table'), 'error');
}
+
// Unset storage to enable redirect.
unset($form_state['storage']);
$form_state['redirect'] = 'admin/content/data';
@@ -191,7 +199,7 @@ function data_ui_edit_form(&$form_state, $table) {
);
$form['fields'][$field_name]['type'] = array(
'#type' => 'select',
- '#options' => drupal_map_assoc(array('int', 'varchar', 'text')),
+ '#options' => data_get_field_types(),
'#default_value' => $field['type'],
);
$form['fields'][$field_name]['unsigned'] = array(
@@ -299,7 +307,7 @@ function data_ui_edit_form_submit($form, &$form_state) {
}
elseif ($form_state['clicked_button']['#value'] == t('Add new')) {
$new = $form_state['values']['new'];
- $spec = data_build_field_spec($new);
+ $spec = data_build_field_definition($new);
$table->addField($new['name'], $spec);
if (!empty($new['index'])) {
$table->addIndex($new['name']);
@@ -406,7 +414,7 @@ function _data_ui_field_form($required = FALSE) {
);
$form['type'] = array(
'#type' => 'select',
- '#options' => drupal_map_assoc(array('int', 'varchar', 'text')),
+ '#options' => data_get_field_types(),
);
$form['unsigned'] = array(
'#type' => 'checkbox',
diff --git a/data_ui/data_ui.module b/data_ui/data_ui.module
index 2c7b759..32e3061 100644
--- a/data_ui/data_ui.module
+++ b/data_ui/data_ui.module
@@ -73,7 +73,6 @@ function data_ui_theme() {
);
}
-
/**
* Implementation of hook_perm().
*/
diff --git a/data_ui/tests/data_ui.test b/data_ui/tests/data_ui.test
index d4f0ef0..324c689 100644
--- a/data_ui/tests/data_ui.test
+++ b/data_ui/tests/data_ui.test
@@ -28,11 +28,159 @@ class DataTestCaseUI extends DataTestCase {
*/
public function setUp() {
parent::setUp('data', 'data_ui');
+
+ $this->drupalLogin(
+ $this->drupalCreateUser(
+ array(
+ 'administer data tables',
+ )
+ )
+ );
+ }
+
+ /**
+ * CRUD table tests on UI.
+ */
+ public function testCRUDTable() {
+ $table_name = $this->createTable(5);
+ // @todo: edit table.
+ $this->dropTable($table_name);
+ }
+
+ /**
+ * Create a table.
+ *
+ * @todo: verify schema in DB.
+ */
+ protected function createTable($num_fields = 5) {
+ $table_name = $this->randomName();
+ $edit = array(
+ 'name' => $table_name,
+ 'title' => 'My table',
+ 'field_num' => $num_fields
+ );
+ $this->drupalPost('admin/content/data/create', $edit, 'Next');
+ $this->assertText('Define the fields of the new table.');
+
+ $fields = $this->randomFields($num_fields);
+ $edit = $this->formatEditFields($fields);
+ $this->drupalPost(NULL, $edit, 'Create');
+ // Data UI has prefixed the table name.
+ $table_name = data_name($table_name);
+ $this->assertText('Created table '. $table_name);
+
+ // Test schema in DB.
+ // @todo: why do we need to clear the cache here?
+ if ($schema = drupal_get_schema($table_name, true)) {
+ foreach ($schema['primary key'] as $key) {
+ if (is_array($key)) {
+ $primary_keys[] = $key[0];
+ }
+ else {
+ $primary_keys[] = $key;
+ }
+ }
+ foreach ($schema['fields'] as $field_name => $field) {
+ $this->assertEqual($fields[$field_name]['type'], $field['type'], "Field $field_name has correct type.");
+ if ($field['type'] == 'int') {
+ $this->assertEqual(isset($fields[$field_name]['unsigned']), !empty($field['unsigned']) , "Field $field_name has correct unsigned value.");
+ }
+ }
+ foreach ($fields as $field_name => $config) {
+ if (isset($config['index'])) {
+ $this->assertTrue(isset($schema['indexes'][$field_name]), "Field $field_name indexed.");
+ }
+ if (isset($config['primary'])) {
+ $this->assertTrue(in_array($field_name, $primary_keys), "Field $field_name in primary key.");
+ }
+ }
+ }
+ else {
+ $this->assertTrue(FALSE, 'Could not create schema.');
+ }
+
+ return $table_name;
+ }
+
+ /**
+ * Drop a table.
+ */
+ protected function dropTable($table_name) {
+ $this->drupalPost('admin/content/data/'. $table_name .'/drop', array(), 'Drop');
+ $exists = db_result(db_query('SELECT name FROM {data_tables} WHERE name = "%s"', $table_name));
+ $this->assertFalse($exists, 'Table removed from data_tables table.');
+ $this->assertFalse(drupal_get_schema($table_name, true), 'Table '. $table_name .' removed from schema API.');
+ $this->assertFalse(db_table_exists($table_name), 'Table '. $table_name .' removed from DB.');
+ }
+
+ /**
+ * Format an edit array from the result of randomFields().
+ */
+ protected function formatEditFields($fields) {
+ $edit = array();
+ $fields = array_values($fields);
+ foreach ($fields as $i => $field) {
+ foreach ($field as $k => $v) {
+ $edit["fields[field_$i][$k]"] = $v;
+ }
+ }
+ return $edit;
+ }
+
+ /**
+ * Generate N random fields. Will create at least 1 field.
+ */
+ protected function randomFields($n = 5) {
+ $fields = array();
+ for ($i = 0; $i < $n-1; $i++) {
+ $label = $this->uniqueRandomName();
+ $name = data_safe_name($label);
+ $fields[$name] = array(
+ 'name' => $name,
+ 'label' => $label,
+ 'type' => $this->randomValue(data_get_field_types()),
+ );
+ if (rand(0, 1)) {
+ $fields[$name]['unsigned'] = 1;
+ }
+ if (rand(0, 1)) {
+ $fields[$name]['index'] = 1;
+ }
+ if (rand(0, 1)) {
+ $fields[$name]['primary'] = 1;
+ }
+ }
+ // Make sure we have at least one field that is text, PK and indexed.
+ $name = $this->uniqueRandomName();
+ $fields[data_safe_name($name)] = array(
+ 'name' => data_safe_name($name),
+ 'label' => $name,
+ 'type' => 'text',
+ 'index' => 1,
+ 'primary' => 1,
+ );
+
+ return $fields;
+ }
+
+ /**
+ * Get a random value from the given array.
+ */
+ protected function randomValue($array) {
+ $array = array_values($array);
+ return $array[rand(0, count($array) - 1)];
}
/**
- * Run admin UI tests.
+ * Create a _unique_ random name.
*/
- public function testAdminUI() {
+ protected function uniqueRandomName() {
+ static $names;
+ do {
+ $name = $this->randomName();
+ }
+ while (isset($names[$name]));
+ $names[$name] = $name;
+ return $name;
}
} \ No newline at end of file