Repository: bitcoin/bitcoin
File: test/functional/wallet_labels.py (Python)

Code before:
            'desc': f'pkh({pubkey})',
            'label': '*',
            'timestamp': 'now',
        }])

        assert_equal(response[0]['success'], False)
        assert_equal(response[0]['error']['code'], -11)
        assert_equal(response[0]['error']['message'], "Invalid label name")

        for rpc_call in rpc_calls:
            assert_raises_rpc_error(-11, "Invalid label name", *rpc_call, label="*")

    def run_test(self):
        # Check that there's no UTXO on the node
        node = self.nodes[0]
        assert_equal(len(node.listunspent()), 0)

        self.log.info("Checking listlabels' invalid parameters")
        assert_raises_rpc_error(-8, "Invalid 'purpose' argument, must be a known purpose string, typically 'send', or 'receive'.", node.listlabels, "notavalidpurpose")
        assert_raises_rpc_error(-8, "Invalid 'purpose' argument, must be a known purpose string, typically 'send', or 'receive'.", node.listlabels, "unknown")

        # Note each time we call generate, all generated coins go into
        # the same address, so we call twice to get two addresses w/50 each
        self.generatetoaddress(node, nblocks=1, address=node.getnewaddress(label='coinbase'))
        self.generatetoaddress(node, nblocks=COINBASE_MATURITY + 1, address=node.getnewaddress(label='coinbase'))
        assert_equal(node.getbalance(), 100)

        # there should be 2 address groups
        # each with 1 address with a balance of 50 Bitcoins
        address_groups = node.listaddressgroupings()
        assert_equal(len(address_groups), 2)
        # the addresses aren't linked now, but will be after we send to the
        # common address
        linked_addresses = set()
        for address_group in address_groups:
            assert_equal(len(address_group), 1)
            assert_equal(len(address_group[0]), 3)
            assert_equal(address_group[0][1], 50)
            assert_equal(address_group[0][2], 'coinbase')
            linked_addresses.add(address_group[0][0])

        # send 50 from each address to a third address not in this wallet
        common_address = "msf4WtN1YQKXvNtvdFYt9JBnUD2FB41kjr"
        node.sendmany(
            amounts={common_address: 100},
            subtractfeefrom=[common_address],
            minconf=1,
        )
        # there should be 1 address group, with the previously
        # unlinked addresses now linked (they both have 0 balance)
        address_groups = node.listaddressgroupings()

Review comment (bug):
In commit "test: Add functional tests for named argument parsing" (24391ed7804a724a62034b21150c89e45ac9b625)

Not important, but I feel like "only if" in this comment is a little misleading, since the test is not confirming parameter is treated as positional only in these cases. Also it is not checking the "valid JSON" case at all. Could also be nice to replace comments in this function with log.info or log.debug calls. And it might be nice to make this example mirror the `my=wallet` example mentioned in client.cpp. Maybe consider updating this to something like:

```python
self.log.info("Test bitcoin-cli -named passes parameter containing '=' by position if it does not specify a known parameter name and is in a string position")
equals_label = "my=label"
result = node.cli("-named", "getnetaddress", equals_label).send_cli()
```

Code after:
            'desc': f'pkh({pubkey})',
            'label': '*',
            'timestamp': 'now',
        }])

        assert_equal(response[0]['success'], False)
        assert_equal(response[0]['error']['code'], -11)
        assert_equal(response[0]['error']['message'], "Invalid label name")

        for rpc_call in rpc_calls:
            assert_raises_rpc_error(-11, "Invalid label name", *rpc_call, label="*")

    def test_label_named_parameter_handling(self):
        """Test that getnewaddress with labels containing '=' characters is handled correctly in -named mode"""
        self.log.info("Test getnewaddress label parameter handling")
        node = self.nodes[0]

        # Test getnewaddress with explicit named parameter containing '='
        label_with_equals = "wallet=wallet"
        result = node.cli("-named", "getnewaddress", f"label={label_with_equals}").send_cli()
        address = result.strip()
        addr_info = node.getaddressinfo(address)
        assert_equal(addr_info.get('labels', []), [label_with_equals])

        self.log.info("Test bitcoin-cli -named passes parameter containing '=' by position if it does not specify a known parameter name and is in a string position")
        equals_label = "my=label"
        result = node.cli("-named", "getnewaddress", equals_label).send_cli()
        address = result.strip()
        addr_info = node.getaddressinfo(address)
        assert_equal(addr_info.get('labels', []), [equals_label])

        self.log.info("getnewaddress label parameter handling test completed successfully")

    def run_test(self):
        # Check that there's no UTXO on the node
        node = self.nodes[0]
        assert_equal(len(node.listunspent()), 0)

        self.log.info("Checking listlabels' invalid parameters")
        assert_raises_rpc_error(-8, "Invalid 'purpose' argument, must be a known purpose string, typically 'send', or 'receive'.", node.listlabels, "notavalidpurpose")
        assert_raises_rpc_error(-8, "Invalid 'purpose' argument, must be a known purpose string, typically 'send', or 'receive'.", node.listlabels, "unknown")

        # Note each time we call generate, all generated coins go into
        # the same address, so we call twice to get two addresses w/50 each
        self.generatetoaddress(node, nblocks=1, address=node.getnewaddress(label='coinbase'))
        self.generatetoaddress(node, nblocks=COINBASE_MATURITY + 1, address=node.getnewaddress(label='coinbase'))
        assert_equal(node.getbalance(), 100)

        # there should be 2 address groups
        # each with 1 address with a balance of 50 Bitcoins
        address_groups = node.listaddressgroupings()