ImplicitRouteBindingTest.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <?php
  2. namespace Illuminate\Tests\Integration\Routing;
  3. use Illuminate\Database\Eloquent\Model;
  4. use Illuminate\Database\Eloquent\SoftDeletes;
  5. use Illuminate\Database\Schema\Blueprint;
  6. use Illuminate\Support\Facades\Route;
  7. use Illuminate\Support\Facades\Schema;
  8. use Orchestra\Testbench\Concerns\InteractsWithPublishedFiles;
  9. use Orchestra\Testbench\TestCase;
  10. class ImplicitRouteBindingTest extends TestCase
  11. {
  12. use InteractsWithPublishedFiles;
  13. protected $files = [
  14. 'routes/testbench.php',
  15. ];
  16. protected function tearDown(): void
  17. {
  18. $this->tearDownInteractsWithPublishedFiles();
  19. parent::tearDown();
  20. }
  21. protected function defineDatabaseMigrations(): void
  22. {
  23. Schema::create('users', function (Blueprint $table) {
  24. $table->increments('id');
  25. $table->string('name');
  26. $table->timestamps();
  27. $table->softDeletes();
  28. });
  29. Schema::create('posts', function (Blueprint $table) {
  30. $table->increments('id');
  31. $table->integer('user_id');
  32. $table->timestamps();
  33. });
  34. $this->beforeApplicationDestroyed(function () {
  35. Schema::dropIfExists('users');
  36. Schema::dropIfExists('posts');
  37. });
  38. }
  39. public function testWithRouteCachingEnabled()
  40. {
  41. $this->defineCacheRoutes(<<<PHP
  42. <?php
  43. use Illuminate\Tests\Integration\Routing\ImplicitBindingUser;
  44. Route::post('/user/{user}', function (ImplicitBindingUser \$user) {
  45. return \$user;
  46. })->middleware('web');
  47. PHP);
  48. $user = ImplicitBindingUser::create(['name' => 'Dries']);
  49. $response = $this->postJson("/user/{$user->id}");
  50. $response->assertJson([
  51. 'id' => $user->id,
  52. 'name' => $user->name,
  53. ]);
  54. }
  55. public function testWithoutRouteCachingEnabled()
  56. {
  57. $user = ImplicitBindingUser::create(['name' => 'Dries']);
  58. config(['app.key' => str_repeat('a', 32)]);
  59. Route::post('/user/{user}', function (ImplicitBindingUser $user) {
  60. return $user;
  61. })->middleware(['web']);
  62. $response = $this->postJson("/user/{$user->id}");
  63. $response->assertJson([
  64. 'id' => $user->id,
  65. 'name' => $user->name,
  66. ]);
  67. }
  68. public function testSoftDeletedModelsAreNotRetrieved()
  69. {
  70. $user = ImplicitBindingUser::create(['name' => 'Dries']);
  71. $user->delete();
  72. config(['app.key' => str_repeat('a', 32)]);
  73. Route::post('/user/{user}', function (ImplicitBindingUser $user) {
  74. return $user;
  75. })->middleware(['web']);
  76. $response = $this->postJson("/user/{$user->id}");
  77. $response->assertStatus(404);
  78. }
  79. public function testSoftDeletedModelsCanBeRetrievedUsingWithTrashedMethod()
  80. {
  81. $user = ImplicitBindingUser::create(['name' => 'Dries']);
  82. $user->delete();
  83. config(['app.key' => str_repeat('a', 32)]);
  84. Route::post('/user/{user}', function (ImplicitBindingUser $user) {
  85. return $user;
  86. })->middleware(['web'])->withTrashed();
  87. $response = $this->postJson("/user/{$user->id}");
  88. $response->assertJson([
  89. 'id' => $user->id,
  90. 'name' => $user->name,
  91. ]);
  92. }
  93. public function testEnforceScopingImplicitRouteBindings()
  94. {
  95. $user = ImplicitBindingUser::create(['name' => 'Dries']);
  96. $post = ImplicitBindingPost::create(['user_id' => 2]);
  97. $this->assertEmpty($user->posts);
  98. config(['app.key' => str_repeat('a', 32)]);
  99. Route::scopeBindings()->group(function () {
  100. Route::get('/user/{user}/post/{post}', function (ImplicitBindingUser $user, ImplicitBindingPost $post) {
  101. return [$user, $post];
  102. })->middleware(['web']);
  103. });
  104. $response = $this->getJson("/user/{$user->id}/post/{$post->id}");
  105. $response->assertNotFound();
  106. }
  107. public function testEnforceScopingImplicitRouteBindingsWithTrashedAndChildWithNoSoftDeleteTrait()
  108. {
  109. $user = ImplicitBindingUser::create(['name' => 'Dries']);
  110. $post = $user->posts()->create();
  111. $user->delete();
  112. config(['app.key' => str_repeat('a', 32)]);
  113. Route::scopeBindings()->group(function () {
  114. Route::get('/user/{user}/post/{post}', function (ImplicitBindingUser $user, ImplicitBindingPost $post) {
  115. return [$user, $post];
  116. })->middleware(['web'])->withTrashed();
  117. });
  118. $response = $this->getJson("/user/{$user->id}/post/{$post->id}");
  119. $response->assertOk();
  120. $response->assertJson([
  121. [
  122. 'id' => $user->id,
  123. 'name' => $user->name,
  124. ],
  125. [
  126. 'id' => 1,
  127. 'user_id' => 1,
  128. ],
  129. ]);
  130. }
  131. public function testEnforceScopingImplicitRouteBindingsWithRouteCachingEnabled()
  132. {
  133. $user = ImplicitBindingUser::create(['name' => 'Dries']);
  134. $post = ImplicitBindingPost::create(['user_id' => 2]);
  135. $this->assertEmpty($user->posts);
  136. $this->defineCacheRoutes(<<<PHP
  137. <?php
  138. use Illuminate\Tests\Integration\Routing\ImplicitBindingUser;
  139. use Illuminate\Tests\Integration\Routing\ImplicitBindingPost;
  140. Route::group(['scoping' => true], function () {
  141. Route::get('/user/{user}/post/{post}', function (ImplicitBindingUser \$user, ImplicitBindingPost \$post) {
  142. return [\$user, \$post];
  143. })->middleware(['web']);
  144. });
  145. PHP);
  146. $response = $this->getJson("/user/{$user->id}/post/{$post->id}");
  147. $response->assertNotFound();
  148. }
  149. public function testWithoutEnforceScopingImplicitRouteBindings()
  150. {
  151. $user = ImplicitBindingUser::create(['name' => 'Dries']);
  152. $post = ImplicitBindingPost::create(['user_id' => 2]);
  153. $this->assertEmpty($user->posts);
  154. config(['app.key' => str_repeat('a', 32)]);
  155. Route::group(['scoping' => false], function () {
  156. Route::get('/user/{user}/post/{post}', function (ImplicitBindingUser $user, ImplicitBindingPost $post) {
  157. return [$user, $post];
  158. })->middleware(['web']);
  159. });
  160. $response = $this->getJson("/user/{$user->id}/post/{$post->id}");
  161. $response->assertOk();
  162. $response->assertJson([
  163. [
  164. 'id' => $user->id,
  165. 'name' => $user->name,
  166. ],
  167. [
  168. 'id' => 1,
  169. 'user_id' => 2,
  170. ],
  171. ]);
  172. }
  173. }
  174. class ImplicitBindingUser extends Model
  175. {
  176. use SoftDeletes;
  177. public $table = 'users';
  178. protected $fillable = ['name'];
  179. public function posts()
  180. {
  181. return $this->hasMany(ImplicitBindingPost::class, 'user_id');
  182. }
  183. }
  184. class ImplicitBindingPost extends Model
  185. {
  186. public $table = 'posts';
  187. protected $fillable = ['user_id'];
  188. }