From 99d3437c8d6d66fcab1cab962f8c6e86b0d18e1c Mon Sep 17 00:00:00 2001
From: megachriz <megachriz@654114.no-reply.drupal.org>
Date: Wed, 23 Dec 2015 14:42:32 +0100
Subject: [PATCH] Issue #2602508 by MegaChriz: Fixed clear out boolean field
 when an empty value is provided.

---
 feeds.info                    |   1 +
 mappers/list.inc              |   9 ++
 tests/feeds/content.csv       |   6 +-
 tests/feeds/content_empty.csv |   6 +-
 tests/feeds_mapper.test       |   3 +
 tests/feeds_mapper_list.test  | 180 ++++++++++++++++++++++++++++++++++
 6 files changed, 199 insertions(+), 6 deletions(-)
 create mode 100644 tests/feeds_mapper_list.test

diff --git a/feeds.info b/feeds.info
index c57e2032..8929f144 100644
--- a/feeds.info
+++ b/feeds.info
@@ -38,6 +38,7 @@ files[] = tests/feeds_mapper_field.test
 files[] = tests/feeds_mapper_file.test
 files[] = tests/feeds_mapper_hooks.test
 files[] = tests/feeds_mapper_link.test
+files[] = tests/feeds_mapper_list.test
 files[] = tests/feeds_mapper_path.test
 files[] = tests/feeds_mapper_profile.test
 files[] = tests/feeds_mapper_unique.test
diff --git a/mappers/list.inc b/mappers/list.inc
index 8c5dc362..2a1196a0 100644
--- a/mappers/list.inc
+++ b/mappers/list.inc
@@ -58,6 +58,15 @@ function list_feeds_set_boolean_target(FeedsSource $source, $entity, $target, ar
       $value = $value->getValue();
     }
 
+    if (is_string($value) && strlen($value) == 0) {
+      // Don't convert an empty string to a boolean.
+      continue;
+    }
+    if (is_null($value)) {
+      // Don't convert a NULL value to a boolean.
+      continue;
+    }
+
     $field[LANGUAGE_NONE][] = array('value' => (int) (bool) $value);
   }
 
