]> BookStack Code Mirror - bookstack/blob - tests/Api/ShelvesApiTest.php
Merge pull request #3556 from GongMingCai/development
[bookstack] / tests / Api / ShelvesApiTest.php
1 <?php
2
3 namespace Tests\Api;
4
5 use BookStack\Entities\Models\Book;
6 use BookStack\Entities\Models\Bookshelf;
7 use Carbon\Carbon;
8 use Illuminate\Support\Facades\DB;
9 use Tests\TestCase;
10 use Tests\Uploads\UsesImages;
11
12 class ShelvesApiTest extends TestCase
13 {
14     use TestsApi;
15     use UsesImages;
16
17     protected string $baseEndpoint = '/api/shelves';
18
19     public function test_index_endpoint_returns_expected_shelf()
20     {
21         $this->actingAsApiEditor();
22         $firstBookshelf = Bookshelf::query()->orderBy('id', 'asc')->first();
23
24         $resp = $this->getJson($this->baseEndpoint . '?count=1&sort=+id');
25         $resp->assertJson(['data' => [
26             [
27                 'id'   => $firstBookshelf->id,
28                 'name' => $firstBookshelf->name,
29                 'slug' => $firstBookshelf->slug,
30             ],
31         ]]);
32     }
33
34     public function test_create_endpoint()
35     {
36         $this->actingAsApiEditor();
37         $books = Book::query()->take(2)->get();
38
39         $details = [
40             'name'        => 'My API shelf',
41             'description' => 'A shelf created via the API',
42         ];
43
44         $resp = $this->postJson($this->baseEndpoint, array_merge($details, ['books' => [$books[0]->id, $books[1]->id]]));
45         $resp->assertStatus(200);
46         $newItem = Bookshelf::query()->orderByDesc('id')->where('name', '=', $details['name'])->first();
47         $resp->assertJson(array_merge($details, ['id' => $newItem->id, 'slug' => $newItem->slug]));
48         $this->assertActivityExists('bookshelf_create', $newItem);
49         foreach ($books as $index => $book) {
50             $this->assertDatabaseHas('bookshelves_books', [
51                 'bookshelf_id' => $newItem->id,
52                 'book_id'      => $book->id,
53                 'order'        => $index,
54             ]);
55         }
56     }
57
58     public function test_shelf_name_needed_to_create()
59     {
60         $this->actingAsApiEditor();
61         $details = [
62             'description' => 'A shelf created via the API',
63         ];
64
65         $resp = $this->postJson($this->baseEndpoint, $details);
66         $resp->assertStatus(422);
67         $resp->assertJson([
68             'error' => [
69                 'message'    => 'The given data was invalid.',
70                 'validation' => [
71                     'name' => ['The name field is required.'],
72                 ],
73                 'code' => 422,
74             ],
75         ]);
76     }
77
78     public function test_read_endpoint()
79     {
80         $this->actingAsApiEditor();
81         $shelf = Bookshelf::visible()->first();
82
83         $resp = $this->getJson($this->baseEndpoint . "/{$shelf->id}");
84
85         $resp->assertStatus(200);
86         $resp->assertJson([
87             'id'         => $shelf->id,
88             'slug'       => $shelf->slug,
89             'created_by' => [
90                 'name' => $shelf->createdBy->name,
91             ],
92             'updated_by' => [
93                 'name' => $shelf->createdBy->name,
94             ],
95             'owned_by' => [
96                 'name' => $shelf->ownedBy->name,
97             ],
98         ]);
99     }
100
101     public function test_update_endpoint()
102     {
103         $this->actingAsApiEditor();
104         $shelf = Bookshelf::visible()->first();
105         $details = [
106             'name'        => 'My updated API shelf',
107             'description' => 'A shelf created via the API',
108         ];
109
110         $resp = $this->putJson($this->baseEndpoint . "/{$shelf->id}", $details);
111         $shelf->refresh();
112
113         $resp->assertStatus(200);
114         $resp->assertJson(array_merge($details, ['id' => $shelf->id, 'slug' => $shelf->slug]));
115         $this->assertActivityExists('bookshelf_update', $shelf);
116     }
117
118     public function test_update_increments_updated_date_if_only_tags_are_sent()
119     {
120         $this->actingAsApiEditor();
121         $shelf = Bookshelf::visible()->first();
122         DB::table('bookshelves')->where('id', '=', $shelf->id)->update(['updated_at' => Carbon::now()->subWeek()]);
123
124         $details = [
125             'tags' => [['name' => 'Category', 'value' => 'Testing']],
126         ];
127
128         $this->putJson($this->baseEndpoint . "/{$shelf->id}", $details);
129         $shelf->refresh();
130         $this->assertGreaterThan(Carbon::now()->subDay()->unix(), $shelf->updated_at->unix());
131     }
132
133     public function test_update_only_assigns_books_if_param_provided()
134     {
135         $this->actingAsApiEditor();
136         $shelf = Bookshelf::visible()->first();
137         $this->assertTrue($shelf->books()->count() > 0);
138         $details = [
139             'name' => 'My updated API shelf',
140         ];
141
142         $resp = $this->putJson($this->baseEndpoint . "/{$shelf->id}", $details);
143         $resp->assertStatus(200);
144         $this->assertTrue($shelf->books()->count() > 0);
145
146         $resp = $this->putJson($this->baseEndpoint . "/{$shelf->id}", ['books' => []]);
147         $resp->assertStatus(200);
148         $this->assertTrue($shelf->books()->count() === 0);
149     }
150
151     public function test_update_cover_image_control()
152     {
153         $this->actingAsApiEditor();
154         /** @var Book $shelf */
155         $shelf = Bookshelf::visible()->first();
156         $this->assertNull($shelf->cover);
157         $file = $this->getTestImage('image.png');
158
159         // Ensure cover image can be set via API
160         $resp = $this->call('PUT', $this->baseEndpoint . "/{$shelf->id}", [
161             'name'  => 'My updated API shelf with image',
162         ], [], ['image' => $file]);
163         $shelf->refresh();
164
165         $resp->assertStatus(200);
166         $this->assertNotNull($shelf->cover);
167
168         // Ensure further updates without image do not clear cover image
169         $resp = $this->put($this->baseEndpoint . "/{$shelf->id}", [
170             'name' => 'My updated shelf again',
171         ]);
172         $shelf->refresh();
173
174         $resp->assertStatus(200);
175         $this->assertNotNull($shelf->cover);
176
177         // Ensure update with null image property clears image
178         $resp = $this->put($this->baseEndpoint . "/{$shelf->id}", [
179             'image' => null,
180         ]);
181         $shelf->refresh();
182
183         $resp->assertStatus(200);
184         $this->assertNull($shelf->cover);
185     }
186
187     public function test_delete_endpoint()
188     {
189         $this->actingAsApiEditor();
190         $shelf = Bookshelf::visible()->first();
191         $resp = $this->deleteJson($this->baseEndpoint . "/{$shelf->id}");
192
193         $resp->assertStatus(204);
194         $this->assertActivityExists('bookshelf_delete');
195     }
196 }