Skip to content

Commit c2745d4

Browse files
liuxiaopai-aiPangjiping
authored andcommitted
test(server): add renew-expiration route coverage
1 parent 4710030 commit c2745d4

1 file changed

Lines changed: 103 additions & 0 deletions

File tree

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# Copyright 2025 Alibaba Group Holding Ltd.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from datetime import datetime, timedelta, timezone
16+
17+
from fastapi.exceptions import HTTPException
18+
from fastapi.testclient import TestClient
19+
20+
from src.api import lifecycle
21+
from src.api.schema import RenewSandboxExpirationResponse
22+
23+
24+
def test_renew_expiration_returns_updated_timestamp(
25+
client: TestClient,
26+
auth_headers: dict,
27+
monkeypatch,
28+
) -> None:
29+
target = datetime.now(timezone.utc) + timedelta(hours=2)
30+
calls: list[tuple[str, datetime]] = []
31+
32+
class StubService:
33+
@staticmethod
34+
def renew_expiration(sandbox_id: str, request) -> RenewSandboxExpirationResponse:
35+
calls.append((sandbox_id, request.expires_at))
36+
return RenewSandboxExpirationResponse(expiresAt=target)
37+
38+
monkeypatch.setattr(lifecycle, "sandbox_service", StubService())
39+
40+
response = client.post(
41+
"/v1/sandboxes/sbx-001/renew-expiration",
42+
headers=auth_headers,
43+
json={"expiresAt": target.isoformat()},
44+
)
45+
46+
assert response.status_code == 200
47+
expires_at = datetime.fromisoformat(response.json()["expiresAt"].replace("Z", "+00:00"))
48+
assert expires_at == target
49+
assert calls == [("sbx-001", target)]
50+
51+
52+
def test_renew_expiration_rejects_invalid_payload(
53+
client: TestClient,
54+
auth_headers: dict,
55+
) -> None:
56+
response = client.post(
57+
"/v1/sandboxes/sbx-001/renew-expiration",
58+
headers=auth_headers,
59+
json={"expiresAt": "not-a-datetime"},
60+
)
61+
62+
assert response.status_code == 422
63+
64+
65+
def test_renew_expiration_propagates_service_http_error(
66+
client: TestClient,
67+
auth_headers: dict,
68+
monkeypatch,
69+
) -> None:
70+
class StubService:
71+
@staticmethod
72+
def renew_expiration(sandbox_id: str, request) -> RenewSandboxExpirationResponse:
73+
raise HTTPException(
74+
status_code=409,
75+
detail={
76+
"code": "INVALID_EXPIRES_AT",
77+
"message": f"Requested expiresAt is not valid for sandbox {sandbox_id}",
78+
},
79+
)
80+
81+
monkeypatch.setattr(lifecycle, "sandbox_service", StubService())
82+
83+
response = client.post(
84+
"/v1/sandboxes/sbx-001/renew-expiration",
85+
headers=auth_headers,
86+
json={"expiresAt": "2030-01-01T00:00:00Z"},
87+
)
88+
89+
assert response.status_code == 409
90+
assert response.json() == {
91+
"code": "INVALID_EXPIRES_AT",
92+
"message": "Requested expiresAt is not valid for sandbox sbx-001",
93+
}
94+
95+
96+
def test_renew_expiration_requires_api_key(client: TestClient) -> None:
97+
response = client.post(
98+
"/v1/sandboxes/sbx-001/renew-expiration",
99+
json={"expiresAt": "2030-01-01T00:00:00Z"},
100+
)
101+
102+
assert response.status_code == 401
103+
assert response.json()["code"] == "MISSING_API_KEY"

0 commit comments

Comments
 (0)