def test_update_traits(environment: Environment) -> None:
    """
    This is quite a long test to verify the update traits functionality correctly
    handles updating and creating traits.
    """
    # Given
    # an identity
    identity = Identity.objects.create(identifier="identifier", environment=environment)

    # that already has 2 traits
    trait_1_key = "trait_1"
    trait_1_value = 1
    trait_2_key = "trait_2"
    trait_2_value = 2
    trait_1 = create_trait_for_identity(identity, trait_1_key, trait_1_value)
    create_trait_for_identity(identity, trait_2_key, trait_2_value)

    # and a list of trait data items that should end up creating 1 additional
    # trait, updating 1 and leaving another alone but returning it as it is
    new_trait_1_value = 5
    trait_3_key = "trait_3"
    trait_3_value = 3

    # and one transient trait that is evaluated against but not persisted
    transient_trait_key = "transient"
    transient_trait_value = "not persisted"

    trait_data_items = [
        generate_trait_data_item(
            trait_key=trait_1.trait_key, trait_value=new_trait_1_value
        ),
        generate_trait_data_item(trait_key=trait_3_key, trait_value=trait_3_value),
        generate_trait_data_item(
            trait_key=transient_trait_key,
            trait_value=transient_trait_value,
            transient=True,
        ),
    ]

    # When
    updated_traits = identity.update_traits(trait_data_items)

    # Then
    # 3 traits are persisted
    assert identity.identity_traits.count() == 3

    # 4 traits are returned
    assert len(updated_traits) == 4

    # and the first trait has it's value updated correctly
    updated_trait_1 = get_trait_from_list_by_key(trait_1_key, updated_traits)
    assert updated_trait_1.trait_value == new_trait_1_value

    # and the second trait is left untouched and returned as is
    updated_trait_2 = get_trait_from_list_by_key(trait_2_key, updated_traits)
    assert updated_trait_2.trait_value == trait_2_value

    # and the third trait is created correctly
    updated_trait_3 = get_trait_from_list_by_key(trait_3_key, updated_traits)
    assert updated_trait_3.trait_value == trait_3_value

    # and the transient trait is returned among others
    transient_trait = get_trait_from_list_by_key(transient_trait_key, updated_traits)
    assert transient_trait.trait_value == transient_trait_value

    This is quite a long test to verify the update traits functionality correctly
    handles updating and creating traits.
    
api/tests/unit/environments/identities/test_unit_identities_models.py