169 lines
5.5 KiB
PHP
169 lines
5.5 KiB
PHP
<?php
|
|
|
|
require_once __DIR__ . '/../../../autoload/Domain/Finances/FakturowniaApiClient.php';
|
|
|
|
use Domain\Finances\FakturowniaApiClient;
|
|
|
|
class FakeFakturowniaApiClient extends FakturowniaApiClient
|
|
{
|
|
public $calledPaths = [];
|
|
public $responses = [];
|
|
|
|
protected function request( $path, $query )
|
|
{
|
|
$this -> calledPaths[] = [ 'path' => $path, 'query' => $query ];
|
|
|
|
if ( !isset( $this -> responses[ $path ] ) )
|
|
return [ 'http_code' => 200, 'body' => '[]' ];
|
|
|
|
return $this -> responses[ $path ];
|
|
}
|
|
}
|
|
|
|
function run_fakturownia_api_client_tests()
|
|
{
|
|
// AC-1: /invoices.json?income=no jest pytane jako primary source,
|
|
// pusta odpowiedz /costs.json NIE konczy wczesniej i faktura 486639934 z /invoices.json trafia do wynikow.
|
|
$client = new FakeFakturowniaApiClient( 'https://example', 'token', 100 );
|
|
$client -> responses = [
|
|
'/invoices.json' => [
|
|
'http_code' => 200,
|
|
'body' => json_encode( [
|
|
'invoices' => [
|
|
[
|
|
'id' => 486639934,
|
|
'number' => 'FV 100/04/2026',
|
|
'kind' => 'vat',
|
|
'income' => false,
|
|
'issue_date' => '2026-04-05',
|
|
'seller_name' => 'Dostawca Sp. z o.o.',
|
|
'seller_tax_no' => '5252344567'
|
|
]
|
|
]
|
|
] )
|
|
],
|
|
'/costs.json' => [ 'http_code' => 200, 'body' => '[]' ],
|
|
'/expenses.json' => [ 'http_code' => 404, 'body' => '' ]
|
|
];
|
|
|
|
$result = $client -> fetchCostDocuments( '2026-04-01', 1 );
|
|
|
|
assert_true(
|
|
count( $result ) === 1,
|
|
'Expected faktura 486639934 to be returned from /invoices.json?income=no even when /costs.json is empty.'
|
|
);
|
|
assert_true(
|
|
(string)$result[0]['id'] === '486639934',
|
|
'Expected invoice id 486639934 in merged cost documents.'
|
|
);
|
|
|
|
$paths = array_map( function( $c ) { return $c['path']; }, $client -> calledPaths );
|
|
assert_true(
|
|
in_array( '/invoices.json', $paths, true ),
|
|
'Expected /invoices.json to be queried for cost documents.'
|
|
);
|
|
assert_true(
|
|
in_array( '/costs.json', $paths, true ),
|
|
'Expected /costs.json to be queried as secondary source.'
|
|
);
|
|
assert_true(
|
|
in_array( '/expenses.json', $paths, true ),
|
|
'Expected /expenses.json to be queried as tertiary source (bug 05-04: empty /costs.json must not short-circuit).'
|
|
);
|
|
|
|
// AC-2: period=more + date_from + date_to sa wysylane, by API filtrowalo po issue_date.
|
|
// Bez tego importer pobieralby wszystkie historyczne faktury i cron by sie zawiesil.
|
|
$invoicesCall = null;
|
|
foreach ( $client -> calledPaths as $call )
|
|
{
|
|
if ( $call['path'] === '/invoices.json' )
|
|
{
|
|
$invoicesCall = $call;
|
|
break;
|
|
}
|
|
}
|
|
assert_true( $invoicesCall !== null, 'Expected at least one call to /invoices.json.' );
|
|
assert_true(
|
|
( $invoicesCall['query']['period'] ?? '' ) === 'more',
|
|
'Expected period=more parameter so Fakturownia filters by date range server-side.'
|
|
);
|
|
assert_true(
|
|
( $invoicesCall['query']['date_from'] ?? '' ) === '2026-04-01',
|
|
'Expected date_from to match startDate passed to fetchCostDocuments.'
|
|
);
|
|
assert_true(
|
|
!empty( $invoicesCall['query']['date_to'] ?? '' ),
|
|
'Expected date_to to be set (default: today) to complete the range filter.'
|
|
);
|
|
assert_true(
|
|
( $invoicesCall['query']['income'] ?? '' ) === 'no',
|
|
'Expected income=no filter on /invoices.json for cost documents.'
|
|
);
|
|
|
|
// Dedup: ten sam id w /invoices.json i /costs.json trafia raz.
|
|
$dedupClient = new FakeFakturowniaApiClient( 'https://example', 'token', 100 );
|
|
$dedupClient -> responses = [
|
|
'/invoices.json' => [
|
|
'http_code' => 200,
|
|
'body' => json_encode( [
|
|
'invoices' => [
|
|
[ 'id' => 111, 'number' => 'A', 'income' => false ],
|
|
[ 'id' => 222, 'number' => 'B', 'income' => false ]
|
|
]
|
|
] )
|
|
],
|
|
'/costs.json' => [
|
|
'http_code' => 200,
|
|
'body' => json_encode( [
|
|
'costs' => [
|
|
[ 'id' => 222, 'number' => 'B' ],
|
|
[ 'id' => 333, 'number' => 'C' ]
|
|
]
|
|
] )
|
|
]
|
|
];
|
|
|
|
$merged = $dedupClient -> fetchCostDocuments( '2026-04-01', 1 );
|
|
$ids = array_map( function( $d ) { return (string)$d['id']; }, $merged );
|
|
sort( $ids );
|
|
assert_true(
|
|
$ids === [ '111', '222', '333' ],
|
|
'Expected merged cost documents to be deduplicated by id across endpoints.'
|
|
);
|
|
|
|
// Gdy wszystkie 3 sciezki zwroca HTTP >= 400, fetchCostDocuments rzuca wyjatek.
|
|
$errorClient = new FakeFakturowniaApiClient( 'https://example', 'token', 100 );
|
|
$errorClient -> responses = [
|
|
'/invoices.json' => [ 'http_code' => 500, 'body' => '' ],
|
|
'/costs.json' => [ 'http_code' => 500, 'body' => '' ],
|
|
'/expenses.json' => [ 'http_code' => 500, 'body' => '' ]
|
|
];
|
|
|
|
$threw = false;
|
|
try
|
|
{
|
|
$errorClient -> fetchCostDocuments( '2026-04-01', 1 );
|
|
}
|
|
catch ( \Throwable $e )
|
|
{
|
|
$threw = true;
|
|
}
|
|
assert_true(
|
|
$threw,
|
|
'Expected fetchCostDocuments to throw when all endpoints fail with HTTP errors.'
|
|
);
|
|
|
|
// Gdy wszystkie 3 sciezki zwroca pusta liste z HTTP 200, zwracamy [] (nie wyjatek).
|
|
$emptyClient = new FakeFakturowniaApiClient( 'https://example', 'token', 100 );
|
|
$emptyClient -> responses = [
|
|
'/invoices.json' => [ 'http_code' => 200, 'body' => '[]' ],
|
|
'/costs.json' => [ 'http_code' => 200, 'body' => '[]' ],
|
|
'/expenses.json' => [ 'http_code' => 200, 'body' => '[]' ]
|
|
];
|
|
$emptyResult = $emptyClient -> fetchCostDocuments( '2026-04-01', 1 );
|
|
assert_true(
|
|
is_array( $emptyResult ) && count( $emptyResult ) === 0,
|
|
'Expected empty array when all endpoints return HTTP 200 with empty lists.'
|
|
);
|
|
}
|