Add tests for creating course
This commit is contained in:
parent
50cf61e944
commit
a30d2659ad
|
@ -8,14 +8,15 @@ use App\Course\Requests\StoreRequest;
|
|||
use App\Course\Requests\UpdateRequest;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Member\Member;
|
||||
use App\Setting\NamiSettings;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CourseController extends Controller
|
||||
{
|
||||
public function store(Member $member, StoreRequest $request): RedirectResponse
|
||||
public function store(Member $member, StoreRequest $request, NamiSettings $settings): RedirectResponse
|
||||
{
|
||||
$request->persist($member);
|
||||
$request->persist($member, $settings);
|
||||
|
||||
return redirect()->back()->success('Ausbildung erstellt');
|
||||
}
|
||||
|
|
|
@ -4,13 +4,16 @@ namespace App\Course\Requests;
|
|||
|
||||
use App\Course\Models\Course;
|
||||
use App\Member\Member;
|
||||
use App\Setting\NamiSettings;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Zoomyboy\LaravelNami\Nami;
|
||||
use Zoomyboy\LaravelNami\NamiException;
|
||||
|
||||
class StoreRequest extends FormRequest
|
||||
{
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
|
@ -36,20 +39,21 @@ class StoreRequest extends FormRequest
|
|||
];
|
||||
}
|
||||
|
||||
public function persist(Member $member): void
|
||||
public function persist(Member $member, NamiSettings $settings): void
|
||||
{
|
||||
$course = Course::where('id', $this->input('course_id'))->firstOrFail();
|
||||
$payload = array_merge(
|
||||
$this->only(['event_name', 'completed_at', 'organizer']),
|
||||
['course_id' => $course->nami_id],
|
||||
);
|
||||
|
||||
$payload = collect($this->input())->only(['event_name', 'completed_at', 'organizer'])->merge([
|
||||
'course_id' => $course->nami_id,
|
||||
])->toArray();
|
||||
|
||||
try {
|
||||
$namiId = auth()->user()->api()->createCourse($member->nami_id, $payload);
|
||||
$namiId = Nami::login($settings->mglnr, $settings->password)->createCourse($member->nami_id, $payload);
|
||||
} catch(NamiException $e) {
|
||||
throw ValidationException::withMessages(['id' => 'Unbekannter Fehler']);
|
||||
}
|
||||
|
||||
$member->courses()->create($this->safe()->collect()->put('nami_id', $namiId)->toArray());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
namespace App\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Throwable;
|
||||
use Zoomyboy\LaravelNami\LoginException;
|
||||
use Zoomyboy\LaravelNami\NamiException;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
|
@ -58,6 +60,10 @@ class Handler extends ExceptionHandler
|
|||
*/
|
||||
public function render($request, Throwable $exception)
|
||||
{
|
||||
if ($exception instanceof LoginException) {
|
||||
throw ValidationException::withMessages(['nami' => 'NaMi Login fehlgeschlagen.']);
|
||||
}
|
||||
|
||||
return parent::render($request, $exception);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ use Illuminate\Http\Resources\Json\JsonResource;
|
|||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Laravel\Telescope\Telescope;
|
||||
use Zoomyboy\LaravelNami\Authentication\NamiGuard;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
@ -38,10 +37,6 @@ class AppServiceProvider extends ServiceProvider
|
|||
*/
|
||||
public function boot()
|
||||
{
|
||||
NamiGuard::beforeLogin(function(array $credentials) {
|
||||
return in_array($credentials['mglnr'], app(GeneralSettings::class)->allowed_nami_accounts)
|
||||
? null
|
||||
: false;
|
||||
});
|
||||
//
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Setting;
|
||||
|
||||
use Spatie\LaravelSettings\Settings;
|
||||
|
||||
class NamiSettings extends Settings
|
||||
{
|
||||
|
||||
public int $mglnr;
|
||||
|
||||
public string $password;
|
||||
|
||||
public static function group(): string
|
||||
{
|
||||
return 'nami';
|
||||
}
|
||||
|
||||
}
|
|
@ -39,8 +39,8 @@ return [
|
|||
|
||||
'guards' => [
|
||||
'web' => [
|
||||
'driver' => 'nami',
|
||||
'other_providers' => ['database'],
|
||||
'driver' => 'session',
|
||||
'provider' => 'database',
|
||||
],
|
||||
|
||||
'api' => [
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Database\Factories;
|
|||
|
||||
use App\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
/**
|
||||
* @extends Factory<User>
|
||||
|
@ -21,7 +22,9 @@ class UserFactory extends Factory
|
|||
public function definition()
|
||||
{
|
||||
return [
|
||||
//
|
||||
'email' => $this->faker->safeEmail,
|
||||
'password' => Hash::make('password'),
|
||||
'name' => $this->faker->firstName,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ class CreateUsersTable extends Migration
|
|||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('email');
|
||||
$table->string('name');
|
||||
$table->string('password');
|
||||
$table->timestamps();
|
||||
});
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
use Spatie\LaravelSettings\Migrations\SettingsMigration;
|
||||
|
||||
class CreateNamiSettings extends SettingsMigration
|
||||
{
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
$this->migrator->add('nami.mglnr', -1);
|
||||
$this->migrator->add('nami.password', '');
|
||||
}
|
||||
}
|
|
@ -1 +1 @@
|
|||
Subproject commit 829dd01358858c887dddaeadd6e4ddebd8f9fb0b
|
||||
Subproject commit b8d2a04d43dd7634ac6e653b26b07b317c5566db
|
|
@ -55,9 +55,9 @@ class StoreTest extends TestCase
|
|||
*/
|
||||
public function testItValidatesInput(array $payload, array $errors): void
|
||||
{
|
||||
$this->login()->init();
|
||||
$member = Member::factory()->defaults()->inNami(123)->createOne();
|
||||
$course = Course::factory()->inNami(456)->createOne();
|
||||
$this->login();
|
||||
$member = Member::factory()->defaults()->createOne();
|
||||
$course = Course::factory()->createOne();
|
||||
|
||||
$response = $this->post("/member/{$member->id}/course", array_merge([
|
||||
'course_id' => $course->id,
|
||||
|
@ -71,8 +71,7 @@ class StoreTest extends TestCase
|
|||
|
||||
public function testItCreatesACourse(): void
|
||||
{
|
||||
$this->withoutExceptionHandling();
|
||||
$this->login()->init();
|
||||
$this->withoutExceptionHandling()->login()->loginNami();
|
||||
$member = Member::factory()->defaults()->inNami(123)->createOne();
|
||||
$course = Course::factory()->inNami(456)->createOne();
|
||||
app(CourseFake::class)->createsSuccessful(123, 999);
|
||||
|
@ -100,9 +99,29 @@ class StoreTest extends TestCase
|
|||
]);
|
||||
}
|
||||
|
||||
public function testItThrowsErrorWhenLoginIsWrong(): void
|
||||
{
|
||||
$this->login()->failedNami();
|
||||
$member = Member::factory()->defaults()->inNami(123)->createOne();
|
||||
$course = Course::factory()->inNami(456)->createOne();
|
||||
|
||||
$response = $this->post("/member/{$member->id}/course", [
|
||||
'course_id' => $course->id,
|
||||
'completed_at' => '2021-01-02',
|
||||
'event_name' => '::event::',
|
||||
'organizer' => '::org::',
|
||||
]);
|
||||
|
||||
$this->assertErrors(['nami' => 'NaMi Login fehlgeschlagen.'], $response);
|
||||
|
||||
$this->assertDatabaseMissing('course_members', [
|
||||
'member_id' => $member->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function testItReceivesUnknownErrors(): void
|
||||
{
|
||||
$this->login()->init();
|
||||
$this->login()->loginNami();
|
||||
$member = Member::factory()->defaults()->inNami(123)->createOne();
|
||||
$course = Course::factory()->inNami(456)->createOne();
|
||||
app(CourseFake::class)->doesntCreateWithError(123);
|
||||
|
|
|
@ -56,7 +56,7 @@ class UpdateTest extends TestCase
|
|||
*/
|
||||
public function testItValidatesInput(array $payload, array $errors): void
|
||||
{
|
||||
$this->login()->init();
|
||||
$this->login();
|
||||
$member = Member::factory()->defaults()->inNami(123)->has(CourseMember::factory()->for(Course::factory()), 'courses')->createOne();
|
||||
$newCourse = Course::factory()->inNami(789)->create();
|
||||
|
||||
|
|
|
@ -1,140 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Setting\GeneralSettings;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Foundation\Testing\WithFaker;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Tests\TestCase;
|
||||
use Zoomyboy\LaravelNami\Authentication\NamiGuard;
|
||||
use Zoomyboy\LaravelNami\Backend\FakeBackend;
|
||||
|
||||
class NamiLoginTest extends TestCase
|
||||
{
|
||||
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testItCanLoginWithANamiAccount(): void
|
||||
{
|
||||
$this->withoutExceptionHandling();
|
||||
$this->setLoginId(123);
|
||||
app(FakeBackend::class)
|
||||
->fakeLogin('123')
|
||||
->addSearch(123, ['entries_vorname' => '::firstname::', 'entries_nachname' => '::lastname::', 'entries_gruppierungId' => 1000]);
|
||||
|
||||
$this->post('/login', [
|
||||
'mglnr' => 123,
|
||||
'provider' => 'nami',
|
||||
'password' => 'secret'
|
||||
]);
|
||||
|
||||
$key = session()->get('auth_key');
|
||||
$cache = Cache::get("namiauth-{$key}");
|
||||
$this->assertEquals('secret', data_get($cache, 'credentials.password'));
|
||||
$this->assertEquals('::firstname::', data_get($cache, 'firstname'));
|
||||
$this->assertEquals('::lastname::', data_get($cache, 'lastname'));
|
||||
$this->assertEquals(1000, data_get($cache, 'group_id'));
|
||||
$this->assertEquals(123, data_get($cache, 'credentials.mglnr'));
|
||||
$this->assertTrue(auth()->check());
|
||||
}
|
||||
|
||||
public function testItDoesntLoginTwoTimes(): void
|
||||
{
|
||||
$this->withoutExceptionHandling();
|
||||
$this->setLoginId(123);
|
||||
app(FakeBackend::class)
|
||||
->fakeLogin('123')
|
||||
->addSearch(123, ['entries_vorname' => '::firstname::', 'entries_nachname' => '::lastname::', 'entries_gruppierungId' => 1000]);
|
||||
|
||||
$this->post('/login', [
|
||||
'mglnr' => 123,
|
||||
'provider' => 'nami',
|
||||
'password' => 'secret'
|
||||
]);
|
||||
auth()->logout();
|
||||
$this->post('/login', [
|
||||
'mglnr' => 123,
|
||||
'provider' => 'nami',
|
||||
'password' => 'secret'
|
||||
]);
|
||||
|
||||
$this->assertTrue(auth()->check());
|
||||
|
||||
Http::assertSentCount(4);
|
||||
}
|
||||
|
||||
public function testItResolvesTheLoginFromTheCache(): void
|
||||
{
|
||||
$this->withoutExceptionHandling();
|
||||
$this->setLoginId(123);
|
||||
app(FakeBackend::class)
|
||||
->fakeLogin('123')
|
||||
->addSearch(123, ['entries_vorname' => '::firstname::', 'entries_nachname' => '::lastname::', 'entries_gruppierungId' => 1000]);
|
||||
|
||||
$this->post('/login', [
|
||||
'mglnr' => 123,
|
||||
'provider' => 'nami',
|
||||
'password' => 'secret'
|
||||
]);
|
||||
app(NamiGuard::class)->setUser(null);
|
||||
$this->post('/login', [
|
||||
'mglnr' => 123,
|
||||
'provider' => 'nami',
|
||||
'password' => 'secret'
|
||||
]);
|
||||
|
||||
$this->assertTrue(auth()->check());
|
||||
|
||||
Http::assertSentCount(3);
|
||||
}
|
||||
|
||||
public function testItThrowsExceptionWhenLoginFailed(): void
|
||||
{
|
||||
$this->setLoginId(123);
|
||||
app(FakeBackend::class)->fakeFailedLogin();
|
||||
|
||||
$this->post('/login', [
|
||||
'mglnr' => 123,
|
||||
'provider' => 'nami',
|
||||
'password' => 'secret'
|
||||
])->assertRedirect('/');
|
||||
|
||||
$this->assertFalse(auth()->check());
|
||||
|
||||
Http::assertSentCount(2);
|
||||
}
|
||||
|
||||
public function testItCannotLoginWithAWrongNamiId(): void
|
||||
{
|
||||
app(FakeBackend::class)
|
||||
->fakeLogin('123')
|
||||
->addSearch(123, ['entries_vorname' => '::firstname::', 'entries_nachname' => '::lastname::', 'entries_gruppierungId' => 1000]);
|
||||
|
||||
$this->post('/login', [
|
||||
'mglnr' => 123,
|
||||
'provider' => 'nami',
|
||||
'password' => 'secret'
|
||||
])->assertRedirect('/');
|
||||
|
||||
$this->assertTrue(auth()->guest());
|
||||
|
||||
Http::assertSentCount(0);
|
||||
}
|
||||
|
||||
private function setLoginId(int $mglNr): self
|
||||
{
|
||||
GeneralSettings::fake([
|
||||
'allowed_nami_accounts' => [$mglNr]
|
||||
]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
|
@ -10,7 +10,6 @@ use Illuminate\Support\Facades\Cache;
|
|||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Tests\TestCase;
|
||||
use Zoomyboy\LaravelNami\Authentication\NamiGuard;
|
||||
use Zoomyboy\LaravelNami\Backend\FakeBackend;
|
||||
|
||||
class UserLoginTest extends TestCase
|
||||
|
|
|
@ -4,9 +4,13 @@ namespace Tests;
|
|||
|
||||
use App\Member\Member;
|
||||
use App\Setting\GeneralSettings;
|
||||
use App\Setting\NamiSettings;
|
||||
use App\User;
|
||||
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Testing\TestResponse;
|
||||
use Tests\Lib\TestsInertia;
|
||||
use Zoomyboy\LaravelNami\Authentication\Auth;
|
||||
use Zoomyboy\LaravelNami\Backend\FakeBackend;
|
||||
use Zoomyboy\LaravelNami\Nami;
|
||||
use Zoomyboy\LaravelNami\NamiUser;
|
||||
|
@ -16,20 +20,40 @@ abstract class TestCase extends BaseTestCase
|
|||
use CreatesApplication;
|
||||
use TestsInertia;
|
||||
|
||||
public function fakeAuthUser(): void
|
||||
protected User $me;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
app(FakeBackend::class)
|
||||
->fakeLogin('123')
|
||||
->addSearch(123, ['entries_vorname' => '::firstname::', 'entries_nachname' => '::lastname::', 'entries_gruppierungId' => 1000]);
|
||||
parent::setUp();
|
||||
Auth::fake();
|
||||
}
|
||||
|
||||
public function loginNami(int $mglnr = 12345, string $password = 'password'): self
|
||||
{
|
||||
Auth::success($mglnr, $password);
|
||||
NamiSettings::fake([
|
||||
'mglnr' => $mglnr,
|
||||
'password' => $password,
|
||||
]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function failedNami(int $mglnr = 12345, string $password = 'password'): self
|
||||
{
|
||||
Auth::failed($mglnr, $password);
|
||||
NamiSettings::fake([
|
||||
'mglnr' => $mglnr,
|
||||
'password' => $password,
|
||||
]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function login(): self
|
||||
{
|
||||
$this->fakeAuthUser();
|
||||
auth()->loginNami([
|
||||
'mglnr' => 123,
|
||||
'password' => 'secret',
|
||||
]);
|
||||
$this->be($user = User::factory()->create());
|
||||
$this->me = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -40,5 +64,20 @@ abstract class TestCase extends BaseTestCase
|
|||
|
||||
return $this;
|
||||
}
|
||||
public function assertErrors(array $errors, TestResponse $response) {
|
||||
$response->assertSessionHas('errors');
|
||||
$this->assertInstanceOf(RedirectResponse::class, $response->baseResponse);
|
||||
/** @var RedirectResponse */
|
||||
$response = $response;
|
||||
|
||||
$sessionErrors = $response->getSession()->get('errors')->getBag('default');
|
||||
|
||||
foreach ($errors as $key => $value) {
|
||||
$this->assertTrue($sessionErrors->has($key), "Cannot find key {$key} in errors '".print_r($sessionErrors, true));
|
||||
$this->assertEquals($value, $sessionErrors->get($key)[0], "Failed to validate value for session error key {$key}. Actual value: ".print_r($sessionErrors, true));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue