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