""" Regression tests for share expiry failing open (review finding #10). create_share parsed expires_days inside `try: ... except: pass`, so any value it could not parse silently became "never expires" — the opposite of what the user asked for, with no error to notice. """ from datetime import datetime, timedelta, timezone from tests.conftest import add_item, auth_headers, make_user def _share(client, token, item_id, recipient='friend@example.com', **extra): body = { 'item_id': item_id, 'recipient_email': recipient, 'enc_data': 'ECDH-CT', 'iv': 'ECDH-IV', 'item_name': 'password', 'item_type': 'password', } body.update(extra) return client.post('/api/sharing', headers=auth_headers(token), json=body) def test_valid_expiry_is_applied(client, app): token, _ = make_user(client) item_id = add_item(client, token) res = _share(client, token, item_id, expires_days=7) assert res.status_code == 201, res.get_json() expires_at = res.get_json()['expires_at'] assert expires_at is not None parsed = datetime.fromisoformat(expires_at) expected = datetime.now(timezone.utc).replace(tzinfo=None) + timedelta(days=7) assert abs((parsed - expected).total_seconds()) < 60 def test_null_expiry_means_never(client, app): token, _ = make_user(client) item_id = add_item(client, token) res = _share(client, token, item_id, expires_days=None) assert res.status_code == 201 assert res.get_json()['expires_at'] is None def test_omitted_expiry_means_never(client, app): token, _ = make_user(client) item_id = add_item(client, token) res = _share(client, token, item_id) assert res.status_code == 201 assert res.get_json()['expires_at'] is None def test_unparseable_expiry_is_rejected_not_silently_dropped(client, app): """The bug: 'seven' used to yield a share that never expires.""" token, _ = make_user(client) for bad in ('seven', '7 days', {}, [], 'NaN', ''): item_id = add_item(client, token) res = _share(client, token, item_id, expires_days=bad) assert res.status_code == 400, ( f'expires_days={bad!r} accepted; share would never expire' ) assert 'expires_days' in res.get_json()['error'] def test_out_of_range_expiry_is_rejected(client, app): token, _ = make_user(client) for bad in (-1, -30, 4000): item_id = add_item(client, token) res = _share(client, token, item_id, expires_days=bad) assert res.status_code == 400, f'expires_days={bad!r} accepted' def test_zero_expiry_means_never(client, app): """0 is 'no expiry', consistent with null — not 'expires immediately'.""" token, _ = make_user(client) item_id = add_item(client, token) res = _share(client, token, item_id, expires_days=0) assert res.status_code == 201 assert res.get_json()['expires_at'] is None