Add tests for storing a course

This commit is contained in:
philipp lang 2022-02-19 22:00:50 +01:00
parent 8515b1fc05
commit 96269d16c7
7 changed files with 131 additions and 52 deletions

View File

@ -13,7 +13,6 @@ use Illuminate\Support\LazyCollection;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Log; use Log;
use Zoomyboy\LaravelNami\Authentication\Authenticator; use Zoomyboy\LaravelNami\Authentication\Authenticator;
use Zoomyboy\LaravelNami\Backend\Backend;
use Zoomyboy\LaravelNami\Concerns\IsNamiMember; use Zoomyboy\LaravelNami\Concerns\IsNamiMember;
use Zoomyboy\LaravelNami\Exceptions\NotAuthenticatedException; use Zoomyboy\LaravelNami\Exceptions\NotAuthenticatedException;
use Zoomyboy\LaravelNami\Exceptions\RightException; use Zoomyboy\LaravelNami\Exceptions\RightException;
@ -169,11 +168,19 @@ class Api {
return collect($r->json()['data']); return collect($r->json()['data']);
} }
public function subactivitiesOf($activityId) { public function subactivitiesOf(int $activityId): Collection
{
$this->assertLoggedIn(); $this->assertLoggedIn();
return collect($this->http()->get($this->url.'/ica/rest/nami/untergliederungauftaetigkeit/filtered/untergliederung/taetigkeit/'.$activityId)->json()['data'])->map(function($subactivity) { $url = $this->url.'/ica/rest/nami/untergliederungauftaetigkeit/filtered/untergliederung/taetigkeit/'.$activityId;
$response = $this->http()->get($url);
if ($response['success'] === false) {
$this->exception('Getting subactivities failed', $url, $response->json());
}
return collect($response['data'])->map(function($subactivity) {
return Subactivity::fromNami($subactivity); return Subactivity::fromNami($subactivity);
});; });
} }
public function membership($memberId, $membershipId) { public function membership($memberId, $membershipId) {
@ -232,15 +239,17 @@ class Api {
public function createCourse(int $memberId, array $payload): int public function createCourse(int $memberId, array $payload): int
{ {
$this->assertLoggedIn(); $this->assertLoggedIn();
$response = $this->http()->post($this->url."/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/{$memberId}", [ $url = $this->url."/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/{$memberId}";
$payload = [
'bausteinId' => $payload['course_id'], 'bausteinId' => $payload['course_id'],
'vstgName' => $payload['event_name'], 'vstgName' => $payload['event_name'],
'vstgTag' => Carbon::parse($payload['completed_at'])->format('Y-m-d').'T00:00:00', 'vstgTag' => Carbon::parse($payload['completed_at'])->format('Y-m-d').'T00:00:00',
'veranstalter' => $payload['organizer'], 'veranstalter' => $payload['organizer'],
]); ];
$response = $this->http()->post($url, $payload);
if (data_get($response->json(), 'success') !== true) { if (data_get($response->json(), 'success') !== true) {
$this->exception('Course creation failed', $payload, $response->json()); $this->exception('Course creation failed', $url, $response->json(), $payload);
} }
return $response['data']; return $response['data'];
@ -255,25 +264,28 @@ class Api {
public function updateCourse(int $memberId, int $courseId, array $payload): void public function updateCourse(int $memberId, int $courseId, array $payload): void
{ {
$this->assertLoggedIn(); $this->assertLoggedIn();
$response = $this->http()->put($this->url."/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/{$memberId}/{$courseId}", [ $url = $this->url."/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/{$memberId}/{$courseId}";
$payload = [
'bausteinId' => $payload['course_id'], 'bausteinId' => $payload['course_id'],
'vstgName' => $payload['event_name'], 'vstgName' => $payload['event_name'],
'vstgTag' => Carbon::parse($payload['completed_at'])->format('Y-m-d').'T00:00:00', 'vstgTag' => Carbon::parse($payload['completed_at'])->format('Y-m-d').'T00:00:00',
'veranstalter' => $payload['organizer'], 'veranstalter' => $payload['organizer'],
]); ];
$response = $this->http()->put($url, $payload);
if (data_get($response->json(), 'success') !== true) { if (data_get($response->json(), 'success') !== true) {
$this->exception('Course update failed', $payload, $response->json()); $this->exception('Course update failed', $url, $response->json(), $payload);
} }
} }
public function deleteCourse(int $memberId, int $courseId): void public function deleteCourse(int $memberId, int $courseId): void
{ {
$this->assertLoggedIn(); $this->assertLoggedIn();
$response = $this->http()->delete($this->url."/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/{$memberId}/{$courseId}"); $url = $this->url."/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/{$memberId}/{$courseId}";
$response = $this->http()->delete($url);
if ($response->json() !== null && data_get($response->json(), 'success') !== true) { if ($response->json() !== null && data_get($response->json(), 'success') !== true) {
$this->exception('Course deletion failed', [], $response->json()); $this->exception('Course deletion failed', $url, $response->json());
} }
} }
@ -292,16 +304,11 @@ class Api {
return $this->singleMemberFallback($groupId, $memberId); return $this->singleMemberFallback($groupId, $memberId);
} }
if ($response->json()['success'] === true) { if ($response->json()['success'] !== true) {
return $response->json()['data']; $this->exception('Fetching member failed', $url, $response->json());
} else {
$e = new NamiException('Fetch von Mitglied fehlgeschlagen');
$e->setData([
'response' => $response->body(),
'url' => $url
]);
throw $e;
} }
return $response->json()['data'];
} }
public function hasGroup($groupId): bool { public function hasGroup($groupId): bool {
@ -342,18 +349,13 @@ class Api {
$url = $this->url."/ica/rest/baseadmin/staatsangehoerigkeit"; $url = $this->url."/ica/rest/baseadmin/staatsangehoerigkeit";
$response = $this->http()->get($url); $response = $this->http()->get($url);
if ($response->json()['success'] === true) { if ($response->json()['success'] !== true) {
return collect($response['data'])->map(function($nationality) { $this->exception("Fetch von Nationalität fehlgeschlagen", $url, $response->json());
return Nationality::fromNami($nationality);
});
} else {
$e = new NamiException('Fetch von Nationalität fehlgeschlagen');
$e->setData([
'response' => $response->body(),
'url' => $url
]);
throw $e;
} }
return collect($response['data'])->map(function($nationality) {
return Nationality::fromNami($nationality);
});
} }
public function countries() { public function countries() {
@ -425,8 +427,9 @@ class Api {
return $member->toArray(); return $member->toArray();
} }
private function exception($message, $request, $response) { private function exception(string $message, string $url, array $response, array $requestData = []): void
throw (new NamiException($message))->response($response)->request($request); {
throw (new NamiException($message))->response($response)->request($url, $requestData);
} }
private function assertLoggedIn(): void private function assertLoggedIn(): void

View File

@ -81,11 +81,14 @@ class CourseFake extends Fake {
}); });
} }
public function doesntCreateWithError(int $memberId): void /**
* @todo migrate this to parent errorResponse
*/
public function createFailed(int $memberId): void
{ {
Http::fake(function($request) use ($memberId) { Http::fake(function($request) use ($memberId) {
if ($request->url() === "https://nami.dpsg.de/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/{$memberId}") { if ($request->url() === "https://nami.dpsg.de/ica/rest/nami/mitglied-ausbildung/filtered-for-navigation/mitglied/mitglied/{$memberId}") {
return Http::response('{"success":false,"data":null,"responseType":"EXCEPTION","message":"Unexpected Error javax.ejb.EJBException","title":null}', 200); return $this->errorResponse("Unexpected Error javaEx");
} }
}); });
} }

