Skip to content

Commit 9bd27bd

Browse files
committed
added test cases
1 parent 7a3efbc commit 9bd27bd

File tree

4 files changed

+290
-0
lines changed

4 files changed

+290
-0
lines changed

spp_encryption/tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import test_encryption_provider
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
from unittest.mock import patch
2+
3+
from odoo.tests.common import TransactionCase
4+
5+
6+
class EncryptionProviderTest(TransactionCase):
7+
@classmethod
8+
def setUpClass(cls):
9+
super().setUpClass()
10+
cls.provide_no_type = cls.env["g2p.encryption.provider"].create({"name": "Test Provider"})
11+
cls.provider = cls.env["g2p.encryption.provider"].create(
12+
{"name": "Test Provider with Type", "type": "jwcrypto"}
13+
)
14+
cls.provider_with_key = cls.env["g2p.encryption.provider"].create(
15+
{"name": "Test Provider with Key", "type": "jwcrypto"}
16+
)
17+
cls.provider_with_key.generate_and_store_jwcrypto_key()
18+
19+
def test_get_jwk_key(self):
20+
self.assertEqual(self.provider.jwcrypto_key, False)
21+
with self.assertRaises(ValueError):
22+
self.provider._get_jwk_key()
23+
24+
expected_keys = ["kty", "kid", "n", "e", "d", "p", "q", "dp", "dq", "qi"]
25+
self.assertTrue(all(elem in expected_keys for elem in self.provider_with_key._get_jwk_key().keys()))
26+
27+
def test_encrypt_data_jwcrypto(self):
28+
with self.assertRaises(NotImplementedError):
29+
self.provide_no_type.encrypt_data(b"test")
30+
31+
with patch.object(type(self.provider), "encrypt_data_jwcrypto", return_value=None) as encrypt_data_jwcrypto:
32+
result = self.provider.encrypt_data(b"test")
33+
encrypt_data_jwcrypto.assert_called_once()
34+
35+
result_with_key = self.provider_with_key.encrypt_data(b"test")
36+
37+
self.assertIsNone(result)
38+
self.assertIsNotNone(result_with_key)
39+
self.assertIsInstance(result_with_key, bytes)
40+
41+
def test_decrypt_data_jwcrypto(self):
42+
with self.assertRaises(NotImplementedError):
43+
self.provide_no_type.decrypt_data(b"test")
44+
45+
with patch.object(type(self.provider), "decrypt_data_jwcrypto", return_value=None) as decrypt_data_jwcrypto:
46+
self.provider.decrypt_data(b"test")
47+
decrypt_data_jwcrypto.assert_called_once()
48+
49+
data = "test"
50+
encoded_data = data.encode("utf-8")
51+
52+
encrypted_data = self.provider_with_key.encrypt_data(encoded_data)
53+
decrypted_data = self.provider_with_key.decrypt_data(encrypted_data)
54+
55+
self.assertEqual(decrypted_data, encoded_data)
56+
57+
def test_jwt_sign_jwcrypto(self):
58+
with self.assertRaises(NotImplementedError):
59+
self.provide_no_type.jwt_sign({})
60+
61+
with patch.object(type(self.provider), "jwt_sign_jwcrypto", return_value=None) as jwt_sign_jwcrypto:
62+
self.provider.jwt_sign({})
63+
jwt_sign_jwcrypto.assert_called_once()
64+
65+
data = {"test": "test"}
66+
result = self.provider_with_key.jwt_sign(data)
67+
68+
self.assertIsNotNone(result)
69+
self.assertIsInstance(result, str)
70+
71+
def test_jwt_verify_jwcrypto(self):
72+
with self.assertRaises(NotImplementedError):
73+
self.provide_no_type.jwt_verify("test")
74+
75+
with patch.object(type(self.provider), "jwt_verify_jwcrypto", return_value=None) as jwt_verify_jwcrypto:
76+
self.provider.jwt_verify("test")
77+
jwt_verify_jwcrypto.assert_called_once()
78+
79+
data = {"test": "test"}
80+
token = self.provider_with_key.jwt_sign(data)
81+
verified, received_jwt = self.provider_with_key.jwt_verify(token)
82+
83+
self.assertTrue(verified)
84+
self.assertIsNotNone(received_jwt)
85+
86+
def test_get_jwks_jwcrypto(self):
87+
with self.assertRaises(NotImplementedError):
88+
self.provide_no_type.get_jwks()
89+
90+
with patch.object(type(self.provider), "get_jwks_jwcrypto", return_value=None) as get_jwks_jwcrypto:
91+
self.provider.get_jwks()
92+
get_jwks_jwcrypto.assert_called_once()
93+
94+
jwks = self.provider_with_key.get_jwks()
95+
96+
self.assertIsNotNone(jwks)
97+
self.assertTrue("keys" in jwks)
98+
self.assertIsInstance(jwks["keys"], list)
99+
self.assertEqual(len(jwks["keys"]), 1)
100+
self.assertIsInstance(jwks["keys"][0], dict)
101+
102+
expected_keys = ["kty", "kid", "n", "e", "d", "p", "q", "dp", "dq", "qi"]
103+
self.assertTrue(all(elem in expected_keys for elem in jwks["keys"][0].keys()))
104+
105+
def test_generate_and_store_jwcrypto_key(self):
106+
with self.assertRaisesRegex(ValueError, "Unsupported key type. Currently, only 'RSA' is supported."):
107+
self.provider.generate_and_store_jwcrypto_key(key_type="DSA")
108+
109+
self.assertIn(self.provider.jwcrypto_key, [False, None])
110+
111+
self.provider.generate_and_store_jwcrypto_key()
112+
113+
expected_keys = ["kty", "kid", "n", "e", "d", "p", "q", "dp", "dq", "qi"]
114+
115+
self.assertIsNotNone(self.provider.jwcrypto_key)
116+
self.assertTrue(all(elem in expected_keys for elem in self.provider_with_key._get_jwk_key().keys()))

