Skip to content

Commit

Permalink
added tests for new event invitation functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Felix Ruf committed Feb 1, 2024
1 parent f634c59 commit b015daa
Show file tree
Hide file tree
Showing 7 changed files with 290 additions and 7 deletions.
1 change: 0 additions & 1 deletion src/Mealz/MealBundle/Controller/MealGuestController.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ public function getEventInvitationData(
return new JsonResponse($guestData, 200);
}

// TODO: check for existing guest
public function joinEventAsGuest(
string $invitationId,
Request $request,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use App\Mealz\MealBundle\Entity\EventParticipation;
use App\Mealz\MealBundle\Entity\Meal;
use App\Mealz\MealBundle\Entity\Participant;
use App\Mealz\MealBundle\Repository\DayRepository;
use App\Mealz\MealBundle\Repository\MealRepositoryInterface;
use App\Mealz\MealBundle\Tests\AbstractDatabaseTestCase;
use App\Mealz\UserBundle\Entity\Profile;
Expand Down Expand Up @@ -167,6 +168,23 @@ protected function createEventParticipation(Day $day, Event $event): EventPartic
return $eventParticipation;
}

protected function createFutureEvent(): EventParticipation
{
$newEvent = $this->createEvent();
$this->persistAndFlushAll([$newEvent]);

$dayRepo = self::$container->get(DayRepository::class);

$criteria = new \Doctrine\Common\Collections\Criteria();
$criteria->where(\Doctrine\Common\Collections\Criteria::expr()->gt('lockParticipationDateTime', new DateTime()));

/** @var Day $day */
$day = $dayRepo->matching($criteria)->get(0);
$this->assertNotNull($day);

return $this->createEventParticipation($day, $newEvent);
}

/**
* Helper method to get the recent meal.
*/
Expand Down
140 changes: 140 additions & 0 deletions src/Mealz/MealBundle/Tests/Controller/MealGuestControllerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?php

declare(strict_types=1);

namespace App\Mealz\MealBundle\Tests\Controller;

use App\Mealz\MealBundle\DataFixtures\ORM\LoadCategories;
use App\Mealz\MealBundle\DataFixtures\ORM\LoadDays;
use App\Mealz\MealBundle\DataFixtures\ORM\LoadDishes;
use App\Mealz\MealBundle\DataFixtures\ORM\LoadDishVariations;
use App\Mealz\MealBundle\DataFixtures\ORM\LoadEvents;
use App\Mealz\MealBundle\DataFixtures\ORM\LoadMeals;
use App\Mealz\MealBundle\DataFixtures\ORM\LoadWeeks;
use App\Mealz\MealBundle\Repository\GuestInvitationRepository;
use App\Mealz\UserBundle\DataFixtures\ORM\LoadRoles;
use App\Mealz\UserBundle\DataFixtures\ORM\LoadUsers;

class MealGuestControllerTest extends AbstractControllerTestCase
{
protected function setUp(): void
{
parent::setUp();

$this->clearAllTables();
$this->loadFixtures([
new LoadWeeks(),
new LoadDays(),
new LoadCategories(),
new LoadDishes(),
new LoadDishVariations(),
new LoadEvents(),
new LoadMeals(),
new LoadRoles(),
new LoadUsers(self::$container->get('security.user_password_encoder.generic')),
]);

$this->loginAs(self::USER_KITCHEN_STAFF);
}

public function testnewGuestEventInvitation(): void
{
$guestInvitationRepo = self::$container->get(GuestInvitationRepository::class);
$eventParticipation = $this->createFutureEvent();
$url = '/event/invitation/' . $eventParticipation->getDay()->getId();

$this->client->request('GET', $url);
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());

$guestLink = json_decode($this->client->getResponse()->getContent())->url;
$prefix = 'http://localhost/guest/event/';
$invitationId = str_ireplace($prefix, '', $guestLink);

$invitation = $guestInvitationRepo->find($invitationId);
$this->assertNotNull($invitation);
$this->assertEquals(
$eventParticipation->getEvent()->getTitle(),
$invitation->getDay()->getEvent()->getEvent()->getTitle()
);
}

