Skip to content

Commit 7130f4b

Browse files
committed
tests groups 2 passing
1 parent cf83d59 commit 7130f4b

File tree

3 files changed

+191
-131
lines changed

3 files changed

+191
-131
lines changed

packages/pytest-simcore/src/pytest_simcore/simcore_webserver_groups_fixtures.py

Lines changed: 54 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111

1212
from collections.abc import AsyncIterator
13-
from typing import Any, Protocol
13+
from typing import Any
1414

1515
import pytest
1616
from aiohttp import web
@@ -19,41 +19,25 @@
1919
from models_library.groups import GroupsByTypeTuple
2020
from models_library.users import UserID
2121
from pytest_simcore.helpers.webserver_login import NewUser, UserInfoDict
22-
from simcore_service_webserver.groups import _groups_db
2322
from simcore_service_webserver.groups._groups_api import (
2423
add_user_in_group,
24+
create_organization,
2525
delete_organization,
2626
list_user_groups_with_read_access,
2727
)
2828

2929

30-
def _to_group_get_json(group, access_rights) -> dict[str, Any]:
30+
def _groupget_model_dump(group, access_rights) -> dict[str, Any]:
3131
return GroupGet.from_model(group, access_rights).model_dump(mode="json")
3232

3333

34-
#
35-
# FACTORY FIXTURES
36-
#
37-
38-
39-
class CreateUserGroupCallable(Protocol):
40-
async def __call__(
41-
self, app: web.Application, user_id: UserID, new_group: dict
42-
) -> dict[str, Any]:
43-
...
44-
45-
46-
@pytest.fixture
47-
def create_user_group() -> CreateUserGroupCallable:
48-
async def _create(
49-
app: web.Application, user_id: UserID, new_group: dict
50-
) -> dict[str, Any]:
51-
group, access_rights = await _groups_db.create_user_group(
52-
app, user_id=user_id, new_group=new_group
53-
)
54-
return _to_group_get_json(group=group, access_rights=access_rights)
55-
56-
return _create
34+
async def _create_organization(
35+
app: web.Application, user_id: UserID, new_group: dict
36+
) -> dict[str, Any]:
37+
group, access_rights = await create_organization(
38+
app, user_id=user_id, new_group_values=new_group
39+
)
40+
return _groupget_model_dump(group=group, access_rights=access_rights)
5741

5842

