SkipsOnErrorTest.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <?php
  2. namespace Maatwebsite\Excel\Tests\Concerns;
  3. use Illuminate\Database\Eloquent\Model;
  4. use Illuminate\Database\QueryException;
  5. use Maatwebsite\Excel\Concerns\Importable;
  6. use Maatwebsite\Excel\Concerns\SkipsErrors;
  7. use Maatwebsite\Excel\Concerns\SkipsOnError;
  8. use Maatwebsite\Excel\Concerns\ToModel;
  9. use Maatwebsite\Excel\Tests\Data\Stubs\Database\User;
  10. use Maatwebsite\Excel\Tests\TestCase;
  11. use PHPUnit\Framework\Assert;
  12. use Throwable;
  13. class SkipsOnErrorTest extends TestCase
  14. {
  15. /**
  16. * Setup the test environment.
  17. */
  18. protected function setUp(): void
  19. {
  20. parent::setUp();
  21. $this->loadLaravelMigrations(['--database' => 'testing']);
  22. }
  23. /**
  24. * @test
  25. */
  26. public function can_skip_on_error()
  27. {
  28. $import = new class implements ToModel, SkipsOnError
  29. {
  30. use Importable;
  31. public $errors = 0;
  32. /**
  33. * @param array $row
  34. * @return Model|null
  35. */
  36. public function model(array $row)
  37. {
  38. return new User([
  39. 'name' => $row[0],
  40. 'email' => $row[1],
  41. 'password' => 'secret',
  42. ]);
  43. }
  44. /**
  45. * @param Throwable $e
  46. */
  47. public function onError(Throwable $e)
  48. {
  49. Assert::assertInstanceOf(QueryException::class, $e);
  50. Assert::stringContains($e->getMessage(), 'Duplicate entry \'patrick@maatwebsite.nl\'');
  51. $this->errors++;
  52. }
  53. };
  54. $import->import('import-users-with-duplicates.xlsx');
  55. $this->assertEquals(1, $import->errors);
  56. // Shouldn't have rollbacked other imported rows.
  57. $this->assertDatabaseHas('users', [
  58. 'email' => 'patrick@maatwebsite.nl',
  59. ]);
  60. // Should have skipped inserting
  61. $this->assertDatabaseMissing('users', [
  62. 'email' => 'taylor@laravel.com',
  63. ]);
  64. }
  65. /**
  66. * @test
  67. */
  68. public function can_skip_errors_and_collect_all_errors_at_the_end()
  69. {
  70. $import = new class implements ToModel, SkipsOnError
  71. {
  72. use Importable, SkipsErrors;
  73. /**
  74. * @param array $row
  75. * @return Model|null
  76. */
  77. public function model(array $row)
  78. {
  79. return new User([
  80. 'name' => $row[0],
  81. 'email' => $row[1],
  82. 'password' => 'secret',
  83. ]);
  84. }
  85. };
  86. $import->import('import-users-with-duplicates.xlsx');
  87. $this->assertCount(1, $import->errors());
  88. /** @var Throwable $e */
  89. $e = $import->errors()->first();
  90. $this->assertInstanceOf(QueryException::class, $e);
  91. $this->stringContains($e->getMessage(), 'Duplicate entry \'patrick@maatwebsite.nl\'');
  92. // Shouldn't have rollbacked other imported rows.
  93. $this->assertDatabaseHas('users', [
  94. 'email' => 'patrick@maatwebsite.nl',
  95. ]);
  96. // Should have skipped inserting
  97. $this->assertDatabaseMissing('users', [
  98. 'email' => 'taylor@laravel.com',
  99. ]);
  100. }
  101. }