Skip to content

Commit

Permalink
added backend tests for MealAdminController and a few frontend tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Felix Ruf committed Jul 6, 2023
1 parent 0b32b0f commit 713fdbf
Show file tree
Hide file tree
Showing 11 changed files with 1,125 additions and 3 deletions.
181 changes: 181 additions & 0 deletions src/Mealz/MealBundle/Tests/Controller/MealAdminControllerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
<?php

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\LoadMeals;
use App\Mealz\MealBundle\DataFixtures\ORM\LoadWeeks;
use App\Mealz\MealBundle\Entity\Dish;
use App\Mealz\MealBundle\Entity\Week;
use App\Mealz\UserBundle\DataFixtures\ORM\LoadRoles;
use App\Mealz\UserBundle\DataFixtures\ORM\LoadUsers;
use DateTime;

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

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

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

public function testGetWeeks(): void
{
$meal = $this->getRecentMeal();

// Request
$this->client->request('GET', '/api/weeks');
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());

// Get data for assertions from response
$responseData = json_decode($this->client->getResponse()->getContent(), true);
$this->assertNotNull($responseData);

// Assert that the response contains the expected data
$found = false;
foreach ($responseData as $week) {
foreach ($week['days'] as $dayId => $day) {
if ($dayId === $meal->getDay()->getId()) {
foreach ($day['meals'] as $parent) {
foreach ($parent as $child) {
if ($child['id'] === $meal->getId()) {
$found = true;
break;
}
}
}
}
}
}

$this->assertTrue($found, 'Expected meal not found in response');
}

public function testNew(): void
{
$date = new DateTime('+2 month');
$year = (int) $date->format('Y');
$week = (int) $date->format('W');
$routeStr = '/api/weeks/' . $year . 'W' . $week;

// Request
$this->client->request('POST', $routeStr);
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());

// Get data for assertions with new request response
$weekRepository = $this->getDoctrine()->getRepository(Week::class);
$createdWeek = $weekRepository->findOneBy([
'year' => $date->format('o'),
'calendarWeek' => $date->format('W'),
]);

$this->assertNotNull($createdWeek, 'Expected week not found in database');
$this->assertEquals($createdWeek->getYear(), $year);
$this->assertEquals($createdWeek->getCalendarWeek(), $week);

// Trying to create the same week twice should fail
$this->client->request('POST', $routeStr);
$this->assertEquals(400, $this->client->getResponse()->getStatusCode());
$response = json_decode($this->client->getResponse()->getContent(), true);
$this->assertEquals('week already exists', $response['status']);
}

public function testCount(): void
{
$this->client->request('GET', '/api/meals/count');
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());

$response = json_decode($this->client->getResponse()->getContent(), true);
$this->assertNotNull($response);

foreach ($response as $id => $count) {
$this->assertIsInt($id);
$this->assertIsInt($count);
}
}

public function testEdit(): void
{
// Create new week
$date = new DateTime('+2 month');
$year = (int) $date->format('Y');
$week = (int) $date->format('W');
$routeStr = '/api/weeks/' . $year . 'W' . $week;

// Request
$this->client->request('POST', $routeStr);
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());

// Get data for assertions with new request response
$weekRepository = $this->getDoctrine()->getRepository(Week::class);
$createdWeek = $weekRepository->findOneBy([
'year' => $date->format('o'),
'calendarWeek' => $date->format('W'),
]);

$foundDay = $createdWeek->getDays()[0];
$foundMeal = $foundDay->getMeals()[0];
$dishRepository = $this->getDoctrine()->getRepository(Dish::class);
$testDish = $dishRepository->findOneBy(['parent' => null]);

$this->assertNull($foundMeal);
$this->assertNotNull($testDish);

$testPutStr = '{
"id": ' . $createdWeek->getId() . ',
"days": [
{
"meals": {
"0": [
{
"dishSlug": "' . $testDish->getSlug() . '",
"mealId": null,
"participationLimit": 0
}
],
"-1": []
},
"id": ' . $createdWeek->getDays()[0]->getId() . ',
"enabled": true,
"date": {
"date": "' . $date->format('Y-m-d') . ' 12:00:00.000000",
"timezone_type": 3,
"timezone": "Europe\/Berlin"
},
"lockDate": null
}
],
"notify": false,
"enabled": true
}';

$this->client->request('PUT', '/api/menu/' . $createdWeek->getId(), [], [], [], $testPutStr);
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());

$createdWeek = $weekRepository->findOneBy([
'year' => $date->format('o'),
'calendarWeek' => $date->format('W'),
]);

$foundDay = $createdWeek->getDays()[0];
$foundMeal = $foundDay->getMeals()[0];

$this->assertEquals($testDish->getId(), $foundMeal->getDish()->getId());
}
}
2 changes: 1 addition & 1 deletion src/Resources/src/components/menu/MenuDay.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ import { useDishes } from '@/stores/dishesStore';
import { translateWeekdayWithoutRef } from '@/tools/localeHelper';
import { useI18n } from 'vue-i18n';
import Switch from "@/components/misc/Switch.vue"
import { UserIcon, CalendarIcon } from '@heroicons/vue/solid';
import { UserIcon } from '@heroicons/vue/solid';
import Popover from '../misc/Popover.vue';
import MenuParticipationPanel from './MenuParticipationPanel.vue';
import MenuLockDatePicker from './MenuLockDatePicker.vue';
Expand Down
14 changes: 13 additions & 1 deletion src/Resources/src/stores/weeksStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,17 @@ export function useWeeks() {
return week.days[dayId];
}

