Skip to content

Commit

Permalink
Merge pull request #83 from RedTurtle/out_of_office_checks
Browse files Browse the repository at this point in the history
Only users with permission can add out of office bookings in @booking
  • Loading branch information
cekk authored Aug 31, 2023
2 parents 3f8123a + 142d119 commit 784b5a5
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 12 deletions.
4 changes: 4 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ Changelog
2.0.0rc2 (unreleased)
---------------------

- Skip required field validation when add out of office bookings in @booking endpoint.
[cekk]
- Only users with permission can add out of office bookings in @booking endpoint.
[cekk]
- Fix slots overlap valiation on booking move
[folix-01]

Expand Down
21 changes: 17 additions & 4 deletions src/redturtle/prenotazioni/restapi/services/booking/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,22 @@ def validate(self):
)
)
raise BadRequest(msg)

if data["booking_type"] in [VACATION_TYPE]:
if not api.user.has_permission(
"redturtle.prenotazioni.ManagePrenotazioni", obj=self.context
):
msg = self.context.translate(
_(
"unauthorized_add_vacation",
"You can't add a booking with type '${booking_type}'.",
mapping=dict(booking_type=data["booking_type"]),
)
)
raise BadRequest(msg)
# TODO: check permission for special booking_types ?
return data, data_fields

for field in self.required_fields:
if not data_fields.get(field):
msg = self.context.translate(
Expand All @@ -83,10 +99,7 @@ def validate(self):
)
raise BadRequest(msg)

if data["booking_type"] in [VACATION_TYPE]:
# TODO: check permission for special booking_types ?
pass
elif data["booking_type"] not in [
if data["booking_type"] not in [
_t["name"] for _t in self.context.booking_types or [] if "name" in _t
]:
msg = self.context.translate(
Expand Down
84 changes: 84 additions & 0 deletions src/redturtle/prenotazioni/tests/test_add_block.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# -*- coding: utf-8 -*-
from datetime import date
from datetime import timedelta
from plone import api
from plone.app.testing import setRoles
from plone.app.testing import SITE_OWNER_NAME
from plone.app.testing import SITE_OWNER_PASSWORD
from plone.app.testing import TEST_USER_ID
from plone.restapi.testing import RelativeSession
from redturtle.prenotazioni.content.prenotazione import VACATION_TYPE
from redturtle.prenotazioni.testing import (
REDTURTLE_PRENOTAZIONI_API_FUNCTIONAL_TESTING,
)
from redturtle.prenotazioni.tests.helpers import WEEK_TABLE_SCHEMA

import transaction
import unittest


class TestBookingRestAPIAddBlock(unittest.TestCase):
layer = REDTURTLE_PRENOTAZIONI_API_FUNCTIONAL_TESTING

def setUp(self):
self.app = self.layer["app"]
self.portal = self.layer["portal"]
setRoles(self.portal, TEST_USER_ID, ["Manager"])
self.portal_url = self.portal.absolute_url()
self.folder_prenotazioni = api.content.create(
container=self.portal,
type="PrenotazioniFolder",
title="Prenota foo",
description="",
daData=date.today(),
booking_types=[
{"name": "Type A", "duration": "30"},
],
gates=["Gate A", "Gate B"],
week_table=WEEK_TABLE_SCHEMA,
required_booking_fields=["email"],
)
api.content.transition(obj=self.folder_prenotazioni, transition="publish")
transaction.commit()

self.api_session = RelativeSession(self.portal_url)
self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD)
self.api_session.headers.update({"Accept": "application/json"})

def test_anonymous_cant_add_block(self):
self.api_session.auth = None
booking_date = "{}T09:00:00+00:00".format(
(date.today() + timedelta(1)).strftime("%Y-%m-%d")
)
res = self.api_session.post(
self.folder_prenotazioni.absolute_url() + "/@booking",
json={
"booking_date": booking_date,
"booking_type": VACATION_TYPE,
"fields": [
{"name": "title", "value": "Mario Rossi"},
],
},
)
self.assertEqual(res.status_code, 400)
self.assertEqual(
res.json()["message"],
f"You can't add a booking with type '{VACATION_TYPE}'.",
)

def test_manager_can_add_block_skipping_required_fields(self):
booking_date = "{}T09:00:00+00:00".format(
(date.today() + timedelta(1)).strftime("%Y-%m-%d")
)
res = self.api_session.post(
self.folder_prenotazioni.absolute_url() + "/@booking",
json={
"booking_date": booking_date,
"booking_type": VACATION_TYPE,
"fields": [
{"name": "title", "value": "Mario Rossi"},
# email is a required field from self.folder_prenotazioni schema
],
},
)
self.assertEqual(res.status_code, 200)
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
from redturtle.prenotazioni.testing import (
REDTURTLE_PRENOTAZIONI_INTEGRATION_TESTING,
)
import transaction
from redturtle.prenotazioni.tests.helpers import WEEK_TABLE_SCHEMA
from zope.interface import Interface

import transaction
import unittest


Expand All @@ -37,7 +38,7 @@ def test_field_modes(self):
)


