mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2026-04-18 12:10:50 +00:00
Fixes for tests
This commit is contained in:
@@ -75,6 +75,28 @@ class ChartController extends BaseController
|
||||
return response()->json($cs->chart_summary($request->input('start_date'), $request->input('end_date')), 200);
|
||||
}
|
||||
|
||||
public function analytics_summary(ShowChartRequest $request)
|
||||
{
|
||||
/** @var \App\Models\User auth()->user() */
|
||||
$user = auth()->user();
|
||||
$admin_equivalent_permissions = $user->isAdmin() || $user->hasExactPermissionAndAll('view_all') || $user->hasExactPermissionAndAll('edit_all');
|
||||
|
||||
$cs = new ChartService($user->company(), $user, $admin_equivalent_permissions);
|
||||
|
||||
return response()->json($cs->analytics_summary($request->input('start_date'), $request->input('end_date')), 200);
|
||||
}
|
||||
|
||||
public function analytics_totals(ShowChartRequest $request)
|
||||
{
|
||||
/** @var \App\Models\User auth()->user() */
|
||||
$user = auth()->user();
|
||||
$admin_equivalent_permissions = $user->isAdmin() || $user->hasExactPermissionAndAll('view_all') || $user->hasExactPermissionAndAll('edit_all');
|
||||
|
||||
$cs = new ChartService($user->company(), $user, $admin_equivalent_permissions);
|
||||
|
||||
return response()->json($cs->analytics_totals($request->input('start_date'), $request->input('end_date')), 200);
|
||||
}
|
||||
|
||||
public function calculatedFields(ShowCalculatedFieldRequest $request)
|
||||
{
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\License\CheckRequest;
|
||||
use App\Models\Account;
|
||||
use App\Services\License\WhiteLabelRenewalService;
|
||||
use App\Utils\CurlUtils;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -226,10 +227,14 @@ class LicenseController extends BaseController
|
||||
{
|
||||
$account = auth()->user()->account;
|
||||
|
||||
if ($account->plan == 'white_label' && Carbon::parse($account->plan_expires)->lt(now())) {
|
||||
$account->plan = null;
|
||||
$account->plan_expires = null;
|
||||
$account->save();
|
||||
if ($account->plan == 'white_label' && $account->plan_expires && Carbon::parse($account->plan_expires)->lt(now())) {
|
||||
$result = (new WhiteLabelRenewalService())->checkAndRenew($account);
|
||||
|
||||
if ($result === false) {
|
||||
$account->plan = null;
|
||||
$account->plan_expires = null;
|
||||
$account->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,11 +73,6 @@ class SquareController extends BaseController
|
||||
'code' => $request->query('code'),
|
||||
]);
|
||||
|
||||
nlog($base_url);
|
||||
nlog($config('services.square.application_id'));
|
||||
nlog($config('services.square.application_secret'));
|
||||
nlog($request->query('code'));
|
||||
nlog($response->body());
|
||||
if ($response->failed()) {
|
||||
return view('auth.square_connect.access_denied');
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ use App\Models\Account;
|
||||
use App\Models\Client;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Vendor;
|
||||
use App\Services\License\WhiteLabelRenewalService;
|
||||
use App\Utils\Ninja;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Bus\Queueable;
|
||||
@@ -59,10 +60,14 @@ class VersionCheck implements ShouldQueue
|
||||
return;
|
||||
}
|
||||
|
||||
if ($account->plan == 'white_label' && $account->plan_expires && Carbon::parse($account->plan_expires)->lt(now())) {
|
||||
$account->plan = null;
|
||||
$account->plan_expires = null;
|
||||
$account->saveQuietly();
|
||||
if ($account->plan == 'white_label' && $account->plan_expires && (Carbon::parse($account->plan_expires)->lt(now()) || Carbon::parse($account->plan_expires)->gt(now()->addYear()->addDays(30)))) {
|
||||
$result = (new WhiteLabelRenewalService())->checkAndRenew($account);
|
||||
|
||||
if ($result === false) {
|
||||
$account->plan = null;
|
||||
$account->plan_expires = null;
|
||||
$account->saveQuietly();
|
||||
}
|
||||
}
|
||||
|
||||
Client::query()->whereNull('country_id')->cursor()->each(function ($client) {
|
||||
|
||||
1108
app/Services/Chart/AnalyticsQueries.php
Normal file
1108
app/Services/Chart/AnalyticsQueries.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,7 @@ class ChartService
|
||||
{
|
||||
use ChartQueries;
|
||||
use ChartCalculations;
|
||||
use AnalyticsQueries;
|
||||
|
||||
public function __construct(public Company $company, private User $user, private bool $is_admin, private bool $include_drafts = false) {}
|
||||
|
||||
@@ -211,6 +212,72 @@ class ChartService
|
||||
return '';
|
||||
}
|
||||
|
||||
/* Analytics */
|
||||
|
||||
/**
|
||||
* Analytics chart summary — time-series data for analytics charts.
|
||||
* Returns per-currency + aggregate (key 999) data matching chart_summary() format.
|
||||
*/
|
||||
public function analytics_summary($start_date, $end_date): array
|
||||
{
|
||||
$currencies = $this->getCurrencyCodes();
|
||||
|
||||
$data = [];
|
||||
$data['start_date'] = $start_date;
|
||||
$data['end_date'] = $end_date;
|
||||
|
||||
foreach ($currencies as $key => $value) {
|
||||
$data[$key]['mrr'] = $this->getMrrChartQuery($start_date, $end_date, $key);
|
||||
$data[$key]['payment_delay'] = $this->getPaymentDelayChartQuery($start_date, $end_date, $key);
|
||||
$data[$key]['quote_pipeline'] = $this->getQuotePipelineChartQuery($start_date, $end_date, $key);
|
||||
$data[$key]['late_payment_rate'] = $this->getLatePaymentRateChartQuery($start_date, $end_date, $key);
|
||||
}
|
||||
|
||||
$data[999]['mrr'] = $this->getAggregateMrrChartQuery($start_date, $end_date);
|
||||
$data[999]['payment_delay'] = $this->getAggregatePaymentDelayChartQuery($start_date, $end_date);
|
||||
$data[999]['quote_pipeline'] = $this->getAggregateQuotePipelineChartQuery($start_date, $end_date);
|
||||
$data[999]['late_payment_rate'] = $this->getAggregateLatePaymentRateChartQuery($start_date, $end_date);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analytics totals — snapshot KPIs for analytics dashboard cards.
|
||||
* Returns per-currency + aggregate (key 999) data matching totals() format.
|
||||
*/
|
||||
public function analytics_totals($start_date, $end_date): array
|
||||
{
|
||||
$data = [];
|
||||
|
||||
$data['currencies'] = $this->getCurrencyCodes();
|
||||
$data['start_date'] = $start_date;
|
||||
$data['end_date'] = $end_date;
|
||||
|
||||
$mrr_totals = $this->getMrrTotalQuery();
|
||||
$aging_totals = $this->getAgingBucketTotals();
|
||||
$client_analytics = $this->getClientPaymentSummary();
|
||||
|
||||
foreach ($data['currencies'] as $key => $value) {
|
||||
$mrr_set = array_search($key, array_column($mrr_totals, 'currency_id'));
|
||||
$aging_set = array_search($key, array_column($aging_totals, 'currency_id'));
|
||||
|
||||
$data[$key]['mrr'] = $mrr_set !== false ? $mrr_totals[$mrr_set] : new \stdClass();
|
||||
$data[$key]['aging'] = $aging_set !== false ? $aging_totals[$aging_set] : new \stdClass();
|
||||
}
|
||||
|
||||
$aggregate_mrr = $this->getAggregateMrrTotalQuery();
|
||||
$aggregate_aging = $this->getAggregateAgingBucketTotals();
|
||||
$company_payment = $this->getCompanyPaymentSummary();
|
||||
|
||||
$data[999]['mrr'] = ! empty($aggregate_mrr) ? reset($aggregate_mrr) : new \stdClass();
|
||||
$data[999]['aging'] = ! empty($aggregate_aging) ? reset($aggregate_aging) : new \stdClass();
|
||||
$data[999]['payment_analytics'] = ! empty($company_payment) ? reset($company_payment) : new \stdClass();
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/* Analytics */
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
|
||||
72
app/Services/License/WhiteLabelRenewalService.php
Normal file
72
app/Services/License/WhiteLabelRenewalService.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Services\License;
|
||||
|
||||
use App\Models\Account;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Client\ConnectionException;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class WhiteLabelRenewalService
|
||||
{
|
||||
/**
|
||||
* Check if an expired white label license has been renewed on the license server.
|
||||
*
|
||||
* @return bool|null true = renewed, false = not renewed, null = inconclusive (network error)
|
||||
*/
|
||||
public function checkAndRenew(Account $account): ?bool
|
||||
{
|
||||
$licenseKey = config('ninja.license_key');
|
||||
|
||||
if (! $licenseKey) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$response = Http::timeout(15)
|
||||
->get(config('ninja.hosted_ninja_url') . '/claim_license', [
|
||||
'license_key' => $licenseKey,
|
||||
'product_id' => 3,
|
||||
]);
|
||||
|
||||
if ($response->successful()) {
|
||||
$payload = $response->json();
|
||||
|
||||
if (is_array($payload) && isset($payload['expires'])) {
|
||||
$expires = Carbon::parse($payload['expires']);
|
||||
|
||||
if ($expires->gt(now())) {
|
||||
$account->plan_term = Account::PLAN_TERM_YEARLY;
|
||||
$account->plan_expires = $expires->format('Y-m-d');
|
||||
$account->plan = Account::PLAN_WHITE_LABEL;
|
||||
$account->saveQuietly();
|
||||
|
||||
nlog('White label license auto-renewed. New expiry: ' . $expires->format('Y-m-d'));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (ConnectionException $e) {
|
||||
nlog('White label renewal check failed - network error: ' . $e->getMessage());
|
||||
|
||||
return null;
|
||||
} catch (\Exception $e) {
|
||||
nlog('White label renewal check failed: ' . $e->getMessage());
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,6 +181,8 @@ Route::group(['middleware' => ['throttle:api', 'token_auth', 'valid_json','local
|
||||
Route::post('charts/totals_v2', [ChartController::class, 'totalsV2'])->name('chart.totals_v2');
|
||||
Route::post('charts/chart_summary_v2', [ChartController::class, 'chart_summaryV2'])->name('chart.chart_summary_v2');
|
||||
Route::post('charts/calculated_fields', [ChartController::class, 'calculatedFields'])->name('chart.calculated_fields');
|
||||
Route::post('charts/analytics_summary', [ChartController::class, 'analytics_summary'])->name('chart.analytics_summary');
|
||||
Route::post('charts/analytics_totals', [ChartController::class, 'analytics_totals'])->name('chart.analytics_totals');
|
||||
|
||||
Route::post('claim_license', [LicenseController::class, 'index'])->name('license.index');
|
||||
Route::post('check_license', [LicenseController::class, 'check'])->name('license.check');
|
||||
|
||||
@@ -432,496 +432,496 @@ class EInvoiceValidationTest extends TestCase
|
||||
|
||||
}
|
||||
|
||||
public function testInValidBusinessClientNoVat()
|
||||
{
|
||||
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $this->account->id,
|
||||
]);
|
||||
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'classification' => 'business',
|
||||
'vat_number' => '',
|
||||
'country_id' => 276,
|
||||
'address1' => '10 Wallaby Way',
|
||||
'address2' => '',
|
||||
'city' => 'Sydney',
|
||||
'state' => 'NSW',
|
||||
'postal_code' => '2113',
|
||||
]);
|
||||
|
||||
|
||||
$cc = ClientContact::factory()->create([
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'first_name' => 'Bob',
|
||||
'last_name' => 'Doe',
|
||||
'email' => 'wasa@b.com',
|
||||
]);
|
||||
|
||||
$el = new EntityLevel();
|
||||
$validation = $el->checkClient($client);
|
||||
|
||||
$this->assertEquals(0, strlen($client->vat_number));
|
||||
|
||||
$this->assertFalse($validation['passes']);
|
||||
|
||||
}
|
||||
|
||||
public function testSeBusinessClientNeedsBothVatAndId()
|
||||
{
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $this->account->id,
|
||||
]);
|
||||
|
||||
// SE business with VAT but no id_number — should fail
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'classification' => 'business',
|
||||
'vat_number' => 'SE123456789012',
|
||||
'id_number' => '',
|
||||
'country_id' => 752,
|
||||
'address1' => '10 Wallaby Way',
|
||||
'city' => 'Stockholm',
|
||||
'state' => 'Stockholm',
|
||||
'postal_code' => '11122',
|
||||
]);
|
||||
|
||||
$cc = ClientContact::factory()->create([
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'first_name' => 'Bob',
|
||||
'last_name' => 'Doe',
|
||||
'email' => 'bob@example.com',
|
||||
]);
|
||||
|
||||
$el = new EntityLevel();
|
||||
$validation = $el->checkClient($client);
|
||||
|
||||
$this->assertFalse($validation['passes']);
|
||||
}
|
||||
|
||||
public function testSeBusinessClientPassesWithBoth()
|
||||
{
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $this->account->id,
|
||||
]);
|
||||
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'classification' => 'business',
|
||||
'vat_number' => 'SE123456789012',
|
||||
'id_number' => '5567891234',
|
||||
'country_id' => 752,
|
||||
'address1' => '10 Wallaby Way',
|
||||
'city' => 'Stockholm',
|
||||
'state' => 'Stockholm',
|
||||
'postal_code' => '11122',
|
||||
]);
|
||||
|
||||
$cc = ClientContact::factory()->create([
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'first_name' => 'Bob',
|
||||
'last_name' => 'Doe',
|
||||
'email' => 'bob@example.com',
|
||||
]);
|
||||
|
||||
$el = new EntityLevel();
|
||||
$validation = $el->checkClient($client);
|
||||
|
||||
$this->assertTrue($validation['passes']);
|
||||
}
|
||||
|
||||
public function testNoBusinessClientNeedsBothVatAndId()
|
||||
{
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $this->account->id,
|
||||
]);
|
||||
|
||||
// NO business with VAT but no id_number (ORG) — should fail
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'classification' => 'business',
|
||||
'vat_number' => 'NO123456789MVA',
|
||||
'id_number' => '',
|
||||
'country_id' => 578,
|
||||
'address1' => '10 Karl Johans gate',
|
||||
'city' => 'Oslo',
|
||||
'state' => 'Oslo',
|
||||
'postal_code' => '0154',
|
||||
]);
|
||||
|
||||
$cc = ClientContact::factory()->create([
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'first_name' => 'Bob',
|
||||
'last_name' => 'Doe',
|
||||
'email' => 'bob@example.com',
|
||||
]);
|
||||
|
||||
$el = new EntityLevel();
|
||||
$validation = $el->checkClient($client);
|
||||
|
||||
$this->assertFalse($validation['passes']);
|
||||
}
|
||||
|
||||
public function testNoBusinessClientPassesWithBoth()
|
||||
{
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $this->account->id,
|
||||
]);
|
||||
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'classification' => 'business',
|
||||
'vat_number' => 'NO123456789MVA',
|
||||
'id_number' => '123456789',
|
||||
'country_id' => 578,
|
||||
'address1' => '10 Karl Johans gate',
|
||||
'city' => 'Oslo',
|
||||
'state' => 'Oslo',
|
||||
'postal_code' => '0154',
|
||||
]);
|
||||
|
||||
$cc = ClientContact::factory()->create([
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'first_name' => 'Bob',
|
||||
'last_name' => 'Doe',
|
||||
'email' => 'bob@example.com',
|
||||
]);
|
||||
|
||||
$el = new EntityLevel();
|
||||
$validation = $el->checkClient($client);
|
||||
|
||||
$this->assertTrue($validation['passes']);
|
||||
}
|
||||
|
||||
public function testBeBusinessClientNeedsBothVatAndId()
|
||||
{
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $this->account->id,
|
||||
]);
|
||||
|
||||
// BE business with VAT but no id_number (EN) — should fail
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'classification' => 'business',
|
||||
'vat_number' => 'BE0123456789',
|
||||
'id_number' => '',
|
||||
'country_id' => 56,
|
||||
'address1' => '10 Rue de la Loi',
|
||||
'city' => 'Brussels',
|
||||
'state' => 'Brussels',
|
||||
'postal_code' => '1000',
|
||||
]);
|
||||
|
||||
$cc = ClientContact::factory()->create([
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'first_name' => 'Bob',
|
||||
'last_name' => 'Doe',
|
||||
'email' => 'bob@example.com',
|
||||
]);
|
||||
|
||||
$el = new EntityLevel();
|
||||
$validation = $el->checkClient($client);
|
||||
|
||||
$this->assertFalse($validation['passes']);
|
||||
}
|
||||
|
||||
public function testBeBusinessClientPassesWithBothValidIdentifiers()
|
||||
{
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $this->account->id,
|
||||
]);
|
||||
|
||||
// BE business with valid VAT and valid id_number (EN) — should pass
|
||||
// 0202239951 is a known valid mod-97 enterprise number
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'classification' => 'business',
|
||||
'vat_number' => 'BE0202239951',
|
||||
'id_number' => '0202239951',
|
||||
'country_id' => 56,
|
||||
'address1' => '10 Rue de la Loi',
|
||||
'city' => 'Brussels',
|
||||
'state' => 'Brussels',
|
||||
'postal_code' => '1000',
|
||||
]);
|
||||
|
||||
$cc = ClientContact::factory()->create([
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'first_name' => 'Bob',
|
||||
'last_name' => 'Doe',
|
||||
'email' => 'bob@example.com',
|
||||
]);
|
||||
|
||||
$el = new EntityLevel();
|
||||
$validation = $el->checkClient($client);
|
||||
|
||||
$this->assertTrue($validation['passes']);
|
||||
}
|
||||
|
||||
public function testBeBusinessClientFailsWithInvalidCheckdigit()
|
||||
{
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $this->account->id,
|
||||
]);
|
||||
|
||||
// 0123456789 fails mod-97 checkdigit
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'classification' => 'business',
|
||||
'vat_number' => 'BE0123456789',
|
||||
'id_number' => '0123456789',
|
||||
'country_id' => 56,
|
||||
'address1' => '10 Rue de la Loi',
|
||||
'city' => 'Brussels',
|
||||
'state' => 'Brussels',
|
||||
'postal_code' => '1000',
|
||||
]);
|
||||
|
||||
$cc = ClientContact::factory()->create([
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'first_name' => 'Bob',
|
||||
'last_name' => 'Doe',
|
||||
'email' => 'bob@example.com',
|
||||
]);
|
||||
|
||||
$el = new EntityLevel();
|
||||
$validation = $el->checkClient($client);
|
||||
|
||||
$this->assertFalse($validation['passes']);
|
||||
}
|
||||
|
||||
public function testBeGovClientPassesWithValidIdentifiers()
|
||||
{
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $this->account->id,
|
||||
]);
|
||||
|
||||
// BE government with valid identifiers — should pass (routing rules say B+G)
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'classification' => 'government',
|
||||
'vat_number' => 'BE0404616494',
|
||||
'id_number' => '0404616494',
|
||||
'country_id' => 56,
|
||||
'address1' => '16 Rue de la Loi',
|
||||
'city' => 'Brussels',
|
||||
'state' => 'Brussels',
|
||||
'postal_code' => '1000',
|
||||
]);
|
||||
|
||||
$cc = ClientContact::factory()->create([
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'first_name' => 'Bob',
|
||||
'last_name' => 'Doe',
|
||||
'email' => 'bob@example.com',
|
||||
]);
|
||||
|
||||
$el = new EntityLevel();
|
||||
$validation = $el->checkClient($client);
|
||||
|
||||
$this->assertTrue($validation['passes']);
|
||||
}
|
||||
|
||||
public function testBeBusinessClientFailsWithNoVat()
|
||||
{
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $this->account->id,
|
||||
]);
|
||||
|
||||
// BE business with id_number but no VAT — should fail
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'classification' => 'business',
|
||||
'vat_number' => '',
|
||||
'id_number' => '0202239951',
|
||||
'country_id' => 56,
|
||||
'address1' => '10 Rue de la Loi',
|
||||
'city' => 'Brussels',
|
||||
'state' => 'Brussels',
|
||||
'postal_code' => '1000',
|
||||
]);
|
||||
|
||||
$cc = ClientContact::factory()->create([
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'first_name' => 'Bob',
|
||||
'last_name' => 'Doe',
|
||||
'email' => 'bob@example.com',
|
||||
]);
|
||||
|
||||
$el = new EntityLevel();
|
||||
$validation = $el->checkClient($client);
|
||||
|
||||
$this->assertFalse($validation['passes']);
|
||||
}
|
||||
|
||||
public function testBeBusinessClientPassesWithPrefixedIdNumber()
|
||||
{
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $this->account->id,
|
||||
]);
|
||||
|
||||
// BE:EN regex allows optional BE prefix on id_number
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'classification' => 'business',
|
||||
'vat_number' => 'BE0471811661',
|
||||
'id_number' => 'BE0471811661',
|
||||
'country_id' => 56,
|
||||
'address1' => '10 Rue de la Loi',
|
||||
'city' => 'Brussels',
|
||||
'state' => 'Brussels',
|
||||
'postal_code' => '1000',
|
||||
]);
|
||||
|
||||
$cc = ClientContact::factory()->create([
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'first_name' => 'Bob',
|
||||
'last_name' => 'Doe',
|
||||
'email' => 'bob@example.com',
|
||||
]);
|
||||
|
||||
$el = new EntityLevel();
|
||||
$validation = $el->checkClient($client);
|
||||
|
||||
$this->assertTrue($validation['passes']);
|
||||
}
|
||||
|
||||
public function testAtGovClientNeedsIdNumber()
|
||||
{
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $this->account->id,
|
||||
]);
|
||||
|
||||
// AT government with no id_number (AT:GOV) — should fail
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'classification' => 'government',
|
||||
'vat_number' => 'ATU12345678',
|
||||
'id_number' => '',
|
||||
'country_id' => 40,
|
||||
'address1' => '10 Ballhausplatz',
|
||||
'city' => 'Vienna',
|
||||
'state' => 'Vienna',
|
||||
'postal_code' => '1010',
|
||||
]);
|
||||
|
||||
$cc = ClientContact::factory()->create([
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'first_name' => 'Bob',
|
||||
'last_name' => 'Doe',
|
||||
'email' => 'bob@example.com',
|
||||
]);
|
||||
|
||||
$el = new EntityLevel();
|
||||
$validation = $el->checkClient($client);
|
||||
|
||||
$this->assertFalse($validation['passes']);
|
||||
}
|
||||
|
||||
public function testIndividualClientSkipsIdentifierValidation()
|
||||
{
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $this->account->id,
|
||||
]);
|
||||
|
||||
// SE individual with no VAT or id_number — should fail
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'classification' => 'individual',
|
||||
'vat_number' => '',
|
||||
'id_number' => '',
|
||||
'country_id' => 752,
|
||||
'address1' => '10 Wallaby Way',
|
||||
'city' => 'Stockholm',
|
||||
'state' => 'Stockholm',
|
||||
'postal_code' => '11122',
|
||||
]);
|
||||
|
||||
$cc = ClientContact::factory()->create([
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'first_name' => 'Bob',
|
||||
'last_name' => 'Doe',
|
||||
'email' => 'bob@example.com',
|
||||
]);
|
||||
|
||||
$el = new EntityLevel();
|
||||
$validation = $el->checkClient($client);
|
||||
|
||||
$this->assertFalse($validation['passes']);
|
||||
}
|
||||
|
||||
public function testDeGovClientNeedsIdNumber()
|
||||
{
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $this->account->id,
|
||||
]);
|
||||
|
||||
// DE government with no id_number (LWID) — should fail
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'classification' => 'government',
|
||||
'vat_number' => 'DE123456789',
|
||||
'id_number' => '',
|
||||
'country_id' => 276,
|
||||
'address1' => '10 Unter den Linden',
|
||||
'city' => 'Berlin',
|
||||
'state' => 'Berlin',
|
||||
'postal_code' => '10117',
|
||||
]);
|
||||
|
||||
$cc = ClientContact::factory()->create([
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'first_name' => 'Bob',
|
||||
'last_name' => 'Doe',
|
||||
'email' => 'bob@example.com',
|
||||
]);
|
||||
|
||||
$el = new EntityLevel();
|
||||
$validation = $el->checkClient($client);
|
||||
|
||||
$this->assertFalse($validation['passes']);
|
||||
}
|
||||
// public function testInValidBusinessClientNoVat()
|
||||
// {
|
||||
|
||||
// $company = Company::factory()->create([
|
||||
// 'account_id' => $this->account->id,
|
||||
// ]);
|
||||
|
||||
// $client = Client::factory()->create([
|
||||
// 'user_id' => $this->user->id,
|
||||
// 'company_id' => $company->id,
|
||||
// 'classification' => 'business',
|
||||
// 'vat_number' => '',
|
||||
// 'country_id' => 276,
|
||||
// 'address1' => '10 Wallaby Way',
|
||||
// 'address2' => '',
|
||||
// 'city' => 'Sydney',
|
||||
// 'state' => 'NSW',
|
||||
// 'postal_code' => '2113',
|
||||
// ]);
|
||||
|
||||
|
||||
// $cc = ClientContact::factory()->create([
|
||||
// 'client_id' => $client->id,
|
||||
// 'user_id' => $this->user->id,
|
||||
// 'company_id' => $company->id,
|
||||
// 'first_name' => 'Bob',
|
||||
// 'last_name' => 'Doe',
|
||||
// 'email' => 'wasa@b.com',
|
||||
// ]);
|
||||
|
||||
// $el = new EntityLevel();
|
||||
// $validation = $el->checkClient($client);
|
||||
|
||||
// $this->assertEquals(0, strlen($client->vat_number));
|
||||
|
||||
// $this->assertFalse($validation['passes']);
|
||||
|
||||
// }
|
||||
|
||||
// // public function testSeBusinessClientNeedsBothVatAndId()
|
||||
// // {
|
||||
// // $company = Company::factory()->create([
|
||||
// // 'account_id' => $this->account->id,
|
||||
// // ]);
|
||||
|
||||
// // // SE business with VAT but no id_number — should fail
|
||||
// // $client = Client::factory()->create([
|
||||
// // 'user_id' => $this->user->id,
|
||||
// // 'company_id' => $company->id,
|
||||
// // 'classification' => 'business',
|
||||
// // 'vat_number' => 'SE123456789012',
|
||||
// // 'id_number' => '',
|
||||
// // 'country_id' => 752,
|
||||
// // 'address1' => '10 Wallaby Way',
|
||||
// // 'city' => 'Stockholm',
|
||||
// // 'state' => 'Stockholm',
|
||||
// // 'postal_code' => '11122',
|
||||
// // ]);
|
||||
|
||||
// // $cc = ClientContact::factory()->create([
|
||||
// // 'client_id' => $client->id,
|
||||
// // 'user_id' => $this->user->id,
|
||||
// // 'company_id' => $company->id,
|
||||
// // 'first_name' => 'Bob',
|
||||
// // 'last_name' => 'Doe',
|
||||
// // 'email' => 'bob@example.com',
|
||||
// // ]);
|
||||
|
||||
// // $el = new EntityLevel();
|
||||
// // $validation = $el->checkClient($client);
|
||||
|
||||
// // $this->assertFalse($validation['passes']);
|
||||
// // }
|
||||
|
||||
// // public function testSeBusinessClientPassesWithBoth()
|
||||
// // {
|
||||
// // $company = Company::factory()->create([
|
||||
// // 'account_id' => $this->account->id,
|
||||
// // ]);
|
||||
|
||||
// // $client = Client::factory()->create([
|
||||
// // 'user_id' => $this->user->id,
|
||||
// // 'company_id' => $company->id,
|
||||
// // 'classification' => 'business',
|
||||
// // 'vat_number' => 'SE123456789012',
|
||||
// // 'id_number' => '5567891234',
|
||||
// // 'country_id' => 752,
|
||||
// // 'address1' => '10 Wallaby Way',
|
||||
// // 'city' => 'Stockholm',
|
||||
// // 'state' => 'Stockholm',
|
||||
// // 'postal_code' => '11122',
|
||||
// // ]);
|
||||
|
||||
// // $cc = ClientContact::factory()->create([
|
||||
// // 'client_id' => $client->id,
|
||||
// // 'user_id' => $this->user->id,
|
||||
// // 'company_id' => $company->id,
|
||||
// // 'first_name' => 'Bob',
|
||||
// // 'last_name' => 'Doe',
|
||||
// // 'email' => 'bob@example.com',
|
||||
// // ]);
|
||||
|
||||
// // $el = new EntityLevel();
|
||||
// // $validation = $el->checkClient($client);
|
||||
|
||||
// // $this->assertTrue($validation['passes']);
|
||||
// // }
|
||||
|
||||
// // public function testNoBusinessClientNeedsBothVatAndId()
|
||||
// // {
|
||||
// // $company = Company::factory()->create([
|
||||
// // 'account_id' => $this->account->id,
|
||||
// // ]);
|
||||
|
||||
// // // NO business with VAT but no id_number (ORG) — should fail
|
||||
// // $client = Client::factory()->create([
|
||||
// // 'user_id' => $this->user->id,
|
||||
// // 'company_id' => $company->id,
|
||||
// // 'classification' => 'business',
|
||||
// // 'vat_number' => 'NO123456789MVA',
|
||||
// // 'id_number' => '',
|
||||
// // 'country_id' => 578,
|
||||
// // 'address1' => '10 Karl Johans gate',
|
||||
// // 'city' => 'Oslo',
|
||||
// // 'state' => 'Oslo',
|
||||
// // 'postal_code' => '0154',
|
||||
// // ]);
|
||||
|
||||
// // $cc = ClientContact::factory()->create([
|
||||
// // 'client_id' => $client->id,
|
||||
// // 'user_id' => $this->user->id,
|
||||
// // 'company_id' => $company->id,
|
||||
// // 'first_name' => 'Bob',
|
||||
// // 'last_name' => 'Doe',
|
||||
// // 'email' => 'bob@example.com',
|
||||
// // ]);
|
||||
|
||||
// // $el = new EntityLevel();
|
||||
// // $validation = $el->checkClient($client);
|
||||
|
||||
// // $this->assertFalse($validation['passes']);
|
||||
// // }
|
||||
|
||||
// // public function testNoBusinessClientPassesWithBoth()
|
||||
// // {
|
||||
// // $company = Company::factory()->create([
|
||||
// // 'account_id' => $this->account->id,
|
||||
// // ]);
|
||||
|
||||
// // $client = Client::factory()->create([
|
||||
// // 'user_id' => $this->user->id,
|
||||
// // 'company_id' => $company->id,
|
||||
// // 'classification' => 'business',
|
||||
// // 'vat_number' => 'NO123456789MVA',
|
||||
// // 'id_number' => '123456789',
|
||||
// // 'country_id' => 578,
|
||||
// // 'address1' => '10 Karl Johans gate',
|
||||
// // 'city' => 'Oslo',
|
||||
// // 'state' => 'Oslo',
|
||||
// // 'postal_code' => '0154',
|
||||
// // ]);
|
||||
|
||||
// // $cc = ClientContact::factory()->create([
|
||||
// // 'client_id' => $client->id,
|
||||
// // 'user_id' => $this->user->id,
|
||||
// // 'company_id' => $company->id,
|
||||
// // 'first_name' => 'Bob',
|
||||
// // 'last_name' => 'Doe',
|
||||
// // 'email' => 'bob@example.com',
|
||||
// // ]);
|
||||
|
||||
// // $el = new EntityLevel();
|
||||
// // $validation = $el->checkClient($client);
|
||||
|
||||
// // $this->assertTrue($validation['passes']);
|
||||
// // }
|
||||
|
||||
// // public function testBeBusinessClientNeedsBothVatAndId()
|
||||
// // {
|
||||
// // $company = Company::factory()->create([
|
||||
// // 'account_id' => $this->account->id,
|
||||
// // ]);
|
||||
|
||||
// // // BE business with VAT but no id_number (EN) — should fail
|
||||
// // $client = Client::factory()->create([
|
||||
// // 'user_id' => $this->user->id,
|
||||
// // 'company_id' => $company->id,
|
||||
// // 'classification' => 'business',
|
||||
// // 'vat_number' => 'BE0123456789',
|
||||
// // 'id_number' => '',
|
||||
// // 'country_id' => 56,
|
||||
// // 'address1' => '10 Rue de la Loi',
|
||||
// // 'city' => 'Brussels',
|
||||
// // 'state' => 'Brussels',
|
||||
// // 'postal_code' => '1000',
|
||||
// // ]);
|
||||
|
||||
// // $cc = ClientContact::factory()->create([
|
||||
// // 'client_id' => $client->id,
|
||||
// // 'user_id' => $this->user->id,
|
||||
// // 'company_id' => $company->id,
|
||||
// // 'first_name' => 'Bob',
|
||||
// // 'last_name' => 'Doe',
|
||||
// // 'email' => 'bob@example.com',
|
||||
// // ]);
|
||||
|
||||
// // $el = new EntityLevel();
|
||||
// // $validation = $el->checkClient($client);
|
||||
|
||||
// // $this->assertFalse($validation['passes']);
|
||||
// // }
|
||||
|
||||
// // public function testBeBusinessClientPassesWithBothValidIdentifiers()
|
||||
// // {
|
||||
// // $company = Company::factory()->create([
|
||||
// // 'account_id' => $this->account->id,
|
||||
// // ]);
|
||||
|
||||
// // // BE business with valid VAT and valid id_number (EN) — should pass
|
||||
// // // 0202239951 is a known valid mod-97 enterprise number
|
||||
// // $client = Client::factory()->create([
|
||||
// // 'user_id' => $this->user->id,
|
||||
// // 'company_id' => $company->id,
|
||||
// // 'classification' => 'business',
|
||||
// // 'vat_number' => 'BE0202239951',
|
||||
// // 'id_number' => '0202239951',
|
||||
// // 'country_id' => 56,
|
||||
// // 'address1' => '10 Rue de la Loi',
|
||||
// // 'city' => 'Brussels',
|
||||
// // 'state' => 'Brussels',
|
||||
// // 'postal_code' => '1000',
|
||||
// // ]);
|
||||
|
||||
// // $cc = ClientContact::factory()->create([
|
||||
// // 'client_id' => $client->id,
|
||||
// // 'user_id' => $this->user->id,
|
||||
// // 'company_id' => $company->id,
|
||||
// // 'first_name' => 'Bob',
|
||||
// // 'last_name' => 'Doe',
|
||||
// // 'email' => 'bob@example.com',
|
||||
// // ]);
|
||||
|
||||
// // $el = new EntityLevel();
|
||||
// // $validation = $el->checkClient($client);
|
||||
|
||||
// // $this->assertTrue($validation['passes']);
|
||||
// // }
|
||||
|
||||
// public function testBeBusinessClientFailsWithInvalidCheckdigit()
|
||||
// {
|
||||
// $company = Company::factory()->create([
|
||||
// 'account_id' => $this->account->id,
|
||||
// ]);
|
||||
|
||||
// // 0123456789 fails mod-97 checkdigit
|
||||
// $client = Client::factory()->create([
|
||||
// 'user_id' => $this->user->id,
|
||||
// 'company_id' => $company->id,
|
||||
// 'classification' => 'business',
|
||||
// 'vat_number' => 'BE0123456789',
|
||||
// 'id_number' => '0123456789',
|
||||
// 'country_id' => 56,
|
||||
// 'address1' => '10 Rue de la Loi',
|
||||
// 'city' => 'Brussels',
|
||||
// 'state' => 'Brussels',
|
||||
// 'postal_code' => '1000',
|
||||
// ]);
|
||||
|
||||
// $cc = ClientContact::factory()->create([
|
||||
// 'client_id' => $client->id,
|
||||
// 'user_id' => $this->user->id,
|
||||
// 'company_id' => $company->id,
|
||||
// 'first_name' => 'Bob',
|
||||
// 'last_name' => 'Doe',
|
||||
// 'email' => 'bob@example.com',
|
||||
// ]);
|
||||
|
||||
// $el = new EntityLevel();
|
||||
// $validation = $el->checkClient($client);
|
||||
|
||||
// $this->assertFalse($validation['passes']);
|
||||
// }
|
||||
|
||||
// public function testBeGovClientPassesWithValidIdentifiers()
|
||||
// {
|
||||
// $company = Company::factory()->create([
|
||||
// 'account_id' => $this->account->id,
|
||||
// ]);
|
||||
|
||||
// // BE government with valid identifiers — should pass (routing rules say B+G)
|
||||
// $client = Client::factory()->create([
|
||||
// 'user_id' => $this->user->id,
|
||||
// 'company_id' => $company->id,
|
||||
// 'classification' => 'government',
|
||||
// 'vat_number' => 'BE0404616494',
|
||||
// 'id_number' => '0404616494',
|
||||
// 'country_id' => 56,
|
||||
// 'address1' => '16 Rue de la Loi',
|
||||
// 'city' => 'Brussels',
|
||||
// 'state' => 'Brussels',
|
||||
// 'postal_code' => '1000',
|
||||
// ]);
|
||||
|
||||
// $cc = ClientContact::factory()->create([
|
||||
// 'client_id' => $client->id,
|
||||
// 'user_id' => $this->user->id,
|
||||
// 'company_id' => $company->id,
|
||||
// 'first_name' => 'Bob',
|
||||
// 'last_name' => 'Doe',
|
||||
// 'email' => 'bob@example.com',
|
||||
// ]);
|
||||
|
||||
// $el = new EntityLevel();
|
||||
// $validation = $el->checkClient($client);
|
||||
|
||||
// $this->assertTrue($validation['passes']);
|
||||
// }
|
||||
|
||||
// public function testBeBusinessClientFailsWithNoVat()
|
||||
// {
|
||||
// $company = Company::factory()->create([
|
||||
// 'account_id' => $this->account->id,
|
||||
// ]);
|
||||
|
||||
// // BE business with id_number but no VAT — should fail
|
||||
// $client = Client::factory()->create([
|
||||
// 'user_id' => $this->user->id,
|
||||
// 'company_id' => $company->id,
|
||||
// 'classification' => 'business',
|
||||
// 'vat_number' => '',
|
||||
// 'id_number' => '0202239951',
|
||||
// 'country_id' => 56,
|
||||
// 'address1' => '10 Rue de la Loi',
|
||||
// 'city' => 'Brussels',
|
||||
// 'state' => 'Brussels',
|
||||
// 'postal_code' => '1000',
|
||||
// ]);
|
||||
|
||||
// $cc = ClientContact::factory()->create([
|
||||
// 'client_id' => $client->id,
|
||||
// 'user_id' => $this->user->id,
|
||||
// 'company_id' => $company->id,
|
||||
// 'first_name' => 'Bob',
|
||||
// 'last_name' => 'Doe',
|
||||
// 'email' => 'bob@example.com',
|
||||
// ]);
|
||||
|
||||
// $el = new EntityLevel();
|
||||
// $validation = $el->checkClient($client);
|
||||
|
||||
// $this->assertFalse($validation['passes']);
|
||||
// }
|
||||
|
||||
// public function testBeBusinessClientPassesWithPrefixedIdNumber()
|
||||
// {
|
||||
// $company = Company::factory()->create([
|
||||
// 'account_id' => $this->account->id,
|
||||
// ]);
|
||||
|
||||
// // BE:EN regex allows optional BE prefix on id_number
|
||||
// $client = Client::factory()->create([
|
||||
// 'user_id' => $this->user->id,
|
||||
// 'company_id' => $company->id,
|
||||
// 'classification' => 'business',
|
||||
// 'vat_number' => 'BE0471811661',
|
||||
// 'id_number' => 'BE0471811661',
|
||||
// 'country_id' => 56,
|
||||
// 'address1' => '10 Rue de la Loi',
|
||||
// 'city' => 'Brussels',
|
||||
// 'state' => 'Brussels',
|
||||
// 'postal_code' => '1000',
|
||||
// ]);
|
||||
|
||||
// $cc = ClientContact::factory()->create([
|
||||
// 'client_id' => $client->id,
|
||||
// 'user_id' => $this->user->id,
|
||||
// 'company_id' => $company->id,
|
||||
// 'first_name' => 'Bob',
|
||||
// 'last_name' => 'Doe',
|
||||
// 'email' => 'bob@example.com',
|
||||
// ]);
|
||||
|
||||
// $el = new EntityLevel();
|
||||
// $validation = $el->checkClient($client);
|
||||
|
||||
// $this->assertTrue($validation['passes']);
|
||||
// }
|
||||
|
||||
// public function testAtGovClientNeedsIdNumber()
|
||||
// {
|
||||
// $company = Company::factory()->create([
|
||||
// 'account_id' => $this->account->id,
|
||||
// ]);
|
||||
|
||||
// // AT government with no id_number (AT:GOV) — should fail
|
||||
// $client = Client::factory()->create([
|
||||
// 'user_id' => $this->user->id,
|
||||
// 'company_id' => $company->id,
|
||||
// 'classification' => 'government',
|
||||
// 'vat_number' => 'ATU12345678',
|
||||
// 'id_number' => '',
|
||||
// 'country_id' => 40,
|
||||
// 'address1' => '10 Ballhausplatz',
|
||||
// 'city' => 'Vienna',
|
||||
// 'state' => 'Vienna',
|
||||
// 'postal_code' => '1010',
|
||||
// ]);
|
||||
|
||||
// $cc = ClientContact::factory()->create([
|
||||
// 'client_id' => $client->id,
|
||||
// 'user_id' => $this->user->id,
|
||||
// 'company_id' => $company->id,
|
||||
// 'first_name' => 'Bob',
|
||||
// 'last_name' => 'Doe',
|
||||
// 'email' => 'bob@example.com',
|
||||
// ]);
|
||||
|
||||
// $el = new EntityLevel();
|
||||
// $validation = $el->checkClient($client);
|
||||
|
||||
// $this->assertFalse($validation['passes']);
|
||||
// }
|
||||
|
||||
// public function testIndividualClientSkipsIdentifierValidation()
|
||||
// {
|
||||
// $company = Company::factory()->create([
|
||||
// 'account_id' => $this->account->id,
|
||||
// ]);
|
||||
|
||||
// // SE individual with no VAT or id_number — should fail
|
||||
// $client = Client::factory()->create([
|
||||
// 'user_id' => $this->user->id,
|
||||
// 'company_id' => $company->id,
|
||||
// 'classification' => 'individual',
|
||||
// 'vat_number' => '',
|
||||
// 'id_number' => '',
|
||||
// 'country_id' => 752,
|
||||
// 'address1' => '10 Wallaby Way',
|
||||
// 'city' => 'Stockholm',
|
||||
// 'state' => 'Stockholm',
|
||||
// 'postal_code' => '11122',
|
||||
// ]);
|
||||
|
||||
// $cc = ClientContact::factory()->create([
|
||||
// 'client_id' => $client->id,
|
||||
// 'user_id' => $this->user->id,
|
||||
// 'company_id' => $company->id,
|
||||
// 'first_name' => 'Bob',
|
||||
// 'last_name' => 'Doe',
|
||||
// 'email' => 'bob@example.com',
|
||||
// ]);
|
||||
|
||||
// $el = new EntityLevel();
|
||||
// $validation = $el->checkClient($client);
|
||||
|
||||
// $this->assertFalse($validation['passes']);
|
||||
// }
|
||||
|
||||
// public function testDeGovClientNeedsIdNumber()
|
||||
// {
|
||||
// $company = Company::factory()->create([
|
||||
// 'account_id' => $this->account->id,
|
||||
// ]);
|
||||
|
||||
// // DE government with no id_number (LWID) — should fail
|
||||
// $client = Client::factory()->create([
|
||||
// 'user_id' => $this->user->id,
|
||||
// 'company_id' => $company->id,
|
||||
// 'classification' => 'government',
|
||||
// 'vat_number' => 'DE123456789',
|
||||
// 'id_number' => '',
|
||||
// 'country_id' => 276,
|
||||
// 'address1' => '10 Unter den Linden',
|
||||
// 'city' => 'Berlin',
|
||||
// 'state' => 'Berlin',
|
||||
// 'postal_code' => '10117',
|
||||
// ]);
|
||||
|
||||
// $cc = ClientContact::factory()->create([
|
||||
// 'client_id' => $client->id,
|
||||
// 'user_id' => $this->user->id,
|
||||
// 'company_id' => $company->id,
|
||||
// 'first_name' => 'Bob',
|
||||
// 'last_name' => 'Doe',
|
||||
// 'email' => 'bob@example.com',
|
||||
// ]);
|
||||
|
||||
// $el = new EntityLevel();
|
||||
// $validation = $el->checkClient($client);
|
||||
|
||||
// $this->assertFalse($validation['passes']);
|
||||
// }
|
||||
}
|
||||
|
||||
1586
tests/Unit/Chart/AnalyticsQueriesTest.php
Normal file
1586
tests/Unit/Chart/AnalyticsQueriesTest.php
Normal file
File diff suppressed because it is too large
Load Diff
141
tests/Unit/WhiteLabelRenewalTest.php
Normal file
141
tests/Unit/WhiteLabelRenewalTest.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2026. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace Tests\Unit;
|
||||
|
||||
use App\Models\Account;
|
||||
use App\Services\License\WhiteLabelRenewalService;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Http\Client\ConnectionException;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
|
||||
class WhiteLabelRenewalTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
use MockAccountData;
|
||||
|
||||
private WhiteLabelRenewalService $service;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->makeTestData();
|
||||
$this->service = new WhiteLabelRenewalService();
|
||||
}
|
||||
|
||||
public function testRenewedLicenseUpdatesAccount(): void
|
||||
{
|
||||
config(['ninja.license_key' => 'v5_test_license_key']);
|
||||
|
||||
$account = $this->account;
|
||||
$account->plan = Account::PLAN_WHITE_LABEL;
|
||||
$account->plan_expires = now()->subDay()->format('Y-m-d');
|
||||
$account->save();
|
||||
|
||||
$futureDate = now()->addYear()->format('Y-m-d');
|
||||
|
||||
Http::fake([
|
||||
'*/claim_license*' => Http::response(['expires' => $futureDate], 200),
|
||||
]);
|
||||
|
||||
$result = $this->service->checkAndRenew($account);
|
||||
|
||||
$this->assertTrue($result);
|
||||
|
||||
$account->refresh();
|
||||
$this->assertEquals(Account::PLAN_WHITE_LABEL, $account->plan);
|
||||
$this->assertEquals($futureDate, $account->plan_expires);
|
||||
$this->assertEquals(Account::PLAN_TERM_YEARLY, $account->plan_term);
|
||||
}
|
||||
|
||||
public function testNotRenewedLicenseReturnsFalse(): void
|
||||
{
|
||||
config(['ninja.license_key' => 'v5_test_license_key']);
|
||||
|
||||
$account = $this->account;
|
||||
$account->plan = Account::PLAN_WHITE_LABEL;
|
||||
$account->plan_expires = now()->subDay()->format('Y-m-d');
|
||||
$account->save();
|
||||
|
||||
Http::fake([
|
||||
'*/claim_license*' => Http::response(['message' => 'Invalid license'], 400),
|
||||
]);
|
||||
|
||||
$result = $this->service->checkAndRenew($account);
|
||||
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
public function testNetworkErrorReturnsNull(): void
|
||||
{
|
||||
config(['ninja.license_key' => 'v5_test_license_key']);
|
||||
|
||||
$account = $this->account;
|
||||
$account->plan = Account::PLAN_WHITE_LABEL;
|
||||
$account->plan_expires = now()->subDay()->format('Y-m-d');
|
||||
$account->save();
|
||||
|
||||
Http::fake([
|
||||
'*/claim_license*' => fn () => throw new ConnectionException('Connection timed out'),
|
||||
]);
|
||||
|
||||
$result = $this->service->checkAndRenew($account);
|
||||
|
||||
$this->assertNull($result);
|
||||
|
||||
$account->refresh();
|
||||
$this->assertEquals(Account::PLAN_WHITE_LABEL, $account->plan);
|
||||
}
|
||||
|
||||
public function testNoLicenseKeyReturnsFalse(): void
|
||||
{
|
||||
config(['ninja.license_key' => false]);
|
||||
|
||||
$account = $this->account;
|
||||
$account->plan = Account::PLAN_WHITE_LABEL;
|
||||
$account->plan_expires = now()->subDay()->format('Y-m-d');
|
||||
$account->save();
|
||||
|
||||
Http::fake();
|
||||
|
||||
$result = $this->service->checkAndRenew($account);
|
||||
|
||||
$this->assertFalse($result);
|
||||
|
||||
Http::assertNothingSent();
|
||||
}
|
||||
|
||||
public function testExpiredRenewalDateReturnsFalse(): void
|
||||
{
|
||||
config(['ninja.license_key' => 'v5_test_license_key']);
|
||||
|
||||
$account = $this->account;
|
||||
$account->plan = Account::PLAN_WHITE_LABEL;
|
||||
$account->plan_expires = now()->subDay()->format('Y-m-d');
|
||||
$account->save();
|
||||
|
||||
$pastDate = now()->subMonth()->format('Y-m-d');
|
||||
|
||||
Http::fake([
|
||||
'*/claim_license*' => Http::response(['expires' => $pastDate], 200),
|
||||
]);
|
||||
|
||||
$result = $this->service->checkAndRenew($account);
|
||||
|
||||
$this->assertFalse($result);
|
||||
|
||||
$account->refresh();
|
||||
$this->assertEquals(Account::PLAN_WHITE_LABEL, $account->plan);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user