2010-04-25 14:19:58 +00:00
|
|
|
<?php
|
2015-01-06 16:54:36 +00:00
|
|
|
/* Copyright (C) 2010-2012 Laurent Destailleur <eldy@users.sourceforge.net>
|
2018-10-27 12:43:12 +00:00
|
|
|
* Copyright (C) 2011-2012 Regis Houssin <regis.houssin@inodbox.com>
|
2026-07-30 15:09:34 +00:00
|
|
|
* Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
|
2026-07-01 17:22:08 +00:00
|
|
|
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
|
FIX #37658 - Add unit tests for TTC unit price rounding and add fixes for others objects (proposals, orders, invoices and contracts) (#39055)
* Test: add unit tests for TTC unit price rounding (#37658)
Covers the "unit price entered including tax" workflow (subtotal title, product
line, free line, no-op update, discount on all lines) for sale/purchase objects,
checking totals and that each line keeps its typed TTC value (subprice_ttc).
* Test - Make TTC rounding test portable across versions (guard subtotal step with method_exists)
* Test - Use non-deprecated module names in isModEnabled (order/invoice/contract)
* Fix #37658 Persist TTC unit price entry mode on order/invoice/contract and supplier proposal
A line entered with the unit price including tax keeps its typed value (subprice_ttc) and
computes totals from it, avoiding a 0.01 rounding drift on create, no-op edit and bulk actions.
Moves wasEnteredIncludingTax() to CommonObjectLine.
* Cast unit price to float on supplier proposal updateline (phan)
* FIX #37658 Preserve TTC unit price entry mode on clone (createFromClone)
* Pass socid (not object id) to SupplierProposal::createFromClone in TTC clone test
* Preserve TTC unit price entry mode on origin conversion and credit note
* Fix phan: cast pu_ht to float for Contrat::defineBuyPrice() argument
* Preserve TTC unit price entry mode on supplier order, invoice and proposal (socle, clone, conversion, line edit and bulk actions)
* Fix cast ht to float for CommandeFournisseur::updateline() argument
* Fix cast subprice_ttc to float in ContratLigne::update SQL (phan SqlInjection)
* Add TTC round-of-total stability tests
Cover MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND=1 (and _SUPPLIER=1) on fresh
customer and supplier objects with mixed HT/TTC lines: create, no-op,
clone and discount must not drift and must keep the entry mode.
* Preserve TTC entry mode when creating a contract from origin
* Add getPriceBaseType() and preserve TTC entry mode on proposal from origin
---------
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-08-11 17:48:40 +00:00
|
|
|
* Copyright (C) 2026 Lionel Vessiller <lvessiller@open-dsi.fr>
|
2010-04-26 23:52:51 +00:00
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
2013-01-16 14:36:08 +00:00
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
2010-04-26 23:52:51 +00:00
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2019-09-23 19:55:30 +00:00
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
* or see https://www.gnu.org/
|
2010-04-26 23:52:51 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/**
|
2025-03-25 17:36:51 +00:00
|
|
|
* \file test/phpunit/AllTests.php
|
2015-01-06 16:54:36 +00:00
|
|
|
* \ingroup test
|
2010-04-26 23:52:51 +00:00
|
|
|
* \brief This file is a test suite to run all unit tests
|
2015-01-06 16:54:36 +00:00
|
|
|
* \remarks To run this script as CLI: phpunit filename.php
|
2010-04-26 23:52:51 +00:00
|
|
|
*/
|
2024-07-13 00:22:26 +00:00
|
|
|
|
2010-04-27 09:05:42 +00:00
|
|
|
print "PHP Version: ".phpversion()."\n";
|
2023-04-11 16:49:15 +00:00
|
|
|
print "Memory limit: ". ini_get('memory_limit')."\n";
|
2010-04-27 09:05:42 +00:00
|
|
|
|
2024-03-11 11:47:53 +00:00
|
|
|
// Workaround for false security issue with main.inc.php on Windows in tests:
|
|
|
|
|
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
|
|
|
|
$_SERVER['PHP_SELF'] = "phpunit";
|
|
|
|
|
}
|
2024-02-21 12:57:05 +00:00
|
|
|
|
2024-07-13 00:22:26 +00:00
|
|
|
if (! defined('NOREQUIREUSER')) {
|
|
|
|
|
define('PHPUNIT_MODE', 1);
|
|
|
|
|
}
|
|
|
|
|
|
2010-04-26 23:20:14 +00:00
|
|
|
global $conf,$user,$langs,$db;
|
2015-01-06 16:54:36 +00:00
|
|
|
//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver
|
2014-05-01 14:38:41 +00:00
|
|
|
//require_once 'PHPUnit/Autoload.php';
|
2026-06-20 06:07:21 +00:00
|
|
|
|
2010-08-15 23:19:46 +00:00
|
|
|
require_once dirname(__FILE__).'/../../htdocs/master.inc.php';
|
2015-12-18 20:56:00 +00:00
|
|
|
print 'DOL_MAIN_URL_ROOT='.DOL_MAIN_URL_ROOT."\n"; // constant will be used by other tests
|
2015-04-19 02:43:28 +00:00
|
|
|
|
2021-01-14 14:09:08 +00:00
|
|
|
if ($langs->defaultlang != 'en_US') {
|
|
|
|
|
print "Error: Default language for company to run tests must be set to en_US or auto. Current is ".$langs->defaultlang."\n";
|
|
|
|
|
exit(1);
|
2012-02-20 00:36:01 +00:00
|
|
|
}
|
2026-06-21 14:52:25 +00:00
|
|
|
if (isModEnabled('debugbar')) {
|
|
|
|
|
print "Error: Debugbar module should not be enabled. It generates troubles in db management.\n";
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
2025-01-15 11:13:23 +00:00
|
|
|
if (!isModEnabled('member')) {
|
2015-12-11 04:08:32 +00:00
|
|
|
print "Error: Module member must be enabled to have significant results.\n";
|
|
|
|
|
exit(1);
|
2015-04-22 19:38:34 +00:00
|
|
|
}
|
2023-02-03 08:29:02 +00:00
|
|
|
if (isModEnabled('ldap')) {
|
2021-01-14 14:09:08 +00:00
|
|
|
print "Error: LDAP module should not be enabled.\n";
|
|
|
|
|
exit(1);
|
2015-10-14 21:50:36 +00:00
|
|
|
}
|
2023-04-15 01:16:53 +00:00
|
|
|
if (isModEnabled('google')) {
|
2021-01-14 14:09:08 +00:00
|
|
|
print "Warning: Google module should not be enabled.\n";
|
2014-05-08 16:09:39 +00:00
|
|
|
}
|
2021-01-14 14:09:08 +00:00
|
|
|
if (empty($user->id)) {
|
|
|
|
|
print "Load permissions for admin user nb 1\n";
|
|
|
|
|
$user->fetch(1);
|
2024-11-13 23:16:43 +00:00
|
|
|
$user->loadRights();
|
2010-04-26 23:52:51 +00:00
|
|
|
}
|
2024-02-19 14:28:21 +00:00
|
|
|
$conf->global->MAIN_DISABLE_ALL_MAILS = 1;
|
|
|
|
|
$conf->global->MAIN_UMASK = '666';
|
2026-06-18 16:40:07 +00:00
|
|
|
$now = dol_now();
|
2010-04-25 14:19:58 +00:00
|
|
|
|
2026-04-20 16:39:37 +00:00
|
|
|
require_once dirname(__FILE__).'/../../htdocs/core/lib/admin.lib.php';
|
2026-04-20 16:22:41 +00:00
|
|
|
dolibarr_set_const($db, 'API_ENABLE_LOGIN_API', 1);
|
|
|
|
|
|
2026-06-21 14:52:25 +00:00
|
|
|
|
2026-06-18 16:40:07 +00:00
|
|
|
dolibarr_set_const($db, 'MAIN_FIRST_REGISTRATION_OK_DATE', dol_print_date($now, 'dayhourlog', 'gmt'));
|
|
|
|
|
dolibarr_set_const($db, 'BLOCKEDLOG_REGISTRATION_NAME', 'MyBigCompanyByPHPUnit');
|
2026-06-19 23:23:21 +00:00
|
|
|
dolibarr_set_const($db, 'BLOCKEDLOG_REGISTRATION_EMAIL', 'mybigcompany@example.com');
|
|
|
|
|
dolibarr_set_const($db, 'MAIN_INFO_SIREN', 'phpunit123');
|
|
|
|
|
dolibarr_set_const($db, 'MAIN_INFO_SIRET', 'phpunit12312345');
|
2026-06-20 01:27:26 +00:00
|
|
|
$sql = "DELETE FROM ".MAIN_DB_PREFIX."const WHERE name = 'blockedlog-1.end'";
|
2026-06-20 00:57:11 +00:00
|
|
|
$db->query($sql);
|
2015-12-19 00:27:19 +00:00
|
|
|
|
2026-06-20 06:07:21 +00:00
|
|
|
// Test there is no webhook enabled
|
|
|
|
|
// TODO
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-04-26 23:20:14 +00:00
|
|
|
/**
|
|
|
|
|
* Class for the All test suite
|
|
|
|
|
*/
|
2011-02-13 10:25:13 +00:00
|
|
|
class AllTests
|
2010-04-26 23:20:14 +00:00
|
|
|
{
|
2021-01-14 14:09:08 +00:00
|
|
|
/**
|
|
|
|
|
* Function suite to make all PHPUnit tests
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public static function suite()
|
|
|
|
|
{
|
|
|
|
|
$suite = new PHPUnit\Framework\TestSuite('PHPUnit Framework');
|
|
|
|
|
|
|
|
|
|
//require_once dirname(__FILE__).'/CoreTest.php';
|
|
|
|
|
//$suite->addTestSuite('CoreTest');
|
|
|
|
|
require_once dirname(__FILE__).'/AdminLibTest.php';
|
|
|
|
|
$suite->addTestSuite('AdminLibTest');
|
|
|
|
|
require_once dirname(__FILE__).'/CompanyLibTest.php';
|
|
|
|
|
$suite->addTestSuite('CompanyLibTest');
|
|
|
|
|
require_once dirname(__FILE__).'/DateLibTest.php';
|
|
|
|
|
$suite->addTestSuite('DateLibTest');
|
|
|
|
|
require_once dirname(__FILE__).'/UtilsTest.php';
|
|
|
|
|
$suite->addTestSuite('UtilsTest');
|
|
|
|
|
require_once dirname(__FILE__).'/LesscTest.php';
|
|
|
|
|
$suite->addTestSuite('LesscTest');
|
|
|
|
|
//require_once dirname(__FILE__).'/DateLibTzFranceTest.php';
|
|
|
|
|
//$suite->addTestSuite('DateLibTzFranceTest');
|
|
|
|
|
require_once dirname(__FILE__).'/MarginsLibTest.php';
|
|
|
|
|
$suite->addTestSuite('MarginsLibTest');
|
2024-06-01 10:02:23 +00:00
|
|
|
require_once dirname(__FILE__).'/FilesLibMoveDirTest.php';
|
|
|
|
|
$suite->addTestSuite('FilesLibMoveDirTest');
|
2021-01-14 14:09:08 +00:00
|
|
|
require_once dirname(__FILE__).'/FilesLibTest.php';
|
|
|
|
|
$suite->addTestSuite('FilesLibTest');
|
|
|
|
|
require_once dirname(__FILE__).'/GetUrlLibTest.php';
|
|
|
|
|
$suite->addTestSuite('GetUrlLibTest');
|
|
|
|
|
require_once dirname(__FILE__).'/JsonLibTest.php';
|
|
|
|
|
$suite->addTestSuite('JsonLibTest');
|
|
|
|
|
require_once dirname(__FILE__).'/ImagesLibTest.php';
|
|
|
|
|
$suite->addTestSuite('ImagesLibTest');
|
|
|
|
|
require_once dirname(__FILE__).'/FunctionsLibTest.php';
|
|
|
|
|
$suite->addTestSuite('FunctionsLibTest');
|
|
|
|
|
require_once dirname(__FILE__).'/Functions2LibTest.php';
|
|
|
|
|
$suite->addTestSuite('Functions2LibTest');
|
2025-08-26 03:27:02 +00:00
|
|
|
require_once dirname(__FILE__).'/FunctionsBELibTest.php';
|
|
|
|
|
$suite->addTestSuite('FunctionsBELibTest');
|
2024-01-27 22:24:01 +00:00
|
|
|
require_once dirname(__FILE__).'/ProfidLibTest.php';
|
2024-01-27 13:09:04 +00:00
|
|
|
$suite->addTestSuite('ProfidLibTest');
|
2021-01-14 14:09:08 +00:00
|
|
|
require_once dirname(__FILE__).'/XCalLibTest.php';
|
|
|
|
|
$suite->addTestSuite('XCalLibTest');
|
|
|
|
|
|
|
|
|
|
require_once dirname(__FILE__).'/SecurityTest.php';
|
|
|
|
|
$suite->addTestSuite('SecurityTest');
|
2024-10-30 18:53:40 +00:00
|
|
|
require_once dirname(__FILE__).'/SecurityGETPOSTTest.php';
|
|
|
|
|
$suite->addTestSuite('SecurityGETPOSTTest');
|
2026-06-20 06:07:21 +00:00
|
|
|
|
2024-12-18 18:00:33 +00:00
|
|
|
require_once dirname(__FILE__).'/SecurityLoginTest.php';
|
|
|
|
|
$suite->addTestSuite('SecurityLoginTest');
|
2021-01-14 14:09:08 +00:00
|
|
|
|
|
|
|
|
require_once dirname(__FILE__).'/UserTest.php';
|
|
|
|
|
$suite->addTestSuite('UserTest');
|
|
|
|
|
require_once dirname(__FILE__).'/UserGroupTest.php';
|
|
|
|
|
$suite->addTestSuite('UserGroupTest');
|
|
|
|
|
|
|
|
|
|
require_once dirname(__FILE__).'/NumberingModulesTest.php';
|
|
|
|
|
$suite->addTestSuite('NumberingModulesTest');
|
2026-08-15 16:22:45 +00:00
|
|
|
require_once dirname(__FILE__).'/CronjobTest.php';
|
|
|
|
|
$suite->addTestSuite('CronjobTest');
|
2021-01-14 14:09:08 +00:00
|
|
|
require_once dirname(__FILE__).'/PgsqlTest.php';
|
|
|
|
|
$suite->addTestSuite('PgsqlTest');
|
|
|
|
|
require_once dirname(__FILE__).'/PdfDocTest.php';
|
|
|
|
|
$suite->addTestSuite('PdfDocTest');
|
|
|
|
|
require_once dirname(__FILE__).'/BuildDocTest.php';
|
|
|
|
|
$suite->addTestSuite('BuildDocTest');
|
2026-07-30 15:09:34 +00:00
|
|
|
require_once dirname(__FILE__).'/CDavLibTest.php';
|
|
|
|
|
$suite->addTestSuite('CDavLibTest');
|
|
|
|
|
require_once dirname(__FILE__).'/DAVLibTest.php';
|
|
|
|
|
$suite->addTestSuite('DAVLibTest');
|
2021-01-14 14:09:08 +00:00
|
|
|
require_once dirname(__FILE__).'/CMailFileTest.php';
|
|
|
|
|
$suite->addTestSuite('CMailFileTest');
|
|
|
|
|
|
|
|
|
|
require_once dirname(__FILE__).'/CommonObjectTest.php';
|
|
|
|
|
$suite->addTestSuite('CommonObjectTest');
|
|
|
|
|
|
2026-08-15 01:04:31 +00:00
|
|
|
require_once dirname(__FILE__).'/ExtraFieldsTest.php';
|
|
|
|
|
$suite->addTestSuite('ExtraFieldsTest');
|
|
|
|
|
|
2021-01-14 14:09:08 +00:00
|
|
|
require_once dirname(__FILE__).'/ActionCommTest.php';
|
|
|
|
|
$suite->addTestSuite('ActionCommTest');
|
|
|
|
|
require_once dirname(__FILE__).'/SocieteTest.php';
|
|
|
|
|
$suite->addTestSuite('SocieteTest');
|
2024-03-24 05:23:56 +00:00
|
|
|
require_once dirname(__FILE__).'/ExpeditionTest.php';
|
2024-03-24 05:31:59 +00:00
|
|
|
$suite->addTestSuite('ExpeditionTest');
|
FIX|Fix some minor issues on Reception and add a new test for it (#26310)
* reception: reOpen: mirror $this->statut in $this->status
$this->statut is the deprecated variable, $this->status should also get
the correct value.
* reception: setDraft: mirror $this->statut in $this->status
$this->statut is the deprecated variable, $this->status should also get
the correct value.
* reception: add missing $weight field
Fix warning:
Undefined property: Reception::$weight
* societe: add country_id field
* reception: use getDolGlobalInt when suitable
Using empty() implies that the value actually exists on the stdClass at
$conf->global, but it's not always the case. getDolGlobalInt will handle
this smoothly by checking first, which solves warnings like those:
Undefined property: stdClass::$STOCK_CALCULATE_ON_RECEPTION
* ReceptionTest: add new test
The test checks the usual workflow of the Reception class, with, on the
one hand, the common CRUD operations:
- create
- fetch
- update
- delete
And on the other hand, the status handling for Reception:
- valid: STATUS_DRAFT -> STATUS_VALID
- setClosed: STATUS_VALID -> STATUS_CLOSED
- reOpen: STATUS_CLOSED -> STATUS_VALID
- setDraft: STATUS_VALID -> STATUS_DRAFT
The stocks lines are not tested yet, and the error cases, like any other
transition not described above, are not tested either. The permissions
for some of the operations are hardcoded for the test and there is no
failure check when the permission is not set yet.
2023-10-21 14:28:30 +00:00
|
|
|
require_once dirname(__FILE__).'/ReceptionTest.php';
|
|
|
|
|
$suite->addTestSuite('ReceptionTest');
|
2021-01-14 14:09:08 +00:00
|
|
|
require_once dirname(__FILE__).'/ContactTest.php';
|
|
|
|
|
$suite->addTestSuite('ContactTest');
|
|
|
|
|
require_once dirname(__FILE__).'/AdherentTest.php';
|
|
|
|
|
$suite->addTestSuite('AdherentTest');
|
|
|
|
|
|
|
|
|
|
require_once dirname(__FILE__).'/ProductTest.php';
|
|
|
|
|
$suite->addTestSuite('ProductTest');
|
|
|
|
|
|
|
|
|
|
require_once dirname(__FILE__).'/PricesTest.php';
|
|
|
|
|
$suite->addTestSuite('PricesTest');
|
NEW: Add phpunit test for Dolresource class (#39520)
* NEW: Add phpunit test for Dolresource class
Add a CRUD test (create/fetch/update/delete) for the Dolresource
class, which had no test coverage yet.
Note: the update() test intentionally does not exercise note_public/
note_private - Dolresource::update()'s SQL UPDATE statement omits
these 2 columns, so changes to them are silently not persisted.
* FIX Dolresource::update() does not persist note_public/note_private
The SQL UPDATE statement was missing these 2 columns while every
other property of the object was included, so changes to a
resource's notes were silently dropped on update. Add them following
the same pattern as the other fields, and extend the phpunit test to
cover it.
* FIX pre-commit PHPStan hook errors on commits with no file in scope
phpstan.neon.dist only analyzes htdocs/ and scripts/, but the
pre-commit wrapper passed every staged file straight to phpstan
regardless of path. A commit touching only files outside that scope
(e.g. test/phpunit/) made phpstan exit with "No files found to
analyse", failing the hook for reasons unrelated to the change being
committed. Filter to htdocs/ and scripts/ first, and skip cleanly
when nothing remains.
* NEW: Auto-activate module resource in DolresourceTest if needed
Activate module resource in setUpBeforeClass() when it is not
already enabled, so the test does not depend on the environment's
module configuration. Same pattern as
OpensurveysondageTest::setUpBeforeClass().
Note: this activation is real and persists after the test run - it
is not undone by the transaction rollback in tearDownAfterClass().
Activating a module re-runs its SQL install scripts (CREATE/ALTER
TABLE), which causes an implicit commit in MySQL/InnoDB, same as an
admin enabling it from Setup > Modules would do.
* fix
2026-08-14 18:31:06 +00:00
|
|
|
|
2021-01-14 14:09:08 +00:00
|
|
|
require_once dirname(__FILE__).'/DiscountTest.php';
|
|
|
|
|
$suite->addTestSuite('DiscountTest');
|
|
|
|
|
|
2026-08-15 14:03:41 +00:00
|
|
|
require_once dirname(__FILE__).'/MultiCurrencyTest.php';
|
|
|
|
|
$suite->addTestSuite('MultiCurrencyTest');
|
|
|
|
|
|
2021-01-14 14:09:08 +00:00
|
|
|
require_once dirname(__FILE__).'/BOMTest.php';
|
|
|
|
|
$suite->addTestSuite('BOMTest');
|
|
|
|
|
|
NEW: Add phpunit test for Mo class (#39535)
* NEW: Add phpunit test for Mo class
Add a unit-level test for the Mo (manufacturing order) class, which
had no direct test coverage yet (RestAPIMoTest.php only exercises
the REST API layer over HTTP, and its most interesting part -
produce/consume - is entirely commented out there).
Covers create() (including the automatic "to produce" line it
creates for the finished product), fetch, update, the
draft -> validated -> canceled -> validated status workflow
(validate/cancel/reopen, including the provisional ref being
replaced on validate()), and delete.
Uses a freshly created specimen Product for fk_product rather than a
random real catalog product: Mo::create() rejects kit/BOM products
unless ALLOW_USE_KITS_INTO_BOM_AND_MO is set, and a specimen product
is guaranteed not to be one.
The module is auto-activated in setUpBeforeClass() if not already
enabled, following the same pattern as the other recently added
tests (activation is real and persists after the test run, it is not
undone by the rollback in tearDownAfterClass - see comment in
setUpBeforeClass() for why).
* FIX MoTest crash in the full test suite (stale $db)
Same class of bug as StockTransferTest (see that commit for the full
analysis): modMrp depends on modBom, which itself depends on
modProduct, whose constructor queries the DB via Societe::useNPR().
If $db is stale/closed when this class's setUpBeforeClass() runs in
the full suite (all classes in one continuous process), activating
modMrp crashes on the dead connection the same way.
Reconnect $db (and refresh $mysoc->db/$user->db, which stashed their
own reference to the old connection at bootstrap) before calling
activateModule(), same pattern as StockTransferTest.
Verified the same way: closing $db and calling
MoTest::setUpBeforeClass() directly reproduces the crash without
this fix and is resolved with it.
* FIX MoTest: resync $mysoc/$user->db unconditionally
Same follow-up fix as StockTransferTest (see that commit for the full
analysis): the previous defensive-reconnect only refreshed
$mysoc->db/$user->db inside the branch where the global $db itself
was detected stale. $mysoc/$user can diverge from a healthy $db
independently (they stash their own ->db reference at bootstrap), so
resync them unconditionally instead.
Verified the same way: closing the original $db but reconnecting only
the global $db variable (leaving $mysoc->db pointing at the closed
one) reproduces the crash with the old code and is resolved with this
fix.
* NEW Centralize the stale-$db reconnect logic in CommonClassTest
Same follow-up as StockTransferTest (#39542): the defensive
reconnect-and-resync-$mysoc/$user logic was duplicated identically
across 3 test classes. Extract it into a shared
CommonClassTest::ensureDbIsConnected() helper so future test classes
that activate a module depending on modProduct don't need to
reimplement it, and so the fix can't drift between test files.
MoTest::setUpBeforeClass() now just calls self::ensureDbIsConnected()
before activateModule().
Re-verified the same way as before: closing the original $db but
reconnecting only the global $db variable (leaving $mysoc->db
pointing at the closed one) still reproduces the crash without this
fix and is resolved with it.
* Remove setUpBeforeClass from MoTest
Removed setUpBeforeClass method to simplify test setup.
* Update CommonClassTest.class.php
---------
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-08-19 00:28:13 +00:00
|
|
|
require_once dirname(__FILE__).'/MoTest.php';
|
|
|
|
|
$suite->addTestSuite('MoTest');
|
|
|
|
|
|
NEW: Add phpunit test for Dolresource class (#39520)
* NEW: Add phpunit test for Dolresource class
Add a CRUD test (create/fetch/update/delete) for the Dolresource
class, which had no test coverage yet.
Note: the update() test intentionally does not exercise note_public/
note_private - Dolresource::update()'s SQL UPDATE statement omits
these 2 columns, so changes to them are silently not persisted.
* FIX Dolresource::update() does not persist note_public/note_private
The SQL UPDATE statement was missing these 2 columns while every
other property of the object was included, so changes to a
resource's notes were silently dropped on update. Add them following
the same pattern as the other fields, and extend the phpunit test to
cover it.
* FIX pre-commit PHPStan hook errors on commits with no file in scope
phpstan.neon.dist only analyzes htdocs/ and scripts/, but the
pre-commit wrapper passed every staged file straight to phpstan
regardless of path. A commit touching only files outside that scope
(e.g. test/phpunit/) made phpstan exit with "No files found to
analyse", failing the hook for reasons unrelated to the change being
committed. Filter to htdocs/ and scripts/ first, and skip cleanly
when nothing remains.
* NEW: Auto-activate module resource in DolresourceTest if needed
Activate module resource in setUpBeforeClass() when it is not
already enabled, so the test does not depend on the environment's
module configuration. Same pattern as
OpensurveysondageTest::setUpBeforeClass().
Note: this activation is real and persists after the test run - it
is not undone by the transaction rollback in tearDownAfterClass().
Activating a module re-runs its SQL install scripts (CREATE/ALTER
TABLE), which causes an implicit commit in MySQL/InnoDB, same as an
admin enabling it from Setup > Modules would do.
* fix
2026-08-14 18:31:06 +00:00
|
|
|
require_once dirname(__FILE__).'/DolresourceTest.php';
|
|
|
|
|
$suite->addTestSuite('DolresourceTest');
|
|
|
|
|
|
2026-08-14 13:56:13 +00:00
|
|
|
require_once dirname(__FILE__).'/WorkstationTest.php';
|
|
|
|
|
$suite->addTestSuite('WorkstationTest');
|
|
|
|
|
|
2026-08-14 12:57:48 +00:00
|
|
|
require_once dirname(__FILE__).'/OpensurveysondageTest.php';
|
|
|
|
|
$suite->addTestSuite('OpensurveysondageTest');
|
|
|
|
|
|
2021-01-14 14:09:08 +00:00
|
|
|
require_once dirname(__FILE__).'/ContratTest.php';
|
|
|
|
|
$suite->addTestSuite('ContratTest');
|
|
|
|
|
|
|
|
|
|
require_once dirname(__FILE__).'/FichinterTest.php';
|
|
|
|
|
$suite->addTestSuite('FichinterTest');
|
|
|
|
|
require_once dirname(__FILE__).'/TicketTest.php';
|
|
|
|
|
$suite->addTestSuite('TicketTest');
|
|
|
|
|
|
|
|
|
|
require_once dirname(__FILE__).'/PropalTest.php';
|
|
|
|
|
$suite->addTestSuite('PropalTest');
|
|
|
|
|
|
|
|
|
|
require_once dirname(__FILE__).'/SupplierProposalTest.php';
|
|
|
|
|
$suite->addTestSuite('SupplierProposalTest');
|
|
|
|
|
|
|
|
|
|
require_once dirname(__FILE__).'/CommandeTest.php';
|
|
|
|
|
$suite->addTestSuite('CommandeTest');
|
|
|
|
|
|
|
|
|
|
require_once dirname(__FILE__).'/CommandeFournisseurTest.php';
|
|
|
|
|
$suite->addTestSuite('CommandeFournisseurTest');
|
|
|
|
|
|
2021-06-22 12:40:48 +00:00
|
|
|
require_once dirname(__FILE__).'/CommonInvoiceTest.php';
|
|
|
|
|
$suite->addTestSuite('CommonInvoiceTest');
|
2021-01-14 14:09:08 +00:00
|
|
|
require_once dirname(__FILE__).'/FactureTest.php';
|
|
|
|
|
$suite->addTestSuite('FactureTest');
|
NEW: Improve phpunit test coverage for Commande, Propal and Facture (#39517)
* NEW: Improve phpunit test coverage for Commande, Propal and Facture
Add line CRUD (addline/updateline/deleteLine) and total-consistency
assertions, reuse the specimen-invariant regression check (previously
only in FactureTest) across all three, and add a new integration test
covering the full Propal -> Commande -> Facture conversion chain
(thirdparty, notes, totals and object_linked propagation).
Two shared assertions were added to CommonClassTest for this:
assertLineTotalsMatchHeader() and assertMatchesFreshSpecimen().
* Update commande.class.php
* FIX PropalCommandeFactureWorkflowTest reads wrong invoice after createFromOrder
Facture::createFromOrder() returns a status flag (1/-1), not the new
invoice id, unlike Commande::createFromProposal(). The test was doing
fetch($result) with $result==1, which happened to no-op locally (no
invoice with rowid=1) but fetched an unrelated invoice in CI, causing
a spurious thirdparty mismatch. Use $facture->id, already set by
create() inside createFromOrder(), like every other caller of this
method does.
2026-08-19 00:35:04 +00:00
|
|
|
require_once dirname(__FILE__).'/PropalCommandeFactureWorkflowTest.php';
|
|
|
|
|
$suite->addTestSuite('PropalCommandeFactureWorkflowTest');
|
2021-01-14 14:09:08 +00:00
|
|
|
require_once dirname(__FILE__).'/FactureRecTest.php';
|
|
|
|
|
$suite->addTestSuite('FactureRecTest');
|
|
|
|
|
require_once dirname(__FILE__).'/FactureTestRounding.php';
|
|
|
|
|
$suite->addTestSuite('FactureTestRounding');
|
FIX #37658 - Add unit tests for TTC unit price rounding and add fixes for others objects (proposals, orders, invoices and contracts) (#39055)
* Test: add unit tests for TTC unit price rounding (#37658)
Covers the "unit price entered including tax" workflow (subtotal title, product
line, free line, no-op update, discount on all lines) for sale/purchase objects,
checking totals and that each line keeps its typed TTC value (subprice_ttc).
* Test - Make TTC rounding test portable across versions (guard subtotal step with method_exists)
* Test - Use non-deprecated module names in isModEnabled (order/invoice/contract)
* Fix #37658 Persist TTC unit price entry mode on order/invoice/contract and supplier proposal
A line entered with the unit price including tax keeps its typed value (subprice_ttc) and
computes totals from it, avoiding a 0.01 rounding drift on create, no-op edit and bulk actions.
Moves wasEnteredIncludingTax() to CommonObjectLine.
* Cast unit price to float on supplier proposal updateline (phan)
* FIX #37658 Preserve TTC unit price entry mode on clone (createFromClone)
* Pass socid (not object id) to SupplierProposal::createFromClone in TTC clone test
* Preserve TTC unit price entry mode on origin conversion and credit note
* Fix phan: cast pu_ht to float for Contrat::defineBuyPrice() argument
* Preserve TTC unit price entry mode on supplier order, invoice and proposal (socle, clone, conversion, line edit and bulk actions)
* Fix cast ht to float for CommandeFournisseur::updateline() argument
* Fix cast subprice_ttc to float in ContratLigne::update SQL (phan SqlInjection)
* Add TTC round-of-total stability tests
Cover MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND=1 (and _SUPPLIER=1) on fresh
customer and supplier objects with mixed HT/TTC lines: create, no-op,
clone and discount must not drift and must keep the entry mode.
* Preserve TTC entry mode when creating a contract from origin
* Add getPriceBaseType() and preserve TTC entry mode on proposal from origin
---------
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-08-11 17:48:40 +00:00
|
|
|
require_once dirname(__FILE__).'/TtcRoundingTest.php';
|
|
|
|
|
$suite->addTestSuite('TtcRoundingTest');
|
2026-07-01 17:22:08 +00:00
|
|
|
require_once dirname(__FILE__).'/PaiementTest.php';
|
|
|
|
|
$suite->addTestSuite('PaiementTest');
|
2026-08-18 23:39:35 +00:00
|
|
|
require_once dirname(__FILE__).'/RemiseChequeTest.php';
|
|
|
|
|
$suite->addTestSuite('RemiseChequeTest');
|
2021-01-14 14:09:08 +00:00
|
|
|
require_once dirname(__FILE__).'/FactureFournisseurTest.php';
|
|
|
|
|
$suite->addTestSuite('FactureFournisseurTest');
|
|
|
|
|
|
|
|
|
|
require_once dirname(__FILE__).'/BankAccountTest.php';
|
|
|
|
|
$suite->addTestSuite('BankAccountTest');
|
|
|
|
|
require_once dirname(__FILE__).'/CompanyBankAccountTest.php';
|
|
|
|
|
$suite->addTestSuite('CompanyBankAccountTest');
|
|
|
|
|
require_once dirname(__FILE__).'/BonPrelevementTest.php';
|
|
|
|
|
$suite->addTestSuite('BonPrelevementTest');
|
|
|
|
|
|
|
|
|
|
require_once dirname(__FILE__).'/ChargeSocialesTest.php';
|
|
|
|
|
$suite->addTestSuite('ChargeSocialesTest');
|
2026-08-18 23:40:33 +00:00
|
|
|
require_once dirname(__FILE__).'/DonTest.php';
|
|
|
|
|
$suite->addTestSuite('DonTest');
|
|
|
|
|
require_once dirname(__FILE__).'/PaymentDonationTest.php';
|
|
|
|
|
$suite->addTestSuite('PaymentDonationTest');
|
2026-08-15 16:21:48 +00:00
|
|
|
require_once dirname(__FILE__).'/PaymentVATTest.php';
|
|
|
|
|
$suite->addTestSuite('PaymentVATTest');
|
2021-01-14 14:09:08 +00:00
|
|
|
require_once dirname(__FILE__).'/HolidayTest.php';
|
|
|
|
|
$suite->addTestSuite('HolidayTest');
|
|
|
|
|
require_once dirname(__FILE__).'/ExpenseReportTest.php';
|
|
|
|
|
$suite->addTestSuite('ExpenseReportTest');
|
|
|
|
|
require_once dirname(__FILE__).'/LoanTest.php';
|
|
|
|
|
$suite->addTestSuite('LoanTest');
|
2026-08-18 23:37:51 +00:00
|
|
|
require_once dirname(__FILE__).'/LoanScheduleTest.php';
|
|
|
|
|
$suite->addTestSuite('LoanScheduleTest');
|
|
|
|
|
require_once dirname(__FILE__).'/PaymentLoanTest.php';
|
|
|
|
|
$suite->addTestSuite('PaymentLoanTest');
|
2021-01-14 14:09:08 +00:00
|
|
|
|
|
|
|
|
require_once dirname(__FILE__).'/EntrepotTest.php';
|
|
|
|
|
$suite->addTestSuite('EntrepotTest');
|
|
|
|
|
require_once dirname(__FILE__).'/MouvementStockTest.php';
|
|
|
|
|
$suite->addTestSuite('MouvementStockTest');
|
2021-06-22 12:40:48 +00:00
|
|
|
require_once dirname(__FILE__).'/InventoryTest.php';
|
|
|
|
|
$suite->addTestSuite('InventoryTest');
|
2021-01-14 14:09:08 +00:00
|
|
|
|
|
|
|
|
require_once dirname(__FILE__).'/CategorieTest.php';
|
|
|
|
|
$suite->addTestSuite('CategorieTest');
|
|
|
|
|
|
NEW Link manage extrafields and phpunit test for the class (#39514)
* NEW: Add extrafields support to Link class
Link now declares isextrafieldmanaged and wires fetch_optionals()/
insertExtraFields()/deleteExtraFields() into fetch(), fetchAll(),
create(), update() and delete(), matching the llx_links_extrafields
table added previously.
* FIX: Several bugs in Link class review
- create(): wrong duplicate-record error message (copy-pasted from
Societe, referenced undefined $this->name) replaced by the generic
ErrorDuplicateField, consistent with update().
- create()/update(): missing "NoURL" translation key replaced by the
standard ErrorFieldRequired pattern.
- fetch(): guard against running an unfiltered query (no rowid, no
hashforshare) that could silently return an arbitrary link; a caller
in actions_linkedfiles.inc.php could hit this when 'linkid' was
missing from the request.
- actions_linkedfiles.inc.php: check fetch() result with `> 0` instead
of a truthy test, since -1 (error) is truthy in PHP.
- delete(): add User type hint (consistent with create()/update()) and
a $notrigger parameter to optionally skip the LINK_DELETE trigger.
- update(): fix copy-pasted docblock ("third party" -> "link").
* NEW: Add PHPUnit test for Link class
Covers create/fetch/update/fetchAll/count/delete, plus regression
tests for the two bugs fixed in the previous commit: create() rejects
an empty url, and fetch() rejects a call with neither rowid nor
hashforshare instead of returning an arbitrary record.
* FIX Phan false positive on $object in actions_linkedfiles.inc.php
Phan's ambient type inference for the loosely-typed global $object in
this shared include file was picking up CommonSocialNetworks (an
unrelated trait, not even a class), reported as undeclared
->id/->entity/->addThumbs()/->delThumbs() in a real CI Phan run on
this branch, once this file was analyzed on its own via the
changed-files file-list (this file has no prior baseline entry, so it
was apparently never previously exercised in isolation like this).
Force $object's type explicitly to CommonObject via the same
@phan-var-force string-literal idiom this file already uses for
$upload_dir/$upload_dirold/$confirm/$forceFullTextIndexation -
CommonObject genuinely declares addThumbs()/delThumbs(), which
resolves those two errors outright. $id/$entity remain reported as
PhanUndeclaredProperty (CommonObject itself does not declare them,
only its concrete subclasses do at runtime) - baseline-suppress that
for this file the same way it is already suppressed for the sibling
shared-include files actions_addupdatedelete.inc.php,
actions_massactions.inc.php and actions_sendmails.inc.php, which have
the exact same $object typing situation.
2026-08-19 00:18:46 +00:00
|
|
|
require_once dirname(__FILE__).'/LinkTest.php';
|
|
|
|
|
$suite->addTestSuite('LinkTest');
|
|
|
|
|
|
2021-06-22 12:40:48 +00:00
|
|
|
require_once dirname(__FILE__).'/ProjectTest.php';
|
|
|
|
|
$suite->addTestSuite('ProjectTest');
|
2026-08-15 14:03:53 +00:00
|
|
|
require_once dirname(__FILE__).'/CommentTest.php';
|
|
|
|
|
$suite->addTestSuite('CommentTest');
|
2021-06-22 12:40:48 +00:00
|
|
|
|
2021-06-22 13:53:14 +00:00
|
|
|
require_once dirname(__FILE__).'/KnowledgeRecordTest.php';
|
2021-06-22 13:46:51 +00:00
|
|
|
$suite->addTestSuite('KnowledgeRecordTest');
|
2021-06-22 12:40:48 +00:00
|
|
|
|
2024-11-24 16:15:25 +00:00
|
|
|
require_once dirname(__FILE__).'/AccountancySystemTest.php';
|
|
|
|
|
$suite->addTestSuite('AccountancySystemTest');
|
|
|
|
|
|
2021-01-14 14:09:08 +00:00
|
|
|
require_once dirname(__FILE__).'/AccountingAccountTest.php';
|
|
|
|
|
$suite->addTestSuite('AccountingAccountTest');
|
2023-09-26 18:52:49 +00:00
|
|
|
require_once dirname(__FILE__).'/AssetModelTest.php';
|
|
|
|
|
$suite->addTestSuite('AssetModelTest');
|
2021-01-14 14:09:08 +00:00
|
|
|
|
2025-11-30 17:37:58 +00:00
|
|
|
require_once dirname(__FILE__).'/BlockedLogAndLNETest.php';
|
|
|
|
|
$suite->addTestSuite('BlockedLogAndLNETest');
|
|
|
|
|
|
2023-03-27 15:37:09 +00:00
|
|
|
// Rest
|
2021-01-14 14:09:08 +00:00
|
|
|
require_once dirname(__FILE__).'/RestAPIUserTest.php';
|
|
|
|
|
$suite->addTestSuite('RestAPIUserTest');
|
2023-09-08 19:12:59 +00:00
|
|
|
require_once dirname(__FILE__).'/RestAPIContactTest.php';
|
|
|
|
|
$suite->addTestSuite('RestAPIContactTest');
|
2021-01-14 14:09:08 +00:00
|
|
|
require_once dirname(__FILE__).'/RestAPIDocumentTest.php';
|
|
|
|
|
$suite->addTestSuite('RestAPIDocumentTest');
|
2025-03-24 20:44:57 +00:00
|
|
|
require_once dirname(__FILE__).'/RestAPIMoTest.php';
|
|
|
|
|
$suite->addTestSuite('RestAPIMoTest');
|
2021-01-14 14:09:08 +00:00
|
|
|
|
|
|
|
|
// Test only with php7.2 or less
|
|
|
|
|
//if ((float) phpversion() < 7.3)
|
|
|
|
|
//{
|
2023-12-04 10:22:28 +00:00
|
|
|
require_once dirname(__FILE__).'/WebservicesProductsTest.php';
|
|
|
|
|
$suite->addTestSuite('WebservicesProductsTest');
|
|
|
|
|
require_once dirname(__FILE__).'/WebservicesInvoicesTest.php';
|
|
|
|
|
$suite->addTestSuite('WebservicesInvoicesTest');
|
|
|
|
|
require_once dirname(__FILE__).'/WebservicesOrdersTest.php';
|
|
|
|
|
$suite->addTestSuite('WebservicesOrdersTest');
|
|
|
|
|
require_once dirname(__FILE__).'/WebservicesOtherTest.php';
|
|
|
|
|
$suite->addTestSuite('WebservicesOtherTest');
|
|
|
|
|
require_once dirname(__FILE__).'/WebservicesThirdpartyTest.php';
|
|
|
|
|
$suite->addTestSuite('WebservicesThirdpartyTest');
|
|
|
|
|
require_once dirname(__FILE__).'/WebservicesUserTest.php';
|
|
|
|
|
$suite->addTestSuite('WebservicesUserTest');
|
2021-01-14 14:09:08 +00:00
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
require_once dirname(__FILE__).'/ExportTest.php';
|
|
|
|
|
$suite->addTestSuite('ExportTest');
|
|
|
|
|
require_once dirname(__FILE__).'/ImportTest.php';
|
|
|
|
|
$suite->addTestSuite('ImportTest');
|
|
|
|
|
|
|
|
|
|
require_once dirname(__FILE__).'/ScriptsTest.php';
|
|
|
|
|
$suite->addTestSuite('ScriptsTest');
|
|
|
|
|
|
|
|
|
|
// GUI
|
|
|
|
|
require_once dirname(__FILE__).'/FormAdminTest.php';
|
|
|
|
|
$suite->addTestSuite('FormAdminTest');
|
|
|
|
|
require_once dirname(__FILE__).'/FormTest.php';
|
|
|
|
|
$suite->addTestSuite('FormTest');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Payment services
|
|
|
|
|
require_once dirname(__FILE__).'/PaypalTest.php';
|
|
|
|
|
$suite->addTestSuite('PaypalTest');
|
|
|
|
|
require_once dirname(__FILE__).'/StripeTest.php';
|
|
|
|
|
$suite->addTestSuite('StripeTest');
|
|
|
|
|
|
2021-06-21 17:47:43 +00:00
|
|
|
// Email collector
|
|
|
|
|
require_once dirname(__FILE__).'/EmailCollectorTest.php';
|
|
|
|
|
$suite->addTestSuite('EmailCollectorTest');
|
|
|
|
|
|
2023-03-27 15:37:09 +00:00
|
|
|
// Website
|
|
|
|
|
require_once dirname(__FILE__).'/WebsiteTest.php';
|
2023-03-28 10:43:45 +00:00
|
|
|
$suite->addTestSuite('WebsiteTest');
|
2023-03-27 15:37:09 +00:00
|
|
|
|
2026-06-21 13:20:14 +00:00
|
|
|
// --- At end because it's the longer
|
|
|
|
|
|
|
|
|
|
// Rules into source files content
|
|
|
|
|
require_once dirname(__FILE__).'/RepositoryTest.php';
|
|
|
|
|
$suite->addTestSuite('RepositoryTest');
|
|
|
|
|
require_once dirname(__FILE__).'/LangTest.php';
|
|
|
|
|
$suite->addTestSuite('LangTest');
|
|
|
|
|
require_once dirname(__FILE__).'/CodingSqlTest.php';
|
|
|
|
|
$suite->addTestSuite('CodingSqlTest');
|
|
|
|
|
require_once dirname(__FILE__).'/CodingPhpTest.php';
|
|
|
|
|
$suite->addTestSuite('CodingPhpTest');
|
|
|
|
|
require_once dirname(__FILE__).'/DoliDBTest.php';
|
|
|
|
|
$suite->addTestSuite('DoliDBTest');
|
|
|
|
|
|
2026-06-21 17:16:53 +00:00
|
|
|
// --- At very end, the LAST ONE.
|
|
|
|
|
|
|
|
|
|
// Also enabling and disabling modules is changing the context and global variables that changes behaviour of previous tests
|
|
|
|
|
// For example, this call init that run DDL functionsand break commit/rollback features.
|
|
|
|
|
require_once dirname(__FILE__).'/ModulesTest.php';
|
|
|
|
|
$suite->addTestSuite('ModulesTest');
|
|
|
|
|
|
2021-01-14 14:09:08 +00:00
|
|
|
return $suite;
|
|
|
|
|
}
|
2010-04-25 14:19:58 +00:00
|
|
|
}
|