]> BookStack Code Mirror - bookstack/blob - tests/BrowserKitTest.php
Fixed role permission removal bug
[bookstack] / tests / BrowserKitTest.php
1 <?php namespace Tests;
2
3 use BookStack\Role;
4 use BookStack\Services\PermissionService;
5 use Illuminate\Contracts\Console\Kernel;
6 use Illuminate\Foundation\Testing\DatabaseTransactions;
7 use Laravel\BrowserKitTesting\TestCase;
8 use Symfony\Component\DomCrawler\Crawler;
9
10 abstract class BrowserKitTest extends TestCase
11 {
12
13     use DatabaseTransactions;
14
15     /**
16      * The base URL to use while testing the application.
17      *
18      * @var string
19      */
20     protected $baseUrl = 'http://localhost';
21
22     // Local user instances
23     private $admin;
24     private $editor;
25
26     public function tearDown()
27     {
28         \DB::disconnect();
29         parent::tearDown();
30     }
31
32     /**
33      * Creates the application.
34      *
35      * @return \Illuminate\Foundation\Application
36      */
37     public function createApplication()
38     {
39         $app = require __DIR__.'/../bootstrap/app.php';
40
41         $app->make(Kernel::class)->bootstrap();
42
43         return $app;
44     }
45
46     /**
47      * Set the current user context to be an admin.
48      * @return $this
49      */
50     public function asAdmin()
51     {
52         return $this->actingAs($this->getAdmin());
53     }
54
55     /**
56      * Get the current admin user.
57      * @return mixed
58      */
59     public function getAdmin() {
60         if($this->admin === null) {
61             $adminRole = Role::getSystemRole('admin');
62             $this->admin = $adminRole->users->first();
63         }
64         return $this->admin;
65     }
66
67     /**
68      * Set the current editor context to be an editor.
69      * @return $this
70      */
71     public function asEditor()
72     {
73         if ($this->editor === null) {
74             $this->editor = $this->getEditor();
75         }
76         return $this->actingAs($this->editor);
77     }
78
79     /**
80      * Get a user that's not a system user such as the guest user.
81      */
82     public function getNormalUser()
83     {
84         return \BookStack\User::where('system_name', '=', null)->get()->last();
85     }
86
87     /**
88      * Quickly sets an array of settings.
89      * @param $settingsArray
90      */
91     protected function setSettings($settingsArray)
92     {
93         $settings = app('BookStack\Services\SettingService');
94         foreach ($settingsArray as $key => $value) {
95             $settings->put($key, $value);
96         }
97     }
98
99     /**
100      * Create a group of entities that belong to a specific user.
101      * @param $creatorUser
102      * @param $updaterUser
103      * @return array
104      */
105     protected function createEntityChainBelongingToUser($creatorUser, $updaterUser = false)
106     {
107         if ($updaterUser === false) $updaterUser = $creatorUser;
108         $book = factory(\BookStack\Book::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id]);
109         $chapter = factory(\BookStack\Chapter::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id, 'book_id' => $book->id]);
110         $page = factory(\BookStack\Page::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id, 'book_id' => $book->id, 'chapter_id' => $chapter->id]);
111         $restrictionService = $this->app[PermissionService::class];
112         $restrictionService->buildJointPermissionsForEntity($book);
113         return [
114             'book' => $book,
115             'chapter' => $chapter,
116             'page' => $page
117         ];
118     }
119
120     /**
121      * Quick way to create a new user
122      * @param array $attributes
123      * @return mixed
124      */
125     protected function getEditor($attributes = [])
126     {
127         $user = factory(\BookStack\User::class)->create($attributes);
128         $role = Role::getRole('editor');
129         $user->attachRole($role);;
130         return $user;
131     }
132
133     /**
134      * Quick way to create a new user without any permissions
135      * @param array $attributes
136      * @return mixed
137      */
138     protected function getNewBlankUser($attributes = [])
139     {
140         $user = factory(\BookStack\User::class)->create($attributes);
141         return $user;
142     }
143
144     /**
145      * Assert that a given string is seen inside an element.
146      *
147      * @param  bool|string|null $element
148      * @param  integer          $position
149      * @param  string           $text
150      * @param  bool             $negate
151      * @return $this
152      */
153     protected function seeInNthElement($element, $position, $text, $negate = false)
154     {
155         $method = $negate ? 'assertNotRegExp' : 'assertRegExp';
156
157         $rawPattern = preg_quote($text, '/');
158
159         $escapedPattern = preg_quote(e($text), '/');
160
161         $content = $this->crawler->filter($element)->eq($position)->html();
162
163         $pattern = $rawPattern == $escapedPattern
164             ? $rawPattern : "({$rawPattern}|{$escapedPattern})";
165
166         $this->$method("/$pattern/i", $content);
167
168         return $this;
169     }
170
171     /**
172      * Assert that the current page matches a given URI.
173      *
174      * @param  string  $uri
175      * @return $this
176      */
177     protected function seePageUrlIs($uri)
178     {
179         $this->assertEquals(
180             $uri, $this->currentUri, "Did not land on expected page [{$uri}].\n"
181         );
182
183         return $this;
184     }
185
186     /**
187      * Do a forced visit that does not error out on exception.
188      * @param string $uri
189      * @param array $parameters
190      * @param array $cookies
191      * @param array $files
192      * @return $this
193      */
194     protected function forceVisit($uri, $parameters = [], $cookies = [], $files = [])
195     {
196         $method = 'GET';
197         $uri = $this->prepareUrlForRequest($uri);
198         $this->call($method, $uri, $parameters, $cookies, $files);
199         $this->clearInputs()->followRedirects();
200         $this->currentUri = $this->app->make('request')->fullUrl();
201         $this->crawler = new Crawler($this->response->getContent(), $uri);
202         return $this;
203     }
204
205     /**
206      * Click the text within the selected element.
207      * @param $parentElement
208      * @param $linkText
209      * @return $this
210      */
211     protected function clickInElement($parentElement, $linkText)
212     {
213         $elem = $this->crawler->filter($parentElement);
214         $link = $elem->selectLink($linkText);
215         $this->visit($link->link()->getUri());
216         return $this;
217     }
218
219     /**
220      * Check if the page contains the given element.
221      * @param  string  $selector
222      */
223     protected function pageHasElement($selector)
224     {
225         $elements = $this->crawler->filter($selector);
226         $this->assertTrue(count($elements) > 0, "The page does not contain an element matching " . $selector);
227         return $this;
228     }
229
230     /**
231      * Check if the page contains the given element.
232      * @param  string  $selector
233      */
234     protected function pageNotHasElement($selector)
235     {
236         $elements = $this->crawler->filter($selector);
237         $this->assertFalse(count($elements) > 0, "The page contains " . count($elements) . " elements matching " . $selector);
238         return $this;
239     }
240 }