Commit b28338f9 authored by Laurent's avatar Laurent
Browse files

Refactoring

parent 26366cb1
Pipeline #9173 passed with stage
in 1 minute and 29 seconds
......@@ -6,7 +6,7 @@ use Slim\Psr7\Request;
use Slim\Psr7\Response;
use Fig\Http\Message\StatusCodeInterface;
use Pellicule\Models\Record;
use Pellicule\Models\Source\Electre;
use Pellicule\Providers\Electre;
class Media {
public function __invoke($request, $response, $args) {
......@@ -24,36 +24,34 @@ class Media {
if (!$record)
return new \Slim\Psr7\Response(StatusCodeInterface::STATUS_NOT_FOUND);
$record->save();
$datas = [ 'media' => array_map(
function($media) {
return [
'original' => $media->getUrl(),
'type' => $media->getType()
];
},
$record->getMedia()) ];
$response->getBody()->write(json_encode($datas));
$response->getBody()->write($record->asJSON());
return $response->withHeader('Content-Type', 'application/json');
}
protected function _fetchRecordFromProviders($request, $args){
$credentials = (new \Storm\Model\Collection($request->getHeader('Authorization')))
$credentials = $this->_parseAuthorizationHeader($request);
return (new Electre($credentials[0]))->fetchRecord($this->_processParams($args));
}
protected function _parseAuthorizationHeader($request){
return (new \Storm\Model\Collection($request->getHeader('Authorization')))
->select(function($header)
{
return strpos('Pellicule ', $header) == 0;
})
->collect(function($header)
{
return json_decode(base64_decode(str_replace('Pellicule ', '', $header)), true);
})->getArrayCopy();
return (new Electre($credentials[0]))->fetchRecord($this->_processParams($args));
->collect([$this, 'decodeAuthorizationHeader'])->getArrayCopy();
}
public function decodeAuthorizationHeader($string){
return json_decode(base64_decode(str_replace('Pellicule ', '', $string)), true);
}
protected function _processParams($args){
if (!$args)
return;
......
......@@ -15,4 +15,17 @@ class Record extends ModelAbstract {
]
];
public function asJSON(){
$datas = [ 'media' => array_map(
function($media) {
return [
'original' => $media->getUrl(),
'type' => $media->getType()
];
},
$this->getMedia()) ];
return json_encode($datas);
}
}
\ No newline at end of file
<?php
namespace Pellicule\Models\Source;
use \Buzz\Browser;
use \Buzz\Client\FileGetContents;
use \Slim\Psr7\Factory\ResponseFactory;
use \Slim\Psr7\Factory\RequestFactory;
use \Slim\Psr7\Request;
class Electre extends \Pellicule\Models\Source {
private $_provider,
$_client_id,
$_client_secret;
public function __construct($data = []){
$this->_provider = "Electre";
if (!array_key_exists('client_id',$data))
return $this;
$this->_client_id = $data['client_id'];
if (!array_key_exists('client_secret',$data))
return $this;
$this->_client_secret = $data['client_secret'];
return $this;
}
public function fetchRecord($search_args){
$token = $this->getToken($this->_client_id, $this->_client_secret);
$links = $this->getAllLinks($token, $search_args['isbn']);
$record = new Record();
$record
->setIsbn($search_args['isbn'])
->setEan($search_args['ean']);
$record
->save();
$links = new \Storm\Model\Collection($links);
$medialist =
$links->select(
function($element){
return in_array($element->rel,['cover','coverCopy']);
})
->eachDo(function($link) use ($record){
$media = (new \Pellicule\Models\Media())
->setProvider('Electre')
->setOriginal($link->href)
->setUrl($link->href)
->setType( (($link->rel=='coverCopy')?"back_cover":$link->rel))
->setRecord($record);
$media->save();
return $media;
});
return $record;
}
public function getTokenResponse($login, $secret){
$browser = static::newHttpClient();
$response = $browser->post("https://electre3staging-idp.bvdep.com/connect/token",[],http_build_query(['client_id' => $login,
'client_secret' =>$secret,
'grant_type'=> 'client_credentials',
'scope'=>'webapi']));
return $response;
}
public function getToken($login, $secret){
return $this->_parseJsonResponse($this->getTokenResponse($login, $secret))->access_token;
}
public function getAllLinks($token, $ean){
return $this->_parseJsonResponse($this->getAllLinksResponse($token, $ean))->_links;
}
public function getAllLinksResponse($token, $ean){
$browser = static::newHttpClient();
$response = $browser->get("https://electre3staging-api.bvdep.com/v1.0/eans/$ean",['Authorization'=>'Bearer '.$token]);
return $response;
}
}
<?php
namespace Pellicule\Providers;
use \Buzz\Browser;
use \Buzz\Client\FileGetContents;
use \Slim\Psr7\Factory\ResponseFactory;
use \Slim\Psr7\Factory\RequestFactory;
use \Slim\Psr7\Request;
use \Pellicule\Models\Record;
class Electre extends Provider {
const
TOKEN_END_POINT = 'https://electre3staging-idp.bvdep.com',
API_END_POINT = 'https://electre3staging-api.bvdep.com';
protected
$_client_id,
$_client_secret;
public function __construct($data = []){
if (!array_key_exists('client_id',$data))
return $this;
$this->_client_id = $data['client_id'];
if (!array_key_exists('client_secret',$data))
return $this;
$this->_client_secret = $data['client_secret'];
}
public function providerName() {
return 'Electre';
}
public function fetchRecord($search_args) {
$token = $this->_getToken($this->_client_id, $this->_client_secret);
$links = $this->_getAllLinks($token, $this->_getIsbnOrEan($search_args));
$medialist =
$links->select(
function($element){
return in_array($element->rel, ['cover','coverCopy']);
})
->collect(function($link)
{
return (new \Pellicule\Models\Media())
->setProvider($this->providerName())
->setOriginal($link->href)
->setUrl($link->href)
->setType( (($link->rel=='coverCopy')
? 'back_cover'
: $link->rel));
});
return (new Record())
->updateAttributes($search_args)
->setMedia($medialist);
}
protected function _getIsbnOrEan($search_args) {
if (isset($search_args['ean']))
return $search_args['ean'];
return $search_args['isbn'];
}
protected function _getToken($login, $secret){
$browser = static::newHttpClient();
$response = $browser->post(static::TOKEN_END_POINT . '/connect/token',
[],
http_build_query(['client_id' => $login,
'client_secret' =>$secret,
'grant_type'=> 'client_credentials',
'scope'=>'webapi']));
return $this->_parseJsonResponse($response)->access_token;
}
public function _getAllLinks($token, $ean){
$browser = static::newHttpClient();
$response = $browser->get(static::API_END_POINT . '/v1.0/eans/' . $ean,
['Authorization'=>'Bearer '. $token]);
return new \Storm\Model\Collection( $this->_parseJsonResponse($response)->_links );
}
}
<?php
namespace Pellicule\Models;
namespace Pellicule\Providers;
use \Buzz\Browser;
use \Buzz\Client\FileGetContents;
......@@ -8,9 +8,11 @@ use \Slim\Psr7\Factory\RequestFactory;
use \Slim\Psr7\Request;
abstract class Source {
abstract class Provider {
protected static $_default_http_client;
abstract public function providerName();
abstract public function fetchRecord($search_args);
static public function newHttpClient() {
......
<?php
namespace Pellicule\Tests;
class BrowserMockBuilder {
protected $_mock;
public function __construct() {
$stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$this->_mock = \Storm\Test\ObjectWrapper::mock('from ' . $stack[0]['file'] . ':' . $stack[0]['line']);
}
public function expectPost($post, $response) {
$post = array_merge(['url' => '', 'headers' => [], 'body' => []],
$post);
$response = array_merge(['status' => 200, 'headers' => null, 'content' => ''],
$response);
$psr7_response = new \Slim\Psr7\Response($response['status'],
$response['headers'],
(new \Slim\Psr7\Factory\StreamFactory())->createStream($response['content']));
$this
->_mock
->whenCalled('post')
->with($post['url'],
$post['headers'],
http_build_query($post['body']))
->answers($this->_forgePSR7Response($response));
return $this;
}
public function expectGet($get, $response) {
$get = array_merge(['url' => '', 'headers' => []],
$get);
$this
->_mock
->whenCalled('get')
->with($get['url'],
$get['headers'])
->answers($this->_forgePSR7Response($response));
return $this;
}
public function getMock() {
return $this->_mock;
}
protected function _forgePSR7Response($response) {
$response = array_merge(['status' => 200, 'headers' => null, 'content' => ''],
$response);
return new \Slim\Psr7\Response($response['status'],
$response['headers'],
(new \Slim\Psr7\Factory\StreamFactory())->createStream($response['content']));
}
}
......@@ -5,7 +5,8 @@ namespace Pellicule\Tests;
use Pellicule\AppFactory;
use Pellicule\Models\Record;
use Pellicule\Models\Media;
use Pellicule\Models\Source\Electre;
use Pellicule\Providers\Electre;
class MediaGetTest extends TestCase {
protected $_response;
......@@ -82,14 +83,16 @@ class MediaGetTest extends TestCase {
$this->httpGet($url));
}
public function urlsFailuresToTest(){
return [['/1.0/media/isbn/2413004084', 404]
,['/1.0/media/UNEAUTREREQUETE', 501]];
}
/** @test
* @dataProvider urlsFailuresToTest
/**
* @test
* @dataProvider urlsFailuresToTest
*/
public function whenCalledWithErroneousDataResponseCodeShouldBeCorrect($url, $status) {
$this->assertEquals($status,
......@@ -99,46 +102,26 @@ class MediaGetTest extends TestCase {
class MediaWithElectreTest extends TestCase {
use \Storm\Test\THelpers;
// use \Slim\Psr7\Response;
// use \Slim\Psr7\Factory\StreamFactory;
public function setUp() {
abstract class MediaWithElectreTestCase extends TestCase {
public function setUp(){
parent::setUp();
$mock_browser = (new BrowserMockBuilder())
->expectPost(['url' => 'https://electre3staging-idp.bvdep.com/connect/token',
'body' => ['client_id' => 'multipass',
'client_secret' => 'leeloo',
'grant_type'=> 'client_credentials',
'scope'=>'webapi']],
['content' => '{"access_token":"MyPr3ttyT0k3n","expires_in":3600,"token_type":"Bearer"}'])
$ident_response = new \Slim\Psr7\Response(
200,
null,
(new \Slim\Psr7\Factory\StreamFactory())->createStream('{"access_token":"MyPr3ttyT0k3n","expires_in":3600,"token_type":"Bearer"}')
);
$data_response = new \Slim\Psr7\Response(
200,
null,
(new \Slim\Psr7\Factory\StreamFactory())->createStream('{"_links":[{"rel":"cover","href":"http://image.org/city.jpg"},{"rel":"coverCopy","href":"htt//image.org/cityback.jpg"},{"rel":"summary","href":"https://electre3staging-api.bvdep.com/v1.0/eans/2259228194/summary"},{"rel":"biographie","href":"https://electre3staging-api.bvdep.com/v1.0/eans/2259228194/biography"}]}'));
$mock_browser = $this->mock()
->whenCalled('post')
->with('https://electre3staging-idp.bvdep.com/connect/token',[],http_build_query(['client_id' => 'multipass',
'client_secret' => 'leeloo',
'grant_type'=> 'client_credentials',
'scope'=>'webapi']))
->answers($ident_response)
->expectGet(['url' => 'https://electre3staging-api.bvdep.com/v1.0/eans/2259228194',
'headers' => ['Authorization' => 'Bearer MyPr3ttyT0k3n']],
['content' => '{"_links":[{"rel":"cover","href":"http://image.org/city.jpg"},{"rel":"coverCopy","href":"htt//image.org/cityback.jpg"},{"rel":"summary","href":"https://electre3staging-api.bvdep.com/v1.0/eans/2259228194/summary"},{"rel":"biographie","href":"https://electre3staging-api.bvdep.com/v1.0/eans/2259228194/biography"}]}'])
->whenCalled('get')
->with('https://electre3staging-api.bvdep.com/v1.0/eans/2259228194', ['Authorization' => 'Bearer MyPr3ttyT0k3n'])
->answers($data_response)
->beStrict();
->getMock();
Electre::setDefaultHttpClient($mock_browser);
$this->_response = $this->httpGet('/1.0/media/isbn/2259228194',
['Authorization' => ['Pellicule ' . base64_encode(json_encode([ 'provider'=> 'electre',
'client_secret'=>'leeloo',
'client_id'=>'multipass']))]]);
}
......@@ -146,21 +129,53 @@ class MediaWithElectreTest extends TestCase {
public function whenCalledWithElectreIdentifiersAndDataNotInCacheShouldReturnExpectedJSON() {
$return_data =
[ 'media' => [
['original'=> 'http://image.org/city.jpg',
'type' => 'cover'],
['original' => 'http;//image.org/cityback.jpg',
'type' => 'back_cover']
]
['original'=> 'http://image.org/city.jpg',
'type' => 'cover'],
['original' => 'http;//image.org/cityback.jpg',
'type' => 'back_cover']
]
];
$this->assertJSON(json_encode($return_data),
$this->_response
$this->_response
);
}
}
class MediaWithElectreOnIsbnTest extends MediaWithElectreTestCase {
public function setUp() {
parent::setUp();
$this->_response = $this->httpGet('/1.0/media/isbn/2259228194',
['Authorization' => ['Pellicule ' . base64_encode(json_encode(['provider'=> 'electre',
'client_secret'=>'leeloo',
'client_id'=>'multipass']))]]);
}
/** @test */
public function databaseShouldContainsRecordForIsbn2259228194() {
$this->assertNotNull(Record::findFirstBy(['isbn' => '2259228194']));
}
}
class MediaWithElectreOnEanTest extends MediaWithElectreTestCase {
public function setUp() {
parent::setUp();
$this->_response = $this->httpGet('/1.0/media/ean/2259228194',
['Authorization' => ['Pellicule ' . base64_encode(json_encode(['provider'=> 'electre',
'client_secret'=>'leeloo',
'client_id'=>'multipass']))]]);
}
/** @test */
public function databaseShouldContainsRecordForEan2259228194() {
$this->assertNotNull(Record::findFirstBy(['ean' => '2259228194']));
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment