From e79c1a41960b66420e5efc9a028cfa6645ddf296 Mon Sep 17 00:00:00 2001 From: Felix Ruf Date: Wed, 24 Jan 2024 16:00:49 +0100 Subject: [PATCH] added tests for printable list and the event participants list --- .gitignore | 1 + .../Tests/Controller/EventControllerTest.php | 34 +++++ src/Resources/src/views/PrintableList.vue | 5 +- .../tests/unit/fixtures/combiDishes.json | 26 ++++ .../tests/unit/stores/dishesStore.spec.ts | 16 +- .../tests/unit/stores/eventsStore.spec.ts | 19 ++- tests/e2e/cypress.config.ts | 1 + tests/e2e/cypress/e2e/Dashboard.cy.ts | 141 ++++++++++++++++++ tests/e2e/cypress/e2e/ParticipationList.cy.ts | 47 +++++- .../cypress/fixtures/printParticipations.json | 78 ++++++++++ 10 files changed, 364 insertions(+), 4 deletions(-) create mode 100644 src/Resources/tests/unit/fixtures/combiDishes.json create mode 100644 tests/e2e/cypress/fixtures/printParticipations.json diff --git a/.gitignore b/.gitignore index b3e188de6..0db0e4088 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,4 @@ tests/e2e/cypress/videos/ tests/e2e/cypress/screenshots/ test_ci_cypress.sh tests/e2e/cypress/e2e/FillDBWithStuff.cy.ts +tests/e2e/cypress/downloads/result.pdf diff --git a/src/Mealz/MealBundle/Tests/Controller/EventControllerTest.php b/src/Mealz/MealBundle/Tests/Controller/EventControllerTest.php index 1ed541dc6..ed4a7932e 100644 --- a/src/Mealz/MealBundle/Tests/Controller/EventControllerTest.php +++ b/src/Mealz/MealBundle/Tests/Controller/EventControllerTest.php @@ -194,4 +194,38 @@ public function testLeave(): void $part = $partRepo->findOneBy(['event' => $eventPart->getId()]); $this->assertNull($part); } + + public function testGetEventParticipants(): void + { + // Create an event and join it + $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); + + $eventParticipation = $this->createEventParticipation($day, $newEvent); + + $date = $day->getDateTime()->format('Y-m-d') . '%20' . $day->getDateTime()->format('H:i:s'); + + // Verify no participants in new event + $this->client->request('GET', '/api/participations/event/' . $date); + $participants = json_decode($this->client->getResponse()->getContent()); + $this->assertEquals(0, count($participants)); + + $this->client->request('POST', '/api/events/participation/' . $date); + $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); + + $this->client->request('GET', '/api/participations/event/' . $date); + $participants = json_decode($this->client->getResponse()->getContent()); + + $this->assertEquals(1, count($participants)); + $this->assertEquals('Meals, Kochomi', $participants[0]); + } } diff --git a/src/Resources/src/views/PrintableList.vue b/src/Resources/src/views/PrintableList.vue index d5aecf4e2..3bca8e5d2 100644 --- a/src/Resources/src/views/PrintableList.vue +++ b/src/Resources/src/views/PrintableList.vue @@ -51,7 +51,10 @@ {{ t('printList.title') + dateString }} -
+
diff --git a/src/Resources/tests/unit/fixtures/combiDishes.json b/src/Resources/tests/unit/fixtures/combiDishes.json new file mode 100644 index 000000000..e278499a7 --- /dev/null +++ b/src/Resources/tests/unit/fixtures/combiDishes.json @@ -0,0 +1,26 @@ +[ + { + "id": 5425, + "slug": "fish-so-juicy-sweat", + "titleDe": "Fish (so juicy sweat) DE", + "titleEn": "Fish (so juicy sweat)", + "descriptionDe": "Beschreibung - Fish (so juicy sweat) DE", + "descriptionEn": "Description - Fish (so juicy sweat)", + "categoryId": 1357, + "oneServingSize": false, + "parentId": null, + "variations": [] + }, + { + "id": 5430, + "slug": "innards-v2", + "titleDe": "Innards DE #v2", + "titleEn": "Innards #v2", + "descriptionDe": null, + "descriptionEn": null, + "categoryId": null, + "oneServingSize": false, + "parentId": 5424, + "variations": [] + } +] \ No newline at end of file diff --git a/src/Resources/tests/unit/stores/dishesStore.spec.ts b/src/Resources/tests/unit/stores/dishesStore.spec.ts index d8ce185c7..49592c9f3 100644 --- a/src/Resources/tests/unit/stores/dishesStore.spec.ts +++ b/src/Resources/tests/unit/stores/dishesStore.spec.ts @@ -6,6 +6,7 @@ import { beforeAll, beforeEach, describe, expect, it } from "@jest/globals"; import Dishes from "../fixtures/getDishes.json"; import Categories from "../fixtures/getCategories.json"; import { CreateDishDTO } from "@/api/postCreateDish"; +import combiDishes from '../fixtures/combiDishes.json'; const dish1: Dish = { id: 17, @@ -53,6 +54,12 @@ const getMockedResponses = (method: string, url: string) => { request: asyncFunc, error: ref(false) } + } else if (url.includes('api/participations/combi/') && /\S*api\/participations\/combi\/\d*$/.test(url) && method === 'GET') { + return { + response: ref(combiDishes), + request: asyncFunc, + error: ref(false) + } } } @@ -61,7 +68,7 @@ const getMockedResponses = (method: string, url: string) => { useApi = jest.fn().mockImplementation((method: string, url: string) => getMockedResponses(method, url)); describe('Test dishesStore', () => { - const { resetState, filterState, DishesState, fetchDishes, setFilter, filteredDishes, updateDish, getDishBySlug, getDishArrayBySlugs } = useDishes(); + const { resetState, filterState, DishesState, fetchDishes, setFilter, filteredDishes, updateDish, getDishBySlug, getDishArrayBySlugs, getCombiDishes } = useDishes(); const { fetchCategories } = useCategories(); beforeAll(async () => { @@ -153,4 +160,11 @@ describe('Test dishesStore', () => { expect(dishArrThree).toEqual(['testen']); }); + + it('should return an array of dishes containing the dishes from the fixtures', async () => { + const dishes = await getCombiDishes(1234); + + expect(dishes).toHaveLength(2); + expect(dishes).toEqual(combiDishes); + }) }); \ No newline at end of file diff --git a/src/Resources/tests/unit/stores/eventsStore.spec.ts b/src/Resources/tests/unit/stores/eventsStore.spec.ts index b20a2de09..06a789b21 100644 --- a/src/Resources/tests/unit/stores/eventsStore.spec.ts +++ b/src/Resources/tests/unit/stores/eventsStore.spec.ts @@ -11,6 +11,8 @@ const testEvent: Event = { public: false } +const userStrings = ['Test, User', 'Another, Testuser', 'abcxyz, User123']; + const asyncFunc: () => Promise = async () => { new Promise(resolve => resolve(undefined)); }; @@ -40,6 +42,12 @@ const getMockedResponses = (method: string, url: string) => { request: asyncFunc, error: ref(false) } + } else if (url.includes('api/participations/event/') && method === 'GET') { + return { + response: ref(userStrings), + request: asyncFunc, + error: ref(false) + } } } @@ -48,7 +56,7 @@ const getMockedResponses = (method: string, url: string) => { useApi = jest.fn().mockImplementation((method: string, url: string) => getMockedResponses(method, url)); describe('Test EventsStore', () => { - const { EventsState, fetchEvents, setFilter, filteredEvents, updateEvent, deleteEventWithSlug, getEventBySlug, resetState } = useEvents(); + const { EventsState, fetchEvents, setFilter, filteredEvents, updateEvent, deleteEventWithSlug, getEventBySlug, resetState, getParticipantsForEvent } = useEvents(); beforeEach(() => { resetState(); @@ -133,4 +141,13 @@ describe('Test EventsStore', () => { expect(event).toBeUndefined(); expect(EventsState.events).toHaveLength(1); }); + + it('should fetch all the users that participate in an event and return a list of their names', async () => { + const users = await getParticipantsForEvent('2024-01-24 12:00:00.000000'); + + expect(users).toHaveLength(3); + for (const user of userStrings) { + expect(users).toContain(user); + } + }); }); \ No newline at end of file diff --git a/tests/e2e/cypress.config.ts b/tests/e2e/cypress.config.ts index 41dbc182d..86a739970 100644 --- a/tests/e2e/cypress.config.ts +++ b/tests/e2e/cypress.config.ts @@ -29,4 +29,5 @@ export default defineConfig({ viewportHeight: 800, screenshotOnRunFailure: false, video: false, + trashAssetsBeforeRuns: true }) diff --git a/tests/e2e/cypress/e2e/Dashboard.cy.ts b/tests/e2e/cypress/e2e/Dashboard.cy.ts index 1e71e32fc..1d5a91e52 100644 --- a/tests/e2e/cypress/e2e/Dashboard.cy.ts +++ b/tests/e2e/cypress/e2e/Dashboard.cy.ts @@ -310,4 +310,145 @@ describe('Test Dashboard View', () => { .children() .should('have.length', 0); }); + + it('should join an event and be in the participants list', () => { + 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.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']); + + // join afterwork + cy.get('h2') + .contains('Nächste Woche') + .parent() + .parent() + .find('span') + .contains('Montag') + .parent() + .parent() + .find('span') + .contains('Afterwork') + .parent() + .find('div') + .eq(3) + .click(); + + // click on the info-icon + cy.get('h2') + .contains('Nächste Woche') + .parent() + .parent() + .contains('Montag') + .parent() + .parent() + .find('span') + .contains('Afterwork') + .parent() + .find('svg') + .eq(0) + .click(); + + cy.wait('@getParticipants'); + + // verify participants on popup + cy.get('span') + .contains('Teilnahmen "Afterwork"') + .parent() + .parent() + .find('li') + .contains('Meals, Kochomi') + .parent() + .parent() + .find('span') + .contains('Es gibt 1 Teilnehmer') + .parent() + .parent() + .find('svg') + .click() + + // leave afterwork + cy.get('h2') + .contains('Nächste Woche') + .parent() + .parent() + .find('span') + .contains('Montag') + .parent() + .parent() + .find('span') + .contains('Afterwork') + .parent() + .find('div') + .eq(3) + .click(); + + // click on the info-icon + cy.get('h2') + .contains('Nächste Woche') + .parent() + .parent() + .contains('Montag') + .parent() + .parent() + .find('span') + .contains('Afterwork') + .parent() + .find('svg') + .eq(0) + .click(); + + cy.wait('@getParticipants'); + + // verify no participants on popup + cy.get('span') + .contains('Teilnahmen "Afterwork"') + .parent() + .parent() + .find('span') + .contains('Noch keine Teilnehmer für dieses Event') + .parent() + .parent() + .find('span') + .contains('Es gibt 0 Teilnehmer') + .parent() + .parent() + .find('svg') + .click() + }); }); \ No newline at end of file diff --git a/tests/e2e/cypress/e2e/ParticipationList.cy.ts b/tests/e2e/cypress/e2e/ParticipationList.cy.ts index c09a5db46..266f49811 100644 --- a/tests/e2e/cypress/e2e/ParticipationList.cy.ts +++ b/tests/e2e/cypress/e2e/ParticipationList.cy.ts @@ -1,4 +1,6 @@ -describe('Test ParticipationsList view', () => { +import { find } from "cypress/types/lodash"; + +describe.skip('Test TV ParticipationsList view', () => { beforeEach(() => { cy.resetDB(); cy.setCookie('locale', 'de'); @@ -8,4 +10,47 @@ describe('Test ParticipationsList view', () => { cy.viewport(1080, 1920); cy.visit(Cypress.env('baseUrl') + 'show/participations'); }); +}); + +describe('Test Print ParticipationList View', () => { + beforeEach(() => { + cy.resetDB(); + cy.loginAs('kochomi'); + cy.visitMeals(); + + cy.intercept('GET', '**/api/print/participations', { fixture: 'printParticipations.json', statusCode: 200 }).as('getParticipations'); + }); + + it('should contain all the infos it received via the fixture', () => { + cy.contains('span', 'Heutige Teilnehmer').click(); + + cy.contains('h1', 'Teilnahmen am Mittwoch, 24.1.'); + + cy.get('[data-cy="printTable"]').find('tbody').find('tr').should('have.length', 10); + cy.contains('th', 'Active w/o limit'); + cy.contains('th', 'Active w/ limit'); + cy.get('[data-cy="printTable"]').find('tbody').find('tr').eq(1).contains('td', 'Meals, Admin'); + cy.get('[data-cy="printTable"]').find('tbody').find('tr').eq(2).contains('td', 'Meals, Alice'); + cy.get('[data-cy="printTable"]').find('tbody').find('tr').eq(3).contains('td', 'Meals, Bob'); + cy.get('[data-cy="printTable"]').find('tbody').find('tr').eq(4).contains('td', 'Meals, Finance'); + cy.get('[data-cy="printTable"]').find('tbody').find('tr').eq(5).contains('td', 'Meals, Jane'); + cy.get('[data-cy="printTable"]').find('tbody').find('tr').eq(6).contains('td', 'Meals, Kochomi'); + cy.get('[data-cy="printTable"]').find('tbody').find('tr').eq(8).contains('td', 'Meals, John'); + cy.get('[data-cy="printTable"]').find('tbody').find('tr').eq(9).find('th').eq(0).contains('Teilnahmen'); + cy.get('[data-cy="printTable"]').find('tbody').find('tr').eq(9).find('th').eq(1).contains('7'); + cy.get('[data-cy="printTable"]').find('tbody').find('tr').eq(9).find('th').eq(2).contains('4'); + cy.get('[data-cy="printTable"]').find('tbody').find('tr').eq(9).find('th').eq(3).contains('0'); + + cy.get('p').contains('Pdf downloaden'); + }); + + it('should verify that a file is downloaded when clicking pdf download', () => { + cy.contains('span', 'Heutige Teilnehmer').click(); + + cy.contains('h1', 'Teilnahmen am Mittwoch, 24.1.'); + + cy.get('p').contains('Pdf downloaden').click(); + + cy.readFile('cypress/downloads/result.pdf', { timeout: 5000 }); + }); }); \ No newline at end of file diff --git a/tests/e2e/cypress/fixtures/printParticipations.json b/tests/e2e/cypress/fixtures/printParticipations.json new file mode 100644 index 000000000..b96254bd3 --- /dev/null +++ b/tests/e2e/cypress/fixtures/printParticipations.json @@ -0,0 +1,78 @@ +{ + "data": { + "Active w\/o limit": { + "Meals, Admin": { + "booked": [ + 5474 + ] + }, + "Meals, Alice": { + "booked": [ + 5476 + ] + }, + "Meals, Bob": { + "booked": [ + 5474 + ] + }, + "Meals, Finance": { + "booked": [ + 5474 + ] + }, + "Meals, Jane": { + "booked": [ + 5476 + ] + }, + "Meals, Kochomi": { + "booked": [ + 5476 + ] + } + }, + "Active w\/ limit": { + "Meals, John": { + "booked": [ + 5474 + ] + } + } + }, + "meals": { + "5474": { + "title": { + "en": "Limbs", + "de": "Limbs DE" + }, + "parent": null, + "participations": 7 + }, + "5476": { + "title": { + "en": "Limbs oh la la la (oven backed) + Finger food with a slimy sweet and sour sauce", + "de": "Limbs oh la la la (Ofen gebacken) + Finger food mit einer schlammigen S\u00fc\u00df-Sauer-So\u00dfe" + }, + "parent": null, + "participations": 4 + }, + "5481": { + "title": { + "en": "Combined Dish", + "de": "Kombi-Gericht" + }, + "parent": null, + "participations": 0 + } + }, + "event": { + "name": "Afterwork", + "participants": [] + }, + "day": { + "date": "2024-01-24 12:00:00.000000", + "timezone_type": 3, + "timezone": "Europe\/Berlin" + } +} \ No newline at end of file