parent
a520a67511
commit
9761c37f20
|
@ -123,7 +123,7 @@ def parse_observable(data, _valid_refs):
|
||||||
obj['_valid_refs'] = _valid_refs
|
obj['_valid_refs'] = _valid_refs
|
||||||
|
|
||||||
if 'type' not in obj:
|
if 'type' not in obj:
|
||||||
raise ValueError("'type' is a required field!")
|
raise ValueError("'type' is a required property!")
|
||||||
try:
|
try:
|
||||||
obj_class = OBJ_MAP_OBSERVABLE[obj['type']]
|
obj_class = OBJ_MAP_OBSERVABLE[obj['type']]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
|
|
@ -12,7 +12,7 @@ from .utils import NOW, format_datetime, get_timestamp, parse_into_datetime
|
||||||
|
|
||||||
__all__ = ['STIXJSONEncoder', '_STIXBase']
|
__all__ = ['STIXJSONEncoder', '_STIXBase']
|
||||||
|
|
||||||
DEFAULT_ERROR = "{type} must have {field}='{expected}'."
|
DEFAULT_ERROR = "{type} must have {property}='{expected}'."
|
||||||
|
|
||||||
|
|
||||||
class STIXJSONEncoder(json.JSONEncoder):
|
class STIXJSONEncoder(json.JSONEncoder):
|
||||||
|
@ -95,9 +95,9 @@ class _STIXBase(collections.Mapping):
|
||||||
if prop_value:
|
if prop_value:
|
||||||
setting_kwargs[prop_name] = prop_value
|
setting_kwargs[prop_name] = prop_value
|
||||||
|
|
||||||
# Detect any missing required fields
|
# Detect any missing required properties
|
||||||
required_fields = get_required_properties(cls._properties)
|
required_properties = get_required_properties(cls._properties)
|
||||||
missing_kwargs = set(required_fields) - set(setting_kwargs)
|
missing_kwargs = set(required_properties) - set(setting_kwargs)
|
||||||
if missing_kwargs:
|
if missing_kwargs:
|
||||||
raise MissingFieldsError(cls, missing_kwargs)
|
raise MissingFieldsError(cls, missing_kwargs)
|
||||||
|
|
||||||
|
|
|
@ -17,31 +17,31 @@ class InvalidValueError(STIXError, ValueError):
|
||||||
|
|
||||||
|
|
||||||
class MissingFieldsError(STIXError, ValueError):
|
class MissingFieldsError(STIXError, ValueError):
|
||||||
"""Missing required field(s) when constructing STIX object."""
|
"""Missing one or more required properties when constructing STIX object."""
|
||||||
|
|
||||||
def __init__(self, cls, fields):
|
def __init__(self, cls, properties):
|
||||||
super(MissingFieldsError, self).__init__()
|
super(MissingFieldsError, self).__init__()
|
||||||
self.cls = cls
|
self.cls = cls
|
||||||
self.fields = sorted(list(fields))
|
self.properties = sorted(list(properties))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
msg = "No values for required field(s) for {0}: ({1})."
|
msg = "No values for required properties for {0}: ({1})."
|
||||||
return msg.format(self.cls.__name__,
|
return msg.format(self.cls.__name__,
|
||||||
", ".join(x for x in self.fields))
|
", ".join(x for x in self.properties))
|
||||||
|
|
||||||
|
|
||||||
class ExtraFieldsError(STIXError, TypeError):
|
class ExtraFieldsError(STIXError, TypeError):
|
||||||
"""Extra field(s) were provided when constructing STIX object."""
|
"""One or more extra properties were provided when constructing STIX object."""
|
||||||
|
|
||||||
def __init__(self, cls, fields):
|
def __init__(self, cls, properties):
|
||||||
super(ExtraFieldsError, self).__init__()
|
super(ExtraFieldsError, self).__init__()
|
||||||
self.cls = cls
|
self.cls = cls
|
||||||
self.fields = sorted(list(fields))
|
self.properties = sorted(list(properties))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
msg = "Unexpected field(s) for {0}: ({1})."
|
msg = "Unexpected properties for {0}: ({1})."
|
||||||
return msg.format(self.cls.__name__,
|
return msg.format(self.cls.__name__,
|
||||||
", ".join(x for x in self.fields))
|
", ".join(x for x in self.properties))
|
||||||
|
|
||||||
|
|
||||||
class ImmutableError(STIXError, ValueError):
|
class ImmutableError(STIXError, ValueError):
|
||||||
|
@ -93,15 +93,15 @@ class UnmodifiablePropertyError(STIXError, ValueError):
|
||||||
class MutuallyExclusivePropertiesError(STIXError, TypeError):
|
class MutuallyExclusivePropertiesError(STIXError, TypeError):
|
||||||
"""Violating interproperty mutually exclusive constraint of a STIX object type."""
|
"""Violating interproperty mutually exclusive constraint of a STIX object type."""
|
||||||
|
|
||||||
def __init__(self, cls, fields):
|
def __init__(self, cls, properties):
|
||||||
super(MutuallyExclusivePropertiesError, self).__init__()
|
super(MutuallyExclusivePropertiesError, self).__init__()
|
||||||
self.cls = cls
|
self.cls = cls
|
||||||
self.fields = sorted(list(fields))
|
self.properties = sorted(list(properties))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
msg = "The field(s) for {0}: ({1}) are mutually exclusive."
|
msg = "The field(s) for {0}: ({1}) are mutually exclusive."
|
||||||
return msg.format(self.cls.__name__,
|
return msg.format(self.cls.__name__,
|
||||||
", ".join(x for x in self.fields))
|
", ".join(x for x in self.properties))
|
||||||
|
|
||||||
|
|
||||||
class DependentPropertiestError(STIXError, TypeError):
|
class DependentPropertiestError(STIXError, TypeError):
|
||||||
|
@ -121,15 +121,15 @@ class DependentPropertiestError(STIXError, TypeError):
|
||||||
class AtLeastOnePropertyError(STIXError, TypeError):
|
class AtLeastOnePropertyError(STIXError, TypeError):
|
||||||
"""Violating a constraint of a STIX object type that at least one of the given properties must be populated."""
|
"""Violating a constraint of a STIX object type that at least one of the given properties must be populated."""
|
||||||
|
|
||||||
def __init__(self, cls, fields):
|
def __init__(self, cls, properties):
|
||||||
super(AtLeastOnePropertyError, self).__init__()
|
super(AtLeastOnePropertyError, self).__init__()
|
||||||
self.cls = cls
|
self.cls = cls
|
||||||
self.fields = sorted(list(fields))
|
self.properties = sorted(list(properties))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
msg = "At least one of the field(s) for {0}: ({1}) must be populated."
|
msg = "At least one of the field(s) for {0}: ({1}) must be populated."
|
||||||
return msg.format(self.cls.__name__,
|
return msg.format(self.cls.__name__,
|
||||||
", ".join(x for x in self.fields))
|
", ".join(x for x in self.properties))
|
||||||
|
|
||||||
|
|
||||||
class RevokeError(STIXError, ValueError):
|
class RevokeError(STIXError, ValueError):
|
||||||
|
|
|
@ -45,7 +45,7 @@ class Property(object):
|
||||||
- provide a default value for this property.
|
- provide a default value for this property.
|
||||||
- `default()` can return the special value `NOW` to use the current
|
- `default()` can return the special value `NOW` to use the current
|
||||||
time. This is useful when several timestamps in the same object need
|
time. This is useful when several timestamps in the same object need
|
||||||
to use the same default value, so calling now() for each field--
|
to use the same default value, so calling now() for each property--
|
||||||
likely several microseconds apart-- does not work.
|
likely several microseconds apart-- does not work.
|
||||||
|
|
||||||
Subclasses can instead provide a lambda function for `default` as a keyword
|
Subclasses can instead provide a lambda function for `default` as a keyword
|
||||||
|
@ -53,7 +53,7 @@ class Property(object):
|
||||||
raise their own exceptions.
|
raise their own exceptions.
|
||||||
|
|
||||||
When instantiating Properties, `required` and `default` should not be used
|
When instantiating Properties, `required` and `default` should not be used
|
||||||
together. `default` implies that the field is required in the specification
|
together. `default` implies that the property is required in the specification
|
||||||
so this function will be used to supply a value if none is provided.
|
so this function will be used to supply a value if none is provided.
|
||||||
`required` means that the user must provide this; it is required in the
|
`required` means that the user must provide this; it is required in the
|
||||||
specification and we can't or don't want to create a default value.
|
specification and we can't or don't want to create a default value.
|
||||||
|
|
|
@ -114,4 +114,4 @@ def test_external_reference_source_required():
|
||||||
stix2.ExternalReference()
|
stix2.ExternalReference()
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.ExternalReference
|
assert excinfo.value.cls == stix2.ExternalReference
|
||||||
assert excinfo.value.fields == ["source_name"]
|
assert excinfo.value.properties == ["source_name"]
|
||||||
|
|
|
@ -32,7 +32,7 @@ EXPECTED_INDICATOR_REPR = "Indicator(" + " ".join("""
|
||||||
""".split()) + ")"
|
""".split()) + ")"
|
||||||
|
|
||||||
|
|
||||||
def test_indicator_with_all_required_fields():
|
def test_indicator_with_all_required_properties():
|
||||||
now = dt.datetime(2017, 1, 1, 0, 0, 1, tzinfo=pytz.utc)
|
now = dt.datetime(2017, 1, 1, 0, 0, 1, tzinfo=pytz.utc)
|
||||||
epoch = dt.datetime(1970, 1, 1, 0, 0, 1, tzinfo=pytz.utc)
|
epoch = dt.datetime(1970, 1, 1, 0, 0, 1, tzinfo=pytz.utc)
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ def test_indicator_with_all_required_fields():
|
||||||
assert rep == EXPECTED_INDICATOR_REPR
|
assert rep == EXPECTED_INDICATOR_REPR
|
||||||
|
|
||||||
|
|
||||||
def test_indicator_autogenerated_fields(indicator):
|
def test_indicator_autogenerated_properties(indicator):
|
||||||
assert indicator.type == 'indicator'
|
assert indicator.type == 'indicator'
|
||||||
assert indicator.id == 'indicator--00000000-0000-0000-0000-000000000001'
|
assert indicator.id == 'indicator--00000000-0000-0000-0000-000000000001'
|
||||||
assert indicator.created == FAKE_TIME
|
assert indicator.created == FAKE_TIME
|
||||||
|
@ -89,21 +89,21 @@ def test_indicator_id_must_start_with_indicator():
|
||||||
assert str(excinfo.value) == "Invalid value for Indicator 'id': must start with 'indicator--'."
|
assert str(excinfo.value) == "Invalid value for Indicator 'id': must start with 'indicator--'."
|
||||||
|
|
||||||
|
|
||||||
def test_indicator_required_fields():
|
def test_indicator_required_properties():
|
||||||
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
||||||
stix2.Indicator()
|
stix2.Indicator()
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.Indicator
|
assert excinfo.value.cls == stix2.Indicator
|
||||||
assert excinfo.value.fields == ["labels", "pattern"]
|
assert excinfo.value.properties == ["labels", "pattern"]
|
||||||
assert str(excinfo.value) == "No values for required field(s) for Indicator: (labels, pattern)."
|
assert str(excinfo.value) == "No values for required properties for Indicator: (labels, pattern)."
|
||||||
|
|
||||||
|
|
||||||
def test_indicator_required_field_pattern():
|
def test_indicator_required_property_pattern():
|
||||||
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
||||||
stix2.Indicator(labels=['malicious-activity'])
|
stix2.Indicator(labels=['malicious-activity'])
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.Indicator
|
assert excinfo.value.cls == stix2.Indicator
|
||||||
assert excinfo.value.fields == ["pattern"]
|
assert excinfo.value.properties == ["pattern"]
|
||||||
|
|
||||||
|
|
||||||
def test_indicator_created_ref_invalid_format():
|
def test_indicator_created_ref_invalid_format():
|
||||||
|
@ -137,8 +137,8 @@ def test_invalid_kwarg_to_indicator():
|
||||||
stix2.Indicator(my_custom_property="foo", **INDICATOR_KWARGS)
|
stix2.Indicator(my_custom_property="foo", **INDICATOR_KWARGS)
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.Indicator
|
assert excinfo.value.cls == stix2.Indicator
|
||||||
assert excinfo.value.fields == ['my_custom_property']
|
assert excinfo.value.properties == ['my_custom_property']
|
||||||
assert str(excinfo.value) == "Unexpected field(s) for Indicator: (my_custom_property)."
|
assert str(excinfo.value) == "Unexpected properties for Indicator: (my_custom_property)."
|
||||||
|
|
||||||
|
|
||||||
def test_created_modified_time_are_identical_by_default():
|
def test_created_modified_time_are_identical_by_default():
|
||||||
|
|
|
@ -35,28 +35,28 @@ def test_kill_chain_example():
|
||||||
assert str(preattack) == FOO_PRE_ATTACK
|
assert str(preattack) == FOO_PRE_ATTACK
|
||||||
|
|
||||||
|
|
||||||
def test_kill_chain_required_fields():
|
def test_kill_chain_required_properties():
|
||||||
|
|
||||||
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
||||||
stix2.KillChainPhase()
|
stix2.KillChainPhase()
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.KillChainPhase
|
assert excinfo.value.cls == stix2.KillChainPhase
|
||||||
assert excinfo.value.fields == ["kill_chain_name", "phase_name"]
|
assert excinfo.value.properties == ["kill_chain_name", "phase_name"]
|
||||||
|
|
||||||
|
|
||||||
def test_kill_chain_required_field_chain_name():
|
def test_kill_chain_required_property_chain_name():
|
||||||
|
|
||||||
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
||||||
stix2.KillChainPhase(phase_name="weaponization")
|
stix2.KillChainPhase(phase_name="weaponization")
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.KillChainPhase
|
assert excinfo.value.cls == stix2.KillChainPhase
|
||||||
assert excinfo.value.fields == ["kill_chain_name"]
|
assert excinfo.value.properties == ["kill_chain_name"]
|
||||||
|
|
||||||
|
|
||||||
def test_kill_chain_required_field_phase_name():
|
def test_kill_chain_required_property_phase_name():
|
||||||
|
|
||||||
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
||||||
stix2.KillChainPhase(kill_chain_name="lockheed-martin-cyber-kill-chain")
|
stix2.KillChainPhase(kill_chain_name="lockheed-martin-cyber-kill-chain")
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.KillChainPhase
|
assert excinfo.value.cls == stix2.KillChainPhase
|
||||||
assert excinfo.value.fields == ["phase_name"]
|
assert excinfo.value.properties == ["phase_name"]
|
||||||
|
|
|
@ -21,7 +21,7 @@ EXPECTED_MALWARE = """{
|
||||||
}"""
|
}"""
|
||||||
|
|
||||||
|
|
||||||
def test_malware_with_all_required_fields():
|
def test_malware_with_all_required_properties():
|
||||||
now = dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
|
now = dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
|
||||||
|
|
||||||
mal = stix2.Malware(
|
mal = stix2.Malware(
|
||||||
|
@ -36,7 +36,7 @@ def test_malware_with_all_required_fields():
|
||||||
assert str(mal) == EXPECTED_MALWARE
|
assert str(mal) == EXPECTED_MALWARE
|
||||||
|
|
||||||
|
|
||||||
def test_malware_autogenerated_fields(malware):
|
def test_malware_autogenerated_properties(malware):
|
||||||
assert malware.type == 'malware'
|
assert malware.type == 'malware'
|
||||||
assert malware.id == 'malware--00000000-0000-0000-0000-000000000001'
|
assert malware.id == 'malware--00000000-0000-0000-0000-000000000001'
|
||||||
assert malware.created == FAKE_TIME
|
assert malware.created == FAKE_TIME
|
||||||
|
@ -72,20 +72,20 @@ def test_malware_id_must_start_with_malware():
|
||||||
assert str(excinfo.value) == "Invalid value for Malware 'id': must start with 'malware--'."
|
assert str(excinfo.value) == "Invalid value for Malware 'id': must start with 'malware--'."
|
||||||
|
|
||||||
|
|
||||||
def test_malware_required_fields():
|
def test_malware_required_properties():
|
||||||
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
||||||
stix2.Malware()
|
stix2.Malware()
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.Malware
|
assert excinfo.value.cls == stix2.Malware
|
||||||
assert excinfo.value.fields == ["labels", "name"]
|
assert excinfo.value.properties == ["labels", "name"]
|
||||||
|
|
||||||
|
|
||||||
def test_malware_required_field_name():
|
def test_malware_required_property_name():
|
||||||
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
||||||
stix2.Malware(labels=['ransomware'])
|
stix2.Malware(labels=['ransomware'])
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.Malware
|
assert excinfo.value.cls == stix2.Malware
|
||||||
assert excinfo.value.fields == ["name"]
|
assert excinfo.value.properties == ["name"]
|
||||||
|
|
||||||
|
|
||||||
def test_cannot_assign_to_malware_attributes(malware):
|
def test_cannot_assign_to_malware_attributes(malware):
|
||||||
|
@ -100,8 +100,8 @@ def test_invalid_kwarg_to_malware():
|
||||||
stix2.Malware(my_custom_property="foo", **MALWARE_KWARGS)
|
stix2.Malware(my_custom_property="foo", **MALWARE_KWARGS)
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.Malware
|
assert excinfo.value.cls == stix2.Malware
|
||||||
assert excinfo.value.fields == ['my_custom_property']
|
assert excinfo.value.properties == ['my_custom_property']
|
||||||
assert str(excinfo.value) == "Unexpected field(s) for Malware: (my_custom_property)."
|
assert str(excinfo.value) == "Unexpected properties for Malware: (my_custom_property)."
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("data", [
|
@pytest.mark.parametrize("data", [
|
||||||
|
|
|
@ -369,7 +369,7 @@ def test_parse_email_message_with_at_least_one_error(data):
|
||||||
stix2.parse_observable(data, [str(i) for i in range(1, 6)])
|
stix2.parse_observable(data, [str(i) for i in range(1, 6)])
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.EmailMIMEComponent
|
assert excinfo.value.cls == stix2.EmailMIMEComponent
|
||||||
assert excinfo.value.fields == ["body", "body_raw_ref"]
|
assert excinfo.value.properties == ["body", "body_raw_ref"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("data", [
|
@pytest.mark.parametrize("data", [
|
||||||
|
@ -416,7 +416,7 @@ def test_parse_basic_tcp_traffic_with_error(data):
|
||||||
stix2.parse_observable(data, ["4"])
|
stix2.parse_observable(data, ["4"])
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.NetworkTraffic
|
assert excinfo.value.cls == stix2.NetworkTraffic
|
||||||
assert excinfo.value.fields == ["dst_ref", "src_ref"]
|
assert excinfo.value.properties == ["dst_ref", "src_ref"]
|
||||||
|
|
||||||
|
|
||||||
EXPECTED_PROCESS_OD = """{
|
EXPECTED_PROCESS_OD = """{
|
||||||
|
@ -508,7 +508,7 @@ def test_artifact_mutual_exclusion_error():
|
||||||
payload_bin="VBORw0KGgoAAAANSUhEUgAAADI==")
|
payload_bin="VBORw0KGgoAAAANSUhEUgAAADI==")
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.Artifact
|
assert excinfo.value.cls == stix2.Artifact
|
||||||
assert excinfo.value.fields == ["payload_bin", "url"]
|
assert excinfo.value.properties == ["payload_bin", "url"]
|
||||||
|
|
||||||
|
|
||||||
def test_directory_example():
|
def test_directory_example():
|
||||||
|
|
|
@ -20,7 +20,7 @@ EXPECTED_RELATIONSHIP = """{
|
||||||
}"""
|
}"""
|
||||||
|
|
||||||
|
|
||||||
def test_relationship_all_required_fields():
|
def test_relationship_all_required_properties():
|
||||||
now = dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc)
|
now = dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc)
|
||||||
|
|
||||||
rel = stix2.Relationship(
|
rel = stix2.Relationship(
|
||||||
|
@ -35,7 +35,7 @@ def test_relationship_all_required_fields():
|
||||||
assert str(rel) == EXPECTED_RELATIONSHIP
|
assert str(rel) == EXPECTED_RELATIONSHIP
|
||||||
|
|
||||||
|
|
||||||
def test_relationship_autogenerated_fields(relationship):
|
def test_relationship_autogenerated_properties(relationship):
|
||||||
assert relationship.type == 'relationship'
|
assert relationship.type == 'relationship'
|
||||||
assert relationship.id == 'relationship--00000000-0000-0000-0000-000000000001'
|
assert relationship.id == 'relationship--00000000-0000-0000-0000-000000000001'
|
||||||
assert relationship.created == FAKE_TIME
|
assert relationship.created == FAKE_TIME
|
||||||
|
@ -73,22 +73,22 @@ def test_relationship_id_must_start_with_relationship():
|
||||||
assert str(excinfo.value) == "Invalid value for Relationship 'id': must start with 'relationship--'."
|
assert str(excinfo.value) == "Invalid value for Relationship 'id': must start with 'relationship--'."
|
||||||
|
|
||||||
|
|
||||||
def test_relationship_required_field_relationship_type():
|
def test_relationship_required_property_relationship_type():
|
||||||
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
||||||
stix2.Relationship()
|
stix2.Relationship()
|
||||||
assert excinfo.value.cls == stix2.Relationship
|
assert excinfo.value.cls == stix2.Relationship
|
||||||
assert excinfo.value.fields == ["relationship_type", "source_ref", "target_ref"]
|
assert excinfo.value.properties == ["relationship_type", "source_ref", "target_ref"]
|
||||||
|
|
||||||
|
|
||||||
def test_relationship_missing_some_required_fields():
|
def test_relationship_missing_some_required_properties():
|
||||||
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
||||||
stix2.Relationship(relationship_type='indicates')
|
stix2.Relationship(relationship_type='indicates')
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.Relationship
|
assert excinfo.value.cls == stix2.Relationship
|
||||||
assert excinfo.value.fields == ["source_ref", "target_ref"]
|
assert excinfo.value.properties == ["source_ref", "target_ref"]
|
||||||
|
|
||||||
|
|
||||||
def test_relationship_required_field_target_ref():
|
def test_relationship_required_properties_target_ref():
|
||||||
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
with pytest.raises(stix2.exceptions.MissingFieldsError) as excinfo:
|
||||||
stix2.Relationship(
|
stix2.Relationship(
|
||||||
relationship_type='indicates',
|
relationship_type='indicates',
|
||||||
|
@ -96,7 +96,7 @@ def test_relationship_required_field_target_ref():
|
||||||
)
|
)
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.Relationship
|
assert excinfo.value.cls == stix2.Relationship
|
||||||
assert excinfo.value.fields == ["target_ref"]
|
assert excinfo.value.properties == ["target_ref"]
|
||||||
|
|
||||||
|
|
||||||
def test_cannot_assign_to_relationship_attributes(relationship):
|
def test_cannot_assign_to_relationship_attributes(relationship):
|
||||||
|
@ -111,8 +111,8 @@ def test_invalid_kwarg_to_relationship():
|
||||||
stix2.Relationship(my_custom_property="foo", **RELATIONSHIP_KWARGS)
|
stix2.Relationship(my_custom_property="foo", **RELATIONSHIP_KWARGS)
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.Relationship
|
assert excinfo.value.cls == stix2.Relationship
|
||||||
assert excinfo.value.fields == ['my_custom_property']
|
assert excinfo.value.properties == ['my_custom_property']
|
||||||
assert str(excinfo.value) == "Unexpected field(s) for Relationship: (my_custom_property)."
|
assert str(excinfo.value) == "Unexpected properties for Relationship: (my_custom_property)."
|
||||||
|
|
||||||
|
|
||||||
def test_create_relationship_from_objects_rather_than_ids(indicator, malware):
|
def test_create_relationship_from_objects_rather_than_ids(indicator, malware):
|
||||||
|
|
|
@ -31,7 +31,7 @@ BAD_SIGHTING = """{
|
||||||
}"""
|
}"""
|
||||||
|
|
||||||
|
|
||||||
def test_sighting_all_required_fields():
|
def test_sighting_all_required_properties():
|
||||||
now = dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc)
|
now = dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc)
|
||||||
|
|
||||||
s = stix2.Sighting(
|
s = stix2.Sighting(
|
||||||
|
@ -79,8 +79,8 @@ def test_invalid_kwarg_to_sighting():
|
||||||
stix2.Sighting(my_custom_property="foo", **SIGHTING_KWARGS)
|
stix2.Sighting(my_custom_property="foo", **SIGHTING_KWARGS)
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.Sighting
|
assert excinfo.value.cls == stix2.Sighting
|
||||||
assert excinfo.value.fields == ['my_custom_property']
|
assert excinfo.value.properties == ['my_custom_property']
|
||||||
assert str(excinfo.value) == "Unexpected field(s) for Sighting: (my_custom_property)."
|
assert str(excinfo.value) == "Unexpected properties for Sighting: (my_custom_property)."
|
||||||
|
|
||||||
|
|
||||||
def test_create_sighting_from_objects_rather_than_ids(malware): # noqa: F811
|
def test_create_sighting_from_objects_rather_than_ids(malware): # noqa: F811
|
||||||
|
|
|
@ -142,7 +142,7 @@ def test_versioning_error_usetting_required_property():
|
||||||
campaign_v1.new_version(name=None)
|
campaign_v1.new_version(name=None)
|
||||||
|
|
||||||
assert excinfo.value.cls == stix2.Campaign
|
assert excinfo.value.cls == stix2.Campaign
|
||||||
assert excinfo.value.fields == ["name"]
|
assert excinfo.value.properties == ["name"]
|
||||||
|
|
||||||
|
|
||||||
def test_versioning_error_new_version_of_revoked():
|
def test_versioning_error_new_version_of_revoked():
|
||||||
|
|
Loading…
Reference in New Issue