'http://test-server.local', 'logistics.api_key' => 'test-api-key', 'logistics.folder' => 'testfolder', 'logistics.timeout' => 30, 'logistics.connect_timeout' => 10, 'logistics.retry.times' => 1, 'logistics.retry.sleep_ms' => 0, ]); $this->actingAs(User::factory()->create()); }); it('defaults to read mode', function () { Livewire::test(Articles::class) ->assertSet('mode', 'read'); }); it('can switch between read and write modes', function () { Livewire::test(Articles::class) ->set('mode', 'write') ->assertSet('mode', 'write') ->set('mode', 'read') ->assertSet('mode', 'read'); }); it('searches articles via art_list', function () { Http::fake([ '*/art_list' => Http::response([ 'data' => [['ARTID' => 'ART001', 'NAME1' => 'Test Article']], 'metadata' => ['rowcount' => 1, 'issuccess' => true], 'error' => null, ]), ]); Livewire::test(Articles::class) ->set('search', 'test') ->set('select', 'artid,name1') ->call('searchArticles') ->assertSet('hasSearched', true) ->assertSet('data', [['ARTID' => 'ART001', 'NAME1' => 'Test Article']]) ->assertSet('errorMessage', null); }); it('sends barcode parameter when provided', function () { Http::fake([ '*/art_list' => Http::response([ 'data' => [['ARTID' => 'ART001']], 'metadata' => ['rowcount' => 1, 'issuccess' => true], 'error' => null, ]), ]); Livewire::test(Articles::class) ->set('search', 'test') ->set('barcode', '5411068700323') ->call('searchArticles') ->assertSet('hasSearched', true) ->assertSet('data', [['ARTID' => 'ART001']]); Http::assertSent(function (\Illuminate\Http\Client\Request $request) { $body = json_decode($request->body(), true); return $body['barcode'] === '5411068700323' && $body['search'] === 'test'; }); }); it('does not send barcode parameter when empty', function () { Http::fake([ '*/art_list' => Http::response([ 'data' => [], 'metadata' => ['rowcount' => 0, 'issuccess' => true], 'error' => null, ]), ]); Livewire::test(Articles::class) ->set('search', 'test') ->set('barcode', '') ->call('searchArticles'); Http::assertSent(function (\Illuminate\Http\Client\Request $request) { $body = json_decode($request->body(), true); return ! array_key_exists('barcode', $body); }); }); it('sets hasSearched even when no results', function () { Http::fake([ '*/art_list' => Http::response([ 'data' => [], 'metadata' => ['rowcount' => 0, 'issuccess' => true], 'error' => null, ]), ]); Livewire::test(Articles::class) ->set('search', 'nonexistent') ->call('searchArticles') ->assertSet('hasSearched', true) ->assertSet('data', []); }); it('gets stock for an article', function () { Http::fake([ '*/art_getstk' => Http::response([ 'data' => ['stock' => 42], 'metadata' => ['rowcount' => 1, 'issuccess' => true], 'error' => null, ]), ]); Livewire::test(Articles::class) ->set('stockArticleId', 'ART001') ->call('getStock') ->assertSet('hasCheckedStock', true) ->assertSet('stockData', ['stock' => 42]) ->assertSet('errorMessage', null); }); it('shows validation error when stockArticleId is empty', function () { Http::fake(); Livewire::test(Articles::class) ->call('getStock') ->assertSet('hasCheckedStock', false) ->assertSet('errorMessage', 'Le champ identifiant article (ARTID) est obligatoire pour verifier le stock.'); Http::assertNothingSent(); }); it('translates API error with explanation', function () { Http::fake([ '*/art_list' => Http::response([ 'data' => null, 'metadata' => ['rowcount' => 0, 'issuccess' => false], 'error' => ['Search terms are required. Please provide search criteria.'], ]), ]); Livewire::test(Articles::class) ->call('searchArticles') ->assertSet('hasSearched', true) ->assertSee('Explication'); }); it('displays error message on API failure', function () { Http::fake([ '*/art_list' => Http::response([ 'data' => null, 'metadata' => ['rowcount' => 0, 'issuccess' => false], 'error' => 'Invalid API key', ]), ]); Livewire::test(Articles::class) ->call('searchArticles') ->assertSet('hasSearched', true); expect(true)->toBeTrue(); }); // --- art_add --- it('adds an article via art_add', function () { Http::fake([ '*/art_add' => Http::response([ 'data' => ['artid' => 'ART001'], 'metadata' => ['rowcount' => 1, 'issuccess' => true], 'error' => null, ]), ]); Livewire::test(Articles::class) ->set('mode', 'write') ->set('addArtId', 'ART001') ->set('addName', 'Test Article') ->set('addSalePrice', '49.99') ->call('addArticle') ->assertSet('hasAdded', true) ->assertSet('addResult', ['artid' => 'ART001']) ->assertSet('errorMessage', null); Http::assertSent(function ($request) { $body = $request->data(); return str_contains($request->url(), 'art_add') && $body['ARTID'] === 'ART001' && $body['NAME1'] === 'Test Article' && $body['SALEPRICE'] === '49.99'; }); }); it('shows validation error when addArtId is empty', function () { Http::fake(); Livewire::test(Articles::class) ->set('mode', 'write') ->call('addArticle') ->assertSet('hasAdded', false) ->assertSet('errorMessage', 'Le champ identifiant article (ARTID) est obligatoire.'); Http::assertNothingSent(); }); it('omits optional params when empty on art_add', function () { Http::fake([ '*/art_add' => Http::response([ 'data' => ['artid' => 'ART001'], 'metadata' => ['rowcount' => 1, 'issuccess' => true], 'error' => null, ]), ]); Livewire::test(Articles::class) ->set('mode', 'write') ->set('addArtId', 'ART001') ->set('addName', '') ->set('addSalePrice', '') ->call('addArticle'); Http::assertSent(function ($request) { $body = $request->data(); return $body['ARTID'] === 'ART001' && ! array_key_exists('NAME1', $body) && ! array_key_exists('SALEPRICE', $body); }); }); it('handles API error on art_add (duplicate)', function () { Http::fake([ '*/art_add' => Http::response([ 'data' => ['xml' => '001Artid already exist'], 'metadata' => ['rowcount' => 1, 'issuccess' => false], 'error' => ['Code: 001, Description: Artid already exist'], ]), ]); $component = Livewire::test(Articles::class) ->set('mode', 'write') ->set('addArtId', 'ART001') ->call('addArticle'); expect($component->get('errorMessage'))->toContain('Artid already exist'); }); // --- art_mod --- it('modifies an article via art_mod', function () { Http::fake([ '*/art_mod' => Http::response([ 'data' => ['artid' => 'ART001'], 'metadata' => ['rowcount' => 1, 'issuccess' => true], 'error' => null, ]), ]); Livewire::test(Articles::class) ->set('mode', 'write') ->set('modArtId', 'ART001') ->set('modName', 'Updated Name') ->set('modSalePrice', '59.99') ->call('modArticle') ->assertSet('hasModified', true) ->assertSet('modResult', ['artid' => 'ART001']) ->assertSet('errorMessage', null); Http::assertSent(function ($request) { $body = $request->data(); return str_contains($request->url(), 'art_mod') && $body['ARTID'] === 'ART001' && $body['NAME1'] === 'Updated Name'; }); }); it('shows validation error when modArtId is empty', function () { Http::fake(); Livewire::test(Articles::class) ->set('mode', 'write') ->call('modArticle') ->assertSet('hasModified', false) ->assertSet('errorMessage', 'Le champ identifiant article (ARTID) est obligatoire.'); Http::assertNothingSent(); }); it('handles API error on art_mod (not found)', function () { Http::fake([ '*/art_mod' => Http::response([ 'data' => ['xml' => '001Artid does not exist'], 'metadata' => ['rowcount' => 1, 'issuccess' => false], 'error' => ['Code: 001, Description: Artid does not exist'], ]), ]); $component = Livewire::test(Articles::class) ->set('mode', 'write') ->set('modArtId', 'INEXISTANT') ->call('modArticle'); expect($component->get('errorMessage'))->toContain('Artid does not exist'); });