<?php
/* Copyright (C) 2010-2012	Laurent Destailleur	<eldy@users.sourceforge.net>
 * Copyright (C) 2012		Regis Houssin		<regis.houssin@inodbox.com>
 * Copyright (C) 2023		Alexandre Janniaux   <alexandre.janniaux@gmail.com>
 * Copyright (C) 2024		MDW							<mdeweerd@users.noreply.github.com>
 * Copyright (C) 2024       Frédéric France         <frederic.france@free.fr>
 *
 * 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
 * the Free Software Foundation; either version 3 of the License, or
 * (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
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 * or see https://www.gnu.org/
 */

/**
 *      \file       test/phpunit/FilesLibTest.php
 *		\ingroup    test
 *      \brief      PHPUnit test
 *		\remarks	To run this script as CLI:  phpunit filename.php
 */

global $conf,$user,$langs,$db;
//define('TEST_DB_FORCE_TYPE','mysql');	// This is to force using mysql driver
//require_once 'PHPUnit/Autoload.php';
require_once dirname(__FILE__).'/../../htdocs/master.inc.php';
require_once dirname(__FILE__).'/../../htdocs/core/lib/files.lib.php';
require_once dirname(__FILE__).'/CommonClassTest.class.php';

if (empty($user->id)) {
	print "Load permissions for admin user nb 1\n";
	$user->fetch(1);
	$user->loadRights();
}
$conf->global->MAIN_DISABLE_ALL_MAILS = 1;


/**
 * Class for PHPUnit tests
 *
 * @backupGlobals disabled
 * @backupStaticAttributes enabled
 * @remarks	backupGlobals must be disabled to have db,conf,user and lang not erased.
 */
class FilesLibTest extends CommonClassTest
{
	/**
	 * testDolBasename
	 *
	 * @return	void
	 */
	public function testDolBasename()
	{
		global $conf,$user,$langs,$db;
		$conf = $this->savconf;
		$user = $this->savuser;
		$langs = $this->savlangs;
		$db = $this->savdb;

		$result = dol_basename('adir/a_file');
		print __METHOD__." result=".$result."\n";
		$this->assertEquals('a_file', $result);

		$result = dol_basename('adir/a_file/');
		print __METHOD__." result=".$result."\n";
		$this->assertEquals('a_file', $result);

		$result = dol_basename('adir/νεο');    // With cyrillic data. Here basename fails to return correct value
		print __METHOD__." result=".$result."\n";
		$this->assertEquals('νεο', $result);

		$result = dol_basename('adir/νεο/');    // With cyrillic data. Here basename fails to return correct value
		print __METHOD__." result=".$result."\n";
		$this->assertEquals('νεο', $result);
	}


	/**
	 * testDolCountNbOfLine
	 *
	 * @return	int
	 */
	public function testDolCountNbOfLine()
	{
		global $conf,$user,$langs,$db;
		$conf = $this->savconf;
		$user = $this->savuser;
		$langs = $this->savlangs;
		$db = $this->savdb;

		$file = dirname(__FILE__).'/file_import_company_1.csv';
		$result = dol_count_nb_of_line($file);
		print __METHOD__." result=".$result."\n";
		$this->assertEquals(3, $result);

		return $result;
	}

	/**
	 * testDolIsFileDir
	 *
	 * @return	int
	 */
	public function testDolIsFileDir()
	{
		global $conf,$user,$langs,$db;
		$conf = $this->savconf;
		$user = $this->savuser;
		$langs = $this->savlangs;
		$db = $this->savdb;

		$file = dirname(__FILE__).'/file_import_company_1.csv';

		$result = dol_is_file($file);
		print __METHOD__." result=".$result."\n";
		$this->assertTrue($result);

		$result = dol_is_dir($file);
		print __METHOD__." result=".$result."\n";
		$this->assertFalse($result);

		return $result;
	}