public function testGetEventInvitationData(): void
{
$guestInvitationRepo = self::$container->get(GuestInvitationRepository::class);
$eventParticipation = $this->createFutureEvent();
$profile = $this->createProfile('Max', 'Mustermann' . time());
$this->persistAndFlushAll([$profile]);
$eventInvitation = $guestInvitationRepo->findOrCreateInvitation($profile, $eventParticipation->getDay());

$this->client->request('GET', '/api/event/invitation/' . $eventInvitation->getId());
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());

$content = json_decode($this->client->getResponse()->getContent());
$this->assertEquals(
json_encode($eventParticipation->getDay()->getDateTime()),
json_encode($content->date)
);
$this->assertEquals(
json_encode($eventParticipation->getDay()->getLockParticipationDateTime()),
json_encode($content->lockDate)
);
$this->assertEquals(
$eventParticipation->getDay()->getEvent()->getEvent()->getTitle(),
$content->event
);
}

public function testJoinEventAsGuest(): void
{
$guestInvitationRepo = self::$container->get(GuestInvitationRepository::class);
$eventParticipation = $this->createFutureEvent();
$profile = $this->createProfile('Max', 'Mustermann' . time());
$this->persistAndFlushAll([$profile]);
$eventInvitation = $guestInvitationRepo->findOrCreateInvitation($profile, $eventParticipation->getDay());

// with company
$this->client->request(
'POST',
'/api/event/invitation/' . $eventInvitation->getId(),
[],
[],
[],
json_encode([
'firstName' => 'John',
'lastName' => 'Doe',
'company' => 'District 9',
])
);
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());

// without company
$this->client->request(
'POST',
'/api/event/invitation/' . $eventInvitation->getId(),
[],
[],
[],
json_encode([
'firstName' => 'Jane',
'lastName' => 'Doe',
'company' => null,
])
);
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());

