Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/fliglio/web into 2.1.x
Browse files Browse the repository at this point in the history
  • Loading branch information
benschw committed Jun 10, 2015
2 parents aeb316f + af69c6b commit 7422ad0
Show file tree
Hide file tree
Showing 11 changed files with 286 additions and 27 deletions.
29 changes: 29 additions & 0 deletions Fliglio/Web/CollectionApiMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Fliglio\Web;

class CollectionApiMapper implements ApiMapper {

private $mapper;

public function __construct(ApiMapper $mapper) {
$this->mapper = $mapper;
}

public function marshal($entities) {
$vos = [];

foreach ($entities as $key => $entity) {
$vos[$key] = $this->mapper->marshal($entity);
}
return $vos;
}
public function unmarshal($serialized) {
$entities = [];

foreach ($serialized as $key => $vo) {
$entities[$key] = $this->mapper->unmarshal($vo);
}
return $entities;
}
}
42 changes: 42 additions & 0 deletions Fliglio/Web/Entity.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Fliglio\Web;

use Fliglio\Http\Exceptions\BadRequestException;

class Entity {
private $body;

public function __construct($body, $contentType) {
$this->body = $body;
$this->contentType = $contentType;
}
public function get() {
return $this->body;
}
public function bind($entityType) {
if (!in_array('Fliglio\Web\MappableApi', class_implements($entityType))) {
throw new \Exception($entityType . " doesn't implement Fliglio\Web\MappableApi");
}

$arr = null;
switch($this->contentType) {

// assume json
case 'application/json':
default:
$arr = json_decode($this->body, true);
}

$entity = $entityType::unmarshal($arr);

if ($entity instanceof Validation) {
try {
$entity->validate();
} catch (ValidationException $e) {
throw new BadRequestException($e->getMessage());
}
}
return $entity;
}
}
8 changes: 8 additions & 0 deletions Fliglio/Web/MappableApi.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Fliglio\Web;

interface MappableApi {
public function marshal();
public static function unmarshal($serialized);
}
22 changes: 22 additions & 0 deletions Fliglio/Web/MappableApiTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Fliglio\Web;

trait MappableApiTrait {

public function marshal() {
return self::getApiMapper()->marshal($this);
}
public static function unmarshal($valueObject) {
return self::getApiMapper()->unmarshal($valueObject);
}

public static function getClass() {
return get_called_class();
}
public static function getApiMapper() {
$className = self::getClass();
$mapperClassName = $className . 'ApiMapper';
return new $mapperClassName();
}
}
70 changes: 70 additions & 0 deletions test/ApiMapperTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php
namespace Fliglio\Web;

use Fliglio\Http\Http;
use Doctrine\Common\Annotations\AnnotationRegistry;

