diff --git a/src/Plugin/Validation/Constraint/SafeSearchConstraintValidator.php b/src/Plugin/Validation/Constraint/SafeSearchConstraintValidator.php index 48543f8..4ace233 100755 --- a/src/Plugin/Validation/Constraint/SafeSearchConstraintValidator.php +++ b/src/Plugin/Validation/Constraint/SafeSearchConstraintValidator.php @@ -62,7 +62,7 @@ class SafeSearchConstraintValidator extends ConstraintValidator implements Conta $result = $this->googleVisionAPI->safeSearchDetection($filepath); if (!empty($result['responses'][0]['safeSearchAnnotation'])) { $adult = $result['responses'][0]['safeSearchAnnotation']['adult']; - $likelihood = array('LIKELY', 'VERY_LIKELY'); + $likelihood = array('POSSIBLE', 'LIKELY', 'VERY_LIKELY'); // if the image has explicit content. if (in_array($adult, $likelihood)) { $this->context->addViolation($constraint->message); diff --git a/src/Tests/SafeSearchConstraintValidationTest.php b/src/Tests/SafeSearchConstraintValidationTest.php new file mode 100644 index 0000000..1d68ddc --- /dev/null +++ b/src/Tests/SafeSearchConstraintValidationTest.php @@ -0,0 +1,195 @@ +drupalCreateContentType(array('type' => 'test_images', 'name' => 'Test Images')); + // Creates administrative user. + $this->adminUser = $this->drupalCreateUser(array('administer google vision','create test_images content', 'access content', 'access administration pages', 'administer node fields', 'administer nodes', 'administer node display') + ); + $this->drupalLogin($this->adminUser); + } + + /** + * Create a new image field. + * + * @param string $name + * The name of the new field (all lowercase), exclude the "field_" prefix. + * @param string $type_name + * The node type that this field will be added to. + * @param array $storage_settings + * A list of field storage settings that will be added to the defaults. + * @param array $field_settings + * A list of instance settings that will be added to the instance defaults. + * @param array $widget_settings + * Widget settings to be added to the widget defaults. + * @param array $formatter_settings + * Formatter settings to be added to the formatter defaults. + * @param string $description + * A description for the field. + */ + public function createImageField($name, $type_name, $storage_settings = array(), $field_settings = array(), $widget_settings = array(), $formatter_settings = array(), $description = '') { + FieldStorageConfig::create(array( + 'field_name' => $name, + 'entity_type' => 'node', + 'type' => 'image', + 'settings' => $storage_settings, + 'cardinality' => 1, + ))->save(); + + $field_config = FieldConfig::create([ + 'field_name' => $name, + 'label' => $name, + 'entity_type' => 'node', + 'bundle' => $type_name, + 'settings' => $field_settings, + 'description' => $description, + ])->addConstraint('SafeSearch'); + $field_config->save(); + + /*$field_config = FieldConfigBase::create([ + 'field_name' => $name, + 'label' => $name, + 'entity_type' => 'node', + 'bundle' => $type_name, + 'settings' => $field_settings, + 'description' => $description, + ])->addConstraint('SafeSearch'); + $field_config->save();*/ + + entity_get_form_display('node', $type_name, 'default') + ->setComponent($name, array( + 'type' => 'image_image', + 'settings' => $widget_settings, + )) + ->save(); + + entity_get_display('node', $type_name, 'default') + ->setComponent($name, array( + 'type' => 'image', + 'settings' => $formatter_settings, + )) + ->save(); + + return $field_config; + + } + + /** + * Upload an image to the node of type test_images and create the node. + * + * @param The image file $image + * A file object representing the image to upload. + */ + function uploadImageFile($image) { + $edit = array( + 'title[0][value]' => $this->randomMachineName(), + 'files[images_0]' => drupal_realpath($image->getFileUri()), + ); + + $this->drupalPostForm('node/add/test_images' , $edit, t('Save and publish')); + // Add alt text. + $this->drupalPostForm(NULL, ['images[0][alt]' => $this->randomMachineName()], t('Save and publish')); + + // Retrieve ID of the newly created node from the current URL. + $matches = array(); + preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches); + return isset($matches[1]) ? $matches[1] : FALSE; + } + + /** + * + */ + public function testSafeSearchConstraint() { + $this->drupalGet('node/add/test_images'); + $this->assertResponse(200); + + // Create an image field and add an field to the custom content type. + $storage_settings['default_image'] = array( + 'uuid' => 1, + 'alt' => '', + 'title' => '', + 'width' => 0, + 'height' => 0, + ); + $field_settings['default_image'] = array( + 'uuid' => 1, + 'alt' => '', + 'title' => '', + 'width' => 0, + 'height' => 0, + ); + $widget_settings = array( + 'preview_image_style' => 'medium', + ); + $field = $this->createImageField('images', 'test_images', $storage_settings, $field_settings, $widget_settings); + + $field_id = $field->id(); + + //Enable the Safe Search. + $edit = array( + 'safe_search' => 1, + ); + $this->drupalPostForm("admin/structure/types/manage/test_images/fields/$field_id", $edit, t('Save settings')); + + //Ensure that the safe search is enabled. + $this->drupalGet("admin/structure/types/manage/test_images/fields/$field_id"); + + // Get an image with explicit content from web. + + $image = file_get_contents('http://www.menshealth.com/sites/menshealth.com/files/articles/2015/12/man-snoring.jpg'); // string + $file = file_save_data($image, 'public://explicit.jpg', FILE_EXISTS_REPLACE); + + // Save the node. + $node_id = $this->uploadImageFile($file); + + + //Display the node. + $this->drupalGet('node/' . $node_id); + + } +} diff --git a/tests/src/Functional/SafeSearchTest.php b/tests/src/Functional/SafeSearchTest.php new file mode 100755 index 0000000..e8164ba --- /dev/null +++ b/tests/src/Functional/SafeSearchTest.php @@ -0,0 +1,234 @@ + 'foo'. + * + * @return \Drupal\node\Entity\NodeType + * Created content type. + */ + protected function drupalCreateContentType(array $values = array()) { + // Find a non-existent random type name. + if (!isset($values['type'])) { + do { + $id = strtolower($this->randomMachineName(8)); + } while (NodeType::load($id)); + } + else { + $id = $values['type']; + } + $values += array( + 'type' => $id, + 'name' => $id, + ); + $type = NodeType::create($values); + $status = $type->save(); + node_add_body_field($type); + \Drupal::service('router.builder')->rebuild(); + + if ($this instanceof \PHPUnit_Framework_TestCase) { + $this->assertSame($status, SAVED_NEW, (new FormattableMarkup('Created content type %type.', array('%type' => $type->id())))->__toString()); + } + else { + $this->assertEqual($status, SAVED_NEW, (new FormattableMarkup('Created content type %type.', array('%type' => $type->id())))->__toString()); + } + + return $type; + } + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + //Create custom content type. + $contentType = $this->drupalCreateContentType(array('type' => 'test_images', 'name' => 'Test Images')); + + // Creates user. + $this->adminUser = $this->drupalCreateUser(array('administer google vision', 'create test_images content', 'access content', 'access administration pages', 'administer node fields', 'administer nodes', 'administer node display') + ); + $this->drupalLogin($this->adminUser); + } + + /** + * Create a new image field. + * + * @param string $name + * The name of the new field (all lowercase), exclude the "field_" prefix. + * @param string $type_name + * The node type that this field will be added to. + * @param array $storage_settings + * A list of field storage settings that will be added to the defaults. + * @param array $field_settings + * A list of instance settings that will be added to the instance defaults. + * @param array $widget_settings + * Widget settings to be added to the widget defaults. + * @param array $formatter_settings + * Formatter settings to be added to the formatter defaults. + * @param string $description + * A description for the field. + */ + public function createImageField($name, $type_name, $storage_settings = array(), $field_settings = array(), $widget_settings = array(), $formatter_settings = array(), $description = '') { + FieldStorageConfig::create(array( + 'field_name' => $name, + 'entity_type' => 'node', + 'type' => 'image', + 'settings' => $storage_settings, + 'cardinality' => 1, + ))->save(); + + $field_config = FieldConfig::create([ + 'field_name' => $name, + 'label' => $name, + 'entity_type' => 'node', + 'bundle' => $type_name, + 'settings' => $field_settings, + 'description' => $description, + ])->addConstraint('SafeSearch'); + $field_config->save(); + + /*$field_config = FieldConfigBase::create([ + 'field_name' => $name, + 'label' => $name, + 'entity_type' => 'node', + 'bundle' => $type_name, + 'settings' => $field_settings, + 'description' => $description, + ])->addConstraint('SafeSearch'); + $field_config->save();*/ + + entity_get_form_display('node', $type_name, 'default') + ->setComponent($name, array( + 'type' => 'image_image', + 'settings' => $widget_settings, + )) + ->save(); + + entity_get_display('node', $type_name, 'default') + ->setComponent($name, array( + 'type' => 'image', + 'settings' => $formatter_settings, + )) + ->save(); + + return $field_config; + + } + + /** + * Upload an image to the node of type test_images and create the node. + * + * @param The image file $image + * A file object representing the image to upload. + */ + function uploadImageFile($image) { + $edit = array( + 'title[0][value]' => $this->randomMachineName(), + 'files[images_0]' => drupal_realpath($image->getFileUri()), + ); + + $this->drupalPostForm('node/add/test_images' , $edit, t('Save and publish')); + // Add alt text. + $this->drupalPostForm(NULL, ['images[0][alt]' => $this->randomMachineName()], t('Save and publish')); + + // Retrieve ID of the newly created node from the current URL. + $matches = array(); + preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches); + return isset($matches[1]) ? $matches[1] : FALSE; + } + + /** + * + */ + public function testSafeSearch() { + $this->drupalGet('node/add/test_images'); + $this->assertSession()->statusCodeEquals(200); + + // Create an image field and add an field to the custom content type. + $storage_settings['default_image'] = array( + 'uuid' => 1, + 'alt' => '', + 'title' => '', + 'width' => 0, + 'height' => 0, + ); + $field_settings['default_image'] = array( + 'uuid' => 1, + 'alt' => '', + 'title' => '', + 'width' => 0, + 'height' => 0, + ); + $widget_settings = array( + 'preview_image_style' => 'medium', + ); + $field = $this->createImageField('images', 'test_images', $storage_settings, $field_settings, $widget_settings); + + $field_id = $field->id(); + + //Enable the Safe Search. + $edit = array( + 'safe_search' => 1, + ); + $this->drupalPostForm("admin/structure/types/manage/test_images/fields/$field_id", $edit, t('Save settings')); + + //Ensure that the safe search is enabled. + $this->drupalGet("admin/structure/types/manage/test_images/fields/$field_id"); + + // Get an image with explicit content from web. + + $image = file_get_contents('http://timesofindia.indiatimes.com/thumb/msid-47037838,width-400,resizemode-4/47037838.jpg'); // string + $file = file_save_data($image, 'public://explicit.jpg', FILE_EXISTS_REPLACE); + + // Save the node. + $node_id = $this->uploadImageFile($file); + + + //Display the node. + $this->drupalGet('node/' . $node_id); + } +}