class TestPrenotazioniRestAPIInfo(unittest.TestCase):
class TestBookingRestAPIInfo(unittest.TestCase):
layer = REDTURTLE_PRENOTAZIONI_API_FUNCTIONAL_TESTING

def setUp(self):
Expand All @@ -64,7 +65,7 @@ def test_prenotazione_restapi_endpoint(self):
)


class TestPrenotazioniRestAPIAdd(unittest.TestCase):
class TestBookingRestAPIAdd(unittest.TestCase):
layer = REDTURTLE_PRENOTAZIONI_API_FUNCTIONAL_TESTING

def setUp(self):
Expand All @@ -82,12 +83,8 @@ def setUp(self):
{"name": "Type A", "duration": "30"},
],
gates=["Gate A", "Gate B"],
week_table=WEEK_TABLE_SCHEMA,
)
week_table = self.folder_prenotazioni.week_table
for row in week_table:
row["morning_start"] = "0700"
row["morning_end"] = "1000"
self.folder_prenotazioni.week_table = week_table
api.content.transition(obj=self.folder_prenotazioni, transition="publish")
transaction.commit()

Expand Down Expand Up @@ -190,6 +187,36 @@ def test_force_gate_anonymous(self):
{"message": "You are not allowed to force the gate.", "type": "BadRequest"},
)

def test_cant_add_booking_if_missing_required_fields(self):
folder = api.content.create(
container=self.portal,
type="PrenotazioniFolder",
title="Prenota foo",
description="",
daData=date.today(),
booking_types=[
{"name": "Type A", "duration": "30"},
],
gates=["Gate A", "Gate B"],
week_table=WEEK_TABLE_SCHEMA,
required_booking_fields=["email"],
)
api.content.transition(obj=folder, transition="publish")
transaction.commit()
res = self.api_session.post(
folder.absolute_url() + "/@booking",
json={
"booking_date": "%sT09:00:00"
% (date.today() + timedelta(1)).strftime("%Y-%m-%d"),
"booking_type": "Type A",
"fields": [
{"name": "title", "value": "Mario Rossi"},
],
},
)
self.assertEqual(res.status_code, 400)
self.assertEqual(res.json()["message"], "Required input 'email' is missing.")


class TestPrenotazioniIntegrationTesting(unittest.TestCase):
layer = REDTURTLE_PRENOTAZIONI_INTEGRATION_TESTING
Expand Down
1 change: 1 addition & 0 deletions src/redturtle/prenotazioni/tests/test_available_slots.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ def test_month_slots_called_without_params_return_all_available_slots_of_current
)
self.assertEqual(expected, response.json()["items"])

@unittest.skipIf(date.today().day > 20, "issue testing in the last days of a month")
def test_month_slots_called_without_params_return_available_slots_of_current_month_when_some_are_full(
self,
):
Expand Down

0 comments on commit 784b5a5

Please sign in to comment.