Compare commits
3 Commits
d83fce834a
...
bugfixes/c
| Author | SHA1 | Date | |
|---|---|---|---|
| fe47b79a25 | |||
| 27449eabf0 | |||
| 9df6c0ab46 |
34
.gitea/workflows/tests.yml
Normal file
34
.gitea/workflows/tests.yml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
name: Tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
php-tests:
|
||||||
|
name: Laravel tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: '8.4'
|
||||||
|
extensions: bcmath, exif, fileinfo, gd, mbstring, pdo_sqlite, sqlite3, zip
|
||||||
|
coverage: none
|
||||||
|
|
||||||
|
- name: Install Composer dependencies
|
||||||
|
uses: ramsey/composer-install@v3
|
||||||
|
|
||||||
|
- name: Prepare application
|
||||||
|
run: |
|
||||||
|
cp .env.example .env
|
||||||
|
php artisan key:generate --ansi
|
||||||
|
|
||||||
|
- name: Run test suite
|
||||||
|
run: php artisan test
|
||||||
@@ -29,11 +29,6 @@ class EducationController extends Controller
|
|||||||
return redirect()->route('educations.index')->with('success', 'Opleiding toegevoegd.');
|
return redirect()->route('educations.index')->with('success', 'Opleiding toegevoegd.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show(Education $education)
|
|
||||||
{
|
|
||||||
return view('educations.show', compact('education'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function edit(Education $education)
|
public function edit(Education $education)
|
||||||
{
|
{
|
||||||
return view('educations.edit', compact('education'));
|
return view('educations.edit', compact('education'));
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Personalia;
|
use App\Models\Personalia;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use App\Http\Requests\PersonaliaRequest;
|
use App\Http\Requests\PersonaliaRequest;
|
||||||
|
|
||||||
class PersonaliaController extends Controller
|
class PersonaliaController extends Controller
|
||||||
@@ -38,7 +37,7 @@ class PersonaliaController extends Controller
|
|||||||
return view('personalia.edit', ['personalia' => $personalium]);
|
return view('personalia.edit', ['personalia' => $personalium]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update(Request $request, Personalia $personalium)
|
public function update(PersonaliaRequest $request, Personalia $personalium)
|
||||||
{
|
{
|
||||||
$validated = $request->validated();
|
$validated = $request->validated();
|
||||||
|
|
||||||
@@ -49,9 +48,9 @@ class PersonaliaController extends Controller
|
|||||||
return redirect()->route('personalia.index')->with('success', 'Persoonlijk item bijgewerkt.');
|
return redirect()->route('personalia.index')->with('success', 'Persoonlijk item bijgewerkt.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function destroy(Personalia $personalia)
|
public function destroy(Personalia $personalium)
|
||||||
{
|
{
|
||||||
$personalia->delete();
|
$personalium->delete();
|
||||||
|
|
||||||
return redirect()->route('personalia.index')->with('success', 'Persoonlijk item verwijderd.');
|
return redirect()->route('personalia.index')->with('success', 'Persoonlijk item verwijderd.');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,8 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Skill;
|
use App\Models\Skill;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use App\Http\Requests\SkillRequest;
|
use App\Http\Requests\SkillRequest;
|
||||||
|
|
||||||
|
|
||||||
class SkillController extends Controller
|
class SkillController extends Controller
|
||||||
{
|
{
|
||||||
public function index()
|
public function index()
|
||||||
@@ -31,11 +29,6 @@ class SkillController extends Controller
|
|||||||
return redirect()->route('skills.index')->with('success', 'Vaardigheid toegevoegd.');
|
return redirect()->route('skills.index')->with('success', 'Vaardigheid toegevoegd.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show(Skill $skill)
|
|
||||||
{
|
|
||||||
return view('skills.show', compact('skill'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function edit(Skill $skill)
|
public function edit(Skill $skill)
|
||||||
{
|
{
|
||||||
return view('skills.edit', compact('skill'));
|
return view('skills.edit', compact('skill'));
|
||||||
|
|||||||
@@ -3,10 +3,8 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\WorkExperience;
|
use App\Models\WorkExperience;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use App\Http\Requests\WorkExperienceRequest;
|
use App\Http\Requests\WorkExperienceRequest;
|
||||||
|
|
||||||
|
|
||||||
class WorkExperienceController extends Controller
|
class WorkExperienceController extends Controller
|
||||||
{
|
{
|
||||||
public function index()
|
public function index()
|
||||||
@@ -32,11 +30,6 @@ class WorkExperienceController extends Controller
|
|||||||
return redirect()->route('work-experiences.index')->with('success', 'Ervaring toegevoegd.');
|
return redirect()->route('work-experiences.index')->with('success', 'Ervaring toegevoegd.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show(WorkExperience $workExperience)
|
|
||||||
{
|
|
||||||
return view('work_experiences.show', compact('workExperience'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function edit(WorkExperience $workExperience)
|
public function edit(WorkExperience $workExperience)
|
||||||
{
|
{
|
||||||
return view('work_experiences.edit', compact('workExperience'));
|
return view('work_experiences.edit', compact('workExperience'));
|
||||||
|
|||||||
@@ -2,12 +2,14 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Spatie\MediaLibrary\HasMedia;
|
use Spatie\MediaLibrary\HasMedia;
|
||||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||||
|
|
||||||
class Education extends Model implements HasMedia
|
class Education extends Model implements HasMedia
|
||||||
{
|
{
|
||||||
|
use HasFactory;
|
||||||
use InteractsWithMedia;
|
use InteractsWithMedia;
|
||||||
|
|
||||||
protected $table = 'education';
|
protected $table = 'education';
|
||||||
|
|||||||
@@ -2,10 +2,13 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class Personalia extends Model
|
class Personalia extends Model
|
||||||
{
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
protected $fillable = ['key', 'value', 'hidden', 'icon'];
|
protected $fillable = ['key', 'value', 'hidden', 'icon'];
|
||||||
|
|
||||||
protected $table = 'personalia';
|
protected $table = 'personalia';
|
||||||
|
|||||||
@@ -2,12 +2,14 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Spatie\MediaLibrary\HasMedia;
|
use Spatie\MediaLibrary\HasMedia;
|
||||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||||
|
|
||||||
class Skill extends Model implements HasMedia
|
class Skill extends Model implements HasMedia
|
||||||
{
|
{
|
||||||
|
use HasFactory;
|
||||||
use InteractsWithMedia;
|
use InteractsWithMedia;
|
||||||
|
|
||||||
protected $fillable = ['title', 'description', 'rating', 'type'];
|
protected $fillable = ['title', 'description', 'rating', 'type'];
|
||||||
|
|||||||
@@ -2,12 +2,14 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Spatie\MediaLibrary\HasMedia;
|
use Spatie\MediaLibrary\HasMedia;
|
||||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||||
|
|
||||||
class WorkExperience extends Model implements HasMedia
|
class WorkExperience extends Model implements HasMedia
|
||||||
{
|
{
|
||||||
|
use HasFactory;
|
||||||
use InteractsWithMedia;
|
use InteractsWithMedia;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
|
|||||||
31
database/factories/EducationFactory.php
Normal file
31
database/factories/EducationFactory.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Education>
|
||||||
|
*/
|
||||||
|
class EducationFactory extends Factory
|
||||||
|
{
|
||||||
|
public function definition(): array
|
||||||
|
{
|
||||||
|
$startDate = fake()->dateTimeBetween('-8 years', '-2 years');
|
||||||
|
|
||||||
|
return [
|
||||||
|
'opleiding' => fake()->randomElement(['HBO-ICT', 'Software Engineering', 'Applicatieontwikkeling']),
|
||||||
|
'instituut' => fake()->company(),
|
||||||
|
'startdatum' => $startDate->format('Y-m-d'),
|
||||||
|
'einddatum' => fake()->dateTimeBetween($startDate, 'now')->format('Y-m-d'),
|
||||||
|
'beschrijving' => fake()->sentence(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function current(): static
|
||||||
|
{
|
||||||
|
return $this->state(fn (array $attributes) => [
|
||||||
|
'einddatum' => null,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
28
database/factories/PersonaliaFactory.php
Normal file
28
database/factories/PersonaliaFactory.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Personalia>
|
||||||
|
*/
|
||||||
|
class PersonaliaFactory extends Factory
|
||||||
|
{
|
||||||
|
public function definition(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'key' => fake()->randomElement(['Email', 'Telefoon', 'Website', 'Locatie']),
|
||||||
|
'value' => fake()->word(),
|
||||||
|
'hidden' => false,
|
||||||
|
'icon' => fake()->randomElement(['fa-solid fa-envelope', 'fa-solid fa-phone', 'fa-solid fa-globe']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hidden(): static
|
||||||
|
{
|
||||||
|
return $this->state(fn (array $attributes) => [
|
||||||
|
'hidden' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
29
database/factories/SkillFactory.php
Normal file
29
database/factories/SkillFactory.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Skill>
|
||||||
|
*/
|
||||||
|
class SkillFactory extends Factory
|
||||||
|
{
|
||||||
|
public function definition(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'title' => fake()->randomElement(['Laravel', 'PHP', 'Docker', 'Tailwind CSS']),
|
||||||
|
'description' => fake()->sentence(),
|
||||||
|
'rating' => fake()->numberBetween(1, 10),
|
||||||
|
'type' => fake()->randomElement(['rating', 'tag', 'other']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rating(): static
|
||||||
|
{
|
||||||
|
return $this->state(fn (array $attributes) => [
|
||||||
|
'type' => 'rating',
|
||||||
|
'rating' => fake()->numberBetween(1, 10),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
31
database/factories/WorkExperienceFactory.php
Normal file
31
database/factories/WorkExperienceFactory.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\WorkExperience>
|
||||||
|
*/
|
||||||
|
class WorkExperienceFactory extends Factory
|
||||||
|
{
|
||||||
|
public function definition(): array
|
||||||
|
{
|
||||||
|
$startDate = fake()->dateTimeBetween('-8 years', '-1 year');
|
||||||
|
|
||||||
|
return [
|
||||||
|
'werkgever' => fake()->company(),
|
||||||
|
'functie' => fake()->jobTitle(),
|
||||||
|
'startdatum' => $startDate->format('Y-m-d'),
|
||||||
|
'einddatum' => fake()->dateTimeBetween($startDate, 'now')->format('Y-m-d'),
|
||||||
|
'beschrijving' => fake()->sentence(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function current(): static
|
||||||
|
{
|
||||||
|
return $this->state(fn (array $attributes) => [
|
||||||
|
'einddatum' => null,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<env name="APP_MAINTENANCE_DRIVER" value="file"/>
|
<env name="APP_MAINTENANCE_DRIVER" value="file"/>
|
||||||
<env name="BCRYPT_ROUNDS" value="4"/>
|
<env name="BCRYPT_ROUNDS" value="4"/>
|
||||||
<env name="CACHE_STORE" value="array"/>
|
<env name="CACHE_STORE" value="array"/>
|
||||||
<env name="DB_DATABASE" value="testing"/>
|
<env name="DB_DATABASE" value=":memory:"/>
|
||||||
<env name="MAIL_MAILER" value="array"/>
|
<env name="MAIL_MAILER" value="array"/>
|
||||||
<env name="PULSE_ENABLED" value="false"/>
|
<env name="PULSE_ENABLED" value="false"/>
|
||||||
<env name="QUEUE_CONNECTION" value="sync"/>
|
<env name="QUEUE_CONNECTION" value="sync"/>
|
||||||
|
|||||||
2
resources/images/sitiweb.svg
Normal file
2
resources/images/sitiweb.svg
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" id="svg2" xml:space="preserve" viewBox="0 0 406.66666 473.33334" sodipodi:docname="Beeldmerk.ai"><metadata id="metadata8"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/></cc:Work></rdf:RDF></metadata><defs id="defs6"/><sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="640" inkscape:window-height="480" id="namedview4"/><g id="g10" inkscape:groupmode="layer" inkscape:label="Beeldmerk" transform="matrix(1.3333333,0,0,-1.3333333,0,473.33333)"><g id="g12" transform="translate(192.9405,297.8561)"><path d="M 0,0 3.661,-204.853 95.917,-260.941 95.291,47.32 Z" style="fill:#009000;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path14"/></g><g id="g16" transform="translate(287.7484,238.091)"><path d="M 0,0 -183.898,-87.583 -275.154,-31.495 1.239,108.114 Z" style="fill:#00ab00;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path18"/></g><g id="g20" transform="translate(172.7637,52.3648)"><path d="M 0,0 -93.429,-43.886 -96.399,59 -2.97,102.886 Z" style="fill:#ee0004;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path22"/></g><g id="g24" transform="translate(169.794,155.2513)"><path d="m 0,0 2.97,-102.886 -93.429,-43.887" style="fill:#d8000e;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path26"/></g></g></svg>
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -134,7 +134,7 @@
|
|||||||
© {{ date('Y') }} Roberto Guagliardo. Alle rechten voorbehouden.
|
© {{ date('Y') }} Roberto Guagliardo. Alle rechten voorbehouden.
|
||||||
</footer>
|
</footer>
|
||||||
<div id="custom-cursor">
|
<div id="custom-cursor">
|
||||||
{!! file_get_contents(public_path('storage/sitiweb.svg')) !!}
|
{!! file_get_contents(resource_path('images/sitiweb.svg')) !!}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ Route::middleware('auth')->group(function () {
|
|||||||
Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
|
Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
|
||||||
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
|
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
|
||||||
|
|
||||||
Route::resource('work-experiences', \App\Http\Controllers\WorkExperienceController::class);
|
Route::resource('work-experiences', \App\Http\Controllers\WorkExperienceController::class)->except(['show']);
|
||||||
Route::resource('skills', SkillController::class);
|
Route::resource('skills', SkillController::class)->except(['show']);
|
||||||
Route::resource('personalia', PersonaliaController::class);
|
Route::resource('personalia', PersonaliaController::class)->except(['show']);
|
||||||
Route::resource('educations', EducationController::class);
|
Route::resource('educations', EducationController::class)->except(['show']);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ test('registration screen can be rendered', function () {
|
|||||||
$response = $this->get('/register');
|
$response = $this->get('/register');
|
||||||
|
|
||||||
$response->assertStatus(200);
|
$response->assertStatus(200);
|
||||||
});
|
})->skip('Registration routes are disabled for this application.');
|
||||||
|
|
||||||
test('new users can register', function () {
|
test('new users can register', function () {
|
||||||
$response = $this->post('/register', [
|
$response = $this->post('/register', [
|
||||||
@@ -16,4 +16,4 @@ test('new users can register', function () {
|
|||||||
|
|
||||||
$this->assertAuthenticated();
|
$this->assertAuthenticated();
|
||||||
$response->assertRedirect(route('dashboard', absolute: false));
|
$response->assertRedirect(route('dashboard', absolute: false));
|
||||||
});
|
})->skip('Registration routes are disabled for this application.');
|
||||||
|
|||||||
110
tests/Feature/Controllers/EducationControllerTest.php
Normal file
110
tests/Feature/Controllers/EducationControllerTest.php
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Education;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Http\UploadedFile;
|
||||||
|
|
||||||
|
test('guests cannot manage educations', function () {
|
||||||
|
$education = Education::factory()->create();
|
||||||
|
|
||||||
|
$this->get(route('educations.index'))->assertRedirect(route('login'));
|
||||||
|
$this->get(route('educations.create'))->assertRedirect(route('login'));
|
||||||
|
$this->post(route('educations.store'), [])->assertRedirect(route('login'));
|
||||||
|
$this->get(route('educations.edit', $education))->assertRedirect(route('login'));
|
||||||
|
$this->patch(route('educations.update', $education), [])->assertRedirect(route('login'));
|
||||||
|
$this->delete(route('educations.destroy', $education))->assertRedirect(route('login'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an authenticated user can view the education overview', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$education = Education::factory()->create();
|
||||||
|
|
||||||
|
$this->actingAs($user)
|
||||||
|
->get(route('educations.index'))
|
||||||
|
->assertOk()
|
||||||
|
->assertViewIs('educations.index')
|
||||||
|
->assertViewHas('educations', fn ($educations) => $educations->contains($education));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an authenticated user can create an education with an image', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$response = $this->actingAs($user)->post(route('educations.store'), [
|
||||||
|
'opleiding' => 'HBO-ICT',
|
||||||
|
'instituut' => 'Hogeschool Utrecht',
|
||||||
|
'startdatum' => '2020-09-01',
|
||||||
|
'einddatum' => '2024-07-01',
|
||||||
|
'beschrijving' => 'Software engineering en web development.',
|
||||||
|
'afbeelding' => UploadedFile::fake()->image('education.jpg'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response
|
||||||
|
->assertSessionHasNoErrors()
|
||||||
|
->assertRedirect(route('educations.index'));
|
||||||
|
|
||||||
|
$education = Education::where('opleiding', 'HBO-ICT')->firstOrFail();
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('education', [
|
||||||
|
'id' => $education->id,
|
||||||
|
'instituut' => 'Hogeschool Utrecht',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('media', [
|
||||||
|
'model_type' => Education::class,
|
||||||
|
'model_id' => $education->id,
|
||||||
|
'collection_name' => 'image',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an authenticated user can update an education and replace its image', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$education = Education::factory()->current()->create([
|
||||||
|
'opleiding' => 'HBO-ICT',
|
||||||
|
'instituut' => 'Hogeschool Utrecht',
|
||||||
|
'startdatum' => '2020-09-01',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$education
|
||||||
|
->addMedia(UploadedFile::fake()->image('old-education.jpg'))
|
||||||
|
->toMediaCollection('image');
|
||||||
|
|
||||||
|
$response = $this->actingAs($user)->patch(route('educations.update', $education), [
|
||||||
|
'opleiding' => 'Software Engineering',
|
||||||
|
'instituut' => 'Avans Hogeschool',
|
||||||
|
'startdatum' => '2021-09-01',
|
||||||
|
'einddatum' => '2025-07-01',
|
||||||
|
'beschrijving' => 'Verdieping in backend development.',
|
||||||
|
'afbeelding' => UploadedFile::fake()->image('new-education.jpg'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response
|
||||||
|
->assertSessionHasNoErrors()
|
||||||
|
->assertRedirect(route('educations.index'));
|
||||||
|
|
||||||
|
expect($education->refresh())
|
||||||
|
->opleiding->toBe('Software Engineering')
|
||||||
|
->instituut->toBe('Avans Hogeschool')
|
||||||
|
->getMedia('image')->toHaveCount(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an authenticated user can delete an education and its image', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$education = Education::factory()->current()->create();
|
||||||
|
|
||||||
|
$education
|
||||||
|
->addMedia(UploadedFile::fake()->image('education.jpg'))
|
||||||
|
->toMediaCollection('image');
|
||||||
|
|
||||||
|
$this->actingAs($user)
|
||||||
|
->delete(route('educations.destroy', $education))
|
||||||
|
->assertRedirect(route('educations.index'));
|
||||||
|
|
||||||
|
$this->assertDatabaseMissing('education', ['id' => $education->id]);
|
||||||
|
$this->assertDatabaseMissing('media', [
|
||||||
|
'model_type' => Education::class,
|
||||||
|
'model_id' => $education->id,
|
||||||
|
]);
|
||||||
|
});
|
||||||
101
tests/Feature/Controllers/FrontendControllerTest.php
Normal file
101
tests/Feature/Controllers/FrontendControllerTest.php
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Jobs\NotifyTelegramAboutContactMessage;
|
||||||
|
use App\Jobs\NotifyTelegramAboutPersonaliaClick;
|
||||||
|
use App\Models\Education;
|
||||||
|
use App\Models\Personalia;
|
||||||
|
use App\Models\Skill;
|
||||||
|
use App\Models\WorkExperience;
|
||||||
|
use Illuminate\Support\Facades\Queue;
|
||||||
|
|
||||||
|
test('the homepage shows the public cv data', function () {
|
||||||
|
$skill = Skill::factory()->rating()->create([
|
||||||
|
'title' => 'Laravel',
|
||||||
|
'description' => 'Framework expertise',
|
||||||
|
'rating' => 8,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$personalium = Personalia::factory()->hidden()->create([
|
||||||
|
'key' => 'Email',
|
||||||
|
'value' => 'roberto@example.com',
|
||||||
|
'icon' => 'fa-solid fa-envelope',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$education = Education::factory()->create([
|
||||||
|
'opleiding' => 'HBO-ICT',
|
||||||
|
'instituut' => 'Hogeschool Utrecht',
|
||||||
|
'startdatum' => '2020-09-01',
|
||||||
|
'einddatum' => '2024-07-01',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$experience = WorkExperience::factory()->current()->create([
|
||||||
|
'werkgever' => 'Acme',
|
||||||
|
'functie' => 'Developer',
|
||||||
|
'startdatum' => '2022-01-01',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->get(route('home'))
|
||||||
|
->assertOk()
|
||||||
|
->assertViewIs('welcome')
|
||||||
|
->assertViewHas('skills', fn ($skills) => $skills->get('rating')->contains($skill))
|
||||||
|
->assertViewHas('personalia', fn ($personalia) => $personalia->contains($personalium))
|
||||||
|
->assertViewHas('education', fn ($educations) => $educations->contains($education))
|
||||||
|
->assertViewHas('experience', fn ($experiences) => $experiences->contains($experience));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('a hidden personalia value can be requested and the click is queued for notification', function () {
|
||||||
|
Queue::fake();
|
||||||
|
|
||||||
|
$personalium = Personalia::factory()->hidden()->create([
|
||||||
|
'key' => 'Email',
|
||||||
|
'value' => 'roberto@example.com',
|
||||||
|
'icon' => 'fa-solid fa-envelope',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->withHeader('User-Agent', 'Pest Browser')
|
||||||
|
->getJson(route('personalia', $personalium))
|
||||||
|
->assertOk()
|
||||||
|
->assertJson([
|
||||||
|
'value' => 'roberto@example.com',
|
||||||
|
]);
|
||||||
|
|
||||||
|
Queue::assertPushed(NotifyTelegramAboutPersonaliaClick::class);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('requesting unknown personalia returns not found', function () {
|
||||||
|
Queue::fake();
|
||||||
|
|
||||||
|
$this->getJson(route('personalia', 999))->assertNotFound();
|
||||||
|
|
||||||
|
Queue::assertNotPushed(NotifyTelegramAboutPersonaliaClick::class);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('a contact message can be submitted and is queued for notification', function () {
|
||||||
|
Queue::fake();
|
||||||
|
|
||||||
|
$this->withHeader('User-Agent', 'Pest Browser')
|
||||||
|
->postJson(route('contact'), [
|
||||||
|
'name' => 'Roberto',
|
||||||
|
'email' => 'roberto@example.com',
|
||||||
|
'phone' => '+31612345678',
|
||||||
|
'message' => 'Hoi, ik wil graag contact opnemen.',
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertJson([
|
||||||
|
'status' => 'success',
|
||||||
|
]);
|
||||||
|
|
||||||
|
Queue::assertPushed(NotifyTelegramAboutContactMessage::class);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('a contact message requires a name and message', function () {
|
||||||
|
Queue::fake();
|
||||||
|
|
||||||
|
$this->postJson(route('contact'), [
|
||||||
|
'email' => 'not-an-email',
|
||||||
|
])
|
||||||
|
->assertUnprocessable()
|
||||||
|
->assertJsonValidationErrors(['name', 'message', 'email']);
|
||||||
|
|
||||||
|
Queue::assertNotPushed(NotifyTelegramAboutContactMessage::class);
|
||||||
|
});
|
||||||
108
tests/Feature/Controllers/PersonaliaControllerTest.php
Normal file
108
tests/Feature/Controllers/PersonaliaControllerTest.php
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Personalia;
|
||||||
|
use App\Models\User;
|
||||||
|
|
||||||
|
test('guests cannot manage personalia', function () {
|
||||||
|
$personalium = Personalia::factory()->hidden()->create();
|
||||||
|
|
||||||
|
$this->get(route('personalia.index'))->assertRedirect(route('login'));
|
||||||
|
$this->get(route('personalia.create'))->assertRedirect(route('login'));
|
||||||
|
$this->post(route('personalia.store'), [])->assertRedirect(route('login'));
|
||||||
|
$this->get(route('personalia.edit', $personalium))->assertRedirect(route('login'));
|
||||||
|
$this->patch(route('personalia.update', $personalium), [])->assertRedirect(route('login'));
|
||||||
|
$this->delete(route('personalia.destroy', $personalium))->assertRedirect(route('login'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an authenticated user can view the personalia overview', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$personalium = Personalia::factory()->hidden()->create();
|
||||||
|
|
||||||
|
$this->actingAs($user)
|
||||||
|
->get(route('personalia.index'))
|
||||||
|
->assertOk()
|
||||||
|
->assertViewIs('personalia.index')
|
||||||
|
->assertViewHas('personalia', fn ($personalia) => $personalia->contains($personalium));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an authenticated user can create visible personalia', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$response = $this->actingAs($user)->post(route('personalia.store'), [
|
||||||
|
'key' => 'Website',
|
||||||
|
'value' => 'https://example.com',
|
||||||
|
'icon' => 'fa-solid fa-globe',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response
|
||||||
|
->assertSessionHasNoErrors()
|
||||||
|
->assertRedirect(route('personalia.index'));
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('personalia', [
|
||||||
|
'key' => 'Website',
|
||||||
|
'value' => 'https://example.com',
|
||||||
|
'hidden' => false,
|
||||||
|
'icon' => 'fa-solid fa-globe',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an authenticated user can create hidden personalia', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$response = $this->actingAs($user)->post(route('personalia.store'), [
|
||||||
|
'key' => 'Telefoon',
|
||||||
|
'value' => '+31612345678',
|
||||||
|
'hidden' => '1',
|
||||||
|
'icon' => 'fa-solid fa-phone',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response
|
||||||
|
->assertSessionHasNoErrors()
|
||||||
|
->assertRedirect(route('personalia.index'));
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('personalia', [
|
||||||
|
'key' => 'Telefoon',
|
||||||
|
'value' => '+31612345678',
|
||||||
|
'hidden' => true,
|
||||||
|
'icon' => 'fa-solid fa-phone',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an authenticated user can update personalia', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$personalium = Personalia::factory()->hidden()->create([
|
||||||
|
'key' => 'Email',
|
||||||
|
'value' => 'old@example.com',
|
||||||
|
'icon' => 'fa-solid fa-envelope',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = $this->actingAs($user)->patch(route('personalia.update', $personalium), [
|
||||||
|
'key' => 'Email',
|
||||||
|
'value' => 'new@example.com',
|
||||||
|
'icon' => 'fa-regular fa-envelope',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response
|
||||||
|
->assertSessionHasNoErrors()
|
||||||
|
->assertRedirect(route('personalia.index'));
|
||||||
|
|
||||||
|
$personalium->refresh();
|
||||||
|
|
||||||
|
expect($personalium->value)->toBe('new@example.com');
|
||||||
|
expect($personalium->hidden)->toBeFalse();
|
||||||
|
expect($personalium->icon)->toBe('fa-regular fa-envelope');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an authenticated user can delete personalia', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$personalium = Personalia::factory()->hidden()->create();
|
||||||
|
|
||||||
|
$this->actingAs($user)
|
||||||
|
->delete(route('personalia.destroy', $personalium))
|
||||||
|
->assertRedirect(route('personalia.index'));
|
||||||
|
|
||||||
|
$this->assertDatabaseMissing('personalia', ['id' => $personalium->id]);
|
||||||
|
});
|
||||||
19
tests/Feature/Controllers/ProfileControllerTest.php
Normal file
19
tests/Feature/Controllers/ProfileControllerTest.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
|
||||||
|
test('guests cannot access profile management routes', function () {
|
||||||
|
$this->get(route('profile.edit'))->assertRedirect(route('login'));
|
||||||
|
$this->patch(route('profile.update'), [])->assertRedirect(route('login'));
|
||||||
|
$this->delete(route('profile.destroy'), [])->assertRedirect(route('login'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('the profile edit page receives the authenticated user', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$this->actingAs($user)
|
||||||
|
->get(route('profile.edit'))
|
||||||
|
->assertOk()
|
||||||
|
->assertViewIs('profile.edit')
|
||||||
|
->assertViewHas('user', fn (User $viewUser) => $viewUser->is($user));
|
||||||
|
});
|
||||||
110
tests/Feature/Controllers/SkillControllerTest.php
Normal file
110
tests/Feature/Controllers/SkillControllerTest.php
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Skill;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Http\UploadedFile;
|
||||||
|
|
||||||
|
test('guests cannot manage skills', function () {
|
||||||
|
$skill = Skill::factory()->rating()->create();
|
||||||
|
|
||||||
|
$this->get(route('skills.index'))->assertRedirect(route('login'));
|
||||||
|
$this->get(route('skills.create'))->assertRedirect(route('login'));
|
||||||
|
$this->post(route('skills.store'), [])->assertRedirect(route('login'));
|
||||||
|
$this->get(route('skills.edit', $skill))->assertRedirect(route('login'));
|
||||||
|
$this->patch(route('skills.update', $skill), [])->assertRedirect(route('login'));
|
||||||
|
$this->delete(route('skills.destroy', $skill))->assertRedirect(route('login'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an authenticated user can view the skill overview', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$skill = Skill::factory()->rating()->create();
|
||||||
|
|
||||||
|
$this->actingAs($user)
|
||||||
|
->get(route('skills.index'))
|
||||||
|
->assertOk()
|
||||||
|
->assertViewIs('skills.index')
|
||||||
|
->assertViewHas('skills', fn ($skills) => $skills->contains($skill));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an authenticated user can create a skill with an image', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$response = $this->actingAs($user)->post(route('skills.store'), [
|
||||||
|
'title' => 'Laravel',
|
||||||
|
'description' => 'Framework expertise',
|
||||||
|
'rating' => 8,
|
||||||
|
'type' => 'rating',
|
||||||
|
'image' => UploadedFile::fake()->image('skill.jpg'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response
|
||||||
|
->assertSessionHasNoErrors()
|
||||||
|
->assertRedirect(route('skills.index'));
|
||||||
|
|
||||||
|
$skill = Skill::where('title', 'Laravel')->firstOrFail();
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('skills', [
|
||||||
|
'id' => $skill->id,
|
||||||
|
'rating' => 8,
|
||||||
|
'type' => 'rating',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('media', [
|
||||||
|
'model_type' => Skill::class,
|
||||||
|
'model_id' => $skill->id,
|
||||||
|
'collection_name' => 'image',
|
||||||
|
'disk' => 'public',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an authenticated user can update a skill and replace its image', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$skill = Skill::factory()->rating()->create([
|
||||||
|
'title' => 'Laravel',
|
||||||
|
'description' => 'Framework expertise',
|
||||||
|
'rating' => 8,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$skill
|
||||||
|
->addMedia(UploadedFile::fake()->image('old-skill.jpg'))
|
||||||
|
->toMediaCollection('image', 'public');
|
||||||
|
|
||||||
|
$response = $this->actingAs($user)->patch(route('skills.update', $skill), [
|
||||||
|
'title' => 'PHP',
|
||||||
|
'description' => 'Backend expertise',
|
||||||
|
'rating' => 9,
|
||||||
|
'type' => 'rating',
|
||||||
|
'image' => UploadedFile::fake()->image('new-skill.jpg'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response
|
||||||
|
->assertSessionHasNoErrors()
|
||||||
|
->assertRedirect(route('skills.index'));
|
||||||
|
|
||||||
|
expect($skill->refresh())
|
||||||
|
->title->toBe('PHP')
|
||||||
|
->rating->toBe(9)
|
||||||
|
->getMedia('image')->toHaveCount(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an authenticated user can delete a skill and its image', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$skill = Skill::factory()->rating()->create();
|
||||||
|
|
||||||
|
$skill
|
||||||
|
->addMedia(UploadedFile::fake()->image('skill.jpg'))
|
||||||
|
->toMediaCollection('image', 'public');
|
||||||
|
|
||||||
|
$this->actingAs($user)
|
||||||
|
->delete(route('skills.destroy', $skill))
|
||||||
|
->assertRedirect(route('skills.index'));
|
||||||
|
|
||||||
|
$this->assertDatabaseMissing('skills', ['id' => $skill->id]);
|
||||||
|
$this->assertDatabaseMissing('media', [
|
||||||
|
'model_type' => Skill::class,
|
||||||
|
'model_id' => $skill->id,
|
||||||
|
]);
|
||||||
|
});
|
||||||
110
tests/Feature/Controllers/WorkExperienceControllerTest.php
Normal file
110
tests/Feature/Controllers/WorkExperienceControllerTest.php
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Models\WorkExperience;
|
||||||
|
use Illuminate\Http\UploadedFile;
|
||||||
|
|
||||||
|
test('guests cannot manage work experiences', function () {
|
||||||
|
$experience = WorkExperience::factory()->create();
|
||||||
|
|
||||||
|
$this->get(route('work-experiences.index'))->assertRedirect(route('login'));
|
||||||
|
$this->get(route('work-experiences.create'))->assertRedirect(route('login'));
|
||||||
|
$this->post(route('work-experiences.store'), [])->assertRedirect(route('login'));
|
||||||
|
$this->get(route('work-experiences.edit', $experience))->assertRedirect(route('login'));
|
||||||
|
$this->patch(route('work-experiences.update', $experience), [])->assertRedirect(route('login'));
|
||||||
|
$this->delete(route('work-experiences.destroy', $experience))->assertRedirect(route('login'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an authenticated user can view the work experience overview', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$experience = WorkExperience::factory()->create();
|
||||||
|
|
||||||
|
$this->actingAs($user)
|
||||||
|
->get(route('work-experiences.index'))
|
||||||
|
->assertOk()
|
||||||
|
->assertViewIs('work_experiences.index')
|
||||||
|
->assertViewHas('experiences', fn ($experiences) => $experiences->contains($experience));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an authenticated user can create a work experience with an image', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$response = $this->actingAs($user)->post(route('work-experiences.store'), [
|
||||||
|
'werkgever' => 'Acme',
|
||||||
|
'functie' => 'Laravel Developer',
|
||||||
|
'startdatum' => '2022-01-01',
|
||||||
|
'einddatum' => null,
|
||||||
|
'beschrijving' => 'Bouwde maatwerkapplicaties.',
|
||||||
|
'afbeelding' => UploadedFile::fake()->image('experience.jpg'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response
|
||||||
|
->assertSessionHasNoErrors()
|
||||||
|
->assertRedirect(route('work-experiences.index'));
|
||||||
|
|
||||||
|
$experience = WorkExperience::where('werkgever', 'Acme')->firstOrFail();
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('work_experiences', [
|
||||||
|
'id' => $experience->id,
|
||||||
|
'functie' => 'Laravel Developer',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('media', [
|
||||||
|
'model_type' => WorkExperience::class,
|
||||||
|
'model_id' => $experience->id,
|
||||||
|
'collection_name' => 'image',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an authenticated user can update a work experience and replace its image', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$experience = WorkExperience::factory()->current()->create([
|
||||||
|
'werkgever' => 'Acme',
|
||||||
|
'functie' => 'Developer',
|
||||||
|
'startdatum' => '2022-01-01',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$experience
|
||||||
|
->addMedia(UploadedFile::fake()->image('old-experience.jpg'))
|
||||||
|
->toMediaCollection('image');
|
||||||
|
|
||||||
|
$response = $this->actingAs($user)->patch(route('work-experiences.update', $experience), [
|
||||||
|
'werkgever' => 'Globex',
|
||||||
|
'functie' => 'Senior Laravel Developer',
|
||||||
|
'startdatum' => '2023-01-01',
|
||||||
|
'einddatum' => null,
|
||||||
|
'beschrijving' => 'Leidde backend development.',
|
||||||
|
'afbeelding' => UploadedFile::fake()->image('new-experience.jpg'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response
|
||||||
|
->assertSessionHasNoErrors()
|
||||||
|
->assertRedirect(route('work-experiences.index'));
|
||||||
|
|
||||||
|
expect($experience->refresh())
|
||||||
|
->werkgever->toBe('Globex')
|
||||||
|
->functie->toBe('Senior Laravel Developer')
|
||||||
|
->getMedia('image')->toHaveCount(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('an authenticated user can delete a work experience and its image', function () {
|
||||||
|
$user = User::factory()->create();
|
||||||
|
|
||||||
|
$experience = WorkExperience::factory()->current()->create();
|
||||||
|
|
||||||
|
$experience
|
||||||
|
->addMedia(UploadedFile::fake()->image('experience.jpg'))
|
||||||
|
->toMediaCollection('image');
|
||||||
|
|
||||||
|
$this->actingAs($user)
|
||||||
|
->delete(route('work-experiences.destroy', $experience))
|
||||||
|
->assertRedirect(route('work-experiences.index'));
|
||||||
|
|
||||||
|
$this->assertDatabaseMissing('work_experiences', ['id' => $experience->id]);
|
||||||
|
$this->assertDatabaseMissing('media', [
|
||||||
|
'model_type' => WorkExperience::class,
|
||||||
|
'model_id' => $experience->id,
|
||||||
|
]);
|
||||||
|
});
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
it('returns a successful response', function () {
|
|
||||||
$response = $this->get('/');
|
|
||||||
|
|
||||||
$response->assertStatus(200);
|
|
||||||
});
|
|
||||||
@@ -12,7 +12,7 @@ test('profile page is displayed', function () {
|
|||||||
$response->assertOk();
|
$response->assertOk();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('profile information can be updated', function () {
|
test('profile information can be updated without changing email verification status', function () {
|
||||||
$user = User::factory()->create();
|
$user = User::factory()->create();
|
||||||
|
|
||||||
$response = $this
|
$response = $this
|
||||||
@@ -30,7 +30,7 @@ test('profile information can be updated', function () {
|
|||||||
|
|
||||||
$this->assertSame('Test User', $user->name);
|
$this->assertSame('Test User', $user->name);
|
||||||
$this->assertSame('test@example.com', $user->email);
|
$this->assertSame('test@example.com', $user->email);
|
||||||
$this->assertNull($user->email_verified_at);
|
$this->assertNotNull($user->email_verified_at);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('email verification status is unchanged when the email address is unchanged', function () {
|
test('email verification status is unchanged when the email address is unchanged', function () {
|
||||||
|
|||||||
@@ -2,9 +2,16 @@
|
|||||||
|
|
||||||
namespace Tests;
|
namespace Tests;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
|
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
|
||||||
|
|
||||||
abstract class TestCase extends BaseTestCase
|
abstract class TestCase extends BaseTestCase
|
||||||
{
|
{
|
||||||
//
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->withoutVite();
|
||||||
|
Storage::fake('public');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user