• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

blockcoders / kuma-wallet / ebbd3c69-fda1-4bf1-80ea-77bef87d3d87

pending completion
ebbd3c69-fda1-4bf1-80ea-77bef87d3d87

Pull #8

circleci

Ruben
fix tests
Pull Request #8: Milestone 2

876 of 1103 branches covered (79.42%)

Branch coverage included in aggregate %.

3452 of 3452 new or added lines in 44 files covered. (100.0%)

6647 of 7185 relevant lines covered (92.51%)

6.69 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.12
/src/pages/send/components/Destination.tsx
1
import { useEffect, useState, useMemo } from "react";
2✔
2
import { Combobox } from "@headlessui/react";
2✔
3
import Extension from "@src/Extension";
2✔
4
import { useFormContext } from "react-hook-form";
2✔
5
import { useAccountContext, useNetworkContext } from "@src/providers";
2✔
6
import { transformAddress } from "@src/utils/account-utils";
2✔
7
import { isHex } from "@polkadot/util";
2✔
8

2✔
9
export const Destination = () => {
2✔
10
  const {
14✔
11
    state: { selectedChain },
14✔
12
  } = useNetworkContext();
14✔
13
  const {
14✔
14
    state: { selectedAccount },
14✔
15
  } = useAccountContext();
14✔
16

14✔
17
  const { register } = useFormContext();
14✔
18

14✔
19
  const [destinationAddress, setDestinationAddress] = useState("");
14✔
20

14✔
21
  const [accountToSelect, setAccountToSelect] = useState<any>([]);
14✔
22
  const [isOpenOptions, setisOpenOptions] = useState(false);
14✔
23

14✔
24
  useEffect(() => {
14✔
25
    if (selectedAccount.key && selectedChain?.name) {
4✔
26
      (async () => {
4✔
27
        const { contacts, ownAccounts, recent } =
4✔
28
          await Extension.getRegistryAddresses();
4✔
29

4✔
30
        const _ownAccounts = ownAccounts
4✔
31
          .map((acc) =>
4✔
32
            !isHex(acc.address)
4!
33
              ? {
×
34
                  name: acc.name,
×
35
                  address: transformAddress(
×
36
                    acc.address,
×
37
                    selectedChain?.addressPrefix
×
38
                  ),
×
39
                }
×
40
              : acc
4✔
41
          )
4✔
42
          .filter((acc) => acc.address !== selectedAccount.value.address);
4✔
43

4✔
44
        const _contacts = contacts.map((acc) =>
4✔
45
          !isHex(acc.address)
4!
46
            ? {
×
47
                name: acc.name,
×
48
                address: transformAddress(
×
49
                  acc.address,
×
50
                  selectedChain?.addressPrefix
×
51
                ),
×
52
              }
×
53
            : acc
4✔
54
        );
4✔
55

4✔
56
        const _recent = recent.map((acc) =>
4✔
57
          !isHex(acc.address)
4!
58
            ? {
×
59
                address: transformAddress(
×
60
                  acc.address,
×
61
                  selectedChain?.addressPrefix
×
62
                ),
×
63
              }
×
64
            : acc
4✔
65
        );
4✔
66

4✔
67
        setAccountToSelect([
4✔
68
          {
4✔
69
            label: "recent",
4✔
70
            values: _recent,
4✔
71
          },
4✔
72
          {
4✔
73
            label: "contacts",
4✔
74
            values: _contacts,
4✔
75
          },
4✔
76
          {
4✔
77
            label: "own accounts",
4✔
78
            values: _ownAccounts,
4✔
79
          },
4✔
80
        ]);
4✔
81
      })();
4✔
82
    }
4✔
83
  }, [selectedAccount?.key, selectedChain?.name]);
14✔
84

14✔
85
  const onChangeAccount = (account: string) => {
14✔
86
    setDestinationAddress(account);
2✔
87
  };
2✔
88

14✔
89
  const filteredAddresses = useMemo(() => {
14✔
90
    if (accountToSelect.length === 0 || !selectedAccount?.value?.address)
10✔
91
      return [];
10✔
92
    if (!destinationAddress) return accountToSelect || [];
10!
93

2✔
94
    const [recent, contacts, ownAccounts] = accountToSelect;
2✔
95

2✔
96
    const filters = [];
2✔
97

2✔
98
    const filterdRecent = recent.values.filter((v: { address: string }) =>
2✔
99
      v?.address?.toLowerCase().includes(destinationAddress.toLowerCase() || "")
2!
100
    );
2✔
101
    const filterdContacts = contacts.values.filter((v: { address: string }) =>
2✔
102
      v?.address?.toLowerCase().includes(destinationAddress.toLowerCase() || "")
2!
103
    );
2✔
104
    const filterdOwnAccounts = ownAccounts.values.filter(
2✔
105
      (v: { address: string }) =>
2✔
106
        v?.address
2✔
107
          ?.toLowerCase()
2✔
108
          .includes(destinationAddress.toLowerCase() || "")
2!
109
    );
2✔
110

2✔
111
    filterdRecent.length > 0 &&
2✔
112
      filters.push({
2✔
113
        label: "recent",
2✔
114
        values: filterdRecent,
2✔
115
      });
2✔
116

10✔
117
    filterdContacts.length > 0 &&
10✔
118
      filters.push({
2✔
119
        label: "contacts",
2✔
120
        values: filterdContacts,
2✔
121
      });
2✔
122

10✔
123
    filterdOwnAccounts.length > 0 &&
10✔
124
      filters.push({
2✔
125
        label: "own accounts",
2✔
126
        values: filterdOwnAccounts,
2✔
127
      });
2✔
128

10✔
129
    return filters;
10✔
130
  }, [accountToSelect, destinationAddress, selectedAccount?.value?.address]);
14✔
131

14✔
132
  const { onChange, ...r } = { ...register("destinationAccount") };
14✔
133

14✔
134
  return (
14✔
135
    <Combobox
14✔
136
      value={destinationAddress}
14✔
137
      onChange={(value) => {
14✔
138
        onChangeAccount(value);
×
139
        onChange({
×
140
          target: {
×
141
            name: "destinationAccount",
×
142
            value,
×
143
          },
×
144
          type: "string",
×
145
        });
×
146
      }}
×
147
    >
14✔
148
      <div className="relative mt-1">
14✔
149
        <Combobox.Input
14✔
150
          data-testid="destination-input"
14✔
151
          autoComplete="off"
14✔
152
          className="bg-[#343A40] text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 flex w-full p-2.5  border-gray-600 placeholder-gray-400 text-white"
14✔
153
          {...r}
14✔
154
          onChange={({ target, type }) => {
14✔
155
            onChangeAccount(target.value);
2✔
156
            onChange({ target, type });
2✔
157
          }}
2✔
158
          onClick={() => setisOpenOptions(true)}
14✔
159
          onBlur={() => {
14✔
160
            setTimeout(() => {
×
161
              setisOpenOptions(false);
×
162
            }, 200);
×
163
          }}
×
164
        />
14✔
165
        {filteredAddresses.length > 0 && (
14✔
166
          <Combobox.Options
6✔
167
            data-testid="destination-options"
6✔
168
            static={isOpenOptions}
6✔
169
            className="absolute mt-1 max-h-60 w-full overflow-auto rounded-md bg-[#212529] py-1  shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none z-50 px-2"
6✔
170
          >
6✔
171
            {filteredAddresses.map(
6✔
172
              (type: {
6✔
173
                label: string;
18✔
174
                values: { name: string; address: string }[];
18✔
175
              }) =>
18✔
176
                type.values?.length > 0 && (
18✔
177
                  <div key={type.label}>
18✔
178
                    <div className="flex items-center gap-3 whitespace-nowrap">
18✔
179
                      <p className="text-[#808385] text-lg">{type.label}</p>
18✔
180
                      <div className="h-[1px] w-full bg-[#343A40]" />
18✔
181
                    </div>
18✔
182
                    {type.values.map(
18✔
183
                      (acc: { name: string; address: string }) => (
18✔
184
                        <Combobox.Option
18✔
185
                          key={acc.address}
18✔
186
                          value={acc.address}
18✔
187
                          className="hover:bg-gray-400 hover:bg-opacity-20 cursor-pointer rounded-md overflow-hidden px-1 py-1 font-extralight text-sm text-gray-300"
18✔
188
                          onClick={() => setisOpenOptions(false)}
18✔
189
                        >
18✔
190
                          <p>{acc.name}</p>
18✔
191
                          <p className="text-ellipsis overflow-hidden">
18✔
192
                            {acc.address}
18✔
193
                          </p>
18✔
194
                        </Combobox.Option>
18✔
195
                      )
18✔
196
                    )}
18✔
197
                  </div>
18✔
198
                )
6✔
199
            )}
6✔
200
          </Combobox.Options>
6✔
201
        )}
14✔
202
      </div>
14✔
203
    </Combobox>
14✔
204
  );
14✔
205
};
4✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc