Index: modules/geocode_widget/tests/geocode_widget.test
--- /dev/null
+++ modules/geocode_widget/tests/geocode_widget.test
@@ -0,0 +1,256 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ *  Test cases for geocoding to cck fields with geocode widget
+ *  So far only testing to geo point.
+ *  @todo from imagefield files; from filefield gpx...
+ */
+
+/**
+ * Base class for testing geocoding of CCK fields with geocode widget.
+ */
+class GeocodeWidgetWebTestCase extends DrupalWebTestCase {
+  /**
+   * Default widgets for fields
+   */
+  private static $field_widgets = array(
+    'text' => 'text_textfield',
+    'geo' => 'geo',  // wkt?
+    'postal' => 'postal_field',
+  );
+
+  /**
+   * Basic setup for all widget tests.
+   */
+  public function setUp() {
+    if (version_compare(PHP_VERSION, '5.2.3', '<')) {
+      $this->fail(t('Geocode requires PHP 5.2.0 or greater. This test requires 5.2.3 or greater'));
+    }
+    // Call parent setup with minimum required modules.
+    $modules = func_get_args();
+    $modules = array_merge(array('geocode', 'geocode_widget', 'geo', 'geo_field', 'content'), $modules);
+    call_user_func_array('parent::setUp', $modules); // requires php >= 5.2.3
+
+    // Useful, a user who can admin content types
+    // for now -- create multiple protected users?
+    // not much permissions testing here?
+    $this->drupalLogin($this->drupalCreateUser(
+      array(
+        'administer content types',
+        'administer nodes',
+      )
+    ));
+  }
+
+  /**
+   * Create a new content-type, and add a field to it. Mostly copied from
+   * cck/tests/content.crud.test ContentUICrud::testAddFieldUI via feeds
+   *
+   * @param $typename
+   *   (Optional) the name of the content-type to create, defaults to a random name.
+   * @param $fields
+   *   (Optional) an keyed array of $field_name => $field_type used to add additional
+   *   fields to the new content type.
+   *
+   * @return
+   *   The name of the new typename.
+   */
+  final protected function createContentType($typename = NULL, $fields = array()) {
+    if ($typename == NULL) {
+      $typename = 'content_type_'. mt_rand();
+    }
+
+    // Create the content type.
+    $edit = array(
+      'type' => $typename,
+      'name' => $typename,
+    );
+    $this->drupalPost('admin/content/types/add', $edit, 'Save content type');
+    $this->assertText('The content type ' . $typename . ' has been added', 'Content type created');
+
+    $admin_type_url = 'admin/content/node-type/'. str_replace('_', '-', $typename);
+
+    // Create the fields
+    foreach ($fields as $field_name => $options) {
+      if (is_string($options)) {
+        $options = array('type' => $options);
+      }
+      $field_type = isset($options['type']) ? $options['type'] : 'text';
+      $field_widget = isset($options['widget']) ? $options['widget'] : $this->selectFieldWidget($field_name, $field_type);
+      $this->assertTrue($field_widget !== NULL, "Field type $field_type supported");
+      $label = $field_name . '_' . $field_type . '_label';
+      $edit = array(
+        '_add_new_field[label]' => $label,
+        '_add_new_field[field_name]' => $field_name,
+        '_add_new_field[type]' => $field_type,
+        '_add_new_field[widget_type]' => $field_widget,
+      );
+      $this->drupalPost($admin_type_url . '/fields', $edit, 'Save');
+
+      // (Default) Configure the field.
+      $edit = isset($options['settings']) ? $options['settings'] : array();
+      $this->drupalPost(NULL, $edit, 'Save field settings');
+      $this->assertText('Added field ' . $label);
+      /**
+       * $this->drupalGet($admin_type_url.'/fields/field_'.$field_name);
+       * cache_clear_all();
+       * $this->drupalGet('node/add/' . str_replace('_', '-', $typename));
+       */
+    }
+
+    $this->drupalPost(NULL, NULL, t('Save'));
+
+    return $typename;
+  }
+
+  /**
+   * Select the widget for the field. Default implementation provides widgets
+   * for Date, Number, Text, Node reference, User reference, Email, Emfield,
+   * Filefield, Image, and Link. Copied from feeds.module
+   *
+   * Extracted as a method to allow test implementations to add widgets for
+   * the tested CCK field type(s). $field_name allow to test the same
+   * field type with different widget (is this useful ?)
+   *
+   * @param $field_name
+   *   The name of the field.
+   * @param $field_type
+   *   The CCK type of the field.
+   *
+   * @return
+   *   The widget for this field, or NULL if the field_type is not
+   *   supported by this test class.
+   */
+  protected function selectFieldWidget($field_name, $field_type) {
+    $field_widgets = GeocodeWidgetWebTestCase::$field_widgets;
+    return isset($field_widgets[$field_type]) ? $field_widgets[$field_type] : NULL;
+  }
+
+  /**
+   * Field to geo point.
+   *
+   * @param $content_type
+   *  Name of configured content type to post to.
+   * @param $text
+   *  String location to search for.
+   * @param $wkt
+   *  String WKT result to test for.
+   *
+   * Checks node/add form for widget hiding geo field.
+   * Checks submission and correct geocoded point saved to geo field.
+   */
+  protected function fieldToPoint($content_type, $field_values, $wkt) {
+    $this->drupalGet('node/add/' . str_replace('_', '-', $content_type));
+    $this->assertNoRaw('field_geo', t('Geo field not visible on form'));
+    $field_values['title'] = $this->randomName();
+    $this->drupalPost(NULL, $field_values, t('Save'));
+    foreach ($field_values as $key => $text) {
+      if (! empty($text)) {
+        $this->assertText($text, t('Text for %field found', array('%field' => $key)));
+      }
+    }
+    $this->assertText($wkt, t('Point geocoded and saved to geo field'));
+  }
+}
+
+/**
+ * Web test class for text field geocoding.
+ * @todo textarea
+ * @todo multiple
+ */
+class GeocodeTextWigetTestCase extends GeocodeWidgetWebTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Text field related geocoding with geocode widget',
+      'description' => 'CCK text fields gecoded to geo field. Requires CCK and Geo.',
+      'group' => 'Geocode',
+    );
+  }
+
+  /**
+   * Set up, add text module.
+   */
+  public function setUp() {
+    parent::setUp('text');
+  }
+
+  /**
+   * Creates a content type with single text field,
+   *   and a geo field with geocode widget.
+   */
+  public function testTextToPoint() {
+    $content_type = $this->createContentType(NULL, array(
+      'text' => array('type' => 'text'),
+      'geo' => array(
+        'type' => 'geo',
+        'widget' => 'geocode_geo',
+        'settings' => array(
+          'geocode_fields[field_text][status]' => TRUE,
+          'geocode_fields[field_text][handler]' => 'geocode_google',
+          'geocode_fields[field_text][return]' => 'point', // only option
+        ),
+      ),
+    ));
+
+    // a specific address
+    $this->fieldToPoint($content_type, array('field_text[0][value]' => '10 Downing Street, Westminster, London SW1A 2AA, United Kingdom'), 'POINT(-0.127821 51.50334)'); // @todo could have a pretty name
+    // a city
+    $this->fieldToPoint($content_type, array('field_text[0][value]' => 'Buenos Aires'), 'POINT(-58.3731613 -34.6084175)');
+    // a country
+    $this->fieldToPoint($content_type, array('field_text[0][value]' => 'Nepal'), 'POINT(84.124008 28.394857)');
+  }
+}
+
+/**
+ * Web test class for postal field geocoding.
+ *
+ * @todo postal field also can have individual fields option,
+ *   can't presently get working, but add when it is.
+ */
+class GeocodePostalWigetTestCase extends GeocodeWidgetWebTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Postal field related geocoding with geocode widget',
+      'description' => 'CCK postal fields gecoded to geo field. Requires CCK, postal and Geo.',
+      'group' => 'Geocode',
+    );
+  }
+
+  /**
+   * Setup, add postal and postal_field modules.
+   */
+  public function setUp() {
+    parent::setUp('postal', 'postal_field');
+  }
+
+  /**
+   * Test postal field to geo field point.
+   *
+   * Creates a postal field, and a geo field with geocode widget.
+   */
+  public function testPostalToPoint() {
+    $content_type = $this->createContentType(NULL, array(
+      'postal' => array('type' => 'postal'),
+      'geo' => array(
+        'type' => 'geo',
+        'widget' => 'geocode_geo',
+        'settings' => array(
+          'geocode_fields[field_postal][status]' => TRUE,
+          'geocode_fields[field_postal][handler]' => 'geocode_google',
+          'geocode_fields[field_postal][return]' => 'point',
+        ),
+      ),
+    ));
+
+    $postal = array(
+      'field_postal[0][street1]' => '10 Downing Street',
+      'field_postal[0][street2]' => 'Westminster',
+      'field_postal[0][city]' => 'London',
+      'field_postal[0][state]' => '',
+      'field_postal[0][zip]' => 'SW1A 2AA',
+    );
+    $this->fieldToPoint($content_type, $postal, 'POINT(-0.127821 51.50334)');
+  }
+}
