<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="http://hefay.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="http://hefay.github.io/" rel="alternate" type="text/html" /><updated>2026-02-25T20:21:28+01:00</updated><id>http://hefay.github.io/feed.xml</id><title type="html">Hefay</title><subtitle>Jednoduchý blog, který prakticky nepoužívám. V minulosti jsem blogoval hodně, ale ty časy jsou již dávno minulé. Asi není žádný důvod, aby sem někdo chodil, natož aby si tu něco četl.</subtitle><entry><title type="html">Konečně jsem našel přístup k technickým normám</title><link href="http://hefay.github.io/technika/2026/02/25/sponzorovany-pristup-csn.html" rel="alternate" type="text/html" title="Konečně jsem našel přístup k technickým normám" /><published>2026-02-25T20:18:00+01:00</published><updated>2026-02-25T20:18:00+01:00</updated><id>http://hefay.github.io/technika/2026/02/25/sponzorovany-pristup-csn</id><content type="html" xml:base="http://hefay.github.io/technika/2026/02/25/sponzorovany-pristup-csn.html"><![CDATA[<p>Kdo někdy potřeboval dohledat konkrétní detaily v ČSN normách, zná to peklo. Buď člověk platí nemalé předplatné za ČSN online, 
nebo riskuje stahování pochybných PDFek z pochybných webů, které jsou stejně tři roky neaktuální.</p>

<p>Narazil jsem ale na věc, která mi udělala neskutečnou radost: <strong><a href="https://sponzorpristup.agentura-cas.cz">Sponzorovaný přístup k normám</a></strong>.</p>

<p>Ve zkratce: Agentura ČAS (Česká agentura pro standardizaci) umožňuje bezplatné prohlížení vybraných norem, které jsou pro veřejnost 
“sponzorovány” státem (ministerstvy). Typicky jde o normy, které jsou závazné v rámci nějakých předpisů.</p>

<p>Stačí se zaregistrovat a člověk má okamžitě přístup k fulltextům přímo v prohlížeči. Žádné složité papírování, 
žádné faktury za každé nahlédnutí.</p>

