diff --git a/faststream/asyncapi/generate.py b/faststream/asyncapi/generate.py index daec95ec00..a713e2d0ff 100644 --- a/faststream/asyncapi/generate.py +++ b/faststream/asyncapi/generate.py @@ -155,14 +155,18 @@ def _resolve_msg_payloads( one_of = m.payload.get("oneOf") if isinstance(one_of, dict): for p_title, p in one_of.items(): + p_title = p_title.replace("/", ".") payloads.update(p.pop(DEF_KEY, {})) if p_title not in payloads: payloads[p_title] = p one_of_list.append(Reference(**{"$ref": f"#/components/schemas/{p_title}"})) elif one_of is not None: + # Descriminator case for p in one_of: - p_title = next(iter(p.values())).split("/")[-1] + p_value = next(iter(p.values())) + p_title = p_value.split("/")[-1] + p_title = p_title.replace("/", ".") if p_title not in payloads: payloads[p_title] = p one_of_list.append(Reference(**{"$ref": f"#/components/schemas/{p_title}"})) @@ -170,6 +174,7 @@ def _resolve_msg_payloads( if not one_of_list: payloads.update(m.payload.pop(DEF_KEY, {})) p_title = m.payload.get("title", f"{channel_name}Payload") + p_title = p_title.replace("/", ".") if p_title not in payloads: payloads[p_title] = m.payload m.payload = {"$ref": f"#/components/schemas/{p_title}"} @@ -178,6 +183,7 @@ def _resolve_msg_payloads( m.payload["oneOf"] = one_of_list assert m.title # nosec B101 + m.title = m.title.replace("/", ".") messages[m.title] = m return Reference(**{"$ref": f"#/components/messages/{m.title}"}) diff --git a/tests/asyncapi/base/arguments.py b/tests/asyncapi/base/arguments.py index 4d5597f232..8c670b2d49 100644 --- a/tests/asyncapi/base/arguments.py +++ b/tests/asyncapi/base/arguments.py @@ -547,6 +547,36 @@ async def handle(user: Model): ... }, }, schema["components"] + def test_with_filter(self): + class User(pydantic.BaseModel): + name: str = "" + id: int + + broker = self.broker_class() + + sub = broker.subscriber("test/one") + + @sub( + filter=lambda m: m.content_type == "application/json", + ) + async def handle(id: int): ... + + @sub + async def handle_default(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + name, message = next(iter(schema["components"]["messages"].items())) + + assert name == IsStr(regex=r"test.one[\w:]*:Handle:Message"), name + + assert len(message["payload"]["oneOf"]) == 2 + + payload = schema["components"]["schemas"] + + assert "Handle:Message:Payload" in list(payload.keys()) + assert "HandleDefault:Message:Payload" in list(payload.keys()) + class ArgumentsTestcase(FastAPICompatible): dependency_builder = staticmethod(Depends) @@ -616,37 +646,3 @@ async def handle(id: int, user: Optional[str] = None, message=Context()): ... "type": "object", } ) - - def test_with_filter(self): - # TODO: move it to FastAPICompatible with FastAPI refactore - class User(pydantic.BaseModel): - name: str = "" - id: int - - broker = self.broker_class() - - sub = broker.subscriber("test") - - @sub( - filter=lambda m: m.content_type == "application/json", - ) - async def handle(id: int): ... - - @sub - async def handle_default(msg): ... - - schema = get_app_schema(self.build_app(broker)).to_jsonable() - - assert ( - len( - next(iter(schema["components"]["messages"].values()))["payload"][ - "oneOf" - ] - ) - == 2 - ) - - payload = schema["components"]["schemas"] - - assert "Handle:Message:Payload" in list(payload.keys()) - assert "HandleDefault:Message:Payload" in list(payload.keys())