2022-12-14 17:25:10 +00:00
|
|
|
import pytest
|
2023-01-09 20:31:15 +00:00
|
|
|
import redis
|
2023-05-13 07:44:25 +00:00
|
|
|
from redis import asyncio as aioredis
|
2022-12-14 17:25:10 +00:00
|
|
|
from .utility import *
|
2023-09-16 09:27:20 +00:00
|
|
|
from json import JSONDecoder, JSONEncoder, dumps
|
2022-12-14 17:25:10 +00:00
|
|
|
|
2023-07-17 10:13:12 +00:00
|
|
|
jane = {"name": "Jane", "Age": 33, "Location": "Chawton"}
|
2022-12-14 17:25:10 +00:00
|
|
|
|
2023-07-17 10:13:12 +00:00
|
|
|
json_num = {"a": {"a": 1, "b": 2, "c": 3}}
|
2022-12-14 17:25:10 +00:00
|
|
|
|
|
|
|
|
2023-03-25 13:05:30 +00:00
|
|
|
async def get_set_json(connection: aioredis.Redis, key, value, path="$"):
|
|
|
|
encoder = JSONEncoder()
|
|
|
|
await connection.execute_command("json.set", key, path, encoder.encode(value))
|
|
|
|
result = await connection.execute_command("json.get", key, path)
|
|
|
|
decoder = JSONDecoder()
|
|
|
|
return decoder.decode(result)
|
2022-12-14 17:25:10 +00:00
|
|
|
|
|
|
|
|
2023-03-25 13:05:30 +00:00
|
|
|
async def test_basic_json_get_set(async_client: aioredis.Redis):
|
2022-12-14 17:25:10 +00:00
|
|
|
key_name = "test-json-key"
|
2023-03-25 13:05:30 +00:00
|
|
|
result = await get_set_json(connection=async_client, key=key_name, value=jane)
|
|
|
|
assert result, "failed to set JSON value"
|
|
|
|
the_type = await async_client.type(key_name)
|
2024-07-27 17:05:00 +00:00
|
|
|
assert the_type == "ReJSON-RL"
|
2022-12-14 17:25:10 +00:00
|
|
|
assert len(result) == 1
|
2023-07-17 10:13:12 +00:00
|
|
|
assert result[0]["name"] == "Jane"
|
|
|
|
assert result[0]["Age"] == 33
|
2022-12-14 17:25:10 +00:00
|
|
|
|
|
|
|
|
2023-03-25 13:05:30 +00:00
|
|
|
async def test_access_json_value_as_string(async_client: aioredis.Redis):
|
2022-12-14 17:25:10 +00:00
|
|
|
key_name = "test-json-key"
|
2023-03-25 13:05:30 +00:00
|
|
|
result = await get_set_json(async_client, key_name, value=jane)
|
2022-12-14 17:25:10 +00:00
|
|
|
assert result is not None, "failed to set JSON value"
|
|
|
|
# make sure that we have valid JSON here
|
2023-03-25 13:05:30 +00:00
|
|
|
the_type = await async_client.type(key_name)
|
2024-07-27 17:05:00 +00:00
|
|
|
assert the_type == "ReJSON-RL"
|
2022-12-14 17:25:10 +00:00
|
|
|
# you cannot access this key as string
|
2023-03-25 13:05:30 +00:00
|
|
|
try:
|
|
|
|
result = await async_client.get(key_name)
|
|
|
|
assert False, "should not be able to access JSON value as string"
|
2023-05-13 07:44:25 +00:00
|
|
|
except redis.exceptions.ResponseError as e:
|
2023-03-25 13:05:30 +00:00
|
|
|
assert e.args[0] == "WRONGTYPE Operation against a key holding the wrong kind of value"
|
2022-12-14 17:25:10 +00:00
|
|
|
|
|
|
|
|
2023-03-25 13:05:30 +00:00
|
|
|
async def test_reset_key_to_string(async_client: aioredis.Redis):
|
2022-12-14 17:25:10 +00:00
|
|
|
key_name = "test-json-key"
|
2023-03-25 13:05:30 +00:00
|
|
|
result = await get_set_json(async_client, key=key_name, value=jane)
|
2022-12-14 17:25:10 +00:00
|
|
|
assert result is not None, "failed to set JSON value"
|
|
|
|
# make sure that we have valid JSON here
|
2023-03-25 13:05:30 +00:00
|
|
|
the_type = await async_client.type(key_name)
|
2024-07-27 17:05:00 +00:00
|
|
|
assert the_type == "ReJSON-RL"
|
2023-03-25 13:05:30 +00:00
|
|
|
|
2022-12-14 17:25:10 +00:00
|
|
|
# set the key to be string - this is legal
|
2023-03-25 13:05:30 +00:00
|
|
|
await async_client.set(key_name, "some random value")
|
|
|
|
result = await async_client.get(key_name)
|
2022-12-14 17:25:10 +00:00
|
|
|
assert result == "some random value"
|
2023-03-25 13:05:30 +00:00
|
|
|
|
2022-12-14 17:25:10 +00:00
|
|
|
# For JSON set the update the root path, we are allowing
|
|
|
|
# to change the type to JSON and override it
|
2023-03-25 13:05:30 +00:00
|
|
|
result = await get_set_json(async_client, key=key_name, value=jane)
|
|
|
|
the_type = await async_client.type(key_name)
|
2024-07-27 17:05:00 +00:00
|
|
|
assert the_type == "ReJSON-RL"
|
2022-12-14 17:25:10 +00:00
|
|
|
|
|
|
|
|
2023-03-25 13:05:30 +00:00
|
|
|
async def test_update_value(async_client: aioredis.Redis):
|
2022-12-14 17:25:10 +00:00
|
|
|
key_name = "test-json-key"
|
2023-03-25 13:05:30 +00:00
|
|
|
result = await get_set_json(async_client, key=key_name, value=json_num)
|
2022-12-14 17:25:10 +00:00
|
|
|
assert result is not None, "failed to set JSON value"
|
|
|
|
# make sure that we have valid JSON here
|
2023-03-25 13:05:30 +00:00
|
|
|
the_type = await async_client.type(key_name)
|
2024-07-27 17:05:00 +00:00
|
|
|
assert the_type == "ReJSON-RL"
|
2023-07-17 10:13:12 +00:00
|
|
|
result = await get_set_json(async_client, value="0", key=key_name, path="$.a.*")
|
2022-12-14 17:25:10 +00:00
|
|
|
assert len(result) == 3
|
|
|
|
# make sure that all the values under 'a' where set to 0
|
2023-07-17 10:13:12 +00:00
|
|
|
assert result == ["0", "0", "0"]
|
2023-03-25 13:05:30 +00:00
|
|
|
|
2022-12-14 17:25:10 +00:00
|
|
|
# Ensure that after we're changing this into STRING type, it will no longer work
|
2023-03-25 13:05:30 +00:00
|
|
|
await async_client.set(key_name, "some random value")
|
|
|
|
assert await async_client.type(key_name) == "string"
|
|
|
|
try:
|
2023-07-17 10:13:12 +00:00
|
|
|
await get_set_json(async_client, value="0", key=key_name, path="$.a.*")
|
2023-03-25 13:05:30 +00:00
|
|
|
assert False, "should not be able to modify JSON value as string"
|
2023-05-13 07:44:25 +00:00
|
|
|
except redis.exceptions.ResponseError as e:
|
2023-03-25 13:05:30 +00:00
|
|
|
assert e.args[0] == "WRONGTYPE Operation against a key holding the wrong kind of value"
|
|
|
|
assert await async_client.type(key_name) == "string"
|
2023-09-16 09:27:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"description,expected_value,expected_type",
|
|
|
|
(
|
|
|
|
("array", "[]", "array"),
|
|
|
|
("string", dumps("dragonfly"), "string"),
|
|
|
|
("number", dumps(3.50), "number"),
|
|
|
|
("object", dumps({"dragon": "fly"}, separators=(",", ":")), "object"),
|
|
|
|
("boolean true", "true", "boolean"),
|
|
|
|
("boolean false", "false", "boolean"),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
async def test_arrappend(async_client: aioredis.Redis, description, expected_value, expected_type):
|
|
|
|
key_name = "test-json-key"
|
|
|
|
|
|
|
|
await async_client.execute_command("json.set", key_name, "$", "[]")
|
|
|
|
await async_client.execute_command("json.arrappend", key_name, "$", expected_value)
|
|
|
|
|
|
|
|
# make sure the value is as expected
|
|
|
|
first_element = await async_client.execute_command("json.get", key_name, "$[0]")
|
|
|
|
assert first_element == "[{}]".format(expected_value)
|
|
|
|
|
|
|
|
# make sure the type is as expected
|
|
|
|
actual_type = await async_client.execute_command("json.type", key_name, "$[0]")
|
|
|
|
assert actual_type[0] == expected_type
|