WithUpsertsTest.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. <?php
  2. namespace Maatwebsite\Excel\Tests\Concerns;
  3. use Illuminate\Database\Eloquent\Builder;
  4. use Illuminate\Database\Eloquent\Model;
  5. use Illuminate\Support\Facades\DB;
  6. use Maatwebsite\Excel\Concerns\Importable;
  7. use Maatwebsite\Excel\Concerns\ToModel;
  8. use Maatwebsite\Excel\Concerns\WithBatchInserts;
  9. use Maatwebsite\Excel\Concerns\WithUpsertColumns;
  10. use Maatwebsite\Excel\Concerns\WithUpserts;
  11. use Maatwebsite\Excel\Tests\Data\Stubs\Database\User;
  12. use Maatwebsite\Excel\Tests\TestCase;
  13. class WithUpsertsTest extends TestCase
  14. {
  15. /**
  16. * Setup the test environment.
  17. */
  18. protected function setUp(): void
  19. {
  20. if (!method_exists(Builder::class, 'upsert')) {
  21. $this->markTestSkipped('The upsert feature is available on Laravel 8.10+');
  22. }
  23. parent::setUp();
  24. $this->loadLaravelMigrations(['--database' => 'testing']);
  25. }
  26. /**
  27. * @test
  28. */
  29. public function can_upsert_models_in_batches()
  30. {
  31. User::create([
  32. 'name' => 'Funny Banana',
  33. 'email' => 'patrick@maatwebsite.nl',
  34. 'password' => 'password',
  35. ]);
  36. DB::connection()->enableQueryLog();
  37. $import = new class implements ToModel, WithBatchInserts, WithUpserts
  38. {
  39. use Importable;
  40. /**
  41. * @param array $row
  42. * @return Model|null
  43. */
  44. public function model(array $row)
  45. {
  46. return new User([
  47. 'name' => $row[0],
  48. 'email' => $row[1],
  49. 'password' => 'secret',
  50. ]);
  51. }
  52. /**
  53. * @return string|array
  54. */
  55. public function uniqueBy()
  56. {
  57. return 'email';
  58. }
  59. /**
  60. * @return int
  61. */
  62. public function batchSize(): int
  63. {
  64. return 2;
  65. }
  66. };
  67. $import->import('import-users.xlsx');
  68. $this->assertCount(1, DB::getQueryLog());
  69. DB::connection()->disableQueryLog();
  70. $this->assertDatabaseHas('users', [
  71. 'name' => 'Patrick Brouwers',
  72. 'email' => 'patrick@maatwebsite.nl',
  73. 'password' => 'secret',
  74. ]);
  75. $this->assertDatabaseHas('users', [
  76. 'name' => 'Taylor Otwell',
  77. 'email' => 'taylor@laravel.com',
  78. 'password' => 'secret',
  79. ]);
  80. $this->assertEquals(2, User::count());
  81. }
  82. /**
  83. * @test
  84. */
  85. public function can_upsert_models_in_rows()
  86. {
  87. User::create([
  88. 'name' => 'Funny Potato',
  89. 'email' => 'patrick@maatwebsite.nl',
  90. 'password' => 'password',
  91. ]);
  92. DB::connection()->enableQueryLog();
  93. $import = new class implements ToModel, WithUpserts
  94. {
  95. use Importable;
  96. /**
  97. * @param array $row
  98. * @return Model|Model[]|null
  99. */
  100. public function model(array $row)
  101. {
  102. return new User([
  103. 'name' => $row[0],
  104. 'email' => $row[1],
  105. 'password' => 'secret',
  106. ]);
  107. }
  108. /**
  109. * @return string|array
  110. */
  111. public function uniqueBy()
  112. {
  113. return 'email';
  114. }
  115. };
  116. $import->import('import-users.xlsx');
  117. $this->assertCount(2, DB::getQueryLog());
  118. DB::connection()->disableQueryLog();
  119. $this->assertDatabaseHas('users', [
  120. 'name' => 'Patrick Brouwers',
  121. 'email' => 'patrick@maatwebsite.nl',
  122. 'password' => 'secret',
  123. ]);
  124. $this->assertDatabaseHas('users', [
  125. 'name' => 'Taylor Otwell',
  126. 'email' => 'taylor@laravel.com',
  127. 'password' => 'secret',
  128. ]);
  129. $this->assertEquals(2, User::count());
  130. }
  131. /**
  132. * @test
  133. */
  134. public function can_upsert_models_in_batches_with_defined_upsert_columns()
  135. {
  136. User::create([
  137. 'name' => 'Funny Banana',
  138. 'email' => 'patrick@maatwebsite.nl',
  139. 'password' => 'password',
  140. ]);
  141. DB::connection()->enableQueryLog();
  142. $import = new class implements ToModel, WithBatchInserts, WithUpserts, WithUpsertColumns
  143. {
  144. use Importable;
  145. /**
  146. * @param array $row
  147. * @return Model|null
  148. */
  149. public function model(array $row)
  150. {
  151. return new User([
  152. 'name' => $row[0],
  153. 'email' => $row[1],
  154. 'password' => 'secret',
  155. ]);
  156. }
  157. /**
  158. * @return string|array
  159. */
  160. public function uniqueBy()
  161. {
  162. return 'email';
  163. }
  164. /**
  165. * @return array
  166. */
  167. public function upsertColumns()
  168. {
  169. return ['name'];
  170. }
  171. /**
  172. * @return int
  173. */
  174. public function batchSize(): int
  175. {
  176. return 2;
  177. }
  178. };
  179. $import->import('import-users.xlsx');
  180. $this->assertCount(1, DB::getQueryLog());
  181. DB::connection()->disableQueryLog();
  182. $this->assertDatabaseHas('users', [
  183. 'name' => 'Patrick Brouwers',
  184. 'email' => 'patrick@maatwebsite.nl',
  185. 'password' => 'password',
  186. ]);
  187. $this->assertDatabaseHas('users', [
  188. 'name' => 'Taylor Otwell',
  189. 'email' => 'taylor@laravel.com',
  190. 'password' => 'secret',
  191. ]);
  192. $this->assertEquals(2, User::count());
  193. }
  194. /**
  195. * @test
  196. */
  197. public function can_upsert_models_in_rows_with_defined_upsert_columns()
  198. {
  199. User::create([
  200. 'name' => 'Funny Potato',
  201. 'email' => 'patrick@maatwebsite.nl',
  202. 'password' => 'password',
  203. ]);
  204. DB::connection()->enableQueryLog();
  205. $import = new class implements ToModel, WithUpserts, WithUpsertColumns
  206. {
  207. use Importable;
  208. /**
  209. * @param array $row
  210. * @return Model|Model[]|null
  211. */
  212. public function model(array $row)
  213. {
  214. return new User([
  215. 'name' => $row[0],
  216. 'email' => $row[1],
  217. 'password' => 'secret',
  218. ]);
  219. }
  220. /**
  221. * @return string|array
  222. */
  223. public function uniqueBy()
  224. {
  225. return 'email';
  226. }
  227. /**
  228. * @return array
  229. */
  230. public function upsertColumns()
  231. {
  232. return ['name'];
  233. }
  234. };
  235. $import->import('import-users.xlsx');
  236. $this->assertCount(2, DB::getQueryLog());
  237. DB::connection()->disableQueryLog();
  238. $this->assertDatabaseHas('users', [
  239. 'name' => 'Patrick Brouwers',
  240. 'email' => 'patrick@maatwebsite.nl',
  241. 'password' => 'password',
  242. ]);
  243. $this->assertDatabaseHas('users', [
  244. 'name' => 'Taylor Otwell',
  245. 'email' => 'taylor@laravel.com',
  246. 'password' => 'secret',
  247. ]);
  248. $this->assertEquals(2, User::count());
  249. }
  250. }