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