<?php

namespace AuthStack\Driver\SOAP\BPS\tests\units;

use AuthStack\Driver\Errors\ConnectionError;
use AuthStack\Driver\Errors\InsufficientCredentialsError;
use AuthStack\Driver\Errors\NoUserObjectError;
use AuthStack\Driver\SOAP\BPS\SOAP as SOAPDriver;
use AuthStack\Driver\SOAP\BPS\User;
use Illuminate\Support\Collection;
use mageekguy\atoum;
use function Buckhill\config;


class Soap extends atoum
{
    const CONF_KEY = 'SOAPTest';
    const AUTHSOURCE_ID = 3;

    public function testNoConnection()
    {
        $this
            ->given( config()->set(self::CONF_KEY, $this->badConfigCredentials() ) )
            ->and( $soap = SOAPDriver::initialize(self::CONF_KEY, self::AUTHSOURCE_ID ) )
            ->then
            ->exception( function()use($soap){
                $conn = $soap->getConnection();
            })
            ->isInstanceOf(ConnectionError::class)
        ;
    }

    public function testConnectionOK()
    {
        $this
            ->given( config()->set(self::CONF_KEY, $this->config() ) )
            ->and( $soap = SOAPDriver::initialize( self::CONF_KEY, self::AUTHSOURCE_ID ) )
            ->then
                ->object( $soap )->isInstanceOf( SOAPDriver::class )
                ->boolean( $soap->connect() )->isTrue()
                ->integer( $soap->getAuthSourceId() )->isEqualTo( self::AUTHSOURCE_ID );
    }

    public function testConnectionBadCredentials()
    {
        $this
            ->given( config()->set(self::CONF_KEY, $this->badConfigCredentials() ) )
            ->and( $soap = SOAPDriver::initialize(self::CONF_KEY, self::AUTHSOURCE_ID ) )
            ->and ($soap->connect() )
            ->then
            ->object( $soap )->isInstanceOf( SOAPDriver::class )
            ->exception( function()use($soap){
                $soap->authenticate(['username' => '095748@app-memo.co.uk', 'password' => 'Veyron1']);
            })
            ->isInstanceOf(InsufficientCredentialsError::class)
        ;
    }

    public function testAuthOK()
    {
        $this
            ->given( config()->set(self::CONF_KEY, $this->config() ) )
            ->and( $soap = SOAPDriver::initialize(self::CONF_KEY, self::AUTHSOURCE_ID ) )
            ->and ($soap->connect() )
            ->then
                ->object( $soap )->isInstanceOf( SOAPDriver::class )
                ->boolean($soap->authenticate(['username' => '095748@app-memo.co.uk', 'password' => 'Veyron1']))->isTrue()
                ->object($soap->getUser())->isInstanceOf( User::class )
                ->string($soap->lastError())->isEmpty()
                ->boolean($soap->passwordChangeAllowed())->isFalse()
                ->boolean($soap->changePassword([]))->isFalse()
                ->object( $collection = $soap->getUser()->getAttributeCollection())->isInstanceOf(Collection::class)
                ->string( $collection->get('bpsId') )->isEqualTo('95748')
                ->string( $collection->get('locked') )->isEqualTo('0')
                ->array( $collection->get('faculty_sig') )
            ;
    }

    public function testAuthInvalidPassword()
    {
        $this
            ->given( config()->set(self::CONF_KEY, $this->config() ) )
            ->and( $soap = SOAPDriver::initialize(self::CONF_KEY, self::AUTHSOURCE_ID ) )
            ->and ($soap->connect() )
            ->then
                ->object( $soap )->isInstanceOf( SOAPDriver::class )
                ->boolean($soap->authenticate(['username' => '095748@app-memo.co.uk', 'password' => 'Veyron2']))->isFalse()
                ->exception( function()use($soap){
                    $user = $soap->getUser();
                })->isInstanceOf( NoUserObjectError::class )
                ->string( $soap->lastError() )->isEqualTo('BAD PASSWORD');
        ;
    }

    public function testAuthLockedOut()
    {
        $this
            ->given( config()->set(self::CONF_KEY, $this->config() ) )
            ->and( $soap = SOAPDriver::initialize(self::CONF_KEY, self::AUTHSOURCE_ID ) )
            ->and ($soap->connect() )
            ->then
                ->object( $soap )->isInstanceOf( SOAPDriver::class )
                ->boolean($soap->authenticate(['username' => '004100@app-memo.co.uk', 'password' => 'Veyron1']))->isFalse()
                ->exception( function()use($soap){
                    $user = $soap->getUser();
                })->isInstanceOf( NoUserObjectError::class )
                ->string( $soap->lastError() )->isEqualTo('LOCKED OUT');
        ;
    }

