Skip to content

Commit 36ad580

Browse files
committed
improve mock for edge cases.
always parse lastUsedAt regardless of parameter
1 parent faeb2f9 commit 36ad580

3 files changed

Lines changed: 70 additions & 5 deletions

File tree

integration/test_users.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ def test_get_user_created_at_and_api_key_first_letters(client_factory: ClientFac
222222
pytest.skip("This test requires Weaviate 1.30.0 or higher")
223223

224224
randomUserName = "new-user" + str(random.randint(1, 1000))
225-
apiKey = client.users.db.create(user_id=randomUserName)
225+
client.users.db.create(user_id=randomUserName)
226226
try:
227227
user = client.users.db.get(user_id=randomUserName)
228228
assert user is not None

mock_tests/test_users.py

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,18 @@
1717
"userId": "test-user",
1818
}
1919

20+
USER_DATA_NO_LAST_USED = {k: v for k, v in USER_DATA.items() if k != "lastUsedAt"}
21+
2022
USERS_DATA = [
2123
USER_DATA,
2224
{**USER_DATA, "userId": "test-user-2"},
2325
]
2426

27+
USERS_DATA_NO_LAST_USED = [
28+
USER_DATA_NO_LAST_USED,
29+
{**USER_DATA_NO_LAST_USED, "userId": "test-user-2"},
30+
]
31+
2532
EXPECTED_CREATED_AT = datetime(2026, 2, 24, 19, 15, 18, 574000, tzinfo=timezone.utc)
2633
EXPECTED_LAST_USED_AT = datetime(2026, 2, 25, 20, 57, 36, 419000, tzinfo=timezone.utc)
2734

@@ -33,7 +40,7 @@ def test_get_user_without_last_used_time(
3340

3441
def handler(request: Request) -> Response:
3542
captured["params"] = dict(request.args)
36-
return Response(json.dumps(USER_DATA), content_type="application/json", status=200)
43+
return Response(json.dumps(USER_DATA_NO_LAST_USED), content_type="application/json", status=200)
3744

3845
weaviate_no_auth_mock.expect_request("/v1/users/db/test-user").respond_with_handler(handler)
3946

@@ -95,7 +102,7 @@ def test_list_all_without_last_used_time(
95102

96103
def handler(request: Request) -> Response:
97104
captured["params"] = dict(request.args)
98-
return Response(json.dumps(USERS_DATA), content_type="application/json", status=200)
105+
return Response(json.dumps(USERS_DATA_NO_LAST_USED), content_type="application/json", status=200)
99106

100107
weaviate_no_auth_mock.expect_request("/v1/users/db").respond_with_handler(handler)
101108

@@ -133,3 +140,61 @@ def handler(request: Request) -> Response:
133140
assert user.last_used_time == EXPECTED_LAST_USED_AT
134141
assert user.created_at == EXPECTED_CREATED_AT
135142
assert captured["params"].get("includeLastUsedTime") in ("True", "true")
143+
144+
145+
def test_get_user_missing_created_at(
146+
weaviate_no_auth_mock: HTTPServer, start_grpc_server: grpc.Server
147+
) -> None:
148+
data = {k: v for k, v in USER_DATA.items() if k != "createdAt"}
149+
weaviate_no_auth_mock.expect_request("/v1/users/db/test-user").respond_with_response(
150+
Response(json.dumps(data), content_type="application/json", status=200)
151+
)
152+
153+
with weaviate.connect_to_local(
154+
host=MOCK_IP, port=MOCK_PORT, grpc_port=MOCK_PORT_GRPC
155+
) as client:
156+
user = client.users.db.get(user_id="test-user")
157+
158+
assert user is not None
159+
assert user.created_at is None
160+
assert user.last_used_time == EXPECTED_LAST_USED_AT
161+
162+
163+
def test_get_user_missing_api_key_first_letters(
164+
weaviate_no_auth_mock: HTTPServer, start_grpc_server: grpc.Server
165+
) -> None:
166+
data = {k: v for k, v in USER_DATA.items() if k != "apiKeyFirstLetters"}
167+
weaviate_no_auth_mock.expect_request("/v1/users/db/test-user").respond_with_response(
168+
Response(json.dumps(data), content_type="application/json", status=200)
169+
)
170+
171+
with weaviate.connect_to_local(
172+
host=MOCK_IP, port=MOCK_PORT, grpc_port=MOCK_PORT_GRPC
173+
) as client:
174+
user = client.users.db.get(user_id="test-user")
175+
176+
assert user is not None
177+
assert user.api_key_first_letters is None
178+
assert user.created_at == EXPECTED_CREATED_AT
179+
180+
181+
def test_get_user_last_used_time_parsed_when_include_false(
182+
weaviate_no_auth_mock: HTTPServer, start_grpc_server: grpc.Server
183+
) -> None:
184+
"""If the API returns lastUsedAt the client must parse it regardless of include_last_used_time."""
185+
captured: dict = {}
186+
187+
def handler(request: Request) -> Response:
188+
captured["params"] = dict(request.args)
189+
return Response(json.dumps(USER_DATA), content_type="application/json", status=200)
190+
191+
weaviate_no_auth_mock.expect_request("/v1/users/db/test-user").respond_with_handler(handler)
192+
193+
with weaviate.connect_to_local(
194+
host=MOCK_IP, port=MOCK_PORT, grpc_port=MOCK_PORT_GRPC
195+
) as client:
196+
user = client.users.db.get(user_id="test-user") # include_last_used_time defaults to False
197+
198+
assert user is not None
199+
assert user.last_used_time == EXPECTED_LAST_USED_AT
200+
assert captured["params"].get("includeLastUsedTime") in ("False", "false")

weaviate/users/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ def resp(res: Response) -> Optional[UserDB]:
468468
parsed = _decode_json_response_dict(res, "Get user")
469469
assert parsed is not None
470470
created_at = parsed.get("createdAt")
471-
last_used_at = parsed.get("lastUsedAt") if include_last_used_time else None
471+
last_used_at = parsed.get("lastUsedAt")
472472
return UserDB(
473473
user_id=parsed["userId"],
474474
role_names=parsed["roles"],
@@ -519,7 +519,7 @@ def resp(res: Response) -> List[UserDB]:
519519
),
520520
last_used_time=(
521521
datetime.fromisoformat(lua.replace("Z", "+00:00"))
522-
if include_last_used_time and (lua := user.get("lastUsedAt")) is not None
522+
if (lua := user.get("lastUsedAt")) is not None
523523
else None
524524
),
525525
api_key_first_letters=user.get("apiKeyFirstLetters"),

0 commit comments

Comments
 (0)