	/**
	 * testDolOther
	 *
	 * @return boolean
	*/
	public function testDolOther()
	{
		global $conf,$user,$langs,$db;
		$conf = $this->savconf;
		$user = $this->savuser;
		$langs = $this->savlangs;
		$db = $this->savdb;

		$url = 'http://www.dolibarr.org';
		$result = dol_is_url($url);
		print __METHOD__." result=".$result."\n";
		$this->assertTrue($result);

		$url = 'https://www.dolibarr.org';
		$result = dol_is_url($url);
		print __METHOD__." result=".$result."\n";
		$this->assertTrue($result);

		$url = 'file://www.dolibarr.org/download/file.zip';
		$result = dol_is_url($url);
		print __METHOD__." result=".$result."\n";
		$this->assertTrue($result);

		return $result;
	}

	/**
	 * testDolMimeType
	 *
	 * @return	void
	 */
	public function testDolMimeType()
	{
		global $conf,$user,$langs,$db;
		$conf = $this->savconf;
		$user = $this->savuser;
		$langs = $this->savlangs;
		$db = $this->savdb;

		// file.png
		$result = dol_mimetype('file.png', '', 0);
		$this->assertEquals('image/png', $result);
		$result = dol_mimetype('file.png', '', 1);
		$this->assertEquals('png', $result);
		$result = dol_mimetype('file.png', '', 2);
		$this->assertEquals('image.png', $result);
		$result = dol_mimetype('file.png', '', 3);
		$this->assertEquals('', $result);
		// file.odt
		$result = dol_mimetype('file.odt', '', 0);
		$this->assertEquals('application/vnd.oasis.opendocument.text', $result);
		$result = dol_mimetype('file.odt', '', 1);
		$this->assertEquals('vnd.oasis.opendocument.text', $result);
		$result = dol_mimetype('file.odt', '', 2);
		$this->assertEquals('ooffice.png', $result);
		$result = dol_mimetype('file.odt', '', 3);
		$this->assertEquals('', $result);
		// file.php
		$result = dol_mimetype('file.php', '', 0);
		$this->assertEquals('text/plain', $result);
		$result = dol_mimetype('file.php', '', 1);
		$this->assertEquals('plain', $result);
		$result = dol_mimetype('file.php', '', 2);
		$this->assertEquals('php.png', $result);
		$result = dol_mimetype('file.php', '', 3);
		$this->assertEquals('php', $result);
		// file.php.noexe
		$result = dol_mimetype('file.php.noexe', '', 0);
		$this->assertEquals('text/plain', $result);
	}


	/**
	 * testDolDeleteDir
	 *
	 * @return	void
	 */
	public function testDolDeleteDir()
	{
		global $conf,$user,$langs,$db;
		$conf = $this->savconf;
		$user = $this->savuser;
		$langs = $this->savlangs;
		$db = $this->savdb;

		$dirout = $conf->admin->dir_temp.'/test';
		$dirout2 = $conf->admin->dir_temp.'/test2';

		$count = 0;
		$result = dol_delete_dir_recursive($dirout, $count);	// If it has no permission to delete, it will fails as if dir does not exists, so we can't test it
		print __METHOD__." result=".$result."\n";
		$this->assertGreaterThanOrEqual(0, $result);

		$count = 0;
		$countdeleted = 0;
		$result = dol_delete_dir_recursive($dirout, $count, 1, 0, $countdeleted);	// If it has no permission to delete, it will fails as if dir does not exists, so we can't test it
		print __METHOD__." result=".$result."\n";
		$this->assertGreaterThanOrEqual(0, $result);
		$this->assertGreaterThanOrEqual(0, $countdeleted);

		dol_mkdir($dirout2);
		$count = 0;
		$countdeleted = 0;
		$result = dol_delete_dir_recursive($dirout2, $count, 1, 0, $countdeleted);	// If it has no permission to delete, it will fails as if dir does not exists, so we can't test it
		print __METHOD__." result=".$result."\n";
		$this->assertGreaterThanOrEqual(1, $result);
		$this->assertGreaterThanOrEqual(1, $countdeleted);
	}


