Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/ilkka starting time freely & duration time can be set freely too #175

Merged
merged 23 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
fa3828c
added logic to show starting times in the time picker, and combined i…
Jun 26, 2024
9da87b8
fix show durations in bookingdrawer
Jun 26, 2024
4b57462
format
Jun 26, 2024
678ff56
tests fixed
Jun 26, 2024
fdbb679
format again
Jun 26, 2024
382c099
format again & some css fixing in order to get the buttons use at lea…
Jun 26, 2024
cabd8e7
added multisectiondigitalclock for starting time selection (custom), …
Jun 28, 2024
a49cb74
puzzling with set constant duration buttons (quick duration selection)
Jul 2, 2024
63dafe0
custom starting time & duration buttons, 1st draft for presentation
Jul 2, 2024
899138f
added custom duration possibility, adds extra button if custom durati…
Jul 5, 2024
3e04d6a
added custom button and custom value button for starting time working…
Jul 5, 2024
8c7e471
fixed starting time and duration to not use redux anymore, and bug fi…
Jul 6, 2024
6969371
merge from summer 2024 branch
Jul 8, 2024
4411325
fixed problems found after merge
Jul 8, 2024
3340d93
fixed problems found after merge, v2
Jul 8, 2024
f333728
ready for pr
Jul 8, 2024
33c76fe
trying to fix styled engine build error
Jul 8, 2024
aa56e21
first jest test refactored to vitest
Jul 9, 2024
48db87f
rest of the jest tests converted to vitest
Jul 9, 2024
3de8eb8
based on review: remove unnecessary onchange and move logic to child …
Jul 9, 2024
b3e9d81
rest of code review changes, refactoring etc.
Jul 9, 2024
dac1cdb
one test was not refactored to vitest, now trying again
Jul 9, 2024
0d81741
fix
Jul 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "",
"main": "src/app.ts",
"engines": {
"node": ">=20.14.0"
"node": ">=20.12.2"
},
"scripts": {
"test": "jest",
Expand Down
14,960 changes: 4,052 additions & 10,908 deletions frontend/package-lock.json

Large diffs are not rendered by default.

21 changes: 10 additions & 11 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"type": "module",
"proxy": "http://localhost:8080",
"engines": {
"node": ">=20.14.0"
"node": ">=20.12.2"
},
"dependencies": {
"@emotion/babel-plugin": "^11.11.0",
Expand All @@ -14,7 +14,7 @@
"@fontsource/roboto": "^5.0.13",
"@mui/icons-material": "^6.0.0-alpha.13",
"@mui/material": "^6.0.0-alpha.13",
"@mui/styled-engine": "npm:@mui/styled-engine-sc@latest",
"@mui/styled-engine": "^5.15.14",
"@mui/styles": "^6.0.0-alpha.13",
"@mui/x-date-pickers": "^7.7.1",
"@types/history": "^4.7.11",
Expand All @@ -29,6 +29,7 @@
"dayjs": "^1.11.11",
"history": "^4.10.1",
"luxon": "^3.4.4",
"node": "^20.14.0",
"notistack": "^3.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand All @@ -40,10 +41,10 @@
"scripts": {
"start": "vite",
"build": "tsc && vite build",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage .",
"test:debug": "jest --inspect-brk --runInBand --no-cache",
"test": "vitest",
"test:watch": "vitest --watch",
"test:coverage": "vitest --coverage .",
"test:debug": "vitest --inspect-brk --runInBand --no-cache",
"preview": "vite preview",
"build:ci": "CI=true npm run build",
"test:ci": "CI=true npm test",
Expand All @@ -69,18 +70,16 @@
]
},
"devDependencies": {
"@testing-library/dom": "^10.1.0",
"@testing-library/dom": "^10.3.1",
"@testing-library/jest-dom": "^6.4.6",
"@testing-library/react": "^16.0.0",
"@testing-library/user-event": "^14.5.2",
"@types/jest": "^29.5.12",
"eslint-config-prettier": "^9.1.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"ts-jest": "^29.1.5",
"happy-dom": "^14.12.3",
"vite": "^5.3.1",
"vite-plugin-svgr": "^4.2.0",
"vite-tsconfig-paths": "^4.3.2",
"vitest": "^1.6.0",
"web-vitals": "^4.1.1"
},
"peerDependencies": {
Expand Down
1 change: 1 addition & 0 deletions frontend/setupTests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '@testing-library/jest-dom/vitest';
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/**
* @vitest-environment happy-dom
*/

// @ts-nocheck
import {
vi,
expect,
describe,
it,
beforeEach,
afterEach,
beforeAll,
afterAll
} from 'vitest';

// @ts-nocheck
import React from 'react';
import ReactDOM, { unmountComponentAtNode } from 'react-dom';
Expand Down Expand Up @@ -57,14 +73,18 @@ const fakeRooms = [
}
];

jest.mock('../../hooks/useCreateNotification', () => () => {
vi.mock('../../hooks/useCreateNotification', () => {
return {
createSuccessNotification: jest.fn(),
createErrorNotification: jest.fn()
default: () => {
return {
createSuccessNotification: vi.fn(),
createErrorNotification: vi.fn()
};
}
};
});

jest.mock('../../services/bookingService');
vi.mock('../../services/bookingService');

const fakeBookings = [];

Expand Down Expand Up @@ -94,6 +114,7 @@ describe('AvailableRoomList', () => {
rooms={fakeRooms}
bookings={fakeBookings}
bookingDuration={15}
startingTime="Now"
/>,
container
);
Expand All @@ -111,6 +132,7 @@ describe('AvailableRoomList', () => {
rooms={fakeRooms}
bookings={fakeBookings}
bookingDuration={15}
startingTime="Now"
/>,
container
);
Expand All @@ -124,6 +146,7 @@ describe('AvailableRoomList', () => {
rooms={fakeRooms}
bookings={fakeBookings}
bookingDuration={30}
startingTime="Now"
/>,
container
);
Expand All @@ -138,6 +161,7 @@ describe('AvailableRoomList', () => {
rooms={fakeRooms}
bookings={fakeBookings}
bookingDuration={60}
startingTime="Now"
/>,
container
);
Expand All @@ -152,6 +176,7 @@ describe('AvailableRoomList', () => {
rooms={fakeRooms}
bookings={fakeBookings}
bookingDuration={120}
startingTime="Now"
/>,
container
);
Expand All @@ -166,6 +191,7 @@ describe('AvailableRoomList', () => {
rooms={fakeRooms}
bookings={fakeBookings}
bookingDuration={15}
startingTime="Now"
/>,
container
);
Expand All @@ -181,7 +207,7 @@ describe('AvailableRoomList', () => {

it('default books for a room for 15 minutes', async () => {
const startTime = now.toUTC().toISO();
(makeBooking as jest.Mock).mockResolvedValueOnce({
(makeBooking as vi.Mock).mockResolvedValueOnce({
duration: 15,
roomId: fakeRooms[0].id,
startTime: startTime,
Expand All @@ -193,6 +219,7 @@ describe('AvailableRoomList', () => {
rooms={fakeRooms}
bookings={fakeBookings}
bookingDuration={15}
startingTime="Now"
/>,
container
);
Expand All @@ -203,7 +230,7 @@ describe('AvailableRoomList', () => {
fireEvent.click(bookButton);

await waitFor(() =>
expect(makeBooking as jest.Mock).toHaveBeenCalledWith(
expect(makeBooking as vi.Mock).toHaveBeenCalledWith(
{
duration: 15,
roomId: fakeRooms[0].id,
Expand All @@ -217,7 +244,7 @@ describe('AvailableRoomList', () => {

it('books for a room for 30 minutes', async () => {
const startTime = now.toUTC().toISO();
(makeBooking as jest.Mock).mockResolvedValueOnce({
(makeBooking as vi.Mock).mockResolvedValueOnce({
duration: 30,
roomId: fakeRooms[0].id,
startTime: startTime,
Expand All @@ -229,6 +256,7 @@ describe('AvailableRoomList', () => {
rooms={fakeRooms}
bookings={fakeBookings}
bookingDuration={30}
startingTime="Now"
/>,
container
);
Expand All @@ -239,7 +267,7 @@ describe('AvailableRoomList', () => {
fireEvent.click(bookButton);

await waitFor(() =>
expect(makeBooking as jest.Mock).toHaveBeenCalledWith(
expect(makeBooking as vi.Mock).toHaveBeenCalledWith(
{
duration: 30,
roomId: fakeRooms[0].id,
Expand All @@ -253,7 +281,7 @@ describe('AvailableRoomList', () => {

it('books for a room for 60 minutes', async () => {
const startTime = now.toUTC().toISO();
(makeBooking as jest.Mock).mockResolvedValueOnce({
(makeBooking as vi.Mock).mockResolvedValueOnce({
duration: 30,
roomId: fakeRooms[0].id,
startTime: startTime,
Expand All @@ -265,6 +293,7 @@ describe('AvailableRoomList', () => {
rooms={fakeRooms}
bookings={fakeBookings}
bookingDuration={60}
startingTime="Now"
/>,
container
);
Expand All @@ -275,7 +304,7 @@ describe('AvailableRoomList', () => {
fireEvent.click(bookButton);

await waitFor(() =>
expect(makeBooking as jest.Mock).toHaveBeenCalledWith(
expect(makeBooking as vi.Mock).toHaveBeenCalledWith(
{
duration: 60,
roomId: fakeRooms[0].id,
Expand All @@ -289,7 +318,7 @@ describe('AvailableRoomList', () => {

it('books for a room for 120 minutes', async () => {
const startTime = now.toUTC().toISO();
(makeBooking as jest.Mock).mockResolvedValueOnce({
(makeBooking as vi.Mock).mockResolvedValueOnce({
duration: 30,
roomId: fakeRooms[0].id,
startTime: startTime,
Expand All @@ -301,6 +330,7 @@ describe('AvailableRoomList', () => {
rooms={fakeRooms}
bookings={fakeBookings}
bookingDuration={120}
startingTime="Now"
/>,
container
);
Expand All @@ -311,7 +341,7 @@ describe('AvailableRoomList', () => {
fireEvent.click(bookButton);

await waitFor(() =>
expect(makeBooking as jest.Mock).toHaveBeenCalledWith(
expect(makeBooking as vi.Mock).toHaveBeenCalledWith(
{
duration: 120,
roomId: fakeRooms[0].id,
Expand Down
68 changes: 59 additions & 9 deletions frontend/src/components/AvailableRoomList/AvailableRoomList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import useCreateNotification from '../../hooks/useCreateNotification';
import RoomCard from '../RoomCard/RoomCard';
import NoRoomsCard from '../RoomCard/NoRoomsCard';
import BookingDrawer from '../BookingDrawer/BookingDrawer';
import TimePickerDrawer from '../TimePickerDrawer/TimePickerDrawer';
import StartingTimePickerDrawer from '../StartingTimePickerDrawer/StartingTimePickerDrawer';
import DurationTimePickerDrawer from '../DurationTimePickerDrawer/DurationTimePickerDrawer';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { LocalizationProvider } from '@mui/x-date-pickers';
import dayjs from 'dayjs';

const SKIP_CONFIRMATION = true;

Expand Down Expand Up @@ -80,6 +84,12 @@ type BookingListProps = {
expandedFeaturesAll: boolean;
preferences?: Preferences;
setPreferences: (pref: Preferences) => void;
startingTime: string;
setStartingTime: (newStartingTime: string) => void;
setBookingDuration: (minutes: number) => void;
setDuration: React.Dispatch<React.SetStateAction<number>>;
setExpandTimePickerDrawer: (show: boolean) => void;
expandTimePickerDrawer: boolean;
};

const AvailableRoomList = (props: BookingListProps) => {
Expand All @@ -91,7 +101,13 @@ const AvailableRoomList = (props: BookingListProps) => {
updateData,
expandedFeaturesAll,
preferences,
setPreferences
setPreferences,
startingTime,
setStartingTime,
setBookingDuration,
setDuration,
setExpandTimePickerDrawer,
expandTimePickerDrawer
} = props;
const { createSuccessNotification, createErrorNotification } =
useCreateNotification();
Expand All @@ -105,13 +121,19 @@ const AvailableRoomList = (props: BookingListProps) => {
undefined
);

const [expandTimePickerDrawer, setExpandTimePickerDrawer] = useState(false);
const [startingTime, setStartingTime] = useState<string>('Now');
const [expandDurationTimePickerDrawer, setExpandDurationTimePickerDrawer] =
useState(false);

const handleAdditionalDurationChange = (additionalMinutes: number) => {
setAdditionalDuration(additionalDuration + additionalMinutes);
};
function maxDuration(room: Room | undefined, startingTime: String) {
const mm = availableForMinutes(room, startingTime);

return dayjs()
.minute(mm % 60)
.hour(Math.floor(mm / 60));
}
const handleUntilHalf = () => {
let halfTime =
startingTime === 'Now'
Expand All @@ -124,7 +146,12 @@ const AvailableRoomList = (props: BookingListProps) => {
.plus({ minutes: bookingDuration })
.toObject();

if (!halfTime || !halfTime.hour || !halfTime.minute) {
if (
halfTime.hour === undefined ||
halfTime.minute === undefined ||
Number.isNaN(halfTime.hour) ||
Number.isNaN(halfTime.minute)
) {
throw new Error('Time not set');
}

Expand Down Expand Up @@ -166,7 +193,12 @@ const AvailableRoomList = (props: BookingListProps) => {
})
.plus({ minutes: bookingDuration })
.toObject();
if (!fullTime || !fullTime.hour || !fullTime.minute) {
if (
fullTime.hour === undefined ||
fullTime.minute === undefined ||
Number.isNaN(fullTime.hour) ||
Number.isNaN(fullTime.minute)
) {
throw new Error('Time not set');
}

Expand Down Expand Up @@ -277,9 +309,15 @@ const AvailableRoomList = (props: BookingListProps) => {
onAddTimeUntilFull={handleUntilFull}
onAddTimeUntilNext={handleUntilNextDurationChange}
startingTime={startingTime}
setBookingDuration={setBookingDuration}
setAdditionalDuration={setAdditionalDuration}
setDuration={setDuration}
setExpandDurationTimePickerDrawer={
setExpandDurationTimePickerDrawer
}
/>
{
<TimePickerDrawer
<LocalizationProvider dateAdapter={AdapterDayjs}>
<StartingTimePickerDrawer
open={expandTimePickerDrawer}
toggle={(newOpen: any) =>
setExpandTimePickerDrawer(newOpen)
Expand All @@ -288,7 +326,19 @@ const AvailableRoomList = (props: BookingListProps) => {
setStartingTime={setStartingTime}
setExpandTimePickerDrawer={setExpandTimePickerDrawer}
/>
}
<DurationTimePickerDrawer
open={expandDurationTimePickerDrawer}
toggle={(newOpen: any) =>
setExpandDurationTimePickerDrawer(newOpen)
}
bookingDuration={bookingDuration}
setBookingDuration={setBookingDuration}
setExpandDurationTimePickerDrawer={
setExpandDurationTimePickerDrawer
}
maxDuration={maxDuration(selectedRoom, startingTime)}
/>
</LocalizationProvider>
</div>
<div
id="available-booking-typography"
Expand Down
Loading