]> BookStack Code Mirror - bookstack/blob - tests/TestCase.php
Added auto-suggestions to tag names and values
[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         if($this->admin === null) {
43             $adminRole = \BookStack\Role::getRole('admin');
44             $this->admin = $adminRole->users->first();
45         }
46         return $this->actingAs($this->admin);
47     }
48
49     /**
50      * Set the current editor context to be an editor.
51      * @return $this
52      */
53     public function asEditor()
54     {
55         if($this->editor === null) {
56             $this->editor = $this->getEditor();
57         }
58         return $this->actingAs($this->editor);
59     }
60
61     /**
62      * Quickly sets an array of settings.
63      * @param $settingsArray
64      */
65     protected function setSettings($settingsArray)
66     {
67         $settings = app('BookStack\Services\SettingService');
68         foreach ($settingsArray as $key => $value) {
69             $settings->put($key, $value);
70         }
71     }
72
73     /**
74      * Create a group of entities that belong to a specific user.
75      * @param $creatorUser
76      * @param $updaterUser
77      * @return array
78      */
79     protected function createEntityChainBelongingToUser($creatorUser, $updaterUser = false)
80     {
81         if ($updaterUser === false) $updaterUser = $creatorUser;
82         $book = factory(BookStack\Book::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id]);
83         $chapter = factory(BookStack\Chapter::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id]);
84         $page = factory(BookStack\Page::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id, 'book_id' => $book->id]);
85         $book->chapters()->saveMany([$chapter]);
86         $chapter->pages()->saveMany([$page]);
87         $restrictionService = $this->app[\BookStack\Services\PermissionService::class];
88         $restrictionService->buildJointPermissionsForEntity($book);
89         return [
90             'book' => $book,
91             'chapter' => $chapter,
92             'page' => $page
93         ];
94     }
95
96     /**
97      * Quick way to create a new user
98      * @param array $attributes
99      * @return mixed
100      */
101     protected function getEditor($attributes = [])
102     {
103         $user = factory(\BookStack\User::class)->create($attributes);
104         $role = \BookStack\Role::getRole('editor');
105         $user->attachRole($role);;
106         return $user;
107     }
108
109     /**
110      * Quick way to create a new user without any permissions
111      * @param array $attributes
112      * @return mixed
113      */
114     protected function getNewBlankUser($attributes = [])
115     {
116         $user = factory(\BookStack\User::class)->create($attributes);
117         return $user;
118     }
119
120     /**
121      * Assert that a given string is seen inside an element.
122      *
123      * @param  bool|string|null $element
124      * @param  integer          $position
125      * @param  string           $text
126      * @param  bool             $negate
127      * @return $this
128      */
129     protected function seeInNthElement($element, $position, $text, $negate = false)
130     {
131         $method = $negate ? 'assertNotRegExp' : 'assertRegExp';
132
133         $rawPattern = preg_quote($text, '/');
134
135         $escapedPattern = preg_quote(e($text), '/');
136
137         $content = $this->crawler->filter($element)->eq($position)->html();
138
139         $pattern = $rawPattern == $escapedPattern
140             ? $rawPattern : "({$rawPattern}|{$escapedPattern})";
141
142         $this->$method("/$pattern/i", $content);
143
144         return $this;
145     }
146
147     /**
148      * Assert that the current page matches a given URI.
149      *
150      * @param  string  $uri
151      * @return $this
152      */
153     protected function seePageUrlIs($uri)
154     {
155         $this->assertEquals(
156             $uri, $this->currentUri, "Did not land on expected page [{$uri}].\n"
157         );
158
159         return $this;
160     }
161
162     /**
163      * Do a forced visit that does not error out on exception.
164      * @param string $uri
165      * @param array $parameters
166      * @param array $cookies
167      * @param array $files
168      * @return $this
169      */
170     protected function forceVisit($uri, $parameters = [], $cookies = [], $files = [])
171     {
172         $method = 'GET';
173         $uri = $this->prepareUrlForRequest($uri);
174         $this->call($method, $uri, $parameters, $cookies, $files);
175         $this->clearInputs()->followRedirects();
176         $this->currentUri = $this->app->make('request')->fullUrl();
177         $this->crawler = new Crawler($this->response->getContent(), $uri);
178         return $this;
179     }
180
181     /**
182      * Click the text within the selected element.
183      * @param $parentElement
184      * @param $linkText
185      * @return $this
186      */
187     protected function clickInElement($parentElement, $linkText)
188     {
189         $elem = $this->crawler->filter($parentElement);
190         $link = $elem->selectLink($linkText);
191         $this->visit($link->link()->getUri());
192         return $this;
193     }
194
195     /**
196      * Check if the page contains the given element.
197      * @param  string  $selector
198      * @return bool
199      */
200     protected function pageHasElement($selector)
201     {
202         $elements = $this->crawler->filter($selector);
203         $this->assertTrue(count($elements) > 0, "The page does not contain an element matching " . $selector);
204         return $this;
205     }
206
207     /**
208      * Check if the page contains the given element.
209      * @param  string  $selector
210      * @return bool
211      */
212     protected function pageNotHasElement($selector)
213     {
214         $elements = $this->crawler->filter($selector);
215         $this->assertFalse(count($elements) > 0, "The page contains " . count($elements) . " elements matching " . $selector);
216         return $this;
217     }
218 }