	/**
	 * testDolCopyMoveDelete
	 *
	 * @return	void
	 * @group WindowsWaitingForFix
	 */
	public function testDolCopyMoveDelete()
	{
		global $conf,$user,$langs,$db;
		$conf = $this->savconf;
		$user = $this->savuser;
		$langs = $this->savlangs;
		$db = $this->savdb;

		$file = dirname(__FILE__).'/file_import_company_1.csv';

		$result = dol_copy($file, '/adir/that/does/not/exists/file.csv');
		print __METHOD__." result=".$result."\n";
		$this->assertLessThan(0, $result, "$result".'copy dir that does not exists');    // We should have error

		$result = dol_copy($file, '/adir/that/does/not/exists/file.csv');
		print __METHOD__." result=".$result."\n";
		$this->assertLessThan(0, $result, "$result".'copy dir that does not exists');    // We should have error

		$result = dol_copy($file, $conf->admin->dir_temp.'/file.csv', 0, 1);
		print __METHOD__." result=".$result."\n";
		$this->assertGreaterThanOrEqual(1, $result, 'copy file ('.$file.') into a dir that exists ('.$conf->admin->dir_temp.'/file.csv)');    // Should be 1

		// Again to test with overwriting=0
		$result = dol_copy($file, $conf->admin->dir_temp.'/file.csv', 0, 0);
		print __METHOD__." result=".$result."\n";
		$this->assertEquals(0, $result, 'copy destination already exists, no overwrite');    // Should be 0

		// Again to test with overwriting=1
		$result = dol_copy($file, $conf->admin->dir_temp.'/file.csv', 0, 1);
		print __METHOD__." result=".$result."\n";
		$this->assertGreaterThanOrEqual(1, $result, 'copy destination already exists, overwrite');    // Should be 1

		// To test a move that should work
		$result = dol_move($conf->admin->dir_temp.'/file.csv', $conf->admin->dir_temp.'/file2.csv', 0, 1);
		print __METHOD__." result=".$result."\n";
		$this->assertTrue($result, 'move with default mask');

		// To test a move that should work with forced mask
		$result = dol_move($conf->admin->dir_temp.'/file2.csv', $conf->admin->dir_temp.'/file3.csv', '0754', 1); // file should be rwxr-wr--
		print __METHOD__." result=".$result."\n";
		$this->assertTrue($result, 'move with forced mask');

		// To test a delete that should success
		$result = dol_delete_file($conf->admin->dir_temp.'/file3.csv');
		print __METHOD__." result=".$result."\n";
		$this->assertTrue($result, 'delete file');

		// Again to test there is error when deleting a non existing file with option disableglob
		$result = dol_delete_file($conf->admin->dir_temp.'/file3.csv', 1, 1);
		print __METHOD__." result=".$result."\n";
		$this->assertFalse($result, 'delete file that does not exists with disabling glob must return ko');

		// Again to test there is no error when deleting a non existing file without option disableglob
		$result = dol_delete_file($conf->admin->dir_temp.'/file3csv', 0, 1);
		print __METHOD__." result=".$result."\n";
		$this->assertTrue($result, 'delete file that does not exists without disabling glob must return ok');

		// Test copy with special char / delete with blob
		$result = dol_copy($file, $conf->admin->dir_temp.'/file with [x] and é.csv', 0, 1);
		print __METHOD__." result=".$result."\n";
		$this->assertGreaterThanOrEqual(1, $result, 'copy file with special chars, overwrite');    // Should be 1

		// Try to delete using a glob criteria
		$result = dol_delete_file($conf->admin->dir_temp.'/file with [x]*é.csv');
		print __METHOD__." result=".$result."\n";
		$this->assertTrue($result, 'delete file using glob');



		$file = dirname(__FILE__).'/file_pdf_with_js.pdf.jpg';

		$result = dol_copy($file, $conf->admin->dir_temp.'/file_pdf_with_js.pdf.jpg');
		print __METHOD__." result=".$result."\n";
		$this->assertGreaterThan(0, $result, "$result".' failed to copy pdf file');

		$result = dol_move($conf->admin->dir_temp.'/file_pdf_with_js.pdf.jpg', $conf->admin->dir_temp.'/file_pdf_with_js.pdf');
		print __METHOD__." dol_move of corrupted file result=".$result."\n";
		$this->assertFalse($result, "$result".' move of a jpg into a corrupted pdf should fails');
	}

