Yaffs site version 1.1
[yaffs-website] / web / modules / contrib / media_entity_twitter / tests / src / Unit / ConstraintsTest.php
1 <?php
2
3 namespace Drupal\Tests\media_entity_twitter\Unit;
4
5 use Drupal\Core\Field\Plugin\Field\FieldType\StringLongItem;
6 use Drupal\Core\TypedData\ComplexDataDefinitionInterface;
7 use Drupal\media_entity_twitter\Plugin\Validation\Constraint\TweetEmbedCodeConstraint;
8 use Drupal\media_entity_twitter\Plugin\Validation\Constraint\TweetEmbedCodeConstraintValidator;
9 use Drupal\media_entity_twitter\Plugin\Validation\Constraint\TweetVisibleConstraint;
10 use Drupal\media_entity_twitter\Plugin\Validation\Constraint\TweetVisibleConstraintValidator;
11 use Drupal\Tests\UnitTestCase;
12
13 /**
14  * Tests media_entity_twitter constraints.
15  *
16  * @group media_entity
17  */
18 class ConstraintsTest extends UnitTestCase {
19
20   /**
21    * Creates a string_long FieldItemInterface wrapper around a value.
22    *
23    * @param string $value
24    *   The wrapped value.
25    *
26    * @return \Drupal\Core\Field\FieldItemInterface
27    *   Mocked string field item.
28    */
29   protected function getMockFieldItem($value) {
30     $definition = $this->prophesize(ComplexDataDefinitionInterface::class);
31     $definition->getPropertyDefinitions()->willReturn([]);
32
33     $item = new StringLongItem($definition->reveal());
34     $item->set('value', $value);
35
36     return $item;
37   }
38
39   /**
40    * Tests TweetEmbedCode constraint.
41    *
42    * @covers \Drupal\media_entity_twitter\Plugin\Validation\Constraint\TweetEmbedCodeConstraintValidator
43    * @covers \Drupal\media_entity_twitter\Plugin\Validation\Constraint\TweetEmbedCodeConstraint
44    *
45    * @dataProvider embedCodeProvider
46    */
47   public function testTweetEmbedCodeConstraint($embed_code, $expected_violation_count) {
48     // Check message in constraint.
49     $constraint = new TweetEmbedCodeConstraint();
50     $this->assertEquals('Not valid Tweet URL/embed code.', $constraint->message, 'Correct constraint message found.');
51
52     $execution_context = $this->getMockBuilder('\Drupal\Core\TypedData\Validation\ExecutionContext')
53       ->disableOriginalConstructor()
54       ->getMock();
55
56     if ($expected_violation_count) {
57       $execution_context->expects($this->exactly($expected_violation_count))
58         ->method('addViolation')
59         ->with($constraint->message);
60     }
61     else {
62       $execution_context->expects($this->exactly($expected_violation_count))
63         ->method('addViolation');
64     }
65
66     $validator = new TweetEmbedCodeConstraintValidator();
67     $validator->initialize($execution_context);
68
69     $validator->validate($this->getMockFieldItem($embed_code), $constraint);
70   }
71
72   /**
73    * Provides test data for testTweetEmbedCodeConstraint().
74    */
75   public function embedCodeProvider() {
76     return [
77       'valid tweet URL' => ['https://twitter.com/drupal8changes/status/649167396230578176', 0],
78       'valid tweet embed code' => ['<blockquote class="twitter-tweet" lang="en"><p lang="en" dir="ltr">EntityChangedInterface now also defines the function setChangedTime <a href="http://t.co/1Q58UcR8OY">http://t.co/1Q58UcR8OY</a></p>&mdash; Drupal 8 Changes (@drupal8changes) <a href="https://twitter.com/drupal8changes/status/649167396230578176">September 30, 2015</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>', 0],
79       'invalid URL' => ['https://drupal.org/project/media_entity_twitter', 1],
80       'invalid text' => ['I want my Tweet!', 1],
81       'invalid tweet URL' => ['https://twitter.com/drupal8changes/statustypo/649167396230578176', 1],
82       'invalid tweet ID' => ['https://twitter.com/drupal8changes/status/aa64916739bb6230578176', 1],
83     ];
84   }
85
86   /**
87    * Tests TweetVisible constraint.
88    *
89    * @covers \Drupal\media_entity_twitter\Plugin\Validation\Constraint\TweetVisibleConstraintValidator
90    * @covers \Drupal\media_entity_twitter\Plugin\Validation\Constraint\TweetVisibleConstraint
91    *
92    * @dataProvider visibleProvider
93    */
94   public function testTweetVisibleConstraint($embed_code, $mocked_response, $violations) {
95     // Check message in constraint.
96     $constraint = new TweetVisibleConstraint();
97     $this->assertEquals('Referenced tweet is not publicly visible.', $constraint->message, 'Correct constraint message found.');
98
99     $http_client = $this->getMock('\GuzzleHttp\Client');
100     $http_client->expects($this->once())
101       ->method('__call')
102       ->with('get', [$embed_code, ['allow_redirects' => FALSE]])
103       ->willReturn($mocked_response);
104
105     // Make sure no violations are raised for visible tweet.
106     $execution_context = $this->getMockBuilder('\Drupal\Core\TypedData\Validation\ExecutionContext')
107       ->disableOriginalConstructor()
108       ->getMock();
109
110     if ($violations) {
111       $execution_context->expects($this->once())
112         ->method('addViolation')
113         ->with($constraint->message);
114     }
115     else {
116       $execution_context->expects($this->exactly($violations))
117         ->method('addViolation');
118     }
119
120     $validator = new TweetVisibleConstraintValidator($http_client);
121     $validator->initialize($execution_context);
122
123     $validator->validate($this->getMockFieldItem($embed_code), $constraint);
124   }
125
126   /**
127    * Provides test data for testTweetVisibleConstraint().
128    */
129   public function visibleProvider() {
130     $visible_response = $this->getMock('\GuzzleHttp\Psr7\Response');
131     $visible_response->expects($this->any())
132       ->method('getStatusCode')
133       ->will($this->returnValue(200));
134
135     $invisible_response = $this->getMock('\GuzzleHttp\Psr7\Response');
136     $invisible_response->expects($this->once())
137       ->method('getStatusCode')
138       ->will($this->returnValue(302));
139     $invisible_response->expects($this->once())
140       ->method('getHeader')
141       ->with('location')
142       ->will($this->returnValue(['https://twitter.com/drupal8changes?protected_redirect=true']));
143
144     return [
145       'valid URL' => [
146         'https://twitter.com/drupal8changes/status/649167396230578176',
147         $visible_response,
148         0,
149       ],
150       'invalid URL' => [
151         'https://twitter.com/drupal8changes/status/649637310024273920',
152         $invisible_response,
153         1,
154       ],
155     ];
156   }
157
158   /**
159    * Tests whether the TweetVisible constraint is robust against bad URLs.
160    *
161    * @covers \Drupal\media_entity_twitter\Plugin\Validation\Constraint\TweetVisibleConstraintValidator
162    * @covers \Drupal\media_entity_twitter\Plugin\Validation\Constraint\TweetVisibleConstraint
163    *
164    * @dataProvider badUrlsProvider
165    */
166   public function testBadUrlsOnVisibleConstraint($embed_code) {
167
168     $http_client = $this->getMock('\GuzzleHttp\Client');
169     $http_client->expects($this->never())->method('get');
170
171     $execution_context = $this->getMockBuilder('\Drupal\Core\TypedData\Validation\ExecutionContext')
172       ->disableOriginalConstructor()
173       ->getMock();
174
175     $validator = new TweetVisibleConstraintValidator($http_client);
176     $validator->initialize($execution_context);
177
178     $constraint = new TweetVisibleConstraint();
179     $validator->validate($this->getMockFieldItem($embed_code), $constraint);
180   }
181
182   /**
183    * Provides test data for testBadUrlsOnVisibleConstraint().
184    */
185   public function badUrlsProvider() {
186
187     return [
188       ['https://google.com'],
189       ['https://twitter.com/drupal/ssstatus/725771037837762561'],
190       ['https://twitter.com/drupal/status'],
191       ['https://twitter.com/drupal/status/foo'],
192     ];
193
194   }
195
196 }