Skip to content
Snippets Groups Projects
WebqueryTest.php 13.4 KiB
Newer Older
<?php

namespace Tests\Functional\Library;

use GuzzleHttp\Psr7\Response;

class WebqueryTest extends \PHPUnit_Framework_TestCase {


    public function test_get_query_string() {

        $tests = [
            ["qry" => "", "exp" => "", "ofs" => null, "max" => null, "msg" => "empty query string"],
            ["qry" => "a=1&b=2", "exp" => "a=1&b=2", "ofs" => null, "max" => null, "msg" => "simple query string"],
            ["qry" => "a=1&b=2", "exp" => "wq_ofs=3&a=1&b=2", "ofs" => 3, "max" => null, "msg" => "simple query string and wq_ofs"],
            ["qry" => "a=1&b=2", "exp" => "wq_ofs=3&wq_max=4&a=1&b=2", "ofs" => 3, "max" => 4, "msg" => "simple query string and wq_ofs and wq_max"],
            ["qry" => ["a" => 1], "exp" => "a=1", "ofs" => null, "max" => null, "msg" => "hash with 1 key/val pair"],
            ["qry" => ["a" => 1, "b" => "2"], "exp" => "wq_ofs=3&wq_max=4&a=1&b=2", "ofs" => 3, "max" => 4, "msg" => "hash with 2 key/val pairs and wq_ofs and wq_max"],
            ["qry" => ["a" => ["11", 12, "13"]], "exp" => "a=11&a=12&a=13", "ofs" => null, "max" => null, "msg" => "1 key/value pair, value is array with 3 values"],
            ["qry" => ["c" => "c1", "a" => ["11", 12], "b" => "b2"], "exp" => "c=c1&a=11&a=12&b=b2", "ofs" => null, "max" => null, "msg" => "3 key/value pairs, 2nd value is array with 2 values"],
            ["qry" => ["a" => "1", "!b" => "2"], "exp" => "a=1&wq_rel=AND+NOT&b=2", "ofs" => null, "max" => null, "msg" => "2 key/value pairs, second key has NOT prefix"],
            ["qry" => ["a"  => "1", "!b" => "2", "c"  => "3"], "exp" => "a=1&wq_rel=AND+NOT&b=2&c=3", "ofs" => null, "max" => null, "msg" => "3 key/value pairs, 2nd key has NOT prefix"],
            ["qry" => ["a"  => "1", "!b" => "2", "!c"  => "3"], "exp" => "a=1&wq_rel=AND+NOT&b=2&wq_rel=AND+NOT&c=3", "ofs" => null, "max" => null, "msg" => "3 key/value pairs, 2nd and 3rd key have NOT prefix"],
            ["qry" => ["c" => "3", "!a" => ["11", 12, "13"], "d" => "4"], "exp" => "c=3&wq_rel=AND+NOT&wq_par=open&a=11&a=12&a=13&wq_par=close&d=4", "ofs" => null, "max" => null, "msg" => "3 key/value pairs, 2nd value is array and has NOT prefix"],
            ["qry" => ["status" => "wacht op lener", "a" => "1"], "exp" => "status=wacht%20op%20lener&a=1", "ofs" => null, "max" => null, "msg" => "2 key/value pairs, value must be urlencoded"],
            ["qry" => ["status" => ["wacht op lener", "wacht op item"]], "exp" => "status=wacht%20op%20lener&status=wacht%20op%20item", "ofs" => null, "max" => null, "msg" => "1 key/value pair, value is array with 2 values which must be urlencoded"],
        ];

        $t = 0;
        foreach ($tests as $test) {
            $result = \Library\Webquery::get_query_string($test["qry"], $test["ofs"], $test["max"]);
            $this->assertEquals($test["exp"], $result, "$t: ".$test["msg"]);
            $t++;
        }
    }


    public function test_get_search_url() {

        // with default settings
        $wq = new \Library\Webquery();
        $expect = 'http://library.wur.nl/WebQuery//xml';
        $this->assertEquals($expect, $wq->get_search_url(), 'no properties set, default url');

        // with url properties set
        $wq = new \Library\Webquery();
        $wq->set_host('devel.library.wur.nl')
            ->set_service('testservice')
            ->set_suffix('record');
        $expect = 'http://devel.library.wur.nl/WebQuery/testservice/record';
        $this->assertEquals($expect, $wq->get_search_url(), 'url properties set');

        // with query string set
        $wq = new \Library\Webquery();
        $wq->set_host('devel.library.wur.nl')
            ->set_service('anotherservice')
            ->set_query('q=*');
        $expect = 'http://devel.library.wur.nl/WebQuery/anotherservice/xml?q=*';
        $this->assertEquals($expect, $wq->get_search_url(), 'query string set');

        // with query array set
        $wq = new \Library\Webquery();
        $wq->set_service('aservice')
            ->set_query(["first" => "1", "second" => "2"]);
        $expect = 'http://library.wur.nl/WebQuery/aservice/xml?first=1&second=2';
        $this->assertEquals($expect, $wq->get_search_url(), 'query array set');

        // with query array set
        $wq = new \Library\Webquery();
        $wq->set_service('aservice')
            ->set_query("q=*")
            ->set_wq_ofs(10)
            ->set_wq_max(50);
        $expect = 'http://library.wur.nl/WebQuery/aservice/xml?wq_ofs=10&wq_max=50&q=*';
        $this->assertEquals($expect, $wq->get_search_url(), 'wq_ofs and wq_max set');
    }


