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