5943
#
@@ -62,36 +46,13 @@ async def _create(
6246

6347

6448
@pytest.fixture
65-
async def logged_user_groups_by_type(
66-
client: TestClient, logged_user: UserInfoDict
67-
) -> GroupsByTypeTuple:
68-
assert client.app
69-
70-
groups_by_type = await list_user_groups_with_read_access(
71-
client.app, user_id=logged_user["id"]
72-
)
73-
assert groups_by_type.primary
74-
assert groups_by_type.everyone
75-
return groups_by_type
76-
77-
78-
@pytest.fixture
79-
async def primary_group(
80-
client: TestClient,
81-
logged_user_groups_by_type: GroupsByTypeTuple,
82-
) -> dict[str, Any]:
83-
assert client.app
84-
assert logged_user_groups_by_type.primary
85-
return _to_group_get_json(*logged_user_groups_by_type.primary)
86-
87-
88-
@pytest.fixture
89-
async def standard_groups(
49+
async def standard_groups_owner(
9050
client: TestClient,
9151
logged_user: UserInfoDict,
92-
logged_user_groups_by_type: GroupsByTypeTuple,
93-
create_user_group: CreateUserGroupCallable,
94-
) -> AsyncIterator[list[dict[str, Any]]]:
52+
) -> AsyncIterator[UserInfoDict]:
53+
"""
54+
standard_groups_owner creates TWO organizations and adds logged_user in them
55+
"""
9556

9657
assert client.app
9758
# create a separate account to own standard groups
@@ -102,8 +63,9 @@ async def standard_groups(
10263
},
10364
client.app,
10465
) as owner_user:
66+
10567
# creates two groups
106-
sparc_group = await create_user_group(
68+
sparc_group = await _create_organization(
10769
app=client.app,
10870
user_id=owner_user["id"],
10971
new_group={
@@ -113,7 +75,7 @@ async def standard_groups(
11375
"inclusionRules": {"email": r"@(sparc)+\.(io|com)$"},
11476
},
11577
)
116-
team_black_group = await create_user_group(
78+
team_black_group = await _create_organization(
11779
app=client.app,
11880
user_id=owner_user["id"],
11981
new_group={
@@ -141,11 +103,7 @@ async def standard_groups(
141103
new_user_email=logged_user["email"],
142104
)
143105

144-
standard_groups = [
145-
_to_group_get_json(*sg) for sg in logged_user_groups_by_type.standard
146-
]
147-
148-
yield standard_groups
106+
yield owner_user
149107

150108
# clean groups
151109
await delete_organization(
@@ -157,11 +115,41 @@ async def standard_groups(
157115

158116

159117
@pytest.fixture
160-
async def all_group(
161-
client: TestClient,
118+
async def logged_user_groups_by_type(
119+
client: TestClient, logged_user: UserInfoDict, standard_groups_owner: UserInfoDict
120+
) -> GroupsByTypeTuple:
121+
assert client.app
122+
123+
assert logged_user["id"] != standard_groups_owner["id"]
124+
125+
groups_by_type = await list_user_groups_with_read_access(
126+
client.app, user_id=logged_user["id"]
127+
)
128+
assert groups_by_type.primary
129+
assert groups_by_type.everyone
130+
return groups_by_type
131+
132+
133+
@pytest.fixture
134+
def primary_group(
162135
logged_user_groups_by_type: GroupsByTypeTuple,
163136
) -> dict[str, Any]:
164-
assert client.app
165-
assert logged_user_groups_by_type.everyone
137+
"""`logged_user`'s primary group"""
138+
assert logged_user_groups_by_type.primary
139+
return _groupget_model_dump(*logged_user_groups_by_type.primary)
166140

167-
return _to_group_get_json(*logged_user_groups_by_type.everyone)
141+
142+
@pytest.fixture
143+
def standard_groups(
144+
logged_user_groups_by_type: GroupsByTypeTuple,
145+
) -> list[dict[str, Any]]:
146+
"""owned by `standard_groups_owner` and shared with `logged_user`"""
147+
return [_groupget_model_dump(*sg) for sg in logged_user_groups_by_type.standard]
148+
149+
150+
@pytest.fixture
151+
def all_group(
152+
logged_user_groups_by_type: GroupsByTypeTuple,
153+
) -> dict[str, Any]:
154+
assert logged_user_groups_by_type.everyone
155+
return _groupget_model_dump(*logged_user_groups_by_type.everyone)
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# pylint: disable=redefined-outer-name
2+
# pylint: disable=too-many-arguments
3+
# pylint: disable=too-many-statements
4+
# pylint: disable=unused-argument
5+
# pylint: disable=unused-variable
6+
7+
8+
import operator
9+
10+
import pytest
11+
from aiohttp.test_utils import TestClient
12+
from models_library.api_schemas_webserver.groups import GroupGet, MyGroupsGet
13+
from pydantic import TypeAdapter
14+
from pytest_simcore.helpers.assert_checks import assert_status
15+
from pytest_simcore.helpers.webserver_login import UserInfoDict
16+
from pytest_simcore.helpers.webserver_parametrizations import (
17+
ExpectedResponse,
18+
standard_role_response,
19+
)
20+
from servicelib.aiohttp import status
21+
from servicelib.aiohttp.application import create_safe_application
22+
from simcore_postgres_database.models.users import UserRole
23+
from simcore_service_webserver._meta import API_VTAG
24+
from simcore_service_webserver.application_settings import setup_settings
25+
from simcore_service_webserver.db.plugin import setup_db
26+
from simcore_service_webserver.groups.plugin import setup_groups
27+
from simcore_service_webserver.login.plugin import setup_login
28+
from simcore_service_webserver.rest.plugin import setup_rest
29+
from simcore_service_webserver.security.plugin import setup_security
30+
from simcore_service_webserver.session.plugin import setup_session
31+
from simcore_service_webserver.users.plugin import setup_users
32+
33+
34+
@pytest.fixture
35+
def client(
36+
event_loop,
37+
aiohttp_client,
38+
app_environment,
39+
postgres_db,
40+
) -> TestClient:
41+
app = create_safe_application()
42+
43+
setup_settings(app)
44+
setup_db(app)
45+
setup_session(app)
46+
setup_security(app)
47+
setup_rest(app)
48+
setup_login(app)
49+
setup_users(app)
50+
setup_groups(app)
51+
52+
return event_loop.run_until_complete(aiohttp_client(app))
53+
54+
55+
@pytest.mark.parametrize(*standard_role_response(), ids=str)
56+
async def test_list_groups_access_rights(
57+
client: TestClient,
58+
logged_user: UserInfoDict,
59+
user_role: UserRole,
60+
expected: ExpectedResponse,
61+
primary_group: dict[str, str],
62+
standard_groups: list[dict[str, str]],
63+
all_group: dict[str, str],
64+
):
65+
assert client.app
66+
url = client.app.router["list_groups"].url_for()
67+
assert f"{url}" == f"/{API_VTAG}/groups"
68+
69+
response = await client.get(f"{url}")
70+
await assert_status(
71+
response, expected.ok if user_role != UserRole.GUEST else status.HTTP_200_OK
72+
)
73+
74+
75+
@pytest.mark.parametrize("user_role", [UserRole.USER])
76+
async def test_list_user_groups(
77+
client: TestClient,
78+
user_role: UserRole,
79+
standard_groups_owner: UserInfoDict,
80+
logged_user: UserInfoDict,
81+
primary_group: dict[str, str],
82+
standard_groups: list[dict[str, str]],
83+
all_group: dict[str, str],
84+
):
85+
assert client.app
86+
assert logged_user["id"] != standard_groups_owner["id"]
87+
assert logged_user["role"] == user_role.value
88+
89+
# List all groups (organizations, primary, everyone and products) I belong to
90+
url = client.app.router["list_groups"].url_for()
91+
assert f"{url}" == f"/{API_VTAG}/groups"
92+
93+
response = await client.get(f"{url}")
94+
data, error = await assert_status(response, status.HTTP_200_OK)
95+
96+
my_groups = MyGroupsGet.model_validate(data)
97+
assert not error
98+
99+
assert my_groups.me.model_dump() == primary_group
100+
assert my_groups.all.model_dump() == all_group
101+
102+
assert my_groups.organizations
103+
assert len(my_groups.organizations) == len(standard_groups)
104+
105+
by_gid = operator.itemgetter("gid")
106+
assert sorted(
107+
TypeAdapter(list[GroupGet]).dump_python(my_groups.organizations, mode="json"),
108+
key=by_gid,
109+
) == sorted(standard_groups, key=by_gid)
110+
111+
for group in standard_groups:
112+
# try to delete a group
113+
url = client.app.router["delete_group"].url_for(gid=f"{group['gid']}")
114+
response = await client.delete(f"{url}")
115+
await assert_status(response, status.HTTP_403_FORBIDDEN)
116+
117+
# try to add some user in the group
118+
url = client.app.router["add_group_user"].url_for(gid=f"{group['gid']}")
119+
response = await client.post(f"{url}", json={"uid": logged_user["id"]})
120+
await assert_status(response, status.HTTP_403_FORBIDDEN)
121+
122+
# try to modify the user in the group
123+
url = client.app.router["update_group_user"].url_for(
124+
gid=f"{group['gid']}", uid=f"{logged_user['id']}"
125+
)
126+
response = await client.patch(
127+
f"{url}",
128+
json={"accessRights": {"read": True, "write": True, "delete": True}},
129+
)
130+
await assert_status(response, status.HTTP_403_FORBIDDEN)
131+
132+
# try to remove the user from the group
133+
url = client.app.router["delete_group_user"].url_for(
134+
gid=f"{group['gid']}", uid=f"{logged_user['id']}"
135+
)
136+
response = await client.delete(f"{url}")
137+
await assert_status(response, status.HTTP_403_FORBIDDEN)

services/web/server/tests/unit/with_dbs/01/test_groups.py

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -104,71 +104,6 @@ def _assert__group_user(
104104
assert "gid" in actual_user
105105

106106

107-
@pytest.mark.parametrize(*standard_role_response(), ids=str)
108-
async def test_list_groups(
109-
client: TestClient,
110-
logged_user: UserInfoDict,
111-
user_role: UserRole,
112-
expected: ExpectedResponse,
113-
primary_group: dict[str, str],
114-
standard_groups: list[dict[str, str]],
115-
all_group: dict[str, str],
116-
):
117-
assert client.app
118-
url = client.app.router["list_groups"].url_for()
119-
assert f"{url}" == f"/{API_VTAG}/groups"
120-
121-
response = await client.get(f"{url}")
122-
data, error = await assert_status(
123-
response, expected.ok if user_role != UserRole.GUEST else status.HTTP_200_OK
124-
)
125-
126-
if not error:
127-
assert isinstance(data, dict)
128-
129-
assert "me" in data
130-
_assert_group(data["me"])
131-
assert data["me"] == primary_group
132-
133-
assert "organizations" in data
134-
assert isinstance(data["organizations"], list)
135-
for group in data["organizations"]:
136-
_assert_group(group)
137-
assert data["organizations"] == standard_groups
138-
139-
assert "all" in data
140-
_assert_group(data["all"])
141-
assert data["all"] == all_group
142-
143-
for group in standard_groups:
144-
# try to delete a group
145-
url = client.app.router["delete_group"].url_for(gid=f"{group['gid']}")
146-
response = await client.delete(f"{url}")
147-
await assert_status(response, status.HTTP_403_FORBIDDEN)
148-
149-
# try to add some user in the group
150-
url = client.app.router["add_group_user"].url_for(gid=f"{group['gid']}")
151-
response = await client.post(f"{url}", json={"uid": logged_user["id"]})
152-
await assert_status(response, status.HTTP_403_FORBIDDEN)
153-
154-
# try to modify the user in the group
155-
url = client.app.router["update_group_user"].url_for(
156-
gid=f"{group['gid']}", uid=f"{logged_user['id']}"
157-
)
158-
response = await client.patch(
159-
f"{url}",
160-
json={"accessRights": {"read": True, "write": True, "delete": True}},
161-
)
162-
await assert_status(response, status.HTTP_403_FORBIDDEN)
163-
164-
# try to remove the user from the group
165-
url = client.app.router["delete_group_user"].url_for(
166-
gid=f"{group['gid']}", uid=f"{logged_user['id']}"
167-
)
168-
response = await client.delete(f"{url}")
169-
await assert_status(response, status.HTTP_403_FORBIDDEN)
170-
171-
172107
@pytest.mark.parametrize(*standard_role_response())
173108
async def test_group_creation_workflow(
174109
client: TestClient,

0 commit comments

Comments
 (0)