<?php
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\DataProvider;
/**
 * Generated by PHPUnit_SkeletonGenerator on 2017-11-26 at 11:24:04.
 */
class Acc_AccountTest extends TestCase
{

    /**
     * @var Acc_Account
     */
    protected $object;

    /**
     * Sets up the fixture, for example, opens a network connection.
     * This method is called before a test is executed.
     */
    protected function setUp():void 
    {
        global $g_connection, $g_parameter, $g_user;
        $_REQUEST['gDossier']=DOSSIER;
        $g_connection=new Database(DOSSIER);
        $g_parameter=new Noalyss_Parameter_Folder($g_connection);
        $g_user=new Noalyss_user($g_connection);
        $cn=Dossier::connect();
        $this->object=new Acc_Account($cn, '400');
    }


    /**
     * @covers Acc_Account::get_parameter
     */
    public function testGet_parameter()
    {

        $this->assertEquals($this->object->get_parameter("pcm_lib"), 'Clients');
    }

    /**
     * @covers Acc_Account::set_parameter
     */
    public function testSet_parameter()
    {
        $this->object->set_parameter("pcm_direct_use", "N");
        $this->assertEquals($this->object->get_parameter("pcm_direct_use"),"N");
    }

    /**
     * @covers Acc_Account::get_lib
     */
    public function testGet_lib()
    {
        $this->assertEquals($this->object->get_lib(), 'Clients');
    }

    /**
     * @covers Acc_Account::load
     */
    public function testLoad()
    {
        $r=$this->object->load();
        $this->assertNotEquals($r,false);
    }

    /**
     * @covers Acc_Account::count
     */
    public function testCount()
    {

        $this->assertEquals($this->object->count("400"), 1);
    }

    /**
     * @covers Acc_Account::verify
     */
    public function testVerify()
    {
        global $g_connection;
        // duplicate
        $duplicate=new Acc_Account($g_connection);
        $duplicate->set_parameter('pcm_val', "400");
        $duplicate->set_parameter("pcm_lib", "duplicate");
        $duplicate->set_parameter("pcm_val_parent", "40");
        $duplicate->set_parameter("pcm_direct_use", "N");

       try {
            $duplicate->insert();
       } catch (Exception $ex) {
           $this->assertEquals($ex->getCode(),EXC_DUPLICATE);
       }
       $duplicate->set_parameter('pcm_val','999TEST');
       try {
           $duplicate->set_parameter("pcm_lib", "");
           $duplicate->insert();
       } catch (Exception $ex) {
            $this->assertEquals($ex->getCode(),EXC_PARAM_VALUE);
       }
       $duplicate->set_parameter("pcm_lib", "duplicate");
       try {
           $duplicate->set_parameter("pcm_val_parent", "999TEST");
            $duplicate->insert();

       } catch (Exception $ex) {
           $this->assertEquals($ex->getCode(),EXC_PARAM_VALUE);
       }
       
       try {
           $duplicate->set_parameter("pcm_val_parent", "xxx");
            $duplicate->insert();

       } catch (Exception $ex) {
           $this->assertEquals($ex->getCode(),EXC_PARAM_VALUE);
       }
       $duplicate->set_parameter("pcm_val_parent", "9");
       try {
           $duplicate->set_parameter("pcm_direct_use", "?");
            $duplicate->insert();

       } catch (Exception $ex) {
           $this->assertEquals($ex->getCode(),EXC_PARAM_VALUE);
       }
       $duplicate->set_parameter("pcm_direct_use", "Y");
       try {
           $duplicate->set_parameter('pcm_val','');
           $duplicate->insert();
       } catch (Exception $ex) {
            $this->assertEquals($ex->getCode(),EXC_PARAM_VALUE);
       }
       $duplicate->set_parameter('pcm_val','999TEST');
       $duplicate->delete();
       
    }

    /**
     * @covers Acc_Account::update
     */
    public function testUpdate()
    {
        global $g_connection;
        $new_string="000001112222";
        $old_label=$this->object->get_lib();
        $this->object->set_parameter("pcm_lib", $new_string);
        $this->object->update();
        $check=new Acc_Account($g_connection,$this->object->get_parameter("pcm_val"));
        $this->assertEquals($check->get_parameter("pcm_lib"),$new_string);
        $check->set_parameter("pcm_lib", $old_label);
        $check->update();
        $this->object->load();
        $this->assertEquals($this->object->get_lib(),$old_label);
    }

    /**
     * @covers Acc_Account::insert
     * @covers Acc_Account::find_by_value
     */
    public function testInsert()
    {
        $cn=Dossier::connect();
        $cn->exec_sql("delete from tmp_pcmn where pcm_val=$1",
                ['400A']);
        $new=new Acc_Account($cn);
        
        $new->set_parameter("pcm_val", '400A');
        $new->set_parameter("pcm_val_parent", "400");
        $new->set_parameter("pcm_direct_use", "Y");
        // expect libelle vide
        try
        {
            // exception must be thrown from insert
            $new->insert();
            $this->assertFalse(true);
        }
        catch (Exception $e)
        {
            $this->assertEquals($e->getCode(), EXC_PARAM_VALUE);
             $new->delete();
        }

        $new->set_parameter("pcm_lib", "Insertion test");
        $new->insert();
        $check=new Acc_Account($cn);     
        $check->find_by_value('400A');
        $this->assertEquals("Insertion test",$check->get_lib());
        $new->delete();
        
    }

    /**
     * @covers Acc_Account::delete
     */
    public function testDelete()
    {
        try
        {
            $this->object->delete();
            $this->assertFalse(true);
        }
        catch (Exception $e)
        {
            $this->assertEquals($e->getCode(), EXC_PARAM_VALUE);
        }
    }

    /**
     * @covers Acc_Account::save
     */
    public function testSave()
    {
        global $g_connection;
        $g_connection->exec_sql("delete from tmp_pcmn where pcm_val=$1",
                ['999TEST']);
        $check=new Acc_Account($g_connection,'999TEST');
        $check->set_parameter("pcm_lib", "TESTING");
        $check->set_parameter('pcm_val_parent','9');
        $check->set_parameter('pcm_direct_use','N');
        // insert
        
        $check->save();
        $check_new=new Acc_Account($g_connection,'999TEST');
        $this->assertEquals($check_new->get_lib(),$check->get_lib());
        $check->set_parameter("pcm_lib","NEW VALUE");
        // update
        $check->save();
        $check_new->load();
        $this->assertNotEquals($check_new->get_lib(),"TESTING");
        $check->delete();
    }
    
    public function testfind_parent()
    {
        $this->object->set_parameter("pcm_val", 70000000);
        $result=$this->object->find_parent();
        $this->assertEquals($result,700);
    }
    public static function dataFormatAccount()
    {
        return array(
            ['60élépànç%','60ELEPANC'],
            ['4000','4000'],
            ['6é&" #çç!!!,%-.','6ECC'],
            ['6-alpha6','6ALPHA6'],
            ['6_alpha6','6ALPHA6'],
            ['6.alpha6','6ALPHA6'],
            ['6:alpha6','6:ALPHA6'],
        );
    }
    /**
     * @brief format properly the accounting
     * @testdox check psql function format_account
     * @param string $param
     * @param string $p_result
     * @dataProvider dataFormatAccount
     */
     #[DataProvider('dataFormatAccount')]
    public function testFormatAccount($param,$p_result)
    {
        global $g_connection;
        $this->assertEquals($g_connection->get_value("select comptaproc.format_account($1)",[$param]),
                $p_result,"comptaproc.format_account $param does not match $p_result");
    }

}