    public function testAuthNotActivated()
    {
        $this
            ->given( config()->set(self::CONF_KEY, $this->config() ) )
            ->and( $soap = SOAPDriver::initialize(self::CONF_KEY, self::AUTHSOURCE_ID ) )
            ->and ($soap->connect() )
            ->then
                ->object( $soap )->isInstanceOf( SOAPDriver::class )
                ->boolean($soap->authenticate(['username' => '084484@app-memo.co.uk', 'password' => 'Veyron1']))->isFalse()
                ->exception( function()use($soap){
                    $user = $soap->getUser();
                })->isInstanceOf( NoUserObjectError::class )
                ->string( $soap->lastError() )->isEqualTo('ACCOUNT NOT ACTIVATED');
        ;
    }

    public function testAuthInvalidUser()
    {
        $this
            ->given( config()->set(self::CONF_KEY, $this->config() ) )
            ->and( $soap = SOAPDriver::initialize(self::CONF_KEY, self::AUTHSOURCE_ID ) )
            ->and ($soap->connect() )
            ->then
                ->object( $soap )->isInstanceOf( SOAPDriver::class )
                ->boolean($soap->authenticate(['username' => 'foo@app-memo.co.uk', 'password' => 'Veyron1']))->isFalse()
                ->exception( function()use($soap){
                    $user = $soap->getUser();
                })->isInstanceOf( NoUserObjectError::class )
                ->string( $soap->lastError() )->isEqualTo('NO SUCH USER');
        ;
    }


    //    TODO:: redo this test when issue with E_WARNING is resolved on invalid wsdl URL
//    public function testConnectionBadWsdl()
//    {
//    }


    protected function config()
    {
        return [
            "connection" => [
                "wsdl" => "http://api.bps.org.uk/SteamEngine.trunk.wsdl",
                "options" => [
                    "trace" => 0,
                    "exceptions" => 1,
                    "cache_wsdl" => 0,
                ],
                "credentials" => [
                    "username" => "samlint",
                    "password" => "fr2l#*K5!",
                ],
                "dataset" => "test",
            ],
            "settings" => [
                "name" => "full_name",
                "email" => "email",
            ],
            "attributes" => [
                [ "name"=> "Mem_FullName",      "renamed" => "full_name" ],
                [ "name"=> "Mem_PublicEmail",   "renamed" => "email" ],
                [ "name"=> "codes.faculty_sig", "renamed" => "faculty_sig"]
            ],
        ];
    }

    protected function badConfigWsdl()
    {
        return [
            "connection" => [
                "wsdl" => "http://api.bps.org.uk/SteamEngine.trunk.wsdla",
                "options" => [
                    "trace" => 1,
                    "exceptions" => true,
                    "cache_wsdl" => 0,
                ],
                "credentials" => [
                    "username" => "samlint",
                    "password" => "fr2l#*K5!",
                ],
                "dataset" => "test",
            ],
            "settings" => [
                "name" => "full_name",
                "email" => "email",
            ],
            "attributes" => [
                [ "name"=> "Mem_FullName",    "renamed" => "full_name" ],
                [ "name"=> "Mem_PublicEmail", "renamed" => "email" ],
                [ "name"=> "codes.faculty_sig", "renamed" => "faculty_sig"]
            ],
        ];

    }

    protected function badConfigCredentials()
    {
        return [
            "connection" => [
                "wsdl" => "http://api.bps.org.uk/SteamEngine.trunk.wsdl",
                "options" => [
                    "trace" => 0,
                    "exceptions" => 1,
                    "cache_wsdl" => 0,
                ],
                "credentials" => [
                    "username" => "foo",
                    "password" => "bar",
                ],
                "dataset" => "test",
            ],
            "settings" => [
                "name" => "full_name",
                "email" => "email",
            ],
            "attributes" => [
                [ "name"=> "Mem_FullName",    "renamed" => "full_name" ],
                [ "name"=> "Mem_PublicEmail", "renamed" => "email" ],
                [ "name"=> "codes.faculty_sig", "renamed" => "faculty_sig"]
            ],
        ];
    }
}