Security update for permissions_by_term
[yaffs-website] / vendor / behat / mink-extension / src / Behat / MinkExtension / Listener / SessionsListener.php
1 <?php
2
3 /*
4  * This file is part of the Behat MinkExtension.
5  * (c) Konstantin Kudryashov <ever.zet@gmail.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 namespace Behat\MinkExtension\Listener;
12
13 use Behat\Behat\EventDispatcher\Event\ExampleTested;
14 use Behat\Behat\EventDispatcher\Event\ScenarioLikeTested;
15 use Behat\Behat\EventDispatcher\Event\ScenarioTested;
16 use Behat\Mink\Mink;
17 use Behat\Testwork\EventDispatcher\Event\ExerciseCompleted;
18 use Behat\Testwork\ServiceContainer\Exception\ProcessingException;
19 use Behat\Testwork\Suite\Exception\SuiteConfigurationException;
20 use Behat\Testwork\Suite\Suite;
21 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
22
23 /**
24  * Mink sessions listener.
25  * Listens Behat events and configures/stops Mink sessions.
26  *
27  * @author Konstantin Kudryashov <ever.zet@gmail.com>
28  */
29 class SessionsListener implements EventSubscriberInterface
30 {
31     private $mink;
32     private $defaultSession;
33     private $javascriptSession;
34
35     /**
36      * @var string[] The available javascript sessions
37      */
38     private $availableJavascriptSessions;
39
40     /**
41      * Initializes initializer.
42      *
43      * @param Mink        $mink
44      * @param string      $defaultSession
45      * @param string|null $javascriptSession
46      * @param string[]    $availableJavascriptSessions
47      */
48     public function __construct(Mink $mink, $defaultSession, $javascriptSession, array $availableJavascriptSessions = array())
49     {
50         $this->mink              = $mink;
51         $this->defaultSession    = $defaultSession;
52         $this->javascriptSession = $javascriptSession;
53         $this->availableJavascriptSessions = $availableJavascriptSessions;
54     }
55
56     /**
57      * {@inheritdoc}
58      */
59     public static function getSubscribedEvents()
60     {
61         return array(
62             ScenarioTested::BEFORE   => array('prepareDefaultMinkSession', 10),
63             ExampleTested::BEFORE    => array('prepareDefaultMinkSession', 10),
64             ExerciseCompleted::AFTER => array('tearDownMinkSessions', -10)
65         );
66     }
67
68     /**
69      * Configures default Mink session before each scenario.
70      * Configuration is based on provided scenario tags:
71      *
72      * `@javascript` tagged scenarios will get `javascript_session` as default session
73      * `@mink:CUSTOM_NAME tagged scenarios will get `CUSTOM_NAME` as default session
74      * Other scenarios get `default_session` as default session
75      *
76      * `@insulated` tag will cause Mink to stop current sessions before scenario
77      * instead of just soft-resetting them
78      *
79      * @param ScenarioLikeTested $event
80      *
81      * @throws ProcessingException when the @javascript tag is used without a javascript session
82      */
83     public function prepareDefaultMinkSession(ScenarioLikeTested $event)
84     {
85         $scenario = $event->getScenario();
86         $feature  = $event->getFeature();
87         $session  = null;
88
89         foreach (array_merge($feature->getTags(), $scenario->getTags()) as $tag) {
90             if ('javascript' === $tag) {
91                 $session = $this->getJavascriptSession($event->getSuite());
92             } elseif (preg_match('/^mink\:(.+)/', $tag, $matches)) {
93                 $session = $matches[1];
94             }
95         }
96
97         if (null === $session) {
98             $session = $this->getDefaultSession($event->getSuite());
99         }
100
101         if ($scenario->hasTag('insulated') || $feature->hasTag('insulated')) {
102             $this->mink->stopSessions();
103         } else {
104             $this->mink->resetSessions();
105         }
106
107         $this->mink->setDefaultSessionName($session);
108     }
109
110     /**
111      * Stops all started Mink sessions.
112      */
113     public function tearDownMinkSessions()
114     {
115         $this->mink->stopSessions();
116     }
117
118     private function getDefaultSession(Suite $suite)
119     {
120         if (!$suite->hasSetting('mink_session')) {
121             return $this->defaultSession;
122         }
123
124         $session = $suite->getSetting('mink_session');
125
126         if (!is_string($session)) {
127             throw new SuiteConfigurationException(
128                 sprintf(
129                     '`mink_session` setting of the "%s" suite is expected to be a string, %s given.',
130                     $suite->getName(),
131                     gettype($session)
132                 ),
133                 $suite->getName()
134             );
135         }
136
137         return $session;
138     }
139
140     private function getJavascriptSession(Suite $suite)
141     {
142         if (!$suite->hasSetting('mink_javascript_session')) {
143             if (null === $this->javascriptSession) {
144                 throw new ProcessingException('The @javascript tag cannot be used without enabling a javascript session');
145             }
146
147             return $this->javascriptSession;
148         }
149
150         $session = $suite->getSetting('mink_javascript_session');
151
152         if (!is_string($session)) {
153             throw new SuiteConfigurationException(
154                 sprintf(
155                     '`mink_javascript_session` setting of the "%s" suite is expected to be a string, %s given.',
156                     $suite->getName(),
157                     gettype($session)
158                 ),
159                 $suite->getName()
160             );
161         }
162
163         if (!in_array($session, $this->availableJavascriptSessions)) {
164             throw new SuiteConfigurationException(
165                 sprintf(
166                     '`mink_javascript_session` setting of the "%s" suite is not a javascript session. %s given but expected one of %s.',
167                     $suite->getName(),
168                     $session,
169                     implode(', ', $this->availableJavascriptSessions)
170                 ),
171                 $suite->getName()
172             );
173         }
174
175         return $session;
176     }
177 }