spp_openid_vci/tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import test_vci_issuer
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
from unittest.mock import Mock, patch
2+
3+
from odoo.exceptions import UserError
4+
from odoo.tests.common import TransactionCase
5+
6+
from ..models.res_partner import SPPRegistry as ResPartner
7+
8+
9+
class VCIIssuer(TransactionCase):
10+
@classmethod
11+
def setUpClass(cls):
12+
super().setUpClass()
13+
14+
cls.res_partner = cls.env["res.partner"].create({"name": "Test Partner"})
15+
cls.vci_issuer = cls.env["g2p.openid.vci.issuers"].create(
16+
{
17+
"name": "TestIssuer",
18+
"issuer_type": "Registry",
19+
"scope": "openid",
20+
}
21+
)
22+
23+
cls.id_type = cls.env["g2p.id.type"].create({"name": "Test ID Type"})
24+
cls.encryption_provider_id = cls.env["g2p.encryption.provider"].create(
25+
{
26+
"name": "Test Provider",
27+
"type": "jwcrypto",
28+
}
29+
)
30+
cls.encryption_provider_id.generate_and_store_jwcrypto_key()
31+
32+
cls.vci_issuer_complete = cls.env["g2p.openid.vci.issuers"].create(
33+
{
34+
"name": "TestIssuerComplete",
35+
"issuer_type": "Registry",
36+
"scope": "openid",
37+
"auth_sub_id_type_id": cls.id_type.id,
38+
"encryption_provider_id": cls.encryption_provider_id.id,
39+
}
40+
)
41+
cls.res_partner_complete = cls.env["res.partner"].create({"name": "Test Partner Complete"})
42+
cls.env["g2p.reg.id"].create(
43+
{
44+
"partner_id": cls.res_partner_complete.id,
45+
"id_type": cls.id_type.id,
46+
"value": "Test Value",
47+
}
48+
)
49+
50+
cls.test_issue_vc_json = {
51+
"credential_configurations_supported": None,
52+
"credential_endpoint": "http://localhost:8080/api/v1/vci/credential",
53+
"credential_issuer": "http://localhost:8080",
54+
"credentials_supported": [
55+
{
56+
"credential_definition": {
57+
"credentialSubject": {
58+
"UIN": {"display": [{"locale": "en", "name": "Beneficiary " "ID"}]},
59+
"address": {"display": [{"locale": "en", "name": "Address"}]},
60+
"dateOfBirth": {"display": [{"locale": "en", "name": "Date " "of " "Birth"}]},
61+
"fullName": {"display": [{"locale": "en", "name": "Name"}]},
62+
"gender": {"display": [{"locale": "en", "name": "Gender"}]},
63+
"nationalID": {"display": [{"locale": "en", "name": "National " "ID"}]},
64+
},
65+
"type": ["VerifiableCredential", "Registry"],
66+
},
67+
"credential_signing_alg_values_supported": ["RS256"],
68+
"cryptographic_binding_methods_supported": ["did:jwk"],
69+
"display": [
70+
{
71+
"background_color": "#12107c",
72+
"locale": "en",
73+
"logo": {
74+
"alt_text": "a square logo " "of a OpenG2P",
75+
"url": "http://localhost:8080/g2p_openid_vci/static/description/icon.png",
76+
},
77+
"name": "OpenG2P Registry Credential",
78+
"text_color": "#FFFFFF",
79+
}
80+
],
81+
"format": "ldp_vc",
82+
"id": "Registry",
83+
"order": ["fullName", "gender", "dateOfBirth"],
84+
"proof_types_supported": ["jwt"],
85+
"scope": "IndividualRegistry",
86+
}
87+
],
88+
}
89+
90+
def test_validate_vci_issuer(self):
91+
with self.assertRaisesRegex(UserError, "No issuer found."):
92+
self.res_partner._validate_vci_issuer(None)
93+
94+
with self.assertRaisesRegex(UserError, "No auth sub id type found in the issuer."):
95+
self.res_partner._validate_vci_issuer(self.vci_issuer)
96+
97+
self.vci_issuer.auth_sub_id_type_id = self.id_type
98+
99+
with self.assertRaisesRegex(UserError, "No encryption provider found in the issuer."):
100+
self.res_partner._validate_vci_issuer(self.vci_issuer)
101+
102+
self.vci_issuer.encryption_provider_id = self.encryption_provider_id
103+
104+
self.res_partner._validate_vci_issuer(self.vci_issuer)
105+
106+
@patch("requests.get")
107+
def test_issue_vc(self, mock_get):
108+
mock_response = Mock()
109+
mock_response.status_code = 200
110+
mock_response.json.return_value = self.test_issue_vc_json
111+
mock_get.return_value = mock_response
112+
113+
with self.assertRaisesRegex(
114+
UserError, f"No Registrant found with this ID Type: {self.vci_issuer.auth_sub_id_type_id.name}."
115+
):
116+
self.res_partner._issue_vc(self.vci_issuer)
117+
118+
with patch.object(type(self.vci_issuer), "issue_vc", return_value=None) as issue_vc:
119+
self.res_partner_complete._issue_vc(self.vci_issuer_complete)
120+
issue_vc.assert_called_once()
121+
122+
def test_create_qr_code(self):
123+
qr_img = self.res_partner_complete._create_qr_code("Test Data")
124+
self.assertIsNotNone(qr_img)
125+
self.assertIsInstance(qr_img, bytes)
126+
127+
def test_registry_issue_card(self):
128+
registry_issue_card_action = self.res_partner_complete.registry_issue_card()
129+
130+
form_id = self.env.ref("spp_openid_vci.issue_card_wizard").id
131+
132+
self.assertIsNotNone(registry_issue_card_action)
133+
self.assertIsInstance(registry_issue_card_action, dict)
134+
self.assertEqual(registry_issue_card_action.get("type"), "ir.actions.act_window")
135+
self.assertEqual(registry_issue_card_action.get("res_model"), "spp.issue.card.wizard")
136+
self.assertEqual(registry_issue_card_action.get("name"), "Issue Card")
137+
self.assertEqual(registry_issue_card_action.get("view_id"), form_id)
138+
self.assertEqual(registry_issue_card_action["context"]["default_partner_id"], self.res_partner_complete.id)
139+
140+
@patch.object(ResPartner, "_validate_vci_issuer")
141+
@patch.object(ResPartner, "_issue_vc")
142+
def test_issue_vc_qr(self, mock_vci_issuer, mock_issue_vc):
143+
mock_vci_issuer.return_value = True
144+
mock_issue_vc.return_value = {}
145+
146+
vc_qr = self.res_partner_complete._issue_vc_qr(self.vci_issuer_complete)
147+
148+
self.assertIsNotNone(vc_qr)
149+
self.assertIsInstance(vc_qr, dict)
150+
self.assertEqual(vc_qr.get("type"), "ir.actions.report")
151+
self.assertEqual(vc_qr.get("report_name"), "spp_openid_vci.id_vc_card")
152+
self.assertEqual(vc_qr.get("report_type"), "qweb-pdf")
153+
self.assertEqual(vc_qr.get("report_file"), "spp_openid_vci.id_vc_card")
154+
self.assertEqual(vc_qr.get("name"), "ID Card")
155+
self.assertEqual(vc_qr.get("context").get("active_ids")[0], self.res_partner_complete.id)
156+
157+
def test_sign_and_issue_credential(self):
158+
credential_data = {
159+
"test_key": "test_value",
160+
}
161+
credential = self.vci_issuer_complete.sign_and_issue_credential(credential_data)
162+
163+
self.assertIsNotNone(credential)
164+
self.assertIsInstance(credential, dict)
165+
self.assertIn("test_key", credential)
166+
self.assertIn("proof", credential)
167+
self.assertIn("jws", credential["proof"])
168+
self.assertIn("type", credential["proof"])
169+
self.assertIn("verificationMethod", credential["proof"])
170+
self.assertIn("proofPurpose", credential["proof"])
171+
self.assertIn("created", credential["proof"])
172+
self.assertIn("@context", credential["proof"])

0 commit comments

Comments
 (0)