Write tests - Write tests for what was done to this point that will be kept #11
|
|
@ -5,10 +5,10 @@ namespace App\Http\Controllers;
|
|||
use App\Models\Audition;
|
||||
use App\Models\School;
|
||||
use App\Models\Student;
|
||||
use App\Models\User;
|
||||
use App\Rules\UniqueFullNameAtSchool;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
use function abort;
|
||||
use function redirect;
|
||||
|
||||
|
|
@ -20,9 +20,13 @@ class StudentController extends Controller
|
|||
*/
|
||||
public function index()
|
||||
{
|
||||
if (! Auth::user()->school_id) {
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
$students = Auth::user()->students()->with('entries')->get();
|
||||
$auditions = Audition::all();
|
||||
return view('students.index',['students' => $students, 'auditions' => $auditions]);
|
||||
|
||||
return view('students.index', ['students' => $students, 'auditions' => $auditions]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -38,21 +42,26 @@ class StudentController extends Controller
|
|||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
if ($request->user()->cannot('create', Student::class)) abort(403);
|
||||
if ($request->user()->cannot('create', Student::class)) {
|
||||
abort(403);
|
||||
}
|
||||
$request->validate([
|
||||
'first_name' => ['required'],
|
||||
'last_name' => ['required', new UniqueFullNameAtSchool(request('first_name'),request('last_name'), Auth::user()->school_id)],
|
||||
'grade' => ['required', 'integer'],
|
||||
'last_name' => [
|
||||
'required',
|
||||
new UniqueFullNameAtSchool(request('first_name'), request('last_name'), Auth::user()->school_id),
|
||||
],
|
||||
'grade' => ['required', 'integer'],
|
||||
]);
|
||||
|
||||
$student = Student::create([
|
||||
'first_name' => request('first_name'),
|
||||
'last_name' => request('last_name'),
|
||||
'grade' => request('grade'),
|
||||
'school_id' => Auth::user()->school_id
|
||||
'school_id' => Auth::user()->school_id,
|
||||
]);
|
||||
|
||||
$request->session()->put('auditionMessages',['success','I did it again ma']);
|
||||
$request->session()->put('auditionMessages', ['success', 'I did it again ma']);
|
||||
|
||||
return redirect('/students');
|
||||
}
|
||||
|
|
@ -70,7 +79,10 @@ class StudentController extends Controller
|
|||
*/
|
||||
public function edit(Request $request, Student $student)
|
||||
{
|
||||
if ($request->user()->cannot('update', $student)) abort(403);
|
||||
if ($request->user()->cannot('update', $student)) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
return view('students.edit', ['student' => $student]);
|
||||
}
|
||||
|
||||
|
|
@ -79,22 +91,23 @@ class StudentController extends Controller
|
|||
*/
|
||||
public function update(Request $request, Student $student)
|
||||
{
|
||||
if ($request->user()->cannot('update', $student)) abort(403);
|
||||
if ($request->user()->cannot('update', $student)) {
|
||||
abort(403);
|
||||
}
|
||||
request()->validate([
|
||||
'first_name' => ['required'],
|
||||
'last_name' => ['required'],
|
||||
'grade' => ['required', 'integer'],
|
||||
'last_name' => ['required'],
|
||||
'grade' => ['required', 'integer'],
|
||||
]);
|
||||
|
||||
$student->update([
|
||||
'first_name' => request('first_name'),
|
||||
'last_name' => request('last_name'),
|
||||
'grade' => request('grade')
|
||||
'grade' => request('grade'),
|
||||
]);
|
||||
|
||||
// TODO if a students grade is changed, we need to be sure they are still eligible for the auditions in which they are entered.
|
||||
|
||||
|
||||
return redirect('/students');
|
||||
}
|
||||
|
||||
|
|
@ -103,8 +116,11 @@ class StudentController extends Controller
|
|||
*/
|
||||
public function destroy(Request $request, Student $student)
|
||||
{
|
||||
if ($request->user()->cannot('delete', $student)) abort(403);
|
||||
if ($request->user()->cannot('delete', $student)) {
|
||||
abort(403);
|
||||
}
|
||||
$student->delete();
|
||||
|
||||
return redirect('/students');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class CheckIfAdmin
|
|||
return $next($request);
|
||||
}
|
||||
|
||||
return redirect('/')->with('error', 'You do not have admin access.');
|
||||
return redirect(route('home'))->with('error', 'You do not have admin access.');
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@ namespace App\Http\Middleware;
|
|||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use function redirect;
|
||||
use function route;
|
||||
|
||||
class CheckIfHasSchool
|
||||
{
|
||||
|
|
@ -15,6 +18,11 @@ class CheckIfHasSchool
|
|||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
return $next($request);
|
||||
if (Auth::check() && Auth::user()->school_id) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
return redirect(route('dashboard'))->with('error', 'You do not have a school to view students for.');
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
use function now;
|
||||
|
||||
class Audition extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
|
@ -26,7 +24,6 @@ class Audition extends Model
|
|||
|
||||
protected $scored_entries_count; //Set by TabulationService
|
||||
|
||||
|
||||
public function event(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Event::class);
|
||||
|
|
@ -175,12 +172,14 @@ class Audition extends Model
|
|||
}
|
||||
|
||||
$this->flags()->create(['flag_name' => $flag]);
|
||||
$this->load('flags');
|
||||
}
|
||||
|
||||
public function removeFlag($flag): void
|
||||
{
|
||||
// remove related auditionFlag where flag_name = $flag
|
||||
$this->flags()->where('flag_name', $flag)->delete();
|
||||
$this->load('flags');
|
||||
}
|
||||
|
||||
public function scopeOpen(Builder $query): void
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace App\Policies;
|
|||
use App\Models\Entry;
|
||||
use App\Models\Student;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
use function is_null;
|
||||
|
||||
class StudentPolicy
|
||||
|
|
@ -31,7 +31,10 @@ class StudentPolicy
|
|||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
if($user->is_admin) return true;
|
||||
if ($user->is_admin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ! is_null($user->school_id);
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +44,10 @@ class StudentPolicy
|
|||
public function update(User $user, Student $student): bool
|
||||
{
|
||||
|
||||
if($user->is_admin) return true;
|
||||
if ($user->is_admin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $user->school_id == $student->school_id;
|
||||
}
|
||||
|
||||
|
|
@ -50,7 +56,10 @@ class StudentPolicy
|
|||
*/
|
||||
public function delete(User $user, Student $student): bool
|
||||
{
|
||||
if (Entry::where('student_id','=',$student->id)->exists()) return false; // Don't allow deletion of a student with entries
|
||||
if (Entry::where('student_id', '=', $student->id)->exists()) {
|
||||
return false;
|
||||
} // Don't allow deletion of a student with entries
|
||||
|
||||
return $user->school_id == $student->school_id;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class UniqueFullNameAtSchool implements ValidationRule
|
|||
$this->school_id = $schoolID;
|
||||
}
|
||||
|
||||
public function passes($attributies, $value)
|
||||
public function studentExists()
|
||||
{
|
||||
return Student::where('first_name', $this->first_name)
|
||||
->where('last_name', $this->last_name)
|
||||
|
|
@ -38,6 +38,8 @@ class UniqueFullNameAtSchool implements ValidationRule
|
|||
*/
|
||||
public function validate(string $attribute, mixed $value, Closure $fail): void
|
||||
{
|
||||
//
|
||||
if($this->studentExists()) {
|
||||
$fail($this->message());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class AuditionFactory extends Factory
|
|||
|
||||
return [
|
||||
'event_id' => $event->id,
|
||||
'name' => $this->faker->randomElement($instruments).$this->faker->randomNumber(1),
|
||||
'name' => $this->faker->randomElement($instruments).$this->faker->randomNumber(3),
|
||||
'score_order' => 1,
|
||||
'entry_deadline' => Carbon::tomorrow(),
|
||||
'entry_fee' => 1000,
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ class RoomFactory extends Factory
|
|||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'Room ' . fake()->numberBetween(7,500),
|
||||
'description' => fake()->sentence()
|
||||
'name' => 'Room '.fake()->numberBetween(7, 500),
|
||||
'description' => fake()->sentence(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class ScoringGuideFactory extends Factory
|
|||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
'name' => $this->faker->sentence(3),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use App\Models\SiteSetting;
|
|||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class SampleSettings extends Seeder
|
||||
class SampleSettingsSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
|
|
@ -55,10 +55,6 @@ class SampleSettings extends Seeder
|
|||
]);
|
||||
SiteSetting::create([
|
||||
'setting_key' => 'school_fee',
|
||||
'setting_value' => 'SBDA',
|
||||
]);
|
||||
SiteSetting::create([
|
||||
'setting_key' => 'auditionAbbreviation',
|
||||
'setting_value' => '2500',
|
||||
]);
|
||||
SiteSetting::create([
|
||||
|
|
@ -66,12 +62,16 @@ class SampleSettings extends Seeder
|
|||
'setting_value' => '143 Sousa Lane',
|
||||
]);
|
||||
SiteSetting::create([
|
||||
'setting_key' => 'auditionAbbreviation',
|
||||
'setting_value' => 'SBDA',
|
||||
'setting_key' => 'payment_city',
|
||||
'setting_value' => 'Maud',
|
||||
]);
|
||||
SiteSetting::create([
|
||||
'setting_key' => 'auditionAbbreviation',
|
||||
'setting_value' => 'SBDA',
|
||||
'setting_key' => 'payment_state',
|
||||
'setting_value' => 'OK',
|
||||
]);
|
||||
SiteSetting::create([
|
||||
'setting_key' => 'payment_zip',
|
||||
'setting_value' => '77777',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
{{-- <button type="button" class="inline-flex items-center gap-x-1 text-sm font-semibold leading-6 text-gray-900" aria-expanded="false" @on:click=" open = ! open">--}}
|
||||
|
||||
<button type="button" class="inline-flex items-center gap-x-1 text-white rounded-md px-3 py-2 text-sm font-medium hover:bg-indigo-500 hover:bg-opacity-75" aria-expanded="false" @click=" open = ! open" @click.outside=" open = false">
|
||||
<span>Admin</span>
|
||||
<span>Administration</span>
|
||||
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
|
|
|
|||
|
|
@ -14,16 +14,16 @@
|
|||
</div>
|
||||
<div class="hidden md:block">
|
||||
<div class="ml-10 flex items-baseline space-x-4">
|
||||
<x-layout.navbar.nav-link href="/dashboard" :active="request()->is('dashboard')">Dashboard
|
||||
<x-layout.navbar.nav-link href="{{ route('dashboard') }}" :active="request()->is('dashboard')">Dashboard
|
||||
</x-layout.navbar.nav-link>
|
||||
@if(Auth::user()->school_id)
|
||||
<x-layout.navbar.nav-link href="/students" :active="request()->is('students')">Students
|
||||
<x-layout.navbar.nav-link href="{{ route('students.index') }}" :active="request()->is('students')">Students
|
||||
</x-layout.navbar.nav-link>
|
||||
<x-layout.navbar.nav-link href="/entries" :active="request()->is('entries')">Entries
|
||||
<x-layout.navbar.nav-link href="{{ route('entries.index') }}" :active="request()->is('entries')">Entries
|
||||
</x-layout.navbar.nav-link>
|
||||
@endif
|
||||
@if(Auth::user()->isJudge() AND Settings::get('judging_enabled'))
|
||||
<x-layout.navbar.nav-link href="/judging" :active="request()->is('judging')">Judging
|
||||
<x-layout.navbar.nav-link href="{{ route('judging.index') }}" :active="request()->is('judging')">Judging
|
||||
</x-layout.navbar.nav-link>
|
||||
@endif
|
||||
@if(Auth::user()->is_admin)
|
||||
|
|
@ -164,8 +164,7 @@
|
|||
<!-- Current: "bg-indigo-700 text-white", Default: "text-white hover:bg-indigo-500 hover:bg-opacity-75" -->
|
||||
<a href="/dashboard" class="bg-indigo-700 text-white block rounded-md px-3 py-2 text-base font-medium"
|
||||
aria-current="page">Dashboard</a>
|
||||
<a href="/students"
|
||||
class="text-white hover:bg-indigo-500 hover:bg-opacity-75 block rounded-md px-3 py-2 text-base font-medium">Students</a>
|
||||
|
||||
</div>
|
||||
<div class="border-t border-indigo-700 pb-3 pt-4">
|
||||
<div class="flex items-center px-5">
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<x-layout.app>
|
||||
<x-slot:page_title>Dashboard</x-slot:page_title>
|
||||
@if(! Auth::user()->school_id)
|
||||
You aren't currently associated with a school. <a href="/my_school" class="text-blue-600">Click here to choose or create one.</a>
|
||||
<p class="pb-5">You aren't currently associated with a school. <a href="/my_school" class="text-blue-600">Click here to choose or create one.</a></p>
|
||||
@endif
|
||||
<div class="grid sm:grid-cols-2 md:grid-cols-4">
|
||||
<div>{{-- Column 1 --}}
|
||||
|
|
|
|||
|
|
@ -19,32 +19,32 @@ Route::middleware(['auth', 'verified'])->group(function () {
|
|||
|
||||
// Entry Related Routes
|
||||
Route::middleware(['auth', 'verified', 'can:create,App\Models\Entry'])->controller(EntryController::class)->group(function () {
|
||||
Route::get('/entries', 'index');
|
||||
Route::get('/entries/create', 'create');
|
||||
Route::post('/entries', 'store');
|
||||
Route::delete('/entries/{entry}', 'destroy');
|
||||
Route::get('/entries', 'index')->name('entries.index');
|
||||
Route::get('/entries/create', 'create')->name('entries.create');
|
||||
Route::post('/entries', 'store')->name('entries.store');
|
||||
Route::delete('/entries/{entry}', 'destroy')->name('entries.destroy');
|
||||
});
|
||||
|
||||
// User Related Routes
|
||||
Route::middleware(['auth', 'verified'])->controller(UserController::class)->group(function () {
|
||||
Route::patch('/users/{user}/set_school', 'set_school');
|
||||
Route::patch('/users/{$user}', 'update');
|
||||
Route::patch('/users/{user}/set_school', 'set_school')->name('users.set_school');
|
||||
Route::patch('/users/{$user}', 'update')->name('users.update');
|
||||
});
|
||||
|
||||
// Student Related Routes
|
||||
Route::middleware(['auth', 'verified', 'can:create,App\Models\Student'])->controller(StudentController::class)->group(function () {
|
||||
Route::get('/students', 'index');
|
||||
Route::post('students', 'store');
|
||||
Route::get('/students/{student}/edit', 'edit');
|
||||
Route::patch('/students/{student}', 'update');
|
||||
Route::delete('/students/{student}', 'destroy');
|
||||
Route::get('/students', 'index')->name('students.index');
|
||||
Route::post('students', 'store')->name('students.store');
|
||||
Route::get('/students/{student}/edit', 'edit')->name('students.edit');
|
||||
Route::patch('/students/{student}', 'update')->name('students.update');
|
||||
Route::delete('/students/{student}', 'destroy')->name('students.destroy');
|
||||
});
|
||||
|
||||
// School Related Routes
|
||||
Route::middleware(['auth', 'verified'])->controller(SchoolController::class)->group(function () {
|
||||
Route::get('/schools/create', 'create');
|
||||
Route::post('/schools', 'store');
|
||||
Route::get('/schools/{school}/edit', 'edit');
|
||||
Route::get('/schools/{school}', 'show')->name('schools.show');
|
||||
Route::patch('/schools/{school}', 'update');
|
||||
Route::get('/schools/create', 'create')->name('schools.create');
|
||||
Route::post('/schools', 'store')->name('schools.store');
|
||||
Route::get('/schools/{school}/edit', 'edit')->name('schools.edit');
|
||||
Route::get('/schools/{school}', 'show')->name('schools.show')->name('schools.show');
|
||||
Route::patch('/schools/{school}', 'update')->name('schools.update');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Audition;
|
||||
use App\Models\AuditionFlag;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
test('has an audition', function () {
|
||||
|
||||
$audition = Audition::factory()->create();
|
||||
// Arrange
|
||||
$flag = AuditionFlag::create([
|
||||
'audition_id' => $audition->id,
|
||||
'flag_name' => 'Test Flag',
|
||||
]);
|
||||
|
||||
// Act and Assert
|
||||
expect($flag->audition->name)->toBe($audition->name);
|
||||
|
||||
});
|
||||
|
|
@ -1,6 +1,12 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Audition;
|
||||
use App\Models\AuditionFlag;
|
||||
use App\Models\Entry;
|
||||
use App\Models\Event;
|
||||
use App\Models\Room;
|
||||
use App\Models\ScoringGuide;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
|
@ -63,3 +69,102 @@ it('only returns published advancement auditions for advancementPublished scope'
|
|||
->first()->id->toEqual($published->id);
|
||||
|
||||
});
|
||||
|
||||
it('has an event', function () {
|
||||
// Arrange
|
||||
$event = Event::factory()->create(['name' => 'Symphonic Concert Wind Ensemble Band']);
|
||||
$audition = Audition::factory()->create(['event_id' => $event->id]);
|
||||
// Act & Assert
|
||||
expect($audition->event->name)->toEqual('Symphonic Concert Wind Ensemble Band');
|
||||
|
||||
});
|
||||
|
||||
it('has entries', function () {
|
||||
// Arrange
|
||||
$audition = Audition::factory()->create();
|
||||
Entry::factory()->count(10)->create(['audition_id' => $audition->id]);
|
||||
// Act & Assert
|
||||
expect($audition->entries->count())->toEqual(10);
|
||||
});
|
||||
|
||||
it('has a room', function () {
|
||||
// Arrange
|
||||
$room = Room::factory()->create(['name' => 'Room 1']);
|
||||
$audition = Audition::factory()->create(['room_id' => $room->id]);
|
||||
|
||||
// Act & Assert
|
||||
expect($audition->room->name)->toEqual('Room 1');
|
||||
|
||||
});
|
||||
|
||||
it('has a scoring guide', function () {
|
||||
// Arrange
|
||||
$sg = ScoringGuide::factory()->create(['name' => 'Sight Reading']);
|
||||
$audition = Audition::factory()->create(['scoring_guide_id' => $sg->id]);
|
||||
// Act & Assert
|
||||
expect($audition->scoringGuide->name)->toEqual('Sight Reading');
|
||||
|
||||
});
|
||||
|
||||
it('displays the entry fee', function () {
|
||||
// Arrange
|
||||
$audition = Audition::factory()->create(['entry_fee' => 1000]);
|
||||
// Act & Assert
|
||||
expect($audition->display_fee())->toEqual('$10.00');
|
||||
});
|
||||
|
||||
it('has many judges', function () {
|
||||
// Arrange
|
||||
$room = Room::factory()->create();
|
||||
$audition = Audition::factory()->create(['room_id' => $room->id]);
|
||||
$judges = User::factory()->count(5)->create();
|
||||
foreach ($judges as $judge) {
|
||||
$room->addJudge($judge->id);
|
||||
}
|
||||
// Act & Assert
|
||||
expect($audition->judges->count())->toEqual(5);
|
||||
});
|
||||
|
||||
it('has a judges_count available', function () {
|
||||
// Arrange
|
||||
$room = Room::factory()->create();
|
||||
$audition = Audition::factory()->create(['room_id' => $room->id]);
|
||||
$judges = User::factory()->count(5)->create();
|
||||
foreach ($judges as $judge) {
|
||||
$room->addJudge($judge->id);
|
||||
}
|
||||
// Act & Assert
|
||||
expect($audition->judges_count)->toEqual(5);
|
||||
});
|
||||
|
||||
it('can have flags', function () {
|
||||
// Arrange
|
||||
$audition = Audition::factory()->create();
|
||||
AuditionFlag::create(['audition_id' => $audition->id, 'flag_name' => 'seats_published']);
|
||||
AuditionFlag::create(['audition_id' => $audition->id, 'flag_name' => 'advance_published']);
|
||||
// Act
|
||||
// Assert
|
||||
expect($audition->hasFlag('seats_published'))->toBeTrue();
|
||||
expect($audition->hasFlag('notaflag'))->toBeFalse();
|
||||
expect($audition->flags->count())->toEqual(2);
|
||||
});
|
||||
|
||||
it('can add flags', function () {
|
||||
// Arrange
|
||||
$audition = Audition::factory()->create();
|
||||
// Act
|
||||
$audition->addFlag('seats_published');
|
||||
// Assert
|
||||
expect($audition->hasFlag('seats_published'))->toBeTrue();
|
||||
});
|
||||
|
||||
it('can remove flags', function () {
|
||||
// Arrange
|
||||
$audition = Audition::factory()->create();
|
||||
AuditionFlag::create(['audition_id' => $audition->id, 'flag_name' => 'seats_published']);
|
||||
// Act & Assert
|
||||
$audition->addFlag('seats_published');
|
||||
expect($audition->hasFlag('seats_published'))->toBeTrue();
|
||||
$audition->removeFlag('seats_published');
|
||||
expect($audition->hasFlag('seats_published'))->toBeFalse();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,56 @@
|
|||
<?php
|
||||
|
||||
it('', function () {
|
||||
use App\Models\School;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
use function Pest\Laravel\get;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
it('only shows Students and Entries menu options if the user has a school', function () {
|
||||
// Act & Assert
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user);
|
||||
get(route('dashboard'))
|
||||
->assertStatus(200)
|
||||
->assertSeeText('Dashboard')
|
||||
->assertDontSeeText('Students')
|
||||
->assertDontSeeText('Entries');
|
||||
|
||||
$school = School::factory()->create();
|
||||
$user->school_id = $school->id;
|
||||
$user->save();
|
||||
get(route('dashboard'))
|
||||
->assertStatus(200)
|
||||
->assertSeeText('My School')
|
||||
->assertSeeText('Dashboard')
|
||||
->assertSeeText('Students')
|
||||
->assertSeeText('Entries');
|
||||
});
|
||||
|
||||
it('only shows Admin menu if an administrator only shows Tabulation if admin or tabulator', function () {
|
||||
// Arrange
|
||||
$user = User::factory()->create();
|
||||
$adminUser = User::factory()->admin()->create();
|
||||
$tabUser = User::factory()->tab()->create();
|
||||
|
||||
// Act & Assert
|
||||
$this->actingAs($user);
|
||||
get(route('dashboard'))
|
||||
->assertStatus(200)
|
||||
->assertDontSeeText('Administration');
|
||||
|
||||
$this->actingAs($adminUser);
|
||||
get(route('dashboard'))
|
||||
->assertStatus(200)
|
||||
->assertSeeText('Administration')
|
||||
->assertSeeText('Tabulation');
|
||||
|
||||
$this->actingAs($tabUser);
|
||||
get(route('dashboard'))
|
||||
->assertStatus(200)
|
||||
->assertDontSeeText('Administration')
|
||||
->assertSeeText('Tabulation');
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,134 @@
|
|||
<?php
|
||||
|
||||
it('', function () {
|
||||
use App\Models\School;
|
||||
use App\Models\Student;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
use function Pest\Laravel\get;
|
||||
use function Pest\Laravel\post;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
it('cannot be accessed by a guest', function () {
|
||||
// Act & Assert
|
||||
get(route('students.index'))
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('home'));
|
||||
});
|
||||
|
||||
it('cannot be accessed by a user without a school', function () {
|
||||
// Arrange
|
||||
$user = User::factory()->create();
|
||||
$userWithSchool = User::factory()->create([
|
||||
'school_id' => School::factory()->create()->id,
|
||||
]);
|
||||
// Act & Assert
|
||||
$this->actingAs($user);
|
||||
get('/students')
|
||||
->assertStatus(403);
|
||||
|
||||
$this->actingAs($userWithSchool);
|
||||
get('/students')
|
||||
->assertStatus(200);
|
||||
|
||||
});
|
||||
|
||||
it('Shows a student for the user', function () {
|
||||
// Arrange
|
||||
$school = School::factory()->create();
|
||||
$user = User::factory()->create([
|
||||
'school_id' => $school->id,
|
||||
]);
|
||||
$student = Student::factory()->create([
|
||||
'school_id' => $school->id,
|
||||
]);
|
||||
|
||||
$students = [
|
||||
['first_name' => 'John', 'last_name' => 'Lennon'],
|
||||
['first_name' => 'Paul', 'last_name' => 'McCartney'],
|
||||
['first_name' => 'George', 'last_name' => 'Harrison'],
|
||||
['first_name' => 'Ringo', 'last_name' => 'Starr'],
|
||||
];
|
||||
|
||||
foreach ($students as $s) {
|
||||
Student::factory()->create([
|
||||
'school_id' => $school->id,
|
||||
'first_name' => $s['first_name'],
|
||||
'last_name' => $s['last_name'],
|
||||
]);
|
||||
}
|
||||
|
||||
// Act and Assert
|
||||
$this->actingAs($user);
|
||||
get(route('students.index'))
|
||||
->assertStatus(200)
|
||||
->assertSeeText($student->name)
|
||||
->assertSeeText(['Lennon, John', 'McCartney, Paul', 'Harrison, George', 'Starr, Ringo']);
|
||||
});
|
||||
|
||||
it('does not show a student from another school', function () {
|
||||
// Arrange
|
||||
$school = School::factory()->create();
|
||||
$user = User::factory()->create([
|
||||
'school_id' => $school->id,
|
||||
]);
|
||||
$student = Student::factory()->create([
|
||||
'school_id' => $school->id,
|
||||
]);
|
||||
$otherSchool = School::factory()->create();
|
||||
$otherStudent = Student::factory()->create([
|
||||
'school_id' => $otherSchool->id,
|
||||
]);
|
||||
// Act & Assert
|
||||
$this->actingAs($user);
|
||||
get(route('students.index'))
|
||||
->assertStatus(200)
|
||||
->assertSeeText($student->name)
|
||||
->assertDontSeeText($otherStudent->name);
|
||||
|
||||
// Assert
|
||||
|
||||
});
|
||||
|
||||
it('can accept a new student entry', function () {
|
||||
// Act and Assert
|
||||
$school = School::factory()->create();
|
||||
$user = User::factory()->create([
|
||||
'school_id' => $school->id,
|
||||
]);
|
||||
$this->actingAs($user);
|
||||
post(route('students.store'), [
|
||||
'first_name' => 'James',
|
||||
'last_name' => 'Brown',
|
||||
'grade' => 10,
|
||||
])
|
||||
->assertSessionHasNoErrors()
|
||||
->assertRedirect(route('students.index'));
|
||||
|
||||
get(route('students.index'))
|
||||
->assertSeeText('Brown, James');
|
||||
|
||||
expect(Student::count())->toBe(1);
|
||||
|
||||
});
|
||||
|
||||
it('cannot have two students with identical names at a school', function () {
|
||||
$school = School::factory()->create();
|
||||
$user = User::factory()->create([
|
||||
'school_id' => $school->id,
|
||||
]);
|
||||
Student::factory()->create([
|
||||
'school_id' => $school->id,
|
||||
'first_name' => 'James',
|
||||
'last_name' => 'Brown',
|
||||
]);
|
||||
$this->actingAs($user);
|
||||
post(route('students.store'), [
|
||||
'first_name' => 'James',
|
||||
'last_name' => 'Brown',
|
||||
'grade' => 10,
|
||||
])
|
||||
->assertSessionHasErrors('last_name');
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
use App\Models\School;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
|
|
@ -57,3 +58,17 @@ it('shows dashboard only if logged in', function () {
|
|||
->assertSeeText('My School')
|
||||
->assertSeeText('Dashboard');
|
||||
});
|
||||
|
||||
it('shows students index only for a user with a school', function () {
|
||||
// Act & Assert
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user);
|
||||
get(route('students.index'))
|
||||
->assertStatus(403);
|
||||
|
||||
$school = School::factory()->create();
|
||||
$user->school_id = $school->id;
|
||||
get(route('students.index'))
|
||||
->assertStatus(200)
|
||||
->assertSeeText('Student Listing');
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue