Repository: redis/redis-py
File: tests/test_asyncio/test_commands.py (Python)

Code before:
    async def test_digest_response_when_available(self, r, value):
        key = "k:digest"
        await r.delete(key)
        await r.set(key, value)

        res = await r.digest(key)
        # got is str if decode_responses=True; ensure bytes->str for comparison
        if isinstance(res, bytes):
            res = res.decode()
        assert res is not None
        assert all(c in "0123456789abcdefABCDEF" for c in res)

        assert len(res) == 16

    @skip_if_server_version_lt("8.3.224")
    @pytest.mark.parametrize(
        "value", [b"", b"abc", b"The quick brown fox jumps over the lazy dog"]
    )
    async def test_local_digest_matches_server(self, r, value):
        key = "k:digest"
        await r.delete(key)
        await r.set(key, value)

        res_server = await r.digest(key)

        # Caution! This one is not executing execute_command and it not async
        res_local = r.digest_local(value)

        # got is str if decode_responses=True; ensure bytes->str for comparison
        if isinstance(res_server, bytes):
            assert isinstance(res_local, bytes)

        assert res_server is not None
        assert len(res_server) == 16
        assert res_local is not None
        assert len(res_local) == 16
        assert res_server == res_local

    @skip_if_server_version_lt("8.3.224")
    async def test_pipeline_digest(self, r):
        k1, k2 = "k:d1{42}", "k:d2{42}"
        await r.mset({k1: b"A", k2: b"B"})
        p = r.pipeline()
        p.digest(k1)
        p.digest(k2)
        out = await p.execute()
        assert len(out) == 2
        for d in out:
            if isinstance(d, bytes):
                d = d.decode()
            assert d is None or len(d) == 16

Review comment (suggestion):
The test only covers bytes values but the digest_local method accepts Union[bytes, str] according to its type annotation. Consider adding test cases with string values to ensure the method correctly handles both bytes and str inputs, especially considering encoding issues.

Code after:
    async def test_digest_response_when_available(self, r, value):
        key = "k:digest"
        await r.delete(key)
        await r.set(key, value)

        res = await r.digest(key)
        # got is str if decode_responses=True; ensure bytes->str for comparison
        if isinstance(res, bytes):
            res = res.decode()
        assert res is not None
        assert all(c in "0123456789abcdefABCDEF" for c in res)

        assert len(res) == 16

    @skip_if_server_version_lt("8.3.224")
    @pytest.mark.parametrize(
        "value",
        [
            b"",
            b"abc",
            b"The quick brown fox jumps over the lazy dog",
            "",
            "abc",
            "The quick brown fox jumps over the lazy dog",
        ],
    )
    async def test_local_digest_matches_server(self, r, value):
        key = "k:digest"
        await r.delete(key)
        await r.set(key, value)

        res_server = await r.digest(key)

        # Caution! This one is not executing execute_command and it is not async
        res_local = r.digest_local(value)

        # Verify type consistency between server and local digest
        if isinstance(res_server, bytes):
            assert isinstance(res_local, bytes)
        else:
            assert isinstance(res_local, str)

        assert res_server is not None
        assert len(res_server) == 16
        assert res_local is not None
        assert len(res_local) == 16
        assert res_server == res_local

    @skip_if_server_version_lt("8.3.224")
    async def test_pipeline_digest(self, r):
        k1, k2 = "k:d1{42}", "k:d2{42}"