	/**
	 * testDolCompressUnCompress
	 *
	 * @return	void
	 */
	public function testDolCompressUnCompress()
	{
		global $conf,$user,$langs,$db;
		$conf = $this->savconf;
		$user = $this->savuser;
		$langs = $this->savlangs;
		$db = $this->savdb;

		// Format zip
		print "\n";
		print 'testDolCompressUnCompress zip'."\n";

		$format = 'zip';
		$filein = dirname(__FILE__).'/file_import_company_1.csv';
		$fileout = $conf->admin->dir_temp.'/test.'.$format;
		$dirout = $conf->admin->dir_temp.'/testdir'.$format;

		dol_delete_file($fileout);
		$count = 0;
		dol_delete_dir_recursive($dirout, $count, 1);

		$errorstring = '';

		dol_mkdir($conf->admin->dir_temp);
		$conf->global->MAIN_ENABLE_LOG_TO_HTML = 1;
		$conf->modules['syslog'] = 'syslog';
		$_REQUEST['logtohtml'] = 1;
		$conf->logbuffer = array();

		$result = dol_compress_file($filein, $fileout, $format, $errorstring);
		print __METHOD__." compress result=".$result."\n";
		print join(', ', $conf->logbuffer);
		$this->assertGreaterThanOrEqual(1, $result, "Pb with dol_compress_file on ".$filein." into ".$fileout." : ".$errorstring);

		$result = dol_uncompress($fileout, $dirout);
		print __METHOD__." uncompress result=".join(',', $result)."\n";
		print join(', ', $conf->logbuffer);
		$this->assertEquals(0, count($result), "Pb with dol_uncompress_file of file ".$fileout);

		// Format gz
		print "\n";
		print 'testDolCompressUnCompress gz'."\n";

		$format = 'gz';
		$filein = dirname(__FILE__).'/file_import_company_1.csv';
		$fileout = $conf->admin->dir_temp.'/test.'.$format;
		$dirout = $conf->admin->dir_temp.'/testdir'.$format;

		dol_delete_file($fileout);
		$count = 0;
		dol_delete_dir_recursive($dirout, $count, 1);

		$errorstring = '';

		dol_mkdir($conf->admin->dir_temp);
		$conf->global->MAIN_ENABLE_LOG_TO_HTML = 1;
		$conf->modules['syslog'] = 'syslog';
		$_REQUEST['logtohtml'] = 1;
		$conf->logbuffer = array();

		$result = dol_compress_file($filein, $fileout, $format, $errorstring);
		print __METHOD__." compress result=".$result."\n";
		print join(', ', $conf->logbuffer);
		$this->assertGreaterThanOrEqual(1, $result, "Pb with dol_compress_file on ".$filein." into ".$fileout." : ".$errorstring);

		$result = dol_uncompress($fileout, $dirout);
		print __METHOD__." uncompress result=".join(',', $result)."\n";
		print join(', ', $conf->logbuffer);
		$this->assertEquals(0, count($result), "Pb with dol_uncompress_file of file ".$fileout);


		// Test compression of a directory
		// $dirout is $conf->admin->dir_temp.'/testdirgz'
		$excludefiles = '/(\.back|\.old|\.log|documents[\/\\\]admin[\/\\\]documents[\/\\\])/i';
		if (preg_match($excludefiles, 'a/temp/b')) {
			echo '----- Regex OK -----'."\n";
		}
		$result = dol_compress_dir($dirout, $conf->admin->dir_temp.'/testcompressdirzip.zip', 'zip', $excludefiles);
		print __METHOD__." dol_compress_dir result=".$result."\n";
		print join(', ', $conf->logbuffer);
		$this->assertGreaterThanOrEqual(1, $result, "Pb with dol_compress_dir of ".$dirout." into ".$conf->admin->dir_temp.'/testdir.zip');
	}

