99import com .openelements .hiero .base .protocol .ProtocolLayerClient ;
1010import com .openelements .hiero .base .protocol .TokenCreateRequest ;
1111import com .openelements .hiero .base .protocol .TokenCreateResult ;
12+ import com .openelements .hiero .base .protocol .TokenTransferRequest ;
13+ import com .openelements .hiero .base .protocol .TokenTransferResult ;
14+ import java .util .List ;
1215import org .junit .jupiter .api .Assertions ;
1316import org .junit .jupiter .api .BeforeEach ;
1417import org .junit .jupiter .api .Test ;
@@ -27,6 +30,7 @@ public class NftClientImplTest {
2730 NftClientImpl nftClientImpl ;
2831
2932 ArgumentCaptor <TokenCreateRequest > tokenRequestCaptor = ArgumentCaptor .forClass (TokenCreateRequest .class );
33+ ArgumentCaptor <TokenTransferRequest > tokenTransferCaptor = ArgumentCaptor .forClass (TokenTransferRequest .class );
3034
3135 @ BeforeEach
3236 public void setup () {
@@ -202,4 +206,111 @@ void testCreateNftForNullParam() {
202206 () -> nftClientImpl .createNftType (null , null , null , null , (PrivateKey ) null )
203207 );
204208 }
209+
210+ @ Test
211+ void testTransferNft () throws HieroException {
212+ // mock
213+ final TokenTransferResult tokenTransferResult = Mockito .mock (TokenTransferResult .class );
214+
215+ // given
216+ final TokenId tokenId = TokenId .fromString ("1.2.3" );
217+ final long serialNumber = 1L ;
218+ final AccountId fromAccount = AccountId .fromString ("1.2.3" );
219+ final AccountId toAccount = AccountId .fromString ("4.5.6" );
220+ final PrivateKey fromAccountKey = PrivateKey .generateECDSA ();
221+
222+ // when
223+ when (protocolLayerClient .executeTransferTransaction (any (TokenTransferRequest .class )))
224+ .thenReturn (tokenTransferResult );
225+ nftClientImpl .transferNft (tokenId , serialNumber , fromAccount , fromAccountKey , toAccount );
226+
227+ // then
228+ verify (protocolLayerClient , times (1 ))
229+ .executeTransferTransaction (tokenTransferCaptor .capture ());
230+
231+ final TokenTransferRequest request = tokenTransferCaptor .getValue ();
232+ Assertions .assertEquals (tokenId , request .tokenId ());
233+ Assertions .assertEquals (List .of (serialNumber ), request .serials ());
234+ Assertions .assertEquals (fromAccount , request .sender ());
235+ Assertions .assertEquals (toAccount , request .receiver ());
236+ Assertions .assertEquals (fromAccountKey , request .senderKey ());
237+ }
238+
239+ @ Test
240+ void testTransferNfts () throws HieroException {
241+ // mock
242+ final TokenTransferResult tokenTransferResult = Mockito .mock (TokenTransferResult .class );
243+
244+ // given
245+ final TokenId tokenId = TokenId .fromString ("1.2.3" );
246+ final List <Long > serialNumbers = List .of (1L , 2L );
247+ final AccountId fromAccount = AccountId .fromString ("1.2.3" );
248+ final AccountId toAccount = AccountId .fromString ("4.5.6" );
249+ final PrivateKey fromAccountKey = PrivateKey .generateECDSA ();
250+
251+ // when
252+ when (protocolLayerClient .executeTransferTransaction (any (TokenTransferRequest .class )))
253+ .thenReturn (tokenTransferResult );
254+ nftClientImpl .transferNfts (tokenId , serialNumbers , fromAccount , fromAccountKey , toAccount );
255+
256+ // then
257+ verify (protocolLayerClient , times (1 ))
258+ .executeTransferTransaction (tokenTransferCaptor .capture ());
259+
260+ final TokenTransferRequest request = tokenTransferCaptor .getValue ();
261+ Assertions .assertEquals (tokenId , request .tokenId ());
262+ Assertions .assertEquals (serialNumbers , request .serials ());
263+ Assertions .assertEquals (fromAccount , request .sender ());
264+ Assertions .assertEquals (toAccount , request .receiver ());
265+ Assertions .assertEquals (fromAccountKey , request .senderKey ());
266+ }
267+
268+ @ Test
269+ void testTransferNftThrowsExceptionForInvalidTokenId () throws HieroException {
270+ //given
271+ final TokenId tokenId = TokenId .fromString ("1.2.3" );
272+ final AccountId fromAccount = AccountId .fromString ("1.2.3" );
273+ final AccountId toAccount = AccountId .fromString ("4.5.6" );
274+ final PrivateKey fromAccountKey = PrivateKey .generateECDSA ();
275+ final long serial = 1L ;
276+
277+ //when
278+ when (protocolLayerClient .executeTransferTransaction (any (TokenTransferRequest .class )))
279+ .thenThrow (new HieroException ("Failed to execute transaction of type TokenTransferTransaction" ));
280+
281+ //then
282+ Assertions .assertThrows (HieroException .class , () -> nftClientImpl .transferNft (tokenId , serial ,
283+ fromAccount , fromAccountKey , toAccount ));
284+ }
285+
286+ @ Test
287+ void testTransferNftThrowsExceptionForInvalidSerial () {
288+ final String e1Message = "serial must be positive" ;
289+ final String e2Message = "either amount or serial must be provided" ;
290+
291+ //given
292+ final TokenId tokenId = TokenId .fromString ("1.2.3" );
293+ final AccountId fromAccount = AccountId .fromString ("1.2.3" );
294+ final AccountId toAccount = AccountId .fromString ("4.5.6" );
295+ final PrivateKey fromAccountKey = PrivateKey .generateECDSA ();
296+ final long serial = -1L ;
297+
298+ IllegalArgumentException e1 = Assertions .assertThrows (IllegalArgumentException .class ,
299+ () -> nftClientImpl .transferNft (tokenId , serial , fromAccount , fromAccountKey , toAccount ));
300+ Assertions .assertEquals (e1Message , e1 .getMessage ());
301+
302+ IllegalArgumentException e2 = Assertions .assertThrows (IllegalArgumentException .class ,
303+ () -> nftClientImpl .transferNfts (tokenId , List .of (), fromAccount , fromAccountKey , toAccount ));
304+ Assertions .assertEquals (e2Message , e2 .getMessage ());
305+ }
306+
307+ @ Test
308+ void testTransferNftNullParams () {
309+ Assertions .assertThrows (NullPointerException .class ,
310+ () -> nftClientImpl .transferNft (null , 1L , null ,
311+ null , null ));
312+ Assertions .assertThrows (NullPointerException .class ,
313+ () -> nftClientImpl .transferNfts (null , null , null ,
314+ null , null ));
315+ }
205316}
0 commit comments