class ApiMapperTest extends \PHPUnit_Framework_TestCase {

public function testApiMapper() {

// given
$mapper = new FooApiMapper();

$entity = new Foo("foo");
$vo = ["myProp" => "foo"];

// when
$foundVo = $mapper->marshal($entity);
$foundEntity = $mapper->unmarshal($vo);

// then
$this->assertEquals($entity, $foundEntity);
$this->assertEquals($vo, $foundVo);
}

public function testStaticApiMapper() {

// given
$entity = new Foo("foo");
$vo = ["myProp" => "foo"];

// when
$foundVo = $entity->marshal();
$foundEntity = Foo::unmarshal($vo);

// then
$this->assertEquals($entity, $foundEntity);
$this->assertEquals($vo, $foundVo);
}
public function testStaticApiMapperWithoutNamingConvention() {

// given
$entity = new Bar("bar", new Foo("foo"), [new Foo("baz"), new Foo("biz")]);

// when
$vo = $entity->marshal();
$foundEntity = Bar::unmarshal($vo);

// then
$this->assertEquals($entity, $foundEntity);
}

public function testCollectionApiMapper() {

// given
$mapper = new CollectionApiMapper(new FooApiMapper());


$entities = [new Foo("foo"), new Foo("bar")];
$vo = [["myProp" => "foo"], ["myProp" => "bar"]];

// when
$foundVo = $mapper->marshal($entities);
$foundEntities = $mapper->unmarshal($vo);

// then
$this->assertEquals($entities, $foundEntities);
$this->assertEquals($vo, $foundVo);
}
}
13 changes: 9 additions & 4 deletions test/Bar.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
/**
*
*/
class Bar implements Validation {
class Bar implements Validation, MappableApi {
use ObjectValidationTrait;
use MappableApiTrait;

/**
* @Assert\EqualTo(
Expand All @@ -20,19 +21,23 @@ class Bar implements Validation {
/**
* @Assert\Valid
*/
private $foo; // FooApi
private $foo; // Foo

/**
* @Assert\Valid
*/
private $foos; // []FooApi
private $foos; // []Foo


public function __construct($n, $f, array $fs = array()) {
$this->name = $n;
$this->foo = $f;
$this->foos = $fs;
}

public static function getApiMapper() {
return new BarApiMapper();
}

public function getName() {
return $this->name;
Expand All @@ -43,4 +48,4 @@ public function getFoo() {
public function getFoos() {
return $this->foos;
}
}
}
24 changes: 24 additions & 0 deletions test/BarApiMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Fliglio\Web;

class BarApiMapper implements ApiMapper {

public function marshal($bar) {
$fooMapper = $bar->getFoo()->getApiMapper();
return [
'name' => $bar->getName(),
'foo' => $fooMapper->marshal($bar->getFoo()),
'foos' => (new CollectionApiMapper($fooMapper))->marshal($bar->getFoos()),
];
}

public function unmarshal($fooArr) {
$fooMapper = new FooApiMapper();
return new Bar(
$fooArr['name'],
$fooMapper->unmarshal($fooArr['foo']),
(new CollectionApiMapper($fooMapper))->unmarshal($fooArr['foos'])
);
}
}
71 changes: 65 additions & 6 deletions test/BodyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ class BodyTest extends \PHPUnit_Framework_TestCase {

public function setUp() {
AnnotationRegistry::registerAutoloadNamespace(
'Symfony\\Component\\Validator\\Constraints\\',
'Symfony\\Component\\Validator\\Constraints\\',
dirname(__DIR__) . "/vendor/symfony/validator"
);
}

public function testBindMapping() {

// given
$expected = new FooApi("foo");
$expected = new Foo("foo");
$fooJson = '{"myProp": "foo"}';

$body = new Body($fooJson, 'application/json');
$mapper = new FooApiMapper();

// when
$found = $body->bind($mapper);

Expand All @@ -35,15 +35,74 @@ public function testBindMapping() {
public function testBindValidationError() {

// given
$expected = new FooApi("bar");
$expected = new Foo("bar");
$fooJson = '{"myProp": "bar"}';

$body = new Body($fooJson, 'application/json');
$mapper = new FooApiMapper();

// when
$found = $body->bind($mapper);
}


}
public function testEntityMapping() {

// given
$expected = new Foo("foo");
$fooJson = '{"myProp": "foo"}';

$body = new Entity($fooJson, 'application/json');

// when
$found = $body->bind('Fliglio\Web\Foo');

// then
$this->assertEquals($expected, $found);
}

/**
* @expectedException \Exception
*/
public function testEntityBadApiClass() {

// given
$expected = new Foo("bar");
$fooJson = '{"myProp": "bar"}';

$body = new Entity($fooJson, 'application/json');

// when
$found = $body->bind('Fliglio\Web\Foodfsdfsdf'); // not a real class
}

/**
* @expectedException \Exception
*/
public function testEntityBadApiInterface() {

// given
$expected = new Foo("bar");
$fooJson = '{"myProp": "bar"}';

$body = new Entity($fooJson, 'application/json');

// when
$found = $body->bind('Fliglio\Web\FooMapper'); // valid class, wrong interface
}

/**
* @expectedException Fliglio\Http\Exceptions\BadRequestException
*/
public function testEntityValidationError() {

// given
$expected = new Foo("bar");
$fooJson = '{"myProp": "bar"}';

$body = new Entity($fooJson, 'application/json');

// when
$found = $body->bind('Fliglio\Web\Foo');
}
}
8 changes: 4 additions & 4 deletions test/FooApi.php → test/Foo.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@
/**
*
*/
class FooApi implements Validation {
class Foo implements Validation, MappableApi {
use ObjectValidationTrait;

use MappableApiTrait;
/**
* @Assert\EqualTo(
* value = "foo"
* )
*/
private $myProp;

public function __construct($p) {
public function __construct($p=null) {
$this->myProp = $p;
}

public function getMyProp() {
return $this->myProp;
}
}
}
4 changes: 2 additions & 2 deletions test/FooApiMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ public function marshal($foo) {
}

public function unmarshal($fooArr) {
return new FooApi($fooArr['myProp']);
return new Foo($fooArr['myProp']);
}
}
}
Loading

0 comments on commit 7422ad0

Please sign in to comment.