	/**
	 * testDolCheckSecureAccessDocument
	 *
	 * @return void
	 */
	public function testDolCheckSecureAccessDocument()
	{
		global $conf,$user,$langs,$db;
		$conf = $this->savconf;
		$user = $this->savuser;
		$langs = $this->savlangs;
		$db = $this->savdb;

		//$dummyuser=new User($db);
		//$result=restrictedArea($dummyuser,'societe');

		// We save user properties
		$savpermlire = $user->hasRight('facture', 'lire');
		$savpermcreer = $user->hasRight('facture', 'creer');

		if (empty($user->rights->facture)) {
			$user->rights->facture = new stdClass();
		}

		// Check access to SPECIMEN
		$user->rights->facture->lire = 0;
		$user->rights->facture->creer = 0;
		$filename = 'SPECIMEN.pdf';             // Filename relative to module part
		$result = dol_check_secure_access_document('facture', $filename, 0, '', '', 'read');
		$this->assertEquals(1, $result['accessallowed'], "Check access allowed to '$filename'".json_encode($result));


		// Check read permission
		$user->rights->facture->lire = 1;
		$user->rights->facture->creer = 1;
		$filename = 'FA010101/FA010101.pdf';    // Filename relative to module part
		$result = dol_check_secure_access_document('facture', $filename, 0, '', '', 'read');
		$this->assertEquals(1, $result['accessallowed'], "Check access allowed to '$filename'".json_encode($result));

		$user->rights->facture->lire = 0;
		$user->rights->facture->creer = 0;
		$filename = 'FA010101/FA010101.pdf';    // Filename relative to module part
		$result = dol_check_secure_access_document('facture', $filename, 0, '', '', 'read');
		$this->assertEquals(0, $result['accessallowed'], "Check access denied to '$filename':".json_encode($result));

		// Check write permission
		$user->rights->facture->lire = 0;
		$user->rights->facture->creer = 0;
		$filename = 'FA010101/FA010101.pdf';    // Filename relative to module part
		$result = dol_check_secure_access_document('facture', $filename, 0, '', '', 'write');
		$this->assertEquals(0, $result['accessallowed']);

		$user->rights->facture->lire = 1;
		$user->rights->facture->creer = 1;
		$filename = 'FA010101/FA010101.pdf';    // Filename relative to module part
		$result = dol_check_secure_access_document('facture', $filename, 0, '', '', 'write');
		$this->assertEquals(1, $result['accessallowed']);

		$user->rights->facture->lire = 1;
		$user->rights->facture->creer = 0;
		$filename = 'FA010101/FA010101.pdf';    // Filename relative to module part
		$result = dol_check_secure_access_document('facture', $filename, 0, '', '', 'write');
		$this->assertEquals(0, $result['accessallowed']);


		// We restore user properties
		$user->rights->facture->lire = $savpermlire;
		$user->rights->facture->creer = $savpermcreer;

		// The API maps modulepart to 'supplier_invoice' / 'supplier_order': they must use the supplier module permissions
		if (!empty($conf->fournisseur->facture->dir_output) && !empty($conf->fournisseur->commande->dir_output)) {
			$savpermsupplier = $user->rights->fournisseur;
			$user->rights->fournisseur = new stdClass();
			$user->rights->fournisseur->facture = new stdClass();
			$user->rights->fournisseur->commande = new stdClass();
			foreach (array('supplier_invoice' => 'facture', 'supplier_order' => 'commande') as $modulepart => $permobject) {
				$filename = 'SI010101/SI010101.pdf';
				$user->rights->fournisseur->$permobject->creer = 1;
				$result = dol_check_secure_access_document($modulepart, $filename, 0, '', '', 'write');
				$this->assertEquals(1, $result['accessallowed'], "Check write access allowed to '$modulepart/$filename':".json_encode($result));
				$this->assertEquals($conf->fournisseur->$permobject->dir_output.'/'.$filename, $result['original_file']);

				$user->rights->fournisseur->$permobject->creer = 0;
				$result = dol_check_secure_access_document($modulepart, $filename, 0, '', '', 'write');
				$this->assertEquals(0, $result['accessallowed'], "Check write access denied to '$modulepart/$filename':".json_encode($result));
			}
			$user->rights->fournisseur = $savpermsupplier;
		}
	}

