Skip to content

Commit 4a27c36

Browse files
committed
WIP unit tests for Presentation class. Some refactoring of the class.
1 parent 9a4c3c5 commit 4a27c36

File tree

4 files changed

+233
-71
lines changed

4 files changed

+233
-71
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
.coverage
12
.idea/
23
.code
34
dist
@@ -17,4 +18,4 @@ libs/om-aries-controller/demo/bob/image_received.png
1718
**/model.pt
1819
**/trained_model.pt
1920
**/untrained_model.pt
20-
**/part_trained.pt
21+
**/part_trained.pt

libs/aries-basic-controller/aries_basic_controller/models/presentation.py

Lines changed: 115 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -3,103 +3,148 @@
33

44
logger = logging.getLogger("aries_controller.models.presentation")
55

6+
67
class Presentation():
78
def __init__(self, presentation_json):
8-
# TODO Load verify var with json.loads() and test code
9-
self.json_data = presentation_json
10-
if self.is_verified() == "false":
11-
logger.error('Presentation Object Verification Failed')
12-
# TODO raise proper PresentationVerificationFailed exception
13-
raise Exception('Presentation Object Verification Failed')
9+
try:
10+
self.json_data = json.loads(presentation_json)
11+
except Exception:
12+
logger.error("Failed to load presentation JSON")
13+
raise
14+
self.validate_presentation_json(presentation_json)
15+
if not self.is_verified():
16+
logger.error('Presentation Object Verification not verified')
17+
raise Exception('Presentation Object Verification not verified')
1418

1519
def get_self_attested(self):
16-
if self.is_verified() == "false":
17-
logger.debug('Verification Failed')
18-
data = {}
19-
for (name, val) in self.json_data['presentation']['requested_proof']['self_attested_attrs'].items():
20-
data[name] = val['raw']
21-
return json.dumps(data)
20+
if self.is_verified():
21+
data = {}
22+
for (name, val) in self.json_data['presentation']['requested_proof']['self_attested_attrs'].items():
23+
data[name] = val['raw']
24+
return json.dumps(data)
2225

2326
def get_revealed(self):
24-
if self.is_verified() == "false":
25-
logger.debug('Verification Failed')
26-
data = {}
27-
for (name, val) in self.json_data['presentation']['requested_proof']['revealed_attrs'].items():
28-
data[name] = val['raw']
29-
30-
return json.dumps(data)
27+
if self.is_verified():
28+
data = {}
29+
for (name, val) in self.json_data['presentation']['requested_proof']['revealed_attrs'].items():
30+
data[name] = val['raw']
31+
return json.dumps(data)
3132

3233
def get_unrevealed_attrs(self):
33-
if self.is_verified() == "false":
34-
logger.debug('Verification Failed')
35-
data = {}
36-
for (name, val) in self.json_data['presentation']['requested_proof']['unrevealed_attrs'].items():
37-
data[name] = val['raw']
38-
return json.dumps(data)
34+
if self.is_verified():
35+
data = {}
36+
for (name, val) in self.json_data['presentation']['requested_proof']['unrevealed_attrs'].items():
37+
data[name] = val['raw']
38+
return json.dumps(data)
3939

4040
def get_predicates(self):
41-
if self.is_verified() == "false":
42-
logger.debug('Verification Failed')
43-
data = {}
44-
for (name, val) in self.json_data['presentation']['requested_proof']['predicates'].items():
45-
data[name] = val['raw']
46-
return json.dumps(data)
41+
if self.is_verified():
42+
data = {}
43+
for (name, val) in self.json_data['presentation']['requested_proof']['predicates'].items():
44+
data[name] = val['raw']
45+
return json.dumps(data)
4746

4847
def get_identifiers(self):
49-
data = {}
50-
identifiers = []
51-
for index in range(len(self.json_data['presentation']['identifiers'])):
52-
identifiers.extend([self.json_data['presentation']['identifiers'][index]])
53-
data['identifiers'] = identifiers
54-
return json.dumps(data)
48+
if self.__has_identifiers():
49+
data = {}
50+
identifiers = []
51+
for index in range(len(self.json_data['presentation']['identifiers'])):
52+
identifiers.extend([self.json_data['presentation']['identifiers'][index]])
53+
data['identifiers'] = identifiers
54+
return json.dumps(data)
5555

