Skip to content

Commit 304f479

Browse files
committed
Add tests
1 parent b6f2523 commit 304f479

2 files changed

Lines changed: 188 additions & 0 deletions

File tree

datajunction-server/tests/api/namespaces_test.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,3 +918,80 @@ def get_deny_all_service():
918918

919919
assert response.status_code in (200, 201)
920920
assert response.json() == []
921+
922+
923+
@pytest.mark.asyncio
924+
async def test_create_namespace_auto_creates_owner_role(
925+
client_with_service_setup: AsyncClient,
926+
) -> None:
927+
"""
928+
Test that creating a namespace automatically creates an owner role.
929+
930+
When a namespace is created, the system should:
931+
1. Create a role named "{namespace}-owner"
932+
2. Add a MANAGE scope on the namespace
933+
3. Assign the role to the creating user
934+
"""
935+
# Create a new namespace
936+
response = await client_with_service_setup.post(
937+
"/namespaces/testrbac.autorole",
938+
)
939+
assert response.status_code == 201
940+
941+
# Verify the owner role was created
942+
response = await client_with_service_setup.get("/roles/testrbac-owner")
943+
assert response.status_code == 200
944+
role_data = response.json()
945+
assert role_data["name"] == "testrbac-owner"
946+
assert role_data["description"] == "Owner role for namespace testrbac"
947+
948+
# Check scopes - should have MANAGE on the namespace
949+
assert len(role_data["scopes"]) == 1
950+
scope = role_data["scopes"][0]
951+
assert scope["action"] == "manage"
952+
assert scope["scope_type"] == "namespace"
953+
assert scope["scope_value"] == "testrbac"
954+
955+
# Verify the child namespace also got an owner role
956+
response = await client_with_service_setup.get("/roles/testrbac.autorole-owner")
957+
assert response.status_code == 200
958+
child_role_data = response.json()
959+
assert child_role_data["name"] == "testrbac.autorole-owner"
960+
961+
# Check the role is assigned to the creator
962+
response = await client_with_service_setup.get("/roles/testrbac-owner/assignments")
963+
assert response.status_code == 200
964+
assignments = response.json()
965+
assert len(assignments) >= 1
966+
# The creator should be assigned this role
967+
assert any(a["principal"]["username"] == "dj" for a in assignments)
968+
969+
970+
@pytest.mark.asyncio
971+
async def test_create_namespace_skips_existing_role(
972+
client_with_service_setup: AsyncClient,
973+
) -> None:
974+
"""
975+
Test that creating a namespace skips role creation if role already exists.
976+
"""
977+
# First, manually create a role with the expected name
978+
response = await client_with_service_setup.post(
979+
"/roles/",
980+
json={
981+
"name": "preexisting-owner",
982+
"description": "Manually created role",
983+
},
984+
)
985+
assert response.status_code == 201
986+
987+
# Now create a namespace with the same name
988+
response = await client_with_service_setup.post(
989+
"/namespaces/preexisting",
990+
)
991+
assert response.status_code == 201
992+
993+
# The role should still be the original one (not overwritten)
994+
response = await client_with_service_setup.get("/roles/preexisting-owner")
995+
assert response.status_code == 200
996+
role_data = response.json()
997+
assert role_data["description"] == "Manually created role" # Original description

datajunction-server/tests/api/nodes_test.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6298,3 +6298,114 @@ async def test_copy_nodes(
62986298
# ]
62996299
# for copied in copied_dimensions:
63006300
# assert copied in original_dimensions
6301+
6302+
6303+
@pytest.mark.asyncio
6304+
async def test_create_node_auto_creates_owner_role(
6305+
client_with_service_setup: AsyncClient,
6306+
) -> None:
6307+
"""
6308+
Test that creating a node automatically creates an owner role.
6309+
6310+
When a node is created, the system should:
6311+
1. Create a role named "{node_name}-owner"
6312+
2. Add a MANAGE scope on the node
6313+
3. Assign the role to the creating user
6314+
"""
6315+
# First create a namespace for our test node
6316+
response = await client_with_service_setup.post("/namespaces/nodeautotest")
6317+
assert response.status_code == 201
6318+
6319+
# Create a source node
6320+
response = await client_with_service_setup.post(
6321+
"/nodes/source/",
6322+
json={
6323+
"name": "nodeautotest.test_source",
6324+
"description": "Test source for auto-role creation",
6325+
"catalog": "default",
6326+
"schema_": "test_schema",
6327+
"table": "test_table",
6328+
"columns": [
6329+
{"name": "id", "type": "int"},
6330+
{"name": "name", "type": "string"},
6331+
],
6332+
"mode": "published",
6333+
},
6334+
)
6335+
assert response.status_code == 201
6336+
6337+
# Verify the owner role was created for the node
6338+
response = await client_with_service_setup.get(
6339+
"/roles/nodeautotest.test_source-owner",
6340+
)
6341+
assert response.status_code == 200
6342+
role_data = response.json()
6343+
assert role_data["name"] == "nodeautotest.test_source-owner"
6344+
assert role_data["description"] == "Owner role for node nodeautotest.test_source"
6345+
6346+
# Check scopes - should have MANAGE on the node
6347+
assert len(role_data["scopes"]) == 1
6348+
scope = role_data["scopes"][0]
6349+
assert scope["action"] == "manage"
6350+
assert scope["scope_type"] == "node"
6351+
assert scope["scope_value"] == "nodeautotest.test_source"
6352+
6353+
# Check the role is assigned to the creator
6354+
response = await client_with_service_setup.get(
6355+
"/roles/nodeautotest.test_source-owner/assignments",
6356+
)
6357+
assert response.status_code == 200
6358+
assignments = response.json()
6359+
assert len(assignments) >= 1
6360+
# The creator should be assigned this role
6361+
assert any(a["principal"]["username"] == "dj" for a in assignments)
6362+
6363+
6364+
@pytest.mark.asyncio
6365+
async def test_create_transform_node_auto_creates_owner_role(
6366+
client_with_service_setup: AsyncClient,
6367+
) -> None:
6368+
"""
6369+
Test that creating a transform node also auto-creates owner role.
6370+
"""
6371+
# First create namespace and source node
6372+
await client_with_service_setup.post("/namespaces/transformtest")
6373+
6374+
await client_with_service_setup.post(
6375+
"/nodes/source/",
6376+
json={
6377+
"name": "transformtest.source",
6378+
"description": "Source for transform test",
6379+
"catalog": "default",
6380+
"schema_": "test_schema",
6381+
"table": "test_table",
6382+
"columns": [
6383+
{"name": "id", "type": "int"},
6384+
{"name": "value", "type": "float"},
6385+
],
6386+
"mode": "published",
6387+
},
6388+
)
6389+
6390+
# Create a transform node
6391+
response = await client_with_service_setup.post(
6392+
"/nodes/transform/",
6393+
json={
6394+
"name": "transformtest.my_transform",
6395+
"description": "Test transform",
6396+
"query": "SELECT id, value FROM transformtest.source",
6397+
"mode": "published",
6398+
},
6399+
)
6400+
assert response.status_code == 201
6401+
6402+
# Verify owner role was created
6403+
response = await client_with_service_setup.get(
6404+
"/roles/transformtest.my_transform-owner",
6405+
)
6406+
assert response.status_code == 200
6407+
role_data = response.json()
6408+
assert role_data["name"] == "transformtest.my_transform-owner"
6409+
assert len(role_data["scopes"]) == 1
6410+
assert role_data["scopes"][0]["action"] == "manage"
6411+
assert role_data["scopes"][0]["scope_type"] == "node"

0 commit comments

Comments
 (0)