diff --git a/app/Bus/Commands/Component/CreateComponentCommand.php b/app/Bus/Commands/Component/CreateComponentCommand.php index eeb36054..4244f42c 100644 --- a/app/Bus/Commands/Component/CreateComponentCommand.php +++ b/app/Bus/Commands/Component/CreateComponentCommand.php @@ -74,6 +74,13 @@ final class CreateComponentCommand */ public $meta; + /** + * Tags string. + * + * @var string + */ + public $tags; + /** * The validation rules. * @@ -88,23 +95,25 @@ final class CreateComponentCommand 'group_id' => 'nullable|int', 'enabled' => 'nullable|bool', 'meta' => 'nullable|array', + 'tags' => 'nullable|string', ]; /** * Create a new add component command instance. * - * @param string $name - * @param string $description - * @param int $status - * @param string $link - * @param int $order - * @param int $group_id - * @param bool $enabled - * @param array|null $meta + * @param string $name + * @param string $description + * @param int $status + * @param string $link + * @param int $order + * @param int $group_id + * @param bool $enabled + * @param array|null $meta + * @param string|null $tags * * @return void */ - public function __construct($name, $description, $status, $link, $order, $group_id, $enabled, $meta) + public function __construct($name, $description, $status, $link, $order, $group_id, $enabled, $meta, $tags = null) { $this->name = $name; $this->description = $description; @@ -114,5 +123,6 @@ final class CreateComponentCommand $this->group_id = $group_id; $this->enabled = $enabled; $this->meta = $meta; + $this->tags = $tags; } } diff --git a/app/Bus/Commands/Component/UpdateComponentCommand.php b/app/Bus/Commands/Component/UpdateComponentCommand.php index 96550fd6..99093397 100644 --- a/app/Bus/Commands/Component/UpdateComponentCommand.php +++ b/app/Bus/Commands/Component/UpdateComponentCommand.php @@ -78,6 +78,13 @@ final class UpdateComponentCommand */ public $meta; + /** + * The tags. + * + * @var string|null + */ + public $tags; + /** * If this is true, we won't notify subscribers of the change. * @@ -114,11 +121,12 @@ final class UpdateComponentCommand * @param int|null $group_id * @param bool|null $enabled * @param array|null $meta + * @param string|null $tags * @param bool $silent * * @return void */ - public function __construct(Component $component, $name = null, $description = null, $status = null, $link = null, $order = null, $group_id = null, $enabled = null, $meta = null, $silent = null) + public function __construct(Component $component, $name = null, $description = null, $status = null, $link = null, $order = null, $group_id = null, $enabled = null, $meta = null, $tags = null, $silent = null) { $this->component = $component; $this->name = $name; @@ -129,6 +137,8 @@ final class UpdateComponentCommand $this->group_id = $group_id; $this->enabled = $enabled; $this->meta = $meta; + $this->tags = $tags; $this->silent = $silent; + $this->tags = $tags; } } diff --git a/app/Bus/Commands/Tag/ApplyTagCommand.php b/app/Bus/Commands/Tag/ApplyTagCommand.php deleted file mode 100644 index 1fbd7421..00000000 --- a/app/Bus/Commands/Tag/ApplyTagCommand.php +++ /dev/null @@ -1,51 +0,0 @@ - - */ -final class ApplyTagCommand -{ - /** - * The model to apply the tag to. - * - * @var \Illuminate\Database\Eloquent\Model - */ - public $model; - - /** - * The tag to apply. - * - * @var \CachetHQ\Cachet\Models\Tag - */ - public $tag; - - /** - * Create a new apply tag command instance. - * - * @param \Illuminate\Database\Eloquent\Model $model - * @param \CachetHQ\Cachet\Models\Tag $tag - * - * @return void - */ - public function __construct(Model $model, Tag $tag) - { - $this->model = $model; - $this->tag = $tag; - } -} diff --git a/app/Bus/Commands/Tag/CreateTagCommand.php b/app/Bus/Commands/Tag/CreateTagCommand.php deleted file mode 100644 index 69ae89eb..00000000 --- a/app/Bus/Commands/Tag/CreateTagCommand.php +++ /dev/null @@ -1,48 +0,0 @@ - - */ -final class CreateTagCommand -{ - /** - * The tag name. - * - * @var string - */ - public $name; - - /** - * The tag slug. - * - * @var string|null - */ - public $slug; - - /** - * Create a new create tag command instance. - * - * @param string $name - * @param string|null $slug - * - * @return void - */ - public function __construct($name, $slug = null) - { - $this->name = $name; - $this->slug = $slug; - } -} diff --git a/app/Bus/Commands/Tag/DeleteTagCommand.php b/app/Bus/Commands/Tag/DeleteTagCommand.php deleted file mode 100644 index 7ab95001..00000000 --- a/app/Bus/Commands/Tag/DeleteTagCommand.php +++ /dev/null @@ -1,41 +0,0 @@ - - */ -final class DeleteTagCommand -{ - /** - * The tag. - * - * @var \CachetHQ\Cachet\Models\Tag - */ - public $tag; - - /** - * Create a new delete tag command instance. - * - * @param \CachetHQ\Cachet\Models\Tag $tag - * - * @return void - */ - public function __construct(Tag $tag) - { - $this->tag = $tag; - } -} diff --git a/app/Bus/Commands/Tag/UpdateTagCommand.php b/app/Bus/Commands/Tag/UpdateTagCommand.php deleted file mode 100644 index f2747500..00000000 --- a/app/Bus/Commands/Tag/UpdateTagCommand.php +++ /dev/null @@ -1,59 +0,0 @@ - - */ -final class UpdateTagCommand -{ - /** - * The tag. - * - * @var \CachetHQ\Cachet\Models\Tag - */ - public $tag; - - /** - * The new tag name. - * - * @var string|null - */ - public $name; - - /** - * The new tag slug. - * - * @var string|null - */ - public $slug; - - /** - * Create a new update tag command instance. - * - * @param \CachetHQ\Cachet\Models\Tag $tag - * @param string|null $name - * @param string|null $slug - * - * @return void - */ - public function __construct(Tag $tag, $name, $slug) - { - $this->tag = $tag; - $this->name = $name; - $this->slug = $slug; - } -} diff --git a/app/Bus/Handlers/Commands/Component/CreateComponentCommandHandler.php b/app/Bus/Handlers/Commands/Component/CreateComponentCommandHandler.php index d9bcc339..867f49fb 100644 --- a/app/Bus/Handlers/Commands/Component/CreateComponentCommandHandler.php +++ b/app/Bus/Handlers/Commands/Component/CreateComponentCommandHandler.php @@ -53,6 +53,15 @@ class CreateComponentCommandHandler { $component = Component::create($this->filter($command)); + // Sync the tags into the component. + if ($command->tags) { + collect(preg_split('/ ?, ?/', $command->tags))->filter()->map(function ($tag) { + return trim($tag); + })->pipe(function ($tags) use ($component) { + $component->attachTags($tags); + }); + } + event(new ComponentWasCreatedEvent($this->auth->user(), $component)); return $component; diff --git a/app/Bus/Handlers/Commands/Component/UpdateComponentCommandHandler.php b/app/Bus/Handlers/Commands/Component/UpdateComponentCommandHandler.php index 1fdaf007..f0ad1e44 100644 --- a/app/Bus/Handlers/Commands/Component/UpdateComponentCommandHandler.php +++ b/app/Bus/Handlers/Commands/Component/UpdateComponentCommandHandler.php @@ -56,6 +56,15 @@ class UpdateComponentCommandHandler $component->update($this->filter($command)); + // Sync the tags into the component. + if ($command->tags) { + collect(preg_split('/ ?, ?/', $command->tags))->filter()->map(function ($tag) { + return trim($tag); + })->pipe(function ($tags) use ($component) { + $component->syncTags($tags); + }); + } + event(new ComponentWasUpdatedEvent($this->auth->user(), $component)); return $component; diff --git a/app/Bus/Handlers/Commands/Tag/ApplyTagCommandHandler.php b/app/Bus/Handlers/Commands/Tag/ApplyTagCommandHandler.php deleted file mode 100644 index 7f1c4f4b..00000000 --- a/app/Bus/Handlers/Commands/Tag/ApplyTagCommandHandler.php +++ /dev/null @@ -1,39 +0,0 @@ - - */ -class ApplyTagCommandHandler -{ - /** - * Handle the command. - * - * @param \CachetHQ\Cachet\Bus\Commands\Tag\ApplyTagCommand $command - * - * @return void - */ - public function handle(ApplyTagCommand $command) - { - Taggable::firstOrCreate([ - 'tag_id' => $command->tag->id, - 'taggable_id' => $command->model->id, - 'taggable_type' => $command->model->getTable(), - ]); - } -} diff --git a/app/Bus/Handlers/Commands/Tag/CreateTagCommandHandler.php b/app/Bus/Handlers/Commands/Tag/CreateTagCommandHandler.php deleted file mode 100644 index 71f616dd..00000000 --- a/app/Bus/Handlers/Commands/Tag/CreateTagCommandHandler.php +++ /dev/null @@ -1,39 +0,0 @@ - - */ -class CreateTagCommandHandler -{ - /** - * Handle the command. - * - * @param \CachetHQ\Cachet\Bus\Commands\Tag\CreateTagCommand $command - * - * @return \CachetHQ\Cachet\Models\Tag - */ - public function handle(CreateTagCommand $command) - { - return Tag::firstOrCreate([ - 'name' => $command->name, - 'slug' => $command->slug ? $command->slug : Str::slug($command->name), - ]); - } -} diff --git a/app/Bus/Handlers/Commands/Tag/DeleteTagCommandHandler.php b/app/Bus/Handlers/Commands/Tag/DeleteTagCommandHandler.php deleted file mode 100644 index 08189349..00000000 --- a/app/Bus/Handlers/Commands/Tag/DeleteTagCommandHandler.php +++ /dev/null @@ -1,34 +0,0 @@ - - */ -class DeleteTagCommandHandler -{ - /** - * Handle the command. - * - * @param \CachetHQ\Cachet\Bus\Commands\Tag\DeleteTagCommand $command - * - * @return \CachetHQ\Cachet\Models\Tag - */ - public function handle(DeleteTagCommand $command) - { - $command->tag->delete(); - } -} diff --git a/app/Bus/Handlers/Commands/Tag/UpdateTagCommandHandler.php b/app/Bus/Handlers/Commands/Tag/UpdateTagCommandHandler.php deleted file mode 100644 index 5a21d7d6..00000000 --- a/app/Bus/Handlers/Commands/Tag/UpdateTagCommandHandler.php +++ /dev/null @@ -1,38 +0,0 @@ - - */ -class UpdateTagCommandHandler -{ - /** - * Handle the command. - * - * @param \CachetHQ\Cachet\Bus\Commands\Tag\UpdateTagCommand $command - * - * @return void - */ - public function handle(UpdateTagCommand $command) - { - return $command->tag->update([ - 'name' => $command->name, - 'slug' => $command->slug ? $command->slug : Str::slug($command->name), - ]); - } -} diff --git a/app/Http/Controllers/Api/ComponentController.php b/app/Http/Controllers/Api/ComponentController.php index 609eeba6..9bda7b09 100644 --- a/app/Http/Controllers/Api/ComponentController.php +++ b/app/Http/Controllers/Api/ComponentController.php @@ -14,13 +14,10 @@ namespace CachetHQ\Cachet\Http\Controllers\Api; use CachetHQ\Cachet\Bus\Commands\Component\CreateComponentCommand; use CachetHQ\Cachet\Bus\Commands\Component\RemoveComponentCommand; use CachetHQ\Cachet\Bus\Commands\Component\UpdateComponentCommand; -use CachetHQ\Cachet\Bus\Commands\Tag\ApplyTagCommand; -use CachetHQ\Cachet\Bus\Commands\Tag\CreateTagCommand; use CachetHQ\Cachet\Models\Component; use GrahamCampbell\Binput\Facades\Binput; use Illuminate\Contracts\Auth\Guard; use Illuminate\Database\QueryException; -use Illuminate\Support\Collection; use Illuminate\Support\Facades\Request; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; @@ -84,25 +81,13 @@ class ComponentController extends AbstractApiController Binput::get('order'), Binput::get('group_id'), (bool) Binput::get('enabled', true), - Binput::get('meta', null) + Binput::get('meta'), + Binput::get('tags') )); } catch (QueryException $e) { throw new BadRequestHttpException(); } - if (Binput::has('tags')) { - $component->tags()->delete(); - - // The component was added successfully, so now let's deal with the tags. - Collection::make(preg_split('/ ?, ?/', $tags))->map(function ($tag) { - return trim($tag); - })->map(function ($tag) { - return execute(new CreateTagCommand($tag)); - })->each(function ($tag) use ($component) { - execute(new ApplyTagCommand($component, $tag)); - }); - } - return $this->item($component); } @@ -125,26 +110,14 @@ class ComponentController extends AbstractApiController Binput::get('order'), Binput::get('group_id'), Binput::get('enabled', $component->enabled), - Binput::get('meta', null), + Binput::get('meta'), + Binput::get('tags'), (bool) Binput::get('silent', false) )); } catch (QueryException $e) { throw new BadRequestHttpException(); } - if (Binput::has('tags')) { - $component->tags()->delete(); - - // The component was added successfully, so now let's deal with the tags. - Collection::make(preg_split('/ ?, ?/', $tags))->map(function ($tag) { - return trim($tag); - })->map(function ($tag) { - return execute(new CreateTagCommand($tag)); - })->each(function ($tag) use ($component) { - execute(new ApplyTagCommand($component, $tag)); - }); - } - return $this->item($component); } diff --git a/app/Http/Controllers/Dashboard/ComponentController.php b/app/Http/Controllers/Dashboard/ComponentController.php index 7e79c12d..c9c8e679 100644 --- a/app/Http/Controllers/Dashboard/ComponentController.php +++ b/app/Http/Controllers/Dashboard/ComponentController.php @@ -15,14 +15,10 @@ use AltThree\Validator\ValidationException; use CachetHQ\Cachet\Bus\Commands\Component\CreateComponentCommand; use CachetHQ\Cachet\Bus\Commands\Component\RemoveComponentCommand; use CachetHQ\Cachet\Bus\Commands\Component\UpdateComponentCommand; -use CachetHQ\Cachet\Bus\Commands\Tag\ApplyTagCommand; -use CachetHQ\Cachet\Bus\Commands\Tag\CreateTagCommand; use CachetHQ\Cachet\Models\Component; use CachetHQ\Cachet\Models\ComponentGroup; use GrahamCampbell\Binput\Facades\Binput; use Illuminate\Routing\Controller; -use Illuminate\Support\Arr; -use Illuminate\Support\Collection; use Illuminate\Support\Facades\View; /** @@ -113,7 +109,6 @@ class ComponentController extends Controller public function updateComponentAction(Component $component) { $componentData = Binput::get('component'); - $tags = Arr::pull($componentData, 'tags'); try { $component = execute(new UpdateComponentCommand( @@ -126,6 +121,7 @@ class ComponentController extends Controller $componentData['group_id'], $componentData['enabled'], null, // Meta data cannot be supplied through the dashboard yet. + $componentData['tags'], // Meta data cannot be supplied through the dashboard yet. true // Silent since we're not really making changes to the component (this should be optional) )); } catch (ValidationException $e) { @@ -135,17 +131,6 @@ class ComponentController extends Controller ->withErrors($e->getMessageBag()); } - $component->tags()->delete(); - - // The component was added successfully, so now let's deal with the tags. - Collection::make(preg_split('/ ?, ?/', $tags))->map(function ($tag) { - return trim($tag); - })->map(function ($tag) { - return execute(new CreateTagCommand($tag)); - })->each(function ($tag) use ($component) { - execute(new ApplyTagCommand($component, $tag)); - }); - return cachet_redirect('dashboard.components.edit', [$component->id]) ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.components.edit.success'))); } @@ -170,7 +155,6 @@ class ComponentController extends Controller public function createComponentAction() { $componentData = Binput::get('component'); - $tags = Arr::pull($componentData, 'tags'); try { $component = execute(new CreateComponentCommand( @@ -181,7 +165,8 @@ class ComponentController extends Controller $componentData['order'], $componentData['group_id'], $componentData['enabled'], - null // Meta data cannot be supplied through the dashboard yet. + null, // Meta data cannot be supplied through the dashboard yet. + $componentData['tags'] )); } catch (ValidationException $e) { return cachet_redirect('dashboard.components.create') @@ -190,15 +175,6 @@ class ComponentController extends Controller ->withErrors($e->getMessageBag()); } - // The component was added successfully, so now let's deal with the tags. - Collection::make(preg_split('/ ?, ?/', $tags))->map(function ($tag) { - return trim($tag); - })->map(function ($tag) { - return execute(new CreateTagCommand($tag)); - })->each(function ($tag) use ($component) { - execute(new ApplyTagCommand($component, $tag)); - }); - return cachet_redirect('dashboard.components') ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.components.add.success'))); } diff --git a/app/Models/Tag.php b/app/Models/Tag.php index f0a18eec..022ceb8c 100644 --- a/app/Models/Tag.php +++ b/app/Models/Tag.php @@ -55,4 +55,31 @@ class Tag extends Model { return $this->belongsToMany(Component::class); } + + /** + * @param array|\ArrayAccess $values + * + * @return \CachetHQ\Cachet\Models\Tag|static + */ + public static function findOrCreate($values) + { + $tags = collect($values)->map(function ($value) { + if ($value instanceof self) { + return $value; + } + + $tag = static::where('name', '=', $value)->first(); + + if (!$tag instanceof self) { + $tag = static::create([ + 'name' => $value, + 'slug' => Str::slug($value), + ]); + } + + return $tag; + }); + + return is_string($values) ? $tags->first() : $tags; + } } diff --git a/app/Models/Taggable.php b/app/Models/Taggable.php deleted file mode 100644 index 9b6c94a1..00000000 --- a/app/Models/Taggable.php +++ /dev/null @@ -1,79 +0,0 @@ - - */ -class Taggable extends Model -{ - use ValidatingTrait; - - /** - * The attributes that should be casted to native types. - * - * @var string[] - */ - protected $casts = [ - 'id' => 'int', - 'tag_id' => 'int', - 'taggable_id' => 'int', - 'taggable_type' => 'string', - ]; - - /** - * The attributes that are mass assignable. - * - * @var array - */ - protected $fillable = [ - 'tag_id', - 'taggable_id', - 'taggable_type', - ]; - - /** - * The validation rules. - * - * @var string[] - */ - public $rules = [ - 'tag_id' => 'required|int', - 'taggable_id' => 'required|int', - 'taggable_type' => 'required|string', - ]; - - /** - * Get the tag relation. - * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - */ - public function tag() - { - return $this->belongsTo(Tag::class); - } - - /** - * Get the taggable relation. - * - * @return \Illuminate\Database\Eloquent\Relations\MorphTo - */ - public function taggable() - { - return $this->morphTo(); - } -} diff --git a/app/Models/Traits/HasTags.php b/app/Models/Traits/HasTags.php index dbb62b75..b707e050 100644 --- a/app/Models/Traits/HasTags.php +++ b/app/Models/Traits/HasTags.php @@ -13,14 +13,43 @@ namespace CachetHQ\Cachet\Models\Traits; use CachetHQ\Cachet\Models\Tag; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Model; /** * This is the has tags trait. + * Code based on https://github.com/spatie/laravel-tags. * * @author James Brooks */ trait HasTags { + /** + * @var array + */ + protected $queuedTags = []; + + /** + * Boot the trait. + * + * @return void + */ + public static function bootHasTags() + { + static::created(function (Model $taggableModel) { + if (count($taggableModel->queuedTags) > 0) { + $taggableModel->attachTags($taggableModel->queuedTags); + + $taggableModel->queuedTags = []; + } + }); + + static::deleted(function (Model $deletedModel) { + $tags = $deletedModel->tags()->get(); + + $deletedModel->detachTags($tags); + }); + } + /** * Get the tags relation. * @@ -31,6 +60,20 @@ trait HasTags return $this->morphToMany(Tag::class, 'taggable'); } + /** + * @param string|array|\ArrayAccess|\CachetHQ\Cachet\Models\Tag $tags + */ + public function setTagsAttribute($tags) + { + if (!$this->exists) { + $this->queuedTags = $tags; + + return; + } + + $this->attachTags($tags); + } + /** * @param \Illuminate\Database\Eloquent\Builder $query * @param array|\ArrayAccess $tags @@ -43,7 +86,7 @@ trait HasTags $tags->each(function ($tag) use ($query) { $query->whereHas('tags', function (Builder $query) use ($tag) { - return $query->where('id', $tag ? $tag->id : 0); + return $query->where('tags.id', $tag ? $tag->id : 0); }); }); @@ -61,12 +104,78 @@ trait HasTags $tags = static::convertToTags($tags); return $query->whereHas('tags', function (Builder $query) use ($tags) { - $tagIds = $tags->pluck('id')->toArray(); + $tagIds = collect($tags)->pluck('id'); - $query->whereIn('taggables.tag_id', $tagIds); + $query->whereIn('tags.id', $tagIds); }); } + /** + * @param array|\ArrayAccess|\CachetHQ\Cachet\Models\Tag $tags + * + * @return $this + */ + public function attachTags($tags) + { + $tags = collect(Tag::findOrCreate($tags)); + + $this->tags()->syncWithoutDetaching($tags->pluck('id')->toArray()); + + return $this; + } + + /** + * @param string|\CachetHQ\Cachet\Models\Tag $tag + * + * @return $this + */ + public function attachTag($tag) + { + return $this->attachTags([$tag]); + } + + /** + * @param array|\ArrayAccess $tags + * + * @return $this + */ + public function detachTags($tags) + { + $tags = static::convertToTags($tags); + + collect($tags) + ->filter() + ->each(function (Tag $tag) { + $this->tags()->detach($tag); + }); + + return $this; + } + + /** + * @param string|\CachetHQ\Cachet\Models\Tag $tag + * + * @return $this + */ + public function detachTag($tag) + { + return $this->detachTags([$tag]); + } + + /** + * @param array|\ArrayAccess $tags + * + * @return $this + */ + public function syncTags($tags) + { + $tags = collect(Tag::findOrCreate($tags)); + + $this->tags()->sync($tags->pluck('id')->toArray()); + + return $this; + } + /** * Convert a list of tags into a collection of \CachetHQ\Cachet\Models\Tag. * diff --git a/app/Presenters/ComponentPresenter.php b/app/Presenters/ComponentPresenter.php index 30bb2239..07a2458e 100644 --- a/app/Presenters/ComponentPresenter.php +++ b/app/Presenters/ComponentPresenter.php @@ -53,7 +53,7 @@ class ComponentPresenter extends BasePresenter implements Arrayable */ public function tags() { - return $this->wrappedObject->tags->pluck('tag.name', 'tag.slug'); + return $this->wrappedObject->tags->pluck('name', 'slug'); } /** diff --git a/database/migrations/2018_04_02_163658_MigrateComponentTagTable.php b/database/migrations/2018_04_02_163658_MigrateComponentTagTable.php index 0d33597f..92690fb3 100644 --- a/database/migrations/2018_04_02_163658_MigrateComponentTagTable.php +++ b/database/migrations/2018_04_02_163658_MigrateComponentTagTable.php @@ -9,7 +9,6 @@ * file that was distributed with this source code. */ -use CachetHQ\Cachet\Models\Taggable; use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\DB; @@ -24,15 +23,16 @@ class MigrateComponentTagTable extends Migration */ public function up() { - // Start by migrating the data into the new taggables field. - DB::table('component_tag')->get()->each(function ($tag) { - Taggable::create([ + $tags = DB::table('component_tag')->get()->map(function ($tag) { + return [ 'tag_id' => $tag->tag_id, 'taggable_type' => 'components', 'taggable_id' => $tag->component_id, - ]); + ]; }); + DB::table('taggables')->insert($tags->toArray()); + Schema::dropIfExists('component_tag'); } diff --git a/tests/Api/ComponentTest.php b/tests/Api/ComponentTest.php index afabe71f..c3f71e0c 100644 --- a/tests/Api/ComponentTest.php +++ b/tests/Api/ComponentTest.php @@ -37,6 +37,19 @@ class ComponentTest extends AbstractApiTestCase $response->assertJsonFragment(['id' => $components[2]->id]); } + public function test_can_get_all_components_with_tags() + { + $components = factory(Component::class, 2)->create(); + $components[0]->attachTags(['Hello World']); + $components[1]->attachTags(['Foo', 'Bar']); + + $response = $this->json('GET', '/api/v1/components', ['tags' => ['foo']]); + + $response->assertStatus(200); + $response->assertJsonMissing(['id' => $components[0]->id]); + $response->assertJsonFragment(['id' => $components[1]->id]); + } + public function test_cannot_get_invalid_component() { $response = $this->json('GET', '/api/v1/components/1'); @@ -99,6 +112,27 @@ class ComponentTest extends AbstractApiTestCase $response->assertJsonFragment(['name' => 'Foo']); } + public function test_can_create_component_with_tags() + { + $this->beUser(); + + $this->expectsEvents(ComponentWasCreatedEvent::class); + + $response = $this->json('POST', '/api/v1/components', [ + 'name' => 'Foo', + 'description' => 'Bar', + 'status' => 1, + 'link' => 'http://example.com', + 'order' => 1, + 'group_id' => 1, + 'enabled' => true, + 'tags' => 'Foo,Bar', + ]); + + $response->assertStatus(200); + $response->assertJsonFragment(['name' => 'Foo', 'tags' => ['foo' => 'Foo', 'bar' => 'Bar']]); + } + public function test_can_create_component_without_enabled_field() { $this->beUser(); @@ -192,6 +226,22 @@ class ComponentTest extends AbstractApiTestCase $response->assertJsonFragment(['name' => 'Foo', 'enabled' => $component->enabled]); } + public function test_can_update_component_tags() + { + $this->beUser(); + $component = factory(Component::class)->create(); + + $this->expectsEvents(ComponentWasUpdatedEvent::class); + + $response = $this->json('PUT', '/api/v1/components/1', [ + 'name' => 'Foo', + 'tags' => 'Hello', + ]); + + $response->assertStatus(200); + $response->assertJsonFragment(['name' => 'Foo', 'enabled' => $component->enabled, 'tags' => ['hello' => 'Hello']]); + } + public function test_can_update_component_without_status_change() { $this->beUser(); diff --git a/tests/Bus/Commands/Component/CreateComponentCommandTest.php b/tests/Bus/Commands/Component/CreateComponentCommandTest.php index 454beeb5..a2f3e272 100644 --- a/tests/Bus/Commands/Component/CreateComponentCommandTest.php +++ b/tests/Bus/Commands/Component/CreateComponentCommandTest.php @@ -37,6 +37,7 @@ class CreateComponentCommandTest extends AbstractTestCase 'group_id' => 0, 'enabled' => true, 'meta' => null, + 'tags' => 'Foo, Bar', ]; $object = new CreateComponentCommand( $params['name'], @@ -46,7 +47,8 @@ class CreateComponentCommandTest extends AbstractTestCase $params['order'], $params['group_id'], $params['enabled'], - $params['meta'] + $params['meta'], + $params['tags'] ); return compact('params', 'object'); diff --git a/tests/Bus/Commands/Component/UpdateComponentCommandTest.php b/tests/Bus/Commands/Component/UpdateComponentCommandTest.php index 59f808be..4360b28f 100644 --- a/tests/Bus/Commands/Component/UpdateComponentCommandTest.php +++ b/tests/Bus/Commands/Component/UpdateComponentCommandTest.php @@ -39,6 +39,7 @@ class UpdateComponentCommandTest extends AbstractTestCase 'group_id' => 0, 'enabled' => true, 'meta' => null, + 'tags' => null, 'silent' => false, ]; @@ -52,6 +53,7 @@ class UpdateComponentCommandTest extends AbstractTestCase $params['group_id'], $params['enabled'], $params['meta'], + $params['tags'], $params['silent'] ); diff --git a/tests/Bus/Commands/Tag/ApplyTagCommandTest.php b/tests/Bus/Commands/Tag/ApplyTagCommandTest.php deleted file mode 100644 index a1c8bd25..00000000 --- a/tests/Bus/Commands/Tag/ApplyTagCommandTest.php +++ /dev/null @@ -1,54 +0,0 @@ - - */ -class ApplyTagCommandTest extends AbstractTestCase -{ - use CommandTrait; - - protected function getObjectAndParams() - { - $params = [ - 'model' => new Component(), - 'tag' => new Tag(), - ]; - - $object = new ApplyTagCommand( - $params['model'], - $params['tag'] - ); - - return compact('params', 'object'); - } - - protected function objectHasRules() - { - return false; - } - - protected function getHandlerClass() - { - return ApplyTagCommandHandler::class; - } -} diff --git a/tests/Bus/Commands/Tag/CreateTagCommandTest.php b/tests/Bus/Commands/Tag/CreateTagCommandTest.php deleted file mode 100644 index 59bf6369..00000000 --- a/tests/Bus/Commands/Tag/CreateTagCommandTest.php +++ /dev/null @@ -1,52 +0,0 @@ - - */ -class CreateTagCommandTest extends AbstractTestCase -{ - use CommandTrait; - - protected function getObjectAndParams() - { - $params = [ - 'name' => 'Test', - 'slug' => 'test', - ]; - - $object = new CreateTagCommand( - $params['name'], - $params['slug'] - ); - - return compact('params', 'object'); - } - - protected function objectHasRules() - { - return false; - } - - protected function getHandlerClass() - { - return CreateTagCommandHandler::class; - } -} diff --git a/tests/Bus/Commands/Tag/DeleteTagCommandTest.php b/tests/Bus/Commands/Tag/DeleteTagCommandTest.php deleted file mode 100644 index 2bee7b97..00000000 --- a/tests/Bus/Commands/Tag/DeleteTagCommandTest.php +++ /dev/null @@ -1,51 +0,0 @@ - - */ -class DeleteTagCommandTest extends AbstractTestCase -{ - use CommandTrait; - - protected function getObjectAndParams() - { - $params = [ - 'tag' => new Tag(), - ]; - - $object = new DeleteTagCommand( - $params['tag'] - ); - - return compact('params', 'object'); - } - - protected function objectHasRules() - { - return false; - } - - protected function getHandlerClass() - { - return DeleteTagCommandHandler::class; - } -} diff --git a/tests/Bus/Commands/Tag/UpdateTagCommandTest.php b/tests/Bus/Commands/Tag/UpdateTagCommandTest.php deleted file mode 100644 index 163c7477..00000000 --- a/tests/Bus/Commands/Tag/UpdateTagCommandTest.php +++ /dev/null @@ -1,55 +0,0 @@ - - */ -class UpdateTagCommandTest extends AbstractTestCase -{ - use CommandTrait; - - protected function getObjectAndParams() - { - $params = [ - 'tag' => new Tag(), - 'name' => 'Test', - 'slug' => 'test', - ]; - - $object = new UpdateTagCommand( - $params['tag'], - $params['name'], - $params['slug'] - ); - - return compact('params', 'object'); - } - - protected function objectHasRules() - { - return false; - } - - protected function getHandlerClass() - { - return UpdateTagCommandHandler::class; - } -} diff --git a/tests/Models/TaggableTest.php b/tests/Models/TaggableTest.php deleted file mode 100644 index 8a5271a3..00000000 --- a/tests/Models/TaggableTest.php +++ /dev/null @@ -1,31 +0,0 @@ - - */ -class TaggableTest extends AbstractTestCase -{ - use ValidationTrait; - - public function testValidation() - { - $this->checkRules(new Taggable()); - } -}