Add check for authentication
This commit is contained in:
parent
15a6bcc70e
commit
798f7222e9
14
src/Api.php
14
src/Api.php
|
@ -15,6 +15,7 @@ use Log;
|
||||||
use Zoomyboy\LaravelNami\Authentication\Authenticator;
|
use Zoomyboy\LaravelNami\Authentication\Authenticator;
|
||||||
use Zoomyboy\LaravelNami\Backend\Backend;
|
use Zoomyboy\LaravelNami\Backend\Backend;
|
||||||
use Zoomyboy\LaravelNami\Concerns\IsNamiMember;
|
use Zoomyboy\LaravelNami\Concerns\IsNamiMember;
|
||||||
|
use Zoomyboy\LaravelNami\Exceptions\NotAuthenticatedException;
|
||||||
use Zoomyboy\LaravelNami\Exceptions\RightException;
|
use Zoomyboy\LaravelNami\Exceptions\RightException;
|
||||||
use Zoomyboy\LaravelNami\NamiException;
|
use Zoomyboy\LaravelNami\NamiException;
|
||||||
|
|
||||||
|
@ -92,6 +93,11 @@ class Api {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isLoggedIn(): bool
|
||||||
|
{
|
||||||
|
return $this->authenticator->isLoggedIn();
|
||||||
|
}
|
||||||
|
|
||||||
public function membersOf($groupId): Collection {
|
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']);
|
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
|
public function coursesFor(int $memberId): Collection
|
||||||
{
|
{
|
||||||
|
$this->assertLoggedIn();
|
||||||
$url = $this->url."/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/{$memberId}/flist";
|
$url = $this->url."/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/{$memberId}/flist";
|
||||||
$response = $this->http()->get($url);
|
$response = $this->http()->get($url);
|
||||||
|
|
||||||
|
@ -382,5 +389,12 @@ class Api {
|
||||||
throw (new NamiException($message))->response($response)->request($request);
|
throw (new NamiException($message))->response($response)->request($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function assertLoggedIn(): void
|
||||||
|
{
|
||||||
|
if (!$this->isLoggedIn()) {
|
||||||
|
throw new NotAuthenticatedException('You need to login first');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,5 +8,6 @@ abstract class Authenticator {
|
||||||
|
|
||||||
abstract public function login(int $mglnr, string $password): self;
|
abstract public function login(int $mglnr, string $password): self;
|
||||||
abstract public function http(): PendingRequest;
|
abstract public function http(): PendingRequest;
|
||||||
|
abstract public function isLoggedIn(): bool;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,11 @@ class FakeCookie extends Authenticator {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isLoggedIn(): bool
|
||||||
|
{
|
||||||
|
return $this->authenticated !== null;
|
||||||
|
}
|
||||||
|
|
||||||
public function http(): PendingRequest
|
public function http(): PendingRequest
|
||||||
{
|
{
|
||||||
return Http::withOptions([]);
|
return Http::withOptions([]);
|
||||||
|
@ -82,15 +87,15 @@ class FakeCookie extends Authenticator {
|
||||||
|
|
||||||
public function assertNotLoggedIn(): void
|
public function assertNotLoggedIn(): void
|
||||||
{
|
{
|
||||||
Assert::assertNull(
|
Assert::assertFalse(
|
||||||
$this->authenticated,
|
$this->isLoggedIn(),
|
||||||
'Failed asserting that noone is logged in. Found login with '.data_get($this->authenticated, 'mglnr')
|
'Failed asserting that noone is logged in. Found login with '.data_get($this->authenticated, 'mglnr')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function assertLoggedIn(): void
|
public function assertLoggedIn(): void
|
||||||
{
|
{
|
||||||
|
Assert::assertTrue($this->isLoggedIn());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,12 +43,7 @@ class MainCookie extends Authenticator {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function http(): PendingRequest
|
public function isLoggedIn(): bool
|
||||||
{
|
|
||||||
return Http::withOptions(['cookies' => $this->load()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function isLoggedIn(): bool
|
|
||||||
{
|
{
|
||||||
if ($this->file() === null) {
|
if ($this->file() === null) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -57,6 +52,11 @@ class MainCookie extends Authenticator {
|
||||||
return ! $this->isExpired();
|
return ! $this->isExpired();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function http(): PendingRequest
|
||||||
|
{
|
||||||
|
return Http::withOptions(['cookies' => $this->load()]);
|
||||||
|
}
|
||||||
|
|
||||||
private function newFileName(): string
|
private function newFileName(): string
|
||||||
{
|
{
|
||||||
return $this->path.'/'.time().'.txt';
|
return $this->path.'/'.time().'.txt';
|
||||||
|
|
|
@ -8,19 +8,13 @@ use Illuminate\Http\Client\Response;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use Zoomyboy\LaravelNami\Fakes\CourseFake;
|
||||||
use Zoomyboy\LaravelNami\Fakes\Fake;
|
use Zoomyboy\LaravelNami\Fakes\Fake;
|
||||||
use Zoomyboy\LaravelNami\Fakes\FakeInstance;
|
use Zoomyboy\LaravelNami\Fakes\FakeInstance;
|
||||||
use Zoomyboy\LaravelNami\Fakes\LoginFake;
|
use Zoomyboy\LaravelNami\Fakes\LoginFake;
|
||||||
|
|
||||||
class FakeBackend {
|
class FakeBackend {
|
||||||
|
|
||||||
public function fakeLogin(string $mglnr): self
|
|
||||||
{
|
|
||||||
app(LoginFake::class)->succeeds($mglnr);
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $mitgliedsNr
|
* @param int $mitgliedsNr
|
||||||
* @param array <string, mixed> $data
|
* @param array <string, mixed> $data
|
||||||
|
@ -116,27 +110,12 @@ class FakeBackend {
|
||||||
]) ?: '{}', 200);
|
]) ?: '{}', 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
foreach ($data as $member) {
|
foreach ($data as $member) {
|
||||||
if ($request->url() === "https://nami.dpsg.de/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/{$member['id']}/flist") {
|
app(CourseFake::class)->forMember($member['id'], $member['courses'] ?? []);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zoomyboy\LaravelNami\Exceptions;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class NotAuthenticatedException extends Exception {
|
||||||
|
|
||||||
|
}
|
|
@ -7,6 +7,28 @@ use Illuminate\Support\Facades\Http;
|
||||||
|
|
||||||
class CourseFake extends Fake {
|
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
|
public function createsSuccessful(int $memberId, int $courseId): void
|
||||||
{
|
{
|
||||||
Http::fake(function($request) use ($memberId, $courseId) {
|
Http::fake(function($request) use ($memberId, $courseId) {
|
||||||
|
|
|
@ -6,15 +6,11 @@ use Illuminate\Support\Facades\Facade;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @method static \Zoomyboy\LaravelNami\Api login(int $mglnr, string $password)
|
* @method static \Zoomyboy\LaravelNami\Api login(int $mglnr, string $password)
|
||||||
|
* @method static bool isLoggedIn()
|
||||||
* @method static \Zoomyboy\LaravelNami\Api fake()
|
* @method static \Zoomyboy\LaravelNami\Api fake()
|
||||||
*/
|
*/
|
||||||
class Nami extends Facade {
|
class Nami extends Facade {
|
||||||
|
|
||||||
protected static function getFacadeAccessor() { return 'nami.api'; }
|
protected static function getFacadeAccessor() { return 'nami.api'; }
|
||||||
|
|
||||||
protected static function fake(): void
|
|
||||||
{
|
|
||||||
static::swap(ApiFake::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -119,6 +119,17 @@ class LoginTest extends TestCase
|
||||||
Auth::assertNotLoggedIn();
|
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
|
private function fakeSuccessfulLogin(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|
Loading…
Reference in New Issue