def test_create_unique_asset_type_content() -> None: """Request content to create an unique asset type.""" request_id = "123456" asset_type = AssetType("987654") content = json.loads(asset_type.put_request_content(request_id=request_id)) assert content == { "_type": "DefineAssetTypeRequest", "assetTypeId": asset_type.asset_type_id, "type": "Unique", "requestId": request_id, }
def test_create_quantifiable_asset_type_content() -> None: """Request content to create a quantifiable asset type.""" request_id = "123456" asset_type = AssetType("123456", scale=2) content = json.loads(asset_type.put_request_content(request_id=request_id)) assert content == { "_type": "DefineAssetTypeRequest", "assetTypeId": asset_type.asset_type_id, "type": "Quantifiable", "scale": 2, "requestId": request_id, }
def test_raises_value_error( invalid_scale: typing.Union[int, str, float]) -> None: """Raises ValueError on an invalid scale value.""" with pytest.raises(ValueError) as excinfo: AssetType(scale=invalid_scale) # type: ignore[arg-type] assert str(excinfo.value ) == f"must be a whole, positive number: '{invalid_scale}'"
def main() -> None: """Create identity, asset type and register products.""" product_data = read_product_data("nfc-tags.csv") # Usually we would store the identity (ID and key) on a safe place. manufacturer = PrivateIdentity( CryptoProtocol.SHA256WithECDSA.generate_private_key()) with Client(cfg.iov42_platform["url"], manufacturer) as client: # Create the identity client.put(manufacturer.public_identity) print(f"Created manufacturer identity: {manufacturer.identity_id}") # Create the asset typ used for the NFC tags. tag_type = AssetType() client.put(tag_type) print(f"Created tag asset type: {tag_type}") # Register the NFC tags on the distributed ledger in parallel. with ThreadPoolExecutor(max_workers=20) as executor: _ = executor.map( register_product, [client] * len(product_data), [tag_type] * len(product_data), product_data, ) executor.shutdown(wait=True)
def test_create_asset_type_claims_with_endorsement( alice_client: Client, existing_asset_type_id: str) -> None: """Create asset type claims and endorsements on an unique asset all at once.""" claims = [b"claim-1", b"claim-2"] response = alice_client.put( AssetType(existing_asset_type_id), claims=claims, endorse=True, create_claims=True, ) prefix = "/".join(( "/api/v1/asset-types", existing_asset_type_id, "claims", )) # Affected resources: for each endorsements we also created the claim. assert len( response.resources) == 2 * len(claims) # type: ignore[union-attr] for c in [hashed_claim(c) for c in claims]: assert "/".join( (prefix, c)) in response.resources # type: ignore[union-attr] assert ("/".join( (prefix, c, "endorsements", alice_client.identity.identity_id)) in response.resources # type: ignore[union-attr] )
def create_asset_type(ctx: click.core.Context, identity: str, asset_type_id: str, scale: int) -> None: """Create an asset type.""" asset_type = AssetType(asset_type_id) id = _load_identity(identity) client = Client(ctx.obj["url"], id) _ = client.put(asset_type, request_id=ctx.obj["request_id"]) print(f"asset_type_id: {asset_type_id}")
def test_invalid_id(invalid_id: str) -> None: """Raises ValueError in case the provided ID is invalid.""" with pytest.raises(ValueError) as excinfo: AssetType(invalid_id) assert ( str(excinfo.value) == f"invalid identifier '{invalid_id}' - valid characters are [a-zA-Z0-9._\\-+]" ) pass
def test_create_asset_type_claims_content() -> None: """Request content to create claims on an asset type.""" request_id = "123456" claims = [b"claim-1", b"claim-2"] asset_type = AssetType("123456") content = json.loads( asset_type.put_request_content(request_id=request_id, claims=claims)) hashed_claims = content.pop("claims") assert content == { "_type": "CreateAssetTypeClaimsRequest", "subjectId": asset_type.asset_type_id, "requestId": request_id, } assert len(hashed_claims) == len(claims) for hc in [hashed_claim(c) for c in claims]: assert hc in hashed_claims
def test_response_asset_type( client: Client, mocked_requests_200: respx.MockTransport, ) -> None: """Platform response to the request to create an asset type.""" entity = AssetType() response = client.put(entity) assert response.resources == [ "/api/v1/asset-types/" + entity.asset_type_id ] # type: ignore[union-attr]
def test_create_asset_type_endorsements_content( identity: PrivateIdentity) -> None: """Request content to create claims and endorsements for an asset type.""" request_id = "123456" claims = [b"claim-1", b"claim-2"] asset_type = AssetType("123456") content = json.loads( asset_type.put_request_content(request_id=request_id, claims=claims, endorser=identity)) # Signatures are always different, we have to verify the signature endorsements = content.pop("endorsements") assert content == { "_type": "CreateAssetTypeEndorsementsRequest", "subjectId": asset_type.asset_type_id, "endorserId": identity.identity_id, "requestId": request_id, } for c, s in endorsements.items(): identity.verify_signature( s, ";".join((asset_type.asset_type_id, c)).encode())
def test_create_asset_type_claims(alice_client: Client, existing_asset_type_id: str) -> None: """Create asset claims on an asset type.""" claims = [b"claim-1", b"claim-2"] response = alice_client.put(AssetType(existing_asset_type_id), claims=claims) prefix = "/".join(( "/api/v1/asset-types", existing_asset_type_id, "claims", )) assert len(response.resources) == len(claims) # type: ignore[union-attr] for c in [hashed_claim(c) for c in claims]: assert "/".join( (prefix, c)) in response.resources # type: ignore[union-attr]
existing_identity_claims: List[bytes], ) -> None: """Bob endorrses Alice's claims.""" response = bob_client.put( alice_public_identity, claims=existing_identity_claims, endorse=True, ) # Affected resources: for each endorsements we also changed the claims. assert len(response.resources) == len( 2 * existing_identity_claims) # type: ignore[union-attr] @pytest.mark.integr @pytest.mark.parametrize("asset_type", [AssetType(), AssetType(scale=3)]) def test_create_asset_type(alice_client: Client, asset_type: AssetType) -> None: """Create an asset types on an iov42 platform.""" response = alice_client.put(asset_type) assert ("/".join(("/api/v1/asset-types", asset_type.asset_type_id )) == response.resources[0] # type: ignore[union-attr] ) @pytest.mark.integr def test_create_asset_type_claims(alice_client: Client, existing_asset_type_id: str) -> None: """Create asset claims on an asset type.""" claims = [b"claim-1", b"claim-2"]
def existing_asset_type_id(alice_client: Client) -> str: """Creates an asset type owned by Alice on an iov42 platform .""" asset_type = AssetType() alice_client.put(asset_type) return asset_type.asset_type_id
def existing_quantifiable_asset_type_id(alice_client: Client) -> str: """Creates a quantifiable asset type owned by Alice on an iov42 platform .""" asset_type = AssetType(scale=2) alice_client.put(asset_type) return asset_type.asset_type_id
def test_read_no_node_id() -> None: """Raise TypeError if no node_id is provided for a GET request.""" with pytest.raises(TypeError) as excinfo: Request("GET", "https://example.org/", AssetType()) assert str(excinfo.value) == "missing required keyword argument: 'node_id'"
def test_relative_path() -> None: """Return relative URL where the asset type information can be read.""" asset = AssetType() assert asset.resource == "/".join( ("/api/v1/asset-types", asset.asset_type_id))
import json import uuid import pytest from iov42.core import Asset from iov42.core import AssetType from iov42.core import CryptoProtocol from iov42.core import Entity from iov42.core import PrivateIdentity from iov42.core import Request entities = [ PrivateIdentity( CryptoProtocol.SHA256WithECDSA.generate_private_key()).public_identity, AssetType(), Asset(asset_type_id="123456"), ] def id_class_name(value: Entity) -> str: """Provide class name as test identifier.""" return str(value.__class__.__name__) @pytest.mark.parametrize("entity", entities, ids=id_class_name) def test_request_with_id(entity: Entity) -> None: """Request with request_id.""" request = Request("PUT", "https://example.org", entity,
import respx from iov42.core import Asset from iov42.core import AssetType from iov42.core import Client from iov42.core import CryptoProtocol from iov42.core import Entity from iov42.core import hashed_claim from iov42.core import InvalidSignature from iov42.core import PrivateIdentity from iov42.core._crypto import iov42_decode entities = [ PrivateIdentity( CryptoProtocol.SHA256WithECDSA.generate_private_key()).public_identity, AssetType(), Asset(asset_type_id="123456"), ] def id_class_name(value: typing.Any) -> str: """Provide class name for test identifier.""" return str(value.__class__.__name__) def test_hased_claim() -> None: """Hash of a claim.""" assert "RIREN5QE4J55V0aOmXdmRWOoSV_EIUtf0o_tdF4hInM" == hashed_claim( b"claim-1")
def test_quantifiable_asset_type(scale: typing.Union[str, int]) -> None: """Create quantifiable asset type.""" asset_type = AssetType(scale=scale) # type: ignore[arg-type] assert asset_type.scale == int(scale)
def test_asset_type_repr() -> None: """Informal representation of asset type.""" asset_type = AssetType() assert repr( asset_type) == f"AssetType(asset_type_id='{asset_type.asset_type_id}')"
def test_generate_unique_asset_type() -> None: """Asset type with no ID generates an UUID as ID.""" asset_type = AssetType() assert uuid.UUID(asset_type.asset_type_id)
def test_create_unique_asset_type() -> None: """Create unique asset type wih desired ID.""" asset_type = AssetType(asset_type_id="12345") assert asset_type.asset_type_id == "12345" assert asset_type.type == "Unique"