// without firstName
$this->client->request(
'POST',
'/api/event/invitation/' . $eventInvitation->getId(),
[],
[],
[],
json_encode([
'firstName' => null,
'lastName' => 'Doe',
'company' => 'District 9',
])
);
$this->assertEquals(404, $this->client->getResponse()->getStatusCode());
}
}
7 changes: 4 additions & 3 deletions src/Resources/src/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@
"701": "Es wurden noch nicht alle Details zu dem Event eingefügt",
"801": "Keine Berechtigung zum beitreten oder verlassen",
"802": "Dem Event konnte nicht beigetreten werden",
"803": "Das Event konnte nicht verlassen werden"
"803": "Das Event konnte nicht verlassen werden",
"903": "Sie haben sich schon angemeldet. Bei Fragen wenden Sie sich bitte an Ihren Ansprechpartner."
},
"success": {
"menu": {
Expand Down Expand Up @@ -205,7 +206,7 @@
"updated": "Der Zeitslot wurde erfolgreich bearbeitet."
},
"guest": {
"joined": "Sie nehmen an der Veranstaltung teil. Wir freuen uns Sie dabei zu haben."
"joined": "Wir freuen uns Sie dabei zu haben."
}
}
},
Expand Down Expand Up @@ -237,7 +238,7 @@
"submit": "An Event teilnehmen",
"joined": "Sie nehmen am %eventDate% an \"%EventTitle%\" teil. Wir freuen uns Sie dabei zu haben.",
"title": "Veranstaltung bei AOE",
"description": "Hiermit laden wir Sie zu der Veranstaltung \"%EventTitle%\" bei uns ein. Damit wir rechtzeitig mit Ihnen planen können tragen Sie sich bitte bis spätestens %lockDate% Uhr für das Event ein.\n\nWir freuen uns auf Sie!"
"description": "Hiermit laden wir Sie zu der Veranstaltung \"%EventTitle%\" ein. Damit wir mit Ihnen planen können tragen Sie sich bitte bis spätestens %lockDate% Uhr für das Event ein.\n\nWir freuen uns auf Sie!"
}
},
"header": {
Expand Down
5 changes: 3 additions & 2 deletions src/Resources/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@
"701": "Event creation parameters are missing",
"801": "No permission to enter or leave the event",
"802": "Couldn't join the event",
"803": "Couldn't leave the event"
"803": "Couldn't leave the event",
"903": "You are already registered. If you have any questions please message your contact person."
},
"success": {
"menu": {
Expand Down Expand Up @@ -205,7 +206,7 @@
"updated": "The timeslot was successfully updated."
},
"guest": {
"joined": "You are participating in the Event. We are looking forward to meeting you."
"joined": "We are looking forward to meeting you."
}
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/Resources/src/views/GuestEvent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ async function handleSubmit() {
console.log('Trying to join');
const { error, response } = await postJoinEventGuest(props.hash, formData.value);
if (error.value === true && isMessage(response.value)) {
if (error.value === true && isMessage(response.value) && response.value.message.includes('already joined')) {
sendFlashMessage({
type: FlashMessageType.ERROR,
message: response.value.message
Expand Down
124 changes: 124 additions & 0 deletions tests/e2e/cypress/e2e/GuestEventInvitation.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
describe('Test GuestEventInvitation', () => {
beforeEach(() => {
cy.resetDB();
cy.loginAs('kochomi');
});

it('should copy a invitation link to the clipboard then visit the link and register for an event', () => {
cy.intercept('GET', '**/api/weeks').as('getWeeks');
cy.intercept('GET', '**/api/meals/count').as('getDishesCount');
cy.intercept('GET', '**/api/categories').as('getCategories');
cy.intercept('GET', '**/api/dishes').as('getDishes');
cy.intercept('GET', '**/api/events').as('getEvents');
cy.intercept('GET', '**/api/dashboard').as('getDashboard');
cy.intercept('GET', '**/api/participations/event/**').as('getParticipants');
cy.intercept('GET', '**/event/invitation/**').as('getEventInvitation');
cy.intercept('POST', '**/api/event/invitation/**').as('postEventInvitation');

cy.visitMeals();
cy.get('span > a').contains('Mahlzeiten').click();
cy.wait(['@getWeeks']);

// Go to the next week
cy.get('h4').eq(1).contains('Woche').click();
cy.wait(['@getDishesCount', '@getCategories', '@getDishes']);

// add an event on monday
cy.get('input')
.eq(2)
.click()
.parent().parent()
.find('li').contains('Afterwork')
.click();

cy.get('h2').should('contain', 'Woche').click();

// Save
cy.contains('input', 'Speichern').click();

cy.get('[data-cy="msgClose"]').click();

// find the saved event
cy.get('input')
.eq(2)
.should('have.value', 'Afterwork');

// go to dashboard
cy.get('header > nav > div > a > svg').click();
cy.wait(['@getDashboard', '@getEvents']);

// confirm event is not joined yet
cy.get('h2')
.contains('Nächste Woche')
.parent()
.parent()
.find('span')
.contains('Montag')
.parent()
.parent()
.find('span')
.contains('Afterwork')
.parent()
.find('svg')
.eq(0)
.click();

cy.wait('@getEventInvitation');

cy.contains('span', 'In die Zwischenablage kopiert!')
.parent()
.parent()
.children()
.eq(0)
.then($el => {
cy.log('Link: ' + $el[0].innerText);
const link = $el[0].innerText;
expect(link).to.match(/^(http|https):\/\/(meals.test|localhost)\/guest\/event\/\S*$/);

cy.clearAllSessionStorage();
cy.visit(link);

cy.get('input[placeholder="Vorname"]')
.click()
.type('John');

cy.get('input[placeholder="Nachname"]')
.click()
.type('Doe');

cy.get('input[placeholder="Betrieb"]')
.click()
.type('District 17')

cy.contains('input', 'An Event teilnehmen').click();

cy.wait('@postEventInvitation');
cy.get('[data-cy=msgClose]').click();

cy.visitMeals();
cy.loginAs('kochomi');

cy.get('h2')
.contains('Nächste Woche')
.parent()
.parent()
.find('span')
.contains('Montag')
.parent()
.parent()
.find('span')
.contains('Afterwork')
.parent()
.find('svg')
.eq(1)
.click();

cy.get('span')
.contains('Teilnahmen "Afterwork"')
.parent()
.parent()
.find('ul')
.contains('Doe, John (District 17)');
});
});
});

0 comments on commit b015daa

Please sign in to comment.