5656
def get_schemas(self):
57-
data = {}
58-
creds = []
59-
for index in range(len(self.json_data['presentation']['identifiers'])):
60-
for key in self.json_data['presentation']['identifiers'][index]:
61-
if key == 'schema_id':
62-
creds.extend([self.json_data['presentation']['identifiers'][index][key]])
63-
data['schema_id'] = creds
64-
return json.dumps(data)
57+
if self.__has_identifiers():
58+
data = {}
59+
creds = []
60+
for index in range(len(self.json_data['presentation']['identifiers'])):
61+
for key in self.json_data['presentation']['identifiers'][index]:
62+
if key == 'schema_id':
63+
creds.extend([self.json_data['presentation']['identifiers'][index][key]])
64+
data['schema_id'] = creds
65+
return json.dumps(data)
6566

6667
def get_cred_def_ids(self):
67-
data = {}
68-
creds = []
69-
for index in range(len(self.json_data['presentation']['identifiers'])):
70-
for key in self.json_data['presentation']['identifiers'][index]:
71-
if key == 'cred_def_id':
72-
creds.extend([self.json_data['presentation']['identifiers'][index][key]])
73-
data['cred_def_id'] = creds
74-
return json.dumps(data)
68+
if self.__has_identifiers():
69+
data = {}
70+
creds = []
71+
for index in range(len(self.json_data['presentation']['identifiers'])):
72+
for key in self.json_data['presentation']['identifiers'][index]:
73+
if key == 'cred_def_id':
74+
creds.extend([self.json_data['presentation']['identifiers'][index][key]])
75+
data['cred_def_id'] = creds
76+
return json.dumps(data)
7577

7678
def get_rev_reg_ids(self):
77-
data = {}
78-
creds = []
79-
for index in range(len(self.json_data['presentation']['identifiers'])):
80-
for key in self.json_data['presentation']['identifiers'][index]:
81-
if key == 'rev_reg_id':
82-
creds.extend([self.json_data['presentation']['identifiers'][index][key]])
83-
data['rev_reg_id'] = creds
84-
return json.dumps(data)
79+
if self.__has_identifiers():
80+
data = {}
81+
creds = []
82+
for index in range(len(self.json_data['presentation']['identifiers'])):
83+
for key in self.json_data['presentation']['identifiers'][index]:
84+
if key == 'rev_reg_id':
85+
creds.extend([self.json_data['presentation']['identifiers'][index][key]])
86+
data['rev_reg_id'] = creds
87+
return json.dumps(data)
8588

8689
def get_role(self):
87-
return(self.json_data['role'])
90+
return(self.json_data['role'])
8891

8992
def get_threadid(self):
90-
return(self.json_data['thread_id'])
93+
return(self.json_data['thread_id'])
9194

9295
def get_presentation_request(self):
93-
return(self.json_data['presentation_request'])
96+
return(self.json_data['presentation_request'])
9497

9598
def get_verified_state(self):
96-
return self.json_data['state']
99+
return self.json_data['state']
97100

98101
def get_presxid(self):
99-
return self.json_data['presentation_exchange_id']
100-
101-
def is_verified(self):
102-
return self.json_data['verified']
102+
return self.json_data['presentation_exchange_id']
103103

104104
def from_conn_id(self):
105-
return self.json_data['connection_id']
105+
return self.json_data['connection_id']
106+
107+
def is_verified(self):
108+
try:
109+
assert self.json_data['verified'] == "true"
110+
except AssertionError:
111+
logger.debug('Verification Failed')
112+
return False
113+
return True
114+
115+
def validate_presentation_json(self, presentation_json):
116+
try:
117+
# Taken from sample response in swagger UI
118+
# TODO Determine whether this is the minimal set of keys
119+
presentation_keys = [
120+
"auto_present",
121+
"connection_id",
122+
"created_at",
123+
"error_msg",
124+
"initiator",
125+
"presentation",
126+
"presentation_exchange_id",
127+
"presentation_proposal_dict",
128+
"presentation_request",
129+
"presentation_request_dict",
130+
"role",
131+
"state",
132+
"thread_id",
133+
"trace",
134+
"updated_at",
135+
"verified"
136+
]
137+
for key in presentation_keys:
138+
assert key in json.loads(presentation_json),\
139+
f"Invalid presentation. Missing key {key}"
140+
except AssertionError:
141+
raise
142+
143+
def __has_identifiers(self):
144+
try:
145+
assert 'identifiers' in self.json_data['presentation'],\
146+
"No key 'identifiers' in presentation"
147+
return True
148+
except AssertionError:
149+
logger.warning("No key 'identifiers' in presentation")
150+
raise