    public function test_get_new_url() {

        // with default settings
        $wq = new \Library\Webquery();
        $expect = 'http://library.wur.nl/WebQuery//new_xml';
        $this->assertEquals($expect, $wq->get_new_url(), 'no properties set, default url');

        // with url properties set
        $wq = new \Library\Webquery();
        $wq->set_host('devel.library.wur.nl')
            ->set_service('testservice')
             ->set_suffix('record');
        $expect = 'http://devel.library.wur.nl/WebQuery/testservice/new_record';
        $this->assertEquals($expect, $wq->get_new_url(), 'url properties set, default url');
    }


    public function test_search() {

        // create mock http client that stores requests and responses
        $request_history = [];
        $record_xml = <<<EOT
<record isn='13' crc='123abcde' cu='tester'>
    <sub1>subval1</sub1>
    <sub2>
        <child1>childval1</child1>
        <child2>childval2</child2>
    </sub2>
    <sub3>subval 3</sub3>
</record>
EOT;
        $responses = [
            new Response(200, [], "<recordset><hits>1</hits>$record_xml</recordset>"),
            new Response(404, [], '<recordset><error code="WQW_NO_HITS"><message>nothing found</message></error></recordset>'),
        ];
        $mock_httpclient = get_mock_httpclient($responses, $request_history);

        $wq = new \Library\Webquery();
        $wq->set_http_client($mock_httpclient);
        $wq->set_logger(new \Monolog\Logger('search'));

        $wq->set_host('devel.library.wur.nl')
            ->set_service('testservice')
            ->set_record_name("record")
            ->set_query('record=*');

        // first request succeeds
        $result = $wq->search();
        $this->assertEquals($wq, $result, '1st: search returns self');
        $this->assertEquals('200', $wq->get_http_status(), '1st: response http status');
        $resp_body = $wq->get_response()->getBody();
        $expect = "<recordset><hits>1</hits>$record_xml</recordset>";
        $this->assertEquals($expect, $resp_body, '1st: search response body');
        $resp_xml = $wq->get_resp_xml();
        $expect = simplexml_load_string($resp_body);
        $this->assertEquals($expect, $resp_xml, '1st: search response xml');
        $record = $wq->get_record();
        $expect = simplexml_load_string($record_xml);
        $this->assertEquals($expect, $record, '1st: search response record');
        $records = $wq->get_records();
        $expect = [$expect];  // array with 1 record
        $this->assertEquals($expect, $records, '1st: search response records');
        $this->assertEquals('', $wq->get_error_code(), '1st: search response error code');
        $this->assertEquals('', $wq->get_error_message(), '1st: search response error message');
        $this->assertEquals(1, $wq->get_hits(), '1st: search response hits');

        // second request fails
        $wq->set_query('record=nothing');
        $result = $wq->search();
        $this->assertEquals($wq, $result, '2nd: search returns self');
        $this->assertEquals('404', $wq->get_http_status(), '2nd: response http status');
        $resp_body = $wq->get_response()->getBody();
        $expect = '<recordset><error code="WQW_NO_HITS"><message>nothing found</message></error></recordset>';
        $this->assertEquals($expect, $resp_body, '2nd: search response body');
        $resp_xml = $wq->get_resp_xml();
        $expect = simplexml_load_string($resp_body);
        $this->assertEquals($expect, $resp_xml, '2nd: search response xml');
        $record = $wq->get_record();
        $expect = false;
        $this->assertEquals($expect, $record, '2nd: search response record');
        $records = $wq->get_records();
        $expect = [];
        $this->assertEquals($expect, $records, '2nd: search response records');
        $this->assertEquals('WQW_NO_HITS', $wq->get_error_code(), '2nd: search response error code');
        $this->assertEquals('nothing found', $wq->get_error_message(), '2nd: search response error message');
        $this->assertEquals(false, $wq->get_hits(), '2nd: search response hits');

        $this->assertEquals(2, count($request_history), 'request history count');
        // check first request
        $request = $request_history[0]['request'];
        $this->assertEquals('GET', $request->getMethod(), 'request 1 method');
        $expect = 'http://devel.library.wur.nl/WebQuery/testservice/xml?record=*';
        $this->assertEquals($expect, $request->getUri(), 'request 1 url');
        // check second request
        $request = $request_history[1]['request'];
        $this->assertEquals('GET', $request->getMethod(), 'request 2 method');
        $expect = 'http://devel.library.wur.nl/WebQuery/testservice/xml?record=nothing';
        $this->assertEquals($expect, $request->getUri(), 'request 2 url');

    }


