From 9ebe6b1c68f4fc277f9d1fff22343dc2c818a8ac Mon Sep 17 00:00:00 2001 From: Gustavo Date: Thu, 13 Aug 2026 10:28:52 -0300 Subject: [PATCH] feat: pagina do gerador de chave manual (client-side, sem gravar no banco) --- app/routers/chave_manual.py | 19 +++++++ app/static/logo-gti-256x256.png | Bin 0 -> 12541 bytes app/templates/gerador_chave.html | 85 ++++++++++++++++++++++++++++++ tests/test_router_chave_manual.py | 24 +++++++++ 4 files changed, 128 insertions(+) create mode 100644 app/routers/chave_manual.py create mode 100644 app/static/logo-gti-256x256.png create mode 100644 app/templates/gerador_chave.html create mode 100644 tests/test_router_chave_manual.py diff --git a/app/routers/chave_manual.py b/app/routers/chave_manual.py new file mode 100644 index 0000000..56abdbe --- /dev/null +++ b/app/routers/chave_manual.py @@ -0,0 +1,19 @@ +""" +Calculadora de chave de reativação, para uso manual (reenvio/correção +pontual). 100% client-side (mesmo algoritmo gerarReativacao já usado no +workflow n8n e em Gerar chave WEB/index.html) — esta rota só serve a +página; NUNCA grava em Clientes_Chaves. +""" +from fastapi import APIRouter, Depends, Request +from fastapi.responses import HTMLResponse +from fastapi.templating import Jinja2Templates + +from ..auth import exigir_login + +router = APIRouter() +templates = Jinja2Templates(directory="app/templates") + + +@router.get("/gerador-chave", response_class=HTMLResponse) +def pagina(request: Request, usuario: str = Depends(exigir_login)): + return templates.TemplateResponse(request, "gerador_chave.html", {}) diff --git a/app/static/logo-gti-256x256.png b/app/static/logo-gti-256x256.png new file mode 100644 index 0000000000000000000000000000000000000000..574db002abadd86b930f1d6fc3502cbd9941f749 GIT binary patch literal 12541 zcmeHtWmjB5v+ghq?jGFT-95NF1c%@R3$B9(3BiKP;1WEzI|SEY!QI{U&U?;Tcdh&F z{(#e8y1IAoy=w2>T~*Ih6{W5!hlWgq3;+Po6y!f@0st^j5e9$=gm$x-;+)V<)kU|d`g;HYLuSOFRg`fHc7UF(Tg*yYtRH zv26r{<@Wn@K%kKgKTtO|MwyBmOT8chP^a4l5&XA(%ILFT(#4ygsYiH6Kp6ACanqGC zh~YraFn`VnXU<$h(fIKiqq<4FxtPxlXps*Xqbk{NrNGpJT5;d>9b6* zomU>x4>!DCVqfz&Lj|>fK!gJUVA`n%QoBN_-=Eb*n-$@qns$UFJlP`K+hG`OU(95z zs>$fw-vwig^vkNhUw%zS&)Gz19rpNsL=vApv!l9IZ6(+Q1P8c-U@BxFzC*_AHY>d0 z!)m#j2~-O<5xhy>4`=oxKYm7HNwc2y=P0M1$sGS5hSVzI&s4Y%+P?9Ndx&;t7Z&-e={zA&0~30&Op7_q7b)ew7G0-#X%;76Z!V@Bgby1M@# zwc%H20c6LO0k-<{p(BX5lDE*6xu7#F2{(U(!TPVjjKvjK%MN5jOxpHlTD){j=wDf( z0j3#N3;g^t~X!XX5Sq)!I8kpp3Fvm@tw9cL8AZvSfS zVcIhl8MF45EO&ALjTzKEyGmrArW0^mx<6zSORfxNVA63|<{s7JmAi-oD}mzY-j_s7 zGq23VC6SU|7H48hcNiW>V1h{*=m5I!x9n)lej1(CZyM2s+|uDg`$fG;Y!tv}bya{} z_QI0CkYM*hAnd~eI&N8$=4KQubkB}JPw)FTy|G_n+P;6*C0_SG&N9NBI6p!! zKfT-Zkcg58)Zu8X$S_cYKTBUPpd4yfI(r3J+>*nw@Kz|}9yt_#qB?qqfZCjAU-c@& z0DBET23e^KWzITPz$fwno;2BHf7Tc2le0_TgD@{BPRbEZ(n*}o9nZS?jh0k{?cxL7 zl3{#lLmFh&3K>)&a^35;68gsFmHAvA1+BX=b_m#DG(f zR3t)ht0ocu+Ju2^fNbn_^_hnoz`VU+BU9w^d3zkOHsK3K`O~W(?-B8E*>w^Zk!wAp zPAbKxmN#WW|2P>aq<@Q>HWFuVKY`U8K;3t0yFPTx+UMCm&J^o*k{9yspK?|5H5(-E z2X_GV5DDLSGVMSUV23aGaG!8x;7jj6`*NOxJD{ZDxv432 zL&N8X=>lRkV{H?9<_HFoS6ozF5Dp{<2ZA3nIoi*Umw(C2qoyupqB!4%Dd0!-xZ6YU zD<{ZgLh_B4c!}HR<&fpg9X?3N*vCT6>UUFI6w6w=8Y>9^+-dV+Z}ndj2DzAs>8IA} z8kgIVp0nS?XUT_rwSl;SS`QEwv1tze!^WZI?y= ziWcZ;@RwdLu-}>-0A$qixlf-z@f=-#jhPSnm|*_+`|4RZaJ9?gw77lOLAS!BtI}*C zJSLSfx|beYY*&=Bn~iKw?zXR+c{j#WaVBRY$2HYX^LR+`Jk9vVMsHi8$vc>x6y`Nq zX!w#O2=;jF`-XSDKc30wGZJau_e6L1BQ7cy5e)@(%J$_2_LWz1xqB*iqh=%iPmRmN z8W|{_t#FNK{-%i=35_Lx2QXXac&MD3Nwg1&cN*i#y{tx^j0>`g;BJ}jWgd>)S2mkO zA{qVqN4?DV>htL@ojx&A5-gI6>wAowYm}S&1vrpIG$In|)o@9|%oN z^_)9Px&bz<6KuwGHW{$<GbY)uvU}VY$^^jIsp=v4VpC3HW!HMF4yB75T8KKGmBr{I{ zTQ8c3(@QsX5d!f%8n*KH-GpiGP~OMm$*!A&Wi(t=ZGLTc7VTQ?(fHixO+=CfINP@V zAp*yL)*J$*4u^>E`_2)&tCHsO!gzn)+@E<&m1QyCFS7iqH_w5}V3d9KTmo|}clitF zQ4l>qVL1T+yq$0U!jn8l*b;OB&)s)xCz<;vmve}|C81UeC@;qA7nsCf9Ha>1aC%TS zbG6EgF1~pp?|dc;BPP;{_mIPjO-9RtrAZg|n`rYo|Co6+sNCt7HH<2wl1`r^<2KNY zlDYfumD-%L+o$wP+j*}R2$Pkm;(XX*(-Ii05^FHiEP1Bsy+?>(xID;cU;Fza-m z`0(vssO_qpW_;+P21uf2XG*=Vt9^W7#rfIfpz;ogG-y1_z+MqpPX!3f7`s7@w|3lF z#Jjiks{njs$*nV;$(Nz3ay8-=fyNUuzQ}RYAN(%hw*5U%gIR*U1?k zT%-VuTA^z-c4_rJ3ExD`P+$b8Srv6qQv#HpvERb&;i{QMXmHnpR|jE4!Z5SX4ic!T z68-T5#DwHZ5PZ`5W{}5rJ3y^#FFF25`VZ*jV*dAM#oiHuO@a~F}POFnyVyuc=2ZIkkt1)w5r;uSD z7Ss-CFFhmHMWg|~t7gr1uC7S!OvJT6U~18kRZpfZpXV#pazuPypFIA~mb7`D9%U}J z?GD$@4BHg(kMnkNdKVGvLGaASVt2}`6&m&>#r17r=;<^4&X}2e-A~~)QIPEEM0p!( zYcm9_R zZn#xc!@s_x&)ABSi*3!b;_}QCJ=*`G22+d!ukc|)l!?FnhWA}bb2aN9;-i=Fwq=-W zW4J{(*8r=f$k4s53VXHo4}@A$Ji{Km#7|L%!vCG6ySzeYAGaL;kv|Juy6P*vTMh+~ z3^m}Y2uRJ|K)1a~hp*7e>vadf_;YG2*#&fw;^bAnG^^c!bfnB&c9i`j5+Sv+&4 zE@YV*h+w^7ofr6{S>nz0-_*BuLV?evt$IPX2lKE;dMVbWLmLvS^^96Fe#w!h!~EC# z2zIbm6Wt9P#5ZTt1xGTm`t3&NtU&d$Pj|~?Eq5!Su^#A+ijU)0`JpmUgY|Ou&zb%^ z>HTnb-1ChhD5=;lwJJ)~7oF(gGR$>5P`}w_HUiCTT~FN4dR3~*pn*t)mKXUam(G?b zCx5L`h$pV`dYrLRJ)#lj9xeXhIg9%9@56P`{_YjCqyuZWXcWLiA3mP+Z(2T997}11 ze+DKofz@B28PIV#lIlf(s=Jlf!4R8*lI`p*RD2-cnJB6KFR)M_al;oO#<3Q>@%A*z zPW>$oa5(++_)Q5%qGmPZTi7Ig<%Za5!K8ti9q%G4tVl@VM$5(@gbVdDK} zAHwu6Bqkx3sV*%WGlCuK?Cw}yd4Rk+S?1`M-$ys+?_*hFeR&_Qpx(#wRqP04BQ%U) z^Y>AloRo>_H#7Z@DI%D+n-rvk$u}-($X2o$ej?6TGI`=!<_rNv`9Fkv^0BN-xE!VLRui-> zP0T*Xw0KSk_i&7bH@?SIq=Nn*u4`gxUDw_~cEJ6yjMFfH7QGr0QhhQ)n}MY8)Eda! zGxRRxrXUR1Qj2HHXQgUQ$Fo(-+A0Y(4kSFSi|xeq#l_Y)e>5(3=J$tWhrp6Ar~Y$j zBPUr~u>+_x)I1)cLMBeudQY1T9#L@!jE)4;UW}V$c^cGW)#c?$4#}9^Qs9N;n?wOS z!XI*#x$*(BY34F&XK0D%;(_m^3n zDT7;~`bs&u_t2bwbW4TrrFvj0!kM)y2wGikxY+A9a^<-kF1SKySSZmuFHy^h*6pOG z1dHJ1Pi%ziPwmN1m|DO>@(!mVaUfS`#`%q^;Ea={%I91dSU-<*tct&aMDS!!hnUe) zv(c!fa2F%G@adZow473>(q(tJSOBrqUH0%2b*HL&OQ{@9eQznpmxgk^fjv?BFhIT) zmr(&fU0?8RR@L@7nHc^Ysi3Ig<4_zKj^Pb4HZal}h}iDh^sPkNMlKXg)D+8CO<(^39vX>$ z5`Uh}%Vzl)a?Km~Chp&*&Qq@6qXgnm`$ksK|2nYcv3EnrVzQPRX!MPO&5+NzmYFRK zfL$Z*E;1adh4j1NCVkUg6=doo*-HK66nv(nHCK^t8p6YTg519v6g(4>c7MJ;`sf`4 zfQr)MBe#3an$y)AHrSe7LG zY!zsB(g`ODkDHkrYgcN1`rAHm1g$Lu!(`~De%uNUh<{7x?)1Lii?ub-KKzSMA=8)b z9H2lGSbt97UxG5#ymPz7JLSy^YPS=)L2>)O&2IL_T!Q(T>!mJ_-K0G}<}ye||lVl>hB4Lw+1 zMya5MZ2kgF6hP z?AdJh?w_|O)*1|(3FDEZB(5VC*zWci9sK(Atze-7PKEs7JdU~`3=ZyAN!h5CrfCai zL~+9>*s{na-1fWjTo-4>(edK|U?!!)r#8e#X`s{7!7A8TzFu4M$UwGw^knpf;Q`?7BMO_E&x3PVeKj zTS!o~aYw7iwKXkCcL9H&81W}fBmc`@xMTkv(9q^Wo7b7Zuks&s05Uh<_mz4-6X~sMe z87Wzd{~=eVErDlBFQSy49V23vl;`H)by6^SSHQDwy$zzEZ`ddSJ0m3^<#gM;fI1*?yo2 zZ)?eT(9e?0qCq)@q8Fj=+ zeS4cPQTsM%k=tPf%p;vKCD5y`I1TmloO`{~dtf|-qM9+HMT=A*nKeuWuj zDEpM|cM`GuUHSY1L)2GyL=(y~Z&C0)e*XhJ3?@hk;M#NBZzvVN-CaMz1Z>-IE?+EA z7#sOW1R_!{yTOE-ZId7I_MT;@#SHAH))Zg<*yszZ&vm6lpU%Ctc&g;RhMJV{aWIQY zyYG68(3>(cYf%*lND6;7$go{J;_>Ch>2B-hPH-aUWI30lea;(acX?1{Sy@AxtNIC; z){gEfv(3|X{C57KE3sEJJQ&$md>qAhYl~c*3qi!A>}srWev78fp~n%sF+{gYzidY~ z3}6C724?;zX#+YOPe2V&*!rSHlZ`c|_oBz-!;CKRN%2>bt?B$Zw)a&MkNR%J%AcxV zy~XhT?lTWa4@|V2bciq_NEOfI_}m7Rdzg)+>|3gHK{UzupO;0XKD(k)$px29Beai3 zZPV8q9hp_bN#uV$0%eRJCB9mAW}Y~sepvj~6}+H!ucBO0S&4@PBlICf{$j8J_SUYa zlkL@D@eRrBy-ky;UHX>2+T&!Q#JODBZ1L@o2%>&Tzx+I|^E^aUXFXAGz-WH&Nin|K z=3ZG^YJ2M$1|Wl9i-(8fntoBaE5P7pIc973W5ZiBm?C@dzdh1v3S*lu7bR7oDLsYS ziG`Qj)J6CfEIdP_>CJ@N>1lrFHC(7JxSDXTvfF!DKMC>^8snZ8YUsI(em9A|?>}De z=Po2;Qm_boz8DHMF=U-~!_(JH-C>({ztiK|1AI|U5BWhM1yBPTzN?M4H&L2qCgP&< z&?|cT7_znZ(I>6F#_Y4>Vgo*bdqTyapr>I`7Pzysby#1C%v|{UH&+5?E_LuJ1SPYB z(EUkTEpl66u+=vYXL#C>|AgS!8(PtxQolJJqTl0R#)Co^&k+B^C z$0_oNQwiO(;&CkbB4ooYr!(YblZd=5$8?=lKb6jIhNqBxI|3!v1ChT4Z+b8#$kT5K zI*s%zRC)@T(>KdCIjJ!*%gmt6O=GeM8$c5Q@lX2`l?l-m+7fWV5E0k>L??9tNrK#^ zE-%Ppgp<0h1e86|ojC+$k?@$A)qU|G0b_Q5t?};8jL1(H={$i^DkqO6j)+ta&>A)j zZ84m97BS}eJqu(K8Nz#H&Pjh98dtqA|`@N?3k;pp{nBA7$ zC>TV?2QO8&dvTL@Kn1K5W%`+2E@lvZHnWx9&&bXfp{_K()z4f}Rq`10^s$j9;x7_MR`FltQ7$y*2xOV0udMx5dA#0q+hgXi{aL}O zs??Df#YgBS`=6Ju$N99qmsb72e1_mQO1PRiT{j#-Z-Lqe@wLsp@sYDqI$*nB)nx3o z2Jo{I>HAVbZ{4wG@M_dMDr7yVO=37q-9Y*q{I?4IPLeJS!N69uu~9{u!*S9 zJht!OqohKe-d{-vWc4g;H@}Xsnd&yvaPcsB&qYo$Mq?wvdD`?tG1ow z|8ce9y{)%Xy&2W^=BOKd-{_b~7k%z|MaYNcp@ z9v)HuTxZd1-oZY{P`|w?D@YU;WLt-R5rjnCyKlnDw0M8VfB3u<_fU`t+t(*fsAuY- z#LCX7#RLjJ8(LXe1q6sbz>|zl^XO<@FEo@dG&-;HK@oQ=fc3ySd?sqJ%fiBWU5a`M z`PK0SQH=?bD@yW{6$PHzY5bQ?zSR)@u`Wtf8L&DOGq(VT>_+sVlHpY7B=OK0mc<6) z?o^KqPb#qOBFdr<^ese{l*eo%EummAmQdLJPrO(Mwk5TO8akif&u?%rS15|LbxQl|eZG{_{nEkePr|nlOH8<=pXMVzYw77sUw;7NO3UNLww{Y&j zpW%^Culuua800sxPhRJ1t1Vwk%%1P;l1gsQmW~gT=<{I>BcU%lLr88-r%45SNXDyNVI}~+}5>vHkynU~CPc`x(X=3N&vNwB& z2}M9V`qzem9uixG#KJQ|rTeaJ~?3)L(I zUiE6BDSZ2KI7%nVjTftwtzjX#asq{lnXIoYv0U-S^`wnSlH8CbJZV zIEQ0Cn5X-*Hs^DbP?!N{ce1!~!5VK;HlZ+nUI$^AZe&F@6&wYWsRU3w&~BQMsBam@ zf7ho>-rvwyBw3Vagq+6h??|#4;r1(~=p3$@C2Sg>)7S?=R9!>ee>{AA=)_m)y^{R< zaG}Z(L40#n=CX(z$v;DJ#j}eoWAKs5)!i}eoI#U{UAryg#4(N29&>w@Xu=U!>FXDoz(%2Q!J-wc)0!h#Niw5JJf!5J&mb6+gyS zzIX3|*VBPDI#@Nl7$73$!wpj7fKkHcV1*J2f6I#JyRA%G{NX+q`2!}Lq_(jGVeA;o zs3^hrh+tUOV*B(H#MxThx~-ueHQ_=aiw4BO-hRHy;2BEK)DDFBp;{K5n(wIm``2lO zvaDQLNA4owo(e@?r;<*djcgLkTB9BK0J5()`_zW2nOcM}YresNt2drcLdG`G>=Vhn zcxmoWR9tG}G1! z82@n!m*2)5w;LrYe*PvXBm(reI2mDPiSYTTCPe<3Am?&0mY6R*_#Dciz`;VXeqt8H z0sz1?`A;nXU*qGR1Rs(rz;w%575tQ{oij8KyK&J;8c7 zHcVSrM(zD?OApaUE(%{fl4W#;2d%%fx*Ce>%b~pgRyazV=h=(hW?TS{pENU8rFR6J zJ&5PiE{X*So(_72p{CK*EQWaC)n#sEJVz`tVg>Fq|MmC!dd>n_wHyJvnXo9;nV$+ta&aVf3rU{9bxQCO&^&0g06*ySS{%!0 zto*?Yt+(Fq3d8_whGiPM0f-526rT_G6^^G#j5*(~OSF9{Cp73* zeycAbA?a6M;_GINs}II@)$mC;E7ZMzoLF?H?%CC+?hH*~?%nZ9olGOJ{DUr? zC#3~Djm|j?<15cd^t15X1w@L#3n}LQ98P#`nVuY=?AK|b#D9esgy>wJ@nv;wy0LT0 zVu6+3MVe&Ss>fy`OQRDj374!x?X-Npub@pERqko=vDze}8cU)+CxC(@)?$^q^9rbE z(r?PPF;Qu)W<`v_&UIpHws>E;*$v#zgD98$e%#{qH-PcF2E3PQS5#siMBw{8#m61P znW4Wt^kFD^MkdS_#iaH(8c6=2Xwp8-`TB1YT7$7+Xv(sW8q!{nUj3)Tiqm`-O8-d9 z$jBgI2q}P}fckG&5PNG;A}7q-!|S~ZTyX6U+0E;-I)zZ@c0~eua5Z)}>L|S5cwz_X zLq(F>Q-eN(7yik^WY-(UcO3dvpFGJPiXRE)n?bE@lJK27<^$5Swcb|zX0s8o`OKt| z@2Jqg@J+BgM5pG9Uv7|ulw;O4C+Uh-)#oAPw(eM24;>GPNtB|IISddI)l zN=d{GS~K7Y1A{u0Sdq=33c7kgnr2P@j->wh;0nzf;57o&e~Bo8s_p{aA@G#oRI@0w zR(cK!ibh@_MP~o{+YSe9ck0iS6sB_|IAF!67EKyD%;0ZexZ|BDoZMwRS)9YAj-i-+ z+j~yES2O?Wn>n8FVDHPspV`8mktN_~3qQ-{~ z^*v(mHToZjNuNCB|CAv8__5u_JX(3^R#oN|=JiF49jYBg zS`(7rTAK|!t*4->c@L!@iUx*;sbf#a#ojOW2D4m#tZLWGR3p+5=7Dh`H|E52m(pcCkt^5TBC;R>1l{(-^p zH`HD8R-BDOD}es#3IL$)5}bTocVr*l^K6B_(M<`>@K#+SL7CBs$?<<0HI~lil){|tSQtmz83en{b{acn6=c_Hu%a{PA#n4$O=|om2t|GTTNThpTaJ{wJ zCdP_Lli2oq)cz8-I)SpO`SRJ`y7x0sG&efdtlGSObevqP^=nCI>pc6ea1`4=`JkiEU?vzisR zV8T=3#Nh5~*s|Qgjqnf{04$KbJLmuhqRRs0oDRZSTrI6|87{&B@j1s%qYu!pR_kIbwS;_lTRWUZB7q(_bAuqe6#RUq$v=f%!SFR{vM3-9|cXafE@w&k;)I9>6 zjzq!IC~dM}T(q`#hvV4??(~_NAKrPjKg7GR0@N_JR11g2f?FKDeoQYVJZV?j?H3k1 z(IQZQF8FG)zAV)n40|S!sdzVkSaF)S)X);##uU{q4ghFgK0zW`<3Rezr~g&n*-zJ zN3H6VQA6=<&q+kpz3ljT$W7d>5wU>osQM|dz7s}zXnA)(-_rEWHdd;w>nesDU9O%^ zUaB^9e}4;-K%iB?dutsvUF=Ui-C%d#XaBOx?zGA7jAIb$@{aqdE&`1hzlT*3jUyo+)8S9$ON4NkL-Xq=Oe~i^bh!P|3S-rr7Ve z$!zC8%CFM`ajRixW1!f>z$|Hd;F^Fs0v%<>R+N-PPjxXpBE{w$b+`Qb%0^Qhi0+#aX&LwFU5ztY)Vp;Q6jR-PHc&rPkuEehXoe zxG<=Pe|>IYA?B{g6zCZ;St(my&K1|rN?|aqi-UWf14!!!yjGA&E7=Z5?fH^yAxFs z8>cJQi>+k=KX%zHIEDM&)o8NE);-ERlsu&l>U3zF`&pNkx$t?N7hdFN1!<3wDOsfS zhXnNQeB7+DfSwE{k5ImOLVk1@=|~vZL-Y)b&z>O=BkSK%P>^RkOS%{OXhJf2mW{#& z%EqJA&fCDX_!9mR4EV~fu2oinFEWib7z@dh1dq8~AWuD=^Q%1`Ijoei(9wT_V8Qbx zPvPz?QX)d>LzUnnryA9mhYe_|eCAWn%T3KL7RK8K&(^WZw?21Ed^%@lwBwfA5MZFCr0j0 zi0ayfd3e=D=!Cx;EDyvJqg5ed#;IahusaRi9=|X`Q8(E<7FJA5jLmq~5^Ekxq@%4m zhdztjP?w5`dYb|nVRtPVSZU(~{oo(F&m}ZV9b9C#WN&CNOcS&9s51M*HTOi)g_yvr zIPs-tp5KuSUXdW1nwRe7l-ga>MyM>w#fn~t!6VeIYd5%BnLeQ3iIkG#c28tom$)fT zlI&XTy*TiR;C8!fDpkAE^`Gt6RN9r=#@;kiS@tJ_Ca;w1-7X@NP41>+UKn+<0A z$LS@kh}%#>pIng#}!9Hf|;3_|I4C)=bWvXR3sas2#CZP^8t*LLqku0eL2P9 z&y^=KCq<-#vp(v4o0mR4Q;Rna|Iw87!YIj?@52;XtBopTttL=3@`@f7-t&A0 zPjjI;ENt=NAx&Q%sn*qaYb%(3waxQ*wR{1JWw>X#?(p$VTHOzI#+e0~y*`>oP%F57 z&8ahcRdKmUVr~)4K(9m$19T#0J~V$o?Q0LXE{3+&)+Yt4T}z}XU2V~Tr>ou3*49>N zb=;!SZbr{GYKjNP!|ZTKnziwj?(rwbk*WH-qB8FKrPGYcIJ*XS|JhjYh29WM-~$iH z#8z;7U2vy}yOS_-WI+P)qA3`8J51NF|T>!Kx M$f$m-k}?bVKQWeKL;wH) literal 0 HcmV?d00001 diff --git a/app/templates/gerador_chave.html b/app/templates/gerador_chave.html new file mode 100644 index 0000000..f6d9042 --- /dev/null +++ b/app/templates/gerador_chave.html @@ -0,0 +1,85 @@ +{% extends "base.html" %} +{% block titulo %}Gerador de Chave de Reativação{% endblock %} +{% block conteudo %} +
+ GTI Grupo +

Gerador de Chave de Reativação

+ + + + + + + + + + + + +
+ + +{% endblock %} diff --git a/tests/test_router_chave_manual.py b/tests/test_router_chave_manual.py new file mode 100644 index 0000000..d4a786a --- /dev/null +++ b/tests/test_router_chave_manual.py @@ -0,0 +1,24 @@ +from fastapi import FastAPI +from fastapi.testclient import TestClient + +from app.auth import exigir_login +from app.routers import chave_manual as router_chave_manual + +app_teste = FastAPI() +app_teste.include_router(router_chave_manual.router) +app_teste.dependency_overrides[exigir_login] = lambda: "teste" +client = TestClient(app_teste) + + +def test_pagina_gerador_carrega(): + resposta = client.get("/gerador-chave") + assert resposta.status_code == 200 + assert "gerarReativacao" in resposta.text + assert "Gerador de Chave de Reativação" in resposta.text + + +def test_pagina_gerador_nao_grava_nada(): + # Rota é GET-only: não existe POST /gerador-chave, então não há como + # este router gravar em Clientes_Chaves. + resposta = client.post("/gerador-chave") + assert resposta.status_code == 405