<p>Pro mě jako pro někoho, kdo se v tom občas potřebuje vrtat a nechce u toho porušovat autorská práva, je to naprostý game changer. 
Pokud se pohybujete kolem techniky, doporučuji vyzkoušet – ten seznam dostupných norem je překvapivě široký.</p>]]></content><author><name></name></author><category term="technika" /><summary type="html"><![CDATA[Kdo někdy potřeboval dohledat konkrétní detaily v ČSN normách, zná to peklo. Buď člověk platí nemalé předplatné za ČSN online, nebo riskuje stahování pochybných PDFek z pochybných webů, které jsou stejně tři roky neaktuální.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://hefay.github.io/assets/images/hefay.png" /><media:content medium="image" url="http://hefay.github.io/assets/images/hefay.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">TODO Board pro děti #1</title><link href="http://hefay.github.io/2025/12/24/todo-board.html" rel="alternate" type="text/html" title="TODO Board pro děti #1" /><published>2025-12-24T20:20:00+01:00</published><updated>2025-12-24T20:20:00+01:00</updated><id>http://hefay.github.io/2025/12/24/todo-board</id><content type="html" xml:base="http://hefay.github.io/2025/12/24/todo-board.html"><![CDATA[<p>Doma jsme přibližně ve stejnou dobu narazili na nápad takového checklistu nebo TODO boardu pro děti a hrozně se nám zalíbil.</p>

<p>Myšlenka je jednoduchá. Děti, když přijdou ze školy nebo školky, vidí přímo na destičce, nástěnce, kapsáři nebo čemkoliv takovém, co je čeká a co mají hotové. Až budou mít hotové všechny povinnosti, tak si mohou jít hrát. (Podobně se to dá využít cestou do školy. Tedy aby si vzaly klíče, svačinu a podobně.)
<!--more--></p>

<p>A jelikož naše děti mají rády různá světélka a tlačítka, tak jsme se rozhodli jim to udělat trochu v jejich stylu. Řekli jsme si, že úkolů bude maximálně 8. Máme tři děti, kdy každé má svou sadu úkolů. Proto by naše deska měla obsahovat tlačítka a světélka ve třech řádcích po osmi sloupcích. Na konci každého řádku by pak měla být nějaká konečná informace o tom, zda děti už mají volno, anebo musí ještě něco splnit.</p>

<p>Výsledný produkt by tedy mohl vypadat nějak takto:</p>

<p><img src="/assets/images/board.svg" alt="Koncept TODO desky pro děti" title="Koncept" /></p>

<p>Možná si teď říkáte, proč prostě nepoužít tablet. Důvod je jednoduchý. Nechce se nám a ani nechceme děti vázat na tablet. Zároveň věcí na baterie máme až až, a tak by to chtělo napájení ze sítě, ale nějaké bezpečné.</p>

<p>USB nabíječek na mobilní telefony a podobně máme doma dostatek, tak by nebylo špatné, kdyby se zařízení napájelo z USB. Pokud pomineme PD přes USB, tak tedy počítejme s 5 V a maximálním proudem kolem 1 A.</p>

<p>Původně jsem chtěl objednat všechny potřebné součástky na , zejména kvůli přehlednému vyhledávání a datasheetu u každé položky. Bohužel to vycházelo o hodně dráž, než jsem byl ochoten obětovat na takový malý projekt. A tak jsem objednal součástky na .</p>

<p>Základem objednávky byla vývojová deska ESP32, step-up měnič, pár multiplexorů, 3× zelené signální světlo, 3× červené signální světlo, 30 žlutých LED diod, tranzistorové pole a pár rezistorů různých hodnot (zejména kvůli nedostatečnému popisu LED).</p>

<p>Měnič je potřeba zejména kvůli signálním světlům, která vyžadují 12 V.</p>

<p>Dále je nutné v nějakém hobby marketu koupit překližku, ze které se vytvoří krabice, ve které tato elektronika bude žít, ale to si nechám na příští příspěvek.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Doma jsme přibližně ve stejnou dobu narazili na nápad takového checklistu nebo TODO boardu pro děti a hrozně se nám zalíbil. Myšlenka je jednoduchá. Děti, když přijdou ze školy nebo školky, vidí přímo na destičce, nástěnce, kapsáři nebo čemkoliv takovém, co je čeká a co mají hotové. Až budou mít hotové všechny povinnosti, tak si mohou jít hrát. (Podobně se to dá využít cestou do školy. Tedy aby si vzaly klíče, svačinu a podobně.)]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://hefay.github.io/assets/images/hefay.png" /><media:content medium="image" url="http://hefay.github.io/assets/images/hefay.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Hiding In The Blue</title><link href="http://hefay.github.io/hudba/2025/10/30/hiding-in-the-blue.html" rel="alternate" type="text/html" title="Hiding In The Blue" /><published>2025-10-30T20:20:00+01:00</published><updated>2025-10-30T20:20:00+01:00</updated><id>http://hefay.github.io/hudba/2025/10/30/hiding-in-the-blue</id><content type="html" xml:base="http://hefay.github.io/hudba/2025/10/30/hiding-in-the-blue.html"><![CDATA[<p>Trochu hudby na večer.</p>

<iframe data-testid="embed-iframe" style="border-radius:12px" src="https://open.spotify.com/embed/track/4uhajAtJz72BBHkiIUvr7v?utm_source=generator" width="100%" height="352" frameborder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe>]]></content><author><name></name></author><category term="hudba" /><category term="hudba" /><summary type="html"><![CDATA[Trochu hudby na večer.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://hefay.github.io/assets/images/hefay.png" /><media:content medium="image" url="http://hefay.github.io/assets/images/hefay.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Tichá láska</title><link href="http://hefay.github.io/poezie/2025/09/06/ticha-laska.html" rel="alternate" type="text/html" title="Tichá láska" /><published>2025-09-06T21:34:00+02:00</published><updated>2025-09-06T21:34:00+02:00</updated><id>http://hefay.github.io/poezie/2025/09/06/ticha-laska</id><content type="html" xml:base="http://hefay.github.io/poezie/2025/09/06/ticha-laska.html"><![CDATA[<p>Někdy se těžko jí, někdy dýchá,<br />
někdy se těžko sní, někdy hýbá,<br />
někdy se těžko směje, někdy žije,<br />
však srdce mé jen pro tebe bije.</p>

<p>Nejsem samý úsměv, ani nechci být,<br />
nejsem vášnivý, neumím moc snít.<br />
Život mnohdy nedává mi smysl,<br />
ale bez tebe bych ho neunesl.</p>

<p>Nechci se hádat, nechci se přít,<br />
chci jen pokojně vedle tebe být.<br />
Nechci ti sloužit, nechci tě vést,<br />
toužím jen břímě života s tebou nést.</p>

<p>Často šetřím slovy a dotyky též,<br />
však že tě miluji, to není lež.<br />
Často jsem zamlklý, nemluvím moc,<br />
to proto, že slova mají obrovskou moc.</p>

<p>Často tě raním jen pouhým slovem,<br />
neříkám přitom nic s nějakým hněvem.<br />
Často tě raním a nevím jak,<br />
ty cítíš se, jak přejel by tě vlak.</p>

<p>Já vždy jen chtěl, aby ses smála,<br />
já vždy jen chtěl, aby ses nebála,<br />
já vždy jen chtěl tu s tebou být,<br />
já vždy jen chtěl pro tebe tu být.</p>

<p>Možná jsem unaven, necítíš něhu,<br />
je chladno jak v kupě ležícího sněhu,<br />
však moje srdce pro tebe bije,<br />
mysl však lásku tráví jako zmije.</p>

<p>Tak už se netrap, neplač po nocích,<br />
i když smutek ti nevidím na očích.<br />
Tak už se netrap, neplač zas znovu,<br />
miluji tě — to řeknu klidně znovu.</p>]]></content><author><name></name></author><category term="poezie" /><summary type="html"><![CDATA[Někdy se těžko jí, někdy dýchá, někdy se těžko sní, někdy hýbá, někdy se těžko směje, někdy žije, však srdce mé jen pro tebe bije.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://hefay.github.io/assets/images/hefay.png" /><media:content medium="image" url="http://hefay.github.io/assets/images/hefay.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Testy jako základ: Od TDD k udržitelným testům krok za krokem</title><link href="http://hefay.github.io/programov%C3%A1n%C3%AD/testov%C3%A1n%C3%AD/java/tdd/2025/06/03/znovu-testy.html" rel="alternate" type="text/html" title="Testy jako základ: Od TDD k udržitelným testům krok za krokem" /><published>2025-06-03T23:12:00+02:00</published><updated>2025-06-03T23:12:00+02:00</updated><id>http://hefay.github.io/programov%C3%A1n%C3%AD/testov%C3%A1n%C3%AD/java/tdd/2025/06/03/znovu-testy</id><content type="html" xml:base="http://hefay.github.io/programov%C3%A1n%C3%AD/testov%C3%A1n%C3%AD/java/tdd/2025/06/03/znovu-testy.html"><![CDATA[<h2 id="úvod-proč-psát-testy-a-proč-je-psát-dobře">Úvod: Proč psát testy (a proč je psát dobře)?</h2>

<p>V dnešním rychlém světě vývoje softwaru je kvalita klíčová. Jedním z nejlepších způsobů, jak ji zajistit, je <strong>Test-Driven Development (TDD)</strong> a psaní čistých, udržitelných testů.</p>

<h2 id="výchozí-bod-implementace-nové-funkcionality-a-první-testy">Výchozí bod: Implementace nové funkcionality (a první testy)</h2>

<p>Představme si, že naším úkolem je implementovat API endpoint pro vytváření nového „Eligible Collateral“ pro danou protistranu.</p>

<h3 id="produkční-kód-eligiblecollateralspringfacadejava">Produkční kód (EligibleCollateralSpringFacade.java)</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">EligibleCollateralSpringFacade</span> <span class="o">{</span>
    <span class="kd">public</span> <span class="nc">EligibleCollateralDetail</span> <span class="nf">create</span><span class="o">(</span><span class="kd">final</span> <span class="nc">Counterparty</span> <span class="n">counterparty</span><span class="o">,</span> <span class="kd">final</span> <span class="nc">EligibleCollateralCreate</span> <span class="n">create</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">validateCounterpartyId</span><span class="o">(</span><span class="n">counterparty</span><span class="o">);</span>
        <span class="kd">final</span> <span class="kt">var</span> <span class="n">eligibleCollateral</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="na">toDomain</span><span class="o">(</span><span class="n">counterparty</span><span class="o">);</span>
        <span class="kd">final</span> <span class="kt">var</span> <span class="n">stored</span> <span class="o">=</span> <span class="k">this</span><span class="o">.</span><span class="na">service</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="n">eligibleCollateral</span><span class="o">);</span>
        <span class="k">return</span> <span class="nc">EligibleCollateralDetail</span><span class="o">.</span><span class="na">from</span><span class="o">(</span><span class="n">stored</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="kd">private</span> <span class="kt">void</span> <span class="nf">validateCounterpartyId</span><span class="o">(</span><span class="kd">final</span> <span class="nc">Counterparty</span> <span class="n">id</span><span class="o">)</span> <span class="o">{</span>
        <span class="c1">// Validace existence protistrany</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="první-testy-eligiblecollateralsacceptancetestjava">První testy (EligibleCollateralsAcceptanceTest.java)</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">EligibleCollateralsAcceptanceTest</span> <span class="o">{</span>
    <span class="nd">@Autowired</span> <span class="nc">MockMvc</span> <span class="n">mockMvc</span><span class="o">;</span>
    <span class="nd">@Autowired</span> <span class="nc">AuthenticatedTestApi</span> <span class="n">authenticationApi</span><span class="o">;</span>

    <span class="nd">@Test</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">created_eligible_collaterals_contains_filled_in_information</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span>
        <span class="n">authenticationApi</span><span class="o">.</span><span class="na">logInAsRisk</span><span class="o">();</span>
        <span class="nc">Long</span> <span class="n">counterpartyId</span> <span class="o">=</span> <span class="mi">4L</span><span class="o">;</span>
        <span class="nc">String</span> <span class="n">requestJson</span> <span class="o">=</span> <span class="s">"{"</span><span class="n">name</span><span class="s">": "</span><span class="nc">Eligible</span> <span class="nc">Name</span><span class="s">", "</span><span class="n">isin</span><span class="s">": "</span><span class="n">isin123</span><span class="s">"}"</span><span class="o">;</span>

        <span class="n">mockMvc</span><span class="o">.</span><span class="na">perform</span><span class="o">(</span><span class="n">post</span><span class="o">(</span><span class="s">"/api/non-clients/{id}/eligible-collaterals"</span><span class="o">,</span> <span class="n">counterpartyId</span><span class="o">)</span>
                <span class="o">.</span><span class="na">content</span><span class="o">(</span><span class="n">requestJson</span><span class="o">)</span>
                <span class="o">.</span><span class="na">contentType</span><span class="o">(</span><span class="nc">MediaType</span><span class="o">.</span><span class="na">APPLICATION_JSON</span><span class="o">)</span>
                <span class="o">.</span><span class="na">session</span><span class="o">(</span><span class="n">authenticationApi</span><span class="o">.</span><span class="na">getSession</span><span class="o">()))</span>
            <span class="o">.</span><span class="na">andExpect</span><span class="o">(</span><span class="n">status</span><span class="o">().</span><span class="na">isOk</span><span class="o">())</span>
            <span class="o">.</span><span class="na">andExpect</span><span class="o">(</span><span class="n">jsonPath</span><span class="o">(</span><span class="s">"name"</span><span class="o">).</span><span class="na">value</span><span class="o">(</span><span class="s">"Eligible Name"</span><span class="o">))</span>
            <span class="o">.</span><span class="na">andExpect</span><span class="o">(</span><span class="n">jsonPath</span><span class="o">(</span><span class="s">"isin"</span><span class="o">).</span><span class="na">value</span><span class="o">(</span><span class="s">"isin123"</span><span class="o">));</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<h2 id="krok-1-refaktoring--vytvoření-test-api">Krok 1: Refaktoring – Vytvoření Test API</h2>

<h3 id="eligiblecollateralstestapijava">EligibleCollateralsTestApi.java</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Component</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">EligibleCollateralsTestApi</span> <span class="o">{</span>
    <span class="nd">@Autowired</span> <span class="nc">MockMvc</span> <span class="n">mockMvc</span><span class="o">;</span>
    <span class="nd">@Autowired</span> <span class="nc">AuthenticatedTestApi</span> <span class="n">authenticationApi</span><span class="o">;</span>

    <span class="kd">public</span> <span class="nc">ResultActions</span> <span class="nf">create</span><span class="o">(</span><span class="nc">Long</span> <span class="n">counterpartyId</span><span class="o">,</span> <span class="nc">String</span> <span class="n">eligibleCollateralJson</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">mockMvc</span><span class="o">.</span><span class="na">perform</span><span class="o">(</span><span class="n">post</span><span class="o">(</span><span class="s">"/api/non-clients/{id}/eligible-collaterals"</span><span class="o">,</span> <span class="n">counterpartyId</span><span class="o">)</span>
            <span class="o">.</span><span class="na">content</span><span class="o">(</span><span class="n">eligibleCollateralJson</span><span class="o">)</span>
            <span class="o">.</span><span class="na">contentType</span><span class="o">(</span><span class="nc">MediaType</span><span class="o">.</span><span class="na">APPLICATION_JSON</span><span class="o">)</span>
            <span class="o">.</span><span class="na">session</span><span class="o">(</span><span class="n">authenticationApi</span><span class="o">.</span><span class="na">getSession</span><span class="o">()));</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="nc">AuthenticatedTestApi</span> <span class="nf">authentication</span><span class="o">()</span> <span class="o">{</span> <span class="k">return</span> <span class="n">authenticationApi</span><span class="o">;</span> <span class="o">}</span>
    <span class="kd">public</span> <span class="nc">Long</span> <span class="nf">existingNonClient</span><span class="o">()</span> <span class="o">{</span> <span class="k">return</span> <span class="mi">4L</span><span class="o">;</span> <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="upravený-test">Upravený test</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Test</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">created_eligible_collaterals_contains_filled_in_information</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span>
    <span class="n">api</span><span class="o">.</span><span class="na">authentication</span><span class="o">().</span><span class="na">logInAsRisk</span><span class="o">();</span>
    <span class="nc">Long</span> <span class="n">counterpartyId</span> <span class="o">=</span> <span class="n">api</span><span class="o">.</span><span class="na">existingNonClient</span><span class="o">();</span>
    <span class="nc">String</span> <span class="n">requestJson</span> <span class="o">=</span> <span class="s">"{"</span><span class="n">name</span><span class="s">": "</span><span class="nc">Eligible</span> <span class="nc">Name</span><span class="s">", "</span><span class="n">isin</span><span class="s">": "</span><span class="n">isin123</span><span class="s">"}"</span><span class="o">;</span>

    <span class="n">api</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="n">counterpartyId</span><span class="o">,</span> <span class="n">requestJson</span><span class="o">)</span>
        <span class="o">.</span><span class="na">andExpect</span><span class="o">(</span><span class="n">status</span><span class="o">().</span><span class="na">isOk</span><span class="o">())</span>
        <span class="o">.</span><span class="na">andExpect</span><span class="o">(</span><span class="n">jsonPath</span><span class="o">(</span><span class="s">"name"</span><span class="o">).</span><span class="na">value</span><span class="o">(</span><span class="s">"Eligible Name"</span><span class="o">))</span>
        <span class="o">.</span><span class="na">andExpect</span><span class="o">(</span><span class="n">jsonPath</span><span class="o">(</span><span class="s">"isin"</span><span class="o">).</span><span class="na">value</span><span class="o">(</span><span class="s">"isin123"</span><span class="o">));</span>
<span class="o">}</span>
</code></pre></div></div>

<h2 id="krok-2-refaktoring--zavedení-response-objectu">Krok 2: Refaktoring – Zavedení Response Objectu</h2>

<h3 id="eligiblecollateralsdetailreponsejava">EligibleCollateralsDetailReponse.java</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">EligibleCollateralsDetailReponse</span> <span class="o">{</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="nc">ResultActions</span> <span class="n">resultActions</span><span class="o">;</span>

    <span class="kd">public</span> <span class="nf">EligibleCollateralsDetailReponse</span><span class="o">(</span><span class="nc">ResultActions</span> <span class="n">resultActions</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">resultActions</span> <span class="o">=</span> <span class="n">resultActions</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="nc">EligibleCollateralsDetailReponse</span> <span class="nf">expectStatusOk</span><span class="o">()</span> <span class="o">{</span>
        <span class="n">expect</span><span class="o">(</span><span class="n">status</span><span class="o">().</span><span class="na">isOk</span><span class="o">());</span>
        <span class="k">return</span> <span class="k">this</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="nc">EligibleCollateralsDetailReponse</span> <span class="nf">expectName</span><span class="o">(</span><span class="nc">String</span> <span class="n">expected</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">expect</span><span class="o">(</span><span class="n">jsonPath</span><span class="o">(</span><span class="s">"name"</span><span class="o">).</span><span class="na">value</span><span class="o">(</span><span class="n">expected</span><span class="o">));</span>
        <span class="k">return</span> <span class="k">this</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">expectIsin</span><span class="o">(</span><span class="nc">String</span> <span class="n">expected</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">expect</span><span class="o">(</span><span class="n">jsonPath</span><span class="o">(</span><span class="s">"isin"</span><span class="o">).</span><span class="na">value</span><span class="o">(</span><span class="n">expected</span><span class="o">));</span>
    <span class="o">}</span>

    <span class="kd">private</span> <span class="kt">void</span> <span class="nf">expect</span><span class="o">(</span><span class="nc">ResultMatcher</span> <span class="n">matcher</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">resultActions</span><span class="o">.</span><span class="na">andExpect</span><span class="o">(</span><span class="n">matcher</span><span class="o">);</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="upravený-test-1">Upravený test</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Test</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">created_eligible_collaterals_contains_filled_in_information</span><span class="o">()</span> <span class="o">{</span>
    <span class="n">api</span><span class="o">.</span><span class="na">authentication</span><span class="o">().</span><span class="na">logInAsRisk</span><span class="o">();</span>
    <span class="nc">Long</span> <span class="n">counterpartyId</span> <span class="o">=</span> <span class="n">api</span><span class="o">.</span><span class="na">existingNonClient</span><span class="o">();</span>
    <span class="nc">String</span> <span class="n">requestJson</span> <span class="o">=</span> <span class="s">"{"</span><span class="n">name</span><span class="s">": "</span><span class="nc">Eligible</span> <span class="nc">Name</span><span class="s">", "</span><span class="n">isin</span><span class="s">": "</span><span class="n">isin123</span><span class="s">"}"</span><span class="o">;</span>

    <span class="n">api</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="n">counterpartyId</span><span class="o">,</span> <span class="n">requestJson</span><span class="o">)</span>
        <span class="o">.</span><span class="na">expectStatusOk</span><span class="o">()</span>
        <span class="o">.</span><span class="na">expectName</span><span class="o">(</span><span class="s">"Eligible Name"</span><span class="o">)</span>
        <span class="o">.</span><span class="na">expectIsin</span><span class="o">(</span><span class="s">"isin123"</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>

<h2 id="krok-3-refaktoring--test-data-builder-eligibledraftjava">Krok 3: Refaktoring – Test Data Builder (EligibleDraft.java)</h2>

<h3 id="eligibledraftjava">EligibleDraft.java</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Data</span>
<span class="nd">@AllArgsConstructor</span>
<span class="nd">@Accessors</span><span class="o">(</span><span class="n">fluent</span> <span class="o">=</span> <span class="kc">true</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">EligibleDraft</span> <span class="o">{</span>
    <span class="nd">@Nullable</span> <span class="nd">@JsonProperty</span><span class="o">(</span><span class="s">"name"</span><span class="o">)</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">name</span><span class="o">;</span>

    <span class="nd">@Nullable</span> <span class="nd">@JsonProperty</span><span class="o">(</span><span class="s">"isin"</span><span class="o">)</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">isin</span><span class="o">;</span>

    <span class="kd">public</span> <span class="nc">String</span> <span class="nf">toJson</span><span class="o">()</span> <span class="o">{</span>
        <span class="kd">final</span> <span class="kt">var</span> <span class="n">om</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ObjectMapper</span><span class="o">();</span>
        <span class="k">return</span> <span class="n">om</span><span class="o">.</span><span class="na">writeValueAsString</span><span class="o">(</span><span class="k">this</span><span class="o">);</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="rozšíření-test-api">Rozšíření Test API</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="nc">EligibleDraft</span> <span class="nf">prefilledEligibleDraft</span><span class="o">()</span> <span class="o">{</span>
    <span class="k">return</span> <span class="k">new</span> <span class="nf">EligibleDraft</span><span class="o">(</span><span class="s">"Default Eligible Name"</span><span class="o">,</span> <span class="s">"DefaultISIN123"</span><span class="o">);</span>
<span class="o">}</span>

<span class="kd">public</span> <span class="nc">EligibleCollateralsDetailReponse</span> <span class="nf">create</span><span class="o">(</span><span class="nc">Long</span> <span class="n">counterparty</span><span class="o">,</span> <span class="nc">EligibleDraft</span> <span class="n">draft</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">return</span> <span class="nf">create</span><span class="o">(</span><span class="n">counterparty</span><span class="o">,</span> <span class="n">draft</span><span class="o">.</span><span class="na">toJson</span><span class="o">());</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="test-s-builderem">Test s builderem</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Test</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">created_eligible_collaterals_contains_filled_in_information</span><span class="o">()</span> <span class="o">{</span>
    <span class="n">api</span><span class="o">.</span><span class="na">authentication</span><span class="o">().</span><span class="na">logInAsRisk</span><span class="o">();</span>
    <span class="kd">final</span> <span class="kt">var</span> <span class="n">counterparty</span> <span class="o">=</span> <span class="n">api</span><span class="o">.</span><span class="na">existingNonClient</span><span class="o">();</span>
    <span class="kd">final</span> <span class="kt">var</span> <span class="n">draft</span> <span class="o">=</span> <span class="n">api</span><span class="o">.</span><span class="na">prefilledEligibleDraft</span><span class="o">()</span>
                         <span class="o">.</span><span class="na">name</span><span class="o">(</span><span class="s">"Eligible Name"</span><span class="o">)</span>
                         <span class="o">.</span><span class="na">isin</span><span class="o">(</span><span class="s">"isin123"</span><span class="o">);</span>

    <span class="n">api</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="n">counterparty</span><span class="o">,</span> <span class="n">draft</span><span class="o">)</span>
        <span class="o">.</span><span class="na">expectStatusOk</span><span class="o">()</span>
        <span class="o">.</span><span class="na">expectName</span><span class="o">(</span><span class="s">"Eligible Name"</span><span class="o">)</span>
        <span class="o">.</span><span class="na">expectIsin</span><span class="o">(</span><span class="s">"isin123"</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>

<h2 id="tdd-v-praxi-přidání-kontroly-oprávnění">TDD v praxi: Přidání kontroly oprávnění</h2>

<h3 id="test-na-nedostatečná-oprávnění">Test na nedostatečná oprávnění</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Test</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">create_eligible_with_insufficient_permissions_collaterals_returns_error</span><span class="o">()</span> <span class="o">{</span>
    <span class="n">api</span><span class="o">.</span><span class="na">authentication</span><span class="o">().</span><span class="na">logInAsBranchWorker</span><span class="o">();</span>
    <span class="kd">final</span> <span class="kt">var</span> <span class="n">counterparty</span> <span class="o">=</span> <span class="n">api</span><span class="o">.</span><span class="na">existingNonClient</span><span class="o">();</span>
    <span class="kd">final</span> <span class="kt">var</span> <span class="n">draft</span> <span class="o">=</span> <span class="n">api</span><span class="o">.</span><span class="na">prefilledEligibleDraft</span><span class="o">();</span>

    <span class="n">api</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="n">counterparty</span><span class="o">,</span> <span class="n">draft</span><span class="o">)</span>
        <span class="o">.</span><span class="na">expectStatusForbidden</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="implementace-zabezpečení">Implementace zabezpečení</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Secured</span><span class="o">(</span><span class="nc">DafosPermissions</span><span class="o">.</span><span class="na">EDIT_COUNTERPARTY_LIMITS</span><span class="o">)</span>
<span class="kd">public</span> <span class="nc">EligibleCollateralDetail</span> <span class="nf">create</span><span class="o">(</span><span class="kd">final</span> <span class="nc">Counterparty</span> <span class="n">counterparty</span><span class="o">,</span> <span class="kd">final</span> <span class="nc">EligibleCollateralCreate</span> <span class="n">create</span><span class="o">)</span> <span class="o">{</span>
    <span class="n">validateCounterpartyId</span><span class="o">(</span><span class="n">counterparty</span><span class="o">);</span>
    <span class="kd">final</span> <span class="kt">var</span> <span class="n">eligibleCollateral</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="na">toDomain</span><span class="o">(</span><span class="n">counterparty</span><span class="o">);</span>
    <span class="kd">final</span> <span class="kt">var</span> <span class="n">stored</span> <span class="o">=</span> <span class="k">this</span><span class="o">.</span><span class="na">service</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="n">eligibleCollateral</span><span class="o">);</span>
    <span class="k">return</span> <span class="nc">EligibleCollateralDetail</span><span class="o">.</span><span class="na">from</span><span class="o">(</span><span class="n">stored</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>

<h2 id="závěr-investice-která-se-vyplatí">Závěr: Investice, která se vyplatí</h2>

<p>Dobře navržená testovací infrastruktura přináší:</p>

<ul>
  <li>Větší důvěru při refaktoringu.</li>
  <li>Rychlejší odhalování chyb.</li>
  <li>Lepší dokumentaci systému.</li>
  <li>Snazší onboarding nových vývojářů.</li>
  <li>Nižší náklady na údržbu a rozvoj aplikace.</li>
</ul>]]></content><author><name></name></author><category term="programování" /><category term="testování" /><category term="java" /><category term="tdd" /><category term="programming" /><category term="tests" /><summary type="html"><![CDATA[Úvod: Proč psát testy (a proč je psát dobře)?]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://hefay.github.io/assets/images/hefay.png" /><media:content medium="image" url="http://hefay.github.io/assets/images/hefay.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Linuxový nástroj TLDR</title><link href="http://hefay.github.io/linux/2025/03/12/tldr.html" rel="alternate" type="text/html" title="Linuxový nástroj TLDR" /><published>2025-03-12T19:56:00+01:00</published><updated>2025-03-12T19:56:00+01:00</updated><id>http://hefay.github.io/linux/2025/03/12/tldr</id><content type="html" xml:base="http://hefay.github.io/linux/2025/03/12/tldr.html"><![CDATA[<p>Narazil jsem na zajímavý tool pro Linux, který zkrátí prohledávání manuálů pro jednotlivé příkazy. Není to nic nového, dokonce jsem zjistil, že to hodně mých kolegů používá, takže jen já procházím staromódně manuálové stránky.</p>

<p>Nástroj se jmenuje TLDR a najdete jej na:</p>

<p><a href="https://web.archive.org/web/20250308214949/https://tldr.sh/">https://web.archive.org/web/20250308214949/https://tldr.sh/</a></p>]]></content><author><name></name></author><category term="linux" /><category term="linux" /><category term="tools" /><summary type="html"><![CDATA[Narazil jsem na zajímavý tool pro Linux, který zkrátí prohledávání manuálů pro jednotlivé příkazy. Není to nic nového, dokonce jsem zjistil, že to hodně mých kolegů používá, takže jen já procházím staromódně manuálové stránky.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://hefay.github.io/assets/images/hefay.png" /><media:content medium="image" url="http://hefay.github.io/assets/images/hefay.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Hicking</title><link href="http://hefay.github.io/turistika/2025/02/19/hicking.html" rel="alternate" type="text/html" title="Hicking" /><published>2025-02-19T22:28:00+01:00</published><updated>2025-02-19T22:28:00+01:00</updated><id>http://hefay.github.io/turistika/2025/02/19/hicking</id><content type="html" xml:base="http://hefay.github.io/turistika/2025/02/19/hicking.html"><![CDATA[<p>Poslední dobou hodně přemýšlíme jak do budoucna budeme brát naši dceru na výlety. Nemyslím tím nějaké výlety po okolí ve městě a nebo přilehlém okolí, ale na delší tůry, kde se setkáme i s nějakým menším terénem.</p>

<p>Hlavní kámen úrazu pro takové větší výlety je ten, že naše dcera je na invalidním vozíku. Ještě je tedy malá, takže se dá použít kočárek, který je do terénu přeci jen o něco vhodnější, ale z něj velmi rychle vyroste. Už teď je na něj veliká.</p>

<p>Shodou náhod jsme však objevili, že existuje takové obrácené zahradní kolečko. Má to více variant, ale to, které nás zaujalo opravdu vypadá skoro jako zahradní kolečko. Hlavní rozdíl je ten, že jej táhnete za sebou místo toho, aby bylo před Vámi. Umístíte do něj dítě, připnete si jej k bedernímu pásu a můžete vyrazit na cestu. Přepravovaná osoba může mít až 60 kg, což by nám mělo na nějakou dobu vystačit.</p>

<p>Není to tedy zrovna levná záležitost. Cenovka atakuje hranici 100k, ale myslíme, že by se jí to mohlo líbit.</p>]]></content><author><name></name></author><category term="turistika" /><category term="turistika" /><category term="hicking" /><summary type="html"><![CDATA[Poslední dobou hodně přemýšlíme jak do budoucna budeme brát naši dceru na výlety. Nemyslím tím nějaké výlety po okolí ve městě a nebo přilehlém okolí, ale na delší tůry, kde se setkáme i s nějakým menším terénem.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://hefay.github.io/assets/images/hefay.png" /><media:content medium="image" url="http://hefay.github.io/assets/images/hefay.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Výletníci na měsíc</title><link href="http://hefay.github.io/turistika/2025/02/19/hicking-2.html" rel="alternate" type="text/html" title="Výletníci na měsíc" /><published>2025-02-19T22:28:00+01:00</published><updated>2025-02-19T22:28:00+01:00</updated><id>http://hefay.github.io/turistika/2025/02/19/hicking-2</id><content type="html" xml:base="http://hefay.github.io/turistika/2025/02/19/hicking-2.html"><![CDATA[<p>Jak jsem psal již minule, našli jsme zajímavý “vozíček”, který se dá použít pro pěší turistiku s dětmi, které jen tak snadno středně těžký terén nenavštíví.</p>

<p>Jedná se o takový vozíček, který za sebe zapřáhnete, dítě do něj položíte a hurá, můžete cestovat.</p>

<p><img src="/assets/images/hicking-cart.jpeg" alt="Hicking cart" /></p>]]></content><author><name></name></author><category term="turistika" /><category term="turistika" /><category term="hicking" /><summary type="html"><![CDATA[Jak jsem psal již minule, našli jsme zajímavý “vozíček”, který se dá použít pro pěší turistiku s dětmi, které jen tak snadno středně těžký terén nenavštíví.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://hefay.github.io/assets/images/hefay.png" /><media:content medium="image" url="http://hefay.github.io/assets/images/hefay.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">I’ve Somehow Gotten Stronger When I Improved My Farm-Related Skills</title><link href="http://hefay.github.io/anime/2025/01/10/image-test.html" rel="alternate" type="text/html" title="I’ve Somehow Gotten Stronger When I Improved My Farm-Related Skills" /><published>2025-01-10T19:50:00+01:00</published><updated>2025-01-10T19:50:00+01:00</updated><id>http://hefay.github.io/anime/2025/01/10/image-test</id><content type="html" xml:base="http://hefay.github.io/anime/2025/01/10/image-test.html"><![CDATA[<p>Tenhle příspěvek je jen test, zda <code class="language-plaintext highlighter-rouge">og:image</code> meta tag funguje správně, ale pokud někoho název zaujal, tak tady je Wiki link:
<a href="https://en.wikipedia.org/wiki/I%27ve_Somehow_Gotten_Stronger_When_I_Improved_My_Farm-Related_Skills">https://en.wikipedia.org/wiki/I%27ve_Somehow_Gotten_Stronger_When_I_Improved_My_Farm-Related_Skills</a></p>]]></content><author><name></name></author><category term="anime" /><category term="anime" /><summary type="html"><![CDATA[Tenhle příspěvek je jen test, zda og:image meta tag funguje správně, ale pokud někoho název zaujal, tak tady je Wiki link: https://en.wikipedia.org/wiki/I%27ve_Somehow_Gotten_Stronger_When_I_Improved_My_Farm-Related_Skills]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://upload.wikimedia.org/wikipedia/en/thumb/a/aa/N%C5%8Dmin_Kanren_no_Skill_Bakka_Agetetara_Nazeka_Tsuyoku_Natta_volume_1.jpg/220px-N%C5%8Dmin_Kanren_no_Skill_Bakka_Agetetara_Nazeka_Tsuyoku_Natta_volume_1.jpg" /><media:content medium="image" url="https://upload.wikimedia.org/wikipedia/en/thumb/a/aa/N%C5%8Dmin_Kanren_no_Skill_Bakka_Agetetara_Nazeka_Tsuyoku_Natta_volume_1.jpg/220px-N%C5%8Dmin_Kanren_no_Skill_Bakka_Agetetara_Nazeka_Tsuyoku_Natta_volume_1.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Arduino (ATMega) the hard way</title><link href="http://hefay.github.io/bastl/2025/01/03/arduino-hard-way.html" rel="alternate" type="text/html" title="Arduino (ATMega) the hard way" /><published>2025-01-03T11:07:00+01:00</published><updated>2025-01-03T11:07:00+01:00</updated><id>http://hefay.github.io/bastl/2025/01/03/arduino-hard-way</id><content type="html" xml:base="http://hefay.github.io/bastl/2025/01/03/arduino-hard-way.html"><![CDATA[<p>Včera večer jsem svému synovi chtěl ukázat jak jednoduché je nahrát jednoduchý program do <em>ATtiny13A</em> a během toho jsem zjistil, že jsem úplně zapomněl jak nastavit LSP a clang tak, aby to dávalo pro takový projektík smysl.</p>

<p>Abych to příště nemusel opět zdlouhavě hledat, řekl jsem si, že si to pro jistotu odložím sem.</p>

<p>Základ komunikace s AVR programátorem, který používám a nastavením clangu je pěkně shrnut v čĺánku <a href="https://web.archive.org/web/20231001155615/https://www.gridbugs.org/programming-an-arduino-the-hard-way/">Programming an Arduino the Hard Way</a>. Raději jsem přiložil verzi z archive.org.</p>

<p>Co se týče mé LSP konfigurace v neovimu, tak používám Mason a lspconfig a clang tedy vypadá jen jako</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>require 'lspconfig'.clangd.setup{}
</code></pre></div></div>]]></content><author><name></name></author><category term="bastl" /><category term="bast" /><category term="avr" /><category term="programování" /><summary type="html"><![CDATA[Včera večer jsem svému synovi chtěl ukázat jak jednoduché je nahrát jednoduchý program do ATtiny13A a během toho jsem zjistil, že jsem úplně zapomněl jak nastavit LSP a clang tak, aby to dávalo pro takový projektík smysl.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://hefay.github.io/assets/images/hefay.png" /><media:content medium="image" url="http://hefay.github.io/assets/images/hefay.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>