]> BookStack Code Mirror - bookstack/blob - tests/Api/BooksApiTest.php
Merge pull request #2899 from BookStackApp/export_permissions
[bookstack] / tests / Api / BooksApiTest.php
1 <?php
2
3 namespace Tests\Api;
4
5 use BookStack\Entities\Models\Book;
6 use Tests\TestCase;
7
8 class BooksApiTest extends TestCase
9 {
10     use TestsApi;
11
12     protected $baseEndpoint = '/api/books';
13
14     public function test_index_endpoint_returns_expected_book()
15     {
16         $this->actingAsApiEditor();
17         $firstBook = Book::query()->orderBy('id', 'asc')->first();
18
19         $resp = $this->getJson($this->baseEndpoint . '?count=1&sort=+id');
20         $resp->assertJson(['data' => [
21             [
22                 'id'   => $firstBook->id,
23                 'name' => $firstBook->name,
24                 'slug' => $firstBook->slug,
25             ],
26         ]]);
27     }
28
29     public function test_create_endpoint()
30     {
31         $this->actingAsApiEditor();
32         $details = [
33             'name'        => 'My API book',
34             'description' => 'A book created via the API',
35         ];
36
37         $resp = $this->postJson($this->baseEndpoint, $details);
38         $resp->assertStatus(200);
39         $newItem = Book::query()->orderByDesc('id')->where('name', '=', $details['name'])->first();
40         $resp->assertJson(array_merge($details, ['id' => $newItem->id, 'slug' => $newItem->slug]));
41         $this->assertActivityExists('book_create', $newItem);
42     }
43
44     public function test_book_name_needed_to_create()
45     {
46         $this->actingAsApiEditor();
47         $details = [
48             'description' => 'A book created via the API',
49         ];
50
51         $resp = $this->postJson($this->baseEndpoint, $details);
52         $resp->assertStatus(422);
53         $resp->assertJson([
54             'error' => [
55                 'message'    => 'The given data was invalid.',
56                 'validation' => [
57                     'name' => ['The name field is required.'],
58                 ],
59                 'code' => 422,
60             ],
61         ]);
62     }
63
64     public function test_read_endpoint()
65     {
66         $this->actingAsApiEditor();
67         $book = Book::visible()->first();
68
69         $resp = $this->getJson($this->baseEndpoint . "/{$book->id}");
70
71         $resp->assertStatus(200);
72         $resp->assertJson([
73             'id'         => $book->id,
74             'slug'       => $book->slug,
75             'created_by' => [
76                 'name' => $book->createdBy->name,
77             ],
78             'updated_by' => [
79                 'name' => $book->createdBy->name,
80             ],
81             'owned_by' => [
82                 'name' => $book->ownedBy->name,
83             ],
84         ]);
85     }
86
87     public function test_update_endpoint()
88     {
89         $this->actingAsApiEditor();
90         $book = Book::visible()->first();
91         $details = [
92             'name'        => 'My updated API book',
93             'description' => 'A book created via the API',
94         ];
95
96         $resp = $this->putJson($this->baseEndpoint . "/{$book->id}", $details);
97         $book->refresh();
98
99         $resp->assertStatus(200);
100         $resp->assertJson(array_merge($details, ['id' => $book->id, 'slug' => $book->slug]));
101         $this->assertActivityExists('book_update', $book);
102     }
103
104     public function test_delete_endpoint()
105     {
106         $this->actingAsApiEditor();
107         $book = Book::visible()->first();
108         $resp = $this->deleteJson($this->baseEndpoint . "/{$book->id}");
109
110         $resp->assertStatus(204);
111         $this->assertActivityExists('book_delete');
112     }
113
114     public function test_export_html_endpoint()
115     {
116         $this->actingAsApiEditor();
117         $book = Book::visible()->first();
118
119         $resp = $this->get($this->baseEndpoint . "/{$book->id}/export/html");
120         $resp->assertStatus(200);
121         $resp->assertSee($book->name);
122         $resp->assertHeader('Content-Disposition', 'attachment; filename="' . $book->slug . '.html"');
123     }
124
125     public function test_export_plain_text_endpoint()
126     {
127         $this->actingAsApiEditor();
128         $book = Book::visible()->first();
129
130         $resp = $this->get($this->baseEndpoint . "/{$book->id}/export/plaintext");
131         $resp->assertStatus(200);
132         $resp->assertSee($book->name);
133         $resp->assertHeader('Content-Disposition', 'attachment; filename="' . $book->slug . '.txt"');
134     }
135
136     public function test_export_pdf_endpoint()
137     {
138         $this->actingAsApiEditor();
139         $book = Book::visible()->first();
140
141         $resp = $this->get($this->baseEndpoint . "/{$book->id}/export/pdf");
142         $resp->assertStatus(200);
143         $resp->assertHeader('Content-Disposition', 'attachment; filename="' . $book->slug . '.pdf"');
144     }
145
146     public function test_export_markdown_endpoint()
147     {
148         $this->actingAsApiEditor();
149         $book = Book::visible()->has('pages')->has('chapters')->first();
150
151         $resp = $this->get($this->baseEndpoint . "/{$book->id}/export/markdown");
152         $resp->assertStatus(200);
153         $resp->assertHeader('Content-Disposition', 'attachment; filename="' . $book->slug . '.md"');
154         $resp->assertSee('# ' . $book->name);
155         $resp->assertSee('# ' . $book->pages()->first()->name);
156         $resp->assertSee('# ' . $book->chapters()->first()->name);
157     }
158
159     public function test_cant_export_when_not_have_permission()
160     {
161         $types = ['html', 'plaintext', 'pdf', 'markdown'];
162         $this->actingAsApiEditor();
163         $this->removePermissionFromUser($this->getEditor(), 'content-export');
164
165         $book = Book::visible()->first();
166         foreach ($types as $type) {
167             $resp = $this->get($this->baseEndpoint . "/{$book->id}/export/{$type}");
168             $this->assertPermissionError($resp);
169         }
170     }
171 }