added tests for diets

This commit is contained in:
2024-01-10 17:11:50 +03:00
parent d96954f4b4
commit fef7f4e2bc
8 changed files with 509 additions and 39 deletions

View File

@@ -53,44 +53,47 @@ class Create extends Component
$this->publish();
}
public function makeCopy($day)
public function makeCopy(string $day): void
{
$this->copyedDay = $day;
}
public function makePaste($copyToDay)
public function makePaste(string $copyToDay): void
{
$data = $this->days[$this->copyedDay];
$this->dispatch('takePaste', day: $copyToDay, data: $data)->to('diet.day-edit');
}
public function publish()
public function publish(): void
{
$this->validate();
$diet = new Diet();
$diet->name = $this->name;
$diet->image = $this->image->store('diets', 'public');
// $diet->image = $this->image->store('diets', 'public');
$diet->image = $this->image->store('diets');
$diet->duration = $this->duration;
$diet->state = $this->state;
$diet->type = json_encode($this->type);
$diet->type = $this->type;
$diet->details = $this->details;
$diet->daily_schedule = json_encode($this->days);
$diet->save();
$diet->daily_schedule = $this->days;
$diet->saveOrFail();
$user = Auth::user();
$user->author_of_diets()->attach($diet->id);
return redirect()->route('diet.show', $diet->id);
$this->redirectRoute('diet.show', $diet);
// return redirect()->route('diet.show', $diet->id);
}
protected function rules()
protected function rules(): array
{
return [
'name' => 'required|min:3',
'image' => 'required|image|max:2048',
'duration' => 'required|numeric|min:7',
'state' => 'required|in:draft,active,inactive',
'state' => 'required|in:active,draft,archived',
'type' => ['required', 'array:meat,veg,corb,alko', 'min:1'],
'details' => 'required|min:3',
];

View File

@@ -2,11 +2,13 @@
namespace App\Livewire\Diet;
use App\Models\Diet;
use Livewire\Component;
use App\Models\Diet; use Livewire\Component;
use Livewire\WithFileUploads;
class Edit extends Component
{
use WithFileUploads;
public Diet $diet;
public $name = '';
@@ -35,9 +37,9 @@ class Edit extends Component
$this->image = $diet->image;
$this->duration = $diet->duration;
$this->state = $diet->state;
$this->type = json_decode($diet->type, true);
$this->type = $diet->type;
$this->details = $diet->details;
$this->days = json_decode($diet->daily_schedule, true);
$this->days = $diet->daily_schedule;
}
public function render()
@@ -78,7 +80,7 @@ class Edit extends Component
)->to('diet.day-edit');
}
public function publish()
public function publish(): void
{
$this->validate();
@@ -86,17 +88,18 @@ class Edit extends Component
$diet->name = $this->name;
/* $diet->image = $this->image->store('diets', 'public'); */
$diet->image = ! is_string($this->image) ? $this->image->store('plans') : $this->image;
$diet->duration = $this->duration;
$diet->state = $this->state;
$diet->type = json_encode($this->type);
$diet->type = $this->type;
$diet->details = $this->details;
$diet->daily_schedule = json_encode($this->days);
$diet->daily_schedule = $this->days;
$diet->save();
$this->redirectRoute('diet.show', $diet);
/* $user = Auth::user(); */
/* $user->author_of_diets()->attach($diet->id); */
return redirect()->route('diet.show', $diet->id);
}
protected function rules()
@@ -105,7 +108,7 @@ class Edit extends Component
'name' => 'required|min:3',
/* 'image' => 'required|image|max:2048', */
'duration' => 'required|numeric|min:7',
'state' => 'required|in:draft,active,inactive',
'state' => 'required|in:active,draft,archived',
'type' => ['required', 'array:meat,veg,corb,alko', 'min:1'],
'details' => 'required|min:3',
];

View File

