Add check for authentication

This commit is contained in:
philipp lang 2022-02-19 13:37:53 +01:00
parent 15a6bcc70e
commit 798f7222e9
10 changed files with 139 additions and 40 deletions

View File

@ -15,6 +15,7 @@ use Log;
use Zoomyboy\LaravelNami\Authentication\Authenticator;
use Zoomyboy\LaravelNami\Backend\Backend;
use Zoomyboy\LaravelNami\Concerns\IsNamiMember;
use Zoomyboy\LaravelNami\Exceptions\NotAuthenticatedException;
use Zoomyboy\LaravelNami\Exceptions\RightException;
use Zoomyboy\LaravelNami\NamiException;
@ -92,6 +93,11 @@ class Api {
return $this;
}
public function isLoggedIn(): bool
{
return $this->authenticator->isLoggedIn();
}
public function membersOf($groupId): Collection {
return collect($this->http()->get($this->url.'/ica/rest/nami/mitglied/filtered-for-navigation/gruppierung/gruppierung/'.$groupId.'/flist')->json()['data']);
}
@ -186,6 +192,7 @@ class Api {
public function coursesFor(int $memberId): Collection
{
$this->assertLoggedIn();
$url = $this->url."/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/{$memberId}/flist";
$response = $this->http()->get($url);
@ -382,5 +389,12 @@ class Api {
throw (new NamiException($message))->response($response)->request($request);
}
private function assertLoggedIn(): void
{
if (!$this->isLoggedIn()) {
throw new NotAuthenticatedException('You need to login first');
}
}
}

View File

@ -8,5 +8,6 @@ abstract class Authenticator {
abstract public function login(int $mglnr, string $password): self;
abstract public function http(): PendingRequest;
abstract public function isLoggedIn(): bool;
}

View File

@ -33,6 +33,11 @@ class FakeCookie extends Authenticator {
return $this;
}
public function isLoggedIn(): bool
{
return $this->authenticated !== null;
}
public function http(): PendingRequest
{
return Http::withOptions([]);
@ -82,15 +87,15 @@ class FakeCookie extends Authenticator {
public function assertNotLoggedIn(): void
{
Assert::assertNull(
$this->authenticated,
Assert::assertFalse(
$this->isLoggedIn(),
'Failed asserting that noone is logged in. Found login with '.data_get($this->authenticated, 'mglnr')
);
}
public function assertLoggedIn(): void
{
Assert::assertTrue($this->isLoggedIn());
}
}

View File

@ -43,12 +43,7 @@ class MainCookie extends Authenticator {
return $this;
}
public function http(): PendingRequest
{
return Http::withOptions(['cookies' => $this->load()]);
}
private function isLoggedIn(): bool
public function isLoggedIn(): bool
{
if ($this->file() === null) {
return false;
@ -57,6 +52,11 @@ class MainCookie extends Authenticator {
return ! $this->isExpired();
}
public function http(): PendingRequest
{
return Http::withOptions(['cookies' => $this->load()]);
}
private function newFileName(): string
{
return $this->path.'/'.time().'.txt';

View File

@ -8,19 +8,13 @@ use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use Zoomyboy\LaravelNami\Fakes\CourseFake;
use Zoomyboy\LaravelNami\Fakes\Fake;
use Zoomyboy\LaravelNami\Fakes\FakeInstance;
use Zoomyboy\LaravelNami\Fakes\LoginFake;
class FakeBackend {
public function fakeLogin(string $mglnr): self
{
app(LoginFake::class)->succeeds($mglnr);
return $this;
}
/**
* @param int $mitgliedsNr
* @param array <string, mixed> $data
@ -116,27 +110,12 @@ class FakeBackend {
]) ?: '{}', 200);
}
}
foreach ($data as $member) {
if ($request->url() === "https://nami.dpsg.de/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/{$member['id']}/flist") {
return Http::response(json_encode([
'success' => true,
'totalEntries' => collect($member['courses'] ?? [])->count(),
'data' => collect($member['courses'] ?? [])->map(fn ($course) => ['id' => $course['id']]),
]) ?: '{}', 200);
}
foreach ($member['courses'] ?? [] as $course) {
if ($request->url() === "https://nami.dpsg.de/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/{$member['id']}/{$course['id']}") {
return Http::response(json_encode([
'success' => true,
'data' => $course,
]) ?: '{}', 200);
}
}
}
});
foreach ($data as $member) {
app(CourseFake::class)->forMember($member['id'], $member['courses'] ?? []);
}
return $this;
}

View File

@ -0,0 +1,9 @@
<?php
namespace Zoomyboy\LaravelNami\Exceptions;
use Exception;
class NotAuthenticatedException extends Exception {
}

View File

@ -7,6 +7,28 @@ use Illuminate\Support\Facades\Http;
class CourseFake extends Fake {
public function forMember(int $memberId, array $data): void
{
Http::fake(function($request) use ($memberId, $data) {
if ($request->url() === "https://nami.dpsg.de/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/{$memberId}/flist") {
return Http::response(json_encode([
'success' => true,
'totalEntries' => collect($data)->count(),
'data' => collect($data)->map(fn ($course) => ['id' => $course['id']]),
]) ?: '{}', 200);
}
foreach ($data as $course) {
if ($request->url() === "https://nami.dpsg.de/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/{$memberId}/{$course['id']}") {
return Http::response(json_encode([
'success' => true,
'data' => $course,
]) ?: '{}', 200);
}
}
});
}
public function createsSuccessful(int $memberId, int $courseId): void
{
Http::fake(function($request) use ($memberId, $courseId) {

View File

@ -6,15 +6,11 @@ use Illuminate\Support\Facades\Facade;
/**
* @method static \Zoomyboy\LaravelNami\Api login(int $mglnr, string $password)
* @method static bool isLoggedIn()
* @method static \Zoomyboy\LaravelNami\Api fake()
*/
class Nami extends Facade {
protected static function getFacadeAccessor() { return 'nami.api'; }
protected static function fake(): void
{
static::swap(ApiFake::class);
}
}

62
tests/Unit/CourseTest.php Normal file
View File

@ -0,0 +1,62 @@
<?php
namespace Zoomyboy\LaravelNami\Tests\Unit;
use Illuminate\Support\Facades\Http;
use Zoomyboy\LaravelNami\Authentication\Auth;
use Zoomyboy\LaravelNami\Exceptions\NotAuthenticatedException;
use Zoomyboy\LaravelNami\Fakes\CourseFake;
use Zoomyboy\LaravelNami\LoginException;
use Zoomyboy\LaravelNami\Nami;
use Zoomyboy\LaravelNami\Tests\TestCase;
class CourseTest extends TestCase
{
public function setUp(): void
{
parent::setUp();
Auth::fake();
}
public function test_get_courses_of_member(): void
{
Auth::success(12345, 'secret');
app(CourseFake::class)->forMember(11111, [
['bausteinId' => 506, 'id' => 788, 'veranstalter' => 'KJA', 'vstgName' => 'eventname', 'vstgTag' => '2021-11-12 00:00:00']
]);
$courses = Nami::login(12345, 'secret')->coursesFor(11111);
$this->assertEquals(788, $courses->first()->id);
$this->assertEquals('KJA', $courses->first()->organizer);
$this->assertEquals(506, $courses->first()->course_id);
$this->assertEquals('eventname', $courses->first()->event_name);
$this->assertEquals('2021-11-12 00:00:00', $courses->first()->completed_at);
Http::assertSent(function($request) {
return $request->url() == 'https://nami.dpsg.de/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/11111/flist';
});
Http::assertSent(function($request) {
return $request->url() == 'https://nami.dpsg.de/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/11111/788';
});
Http::assertSentCount(2);
}
public function test_needs_login(): void
{
$this->expectException(NotAuthenticatedException::class);
$courses = Nami::coursesFor(11111);
}
public function test_parses_failed_login(): void
{
Auth::failed(12345, 'secret');
$this->expectException(LoginException::class);
Nami::login(12345, 'secret')->coursesFor(11111);
}
}

View File

@ -119,6 +119,17 @@ class LoginTest extends TestCase
Auth::assertNotLoggedIn();
}
public function test_it_fakes_login_state(): void
{
Auth::fake();
Auth::success(12345, 'secret');
$this->assertFalse(Nami::isLoggedIn());
Nami::login(12345, 'secret');
$this->assertTrue(Nami::isLoggedIn());
}
private function fakeSuccessfulLogin(): array
{
return [