]> BookStack Code Mirror - bookstack/commitdiff
Added further tests, Fixed speed_update issues, improved search result query count
authorDan Brown <redacted>
Sun, 29 Nov 2015 17:33:25 +0000 (17:33 +0000)
committerDan Brown <redacted>
Sun, 29 Nov 2015 17:33:25 +0000 (17:33 +0000)
12 files changed:
app/Chapter.php
app/Entity.php
app/Http/Controllers/BookController.php
app/Http/Controllers/ChapterController.php
app/Repos/BookRepo.php
database/factories/ModelFactory.php
database/migrations/2015_11_26_221857_add_entity_indexes.php
readme.md
resources/views/base.blade.php
resources/views/books/sort-box.blade.php
resources/views/books/sort.blade.php
tests/EntityTest.php

index c3001b69bd43778c2228f907901f5d3d8823b304..b6c8684a00069de44dc1341d77da27cc45410cd4 100644 (file)
@@ -3,7 +3,6 @@
 
 class Chapter extends Entity
 {
-
     protected $fillable = ['name', 'description', 'priority', 'book_id'];
 
     public function book()
@@ -18,7 +17,7 @@ class Chapter extends Entity
 
     public function getUrl()
     {
-        $bookSlug = isset($this->bookSlug) ? $this->bookSlug : $this->book->slug;
+        $bookSlug = $this->getAttribute('bookSlug') ? $this->getAttribute('bookSlug') : $this->book->slug;
         return '/books/' . $bookSlug. '/chapter/' . $this->slug;
     }
 
index 1a8b02a4b1e7aee5e67706d843b74ce9e7b9d640..68c77359200491da9896319f683149438ec2664a 100644 (file)
@@ -69,19 +69,18 @@ abstract class Entity extends Model
      * @param $type
      * @return bool
      */
-    public function isA($type)
+    public static function isA($type)
     {
-        return $this->getName() === strtolower($type);
+        return static::getName() === strtolower($type);
     }
 
     /**
      * Gets the class name.
      * @return string
      */
-    public function getName()
+    public static function getName()
     {
-        $fullClassName = get_class($this);
-        return strtolower(array_slice(explode('\\', $fullClassName), -1, 1)[0]);
+        return strtolower(array_slice(explode('\\', static::class), -1, 1)[0]);
     }
 
     /**
@@ -102,6 +101,15 @@ abstract class Entity extends Model
         foreach ($wheres as $whereTerm) {
             $search->where($whereTerm[0], $whereTerm[1], $whereTerm[2]);
         }
+
+        if (!static::isA('book')) {
+            $search = $search->with('book');
+        }
+
+        if(static::isA('page')) {
+            $search = $search->with('chapter');
+        }
+
         return $search->get();
     }
 
index c4173730dde2db26f74b29ef74e961a8addf462d..6b2d6928dc9d01d2a732d035fa3f7326d066da24 100644 (file)
@@ -150,14 +150,16 @@ class BookController extends Controller
     {
         $this->checkPermission('book-update');
         $book = $this->bookRepo->getBySlug($bookSlug);
+        $bookChildren = $this->bookRepo->getChildren($book);
         $books = $this->bookRepo->getAll();
-        return view('books/sort', ['book' => $book, 'current' => $book, 'books' => $books]);
+        return view('books/sort', ['book' => $book, 'current' => $book, 'books' => $books, 'bookChildren' => $bookChildren]);
     }
 
     public function getSortItem($bookSlug)
     {
         $book = $this->bookRepo->getBySlug($bookSlug);
-        return view('books/sort-box', ['book' => $book]);
+        $bookChildren = $this->bookRepo->getChildren($book);
+        return view('books/sort-box', ['book' => $book, 'bookChildren' => $bookChildren]);
     }
 
     /**
index 42ae113559260b8fdc29325afb2e016b9cee4077..1fe1e8b3ef3c63a1c4a952b31965362c5447e826 100644 (file)
@@ -33,7 +33,6 @@ class ChapterController extends Controller
 
     /**
      * Show the form for creating a new chapter.
-     *
      * @param $bookSlug
      * @return Response
      */
@@ -46,7 +45,6 @@ class ChapterController extends Controller
 
     /**
      * Store a newly created chapter in storage.
-     *
      * @param          $bookSlug
      * @param  Request $request
      * @return Response
@@ -62,8 +60,8 @@ class ChapterController extends Controller
         $chapter = $this->chapterRepo->newFromInput($request->all());
         $chapter->slug = $this->chapterRepo->findSuitableSlug($chapter->name, $book->id);
         $chapter->priority = $this->bookRepo->getNewPriority($book);
-        $chapter->created_by = Auth::user()->id;
-        $chapter->updated_by = Auth::user()->id;
+        $chapter->created_by = auth()->user()->id;
+        $chapter->updated_by = auth()->user()->id;
         $book->chapters()->save($chapter);
         Activity::add($chapter, 'chapter_create', $book->id);
         return redirect($chapter->getUrl());
@@ -71,7 +69,6 @@ class ChapterController extends Controller
 
     /**
      * Display the specified chapter.
-     *
      * @param $bookSlug
      * @param $chapterSlug
      * @return Response
@@ -87,7 +84,6 @@ class ChapterController extends Controller
 
     /**
      * Show the form for editing the specified chapter.
-     *
      * @param $bookSlug
      * @param $chapterSlug
      * @return Response
@@ -102,7 +98,6 @@ class ChapterController extends Controller
 
     /**
      * Update the specified chapter in storage.
-     *
      * @param  Request $request
      * @param          $bookSlug
      * @param          $chapterSlug
@@ -115,7 +110,7 @@ class ChapterController extends Controller
         $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id);
         $chapter->fill($request->all());
         $chapter->slug = $this->chapterRepo->findSuitableSlug($chapter->name, $book->id, $chapter->id);
-        $chapter->updated_by = Auth::user()->id;
+        $chapter->updated_by = auth()->user()->id;
         $chapter->save();
         Activity::add($chapter, 'chapter_update', $book->id);
         return redirect($chapter->getUrl());
@@ -137,7 +132,6 @@ class ChapterController extends Controller
 
     /**
      * Remove the specified chapter from storage.
-     *
      * @param $bookSlug
      * @param $chapterSlug
      * @return Response
index 112971a27fbf468aeea744be26d039bd70508198..9be77defe0cd7a6bac169a0061a85f596081edd7 100644 (file)
@@ -141,7 +141,7 @@ class BookRepo
      */
     public function getNewPriority($book)
     {
-        $lastElem = $book->children()->pop();
+        $lastElem = $this->getChildren($book)->pop();
         return $lastElem ? $lastElem->priority + 1 : 0;
     }
 
index 31c7a3716689428b4495e930ef210f13190b12cf..e0f1550875c27a6e0ec0710a3493f23ca1e097f6 100644 (file)
 
 $factory->define(BookStack\User::class, function ($faker) {
     return [
-        'name'           => $faker->name,
-        'email'          => $faker->email,
-        'password'       => str_random(10),
+        'name' => $faker->name,
+        'email' => $faker->email,
+        'password' => str_random(10),
         'remember_token' => str_random(10),
     ];
 });
 
 $factory->define(BookStack\Book::class, function ($faker) {
     return [
-        'name'        => $faker->sentence,
-        'slug'        => str_random(10),
+        'name' => $faker->sentence,
+        'slug' => str_random(10),
         'description' => $faker->paragraph
     ];
 });
 
 $factory->define(BookStack\Chapter::class, function ($faker) {
     return [
-        'name'        => $faker->sentence,
-        'slug'        => str_random(10),
+        'name' => $faker->sentence,
+        'slug' => str_random(10),
         'description' => $faker->paragraph
     ];
 });
 
 $factory->define(BookStack\Page::class, function ($faker) {
+    $html = '<p>' . implode('</p>', $faker->paragraphs(5)) . '</p>';
     return [
         'name' => $faker->sentence,
-        'slug'        => str_random(10),
-        'html' => '<p>' . implode('</p>', $faker->paragraphs(5)) . '</p>'
+        'slug' => str_random(10),
+        'html' => $html,
+        'text' => strip_tags($html)
     ];
 });
index 4e68dd68eda1b64086bf8dfa9c656c2b3f0244da..30f978cad5bc8fe93e7f2ffbdfef2aa1bb35bade 100644 (file)
@@ -54,36 +54,36 @@ class AddEntityIndexes extends Migration
     public function down()
     {
         Schema::table('books', function (Blueprint $table) {
-            $table->dropIndex('slug');
-            $table->dropIndex('created_by');
-            $table->dropIndex('updated_by');
+            $table->dropIndex('books_slug_index');
+            $table->dropIndex('books_created_by_index');
+            $table->dropIndex('books_updated_by_index');
         });
         Schema::table('pages', function (Blueprint $table) {
-            $table->dropIndex('slug');
-            $table->dropIndex('book_id');
-            $table->dropIndex('chapter_id');
-            $table->dropIndex('priority');
-            $table->dropIndex('created_by');
-            $table->dropIndex('updated_by');
+            $table->dropIndex('pages_slug_index');
+            $table->dropIndex('pages_book_id_index');
+            $table->dropIndex('pages_chapter_id_index');
+            $table->dropIndex('pages_priority_index');
+            $table->dropIndex('pages_created_by_index');
+            $table->dropIndex('pages_updated_by_index');
         });
         Schema::table('page_revisions', function (Blueprint $table) {
-            $table->dropIndex('page_id');
+            $table->dropIndex('page_revisions_page_id_index');
         });
         Schema::table('chapters', function (Blueprint $table) {
-            $table->dropIndex('slug');
-            $table->dropIndex('book_id');
-            $table->dropIndex('priority');
-            $table->dropIndex('created_by');
-            $table->dropIndex('updated_by');
+            $table->dropIndex('chapters_slug_index');
+            $table->dropIndex('chapters_book_id_index');
+            $table->dropIndex('chapters_priority_index');
+            $table->dropIndex('chapters_created_by_index');
+            $table->dropIndex('chapters_updated_by_index');
         });
         Schema::table('activities', function (Blueprint $table) {
-            $table->dropIndex('book_id');
-            $table->dropIndex('user_id');
-            $table->dropIndex('entity_id');
+            $table->dropIndex('activities_book_id_index');
+            $table->dropIndex('activities_user_id_index');
+            $table->dropIndex('activities_entity_id_index');
         });
         Schema::table('views', function (Blueprint $table) {
-            $table->dropIndex('user_id');
-            $table->dropIndex('entity_id');
+            $table->dropIndex('views_user_id_index');
+            $table->dropIndex('views_viewable_id_index');
         });
     }
 }
index 227c6210aab811ca90401bb3239d4eecbe1d820f..d2791f6e475b1f8f68d9e14f72b68df50aba17b9 100644 (file)
--- a/readme.md
+++ b/readme.md
@@ -55,6 +55,18 @@ location / {
 }
 ```
 
+## Testing
+
+BookStack has many integration tests that use Laravel's built-in testing capabilities which makes use of PHPUnit. To use you will need PHPUnit installed and accessible via command line. There is a `mysql_testing` database defined within the app config which is what is used by PHPUnit. This database is set with the following database name, user name and password defined as `bookstack-test`. You will have to create that database and credentials before testing.
+
+The testing database will also need migrating and seeding beforehand. This can be done with the following commands:
+
+```
+php artisan migrate --database=mysql_testing
+php artisan db:seed --class=DummyContentSeeder --database=mysql_testing
+```
+
+Once done you can run `phpunit` in the application root directory to run all tests.
 
 ## License
 
index 6bbe434b46d745fcb7a3d59693c9075283fbe741..f9dc81fa342f0960d0cca69a39af0772029ff1e9 100644 (file)
@@ -47,8 +47,8 @@
                 </div>
                 <div class="col-lg-4 col-sm-3 text-center">
                     <form action="/search/all" method="GET" class="search-box">
-                        <input type="text" name="term" tabindex="2" value="{{ isset($searchTerm) ? $searchTerm : '' }}">
-                        <button class="text-button"><i class="zmdi zmdi-search"></i></button>
+                        <input id="header-search-box-input" type="text" name="term" tabindex="2" value="{{ isset($searchTerm) ? $searchTerm : '' }}">
+                        <button id="header-search-box-button" type="submit" class="text-button"><i class="zmdi zmdi-search"></i></button>
                     </form>
                 </div>
                 <div class="col-lg-4 col-sm-5">
index 1af2d1a42e44a6b55255d4df1cf9f26d1e1b513a..768a9f6086ac8f3ab9129beaa2e081e59e262501 100644 (file)
@@ -1,7 +1,7 @@
 <div class="sort-box" data-type="book" data-id="{{ $book->id }}">
     <h3 class="text-book"><i class="zmdi zmdi-book"></i>{{ $book->name }}</h3>
     <ul class="sortable-page-list sort-list">
-        @foreach($book->children() as $bookChild)
+        @foreach($bookChildren as $bookChild)
             <li data-id="{{$bookChild->id}}" data-type="{{ $bookChild->getName() }}" class="text-{{ $bookChild->getName() }}">
                 <i class="zmdi {{ $bookChild->isA('chapter') ? 'zmdi-collection-bookmark':'zmdi-file-text'}}"></i>{{ $bookChild->name }}
                 @if($bookChild->isA('chapter'))
index 5fe278128bcfaf007e0d87d023c9b5feb46ffdcf..efdc04cf0142001218c8f60a3250b4b1fe705dd3 100644 (file)
@@ -7,7 +7,7 @@
         <div class="row">
             <div class="col-md-8" id="sort-boxes">
 
-                @include('books/sort-box', ['book' => $book])
+                @include('books/sort-box', ['book' => $book, 'bookChildren' => $bookChildren])
 
             </div>
 
index 493f99cac396c7c27e867c30124174fdb6c9e851..7cc2d640f77250715f0049579a77c290e6a9cc10 100644 (file)
@@ -51,6 +51,34 @@ class EntityTest extends TestCase
         return \BookStack\Book::find($book->id);
     }
 
+    public function testBookSortPageShows()
+    {
+        $books =  \BookStack\Book::all();
+        $bookToSort = $books[0];
+        $this->asAdmin()
+            ->visit($bookToSort->getUrl())
+            ->click('Sort')
+            ->seePageIs($bookToSort->getUrl() . '/sort')
+            ->seeStatusCode(200)
+            ->see($bookToSort->name)
+            // Ensure page shows other books
+            ->see($books[1]->name);
+    }
+
+    public function testBookSortItemReturnsBookContent()
+    {
+        $books =  \BookStack\Book::all();
+        $bookToSort = $books[0];
+        $firstPage = $bookToSort->pages[0];
+        $firstChapter = $bookToSort->chapters[0];
+        $this->asAdmin()
+            ->visit($bookToSort->getUrl() . '/sort-item')
+            // Ensure book details are returned
+            ->see($bookToSort->name)
+            ->see($firstPage->name)
+            ->see($firstChapter->name);
+    }
+
     public function pageCreation($chapter)
     {
         $page = factory(\BookStack\Page::class)->make([
@@ -118,12 +146,29 @@ class EntityTest extends TestCase
         // Ensure duplicate names are given different slugs
         $this->asAdmin()
             ->visit('/books/create')
-            ->submitForm('Save Book', $book->toArray())
+            ->type($book->name, '#name')
+            ->type($book->description, '#description')
+            ->press('Save Book')
             ->seePageIs('/books/my-first-book-2');
 
         $book = \BookStack\Book::where('slug', '=', 'my-first-book')->first();
         return $book;
     }
 
+    public function testPageSearch()
+    {
+        $book = \BookStack\Book::all()->first();
+        $page = $book->pages->first();
+
+        $this->asAdmin()
+            ->visit('/')
+            ->type($page->name, 'term')
+            ->press('header-search-box-button')
+            ->see('Search Results')
+            ->see($page->name)
+            ->click($page->name)
+            ->seePageIs($page->getUrl());
+    }
+
 
 }