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