libs/aries-basic-controller/aries_basic_controller/tests/__init__.py

Whitespace-only changes.
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import pytest
2+
import json
3+
import logging
4+
5+
from ..models.presentation import Presentation
6+
7+
LOGGER = logging.getLogger(__name__)
8+
9+
presentation_keys = [
10+
"auto_present",
11+
"connection_id",
12+
"created_at",
13+
"error_msg",
14+
"initiator",
15+
"presentation",
16+
"presentation_exchange_id",
17+
"presentation_proposal_dict",
18+
"presentation_request",
19+
"presentation_request_dict",
20+
"role",
21+
"state",
22+
"thread_id",
23+
"trace",
24+
"updated_at",
25+
"verified"
26+
]
27+
28+
# From sample response in Swagger UI
29+
pytest.valid_presentation = json.dumps({
30+
"auto_present": "false",
31+
"connection_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
32+
"created_at": "2021-04-08 09:04:01Z",
33+
"error_msg": "Invalid structure",
34+
"initiator": "self",
35+
"presentation": {},
36+
"presentation_exchange_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
37+
"presentation_proposal_dict": {},
38+
"presentation_request": {},
39+
"presentation_request_dict": {},
40+
"role": "prover",
41+
"state": "verified",
42+
"thread_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
43+
"trace": "true",
44+
"updated_at": "2021-04-08 09:04:01Z",
45+
"verified": "true"
46+
})
47+
48+
pytest.unverified_presentation = json.dumps({
49+
"auto_present": "false",
50+
"connection_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
51+
"created_at": "2021-04-08 09:04:01Z",
52+
"error_msg": "Invalid structure",
53+
"initiator": "self",
54+
"presentation": {},
55+
"presentation_exchange_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
56+
"presentation_proposal_dict": {},
57+
"presentation_request": {},
58+
"presentation_request_dict": {},
59+
"role": "prover",
60+
"state": "verified",
61+
"thread_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
62+
"trace": "true",
63+
"updated_at": "2021-04-08 09:04:01Z",
64+
"verified": "false"
65+
})
66+
67+
pytest.invalid_presentation = json.dumps({
68+
"abc": "1234"
69+
})
70+
71+
pytest.not_json = 123456
72+
73+
74+
def test_init_valid():
75+
pres = Presentation(pytest.valid_presentation)
76+
assert pres.json_data == json.loads(pytest.valid_presentation)
77+
78+
79+
def test_init_invalid():
80+
with pytest.raises(AssertionError,
81+
match="Missing key"):
82+
Presentation(pytest.invalid_presentation)
83+
84+
85+
def test_init_unverified(caplog):
86+
error_msg = "Presentation Object Verification not verified"
87+
with pytest.raises(Exception,
88+
match=error_msg):
89+
Presentation(pytest.unverified_presentation)
90+
assert error_msg in caplog.text
91+
92+
93+
def test_init_not_json(caplog):
94+
error_msg = "the JSON object must be str, bytes or bytearray, not int"
95+
with pytest.raises(TypeError, match=error_msg):
96+
Presentation(pytest.not_json)
97+
assert "Failed to load presentation JSON" in caplog.text
98+
99+
100+
# check for each possibly missing key whether the correct error is raised
101+
@pytest.mark.parametrize("key", presentation_keys)
102+
def test_validate_presentation_json(key):
103+
pres = pytest.valid_presentation
104+
pres_obj = Presentation(pres)
105+
with pytest.raises(AssertionError,
106+
match=f"Missing key {key}"):
107+
del pres_obj.json_data[key]
108+
pres_obj.validate_presentation_json(json.dumps(pres_obj.json_data))
109+
110+
111+
def test_has_no_identifiers(caplog):
112+
error_msg = "No key 'identifiers' in presentation"
113+
with pytest.raises(AssertionError,
114+
match=error_msg):
115+
Presentation(pytest.valid_presentation).get_cred_def_ids()
116+
assert error_msg in caplog.text

0 commit comments

Comments
 (0)