3 namespace Tests\Entity;
5 use BookStack\Entities\Models\SlugHistory;
8 class SlugTest extends TestCase
10 public function test_slug_multi_byte_url_safe()
12 $book = $this->entities->newBook([
13 'name' => 'информация',
16 $this->assertEquals('informaciia', $book->slug);
18 $book = $this->entities->newBook([
22 $this->assertEquals('que', $book->slug);
25 public function test_slug_format()
27 $book = $this->entities->newBook([
28 'name' => 'PartA / PartB / PartC',
31 $this->assertEquals('parta-partb-partc', $book->slug);
34 public function test_old_page_slugs_redirect_to_new_pages()
36 $page = $this->entities->page();
37 $pageUrl = $page->getUrl();
39 $this->asAdmin()->put($pageUrl, [
40 'name' => 'super test page',
45 ->assertRedirect("/books/{$page->book->slug}/page/super-test-page");
48 public function test_old_shelf_slugs_redirect_to_new_shelf()
50 $shelf = $this->entities->shelf();
51 $shelfUrl = $shelf->getUrl();
53 $this->asAdmin()->put($shelf->getUrl(), [
54 'name' => 'super test shelf',
58 ->assertRedirect("/shelves/super-test-shelf");
61 public function test_old_book_slugs_redirect_to_new_book()
63 $book = $this->entities->book();
64 $bookUrl = $book->getUrl();
66 $this->asAdmin()->put($book->getUrl(), [
67 'name' => 'super test book',
71 ->assertRedirect("/books/super-test-book");
74 public function test_old_chapter_slugs_redirect_to_new_chapter()
76 $chapter = $this->entities->chapter();
77 $chapterUrl = $chapter->getUrl();
79 $this->asAdmin()->put($chapter->getUrl(), [
80 'name' => 'super test chapter',
83 $this->get($chapterUrl)
84 ->assertRedirect("/books/{$chapter->book->slug}/chapter/super-test-chapter");
87 public function test_old_book_slugs_in_page_urls_redirect_to_current_page_url()
89 $page = $this->entities->page();
91 $pageUrl = $page->getUrl();
93 $this->asAdmin()->put($book->getUrl(), [
94 'name' => 'super test book',
98 ->assertRedirect("/books/super-test-book/page/{$page->slug}");
101 public function test_old_book_slugs_in_chapter_urls_redirect_to_current_chapter_url()
103 $chapter = $this->entities->chapter();
104 $book = $chapter->book;
105 $chapterUrl = $chapter->getUrl();
107 $this->asAdmin()->put($book->getUrl(), [
108 'name' => 'super test book',
111 $this->get($chapterUrl)
112 ->assertRedirect("/books/super-test-book/chapter/{$chapter->slug}");
115 public function test_slug_lookup_controlled_by_permissions()
117 $editor = $this->users->editor();
118 $pageA = $this->entities->page();
119 $pageB = $this->entities->page();
121 SlugHistory::factory()->create(['sluggable_id' => $pageA->id, 'sluggable_type' => 'page', 'slug' => 'monkey', 'parent_slug' => 'animals', 'created_at' => now()]);
122 SlugHistory::factory()->create(['sluggable_id' => $pageB->id, 'sluggable_type' => 'page', 'slug' => 'monkey', 'parent_slug' => 'animals', 'created_at' => now()->subDay()]);
124 // Defaults to latest where visible
125 $this->actingAs($editor)->get("/books/animals/page/monkey")->assertRedirect($pageA->getUrl());
127 $this->permissions->disableEntityInheritedPermissions($pageA);
129 // Falls back to other entry where the latest is not visible
130 $this->actingAs($editor)->get("/books/animals/page/monkey")->assertRedirect($pageB->getUrl());
132 // Original still accessible where permissions allow
133 $this->asAdmin()->get("/books/animals/page/monkey")->assertRedirect($pageA->getUrl());
136 public function test_slugs_recorded_in_history_on_page_update()
138 $page = $this->entities->page();
139 $this->asAdmin()->put($page->getUrl(), [
140 'name' => 'new slug',
144 $oldSlug = $page->slug;
146 $this->assertNotEquals($oldSlug, $page->slug);
148 $this->assertDatabaseHas('slug_history', [
149 'sluggable_id' => $page->id,
150 'sluggable_type' => 'page',
152 'parent_slug' => $page->book->slug,
156 public function test_slugs_recorded_in_history_on_chapter_update()
158 $chapter = $this->entities->chapter();
159 $this->asAdmin()->put($chapter->getUrl(), [
160 'name' => 'new slug',
163 $oldSlug = $chapter->slug;
165 $this->assertNotEquals($oldSlug, $chapter->slug);
167 $this->assertDatabaseHas('slug_history', [
168 'sluggable_id' => $chapter->id,
169 'sluggable_type' => 'chapter',
171 'parent_slug' => $chapter->book->slug,
175 public function test_slugs_recorded_in_history_on_book_update()
177 $book = $this->entities->book();
178 $this->asAdmin()->put($book->getUrl(), [
179 'name' => 'new slug',
182 $oldSlug = $book->slug;
184 $this->assertNotEquals($oldSlug, $book->slug);
186 $this->assertDatabaseHas('slug_history', [
187 'sluggable_id' => $book->id,
188 'sluggable_type' => 'book',
190 'parent_slug' => null,
194 public function test_slugs_recorded_in_history_on_shelf_update()
196 $shelf = $this->entities->shelf();
197 $this->asAdmin()->put($shelf->getUrl(), [
198 'name' => 'new slug',
201 $oldSlug = $shelf->slug;
203 $this->assertNotEquals($oldSlug, $shelf->slug);
205 $this->assertDatabaseHas('slug_history', [
206 'sluggable_id' => $shelf->id,
207 'sluggable_type' => 'bookshelf',
209 'parent_slug' => null,