active user

This commit is contained in:
Jedd Morgan
2024-10-24 14:13:19 +01:00
parent a10b2594d3
commit cc004c8e6b
20 changed files with 528 additions and 312 deletions
+7 -5
View File
@@ -2,7 +2,6 @@ from deprecated import deprecated
from specklepy.api.credentials import Account
from specklepy.api.resources import (
active_user,
branch,
commit,
object,
@@ -13,9 +12,12 @@ from specklepy.api.resources import (
user,
)
from specklepy.core.api.client import SpeckleClient as CoreSpeckleClient
from specklepy.core.api.resources.model import ModelResource
from specklepy.core.api.resources.project import ProjectResource
from specklepy.core.api.resources.version import VersionResource
# TODO: re-reference core.api resources
from specklepy.core.api.resources.active_user_resource import ActiveUserResource
from specklepy.core.api.resources.model_resource import ModelResource
from specklepy.core.api.resources.project_resource import ProjectResource
from specklepy.core.api.resources.version_resource import VersionResource
from specklepy.logging import metrics
@@ -83,7 +85,7 @@ class SpeckleClient(CoreSpeckleClient):
client=self.httpclient,
server_version=server_version,
)
self.active_user = active_user.Resource(
self.active_user = ActiveUserResource(
account=self.account,
basepath=self.url,
client=self.httpclient,
+3 -1
View File
@@ -2,7 +2,9 @@ from datetime import datetime
from typing import List, Optional
from specklepy.api.models import PendingStreamCollaborator, User
from specklepy.core.api.resources.active_user import Resource as CoreResource
from specklepy.core.api.resources.active_user_resource import (
ActiveUserResource as CoreResource,
)
from specklepy.logging import metrics
+32 -8
View File
@@ -11,7 +11,6 @@ from gql.transport.websockets import WebsocketsTransport
from specklepy.core.api import resources
from specklepy.core.api.credentials import Account, get_account_from_token
from specklepy.core.api.resources import (
active_user,
branch,
commit,
object,
@@ -21,6 +20,10 @@ from specklepy.core.api.resources import (
subscriptions,
user,
)
from specklepy.core.api.resources.active_user_resource import ActiveUserResource
from specklepy.core.api.resources.model_resource import ModelResource
from specklepy.core.api.resources.project_resource import ProjectResource
from specklepy.core.api.resources.version_resource import VersionResource
from specklepy.logging import metrics
from specklepy.logging.exceptions import SpeckleException, SpeckleWarning
@@ -200,24 +203,45 @@ class SpeckleClient:
self.server = server.Resource(
account=self.account, basepath=self.url, client=self.httpclient
)
server_version = None
try:
server_version = self.server.version()
except Exception:
pass
self.user = user.Resource(
account=self.account,
basepath=self.url,
client=self.httpclient,
server_version=server_version,
)
self.other_user = other_user.Resource(
account=self.account,
basepath=self.url,
client=self.httpclient,
server_version=server_version,
)
self.active_user = active_user.Resource(
self.active_user = ActiveUserResource(
account=self.account,
basepath=self.url,
client=self.httpclient,
server_version=server_version,
)
self.project = ProjectResource(
account=self.account,
basepath=self.url,
client=self.httpclient,
server_version=server_version,
)
self.model = ModelResource(
account=self.account,
basepath=self.url,
client=self.httpclient,
server_version=server_version,
)
self.version = VersionResource(
account=self.account,
basepath=self.url,
client=self.httpclient,
server_version=server_version,
)
# Deprecated Resources
self.user = user.Resource(
account=self.account,
basepath=self.url,
client=self.httpclient,
+2 -1
View File
@@ -12,10 +12,11 @@ from specklepy.transports.sqlite import SQLiteTransport
class UserInfo(BaseModel):
id: Optional[str] = None
name: Optional[str] = None
email: Optional[str] = None
company: Optional[str] = None
id: Optional[str] = None
avatar: Optional[str] = None
class Account(BaseModel):
@@ -0,0 +1,9 @@
from typing import Optional
from pydantic import BaseModel
class UserUpdateInput(BaseModel):
avatar: Optional[str] = None
bio: Optional[str] = None
company: Optional[str] = None
name: Optional[str] = None
+10 -275
View File
@@ -1,279 +1,14 @@
from datetime import datetime, timezone
from typing import List, Optional
from deprecated import deprecated
from specklepy.core.api.models import FE1_DEPRECATION_VERSION
from specklepy.core.api.resources.active_user_resource import ActiveUserResource
from gql import gql
from specklepy.core.api.models import (
ActivityCollection,
PendingStreamCollaborator,
User,
@deprecated(
reason="Class renamed to ActiveUserResource", version=FE1_DEPRECATION_VERSION
)
from specklepy.core.api.resource import ResourceBase
from specklepy.logging.exceptions import SpeckleException
class Resource(ActiveUserResource):
"""
Class renamed to ActiveUserResource
"""
NAME = "active_user"
class Resource(ResourceBase):
"""API Access class for users"""
def __init__(self, account, basepath, client, server_version) -> None:
super().__init__(
account=account,
basepath=basepath,
client=client,
name=NAME,
server_version=server_version,
)
self.schema = User
def get(self) -> User:
"""Gets the profile of a user. If no id argument is provided,
will return the current authenticated user's profile
(as extracted from the authorization header).
Arguments:
id {str} -- the user id
Returns:
User -- the retrieved user
"""
query = gql(
"""
query User {
activeUser {
id
email
name
bio
company
avatar
verified
profiles
role
}
}
"""
)
params = {}
return self.make_request(query=query, params=params, return_type="activeUser")
def update(
self,
name: Optional[str] = None,
company: Optional[str] = None,
bio: Optional[str] = None,
avatar: Optional[str] = None,
) -> bool:
"""Updates your user profile. All arguments are optional.
Arguments:
name {str} -- your name
company {str} -- the company you may or may not work for
bio {str} -- tell us about yourself
avatar {str} -- a nice photo of yourself
Returns @deprecated(version=DEPRECATION_VERSION, reason=DEPRECATION_TEXT):
bool -- True if your profile was updated successfully
"""
query = gql(
"""
mutation UserUpdate($user: UserUpdateInput!) {
userUpdate(user: $user)
}
"""
)
params = {"name": name, "company": company, "bio": bio, "avatar": avatar}
params = {"user": {k: v for k, v in params.items() if v is not None}}
if not params["user"]:
return SpeckleException(
message=(
"You must provide at least one field to update your user profile"
)
)
return self.make_request(
query=query, params=params, return_type="userUpdate", parse_response=False
)
def activity(
self,
limit: int = 20,
action_type: Optional[str] = None,
before: Optional[datetime] = None,
after: Optional[datetime] = None,
cursor: Optional[datetime] = None,
) -> ActivityCollection:
"""
Get the activity from a given stream in an Activity collection.
Step into the activity `items` for the list of activity.
If no id argument is provided, will return the current authenticated user's
activity (as extracted from the authorization header).
Note: all timestamps arguments should be `datetime` of any tz as they will be
converted to UTC ISO format strings
user_id {str} -- the id of the user to get the activity from
action_type {str} -- filter results to a single action type
(eg: `commit_create` or `commit_receive`)
limit {int} -- max number of Activity items to return
before {datetime} -- latest cutoff for activity
(ie: return all activity _before_ this time)
after {datetime} -- oldest cutoff for activity
(ie: return all activity _after_ this time)
cursor {datetime} -- timestamp cursor for pagination
"""
query = gql(
"""
query UserActivity(
$action_type: String,
$before:DateTime,
$after: DateTime,
$cursor: DateTime,
$limit: Int
){
activeUser {
activity(
actionType: $action_type,
before: $before,
after: $after,
cursor: $cursor,
limit: $limit
) {
totalCount
cursor
items {
actionType
info
userId
streamId
resourceId
resourceType
message
time
}
}
}
}
"""
)
params = {
"limit": limit,
"action_type": action_type,
"before": before.astimezone(timezone.utc).isoformat() if before else before,
"after": after.astimezone(timezone.utc).isoformat() if after else after,
"cursor": cursor.astimezone(timezone.utc).isoformat() if cursor else cursor,
}
return self.make_request(
query=query,
params=params,
return_type=["activeUser", "activity"],
schema=ActivityCollection,
)
def get_all_pending_invites(self) -> List[PendingStreamCollaborator]:
"""Get all of the active user's pending stream invites
Requires Speckle Server version >= 2.6.4
Returns:
List[PendingStreamCollaborator]
-- a list of pending invites for the current user
"""
self._check_invites_supported()
query = gql(
"""
query StreamInvites {
streamInvites{
id
token
inviteId
streamId
streamName
projectId
projectName
title
role
invitedBy {
id
name
bio
company
avatar
verified
role
}
}
}
"""
)
return self.make_request(
query=query,
return_type="streamInvites",
schema=PendingStreamCollaborator,
)
def get_pending_invite(
self, stream_id: str, token: Optional[str] = None
) -> Optional[PendingStreamCollaborator]:
"""Get a particular pending invite for the active user on a given stream.
If no invite_id is provided, any valid invite will be returned.
Requires Speckle Server version >= 2.6.4
Arguments:
stream_id {str} -- the id of the stream to look for invites on
token {str} -- the token of the invite to look for (optional)
Returns:
PendingStreamCollaborator
-- the invite for the given stream (or None if it isn't found)
"""
self._check_invites_supported()
query = gql(
"""
query StreamInvite($streamId: String!, $token: String) {
streamInvite(streamId: $streamId, token: $token) {
id
token
inviteId
streamId
streamName
projectId
projectName
title
role
invitedBy {
id
name
bio
company
avatar
verified
role
}
}
}
"""
)
params = {"streamId": stream_id}
if token:
params["token"] = token
return self.make_request(
query=query,
params=params,
return_type="streamInvite",
schema=PendingStreamCollaborator,
)
pass
@@ -0,0 +1,373 @@
from datetime import datetime, timezone
from typing import List, Optional
from deprecated import deprecated
from gql import gql
from specklepy.core.api.inputs.project_inputs import UserProjectsFilter
from specklepy.core.api.inputs.user_inputs import UserUpdateInput
from specklepy.core.api.models import (
FE1_DEPRECATION_REASON,
FE1_DEPRECATION_VERSION,
ActivityCollection,
PendingStreamCollaborator,
User,
)
from specklepy.core.api.new_models import Project
from specklepy.core.api.resource import ResourceBase
from specklepy.core.api.responses import DataResponse, ResourceCollection
from specklepy.logging.exceptions import GraphQLException
NAME = "active_user"
class ActiveUserResource(ResourceBase):
"""API Access class for users"""
def __init__(self, account, basepath, client, server_version) -> None:
super().__init__(
account=account,
basepath=basepath,
client=client,
name=NAME,
server_version=server_version,
)
self.schema = User
def get(self) -> Optional[User]:
"""Gets the currently active user profile (as extracted from the authorization header)
Returns:
User -- the requested user, or none if no authentication token is provided to the Client
"""
QUERY = gql(
"""
query User {
data:activeUser {
id
email
name
bio
company
avatar
verified
role
}
}
"""
)
variables = {}
return self.make_request_and_parse_response(
DataResponse[Optional[User]], QUERY, variables
).data
# todo: breaking change, can we make this not?
def update(self, input: UserUpdateInput) -> User:
QUERY = gql(
"""
mutation ActiveUserMutations($input: UserUpdateInput!) {
data:activeUserMutations {
data:update(user: $input) {
id
email
name
bio
company
avatar
verified
role
}
}
}
"""
)
variables = {"input": input.model_dump(warnings="error")}
return self.make_request_and_parse_response(
DataResponse[DataResponse[User]], QUERY, variables
).data.data
def get_projects(
self,
*,
limit: int = 25,
cursor: Optional[str] = None,
filter: Optional[UserProjectsFilter] = None,
) -> ResourceCollection[Project]:
QUERY = gql(
"""
query User($limit : Int!, $cursor: String, $filter: UserProjectsFilter) {
data:activeUser {
data:projects(limit: $limit, cursor: $cursor, filter: $filter) {
totalCount
items {
id
name
description
visibility
allowPublicComments
role
createdAt
updatedAt
sourceApps
workspaceId
}
}
}
}
"""
)
variables = {
"limit": limit,
"cursor": cursor,
"filter": filter.model_dump(warnings="error") if filter else None,
}
response = self.make_request_and_parse_response(
DataResponse[Optional[DataResponse[ResourceCollection[Project]]]],
QUERY,
variables,
)
if response.data is None:
raise GraphQLException(
"GraphQL response indicated that the ActiveUser could not be found"
)
return response.data.data
def get_project_invites(self) -> List[PendingStreamCollaborator]:
QUERY = gql(
"""
query ProjectInvites {
data:activeUser {
data:projectInvites {
id
inviteId
invitedBy {
avatar
bio
company
id
name
role
verified
}
projectId
projectName
role
title
token
user {
id,
name,
bio,
company,
verified,
role,
}
}
}
}
"""
)
variables = {}
response = self.make_request_and_parse_response(
DataResponse[Optional[DataResponse[List[PendingStreamCollaborator]]]],
QUERY,
variables,
)
if response.data is None:
raise GraphQLException(
"GraphQL response indicated that the ActiveUser could not be found"
)
return response.data.data
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
def activity(
self,
limit: int = 20,
action_type: Optional[str] = None,
before: Optional[datetime] = None,
after: Optional[datetime] = None,
cursor: Optional[datetime] = None,
) -> ActivityCollection:
"""
Get the activity from a given stream in an Activity collection.
Step into the activity `items` for the list of activity.
If no id argument is provided, will return the current authenticated user's
activity (as extracted from the authorization header).
Note: all timestamps arguments should be `datetime` of any tz as they will be
converted to UTC ISO format strings
user_id {str} -- the id of the user to get the activity from
action_type {str} -- filter results to a single action type
(eg: `commit_create` or `commit_receive`)
limit {int} -- max number of Activity items to return
before {datetime} -- latest cutoff for activity
(ie: return all activity _before_ this time)
after {datetime} -- oldest cutoff for activity
(ie: return all activity _after_ this time)
cursor {datetime} -- timestamp cursor for pagination
"""
query = gql(
"""
query UserActivity(
$action_type: String,
$before:DateTime,
$after: DateTime,
$cursor: DateTime,
$limit: Int
){
activeUser {
activity(
actionType: $action_type,
before: $before,
after: $after,
cursor: $cursor,
limit: $limit
) {
totalCount
cursor
items {
actionType
info
userId
streamId
resourceId
resourceType
message
time
}
}
}
}
"""
)
params = {
"limit": limit,
"action_type": action_type,
"before": before.astimezone(timezone.utc).isoformat() if before else before,
"after": after.astimezone(timezone.utc).isoformat() if after else after,
"cursor": cursor.astimezone(timezone.utc).isoformat() if cursor else cursor,
}
return self.make_request(
query=query,
params=params,
return_type=["activeUser", "activity"],
schema=ActivityCollection,
)
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
def get_all_pending_invites(self) -> List[PendingStreamCollaborator]:
"""Get all of the active user's pending stream invites
Requires Speckle Server version >= 2.6.4
Returns:
List[PendingStreamCollaborator]
-- a list of pending invites for the current user
"""
self._check_invites_supported()
query = gql(
"""
query StreamInvites {
streamInvites{
id
token
inviteId
streamId
streamName
projectId
projectName
title
role
invitedBy {
id
name
bio
company
avatar
verified
role
}
}
}
"""
)
return self.make_request(
query=query,
return_type="streamInvites",
schema=PendingStreamCollaborator,
)
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
def get_pending_invite(
self, stream_id: str, token: Optional[str] = None
) -> Optional[PendingStreamCollaborator]:
"""Get a particular pending invite for the active user on a given stream.
If no invite_id is provided, any valid invite will be returned.
Requires Speckle Server version >= 2.6.4
Arguments:
stream_id {str} -- the id of the stream to look for invites on
token {str} -- the token of the invite to look for (optional)
Returns:
PendingStreamCollaborator
-- the invite for the given stream (or None if it isn't found)
"""
self._check_invites_supported()
query = gql(
"""
query StreamInvite($streamId: String!, $token: String) {
streamInvite(streamId: $streamId, token: $token) {
id
token
inviteId
streamId
streamName
projectId
projectName
title
role
invitedBy {
id
name
bio
company
avatar
verified
role
}
}
}
"""
)
params = {"streamId": stream_id}
if token:
params["token"] = token
return self.make_request(
query=query,
params=params,
return_type="streamInvite",
schema=PendingStreamCollaborator,
)
@@ -66,6 +66,7 @@ class ModelResource(ResourceBase):
self,
model_id: str,
project_id: str,
*,
versions_limit: int = 25,
versions_cursor: Optional[str] = None,
versions_filter: Optional[ModelVersionsFilter] = None,
@@ -135,6 +136,7 @@ class ModelResource(ResourceBase):
def get_models(
self,
project_id: str,
*,
models_limit: int = 25,
models_cursor: Optional[str] = None,
models_filter: Optional[ProjectModelsFilter] = None,
@@ -56,6 +56,7 @@ class ProjectResource(ResourceBase):
def get_with_models(
self,
project_id: str,
*,
models_limit: int = 25,
models_cursor: Optional[str] = None,
models_filter: Optional[ProjectModelsFilter] = None,
@@ -3,12 +3,8 @@ from typing import Optional
from gql import gql
from specklepy.core.api.inputs.model_inputs import (
CreateModelInput,
DeleteModelInput,
ModelVersionsFilter,
UpdateModelInput,
)
from specklepy.core.api.inputs.project_inputs import ProjectModelsFilter
from specklepy.core.api.inputs.version_inputs import (
CreateVersionInput,
DeleteVersionsInput,
@@ -16,8 +12,7 @@ from specklepy.core.api.inputs.version_inputs import (
MoveVersionsInput,
UpdateVersionInput,
)
from specklepy.core.api.models import Project
from specklepy.core.api.new_models import Model, ModelWithVersions, Version
from specklepy.core.api.new_models import Version
from specklepy.core.api.resource import ResourceBase
from specklepy.core.api.responses import DataResponse, ResourceCollection
@@ -72,6 +67,7 @@ class VersionResource(ResourceBase):
self,
model_id: str,
project_id: str,
*,
limit: int = 25,
cursor: Optional[str] = None,
filter: Optional[ModelVersionsFilter] = None,
+10 -8
View File
@@ -1,10 +1,13 @@
from deprecated import deprecated
import pytest
from specklepy.api.client import SpeckleClient
from specklepy.api.models import Activity, ActivityCollection, User
from specklepy.logging.exceptions import SpeckleException
from specklepy.core.api.inputs.user_inputs import UserUpdateInput
from specklepy.logging.exceptions import GraphQLException
@deprecated
@pytest.mark.run(order=2)
class TestUser:
def test_user_get_self(self, client: SpeckleClient, user_dict):
@@ -19,15 +22,14 @@ class TestUser:
def test_user_update(self, client: SpeckleClient):
bio = "i am a ghost in the machine"
failed_update = client.active_user.update()
assert isinstance(failed_update, SpeckleException)
with pytest.raises(GraphQLException):
client.active_user.update(UserUpdateInput())
updated = client.active_user.update(bio=bio)
updated = client.active_user.update(UserUpdateInput(bio=bio))
me = client.active_user.get()
assert updated is True
assert me.bio == bio
assert isinstance(updated, User)
assert isinstance(updated, User)
assert updated.bio == bio
def test_user_activity(self, client: SpeckleClient, second_user_dict):
my_activity = client.active_user.activity(limit=10)
@@ -0,0 +1,44 @@
import pytest
from specklepy.core.api.client import SpeckleClient
from specklepy.core.api.inputs.user_inputs import UserUpdateInput
from specklepy.core.api.inputs.project_inputs import ProjectCreateInput
from specklepy.core.api.models import User
from specklepy.core.api.responses import ResourceCollection
@pytest.mark.run()
class TestActiveUserResource:
def test_active_user_get(self, client: SpeckleClient):
res = client.active_user.get()
assert isinstance(res, User)
def test_active_user_update(self, client: SpeckleClient):
NEW_NAME = "Ron"
NEW_BIO = "Now I have a bio, isn't that nice!"
NEW_COMPANY = "Limited Cooperation Organization Inc"
input_data = UserUpdateInput(name=NEW_NAME, bio=NEW_BIO, company=NEW_COMPANY)
res = client.active_user.update(input_data)
assert isinstance(res, User)
assert res.name == NEW_NAME
assert res.bio == NEW_BIO
assert res.company == NEW_COMPANY
def test_active_user_get_projects(self, client: SpeckleClient):
existing = client.active_user.get_projects()
p1 = client.project.create(
ProjectCreateInput(name="Project 1", description=None, visibility=None)
)
p2 = client.project.create(
ProjectCreateInput(name="Project 2", description=None, visibility=None)
)
res = client.active_user.get_projects()
assert isinstance(res, ResourceCollection)
assert len(res.items) == len(existing.items) + 2
assert any(project.id == p1.id for project in res.items)
assert any(project.id == p2.id for project in res.items)
+2
View File
@@ -1,3 +1,4 @@
from deprecated import deprecated
import pytest
from specklepy.api import operations
@@ -5,6 +6,7 @@ from specklepy.api.models import Branch, Commit, Stream
from specklepy.transports.server import ServerTransport
@deprecated
class TestBranch:
@pytest.fixture(scope="module")
def branch(self):
+2
View File
@@ -1,3 +1,4 @@
from deprecated import deprecated
import pytest
from specklepy.api import operations
@@ -5,6 +6,7 @@ from specklepy.api.models import Commit, Stream
from specklepy.transports.server.server import ServerTransport
@deprecated
@pytest.mark.run(order=6)
class TestCommit:
@pytest.fixture(scope="module")
@@ -8,11 +8,13 @@ from specklepy.core.api.inputs.model_inputs import (
)
from specklepy.core.api.inputs.project_inputs import ProjectCreateInput
from specklepy.core.api.models import Model, Project
from specklepy.core.api.new_models import ProjectWithModels
from specklepy.core.api.responses import ResourceCollection
from specklepy.logging.exceptions import GraphQLException
@pytest.mark.run()
class TestModel:
class TestModelResource:
@pytest.fixture()
def test_project(self, client: SpeckleClient) -> Project:
project = client.project.create(
@@ -44,8 +46,7 @@ class TestModel:
)
result = client.model.create(input_data)
assert result is not None
assert result.id is not None
assert isinstance(result, Model)
assert result.name.lower() == name.lower()
assert result.description == description
@@ -54,6 +55,7 @@ class TestModel:
):
result = client.model.get(test_model.id, test_project.id)
assert isinstance(result, Model)
assert result.id == test_model.id
assert result.name == test_model.name
assert result.description == test_model.description
@@ -65,6 +67,7 @@ class TestModel:
):
result = client.model.get_models(test_project.id)
assert isinstance(result, ResourceCollection)
assert len(result.items) == 1
assert result.totalCount == 1
assert result.items[0].id == test_model.id
@@ -74,6 +77,7 @@ class TestModel:
):
result = client.project.get_with_models(test_project.id)
assert isinstance(result, ProjectWithModels)
assert result.id == test_project.id
assert len(result.models.items) == 1
assert result.models.totalCount == 1
@@ -94,6 +98,7 @@ class TestModel:
updated_model = client.model.update(update_data)
assert isinstance(updated_model, Model)
assert updated_model.id == test_model.id
assert updated_model.name.lower() == new_name.lower()
assert updated_model.description == new_description
+2
View File
@@ -1,3 +1,4 @@
from deprecated import deprecated
import pytest
from specklepy.api.models import Stream
@@ -7,6 +8,7 @@ from specklepy.serialization.base_object_serializer import BaseObjectSerializer
from specklepy.transports.sqlite import SQLiteTransport
@deprecated
class TestObject:
@pytest.fixture(scope="module")
def stream(self, client):
@@ -11,8 +11,8 @@ from specklepy.logging.exceptions import GraphQLException
@pytest.mark.run()
class TestProject:
@pytest.fixture(scope="session")
class TestProjectResource:
@pytest.fixture()
def test_project(self, client: SpeckleClient) -> Project:
project = client.project.create(
ProjectCreateInput(
@@ -44,7 +44,7 @@ class TestProject:
)
result = client.project.create(input_data)
assert result is not None
assert isinstance(result, Project)
assert result.id is not None
assert result.name == name
assert result.description == (description or "")
@@ -53,6 +53,7 @@ class TestProject:
def test_project_get(self, client: SpeckleClient, test_project: Project):
result = client.project.get(test_project.id)
assert isinstance(result, Project)
assert result.id == test_project.id
assert result.name == test_project.name
assert result.description == test_project.description
@@ -73,6 +74,7 @@ class TestProject:
updated_project = client.project.update(update_data)
assert isinstance(updated_project, Project)
assert updated_project.id == test_project.id
assert updated_project.name == new_name
assert updated_project.description == new_description
+2
View File
@@ -1,3 +1,4 @@
from deprecated import deprecated
import pytest
from specklepy.api.client import SpeckleClient
@@ -11,6 +12,7 @@ from specklepy.api.models import (
from specklepy.logging.exceptions import GraphQLException, SpeckleException
@deprecated
@pytest.mark.run(order=3)
class TestStream:
@pytest.fixture(scope="session")
+2
View File
@@ -1,3 +1,4 @@
from deprecated import deprecated
import pytest
from specklepy.api.client import SpeckleClient
@@ -5,6 +6,7 @@ from specklepy.api.models import Activity, ActivityCollection, User
from specklepy.logging.exceptions import SpeckleException
@deprecated
@pytest.mark.run(order=1)
class TestUser:
def test_user_get_self(self, client: SpeckleClient, user_dict):
@@ -12,13 +12,15 @@ from specklepy.core.api.inputs.version_inputs import (
UpdateVersionInput,
)
from specklepy.core.api.models import Model, Project, Version
from specklepy.core.api.new_models import ModelWithVersions
from specklepy.core.api.responses import ResourceCollection
from specklepy.logging.exceptions import GraphQLException
from specklepy.objects.base import Base
from specklepy.transports.server.server import ServerTransport
@pytest.mark.run(order=4)
class TestVersion:
@pytest.mark.run()
class TestVersionResource:
@pytest.fixture
def test_project(self, client: SpeckleClient) -> Project:
project = client.project.create(
@@ -63,6 +65,7 @@ class TestVersion:
):
result = client.version.get(test_version.id, test_project.id)
assert isinstance(result, Version)
assert result.id == test_version.id
assert result.message == test_version.message
@@ -75,6 +78,7 @@ class TestVersion:
):
result = client.version.get_versions(test_model_1.id, test_project.id)
assert isinstance(result, ResourceCollection)
assert len(result.items) == 1
assert result.totalCount == 1
assert result.items[0].id == test_version.id
@@ -100,6 +104,7 @@ class TestVersion:
):
result = client.model.get_with_versions(test_model_1.id, test_project.id)
assert isinstance(result, ModelWithVersions)
assert result.id == test_model_1.id
assert len(result.versions.items) == 1
assert result.versions.totalCount == 1
@@ -110,6 +115,7 @@ class TestVersion:
input_data = UpdateVersionInput(versionId=test_version.id, message=new_message)
updated_version = client.version.update(input_data)
assert isinstance(updated_version, Version)
assert updated_version.id == test_version.id
assert updated_version.message == new_message
assert updated_version.previewUrl == test_version.previewUrl
@@ -126,9 +132,11 @@ class TestVersion:
)
moved_model_id = client.version.move_to_model(input_data)
assert isinstance(moved_model_id, str)
assert moved_model_id == test_model_2.id
moved_version = client.version.get(test_version.id, test_project.id)
assert isinstance(moved_version, Version)
assert moved_version.id == test_version.id
assert moved_version.message == test_version.message
assert moved_version.previewUrl == test_version.previewUrl