From 40cabae6f48a97619d027cc67edd4756bdfdf540 Mon Sep 17 00:00:00 2001
From: wkarwacki <wojciech.karwacki@dotdata.com>
Date: Sun, 24 Nov 2024 14:14:18 +0100
Subject: [PATCH] keep params sorted for the python generated router

---
 src/lib/gen/python/server/templates/router.hbs | 2 +-
 src/lib/test/op-params-open-api.yml            | 6 +++++-
 src/lib/test/op-params-trust.yml               | 4 ++++
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/lib/gen/python/server/templates/router.hbs b/src/lib/gen/python/server/templates/router.hbs
index ae51b3b..7e26f8f 100644
--- a/src/lib/gen/python/server/templates/router.hbs
+++ b/src/lib/gen/python/server/templates/router.hbs
@@ -13,7 +13,7 @@ from typing import Annotated, Any
     "{{#if ../../useNamespace}}/{{to_kebab_case ../../feature}}{{/if}}{{@../key}}"{{#unless this.res}}, status_code=204, response_class=Response{{/unless}}{{#if this.res.meta}},
 responses={200: {"headers": { {{#each this.res.meta}}"{{@key}}": {"schema": {"type": "string"{{#if (eq this.type "const")}}, "const": "{{#each this.val}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}"{{/if}} }}{{/each}} }}}{{/if}}
 )
-def {{to_snake_case this.name}}({{#if this.req}}{{#if this.req.path}}{{fmtName this.req.path}}: {{>dtoName val=(fmtClass this.req.path)}}{{else}}{{#if (eq this.req.form "multipart/form-data")}}{{fmtName (add this.name "Req")}}: {{>dtoName val=(fmtClass (add this.name "Req"))}} = Depends({{>dtoName val=(fmtClass (add this.name "Req"))}}.of_form){{else if (or (eq this.req.type "obj") (eq this.req.type "seq") (eq this.req.type "map"))}}{{fmtName (add this.name "Req")}}: {{>dtoName val=(fmtClass (add this.name "Req"))}}{{else}}request: {{fmtType this.req}}{{/if}}{{/if}}, {{/if}}{{#each this.params}}{{to_snake_case this.name}}: Annotated[{{#if (and (hasKey this "default") (eq this.default null))}}{{fmtOpt (fmtType this)}}{{else}}{{fmtType this}}{{/if}}, {{fmtClass this.loc}}{{#if (ne (to_snake_case this.name) this.name)}}(alias = {{json this.name}}){{/if}}]{{#if (hasKey this "default")}} = {{fmtValue this.default}}{{/if}}, {{/each}}service: {{to_pascal_case ../../feature}}Service = Depends({{to_pascal_case ../../feature}}Service)) -> {{#with this.res}}{{#if (eq this.carrier "stream")}}Streaming{{else}}JSON{{/if}}Response{{else}}None{{/with}}:
+def {{to_snake_case this.name}}({{#if this.req}}{{#if this.req.path}}{{fmtName this.req.path}}: {{>dtoName val=(fmtClass this.req.path)}}{{else}}{{#if (eq this.req.form "multipart/form-data")}}{{fmtName (add this.name "Req")}}: {{>dtoName val=(fmtClass (add this.name "Req"))}} = Depends({{>dtoName val=(fmtClass (add this.name "Req"))}}.of_form){{else if (or (eq this.req.type "obj") (eq this.req.type "seq") (eq this.req.type "map"))}}{{fmtName (add this.name "Req")}}: {{>dtoName val=(fmtClass (add this.name "Req"))}}{{else}}request: {{fmtType this.req}}{{/if}}{{/if}}, {{/if}}{{#each (sortOptionalsLast this.params)}}{{to_snake_case this.name}}: Annotated[{{#if (and (hasKey this "default") (eq this.default null))}}{{fmtOpt (fmtType this)}}{{else}}{{fmtType this}}{{/if}}, {{fmtClass this.loc}}{{#if (ne (to_snake_case this.name) this.name)}}(alias = {{json this.name}}){{/if}}]{{#if (hasKey this "default")}} = {{fmtValue this.default}}{{/if}}, {{/each}}service: {{to_pascal_case ../../feature}}Service = Depends({{to_pascal_case ../../feature}}Service)) -> {{#with this.res}}{{#if (eq this.carrier "stream")}}Streaming{{else}}JSON{{/if}}Response{{else}}None{{/with}}:
     {{#if this.res}}content{{#if (filterNonconst this.res.meta)}}, headers{{/if}} = {{/if}}service.{{to_snake_case this.name}}({{#if this.req}}{{#if this.req.path}}{{#with (resolveIfMappedType (fmtClass this.req.path))}}{{fmtName ../req.path}}_to_{{fmtName this}}({{fmtName ../req.path}}){{else}}{{fmtName this.req.path}}{{/with}}{{else}}{{#if (or (eq this.req.form "multipart/form-data") (eq this.req.type "obj") (eq this.req.type "seq") (eq this.req.type "map"))}}{{fmtName (add this.name "Req")}}{{else}}request{{/if}}{{/if}}{{#if this.params}}, {{/if}}{{/if}}{{#each this.params}}{{to_snake_case this.name}}{{#unless @last}}, {{/unless}}{{/each}}){{#if this.res}}
     {{#with this.res}}{{#with (resolveIfMappedType (fmtClass this.path))}}content = {{fmtName this}}_to_{{fmtName ../path}}(content){{/with}}{{/with}}
     {{#unless (eq this.res.carrier "stream")}}content = jsonable_encoder(content){{/unless}}
diff --git a/src/lib/test/op-params-open-api.yml b/src/lib/test/op-params-open-api.yml
index d5e56df..71028c7 100644
--- a/src/lib/test/op-params-open-api.yml
+++ b/src/lib/test/op-params-open-api.yml
@@ -29,10 +29,14 @@ paths:
             type: boolean
             default: true
         - in: query
-          name: optQueryParamEnum
+          name: queryParamEnum
           schema:
             $ref: '#/components/schemas/SomeEnum'
           required: true
+        - in: query
+          name: optQueryParamEnum
+          schema:
+            $ref: '#/components/schemas/SomeEnum'
       operationId: op0Gett
     post:
       parameters:
diff --git a/src/lib/test/op-params-trust.yml b/src/lib/test/op-params-trust.yml
index a27d582..321bf6a 100644
--- a/src/lib/test/op-params-trust.yml
+++ b/src/lib/test/op-params-trust.yml
@@ -34,9 +34,13 @@ ops:
           loc: query
           type: bool
           default: true
+        - name: queryParamEnum
+          loc: query
+          path: defs.SomeEnum
         - name: optQueryParamEnum
           loc: query
           path: defs.SomeEnum
+          default: null
       type: GET
     - name: op1Postt
       params: