Commit 39e70687 authored by Patrick Barroca's avatar Patrick Barroca 😁
Browse files

dev #152400 : new electre provider API version

parent a5b97654
Pipeline #16779 passed with stage
in 39 seconds
......@@ -63,9 +63,6 @@ class Media extends ModelAbstract {
if (!$this->getCreatedAt())
$this->setCreatedAt($datenow);
$this->setUpdatedAt($datenow);
if (!$this->fileExists())
$this->getPelliculeFileSystem()->download($this);
}
......
<?php
namespace Pellicule\Providers;
use \Fig\Http\Message\StatusCodeInterface;
use \Pellicule\Models\Media;
use \Pellicule\Models\Record;
use \Pellicule\FileSystem;
class ElectreNg extends Provider {
const
ID = 'electre_ng',
TOKEN_URL = 'https://login.electre-ng-horsprod.com/auth/realms/electre/protocol/openid-connect/token',
API_URL = 'https://api.demo.electre-ng-horsprod.com/notices/ean/{ean}',
CLIENT_ID = 'api-client',
ID_KEY = 'client_id',
SECRET_KEY = 'client_secret';
protected
$_id,
$_secret;
public function __construct($credentials) {
$this->_id = $credentials[static::ID_KEY] ?? '';
$this->_secret = $credentials[static::SECRET_KEY] ?? '';
}
public function fetchRecord() {
// basic guards
if (!$this->_id || !$this->_secret)
return $this->_newError(StatusCodeInterface::STATUS_UNAUTHORIZED, 'invalid_credentials');
if (!$ean = $this->_getIsbnOrEan())
return $this->_newError(StatusCodeInterface::STATUS_BAD_REQUEST, 'missing_param');
// getting access_token
try {
$response = static::newHttpClient()->submitForm(static::TOKEN_URL,
['grant_type' => 'password',
'client_id' => static::CLIENT_ID,
'username' => $this->_id,
'password' => $this->_secret]);
} catch(\Exception $e) {
return $this->_newError(StatusCodeInterface::STATUS_GATEWAY_TIMEOUT,
'no_answer_from_gateway');
}
if ($response->getStatusCode() != StatusCodeInterface::STATUS_OK
|| (!$body = $response->getBody())
|| 0 == $body->getSize())
return $this->_newError(StatusCodeInterface::STATUS_BAD_GATEWAY, 'provider_error');
if ((!$json_response = $this->_parseJsonResponse($response))
|| isset($json_response->error)
|| !isset($json_response->access_token))
return $this->_newError(StatusCodeInterface::STATUS_BAD_GATEWAY, 'provider_error');
$access_token = $json_response->access_token;
$token_type = $json_response->token_type ?? 'Bearer';
// getting record info
try {
$response = static::newHttpClient()
->get(str_replace('{ean}', $ean, static::API_URL),
['Authorization' => $token_type . ' ' . $access_token]);
} catch(\Exception $e) {
return $this->_newError(StatusCodeInterface::STATUS_GATEWAY_TIMEOUT,
'no_answer_from_gateway');
}
if ($response->getStatusCode() != StatusCodeInterface::STATUS_OK
|| (!$body = $response->getBody())
|| 0 == $body->getSize())
return $this->_newError(StatusCodeInterface::STATUS_BAD_GATEWAY, 'provider_error');
if ((!$json_response = $this->_parseJsonResponse($response))
|| (!$records = $json_response->notices ?? [])
|| (!$cover_url = $records[0]->imageCouverture ?? false))
return $this->_newError(StatusCodeInterface::STATUS_BAD_GATEWAY, 'provider_error');
// get cover
try {
$response = static::newHttpClient()->get($cover_url);
} catch(\Exception $e) {
return $this->_newError(StatusCodeInterface::STATUS_GATEWAY_TIMEOUT,
'no_answer_from_gateway');
}
$media = (new Media)
->setProvider($this->providerName())
->setUrl($cover_url)
->beCover()
->setFullsizeFromIdentifier($ean)
;
if (!(new FileSystem)->writeMediaFrom($media, $response))
return $this->_newError(StatusCodeInterface::STATUS_INTERNAL_SERVER_ERROR,
'error_writing_cover');
$record = (new Record)
->updateAttributes($this->_search_args)
->setMedia([$media]);
return (new FetchRecordResult)->beSuccess($record);
}
public function providerName() {
return 'Electre';
}
}
......@@ -11,7 +11,8 @@ class RemoteProviders {
public function __construct() {
$this->_providers = new Collection([ElectreRest2::class,
$this->_providers = new Collection([ElectreNg::class,
ElectreRest2::class,
Electre::class,
Orb::class]);
}
......
......@@ -34,16 +34,15 @@ class FileSystemMediaDownloadTest extends TestCase {
'ean' => '9782259228190',
'ark' => 'https://catalogue.bnf.fr/ark:/12148/cb445155569']);
(new Media())
->updateAttributes(['record_id'=> 1,
'type' => 'cover',
'url' => 'http://image.org/city.jpg',
'provider' => 'Me',
'fullsize' => '/images/fullsize/cover/2/2/5/9/2259228194',
'created_at' => '2020-01-13 08:00:00',
'updated_at' => '2020-01-16 08:00:00'
])
->save();
$this->_media = Media::newInstance(['record_id'=> 1,
'type' => 'cover',
'url' => 'http://image.org/city.jpg',
'provider' => 'Me',
'fullsize' => '/images/fullsize/cover/2/2/5/9/2259228194',
'created_at' => '2020-01-13 08:00:00',
'updated_at' => '2020-01-16 08:00:00'
]);
$this->_file_system->download($this->_media);
}
......@@ -62,6 +61,6 @@ class FileSystemMediaDownloadTest extends TestCase {
/** @test */
public function mediaShouldHaveFullsizeWithExtension() {
$this->assertEquals('/images/fullsize/cover/2/2/5/9/2259228194.jpg',
Media::find(1)->getFullsize());
$this->_media->getFullsize());
}
}
<?php
namespace Pellicule\Tests;
use \Fig\Http\Message\StatusCodeInterface;
use \Slim\Psr7\Headers;
use \Storm\FileSystem\Volatile;
use \Pellicule\Providers\ElectreNg;
use \Pellicule\FileSystem;
use \Pellicule\Models\Media;
abstract class MediaElectreNgTestCase extends TestCase {
protected $_credentials;
public function setUp() {
parent::setUp();
$this->_credentials = base64_encode(json_encode(['provider'=> 'electre_ng',
'client_id' => 'leeloo',
'client_secret' => 'multipass']));
}
protected function _dispatchAndAssertStatus(int $status_code) {
$this->dispatch('/1.0/media/isbn/9782818976173',
['Authorization' => ['Pellicule ' . $this->_credentials]]);
$this->assertResponseCode($status_code);
}
}
class MediaElectreNgBadAuthenticationTest extends MediaElectreNgTestCase {
/** @test */
public function withTokenTimeoutShouldRespondGatewayTimeout() {
$this->_http_client
->whenCalled('submitForm')
->willDo(function() { throw new \RuntimeException('timeout !'); })
;
$this->_dispatchAndAssertStatus(StatusCodeInterface::STATUS_GATEWAY_TIMEOUT);
}
/** @test */
public function withTokenNotFoundShouldRespondBadGateway() {
$this->_http_client
->whenCalled('submitForm')
->answers($this->_forgePSR7Response(['status' => StatusCodeInterface::STATUS_NOT_FOUND]))
;
$this->_dispatchAndAssertStatus(StatusCodeInterface::STATUS_BAD_GATEWAY);
}
/** @test */
public function withTokenNotJsonShouldRespondBadGateway() {
$this->_http_client
->whenCalled('submitForm')
->answers($this->_forgePSR7Response(['content' => '<!doctype html>']))
;
$this->_dispatchAndAssertStatus(StatusCodeInterface::STATUS_BAD_GATEWAY);
}
/** @test */
public function withTokenJsonErrorShouldRespondBadGateway() {
$content = json_encode(['error' => 'invalid_grant',
'error_description' => 'Invalid user credentials']);
$this->_http_client
->whenCalled('submitForm')
->answers($this->_forgePSR7Response(['content' => $content]))
;
$this->_dispatchAndAssertStatus(StatusCodeInterface::STATUS_BAD_GATEWAY);
}
}
class MediaElectreNgGoodAuthenticationTest extends MediaElectreNgTestCase {
public function setUp() {
parent::setUp();
$content = json_encode(['access_token' => 'ACCESS_TOKEN',
'expires_in' => 172800,
'refresh_expires_in' => 300,
'refresh_token' => 'REFRESH_TOKEN',
'token_type' => 'Bearer',
'not-before-policy' => 1637075208,
'session_state' => 'SESSION_STATE',
'scope' => 'profile email',
]);
$this->_http_client
->whenCalled('submitForm')
->answers($this->_forgePSR7Response(['content' => $content]))
;
}
/** @test */
public function withApiTimeoutShouldRespondGatewayTimeout() {
$this->_http_client
->whenCalled('get')
->with(str_replace('{ean}', '9782818976173', ElectreNg::API_URL),
['Authorization' => 'Bearer ACCESS_TOKEN'])
->willDo(function() { throw new \RuntimeException('Timeout !'); })
;
$this->_dispatchAndAssertStatus(StatusCodeInterface::STATUS_GATEWAY_TIMEOUT);
}
/** @test */
public function withApiNotAuthorizedShouldRespondBadGateway() {
$this->_http_client
->whenCalled('get')
->with(str_replace('{ean}', '9782818976173', ElectreNg::API_URL),
['Authorization' => 'Bearer ACCESS_TOKEN'])
->answers($this->_forgePSR7Response(['status' => StatusCodeInterface::STATUS_UNAUTHORIZED]))
;
$this->_dispatchAndAssertStatus(StatusCodeInterface::STATUS_BAD_GATEWAY);
}
/** @test */
public function withApiNotJsonShouldRespondBadGateway() {
$this->_http_client
->whenCalled('get')
->with(str_replace('{ean}', '9782818976173', ElectreNg::API_URL),
['Authorization' => 'Bearer ACCESS_TOKEN'])
->answers($this->_forgePSR7Response(['content' => '<!doctype html>']))
;
$this->_dispatchAndAssertStatus(StatusCodeInterface::STATUS_BAD_GATEWAY);
}
/** @test */
public function withApiUnknownJsonFormatShouldRespondBadGateway() {
$this->_http_client
->whenCalled('get')
->with(str_replace('{ean}', '9782818976173', ElectreNg::API_URL),
['Authorization' => 'Bearer ACCESS_TOKEN'])
->answers($this->_forgePSR7Response(['content' => json_encode(['unknown' => 'format'])]))
;
$this->_dispatchAndAssertStatus(StatusCodeInterface::STATUS_BAD_GATEWAY);
}
/** @test */
public function withApiValidJsonShouldRespondFoundMedia() {
$record = ['eansUtilises' => [],
'isbnsUtilises' => [],
'desactive' => false,
'tableDesMatieres' => '',
'isbns' => ['978-28-18976-17-3'],
'passagesMedia' => null,
'imageCouverture' => 'https://media.server.com/images/image-id/b212dc4.jpg',
'legacyNoticeId' => '0-98378947',
'biographie' => null,
'source' => 'electre',
'noticeId' => '83749084704',
'catalogue' => 'Livre',
'isbnsJustes' => ['978-28-18976-17-3'],
'imagetteCouverture' => 'https://media.server.com/imagettes/image-id/b212dc4.jpg',
'mesChampsExtras' => null,
'eansErrones' => [],
'isbnsErrones' => [],
'eansJustes' => ['9782818976173'],
'bandesAnnonces' => null,
'extrait' => ['extraitUrl' => 'https://media.server.com/extraits/extrait-id/92ca98.epub',
'extraitFormat' => 'epub'],
];
$this->_http_client
->whenCalled('get')
->with(str_replace('{ean}', '9782818976173', ElectreNg::API_URL),
['Authorization' => 'Bearer ACCESS_TOKEN'])
->answers($this->_forgePSR7Response(['content' => json_encode(['total' => 1,
'notices' => [ $record ]])]))
->whenCalled('get')
->with('https://media.server.com/images/image-id/b212dc4.jpg')
->answers($this->_forgePSR7Response(['headers' => new Headers(['content-type' => 'image/jpg']),
'content' => 'image content']))
;
FileSystem::setBasePath('./images');
FileSystem::setFileSystem($filesystem = new Volatile);
Media::setFileSystem($filesystem);
$this->dispatch('/1.0/media/isbn/9782818976173',
['Authorization' => ['Pellicule ' . $this->_credentials]]);
$this->assertResponseCode(StatusCodeInterface::STATUS_OK);
$this->assertEquals('/fullsize/cover/9/7/8/2/9782818976173.jpg',
Media::find(1)->getFullsize());
$this->assertEquals('image content',
$filesystem->fileGetContents('/images/fullsize/cover/9/7/8/2/9782818976173.jpg'));
$json_response = json_decode((string)$this->_response->getBody());
$this->assertEquals('http://pellicule.io:8899/images/fullsize/cover/9/7/8/2/9782818976173.jpg',
$json_response->media[0]->fullsize);
$this->assertEquals('Electre',
$json_response->media[0]->provider);
$this->assertEquals('https://media.server.com/images/image-id/b212dc4.jpg',
$json_response->media[0]->url);
}
}
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