Skip to content

Commit 4c416b8

Browse files
authored
[tests] Improved Unit and integration tests (OpenCTI-Platform#192)
1 parent e5b23f1 commit 4c416b8

17 files changed

+1193
-195
lines changed

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ sseclient==0.0.27
1010
black==20.8b1
1111
python-magic==0.4.22; sys_platform == 'linux' or sys_platform == 'darwin'
1212
python-magic-bin==0.4.14; sys_platform == 'win32'
13+
pytest_randomly==3.8.0

tests/01-unit/test_stix.py

Lines changed: 0 additions & 66 deletions
This file was deleted.

tests/01-unit/test_stix_split.py

Lines changed: 0 additions & 10 deletions
This file was deleted.

tests/01-unit/utils/__init__.py

Whitespace-only changes.

tests/01-unit/utils/test_constants.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from pycti.utils.constants import (
2+
StixCyberObservableTypes,
3+
IdentityTypes,
4+
LocationTypes,
5+
ContainerTypes,
6+
)
7+
8+
9+
def test_for_enum_typos():
10+
# Test check for typos between enum names and values
11+
enums = [StixCyberObservableTypes, LocationTypes, IdentityTypes, ContainerTypes]
12+
for enum in enums:
13+
for data in enum:
14+
name = data.name.replace("_", "-")
15+
value = data.value.upper()
16+
assert name == value
17+
18+
19+
def test_for_enum_has_value_functionality():
20+
# Test if the has_value function works as intended
21+
assert StixCyberObservableTypes.has_value("url") is True
22+
assert StixCyberObservableTypes.has_value("LRU") is False
23+
24+
assert LocationTypes.has_value("CITY") is True
25+
assert LocationTypes.has_value("YTIC") is False
26+
27+
assert IdentityTypes.has_value("SECTOR") is True
28+
assert IdentityTypes.has_value("RECTOS") is False
29+
30+
assert ContainerTypes.has_value("Note") is True
31+
assert ContainerTypes.has_value("ETON") is False
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import datetime
2+
from pycti.utils.opencti_stix2 import OpenCTIStix2
3+
import pytest
4+
5+
6+
@pytest.fixture
7+
def opencti_stix2(api_client):
8+
return OpenCTIStix2(api_client)
9+
10+
11+
def test_unknown_type(opencti_stix2: OpenCTIStix2, caplog):
12+
opencti_stix2.unknown_type({"type": "foo"})
13+
for record in caplog.records:
14+
assert record.levelname == "ERROR"
15+
assert 'Unknown object type "foo", doing nothing...' in caplog.text
16+
17+
18+
def test_convert_markdown(opencti_stix2: OpenCTIStix2):
19+
result = opencti_stix2.convert_markdown(
20+
" my <code> is very </special> </code> to me"
21+
)
22+
assert " my ` is very </special> ` to me" == result
23+
24+
25+
def test_convert_markdown_typo(opencti_stix2: OpenCTIStix2):
26+
result = opencti_stix2.convert_markdown(
27+
" my <code is very </special> </code> to me"
28+
)
29+
assert " my <code is very </special> ` to me" == result
30+
31+
32+
def test_format_date_with_tz(opencti_stix2: OpenCTIStix2):
33+
# Test all 4 format_date cases with timestamp + timezone
34+
my_datetime = datetime.datetime(
35+
2021, 3, 5, 13, 31, 19, 42621, tzinfo=datetime.timezone.utc
36+
)
37+
my_datetime_str = my_datetime.isoformat(timespec="milliseconds").replace(
38+
"+00:00", "Z"
39+
)
40+
assert my_datetime_str == opencti_stix2.format_date(my_datetime)
41+
my_date = my_datetime.date()
42+
my_date_str = "2021-03-05T00:00:00.000Z"
43+
assert my_date_str == opencti_stix2.format_date(my_date)
44+
assert my_datetime_str == opencti_stix2.format_date(my_datetime_str)
45+
assert (
46+
str(
47+
datetime.datetime.now(tz=datetime.timezone.utc)
48+
.isoformat(timespec="seconds")
49+
.replace("+00:00", "")
50+
)
51+
in opencti_stix2.format_date()
52+
)
53+
with pytest.raises(ValueError):
54+
opencti_stix2.format_date("No time")
55+
56+
# Test all 4 format_date cases with timestamp w/o timezone
57+
my_datetime = datetime.datetime(2021, 3, 5, 13, 31, 19, 42621)
58+
my_datetime_str = (
59+
my_datetime.replace(tzinfo=datetime.timezone.utc)
60+
.isoformat(timespec="milliseconds")
61+
.replace("+00:00", "Z")
62+
)
63+
assert my_datetime_str == opencti_stix2.format_date(my_datetime)
64+
my_date = my_datetime.date()
65+
my_date_str = "2021-03-05T00:00:00.000Z"
66+
assert my_date_str == opencti_stix2.format_date(my_date)
67+
assert my_datetime_str == opencti_stix2.format_date(my_datetime_str)
68+
assert (
69+
str(
70+
datetime.datetime.now(tz=datetime.timezone.utc)
71+
.isoformat(timespec="seconds")
72+
.replace("+00:00", "")
73+
)
74+
in opencti_stix2.format_date()
75+
)
76+
with pytest.raises(ValueError):
77+
opencti_stix2.format_date("No time")
78+
79+
80+
def test_filter_objects(opencti_stix2: OpenCTIStix2):
81+
objects = [{"id": "123"}, {"id": "124"}, {"id": "125"}, {"id": "126"}]
82+
result = opencti_stix2.filter_objects(["123", "124", "126"], objects)
83+
assert len(result) == 1
84+
assert "126" not in result
85+
86+
87+
def test_pick_aliases(opencti_stix2: OpenCTIStix2) -> None:
88+
stix_object = {}
89+
assert opencti_stix2.pick_aliases(stix_object) is None
90+
stix_object["aliases"] = "alias"
91+
assert opencti_stix2.pick_aliases(stix_object) == "alias"
92+
stix_object["x_amitt_aliases"] = "amitt_alias"
93+
assert opencti_stix2.pick_aliases(stix_object) == "amitt_alias"
94+
stix_object["x_mitre_aliases"] = "mitre_alias"
95+
assert opencti_stix2.pick_aliases(stix_object) == "mitre_alias"
96+
stix_object["x_opencti_aliases"] = "opencti_alias"
97+
assert opencti_stix2.pick_aliases(stix_object) == "opencti_alias"
98+
99+
100+
def test_import_bundle_from_file(opencti_stix2: OpenCTIStix2, caplog) -> None:
101+
opencti_stix2.import_bundle_from_file("foo.txt")
102+
for record in caplog.records:
103+
assert record.levelname == "ERROR"
104+
assert "The bundle file does not exists" in caplog.text
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import json
2+
from stix.report import Report
3+
from pycti.utils.opencti_stix2_splitter import OpenCTIStix2Splitter
4+
5+
6+
def test_split_bundle():
7+
stix_splitter = OpenCTIStix2Splitter()
8+
with open("./tests/data/enterprise-attack.json") as file:
9+
content = file.read()
10+
bundles = stix_splitter.split_bundle(content)
11+
assert len(bundles) == 7029
12+
#
13+
# with open("./tests/data/test.pdf", 'w') as file:
14+
# content = file.read()
15+
# with pytest.raises(Exception):
16+
# stix_splitter.split_bundle(content)
17+
18+
19+
def test_crate_bundle():
20+
stix_splitter = OpenCTIStix2Splitter()
21+
report = Report().to_json()
22+
observables = [report]
23+
bundle = stix_splitter.stix2_create_bundle(
24+
observables, use_json=True, event_version=None
25+
)
26+
for key in ["type", "id", "spec_version", "objects"]:
27+
assert key in bundle
28+
assert len(json.loads(bundle).keys()) == 4
29+
30+
bundle = stix_splitter.stix2_create_bundle(
31+
observables, use_json=True, event_version=1
32+
)
33+
for key in ["type", "id", "spec_version", "objects", "x_opencti_event_version"]:
34+
assert key in bundle
35+
assert len(json.loads(bundle).keys()) == 5

tests/02-integration/__init__.py

Whitespace-only changes.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# coding: utf-8
2+
3+
import json
4+
5+
import pytest
6+
from dateutil.parser import parse
7+
from stix2 import TLP_GREEN, TLP_WHITE
8+
9+
# Commented out since OpenCTI requires at least 100 indicators
10+
# for this test to work
11+
#
12+
# def test_get_100_indicators_with_pagination(api_client):
13+
# # Get 100 Indicators using the pagination
14+
# custom_attributes = """
15+
# id
16+
# revoked
17+
# created
18+
# """
19+
#
20+
# final_indicators = []
21+
# data = api_client.indicator.list(
22+
# first=50, customAttributes=custom_attributes, withPagination=True
23+
# )
24+
# final_indicators = final_indicators + data["entities"]
25+
#
26+
# assert len(final_indicators) == 50
27+
#
28+
# after = data["pagination"]["endCursor"]
29+
# data = api_client.indicator.list(
30+
# first=50,
31+
# after=after,
32+
# customAttributes=custom_attributes,
33+
# withPagination=True,
34+
# )
35+
# final_indicators = final_indicators + data["entities"]
36+
#
37+
# assert len(final_indicators) == 100
38+
39+
40+
def test_indicator_stix_marshall(api_client):
41+
with open("tests/data/indicator_stix.json", "r") as content_file:
42+
content = content_file.read()
43+
44+
json_data = json.loads(content)
45+
46+
for indic in json_data["objects"]:
47+
imported_indicator = api_client.indicator.import_from_stix2(
48+
stixObject=indic, update=True
49+
)
50+
assert imported_indicator is not None

tests/02-integration/stories/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)