Files
Jedd Morgan 2594ce0382
Publish Python Package / test (push) Has been cancelled
Publish Python Package / Build and Publish Python Package (push) Has been cancelled
fix(specklepy): small tweaks to the url handling of accounts (#452)
* set url post query

* Use canonical url if available

* format

* revert canonical url changes

* quick tweak

* small tweak again

* Add test
2025-09-11 17:34:06 +01:00

145 lines
4.5 KiB
Python

import random
import uuid
from typing import Dict
from urllib.parse import parse_qs, urlparse
import pytest
import requests
from specklepy.api.client import SpeckleClient
from specklepy.core.api import operations
from specklepy.core.api.credentials import Account, UserInfo
from specklepy.core.api.enums import ProjectVisibility
from specklepy.core.api.inputs.project_inputs import ProjectCreateInput
from specklepy.core.api.inputs.version_inputs import CreateVersionInput
from specklepy.core.api.models import Version
from specklepy.core.api.models.current import Project, ServerInfo
from specklepy.logging import metrics
from specklepy.objects.base import Base
from specklepy.objects.geometry import Point
from specklepy.transports.server.server import ServerTransport
from .fakemesh import FakeDirection, FakeMesh
metrics.disable()
@pytest.fixture(scope="session")
def host() -> str:
return "localhost:3000"
def seed_user(host: str) -> Dict[str, str]:
seed = uuid.uuid4().hex
user_dict = {
"email": f"{seed[0:7]}@example.org",
"password": "$uper$3cr3tP@ss",
"name": f"{seed[0:7]} Name",
"company": "test spockle",
}
r = requests.post(
url=f"http://{host}/auth/local/register?challenge=pyspeckletests",
data=user_dict,
# do not follow redirects here, they lead to the frontend, which might not be
# running in a test environment
# causing the response to not be OK in the end
allow_redirects=False,
)
if not r.ok:
raise Exception(f"Cannot seed user: {r.reason}")
redirect_url = urlparse(r.headers.get("location"))
access_code = parse_qs(redirect_url.query)["access_code"][0] # type: ignore
r_tokens = requests.post(
url=f"http://{host}/auth/token",
json={
"appSecret": "spklwebapp",
"appId": "spklwebapp",
"accessCode": access_code,
"challenge": "pyspeckletests",
},
)
user_dict.update(**r_tokens.json())
return user_dict
def create_version(client: SpeckleClient, project_id: str, model_id: str) -> Version:
remote = ServerTransport(project_id, client)
objectId = operations.send(
Base(applicationId="ASDF"), [remote], use_default_cache=False
)
input = CreateVersionInput(
object_id=objectId, model_id=model_id, project_id=project_id
)
return client.version.create(input)
@pytest.fixture(scope="session")
def user_dict(host: str) -> Dict[str, str]:
return seed_user(host)
@pytest.fixture(scope="session")
def second_user_dict(host: str) -> Dict[str, str]:
return seed_user(host)
def create_client(host: str, token: str) -> SpeckleClient:
client = SpeckleClient(host=host, use_ssl=False)
client.authenticate_with_token(token)
assert isinstance(client.account, Account)
assert isinstance(client.account.userInfo, UserInfo)
assert client.account.userInfo.id
assert client.account.userInfo.name
assert isinstance(client.account.serverInfo, ServerInfo)
assert client.account.serverInfo.url
assert client.account.serverInfo.name
return client
@pytest.fixture(scope="session")
def client(host: str, user_dict: Dict[str, str]) -> SpeckleClient:
return create_client(host, user_dict["token"])
@pytest.fixture(scope="session")
def second_client(host: str, second_user_dict: Dict[str, str]):
return create_client(host, second_user_dict["token"])
@pytest.fixture(scope="session")
def sample_project(client: SpeckleClient) -> Project:
input = ProjectCreateInput(
name="a sample stream for testing",
description="a stream created for testing",
visibility=ProjectVisibility.PUBLIC,
)
return client.project.create(input)
@pytest.fixture(scope="session")
def mesh() -> FakeMesh:
mesh = FakeMesh()
mesh.name = "my_mesh"
mesh.vertices = [random.uniform(0, 10) for _ in range(1, 210)]
mesh.faces = list(range(1, 210))
mesh["@(100)colours"] = [random.uniform(0, 10) for _ in range(1, 210)]
mesh["@()default_chunk"] = [random.uniform(0, 10) for _ in range(1, 210)]
mesh.cardinal_dir = FakeDirection.WEST
mesh.test_bases = [Base(applicationId=f"test {i}") for i in range(1, 22)]
mesh.detach_this = Base(applicationId="predefined detached base")
mesh["@detach"] = Base(applicationId="detached base")
mesh["@detached_list"] = [
42,
"some text",
[1, 2, 3],
Base(applicationId="detached within a list"),
]
mesh.origin = Point(x=4, y=2, z=0, units="m")
return mesh