    public function test_xml_to_wwwform() {

        $xml = get_test_xml();
        $wq = new \Library\Webquery();
        $wwwform = $wq->xml_to_wwwform($xml);
        $expect = 'sub1=subval1&sub2=&child1=childval1&child2=childval2&sub3=subval+3';
        $this->assertEquals($expect, $wwwform, 'record in x-www-form-urlencoded string');
    }

    public function test_create_record() {

        // create mock http client that stores requests and responses
        $request_history = [];
        $responses = [
            new Response(200, [], '<recordset><error status="200" isn="13"><code>WQW_UPDATE_OK</code><message>record created</message></error></recordset>'),
            new Response(500, [], '<recordset><error status="501"><code>WQE_FAILED</code><message>record not created</message></error></recordset>'),
        ];
        $mock_httpclient = get_mock_httpclient($responses, $request_history);

        $wq = new \Library\Webquery();
        $wq->set_http_client($mock_httpclient);
        //$wq->set_logger(new \Monolog\Logger('create_record'));

        $wq->set_host('devel.library.wur.nl')
            ->set_service('testservice');

        $xml = get_test_xml();

        // first request succeeds
        $result = $wq->create_record($xml);
        $this->assertTrue($result, 'first request return value');
        $this->assertEquals('200', $wq->get_error_status(), 'first response error status');
        $this->assertEquals('WQW_UPDATE_OK', $wq->get_error_code(), 'first response error code');
        $this->assertEquals('record created', $wq->get_error_message(), 'first response error message');
        $this->assertEquals('13', $wq->get_isn(), 'first response isn');

        // second request fails
        $wq->set_suffix('record');
        $result = $wq->create_record($xml);
        $this->assertFalse($result, 'second request return value');
        $this->assertEquals('501', $wq->get_error_status(), 'second response error status');
        $this->assertEquals('WQE_FAILED', $wq->get_error_code(), 'second response error code');
        $this->assertEquals('record not created', $wq->get_error_message(), 'second response error message');
        $this->assertEquals('', $wq->get_isn(), 'second response isn');

        $this->assertEquals(2, count($request_history), 'request history count');
        // check first request
        $request = $request_history[0]['request'];
        $this->assertEquals('POST', $request->getMethod(), 'request 1 method');
        $expect = 'http://devel.library.wur.nl/WebQuery/testservice/new_xml';
        $this->assertEquals($expect, $request->getUri(), 'request 1 url');
        $expect = 'sub1=subval1&sub2=&child1=childval1&child2=childval2&sub3=subval+3';
        $this->assertEquals($expect, $request->getBody(), 'request 1 body');
        // check second request
        $request = $request_history[1]['request'];
        $this->assertEquals('POST', $request->getMethod(), 'request 2 method');
        $expect = 'http://devel.library.wur.nl/WebQuery/testservice/new_record';
        $this->assertEquals($expect, $request->getUri(), 'request 2 url');
        $expect = 'sub1=subval1&sub2=&child1=childval1&child2=childval2&sub3=subval+3';
        $this->assertEquals($expect, $request->getBody(), 'request 2 body');

    }


}

/***********  Helper Functions    **************/

function get_test_xml() {

    $xml_txt = <<<EOT
<record>
    <sub1>subval1</sub1>
    <sub2>
        <child1>childval1</child1>
        <child2>childval2</child2>
    </sub2>
    <sub3>subval 3</sub3>
</record>
EOT;
    $wq = new \Library\Webquery();
    return $wq->parse_xml($xml_txt);
}


function get_mock_httpclient(array $mock_responses, array &$history = null) {

    foreach ($mock_responses as $key => $value) {
        if (is_int($value)) {
            $mock_responses[$key] = new \GuzzleHttp\Psr7\Response($value);
        }
    }
    $mock_handler = new \GuzzleHttp\Handler\MockHandler($mock_responses);
    $mock_stack = \GuzzleHttp\HandlerStack::create($mock_handler);
    if (isset($history)) {
        $mock_history = \GuzzleHttp\Middleware::history($history);
        $mock_stack->push($mock_history);
    }
    return new \GuzzleHttp\Client(['handler' => $mock_stack]);
}