View File

@ -2,6 +2,17 @@
namespace Zoomyboy\LaravelNami\Fakes; namespace Zoomyboy\LaravelNami\Fakes;
use GuzzleHttp\Promise\PromiseInterface;
use Illuminate\Support\Facades\Http;
abstract class Fake { abstract class Fake {
public function errorResponse(string $error): PromiseInterface
{
return Http::response(json_encode([
'success' => false,
'message' => $error,
]));
}
} }

View File

@ -0,0 +1,19 @@
<?php
namespace Zoomyboy\LaravelNami\Fakes;
use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\Http;
class SubactivityFake extends Fake {
public function fetchFailed(int $activityId, ?string $error = 'wrong message'): void
{
Http::fake(function($request) use ($activityId, $error) {
if ($request->url() === 'https://nami.dpsg.de/ica/rest/nami/untergliederungauftaetigkeit/filtered/untergliederung/taetigkeit/'.$activityId) {
return $this->errorResponse($error);
}
});
}
}

View File

@ -7,25 +7,32 @@ use Illuminate\Validation\ValidationException;
class NamiException extends \Exception { class NamiException extends \Exception {
private $data; private array $data;
public $response; private array $response;
public $request; private string $requestUrl;
public function setData($data) { public function setData(array $data): self
{
$this->data = $data; $this->data = $data;
}
public function getData() {
return $this->data;
}
public function request($request) {
$this->request = $request;
return $this; return $this;
} }
public function response($response) { public function getData(): array
{
return $this->data;
}
public function request(string $url, ?array $data = []): self
{
$this->requestUrl = $url;
$this->data = $data;
return $this;
}
public function response(array $response): self
{
$this->response = $response; $this->response = $response;
return $this; return $this;
@ -34,8 +41,9 @@ class NamiException extends \Exception {
public function report(): void public function report(): void
{ {
\Log::error($this->getMessage(), [ \Log::error($this->getMessage(), [
'request' => $this->request, 'requestUrl' => $this->requestUrl,
'response' => $this->response 'data' => $this->data,
'response' => json_encode($this->response),
]); ]);
throw ValidationException::withMessages(['id' => 'Unbekannter Fehler']); throw ValidationException::withMessages(['id' => 'Unbekannter Fehler']);

View File

@ -8,6 +8,7 @@ use Zoomyboy\LaravelNami\Exceptions\NotAuthenticatedException;
use Zoomyboy\LaravelNami\Fakes\CourseFake; use Zoomyboy\LaravelNami\Fakes\CourseFake;
use Zoomyboy\LaravelNami\LoginException; use Zoomyboy\LaravelNami\LoginException;
use Zoomyboy\LaravelNami\Nami; use Zoomyboy\LaravelNami\Nami;
use Zoomyboy\LaravelNami\NamiException;
use Zoomyboy\LaravelNami\Tests\TestCase; use Zoomyboy\LaravelNami\Tests\TestCase;
class CourseTest extends TestCase class CourseTest extends TestCase
@ -101,4 +102,19 @@ class CourseTest extends TestCase
Nami::login(12345, 'secret')->coursesFor(11111); Nami::login(12345, 'secret')->coursesFor(11111);
} }
public function test_throw_exception_when_storing_failed(): void
{
$this->expectException(NamiException::class);
Auth::success(12345, 'secret');
app(CourseFake::class)->createFailed(123);
Nami::login(12345, 'secret');
Nami::createCourse(123, [
'event_name' => '::event::',
'completed_at' => '2021-01-02 00:00:00',
'organizer' => '::org::',
'course_id' => 456
]);
}
} }

View File

@ -4,9 +4,11 @@ namespace Zoomyboy\LaravelNami\Tests\Unit;
use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
use Zoomyboy\LaravelNami\Fakes\SubactivityFake;
use Zoomyboy\LaravelNami\Group; use Zoomyboy\LaravelNami\Group;
use Zoomyboy\LaravelNami\LoginException; use Zoomyboy\LaravelNami\LoginException;
use Zoomyboy\LaravelNami\Nami; use Zoomyboy\LaravelNami\Nami;
use Zoomyboy\LaravelNami\NamiException;
use Zoomyboy\LaravelNami\NamiServiceProvider; use Zoomyboy\LaravelNami\NamiServiceProvider;
use Zoomyboy\LaravelNami\Tests\TestCase; use Zoomyboy\LaravelNami\Tests\TestCase;
@ -48,4 +50,21 @@ class PullActivitiesTest extends TestCase
Http::assertSentCount(3); Http::assertSentCount(3);
} }
public function test_throw_error_when_subactivities_request_fails(): void
{
$this->expectException(NamiException::class);
app(SubactivityFake::class)->fetchFailed(4, 'sorry dude');
Http::fake([
'https://nami.dpsg.de/ica/rest/nami/untergliederungauftaetigkeit/filtered/untergliederung/taetigkeit/4' => Http::response($this->fakeJson('subactivities-4.json'), 200)
]);
$subactivities = $this->login()->subactivitiesOf(4);
$this->assertSame([
[ 'name' => 'Biber', 'id' => 40 ],
[ 'name' => 'Wölfling', 'id' => 30 ]
], $subactivities->toArray());
Http::assertSentCount(3);
}
} }