Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 14 additions & 18 deletions app/server/somni/quiz/rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

from __future__ import annotations

import json
from typing import TYPE_CHECKING, Any

from google.protobuf.json_format import ParseDict

from app.core.exceptions import ServiceNotReadyError
from app.server.errors import abort_from_app_error, abort_invalid, run_rpc_call
from app.uburnode_grpc.grpc_gen import uburnode_somni_pb2, uburnode_somni_pb2_grpc
Expand Down Expand Up @@ -36,20 +35,17 @@ async def _require(self, context) -> QuizService:


def _to_res(payload: dict[str, Any]) -> uburnode_somni_pb2.GetAnswerRes:
res = uburnode_somni_pb2.GetAnswerRes()
for item in payload.get("answers") or []:
res.answers.append(_to_item(item if isinstance(item, dict) else {}))
return res


def _to_item(item: dict[str, Any]) -> uburnode_somni_pb2.AnswerItem:
answer = uburnode_somni_pb2.AnswerItem(
question_id=str(item.get("question_id") or ""),
input_type=str(item.get("input_type") or ""),
title=str(item.get("title") or ""),
extra_input=str(item.get("extra_input") or ""),
items = [
{
"question_id": str(item.get("question_id") or ""),
"input_type": str(item.get("input_type") or ""),
"title": str(item.get("title") or ""),
"value": item.get("value"),
"extra_input": str(item.get("extra_input") or ""),
}
for item in (payload.get("answers") or [])
if isinstance(item, dict)
]
return uburnode_somni_pb2.GetAnswerRes(
answers=json.dumps(items, ensure_ascii=False, separators=(",", ":")),
)
raw = item.get("value")
if raw is not None:
ParseDict(raw, answer.value)
return answer
76 changes: 37 additions & 39 deletions app/uburnode_grpc/grpc_gen/uburnode_somni_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 2 additions & 12 deletions proto/uburnode_somni.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,9 @@ message GetAnswerReq {
string answer_id = 2; // 必传:答卷 _id
}

message AnswerItem {
string question_id = 1;
string input_type = 2;
string title = 3;
reserved 4;
reserved "tags";
reserved "values";
google.protobuf.Value value = 5;
string extra_input = 6;
}

// answers 为整份答卷数组的 JSON 文本(与库 answers 同形),客户端一次 JSON.parse。
message GetAnswerRes {
repeated AnswerItem answers = 1;
string answers = 1;
}

service QuizService {
Expand Down
26 changes: 15 additions & 11 deletions tests/test_grpc_quiz.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

import json
from unittest.mock import AsyncMock, MagicMock

import grpc
Expand Down Expand Up @@ -101,21 +102,24 @@ async def test_somni_get_answer_maps_answer_item() -> None:
_context(),
)
payload = MessageToDict(res, preserving_proto_field_name=True)
assert len(payload["answers"]) == 5
assert payload["answers"][0]["value"] == {
"option_id": "A",
"option_text": "先生",
answers = json.loads(payload["answers"])
assert len(answers) == 5
assert answers[0] == {
"question_id": "q1",
"input_type": "radio",
"title": "您的性别是?",
"value": {"option_id": "A", "option_text": "先生"},
"extra_input": "",
}
assert payload["answers"][1]["value"] == [
assert "tags" not in answers[0]
assert answers[1]["value"] == [
{"option_id": "A", "option_text": "早期"},
{"option_id": "B", "option_text": "VC"},
]
assert payload["answers"][2]["value"] == 2
assert payload["answers"][3]["value"] == "最近压力比较大"
assert payload["answers"][4]["value"] is True
assert "tags" not in payload["answers"][0]
assert "values" not in payload["answers"][0]

assert answers[2]["value"] == 2
assert answers[3]["value"] == "最近压力比较大"
assert answers[4]["value"] is True
assert json.loads(res.answers)[0]["title"] == "您的性别是?"

@pytest.mark.asyncio
async def test_somni_quiz_service_loads_from_collection() -> None:
Expand Down
9 changes: 4 additions & 5 deletions tests/test_uburnode_proto_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ def test_somni_package() -> None:
assert hasattr(uburnode_somni_pb2_grpc, "AudioServiceServicer")
quiz = uburnode_somni_pb2.DESCRIPTOR.services_by_name["QuizService"]
assert quiz.full_name == "uburnode.somni.v1.QuizService"
assert "tags" not in uburnode_somni_pb2.AnswerItem.DESCRIPTOR.fields_by_name
assert "values" not in uburnode_somni_pb2.AnswerItem.DESCRIPTOR.fields_by_name
value_field = uburnode_somni_pb2.AnswerItem.DESCRIPTOR.fields_by_name["value"]
assert value_field.number == 5
assert value_field.message_type.full_name == "google.protobuf.Value"
assert "AnswerItem" not in uburnode_somni_pb2.DESCRIPTOR.message_types_by_name
answers_field = uburnode_somni_pb2.GetAnswerRes.DESCRIPTOR.fields_by_name["answers"]
assert answers_field.type == answers_field.TYPE_STRING
assert not answers_field.is_repeated