@@ -4,11 +4,11 @@ namespace App\Models;
use CyrildeWit\EloquentViewable\Contracts\Viewable;
use CyrildeWit\EloquentViewable\InteractsWithViews;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
/**
* App\Models\Diet
@@ -64,10 +64,20 @@ class Diet extends Model implements Viewable
{
use HasFactory, InteractsWithViews;
protected $withCount = [
'likes',
'comments',
'choses',
// protected $withCount = [
// 'likes',
// 'comments',
// 'choses',
// ];
public static function getWithLikesCommentsChosesCount(): Builder
{
return self::withCount(['likes', 'comments', 'choses']);
}
protected $casts = [
'type' => 'array',
'daily_schedule' => 'array',
];
private $allowedDietTypes = [
@@ -120,19 +130,19 @@ class Diet extends Model implements Viewable
public function types(): Attribute
{
$data = $this->unserializeOptionsArr($this->type);
$data = $this->type;
return new Attribute(
get: fn () => array_keys($data),
get: fn() => array_keys($data),
);
}
public function schedules(): Attribute
{
$data = $this->unserializeOptionsArr($this->daily_schedule);
$data = $this->daily_schedule;
return new Attribute(
get: fn () => $data,
get: fn() => $data,
);
}
@@ -168,8 +178,8 @@ class Diet extends Model implements Viewable
foreach ($types as $type) {
if (in_array($type, $this->allowedDietTypes)) {
$query = $i === 0
? $query->whereJsonContainsKey('type->'.$type)
: $query->orWhereJsonContainsKey('type->'.$type);
? $query->whereJsonContainsKey('type->' . $type)
: $query->orWhereJsonContainsKey('type->' . $type);
$i++;
}
}
@@ -177,12 +187,12 @@ class Diet extends Model implements Viewable
return $query;
}
private function unserializeOptionsArr($str)
{
if (preg_match('/^".*"$/', $str)) {
return json_decode(stripslashes(mb_substr($str, 1, -1)), true);
}
// private function unserializeOptionsArr($str)
// {
// if (preg_match('/^".*"$/', $str)) {
// return stripslashes(mb_substr($str, 1, -1)), true;
// }
return json_decode(stripslashes($str), true);
}
// return json_decode(stripslashes($str), true);
// }
}

View File

@@ -18,5 +18,6 @@ class DatabaseSeeder extends Seeder
$this->call(RecipeAuthor::class);
$this->call(RecipeCommentSeeder::class);
$this->call(RecipeTagSeeder::class);
$this->call(DietsSeeder::class);
}
}

View File

@@ -0,0 +1,187 @@
<?php
namespace Tests\Feature\Diet;
use App\Livewire\Diet\Create;
use App\Models\Diet;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\Testing\File;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Livewire\Livewire;
use Tests\TestCase;
class CreateTest extends TestCase
{
use RefreshDatabase;
private File $image;
private Diet $diet;
protected User $user;
public function setUp(): void
{
$this->refreshApplicationWithLocale('en');
Storage::fake('tmp-for-tests');
$this->image = UploadedFile::fake()->image('diet.png');
$this->user = User::factory()->create(['is_consultant' => true]);
$this->diet = Diet::factory()->make();
}
public function test_show_form_create_diet(): void
{
$response = $this
->actingAs($this->user)
->get(route('diet.create'));
$response->assertSuccessful();
}
public function test_publish_new_diet_success(): void
{
$this->actingAs($this->user);
$dietCountAtStart = Diet::count();
$testCase = Livewire::test(Create::class)
->set('name', $this->diet->name)
->assertSet('name', $this->diet->name)
->set('image', $this->image)
->set('duration', $this->diet->duration)
->assertSet('duration', $this->diet->duration)
->set('state', $this->diet->state)
->assertSet('state', $this->diet->state)
->set('type', $this->diet->type)
->assertSet('type', $this->diet->type)
->set('details', $this->diet->details)
->assertSet('details', $this->diet->details)
->set('daily_schedule', $this->diet->daily_schedule)
->assertSet('daily_schedule', $this->diet->daily_schedule)
->call('publish')
->assertSuccessful()
->assertHasNoErrors(['name', 'image', 'duration', 'state', 'details', 'daily_schedule', 'type']);
$lastCreatedDiet = Diet::orderBy('id', 'desc')->first();
$this->assertEquals($dietCountAtStart + 1, Diet::count());
$newDietUrl = route('diet.show', $lastCreatedDiet);
$testCase->assertRedirect($newDietUrl);
Storage::disk('tmp-for-tests')->assertExists($lastCreatedDiet->image);
$response = $this->actingAs($this->user)->get(route('diet.index'));
$response->assertSuccessful();
}
public function test_to_draft_new_diet_success(): void
{
$this->actingAs($this->user);
$dietCountAtStart = Diet::count();
$testCase = Livewire::test(Create::class)
->set('name', $this->diet->name)
->assertSet('name', $this->diet->name)
->set('image', $this->image)
->set('duration', $this->diet->duration)
->assertSet('duration', $this->diet->duration)
->set('state', $this->diet->state)
->assertSet('state', $this->diet->state)
->set('type', $this->diet->type)
->assertSet('type', $this->diet->type)
->set('details', $this->diet->details)
->assertSet('details', $this->diet->details)
->set('daily_schedule', $this->diet->daily_schedule)
->assertSet('daily_schedule', $this->diet->daily_schedule)
->call('addToDrafts')
->assertSuccessful()
->assertHasNoErrors(['name', 'image', 'duration', 'details', 'daily_schedule']);
self::assertEquals('draft', $testCase->state);
$lastCreatedDiet = Diet::orderBy('id', 'desc')->first();
$newDietUrl = route('diet.show', $lastCreatedDiet);
$testCase->assertRedirect($newDietUrl);
Storage::disk('tmp-for-tests')->assertExists($lastCreatedDiet->image);
$this->assertEquals($dietCountAtStart + 1, Diet::count());
$response = $this->actingAs($this->user)->get(route('diet.index'));
$response->assertSuccessful();
}
public function test_to_preview_new_diet_success(): void
{
$this->actingAs($this->user);
$dietCountAtStart = Diet::count();
$testCase = Livewire::test(Create::class)
->set('name', $this->diet->name)
->assertSet('name', $this->diet->name)
->set('image', $this->image)
->set('duration', $this->diet->duration)
->assertSet('duration', $this->diet->duration)
->set('state', $this->diet->state)
->assertSet('state', $this->diet->state)
->set('type', $this->diet->type)
->assertSet('type', $this->diet->type)
->set('details', $this->diet->details)
->assertSet('details', $this->diet->details)
->set('daily_schedule', $this->diet->daily_schedule)
->assertSet('daily_schedule', $this->diet->daily_schedule)
->call('showPreview')
->assertSuccessful()
->assertHasNoErrors(['name', 'image', 'duration', 'details', 'daily_schedule']);
self::assertEquals('draft', $testCase->state);
$lastCreatedDiet = Diet::orderBy('id', 'desc')->first();
$newDietUrl = route('diet.show', $lastCreatedDiet);
$testCase->assertRedirect($newDietUrl);
Storage::disk('tmp-for-tests')->assertExists($lastCreatedDiet->image);
$this->assertEquals($dietCountAtStart + 1, Diet::count());
$response = $this->actingAs($this->user)->get(route('diet.index'));
$response->assertSuccessful();
}
public function test_set_empty_data(): void
{
$this->actingAs($this->user);
$dietCountAtStart = Diet::count();
Livewire::test(Create::class)
->set('name', null)
->set('image', null)
->set('duration', null)
->set('state', null)
->set('type', null)
->set('details', null)
->set('daily_schedule', null)
->call('publish')
->assertHasErrors(['name', 'image', 'duration', 'details', 'state', 'type']);
$this->assertEquals($dietCountAtStart, Diet::count());
}
}

View File

@@ -0,0 +1,204 @@
<?php
namespace Tests\Feature\Diet;
use App\Models\Diet;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;
use App\Livewire\Diet\Edit;
use Livewire\Livewire;
class EditTest extends TestCase
{
use RefreshDatabase;
private UploadedFile $image;
private Diet $diet;
protected User $user;
public function setUp(): void
{
$this->refreshApplicationWithLocale('en');
Storage::fake('tmp-for-tests');
$this->image = UploadedFile::fake()->image('diet.png');
$this->user = User::factory()->create(['is_consultant' => true]);
$this->diet = Diet::factory()->create();
}
public function test_show_form_edit_diet(): void
{
$response = $this
->actingAs($this->user)
->get(route('diet.edit', $this->diet));
$response->assertSuccessful();
}
public function test_publish_new_diet_success(): void
{
$this->actingAs($this->user);
$updatedDietBeforeToAddDatabase = Diet::factory()->make();
$testCase = Livewire::test(Edit::class, [
'diet' => $this->diet,
])
->set('name', $updatedDietBeforeToAddDatabase->name)
->assertSet('name', $updatedDietBeforeToAddDatabase->name)
->set('image', $this->image)
->set('duration', $updatedDietBeforeToAddDatabase->duration)
->assertSet('duration', $updatedDietBeforeToAddDatabase->duration)
->set('state', $updatedDietBeforeToAddDatabase->state)
->assertSet('state', $updatedDietBeforeToAddDatabase->state)
->set('type', $updatedDietBeforeToAddDatabase->type)
->assertSet('type', $updatedDietBeforeToAddDatabase->type)
->set('details', $updatedDietBeforeToAddDatabase->details)
->assertSet('details', $updatedDietBeforeToAddDatabase->details)
->set('daily_schedule', $this->diet->daily_schedule)
->assertSet('daily_schedule', $this->diet->daily_schedule)
->call('publish')
->assertSuccessful()
->assertHasNoErrors(['name', 'image', 'duration', 'state', 'details', 'daily_schedule', 'type']);
$updatedDietAfterToAddDatabase = Diet::orderByDesc('id')->first();
$newDietUrl = route('diet.show', $updatedDietAfterToAddDatabase);
Storage::disk('tmp-for-tests')->assertExists($updatedDietAfterToAddDatabase->image);
// check data after update recipe
self::assertEquals($updatedDietBeforeToAddDatabase->name, $updatedDietAfterToAddDatabase->name);
self::assertEquals($updatedDietBeforeToAddDatabase->duration, $updatedDietAfterToAddDatabase->duration);
self::assertEquals($updatedDietBeforeToAddDatabase->state, $updatedDietAfterToAddDatabase->state);
self::assertEquals($updatedDietBeforeToAddDatabase->type, $updatedDietAfterToAddDatabase->type);
self::assertEquals($updatedDietBeforeToAddDatabase->details, $updatedDietAfterToAddDatabase->details);
// self::assertEquals($updatedDietBeforeToAddDatabase->daily_schedule, $updatedDietAfterToAddDatabase->daily_schedule);
$testCase->assertRedirect($newDietUrl);
}
public function test_to_draft_new_diet_success(): void
{
$this->actingAs($this->user);
$updatedDietBeforeToAddDatabase = Diet::factory()->make();
$testCase = Livewire::test(Edit::class, [
'diet' => $this->diet,
])
->set('name', $updatedDietBeforeToAddDatabase->name)
->assertSet('name', $updatedDietBeforeToAddDatabase->name)
->set('image', $this->image)
->set('duration', $updatedDietBeforeToAddDatabase->duration)
->assertSet('duration', $updatedDietBeforeToAddDatabase->duration)
->set('state', $updatedDietBeforeToAddDatabase->state)
->assertSet('state', $updatedDietBeforeToAddDatabase->state)
->set('type', $updatedDietBeforeToAddDatabase->type)
->assertSet('type', $updatedDietBeforeToAddDatabase->type)
->set('details', $updatedDietBeforeToAddDatabase->details)
->assertSet('details', $updatedDietBeforeToAddDatabase->details)
->set('daily_schedule', $this->diet->daily_schedule)
->assertSet('daily_schedule', $this->diet->daily_schedule)
->call('addToDrafts')
->assertSuccessful()
->assertHasNoErrors(['name', 'image', 'duration', 'state', 'details', 'days', 'type']);
$updatedDietAfterToAddDatabase = Diet::orderByDesc('id')->first();
$newDietUrl = route('diet.show', $updatedDietAfterToAddDatabase);
Storage::disk('tmp-for-tests')->assertExists($updatedDietAfterToAddDatabase->image);
// check data after update recipe
self::assertEquals($updatedDietBeforeToAddDatabase->name, $updatedDietAfterToAddDatabase->name);
self::assertEquals($updatedDietBeforeToAddDatabase->duration, $updatedDietAfterToAddDatabase->duration);
self::assertEquals('draft', $updatedDietAfterToAddDatabase->state);
self::assertEquals($updatedDietBeforeToAddDatabase->type, $updatedDietAfterToAddDatabase->type);
self::assertEquals($updatedDietBeforeToAddDatabase->details, $updatedDietAfterToAddDatabase->details);
// self::assertEquals($updatedDietBeforeToAddDatabase->daily_schedule, $updatedDietAfterToAddDatabase->daily_schedule);
$testCase->assertRedirect($newDietUrl);
}
public function test_to_preview_new_diet_success(): void
{
$this->actingAs($this->user);
$updatedDietBeforeToAddDatabase = Diet::factory()->make();
$testCase = Livewire::test(Edit::class, [
'diet' => $this->diet,
])
->set('name', $updatedDietBeforeToAddDatabase->name)
->assertSet('name', $updatedDietBeforeToAddDatabase->name)
->set('image', $this->image)
->set('duration', $updatedDietBeforeToAddDatabase->duration)
->assertSet('duration', $updatedDietBeforeToAddDatabase->duration)
->set('state', $updatedDietBeforeToAddDatabase->state)
->assertSet('state', $updatedDietBeforeToAddDatabase->state)
->set('type', $updatedDietBeforeToAddDatabase->type)
->assertSet('type', $updatedDietBeforeToAddDatabase->type)
->set('details', $updatedDietBeforeToAddDatabase->details)
->assertSet('details', $updatedDietBeforeToAddDatabase->details)
->set('daily_schedule', $this->diet->daily_schedule)
->assertSet('daily_schedule', $this->diet->daily_schedule)
->call('showPreview')
->assertSuccessful()
->assertHasNoErrors(['name', 'image', 'duration', 'state', 'details', 'days', 'type']);
$updatedDietAfterToAddDatabase = Diet::orderByDesc('id')->first();
$newDietUrl = route('diet.show', $updatedDietAfterToAddDatabase);
Storage::disk('tmp-for-tests')->assertExists($updatedDietAfterToAddDatabase->image);
// check data after update recipe
self::assertEquals($updatedDietBeforeToAddDatabase->name, $updatedDietAfterToAddDatabase->name);
self::assertEquals($updatedDietBeforeToAddDatabase->duration, $updatedDietAfterToAddDatabase->duration);
self::assertEquals('draft', $updatedDietAfterToAddDatabase->state);
self::assertEquals($updatedDietBeforeToAddDatabase->type, $updatedDietAfterToAddDatabase->type);
self::assertEquals($updatedDietBeforeToAddDatabase->details, $updatedDietAfterToAddDatabase->details);
// self::assertEquals($updatedDietBeforeToAddDatabase->daily_schedule, $updatedDietAfterToAddDatabase->daily_schedule);
$testCase->assertRedirect($newDietUrl);
}
public function testNothingChange(): void
{
$this->actingAs($this->user);
$dietUpdate = Livewire::test(Edit::class, [
'diet' => $this->diet,
])
->call('publish')
->assertSuccessful()
->assertHasNoErrors(['name', 'image', 'duration', 'state', 'details', 'days', 'type']);
$newDietUrl = route('diet.show', $this->diet, false);
Storage::disk('tmp-for-tests')->assertMissing($dietUpdate->image);
// check data after update recipe
self::assertEquals($this->diet->name, $dietUpdate->name);
self::assertEquals($this->diet->duration, $dietUpdate->duration);
self::assertEquals($this->diet->state, $dietUpdate->state);
self::assertEquals($this->diet->type, $dietUpdate->type);
self::assertEquals($this->diet->details, $dietUpdate->details);
self::assertEquals($this->diet->daily_schedule, $dietUpdate->days);
$dietUpdate->assertRedirect($newDietUrl);
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Tests\Feature\Diet;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class IndexTest extends TestCase
{
use RefreshDatabase;
protected User $user;
public function setUp(): void
{
$this->refreshApplicationWithLocale('en');
$this->user = User::factory()->create(['is_consultant' => true]);
}
public function test_index_page_success(): void
{
$response = $this
->actingAs($this->user)
->get(route('plan.index'));
$response
->assertOk();
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Tests\Feature\Diet;
use Tests\TestCase;
use App\Models\User;
use App\Models\Diet;
class ShowTest extends TestCase
{
protected User $user;
private Diet $diet;
public function setUp(): void
{
$this->refreshApplicationWithLocale('en');
$this->user = User::factory()->create(['is_consultant' => true]);
$this->diet = Diet::inRandomOrder()->first();
}
public function test_show_page_success(): void
{
$response = $this
->actingAs($this->user)
->get(route('diet.show', $this->diet));
$response
->assertOk();
}
}