Skip to content

Commit

Permalink
article image api changes
Browse files Browse the repository at this point in the history
article image tests
db structure changes
  • Loading branch information
Redjik committed Aug 27, 2015
1 parent 87dbcd5 commit 8db2f2e
Show file tree
Hide file tree
Showing 9 changed files with 181 additions and 78 deletions.
75 changes: 7 additions & 68 deletions api/app/Http/Controllers/ArticleImageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,79 +2,18 @@

namespace App\Http\Controllers;

use App\Models\Image;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Request;
use Spira\Model\Model\BaseModel;
use Spira\Responder\Response\ApiResponse;
use App\Http\Transformers\EloquentModelTransformer;
use App\Models\Article;


class ArticleImageController extends ChildEntityController
{
/**
* Put many entities.
*
* @param Request $request
* @param string $id
* @param $group
* @return ApiResponse
*/
public function putMany(Request $request, $id, $group)
{
$parent = $this->findParentEntity($id);

$requestCollection = $request->data;
$this->validateRequestCollection($requestCollection, $this->getValidationRules());

$existingChildModels = Image::whereIn('image_id', $this->getIds($requestCollection, 'image_id'))->get();
protected $relationName = 'imagesPivot';

$childModels = $this->getChildModel()
->hydrateRequestCollection($requestCollection, $existingChildModels)
->each(function (BaseModel $model) {
if (!$model->exists) {
$model->save();
}
});

foreach ($childModels as $childModel) {
$this->getRelation($parent)->attach($childModel,['group_type'=>$group]);
}

return $this->getResponse()
->transformer($this->getTransformer())
->createdCollection($childModels);
}

/**
* Delete an entity.
*
* @param string $id
* @param string $childId
* @param $group
* @return ApiResponse
* @throws \Exception
*/
public function deleteOne($id, $childId, $group)
public function __construct(Article $parentModel, EloquentModelTransformer $transformer)
{
$model = $this->findParentEntity($id);
$childModel = $this->findOrFailChildEntity($childId, $model, $group);

$childModel->pivot->delete();

return $this->getResponse()->noContent();
parent::__construct($parentModel, $transformer);
}

/**
* @param $id
* @param BaseModel $parent
* @param $group
* @return BaseModel
*/
protected function findOrFailChildEntity($id, BaseModel $parent, $group)
{
try {
return $this->getRelation($parent)->wherePivot('group_type','=',$group)->findOrFail($id);
} catch (ModelNotFoundException $e) {
throw $this->notFoundException($this->getChildModel()->getKeyName());
}
}

}
2 changes: 0 additions & 2 deletions api/app/Http/Controllers/ChildEntityController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ class ChildEntityController extends ApiController
{
use RequestValidationTrait;

protected $validateParentIdRule = null;
protected $validateChildIdRule = null;
protected $relationName = null;

/**
Expand Down
3 changes: 1 addition & 2 deletions api/app/Http/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,8 @@
$app->put('{id}/tags', 'App\Http\Controllers\ArticleTagController@putMany');

$app->get('{id}/images', 'App\Http\Controllers\ArticleImageController@getAll');
$app->get('{id}/images/{group}', 'App\Http\Controllers\ArticleImageController@getAll');
$app->put('{id}/images', 'App\Http\Controllers\ArticleImageController@putMany');
$app->delete('{id}/image/{childId}/{group}', 'App\Http\Controllers\ArticleImageController@deleteOne');
$app->delete('{id}/images', 'App\Http\Controllers\ArticleImageController@deleteMany');
});

$app->group(['prefix' => 'tags'], function (Application $app) {
Expand Down
7 changes: 6 additions & 1 deletion api/app/Models/Article.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@ public function tags()
*/
public function images()
{
return $this->belongsToMany(Image::class, 'image_article')->withPivot('group_type');
return $this->belongsToMany(Image::class, 'image_article');
}

public function imagesPivot()
{
return $this->hasMany(ArticleImage::class);
}
}
16 changes: 14 additions & 2 deletions api/app/Models/ArticleImage.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@

