Skip to content

Commit 393f85b

Browse files
committed
Merge branch 'main' into staging
2 parents c846804 + 8812973 commit 393f85b

File tree

10 files changed

+331
-16
lines changed

10 files changed

+331
-16
lines changed

.github/workflows/main.yml renamed to .github/workflows/create-release-changelog.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
name: 'CI'
1+
name: 'Create release and changelog'
22
on:
3-
push:
4-
tags:
5-
- 'v.*'
3+
release:
4+
types: [created]
65

76
jobs:
87
release:

.github/workflows/lint-black.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: 'Run black linting'
2+
3+
on:
4+
# Trigger the workflow on push or pull request,
5+
# but only for the main branch
6+
push:
7+
branches:
8+
- main
9+
pull_request:
10+
branches:
11+
- main
12+
13+
jobs:
14+
PythonLinting:
15+
name: Python linting
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@master
19+
- name: Black Python linting
20+
uses: lgeiger/black-action@master
21+
with:
22+
args: . --check

.github/workflows/python-test-publish.yml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,8 @@ name: Upload Python Package
66
on:
77
# Trigger the workflow on push or pull request,
88
# but only for the main branch
9-
push:
10-
branches:
11-
- main
12-
pull_request:
13-
branches:
14-
- main
9+
release:
10+
types: [created]
1511

1612
jobs:
1713
deploy:

.github/workflows/run-py-tests.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Run Python Tests
2+
on:
3+
release:
4+
types: [created]
5+
pull_request:
6+
branches:
7+
- staging
8+
9+
jobs:
10+
RunPytest:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v2
14+
- name: Install Python 3
15+
uses: actions/setup-python@v1
16+
with:
17+
python-version: 3.7
18+
- name: Install dependencies
19+
run: |
20+
python -m pip install --upgrade pip
21+
pip install -r requirements.txt
22+
- name: Run tests with pytest
23+
run: pytest

aries_cloudcontroller/controllers/issuer.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,10 @@ async def issue_credential(self, cred_ex_id, comment, attributes):
135135
)
136136

137137
# Store a received credential
138-
async def store_credential(self, cred_ex_id, credential_id):
139-
body = {"credential_id": credential_id}
138+
async def store_credential(self, cred_ex_id, credential_id: str = None):
139+
body = {}
140+
if credential_id:
141+
body["credential_id"] = credential_id
140142
return await self.admin_POST(
141143
f"{self.base_url}/records/{cred_ex_id}/store", json_data=body
142144
)

aries_cloudcontroller/controllers/messaging.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,13 @@ async def send_message(self, connection_id, msg):
2121
)
2222
return response
2323

24-
async def trust_ping(self, connection_id: str, msg: str):
25-
response = await self.admin_POST(
26-
f"/connections/{connection_id}/send-ping", {"content": msg}
27-
)
24+
async def trust_ping(self, connection_id: str, comment_msg: str = None):
25+
if comment_msg:
26+
response = await self.admin_POST(
27+
f"/connections/{connection_id}/send-ping", {"comment": comment_msg}
28+
)
29+
else:
30+
response = await self.admin_POST(
31+
f"/connections/{connection_id}/send-ping", {}
32+
)
2833
return response
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import json
2+
import logging
3+
4+
logger = logging.getLogger("aries_controller.models.proof_request")
5+
6+
7+
class ProofRequest:
8+
def __init__(self, proof_request_json):
9+
try:
10+
self.json_data = json.loads(proof_request_json)
11+
except Exception:
12+
logger.error("Failed to load proof request JSON")
13+
raise
14+
self.validate_proof_request_json(proof_request_json)
15+
16+
def get_requested_attributes(self):
17+
return self.json_data["requested_attributes"]
18+
19+
def get_requested_predicates(self):
20+
return self.json_data["requested_predicates"]
21+
22+
def get_connection_id(self):
23+
return self.json_data["connection_id"]
24+
25+
def get_version(self):
26+
return self.json_data["version"]
27+
28+
def get_name(self):
29+
return self.json_data["name"]
30+
31+
def validate_proof_request_json(self, presentation_json):
32+
try:
33+
# Taken from sample response in swagger UI
34+
# TODO Determine whether this is the minimal set of keys
35+
presentation_keys = [
36+
"connection_id",
37+
"version",
38+
"name",
39+
"requested_attributes",
40+
"requested_predicates",
41+
]
42+
for key in presentation_keys:
43+
assert key in json.loads(
44+
presentation_json
45+
), f"Invalid proof request. Missing key {key}"
46+
except AssertionError:
47+
raise

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
aiohttp~=3.7.3
22
asyncio
3+
black
34
prompt_toolkit
45
pygments
56
PyPubSub

