FIxed date range overlap

This commit is contained in:
Jonas Linter
2025-12-04 16:33:11 +01:00
parent 16d12f5b62
commit a6837197b6
2 changed files with 392 additions and 8 deletions

View File

@@ -723,3 +723,339 @@ async def test_complete_set_preserves_inventory_from_other_sources(db_session: A
# Preserved HotelInventory source
assert inventory_after[1].source == "HotelInventory"
assert inventory_after[1].inv_type_code == "SGL"
@pytest.mark.asyncio
async def test_closing_season_overlapping_with_inventory_is_rejected(db_session: AsyncSession):
"""Test that closing seasons cannot overlap with regular inventory entries."""
await insert_test_hotel(db_session)
action = make_action()
# Closing season from July 31 to Sept 30, with inventory from Aug 1-10 (overlaps!)
xml = build_complete_set_xml(
"""
<Inventory>
<StatusApplicationControl Start="2022-07-31" End="2022-09-30" AllInvCode="true" />
</Inventory>
<Inventory>
<StatusApplicationControl Start="2022-08-01" End="2022-08-10" InvTypeCode="DOUBLE" />
<InvCounts>
<InvCount CountType="2" Count="3" />
</InvCounts>
</Inventory>
"""
)
response = await action.handle(
"OTA_HotelInvCountNotif:FreeRooms",
xml,
Version.V2024_10,
make_client_info(),
db_session,
)
assert response.status_code == HttpStatusCode.BAD_REQUEST
assert "overlaps with closing season" in response.xml_content
@pytest.mark.asyncio
async def test_overlapping_closing_seasons_are_rejected(db_session: AsyncSession):
"""Test that multiple closing seasons cannot overlap with each other."""
await insert_test_hotel(db_session)
action = make_action()
# Two overlapping closing seasons
xml = build_complete_set_xml(
"""
<Inventory>
<StatusApplicationControl Start="2022-07-01" End="2022-07-31" AllInvCode="true" />
</Inventory>
<Inventory>
<StatusApplicationControl Start="2022-07-15" End="2022-08-15" AllInvCode="true" />
</Inventory>
"""
)
response = await action.handle(
"OTA_HotelInvCountNotif:FreeRooms",
xml,
Version.V2024_10,
make_client_info(),
db_session,
)
assert response.status_code == HttpStatusCode.BAD_REQUEST
assert "Closing seasons overlap" in response.xml_content
@pytest.mark.asyncio
async def test_non_overlapping_closing_seasons_are_allowed(db_session: AsyncSession):
"""Test that multiple non-overlapping closing seasons are allowed."""
await insert_test_hotel(db_session)
action = make_action()
# Two non-overlapping closing seasons
xml = build_complete_set_xml(
"""
<Inventory>
<StatusApplicationControl Start="2022-07-01" End="2022-07-15" AllInvCode="true" />
</Inventory>
<Inventory>
<StatusApplicationControl Start="2022-08-01" End="2022-08-15" AllInvCode="true" />
</Inventory>
<Inventory>
<StatusApplicationControl Start="2022-07-16" End="2022-07-31" InvTypeCode="DOUBLE" />
<InvCounts>
<InvCount CountType="2" Count="5" />
</InvCounts>
</Inventory>
"""
)
response = await action.handle(
"OTA_HotelInvCountNotif:FreeRooms",
xml,
Version.V2024_10,
make_client_info(),
db_session,
)
assert response.status_code == HttpStatusCode.OK
# Verify closing seasons were created
rows = (
await db_session.execute(
select(RoomAvailability).where(RoomAvailability.is_closing_season.is_(True))
)
).scalars().all()
# 15 days in July + 15 days in August = 30 closing season days
assert len(rows) == 30
@pytest.mark.asyncio
async def test_adjacent_closing_season_and_inventory_are_allowed(db_session: AsyncSession):
"""Test that closing seasons and inventory can be adjacent (not overlapping) without error."""
await insert_test_hotel(db_session)
action = make_action()
# Closing season ends July 31, inventory starts Aug 1 (adjacent, not overlapping)
xml = build_complete_set_xml(
"""
<Inventory>
<StatusApplicationControl Start="2022-07-01" End="2022-07-31" AllInvCode="true" />
</Inventory>
<Inventory>
<StatusApplicationControl Start="2022-08-01" End="2022-08-10" InvTypeCode="DOUBLE" />
<InvCounts>
<InvCount CountType="2" Count="3" />
</InvCounts>
</Inventory>
"""
)
response = await action.handle(
"OTA_HotelInvCountNotif:FreeRooms",
xml,
Version.V2024_10,
make_client_info(),
db_session,
)
assert response.status_code == HttpStatusCode.OK
@pytest.mark.asyncio
async def test_overlapping_inventory_for_same_category_is_rejected(db_session: AsyncSession):
"""Test that overlapping date ranges for the same room category are rejected."""
await insert_test_hotel(db_session)
action = make_action()
# Two overlapping date ranges for DOUBLE category
xml = build_complete_set_xml(
"""
<Inventory>
<StatusApplicationControl Start="2022-08-01" End="2022-08-10" InvTypeCode="DOUBLE" />
<InvCounts>
<InvCount CountType="2" Count="3" />
</InvCounts>
</Inventory>
<Inventory>
<StatusApplicationControl Start="2022-08-11" End="2022-08-20" InvTypeCode="DOUBLE" />
<InvCounts>
<InvCount CountType="2" Count="5" />
</InvCounts>
</Inventory>
<Inventory>
<StatusApplicationControl Start="2022-08-15" End="2022-08-30" InvTypeCode="DOUBLE" />
<InvCounts>
<InvCount CountType="2" Count="3" />
</InvCounts>
</Inventory>
"""
)
response = await action.handle(
"OTA_HotelInvCountNotif:FreeRooms",
xml,
Version.V2024_10,
make_client_info(),
db_session,
)
assert response.status_code == HttpStatusCode.BAD_REQUEST
assert "Overlapping date ranges for category 'DOUBLE'" in response.xml_content
@pytest.mark.asyncio
async def test_overlapping_inventory_for_same_room_is_rejected(db_session: AsyncSession):
"""Test that overlapping date ranges for the same individual room are rejected."""
await insert_test_hotel(db_session)
action = make_action()
# Two overlapping date ranges for room 101
xml = build_complete_set_xml(
"""
<Inventory>
<StatusApplicationControl Start="2022-08-01" End="2022-08-15" InvTypeCode="DOUBLE" InvCode="101" />
<InvCounts>
<InvCount CountType="2" Count="1" />
</InvCounts>
</Inventory>
<Inventory>
<StatusApplicationControl Start="2022-08-10" End="2022-08-20" InvTypeCode="DOUBLE" InvCode="101" />
<InvCounts>
<InvCount CountType="2" Count="1" />
</InvCounts>
</Inventory>
"""
)
response = await action.handle(
"OTA_HotelInvCountNotif:FreeRooms",
xml,
Version.V2024_10,
make_client_info(),
db_session,
)
assert response.status_code == HttpStatusCode.BAD_REQUEST
assert "Overlapping date ranges for room '101'" in response.xml_content
@pytest.mark.asyncio
async def test_non_overlapping_inventory_for_same_category_is_allowed(db_session: AsyncSession):
"""Test that non-overlapping date ranges for the same category are allowed."""
await insert_test_hotel(db_session)
action = make_action()
# Three non-overlapping date ranges for DOUBLE category
xml = build_complete_set_xml(
"""
<Inventory>
<StatusApplicationControl Start="2022-08-01" End="2022-08-10" InvTypeCode="DOUBLE" />
<InvCounts>
<InvCount CountType="2" Count="3" />
</InvCounts>
</Inventory>
<Inventory>
<StatusApplicationControl Start="2022-08-11" End="2022-08-20" InvTypeCode="DOUBLE" />
<InvCounts>
<InvCount CountType="2" Count="5" />
</InvCounts>
</Inventory>
<Inventory>
<StatusApplicationControl Start="2022-08-21" End="2022-08-30" InvTypeCode="DOUBLE" />
<InvCounts>
<InvCount CountType="2" Count="3" />
</InvCounts>
</Inventory>
"""
)
response = await action.handle(
"OTA_HotelInvCountNotif:FreeRooms",
xml,
Version.V2024_10,
make_client_info(),
db_session,
)
assert response.status_code == HttpStatusCode.OK
# Verify all dates were created
rows = (
await db_session.execute(
select(RoomAvailability).order_by(RoomAvailability.date)
)
).scalars().all()
assert len(rows) == 30 # Aug 1-30
@pytest.mark.asyncio
async def test_overlapping_inventory_for_different_categories_is_allowed(db_session: AsyncSession):
"""Test that overlapping dates for different room categories are allowed."""
await insert_test_hotel(db_session)
action = make_action()
# Overlapping dates but for different categories (DOUBLE vs SINGLE)
xml = build_complete_set_xml(
"""
<Inventory>
<StatusApplicationControl Start="2022-08-01" End="2022-08-15" InvTypeCode="DOUBLE" />
<InvCounts>
<InvCount CountType="2" Count="3" />
</InvCounts>
</Inventory>
<Inventory>
<StatusApplicationControl Start="2022-08-10" End="2022-08-20" InvTypeCode="SINGLE" />
<InvCounts>
<InvCount CountType="2" Count="2" />
</InvCounts>
</Inventory>
"""
)
response = await action.handle(
"OTA_HotelInvCountNotif:FreeRooms",
xml,
Version.V2024_10,
make_client_info(),
db_session,
)
assert response.status_code == HttpStatusCode.OK
@pytest.mark.asyncio
async def test_overlapping_inventory_for_different_rooms_is_allowed(db_session: AsyncSession):
"""Test that overlapping dates for different individual rooms are allowed."""
await insert_test_hotel(db_session)
action = make_action()
# Overlapping dates but for different rooms (101 vs 102)
xml = build_complete_set_xml(
"""
<Inventory>
<StatusApplicationControl Start="2022-08-01" End="2022-08-15" InvTypeCode="DOUBLE" InvCode="101" />
<InvCounts>
<InvCount CountType="2" Count="1" />
</InvCounts>
</Inventory>
<Inventory>
<StatusApplicationControl Start="2022-08-10" End="2022-08-20" InvTypeCode="DOUBLE" InvCode="102" />
<InvCounts>
<InvCount CountType="2" Count="1" />
</InvCounts>
</Inventory>
"""
)
response = await action.handle(
"OTA_HotelInvCountNotif:FreeRooms",
xml,
Version.V2024_10,
make_client_info(),
db_session,
)
assert response.status_code == HttpStatusCode.OK