diff --git a/tests/feeds/content.csv b/tests/feeds/content.csv
index 1e68bdf8..be5d69d7 100644
--- a/tests/feeds/content.csv
+++ b/tests/feeds/content.csv
@@ -1,3 +1,3 @@
-"guid","title","created","alpha","beta","gamma","delta","body"
-1,"Lorem ipsum",1251936720,"Lorem",42,"4.2",3.14159265,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat."
-2,"Ut wisi enim ad minim veniam",1251932360,"Ut wisi",32,"1.2",5.62951413,"Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat."
+"guid","title","created","alpha","beta","gamma","delta","epsilon","body"
+1,"Lorem ipsum",1251936720,"Lorem",42,"4.2",3.14159265,1,"Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat."
+2,"Ut wisi enim ad minim veniam",1251932360,"Ut wisi",32,"1.2",5.62951413,0,"Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat."
diff --git a/tests/feeds/content_empty.csv b/tests/feeds/content_empty.csv
index 5b08023a..f1afa75c 100644
--- a/tests/feeds/content_empty.csv
+++ b/tests/feeds/content_empty.csv
@@ -1,3 +1,3 @@
-"guid","title","created","end","alpha","beta","gamma","delta","body","link_title","url"
-1,"Lorem ipsum",,,,,,,,,
-2,"Ut wisi enim ad minim veniam",0,0,"0",0,0,0,0,0,0
+"guid","title","created","end","alpha","beta","gamma","delta","epsilon","body","link_title","url"
+1,"Lorem ipsum",,,,,,,,,,
+2,"Ut wisi enim ad minim veniam",0,0,"0",0,0,0,0,0,0,0
diff --git a/tests/feeds_mapper.test b/tests/feeds_mapper.test
index 0cd0d3d7..87efbdb2 100644
--- a/tests/feeds_mapper.test
+++ b/tests/feeds_mapper.test
@@ -22,6 +22,9 @@ class FeedsMapperTestCase extends FeedsWebTestCase {
     'file' => 'file_generic',
     'image' => 'image_image',
     'link_field' => 'link_field',
+    'list_boolean' => 'options_onoff',
+    'list_float' => 'options_select',
+    'list_integer' => 'options_select',
     'list_text' => 'options_select',
     'number_float' => 'number',
     'number_integer' => 'number',
diff --git a/tests/feeds_mapper_list.test b/tests/feeds_mapper_list.test
new file mode 100644
index 00000000..279fdce2
--- /dev/null
+++ b/tests/feeds_mapper_list.test
@@ -0,0 +1,180 @@
+<?php
+
+/**
+ * @file
+ * Contains FeedsMapperListTestCase.
+ */
+
+/**
+ * Test case for List field mappers in mappers/list.inc
+ */
+class FeedsMapperListTestCase extends FeedsMapperTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Mapper: List and Boolean',
+      'description' => 'Test Feeds Mapper support for List and Boolean fields.',
+      'group' => 'Feeds',
+      'dependencies' => array('list'),
+    );
+  }
+
+  public function setUp() {
+    parent::setUp(array('list'));
+  }
+
+  /**
+   * Tests if values are cleared out when an empty value is provided.
+   */
+  public function testClearOutValues() {
+    // Create content type.
+    $typename = $this->createContentType(array(), array(
+      'alpha' => array(
+        'type' => 'list_text',
+        'settings' => array(
+          'field[settings][allowed_values]' => "0\nLorem\nUt wisi",
+        ),
+      ),
+      'beta' => array(
+        'type' => 'list_integer',
+        'settings' => array(
+          'field[settings][allowed_values]' => "0\n42\n32",
+        ),
+      ),
+      'delta' => array(
+        'type' => 'list_float',
+        'settings' => array(
+          'field[settings][allowed_values]' => "0\n3.14159\n5.62951",
+        ),
+      ),
+      'epsilon' => 'list_boolean',
+    ));
+
+    // Create and configure importer.
+    $this->createImporterConfiguration('Content CSV', 'csv');
+    $this->setSettings('csv', NULL, array(
+      'content_type' => '',
+      'import_period' => FEEDS_SCHEDULE_NEVER,
+    ));
+    $this->setPlugin('csv', 'FeedsFileFetcher');
+    $this->setPlugin('csv', 'FeedsCSVParser');
+    $this->setSettings('csv', 'FeedsNodeProcessor', array(
+      'bundle' => $typename,
+      'update_existing' => 1
+    ));
+    $this->addMappings('csv', array(
+      array(
+        'source' => 'guid',
+        'target' => 'guid',
+        'unique' => TRUE,
+      ),
+      array(
+        'source' => 'title',
+        'target' => 'title',
+      ),
+      array(
+        'source' => 'alpha',
+        'target' => 'field_alpha',
+      ),
+      array(
+        'source' => 'beta',
+        'target' => 'field_beta',
+      ),
+      array(
+        'source' => 'delta',
+        'target' => 'field_delta',
+      ),
+      array(
+        'source' => 'epsilon',
+        'target' => 'field_epsilon',
+      ),
+    ));
+
+    // Import CSV file.
+    $this->importFile('csv', $this->absolutePath() . '/tests/feeds/content.csv');
+    $this->assertText('Created 2 nodes');
+
+    // Check the two imported nodes.
+    $this->drupalGet('node/1/edit');
+    $this->assertOptionSelected('edit-field-alpha-und', 'Lorem');
+    $this->assertOptionSelected('edit-field-beta-und', '42');
+    $this->assertOptionSelected('edit-field-delta-und', '3.14159');
+    $this->assertFieldChecked('edit-field-epsilon-und');
+    $this->drupalGet('node/2/edit');
+    $this->assertOptionSelected('edit-field-alpha-und', 'Ut wisi');
+    $this->assertOptionSelected('edit-field-beta-und', '32');
+    $this->assertOptionSelected('edit-field-delta-und', '5.62951');
+    $this->assertNoFieldChecked('edit-field-epsilon-und');
+
+    // Import CSV file with empty values.
+    $this->importFile('csv', $this->absolutePath() . '/tests/feeds/content_empty.csv');
+    $this->assertText('Updated 2 nodes');
+
+    // Check if all values were cleared out for node 1.
+    $this->drupalGet('node/1/edit');
+    $this->assertNoOptionSelected('edit-field-alpha-und', 'Lorem');
+    $this->assertNoOptionSelected('edit-field-beta-und', '42');
+    $this->assertNoOptionSelected('edit-field-delta-und', '3.14159');
+    $this->assertNoFieldChecked('edit-field-epsilon-und');
+    // Check if labels for fields that should be cleared out are not shown.
+    $this->drupalGet('node/1');
+    $this->assertNoText('alpha_list_text_label');
+    $this->assertNoText('beta_list_integer_label');
+    $this->assertNoText('delta_list_float_label');
+    $this->assertNoText('epsilon_list_boolean_label');
+    // Load node 1 and check if the boolean field does *not* have a value.
+    $node = node_load(1, NULL, TRUE);
+    $this->assertTrue(empty($node->field_epsilon[LANGUAGE_NONE]), 'The field field_epsilon is empty.');
+
+    // Check if zero's didn't cleared out values for node 2.
+    $this->drupalGet('node/2/edit');
+    $this->assertOptionSelected('edit-field-alpha-und', '0');
+    $this->assertOptionSelected('edit-field-beta-und', '0');
+    $this->assertOptionSelected('edit-field-delta-und', '0');
+    $this->assertNoFieldChecked('edit-field-epsilon-und');
+    // Check if labels for fields of node 2 are still shown.
+    $this->drupalGet('node/2');
+    $this->assertText('alpha_list_text_label');
+    $this->assertText('beta_list_integer_label');
+    $this->assertText('delta_list_float_label');
+    $this->assertText('epsilon_list_boolean_label');
+    // Load node 2 and check if the boolean field *does* have a value.
+    $node = node_load(2, NULL, TRUE);
+    $this->assertEqual('0', $node->field_epsilon[LANGUAGE_NONE][0]['value']);
+
+    // Re-import the first file again.
+    $this->importFile('csv', $this->absolutePath() . '/tests/feeds/content.csv');
+    $this->assertText('Updated 2 nodes');
+
+    // Check if the two imported nodes have content again.
+    $this->drupalGet('node/1/edit');
+    $this->assertOptionSelected('edit-field-alpha-und', 'Lorem');
+    $this->assertOptionSelected('edit-field-beta-und', '42');
+    $this->assertOptionSelected('edit-field-delta-und', '3.14159');
+    $this->assertFieldChecked('edit-field-epsilon-und');
+    $this->drupalGet('node/2/edit');
+    $this->assertOptionSelected('edit-field-alpha-und', 'Ut wisi');
+    $this->assertOptionSelected('edit-field-beta-und', '32');
+    $this->assertOptionSelected('edit-field-delta-und', '5.62951');
+    $this->assertNoFieldChecked('edit-field-epsilon-und');
+
+    // Import CSV file with non-existent values.
+    $this->importFile('csv', $this->absolutePath() . '/tests/feeds/content_non_existent.csv');
+    $this->assertText('Updated 2 nodes');
+
+    // Check if all values were cleared out for node 1.
+    $this->drupalGet('node/1/edit');
+    $this->assertNoOptionSelected('edit-field-alpha-und', 'Lorem');
+    $this->assertNoOptionSelected('edit-field-beta-und', '42');
+    $this->assertNoOptionSelected('edit-field-delta-und', '3.14159');
+    $this->assertNoFieldChecked('edit-field-epsilon-und');
+    // Check if labels for fields that should be cleared out are not shown.
+    $this->drupalGet('node/1');
+    $this->assertNoText('alpha_list_text_label');
+    $this->assertNoText('beta_list_integer_label');
+    $this->assertNoText('delta_list_float_label');
+    $this->assertNoText('epsilon_list_boolean_label');
+    // Load node 1 and check if the boolean field does *not* have a value.
+    $node = node_load(1, NULL, TRUE);
+    $this->assertTrue(empty($node->field_epsilon[LANGUAGE_NONE]), 'The field field_epsilon is empty.');
+  }
+}
-- 
GitLab