tests/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
### Running tests locally
2+
3+
In order to run the tests locally, e.g. for development, make sure you have installed the requirements by running `pip install -r requirements.txt` in the root of the project.
4+
5+
You can now run all tests py running `pytest` in the root of the project. in order to run specific tests you can specifying the test file to run, e.g. `pytest tests/path/to/your/testfile.py`. You can also run individual tests only using the `-k` flag of pytest `pytest tests/path/to/your/testfile.py -k 'test_your_whatever'` where `test_your_whatever` is the name of the test definition. For more information, please, refer to the [pytest docs](https://docs.pytest.org/en/).
6+
7+
It is recommended to run the tests locally (and to add tests to your chnages and code additions). Tests will automatically run when trying to merge into or push to master. The merge or push will be rejected if any test fails.

tests/models/test_proof_request.py

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
import pytest
2+
import json
3+
import logging
4+
5+
from aries_cloudcontroller.models.proof_request import ProofRequest
6+
7+
LOGGER = logging.getLogger(__name__)
8+
9+
pytest.proof_keys = [
10+
"connection_id",
11+
"version",
12+
"name",
13+
"requested_attributes",
14+
"requested_predicates",
15+
]
16+
17+
# From sample in https://github.com/hyperledger/aries-cloudagent-python/issues/175
18+
pytest.valid_proof_request = json.dumps(
19+
{
20+
"connection_id": "d965bd54-affb-4e11-ba8e-ea54a3214123",
21+
"version": "1.0.0",
22+
"name": "Proof of Name",
23+
"requested_attributes": [
24+
{
25+
"name": "name",
26+
"restrictions": [
27+
{"cred_def_id": "3avoBCqDMFHFaKUHug9s8W:3:CL:13:default"},
28+
{"value": "Alice Jones"},
29+
],
30+
}
31+
],
32+
"requested_predicates": [],
33+
}
34+
)
35+
36+
pytest.multi_attrs = json.dumps(
37+
{
38+
"connection_id": "d965bd54-affb-4e11-ba8e-ea54a3214123",
39+
"version": "1.0.0",
40+
"name": "Proof of Name",
41+
"requested_attributes": [
42+
{
43+
"name": "name",
44+
"restrictions": [
45+
{"cred_def_id": "3avoBCqDMFHFaKUHug9s8W:3:CL:13:default"},
46+
{"value": "Alice Jones"},
47+
],
48+
},
49+
{
50+
"name": "name",
51+
"restrictions": [
52+
{"cred_def_id": "3avoBCqDMFHFaKUHug9s8W:3:CL:13:default"},
53+
{"value": "Alice Jones"},
54+
],
55+
},
56+
],
57+
"requested_predicates": [],
58+
}
59+
)
60+
61+
pytest.multi_predicates = json.dumps(
62+
{
63+
"connection_id": "d965bd54-affb-4e11-ba8e-ea54a3214123",
64+
"version": "1.0.0",
65+
"name": "Proof of Name",
66+
"requested_attributes": [],
67+
"requested_predicates": [
68+
{
69+
"name": "name",
70+
"restrictions": [
71+
{"cred_def_id": "3avoBCqDMFHFaKUHug9s8W:3:CL:13:default"},
72+
{"value": "Alice Jones"},
73+
],
74+
},
75+
{
76+
"name": "name",
77+
"restrictions": [
78+
{"cred_def_id": "3avoBCqDMFHFaKUHug9s8W:3:CL:13:default"},
79+
{"value": "Alice Jones"},
80+
],
81+
},
82+
],
83+
}
84+
)
85+
86+
pytest.not_json = 123456
87+
88+
pytest.invalid_proof_request = json.dumps({"abc": "1234"})
89+
90+
pytest.no_requested_attrs = json.dumps(
91+
{
92+
"connection_id": "d965bd54-affb-4e11-ba8e-ea54a3214123",
93+
"version": "1.0.0",
94+
"name": "Proof of Name",
95+
"requested_attributes": [],
96+
"requested_predicates": [],
97+
}
98+
)
99+
100+
101+
def test_init_valid():
102+
proof = ProofRequest(pytest.valid_proof_request)
103+
assert proof.json_data == json.loads(pytest.valid_proof_request)
104+
105+
106+
def test_init_invalid():
107+
with pytest.raises(AssertionError, match="Missing key"):
108+
ProofRequest(pytest.invalid_proof_request)
109+
110+
111+
def test_init_not_json(caplog):
112+
error_msg = "the JSON object must be str, bytes or bytearray, not int"
113+
with pytest.raises(TypeError, match=error_msg):
114+
ProofRequest(pytest.not_json)
115+
assert "Failed to load proof request JSON" in caplog.text
116+
117+
118+
# check for each possibly missing key whether the correct error is raised
119+
@pytest.mark.parametrize("key", pytest.proof_keys)
120+
def test_validate_presentation_json(key):
121+
proof = pytest.valid_proof_request
122+
proof_obj = ProofRequest(proof)
123+
with pytest.raises(AssertionError, match=f"Missing key {key}"):
124+
del proof_obj.json_data[key]
125+
proof_obj.validate_proof_request_json(json.dumps(proof_obj.json_data))
126+
127+
128+
def test_requested_attributes_empty(caplog):
129+
requested_attrs = ProofRequest(pytest.no_requested_attrs).get_requested_attributes()
130+
assert requested_attrs == []
131+
132+
133+
def test_requested_predicates_empty(caplog):
134+
requested_predicates = ProofRequest(
135+
pytest.valid_proof_request
136+
).get_requested_predicates()
137+
assert requested_predicates == []
138+
139+
140+
def test_requested_attributes(caplog):
141+
expected = [
142+
{
143+
"name": "name",
144+
"restrictions": [
145+
{"cred_def_id": "3avoBCqDMFHFaKUHug9s8W:3:CL:13:default"},
146+
{"value": "Alice Jones"},
147+
],
148+
}
149+
]
150+
requested_attrs = ProofRequest(
151+
pytest.valid_proof_request
152+
).get_requested_attributes()
153+
assert requested_attrs == expected
154+
155+
156+
def test_multi_attributes(caplog):
157+
expected = [
158+
{
159+
"name": "name",
160+
"restrictions": [
161+
{"cred_def_id": "3avoBCqDMFHFaKUHug9s8W:3:CL:13:default"},
162+
{"value": "Alice Jones"},
163+
],
164+
},
165+
{
166+
"name": "name",
167+
"restrictions": [
168+
{"cred_def_id": "3avoBCqDMFHFaKUHug9s8W:3:CL:13:default"},
169+
{"value": "Alice Jones"},
170+
],
171+
},
172+
]
173+
requested_attrs = ProofRequest(pytest.multi_attrs).get_requested_attributes()
174+
assert requested_attrs == expected
175+
176+
177+
def test_multi_preds(caplog):
178+
expected = [
179+
{
180+
"name": "name",
181+
"restrictions": [
182+
{"cred_def_id": "3avoBCqDMFHFaKUHug9s8W:3:CL:13:default"},
183+
{"value": "Alice Jones"},
184+
],
185+
},
186+
{
187+
"name": "name",
188+
"restrictions": [
189+
{"cred_def_id": "3avoBCqDMFHFaKUHug9s8W:3:CL:13:default"},
190+
{"value": "Alice Jones"},
191+
],
192+
},
193+
]
194+
requested_attrs = ProofRequest(pytest.multi_predicates).get_requested_predicates()
195+
assert requested_attrs == expected
196+
197+
198+
def test_get_connection_id():
199+
expected = "d965bd54-affb-4e11-ba8e-ea54a3214123"
200+
connection_id = ProofRequest(pytest.valid_proof_request).get_connection_id()
201+
assert connection_id == expected
202+
203+
204+
def test_get_version():
205+
expected = "1.0.0"
206+
version = ProofRequest(pytest.valid_proof_request).get_version()
207+
assert version == expected
208+
209+
210+
def test_get_name():
211+
expected = "Proof of Name"
212+
name = ProofRequest(pytest.valid_proof_request).get_name()
213+
assert name == expected

0 commit comments

Comments
 (0)