Files
2026-10-26 00:06:24 +01:00

89 lines
4.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Run: PYTHONPATH=app pytest -q tests/test_calendar.py"""
from datetime import date, datetime, timedelta
from zoneinfo import ZoneInfo
import pytest
from services import ha_views, alfred_intents as intents
PARIS=ZoneInfo('Europe/Paris')
NOW=datetime(2026,10,25,18,0,tzinfo=PARIS)
@pytest.mark.parametrize('utterance,start,end',[
('J’ai quelque chose de prévu demain ?',date(2026,10,26),date(2026,10,27)),
('Montre mon planning sur 3 jours',date(2026,10,25),date(2026,10,28)),
('Que j’ai le 8 novembre ?',date(2026,11,8),date(2026,11,9)),
('Je veux mon agenda du mois',date(2026,10,1),date(2026,11,1)),
('Qu’est-ce que j’ai ce matin ?',date(2026,10,25),date(2026,10,25)),
])
def test_voice_period(utterance,start,end):
a,b,view=intents.period(utterance,NOW)
assert a.date()==start
if 'matin' not in utterance:assert b.date()==end
else:assert (a.hour,b.hour)==(6,12)
@pytest.mark.parametrize('utterance,kind',[
('Montre mon planning sur 7 jours','calendar'),
('J’ai des choses de prévu le 8 novembre ?','calendar'),
('Ajoute un rendez-vous dentiste demain à 15h','create'),
('Supprime mon rendez-vous demain','delete'),
('Affiche les caméras extérieures','cameras'),
('Montre les températures','temperatures'),
('Reviens à l’accueil','home'),
('Génère-moi une image de poulet',None),
])
def test_intent(utterance,kind):
result=intents.classify(utterance)
assert (result or {}).get('kind')==kind
def test_event_adapter(monkeypatch):
def fake_request(method,path,**kwargs):
if path=='/api/calendars':return [{'entity_id':'calendar.family','name':'Famille'}]
if path=='/api/states':return [{'entity_id':'calendar.family','attributes':{'supported_features':3}}]
if path.startswith('/api/calendars/'):
return [{'summary':'Dentiste','uid':'abc123','start':{'dateTime':'2026-10-25T10:00:00+01:00'},
'end':{'dateTime':'2026-10-25T11:00:00+01:00'}}]
monkeypatch.setattr(ha_views,'_request',fake_request)
data=ha_views.get_events(datetime(2026,10,25,tzinfo=PARIS),datetime(2026,10,26,tzinfo=PARIS))
assert data['events'][0]['title']=='Dentiste'
assert data['events'][0]['id']=='abc123'
assert data['events'][0]['can_delete'] is True
def test_recurring_no_uid_cannot_delete(monkeypatch):
def fake_request(method,path,**kwargs):
if path=='/api/calendars':return [{'entity_id':'calendar.a','name':'A'}]
if path=='/api/states':return [{'entity_id':'calendar.a','attributes':{'supported_features':0}}]
if path.startswith('/api/calendars/'):
return [{'summary':'Test','start':'2026-10-26','end':'2026-10-27'}]
monkeypatch.setattr(ha_views,'_request',fake_request)
data=ha_views.get_events(datetime(2026,10,25,tzinfo=PARIS),datetime(2026,10,27,tzinfo=PARIS))
assert data['events'][0]['all_day'] is True
assert data['events'][0]['can_delete'] is False
def test_create_event_calls_service(monkeypatch):
calls=[]
monkeypatch.setattr(ha_views,'list_calendars',lambda:[{'entity_id':'calendar.family','can_create':True,'can_delete':True}])
monkeypatch.setattr(ha_views,'_request',lambda method,path,**kwargs:calls.append((method,path,kwargs)) or None)
start=datetime(2026,11,8,15,0,tzinfo=PARIS)
assert ha_views.create_event('calendar.family','Dentiste',start,start+timedelta(hours=1))['ok']
assert calls[0][1]=='/api/services/calendar/create_event'
assert calls[0][2]['payload']['entity_id']=='calendar.family'
def test_delete_uses_websocket(monkeypatch):
import websocket
monkeypatch.setattr(ha_views,'list_calendars',lambda:[{'entity_id':'calendar.family','can_create':True,'can_delete':True}])
monkeypatch.setattr(ha_views,'_cfg',lambda:('http://ha.example:8123','test-token'))
class FakeWS:
messages=[]
def __init__(self):self.replies=iter(['{"type":"auth_required"}','{"type":"auth_ok"}','{"id":1,"success":true}'])
def recv(self):return next(self.replies)
def send(self,m):self.messages.append(m)
def close(self):pass
ws=FakeWS()
monkeypatch.setattr(websocket,'create_connection',lambda url,timeout:ws)
ha_views.delete_event('calendar.family','event1')
assert 'calendar/event/delete' in ws.messages[1]
assert 'event1' in ws.messages[1]