	/**
	 * testDolDirMove
	 *
	 * @return void
	 * @group WindowsWaitingForFix
	 */
	public function testDolDirMove()
	{
		global $conf,$user,$langs,$db;
		$conf = $this->savconf;
		$user = $this->savuser;
		$langs = $this->savlangs;
		$db = $this->savdb;

		// To test a move of empty directory that should work
		$dirsrcpath = $conf->admin->dir_temp.'/directory';
		$dirdestpath = $conf->admin->dir_temp.'/directory2';
		$file = dirname(__FILE__).'/file_import_company_1.csv';
		dol_mkdir($dirsrcpath);
		dol_delete_dir_recursive($dirdestpath, 0, 1);
		$result = dol_move_dir($dirsrcpath, $dirdestpath, 1, 1, 1);
		print __METHOD__." result=".$result."\n";
		$this->assertTrue($result, 'move of directory with empty directory');

		// To test a move on existing directory with overwrite
		dol_mkdir($dirsrcpath);
		$result = dol_move_dir($dirsrcpath, $dirdestpath, 1, 1, 1);
		print __METHOD__." result=".$result."\n";
		$this->assertTrue($result, "move of directory on existing directory with empty directory");

		// To test a move on existing directory without overwrite
		dol_mkdir($dirsrcpath);
		$result = dol_move_dir($dirsrcpath, $dirdestpath, 0, 1, 1);
		print __METHOD__." result=".$result."\n";
		$this->assertFalse($result, 'move of directory on existing directory without overwrite');

		// To test a move with a file to rename in src directory
		dol_mkdir($dirsrcpath);
		dol_delete_dir_recursive($dirdestpath, 0, 1);
		dol_copy($file, $dirsrcpath.'/directory_file.csv');
		$result = dol_move_dir($dirsrcpath, $dirdestpath, 1, 1, 1);
		print __METHOD__." result=".$result."\n";
		$this->assertTrue($result, 'move of directory with file in directory');

		// To test a move without a file to rename in src directory
		dol_mkdir($dirsrcpath);
		dol_delete_dir_recursive($dirdestpath, 0, 1);
		dol_copy($file, $dirsrcpath.'/file.csv');
		$result = dol_move_dir($dirsrcpath, $dirdestpath, 1, 1, 1);
		print __METHOD__." result=".$result."\n";
		$this->assertTrue($result, 'move of directory with file without rename needed in directory');

		// To test a move with a directory to rename in src directory
		dol_mkdir($dirsrcpath);
		dol_delete_dir_recursive($dirdestpath, 0, 1);
		dol_mkdir($dirsrcpath.'/directory');
		$result = dol_move_dir($dirsrcpath, $dirdestpath, 1, 1, 1);
		print __METHOD__." result=".$result."\n";
		$this->assertTrue($result, 'move of directory with file with rename needed in directory');

		// To test a move without a directory to rename in src directory
		dol_mkdir($dirsrcpath);
		dol_delete_dir_recursive($dirdestpath, 0, 1);
		dol_mkdir($dirsrcpath.'/notorename');
		$result = dol_move_dir($dirsrcpath, $dirdestpath, 1, 1, 1);
		print __METHOD__." result=".$result."\n";
		$this->assertTrue($result, 'move of directory with directory without rename needed in directory');
	}

	/**
	 * testDolConvertFile
	 *
	 * @return void
	 */
	public function testDolConvertFile()
	{
		global $conf,$user,$langs,$db;
		$conf = $this->savconf;
		$user = $this->savuser;
		$langs = $this->savlangs;
		$db = $this->savdb;

		// If imagick not installed, you can install it with
		// apt install imagemagick php7.4-imagick
		if (class_exists('Imagick')) {
			$filepdf = dirname(__FILE__).'/imgsvgwithjs.svg';
			$fileimage = $conf->admin->dir_temp.'/testdolconvert.png';

			$result = dol_convert_file($filepdf, 'png', $fileimage, '0'); // Convert first page of PDF into a file _preview.png
			print __METHOD__." result=".$result."\n";
			$this->assertEquals(-4, $result, 'Convert of PDF file '.$filepdf.' into image should have return an error because it is not a real PDF, but this did not happen.');

			$filepdf = dirname(__FILE__).'/file_pdf_with_js.pdf.jpg';
			$result = dol_copy($filepdf, $conf->admin->dir_temp.'/testdolconvert.pdf');

			$fileimage = $conf->admin->dir_temp.'/testdolconvert.png';

			$result = dol_convert_file($filepdf, 'png', $fileimage, '0'); // Convert first page of PDF into a file _preview.png
			print __METHOD__." result=".$result."\n";
			$this->assertEquals(1, $result, 'Failed to convert PDF file into '.$fileimage.', error '.$result);
		} else {
			print __METHOD__." skipped because Imagick is not installed.\n";

			$this->expectNotToPerformAssertions();
		}
	}
}