/**
* Resets the DishesState.
* Only used for testing purposes.
*/
function resetStates() {
WeeksState.weeks = [];
WeeksState.error = '';
WeeksState.isLoading = false;
MenuCountState.counts = {};
}

return {
WeeksState: readonly(WeeksState),
MenuCountState: readonly(MenuCountState),
Expand All @@ -173,6 +184,7 @@ export function useWeeks() {
createMealDTO,
getWeekById,
updateWeek,
getDishCountForWeek
getDishCountForWeek,
resetStates
}
}
2 changes: 1 addition & 1 deletion src/Resources/src/views/Dishes.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import DishTableRow from '@/components/dishes/DishTableRow.vue';
import { Dish } from '@/stores/dishesStore';
const { t } = useI18n();
const { fetchDishes, DishesState, filteredDishes } = useDishes();
const { fetchDishes, filteredDishes } = useDishes();
const { fetchCategories } = useCategories();
onMounted(async () => {
Expand Down
29 changes: 29 additions & 0 deletions src/Resources/tests/unit/api/getDishCount.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import getDishCount from "@/api/getDishCount";
import { ref } from "vue";
import DishesCount from "../fixtures/dishesCount.json";
import useApi from "@/api/api";


const asyncFunc: () => Promise<void> = async () => {
new Promise(resolve => resolve(undefined));
};

const mockedReturnValue = {
response: ref(DishesCount),
request: asyncFunc,
error: ref(false)
}

// @ts-expect-error ts doesn't like mocking with jest.fn()
useApi = jest.fn(useApi);
// @ts-expect-error continuation of expect error from line above
useApi.mockReturnValue(mockedReturnValue);

describe('Test getDishCount', () => {
it('should return a map of ids from dishes with their respective counts', async () => {
const { response, error } = await getDishCount();

expect(error.value).toBeFalsy();
expect(response.value).toEqual(DishesCount);
});
});
29 changes: 29 additions & 0 deletions src/Resources/tests/unit/api/getWeeks.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import getWeeks from "@/api/getWeeks";
import { ref } from "vue";
import Weeks from "../fixtures/getWeeks.json";
import useApi from "@/api/api";


const asyncFunc: () => Promise<void> = async () => {
new Promise(resolve => resolve(undefined));
};

const mockedReturnValue = {
response: ref(Weeks),
request: asyncFunc,
error: ref(false)
}

// @ts-expect-error ts doesn't like mocking with jest.fn()
useApi = jest.fn(useApi);
// @ts-expect-error continuation of expect error from line above
useApi.mockReturnValue(mockedReturnValue);

describe('Test getWeeks', () => {
it('should return a list of Weeks', async () => {
const { weeks, error } = await getWeeks();

expect(error.value).toBeFalsy();
expect(weeks.value).toEqual(Weeks);
});
});
28 changes: 28 additions & 0 deletions src/Resources/tests/unit/api/postCreateWeek.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import postCreateWeek from "@/api/postCreateWeek";
import { ref } from "vue";
import Success from "../fixtures/Success.json";
import useApi from "@/api/api";

const asyncFunc: () => Promise<void> = async () => {
new Promise(resolve => resolve(undefined));
};

const mockedReturnValue = {
response: ref(Success),
request: asyncFunc,
error: ref(false)
}

// @ts-expect-error ts doesn't like mocking with jest.fn()
useApi = jest.fn(useApi);
// @ts-expect-error continuation of expect error from line above
useApi.mockReturnValue(mockedReturnValue);

describe('Test postCreateWeek', () => {
it('should create a new week', async () => {
const { error, response } = await postCreateWeek(2023, 20);

expect(error.value).toBeFalsy();
expect(response.value).toEqual(Success);
});
});
58 changes: 58 additions & 0 deletions src/Resources/tests/unit/api/putWeekUpdate.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import putWeekUpdate from "@/api/putWeekUpdate";
import { ref } from "vue";
import useApi from "@/api/api";
import { WeekDTO, DayDTO, MealDTO } from "@/interfaces/DayDTO";
import Success from "../fixtures/Success.json";

const testMeal: MealDTO = {
dishSlug: "test",
mealId: 0,
participationLimit: 0
}

const testDay: DayDTO = {
meals: { 0: [testMeal] },
enabled: false,
id: 0,
date: {
date: "",
timezone_type: 0,
timezone: ""
},
lockDate: {
date: "",
timezone_type: 0,
timezone: ""
}
}

const testWeek: WeekDTO = {
id: 0,
notify: false,
enabled: false,
days: [testDay]
}

const asyncFunc: () => Promise<void> = async () => {
new Promise(resolve => resolve(undefined));
};

const mockedReturnValue = {
response: ref(Success),
request: asyncFunc,
error: ref(false)
}

// @ts-expect-error ts doesn't like mocking with jest.fn()
useApi = jest.fn(useApi);
// @ts-expect-error continuation of expect error from line above
useApi.mockReturnValue(mockedReturnValue);

describe('Test putWeekUpdate', () => {
it('should return a success message', async () => {
const { error, response } = await putWeekUpdate(testWeek);

expect(error.value).toBeFalsy();
expect(response.value).toEqual(Success);
});
});
13 changes: 13 additions & 0 deletions src/Resources/tests/unit/fixtures/dishesCount.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"13": 11,
"14": 3,
"16": 8,
"17": 7,
"19": 4,
"20": 4,
"21": 3,
"22": 4,
"23": 2,
"24": 8,
"31": 1
}
Loading

0 comments on commit 713fdbf

Please sign in to comment.