Completed
Push — master ( 3e2cfb...e8c489 )
by Pieter
06:46
created

MessageContext::assertValidMessageTable()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.7
c 0
b 0
f 0
cc 3
nc 3
nop 2
1
<?php
2
3
namespace Drupal\DrupalExtension\Context;
4
5
use Behat\Behat\Context\TranslatableContext;
6
use Behat\Gherkin\Node\TableNode;
7
use Behat\Mink\Exception\ExpectationException;
8
9
/**
10
 * Provides step-definitions for interacting with Drupal messages.
11
 */
12
class MessageContext extends RawDrupalContext implements TranslatableContext
13
{
14
15
  /**
16
   * {@inheritDoc}
17
   */
18
    public static function getTranslationResources()
19
    {
20
        return glob(__DIR__ . '/../../../../i18n/*.xliff');
21
    }
22
23
  /**
24
   * Checks if the current page contains the given error message
25
   *
26
   * @param $message
27
   *   string The text to be checked
28
   *
29
   * @Then I should see the error message( containing) :message
30
   */
31
    public function assertErrorVisible($message)
32
    {
33
        $this->assert(
34
            $message,
35
            'error_message_selector',
36
            "The page '%s' does not contain any error messages",
37
            "The page '%s' does not contain the error message '%s'"
38
        );
39
    }
40
41
  /**
42
   * Checks if the current page contains the given set of error messages
43
   *
44
   * @param array $messages
45
   *   An array of texts to be checked. The first row should consist of the
46
   *   string "Error messages".
47
   *
48
   * @Then I should see the following error message(s):
49
   */
50 View Code Duplication
    public function assertMultipleErrors(TableNode $messages)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
51
    {
52
        $this->assertValidMessageTable($messages, 'error messages');
53
        foreach ($messages->getHash() as $key => $value) {
54
            $value = array_change_key_case($value);
55
            $message = trim($value['error messages']);
56
            $this->assertErrorVisible($message);
57
        }
58
    }
59
60
  /**
61
   * Checks if the current page does not contain the given error message
62
   *
63
   * @param $message
64
   *   string The text to be checked
65
   *
66
   * @Given I should not see the error message( containing) :message
67
   */
68
    public function assertNotErrorVisible($message)
69
    {
70
        $this->assertNot(
71
            $message,
72
            'error_message_selector',
73
            "The page '%s' contains the error message '%s'"
74
        );
75
    }
76
77
  /**
78
   * Checks if the current page does not contain the given set error messages
79
   *
80
   * @param array $messages
81
   *   An array of texts to be checked. The first row should consist of the
82
   *   string "Error messages".
83
   *
84
   * @Then I should not see the following error messages:
85
   */
86 View Code Duplication
    public function assertNotMultipleErrors(TableNode $messages)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
87
    {
88
        $this->assertValidMessageTable($messages, 'error messages');
89
        foreach ($messages->getHash() as $key => $value) {
90
            $value = array_change_key_case($value);
91
            $message = trim($value['error messages']);
92
            $this->assertNotErrorVisible($message);
93
        }
94
    }
95
96
  /**
97
   * Checks if the current page contains the given success message
98
   *
99
   * @param $message
100
   *   string The text to be checked
101
   *
102
   * @Then I should see the success message( containing) :message
103
   */
104
    public function assertSuccessMessage($message)
105
    {
106
        $this->assert(
107
            $message,
108
            'success_message_selector',
109
            "The page '%s' does not contain any success messages",
110
            "The page '%s' does not contain the success message '%s'"
111
        );
112
    }
113
114
  /**
115
   * Checks if the current page contains the given set of success messages
116
   *
117
   * @param array $message
0 ignored issues
show
Documentation introduced by
There is no parameter named $message. Did you maybe mean $messages?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
118
   *   An array of texts to be checked. The first row should consist of the
119
   *   string "Success messages".
120
   *
121
   * @Then I should see the following success messages:
122
   */
123 View Code Duplication
    public function assertMultipleSuccessMessage(TableNode $messages)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
124
    {
125
        $this->assertValidMessageTable($messages, 'success messages');
126
        foreach ($messages->getHash() as $key => $value) {
127
            $value = array_change_key_case($value);
128
            $message = trim($value['success messages']);
129
            $this->assertSuccessMessage($message);
130
        }
131
    }
132
133
  /**
134
   * Checks if the current page does not contain the given set of success message
135
   *
136
   * @param $message
137
   *   string The text to be checked
138
   *
139
   * @Given I should not see the success message( containing) :message
140
   */
141
    public function assertNotSuccessMessage($message)
142
    {
143
        $this->assertNot(
144
            $message,
145
            'success_message_selector',
146
            "The page '%s' contains the success message '%s'"
147
        );
148
    }
149
150
  /**
151
   * Checks if the current page does not contain the given set of success messages
152
   *
153
   * @param array $message
0 ignored issues
show
Documentation introduced by
There is no parameter named $message. Did you maybe mean $messages?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
154
   *   An array of texts to be checked. The first row should consist of the
155
   *   string "Success messages".
156
   *
157
   * @Then I should not see the following success messages:
158
   */
159 View Code Duplication
    public function assertNotMultipleSuccessMessage(TableNode $messages)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
160
    {
161
        $this->assertValidMessageTable($messages, 'success messages');
162
        foreach ($messages->getHash() as $key => $value) {
163
            $value = array_change_key_case($value);
164
            $message = trim($value['success messages']);
165
            $this->assertNotSuccessMessage($message);
166
        }
167
    }
168
169
  /**
170
   * Checks if the current page contains the given warning message
171
   *
172
   * @param $message
173
   *   string The text to be checked
174
   *
175
   * @Then I should see the warning message( containing) :message
176
   */
177
    public function assertWarningMessage($message)
178
    {
179
        $this->assert(
180
            $message,
181
            'warning_message_selector',
182
            "The page '%s' does not contain any warning messages",
183
            "The page '%s' does not contain the warning message '%s'"
184
        );
185
    }
186
187
  /**
188
   * Checks if the current page contains the given set of warning messages
189
   *
190
   * @param array $message
0 ignored issues
show
Documentation introduced by
There is no parameter named $message. Did you maybe mean $messages?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
191
   *   An array of texts to be checked. The first row should consist of the
192
   *   string "Warning messages".
193
   *
194
   * @Then I should see the following warning messages:
195
   */
196 View Code Duplication
    public function assertMultipleWarningMessage(TableNode $messages)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
197
    {
198
        $this->assertValidMessageTable($messages, 'warning messages');
199
        foreach ($messages->getHash() as $key => $value) {
200
            $value = array_change_key_case($value);
201
            $message = trim($value['warning messages']);
202
            $this->assertWarningMessage($message);
203
        }
204
    }
205
206
  /**
207
   * Checks if the current page does not contain the given set of warning message
208
   *
209
   * @param $message
210
   *   string The text to be checked
211
   *
212
   * @Given I should not see the warning message( containing) :message
213
   */
214
    public function assertNotWarningMessage($message)
215
    {
216
        $this->assertNot(
217
            $message,
218
            'warning_message_selector',
219
            "The page '%s' contains the warning message '%s'"
220
        );
221
    }
222
223
  /**
224
   * Checks if the current page does not contain the given set of warning messages
225
   *
226
   * @param array $message
0 ignored issues
show
Documentation introduced by
There is no parameter named $message. Did you maybe mean $messages?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
227
   *   An array of texts to be checked. The first row should consist of the
228
   *   string "Warning messages".
229
   *
230
   * @Then I should not see the following warning messages:
231
   */
232 View Code Duplication
    public function assertNotMultipleWarningMessage(TableNode $messages)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
233
    {
234
        $this->assertValidMessageTable($messages, 'warning messages');
235
        foreach ($messages->getHash() as $key => $value) {
236
            $value = array_change_key_case($value);
237
            $message = trim($value['warning messages']);
238
            $this->assertNotWarningMessage($message);
239
        }
240
    }
241
242
  /**
243
   * Checks if the current page contain the given message
244
   *
245
   * @param $message
246
   *   string The message to be checked
247
   *
248
   * @Then I should see the message( containing) :message
249
   */
250
    public function assertMessage($message)
251
    {
252
        $this->assert(
253
            $message,
254
            'message_selector',
255
            "The page '%s' does not contain any messages",
256
            "The page '%s' does not contain the message '%s'"
257
        );
258
    }
259
260
  /**
261
   * Checks if the current page does not contain the given message
262
   *
263
   * @param $message
264
   *   string The message to be checked
265
   *
266
   * @Then I should not see the message( containing) :message
267
   */
268
    public function assertNotMessage($message)
269
    {
270
        $this->assertNot(
271
            $message,
272
            'message_selector',
273
            "The page '%s' contains the message '%s'"
274
        );
275
    }
276
277
    /**
278
     * Checks whether the given list of messages is valid.
279
     *
280
     * This checks whether the list has only one column and has the correct
281
     * header.
282
     *
283
     * @param \Behat\Gherkin\Node\TableNode $messages
284
     *   The list of messages.
285
     * @param string $expected_header
286
     *   The header that should be present in the list.
287
     */
288
    protected function assertValidMessageTable(TableNode $messages, $expected_header)
289
    {
290
        // Check that the table only contains a single column.
291
        $header_row = $messages->getRow(0);
292
293
        $column_count = count($header_row);
294
        if ($column_count != 1) {
295
            throw new \RuntimeException("The list of $expected_header should only contain 1 column. It has $column_count columns.");
296
        }
297
298
        // Check that the correct header is used.
299
        $actual_header = reset($header_row);
300
        if (strtolower(trim($actual_header)) !== $expected_header) {
301
            $capitalized_header = ucfirst($expected_header);
302
            throw new \RuntimeException("The list of $expected_header should have the header '$capitalized_header'.");
303
        }
304
    }
305
306
  /**
307
   * Internal callback to check for a specific message in a given context.
308
   *
309
   * @param $message
310
   *   string The message to be checked
311
   * @param $selectorId
312
   *   string CSS selector name
313
   * @param $exceptionMsgNone
314
   *   string The message being thrown when no message is contained, string
315
   *   should contain one '%s' as a placeholder for the current URL
316
   * @param $exceptionMsgMissing
317
   *   string The message being thrown when the message is not contained, string
318
   *   should contain two '%s' as placeholders for the current URL and the message.
319
   *
320
   * @throws \Behat\Mink\Exception\ExpectationException
321
   *   Thrown when the expected message is not present in the page.
322
   */
323
    private function assert($message, $selectorId, $exceptionMsgNone, $exceptionMsgMissing)
324
    {
325
        $selector = $this->getDrupalSelector($selectorId);
326
        $selectorObjects = $this->getSession()->getPage()->findAll("css", $selector);
327
        if (empty($selectorObjects)) {
328
            throw new ExpectationException(sprintf($exceptionMsgNone, $this->getSession()->getCurrentUrl()), $this->getSession()->getDriver());
329
        }
330
        foreach ($selectorObjects as $selectorObject) {
331
            if (strpos(trim($selectorObject->getText()), $message) !== false) {
332
                return;
333
            }
334
        }
335
        throw new ExpectationException(sprintf($exceptionMsgMissing, $this->getSession()->getCurrentUrl(), $message), $this->getSession()->getDriver());
336
    }
337
338
  /**
339
   * Internal callback to check if the current page does not contain the given message
340
   *
341
   * @param $message
342
   *   string The message to be checked
343
   * @param $selectorId
344
   *   string CSS selector name
345
   * @param $exceptionMsg
346
   *   string The message being thrown when the message is contained, string
347
   *   should contain two '%s' as placeholders for the current URL and the message.
348
   *
349
   * @throws \Behat\Mink\Exception\ExpectationException
350
   *   Thrown when the expected message is present in the page.
351
   */
352
    private function assertNot($message, $selectorId, $exceptionMsg)
353
    {
354
        $selector = $this->getDrupalSelector($selectorId);
355
        $selectorObjects = $this->getSession()->getPage()->findAll("css", $selector);
356
        if (!empty($selectorObjects)) {
357
            foreach ($selectorObjects as $selectorObject) {
358
                if (strpos(trim($selectorObject->getText()), $message) !== false) {
359
                    throw new ExpectationException(sprintf($exceptionMsg, $this->getSession()->getCurrentUrl(), $message), $this->getSession()->getDriver());
360
                }
361
            }
362
        }
363
    }
364
}
365