# Test the asset management system · Asset management system with React and FT4 · Learn Chromia

> This last lesson covers testing the asset management system end to end. You will work through several test scenarios and check that the system behaves as…

Source: https://chromia.com/learn/ft4-demo-app/module-blockchain/test/

Asset management system with React and FT4Lesson 8 of 16

1. [01Create an asset management system using FT4](https://chromia.com/learn/ft4-demo-app/introduction/)

Module 1: Initialize the full-stack application

1. [02Overview](https://chromia.com/learn/ft4-demo-app/module-init/)
2. [03Prepare the full-stack application](https://chromia.com/learn/ft4-demo-app/module-init/setup-application/)

Module 2: The blockchain dapp

1. [04Overview](https://chromia.com/learn/ft4-demo-app/module-blockchain/)
2. [05Part 1: Set up the blockchain dapp](https://chromia.com/learn/ft4-demo-app/module-blockchain/setup/)
3. [06Account management](https://chromia.com/learn/ft4-demo-app/module-blockchain/account-management/)
4. [07Asset Registration and Minting](https://chromia.com/learn/ft4-demo-app/module-blockchain/asset-registration/)
5. [08Test the asset management system](https://chromia.com/learn/ft4-demo-app/module-blockchain/test/)

Module 3: The frontend application

1. [09Overview](https://chromia.com/learn/ft4-demo-app/module-frontend-application/)
2. [10Part 1: Prepare the frontend application](https://chromia.com/learn/ft4-demo-app/module-frontend-application/setup/)
3. [11Part 2: Tools for Chromia development](https://chromia.com/learn/ft4-demo-app/module-frontend-application/tools/)
4. [12Part 3: Registering accounts](https://chromia.com/learn/ft4-demo-app/module-frontend-application/account-regisration/)
5. [13Part 4: Registering and minting](https://chromia.com/learn/ft4-demo-app/module-frontend-application/register-and-mint/)
6. [14Part 5: Burning tokens](https://chromia.com/learn/ft4-demo-app/module-frontend-application/burn/)
7. [15Part 6: Transferring assets](https://chromia.com/learn/ft4-demo-app/module-frontend-application/transfer/)
8. [16Part 7: Deploying onchain](https://chromia.com/learn/ft4-demo-app/module-frontend-application/deploy-onchain/)

[Learn](https://chromia.com/learn/)[Asset management system with React and FT4](https://chromia.com/learn/ft4-demo-app/)

08 / 16Module 2: The blockchain dappIntermediate

# Test the asset management system

This last lesson covers testing the asset management system end to end. You will work through several test scenarios and check that the system behaves as expected in each one.

## Test Setup

Start with a test module that imports every component the tests depend on:

src/test/module.rell

```
@test module;

import lib.ft4.core.accounts.strategies.open.{ ras_open };
import lib.ft4.external.accounts. { get_accounts_by_signer };
import lib.ft4.external.accounts.strategies.{ register_account };
import lib.ft4.external.assets. { get_asset_balance, get_assets_by_name, transfer };
import lib.ft4.test.core. { ft_auth_operation_for, create_auth_descriptor };
import lib.ft4.utils. { paged_result };
import ^.main. { register_and_mint_asset };
```

## Structuring

The utils file contains helper functions for fetching account information:

src/test/utils.rell

```
struct account_dto {    id: byte_array;    type: text;}struct asset_dto {    id: byte_array;    name: text;    symbol: text;    decimals: integer;    blockchain_rid: byte_array;    icon_url: text;    type: text;    supply: big_integer;}function account_from_gtv(paged_result) = account_dto.from_gtv_pretty(paged_result.data[0]);function asset_from_gtv(paged_result) = asset_dto.from_gtv_pretty(paged_result.data[0]);
```

You will rely on these helpers across the tests to handle account data consistently.

## Test Cases

### 1. Asset Registration Test

The first test creates an account and registers a new asset with it. It confirms that the asset is created and that the asset registry correctly records it.

src/test/asset\_management\_test.rell

```
function test_create_account_and_register_and_mint_asset() {
    val alice = rell.test.keypairs.alice;
    val trudy = rell.test.keypairs.trudy;

    val required_asset = (
        name = "TestAsset1",
        id = x"A85755C27F76B25C4139C929861E81C001C8C449F0260A9132F8ECFEA9075C39", //(asset_name, chain_context.blockchain_rid).hash();
        symbol = "TST1",
        decimals = 10,
        blockchain_rid = x"0000000000000000000000000000000000000000000000000000000000000000",
        icon_url = "https://url-to-asset-1-icon",
        type = "ft4",
        supply = 100L,
    );
    val auth_descriptor_alice = create_auth_descriptor(alice.pub, ["A", "T"], null.to_gtv());
    val auth_descriptor_trudy = create_auth_descriptor(trudy.pub, ["A", "T"], null.to_gtv());
    rell.test.tx()
        .op(ras_open(auth_descriptor_alice))
        .op(register_account())
        
        .sign(alice)
        .run();
    rell.test.tx()
        .op(ras_open(auth_descriptor_trudy))
        .op(register_account()).sign(trudy)
        .run();

    rell.test.tx()
        .op(ft_auth_operation_for(alice.pub))
        .op(
            register_and_mint_asset(
                required_asset.name,
                required_asset.symbol,
                required_asset.decimals,
                required_asset.supply,
                required_asset.icon_url
            )
        )
        .sign(alice)
        .run();

    //query
    val asset_gtv = get_assets_by_name(required_asset.name, 10, null);
    assert_equals(asset_gtv.data[0], required_asset.to_gtv_pretty());

    val asset_data = asset_from_gtv(asset_gtv);

    val account_alice = account_from_gtv(get_accounts_by_signer(alice.pub, 10, null));
    val account_trudy = account_from_gtv(get_accounts_by_signer(trudy.pub, 10, null));

    val balance_alice = get_asset_balance(account_alice.id, asset_data.id);
    assert_equals(balance_alice?.amount, required_asset.supply);
}
```

### 2. Multiple Asset Registration Test

The second test enforces the rule that each account can register only one asset. Registering the first asset must succeed, and a second attempt with a different asset must fail.

src/test/asset\_management\_test.rell

```
function test_create_account_and_register_and_mint_2_assets_must_fail() {
    val alice = rell.test.keypairs.alice;
    val trudy = rell.test.keypairs.trudy;
    val required_asset_1 = (
        name = "TestAsset1",
        symbol = "TST1",
        decimals = 10,
        icon_url = "https://url-to-asset-1-icon",
        type = "ft4",
        supply = 100L,
    );
    val required_asset_2 = (
        name = "TestAsset2",
        symbol = "TST2",
        decimals = 10,
        icon_url = "https://url-to-asset-1-icon",
        type = "ft4",
        supply = 100L,
    );
    val auth_descriptor_alice = create_auth_descriptor(alice.pub, ["A", "T"], null.to_gtv());
    val auth_descriptor_trudy = create_auth_descriptor(trudy.pub, ["A", "T"], null.to_gtv());
    rell.test.tx()
        .op(ras_open(auth_descriptor_alice))
        .op(register_account()).sign(alice)
        .run();
    rell.test.tx()
        .op(ras_open(auth_descriptor_trudy))
        .op(register_account()).sign(trudy)
        .run();
    rell.test.tx()
        .op(ft_auth_operation_for(alice.pub))
        .op(
            register_and_mint_asset(
                required_asset_1.name,
                required_asset_1.symbol,
                required_asset_1.decimals,
                required_asset_1.supply,
                required_asset_1.icon_url
            )
        ).sign(alice)
        .run();

    rell.test.tx()
        .op(ft_auth_operation_for(alice.pub))
        .op(
            register_and_mint_asset(
                required_asset_2.name,
                required_asset_2.symbol,
                required_asset_2.decimals,
                required_asset_2.supply,
                required_asset_2.icon_url
            )
        ).sign(alice)
        .run_must_fail();
}
```

### Transfer Test

You don't need to write your own transfer logic, because the FT4 library already includes a transfer operation. The following test exercises asset transfers with it:

src/test/asset\_management\_test.rell

```
function test_create_account_and_register_and_mint_and_transfer_asset() {
    val alice = rell.test.keypairs.alice;
    val trudy = rell.test.keypairs.trudy;
    val asset_name = "TestAsset1";
    val asset_amount = 100;
    val asset_amount_to_transfer = 20;

    val required_asset = (
        name = "TestAsset1",
        symbol = "TST1",
        decimals = 10,
        icon_url = "https://url-to-asset-1-icon",
        type = "ft4",
        supply = 100L,
    );

    val auth_descriptor = create_auth_descriptor(alice.pub, ["A", "T"], null.to_gtv());
    val auth_descriptor_trudy = create_auth_descriptor(trudy.pub, ["A", "T"], null.to_gtv());
    rell.test.tx()
        .op(ras_open(auth_descriptor))
        .op(register_account()).sign(alice)
        .run();
    rell.test.tx()
        .op(ras_open(auth_descriptor_trudy))
        .op(register_account()).sign(trudy)
        .run();

    rell.test.tx()
        .op(ft_auth_operation_for(alice.pub))
        .op(
            register_and_mint_asset(
                required_asset.name,
                required_asset.symbol,
                required_asset.decimals,
                required_asset.supply,
                required_asset.icon_url
            )
        ).sign(alice)
        .run();

    //query
    val asset_data = asset_from_gtv(get_assets_by_name(required_asset.name, 10, null));

    val account_alice = account_from_gtv(get_accounts_by_signer(alice.pub, 10, null));
    val account_trudy = account_from_gtv(get_accounts_by_signer(trudy.pub, 10, null));

    rell.test.tx()
        .op(ft_auth_operation_for(alice.pub))
        .op(transfer(account_trudy.id, asset_data.id, asset_amount_to_transfer)).sign(alice)
        .run();

    val alice_balance = get_asset_balance(account_alice.id, asset_data.id);
    assert_equals(alice_balance?.amount, asset_amount - asset_amount_to_transfer);

    val trudy_balance = get_asset_balance(account_trudy.id, asset_data.id);
    assert_equals(trudy_balance?.amount, asset_amount_to_transfer);
}
```

A transfer goes through these main stages:

1. **Account Setup**: The sender and the receiver each need a valid account.
2. **Asset Registration**: The asset has to be registered and minted.
3. **Transfer Execution**: The transfer runs through FT4's transfer operation.
4. **Balance Verification**: The test confirms that both balances changed correctly.

## Running Tests

Run the full test suite with the Chromia CLI:

bash

```nolines
chr test
```

Written for this site from Chromia’s public course. Code samples are the course’s own.

[← Previous**Asset Registration and Minting**](https://chromia.com/learn/ft4-demo-app/module-blockchain/asset-registration/)[Next →**Module 3: The frontend application**](https://chromia.com/learn/ft4-demo-app/module-frontend-application/)

On this page

* [Test Setup](#test-setup)
* [Structuring](#structuring)
* [Test Cases](#test-cases)
* [Running Tests](#running-tests)
