package Ġbr . com . gui ab ol so . connector . token čĊč Ċ import Ġbr . com . gui ab ol so . connector . common . cache . Cache Service č Ċ import Ġbr . com . gui ab ol so . connector . common . crypto graphy . Cryptography Service č Ċ import Ġbr . com . gui ab ol so . connector . common . crypto graphy . Encrypted Data č Ċ import Ġbr . com . gui ab ol so . connector . common . time . Z onedDateTime Provider č Ċ import Ġbr . com . gui ab ol so . connector . event . EventDispatcher č Ċ import Ġbr . com . gui ab ol so . connector . event . misc . Easy Random Wrapper . next Object č Ċ import Ġbr . com . gui ab ol so . connector . event . misc . build Event č Ċ import Ġbr . com . gui ab ol so . connector . helper . create JWT č Ċ import Ġbr . com . gui ab ol so . connector . token . exception . Expired Authorization Code Exception č Ċ import Ġbr . com . gui ab ol so . connector . token . model . Token č Ċ import Ġbr . com . gui ab ol so . connector . token . repository . Token Repository č Ċ import Ġbr . com . gui ab ol so . events . builder . Event Builder č Ċ import Ġbr . com . gui ab ol so . events . context . Event Context č Ċ import Ġbr . com . gui ab ol so . events . context . Event Context Holder č Ċ import Ġbr . com . gui ab ol so . events . model . Request Event č Ċ import Ġcom . google . gson . JsonObject č Ċ import Ġcom . n ha ar man . mockito _ kotlin . any č Ċ import Ġcom . n ha ar man . mockito _ kotlin . argument Captor č Ċ import Ġcom . n ha ar man . mockito _ kotlin . mock č Ċ import Ġcom . n ha ar man . mockito _ kotlin . verify č Ċ import Ġcom . n ha ar man . mockito _ kotlin . wh enever č Ċ import Ġjava . time . Duration č Ċ import Ġjava . time . Z onedDateTime . now č Ċ import Ġorg . assertj . core . api . Assertions . assertThat č Ċ import Ġorg . assertj . core . api . Assertions . assertThat Exception OfType č Ċ import Ġorg . junit . jupiter . api . BeforeEach č Ċ import Ġorg . junit . jupiter . api . Test čĊč Ċ class ĠToken Exchange Service Test Ġ{ čĊčĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġrepository : ĠToken Repository čĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġdispatcher : ĠEvent Dispatcher čĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġcache Service : ĠCache Service čĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġcrypto graphy Service : ĠCrypto graphy Service čĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġservice : ĠToken Exchange Service čĊĠĠĠ Ġprivate Ġlateinit Ġvar ĠdateTime Provider : ĠZ onedDateTime Provider čĊčĊĠĠĠ Ġ@ BeforeEach čĊĠĠĠ Ġfun ĠsetUp () Ġ{ čĊĠĠĠĠĠĠĠ Ġrepository Ġ= Ġmock () čĊĠĠĠĠĠĠĠ Ġdispatcher Ġ= Ġmock () čĊĠĠĠĠĠĠĠ Ġcache Service Ġ= Ġmock () čĊĠĠĠĠĠĠĠ Ġcrypto graphy Service Ġ= Ġmock () čĊĠĠĠĠĠĠĠ ĠdateTime Provider Ġ= Ġmock () čĊčĊĠĠĠĠĠĠĠ Ġservice Ġ= ĠToken Exchange Service ( repository , Ġdispatcher , Ġcache Service , Ġcrypto graphy Service , ĠdateTime Provider ) čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġ@ Test čĊĠĠĠ Ġfun Ġ` should Ġexchange Ġtokens `() Ġ{ čĊĠĠĠĠĠĠĠ ĠEvent Context Holder . set Context ( čĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext Ġ= ĠEvent Context ( čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġid Ġ= Ġnext Object < String >(), čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflow Id Ġ= Ġnext Object < String >() čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) čĊĠĠĠĠĠĠĠ Ġ) čĊčĊĠĠĠĠĠĠĠ Ġval ĠuserId Ġ= Ġnext Object < String >() čĊĠĠĠĠĠĠĠ Ġval Ġauthorization Code Ġ= Ġcreate JWT ( now (), Ġnow (). plus Minutes ( 1 )) čĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= ĠToken . getKey ( userId ) čĊĠĠĠĠĠĠĠ Ġval Ġdecrypted AccessToken Ġ= Ġnext Object < String >() čĊĠĠĠĠĠĠĠ Ġval ĠaccessToken Ġ= Ġnext Object < Encrypted Data >() čĊĠĠĠĠĠĠĠ Ġval Ġdecrypted RefreshToken Ġ= Ġnext Object < String >() čĊĠĠĠĠĠĠĠ Ġval Ġrefresh Token Ġ= Ġnext Object < Encrypted Data >() čĊčĊĠĠĠĠĠĠĠ Ġval Ġresponse Event Ġ= ĠEvent Builder . response For ( build Event ()) Ġ{} . copy ( čĊĠĠĠĠĠĠĠĠĠĠĠ Ġpayload Ġ= ĠJsonObject (). apply Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Property (" accessToken ", Ġdecrypted AccessToken ) čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Property (" refresh Token ", Ġdecrypted RefreshToken ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġ) čĊčĊĠĠĠĠĠĠĠ Ġwhenever ( dateTime Provider . now ()). thenReturn ( now ()) čĊĠĠĠĠĠĠĠ Ġwhenever ( crypto graphy Service . encrypt ( de crypted AccessToken . toByteArray ())). thenReturn ( accessToken ) čĊĠĠĠĠĠĠĠ Ġwhenever ( crypto graphy Service . encrypt ( de crypted RefreshToken . toByteArray ())). thenReturn ( refresh Token ) čĊĠĠĠĠĠĠĠ Ġwhenever ( dispatcher . send Event ( any ())). thenReturn ( response Event ) čĊčĊĠĠĠĠĠĠĠ Ġservice . exchange Tokens ( userId , Ġauthorization Code ) čĊčĊĠĠĠĠĠĠĠ Ġargument Captor < Request Event >(). run Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġverify ( dispatcher ). send Event ( capture ()) čĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( first Value . payload . as JsonObject [" code "]. asString ). isEqualTo ( authorization Code ) čĊĠĠĠĠĠĠĠ Ġ} čĊčĊĠĠĠĠĠĠĠ Ġverify ( crypto graphy Service ). encrypt ( de crypted AccessToken . toByteArray ()) čĊĠĠĠĠĠĠĠ Ġverify ( crypto graphy Service ). encrypt ( de crypted RefreshToken . toByteArray ()) čĊĠĠĠĠĠĠĠ Ġverify ( cache Service ). put Data ( key , ĠaccessToken , ĠD URATION , ĠONLY _ IN _ MEMORY ) čĊĠĠĠĠĠĠĠ Ġverify ( repository ). put Token ( userId , ĠaccessToken , Ġrefresh Token ) čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġ@ Test čĊĠĠĠ Ġfun Ġ` should Ġri se Ġwhen Ġauthorization Ġcode Ġis Ġexpired `() Ġ{ čĊĠĠĠĠĠĠĠ Ġval Ġnow Ġ= Ġnow () čĊĠĠĠĠĠĠĠ Ġwhenever ( dateTime Provider . now ()). thenReturn ( now ) čĊĠĠĠĠĠĠĠ Ġval Ġexpired Token Ġ= Ġcreate JWT ( iss ued At Ġ= Ġnow . minus Minutes ( 1 ), Ġexpire At Ġ= Ġnow . minus Seconds ( 1 )) čĊčĊĠĠĠĠĠĠĠ ĠassertThat Exception OfType ( Expired Authorization Code Exception :: class . java ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. is Thrown By Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġservice . exchange Tokens ( userId Ġ= Ġnext Object (), Ġauthorization Code Ġ= Ġexpired Token ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġcompanion Ġobject Ġ{ čĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠD URATION Ġ= ĠDuration . of Minutes ( 5 ) čĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠONLY _ IN _ MEMORY Ġ= Ġtrue čĊĠĠĠ Ġ} č Ċ } čĊ