class ArticleImage extends BaseModel
{
public $table = 'article_image_id';
public $table = 'article_image';

protected $primaryKey = 'image_id';
protected $primaryKey = 'article_image_id';

public $timestamps = false;

public $with = ['image'];

/**
* The attributes that are mass assignable.
*
Expand All @@ -35,4 +37,14 @@ class ArticleImage extends BaseModel
'alt' => 'string|max:255',
'title' => 'string|max:255',
];

public function image()
{
return $this->hasOne(Image::class,'image_id','image_id');
}

public function article()
{
return $this->hasOne(Article::class);
}
}
2 changes: 1 addition & 1 deletion api/database/factories/ModelFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@
return [
'article_image_id' => $faker->uuid,
'image_type' => $faker->randomElement(['primary','thumbnail','carousel']),
'position' => $faker->numberBetween(1,35000),
'position' => $faker->numberBetween(1,32000),
'alt' => $faker->sentence,
'title' => $faker->sentence
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function up()
$table->string('title',255)->nullable();
$table->smallInteger('position',false,true)->default(1);

$table->index(['image_id','article_id']);
$table->unique(['image_id','article_id','image_type']);

$table->foreign('article_id')
->references('article_id')->on(\App\Models\Article::getTableName())
Expand Down
2 changes: 1 addition & 1 deletion api/database/seeds/ArticleSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function run()
$article->permalinks()->saveMany($permalinks);
$article->tags()->saveMany($tags);
foreach ($images as $image) {
$imageArticle = factory(ArticleImage::class)->create();
$imageArticle = factory(ArticleImage::class)->make();
$imageArticle->article_id = $article->article_id;
$imageArticle->image_id = $image->image_id;
$imageArticle->save();
Expand Down
150 changes: 150 additions & 0 deletions api/tests/integration/ArticleImageTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,156 @@
<?php

use App\Models\Article;
use App\Models\ArticleImage;
use App\Models\Image;

class ArticleImageTest extends TestCase
{
public function setUp()
{
parent::setUp();

App\Models\Article::flushEventListeners();
App\Models\Article::boot();

App\Models\Image::flushEventListeners();
App\Models\Image::boot();

App\Models\ArticleImage::flushEventListeners();
App\Models\ArticleImage::boot();
// Workaround for model event firing.
// The package Bosnadev\Database used for automatic UUID creation relies
// on model events (creating) to generate the UUID.
//
// Laravel/Lumen currently doesn't fire repeated model events during
// unit testing, see: https://github.com/laravel/framework/issues/1181
}

/**
* Prepare a factory generated entity to be sent as input data.
*
* @param Arrayable $entity
*
* @return array
*/
protected function prepareEntity($entity)
{
// We run the entity through the transformer to get the attributes named
// as if they came from the frontend.
$transformer = $this->app->make(\App\Http\Transformers\EloquentModelTransformer::class);
$entity = $transformer->transform($entity);
return $entity;
}

protected function addImagesToArticle(\App\Models\Article $article)
{
$images = factory(Image::class, 5)->create();
foreach ($images as $image) {
$imageArticle = factory(ArticleImage::class)->make();
$imageArticle->article_id = $article->article_id;
$imageArticle->image_id = $image->image_id;
$imageArticle->save();
}
}

public function testGetAll()
{
$article = factory(App\Models\Article::class)->create();
$this->addImagesToArticle($article);

$this->getJson('/articles/'.$article->article_id.'/images');
$object = json_decode($this->response->getContent());

$this->assertResponseOk();
$this->shouldReturnJson();
$this->assertJsonArray();
$this->assertJsonMultipleEntries();

$this->assertEquals(5, count($object));
$this->assertObjectHasAttribute('_image',current($object));
}

public function testPutManyNew()
{
$article = factory(App\Models\Article::class)->create();

$images = factory(Image::class, 5)->create();
$articleImages = [];
foreach ($images as $image) {
$imageArticle = factory(ArticleImage::class)->make();
$imageArticle->article_id = $article->article_id;
$imageArticle->image_id = $image->image_id;
$articleImages[]=$imageArticle;
}

$images = array_map(function ($entity) {
return $this->prepareEntity($entity);
}, $articleImages);

$childCount = \App\Models\Article::find($article->article_id)->imagesPivot->count();

$this->putJson('/articles/'.$article->article_id.'/images', $images);

$object = json_decode($this->response->getContent());

$this->assertResponseStatus(201);
$this->assertEquals($childCount + 5, \App\Models\Article::find($article->article_id)->imagesPivot->count());
$this->assertTrue(is_array($object));
$this->assertCount(5, $object);
}


public function testPutManyNewInvalid()
{
$article = factory(App\Models\Article::class)->create();

$images = factory(Image::class, 5)->create();
$articleImages = [];
foreach ($images as $image) {
$imageArticle = factory(ArticleImage::class)->make();
$imageArticle->article_id = $article->article_id;
$imageArticle->image_id = $image->image_id;
$articleImages[]=$imageArticle;
}

$images = array_map(function ($entity) {
return $this->prepareEntity($entity);
}, $articleImages);

foreach ($images as &$image) {
unset($image['articleId']);
}

$childCount = \App\Models\Article::find($article->article_id)->imagesPivot->count();

$this->putJson('/articles/'.$article->article_id.'/images', $images);

$object = json_decode($this->response->getContent());

$this->assertCount(5, $object->invalid);
$this->assertObjectHasAttribute('articleId', $object->invalid[0]);
$this->assertEquals($childCount, \App\Models\Article::find($article->article_id)->imagesPivot->count());
}



public function testDeleteMany()
{
/** @var Article $article */
$article = factory(App\Models\Article::class)->create();
$this->addImagesToArticle($article);

$childCount = \App\Models\Article::find($article->article_id)->imagesPivot->count();

$images = array_map(function ($entity) {
return $this->prepareEntity($entity);
}, $article->imagesPivot->all());

$this->deleteJson('/articles/'.$article->article_id.'/images', $images);

$this->assertResponseStatus(204);
$this->assertResponseHasNoContent();
$this->assertEquals($childCount - 5, \App\Models\Article::find($article->article_id)->imagesPivot->count());
}

}

0 comments on commit 8db2f2e

Please sign in to comment.