Skip to content

Commit 4c2200a

Browse files
committed
SDK-1019: Test coverage for unknown anchors
1 parent 72e5abb commit 4c2200a

File tree

5 files changed

+194
-36
lines changed

5 files changed

+194
-36
lines changed

src/Yoti/Util/Profile/AnchorConverter.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class AnchorConverter
1717
*
1818
* @return array map of oid => YotiAnchor[]
1919
*/
20-
public static function convertAnchors(Anchor $protobufAnchor)
20+
public static function convertAnchor(Anchor $protobufAnchor)
2121
{
2222
$anchorMap = [];
2323
$anchorSubType = $protobufAnchor->getSubType();
@@ -58,7 +58,7 @@ public static function convertAnchors(Anchor $protobufAnchor)
5858
*/
5959
public static function convert(Anchor $protobufAnchor)
6060
{
61-
$extensions = self::convertAnchors($protobufAnchor);
61+
$extensions = self::convertAnchor($protobufAnchor);
6262
foreach (array_keys(self::getAnchorTypesMap()) as $oid) {
6363
if (isset($extensions[$oid][0])) {
6464
return [
@@ -172,7 +172,8 @@ private static function convertCertToX509($certificate)
172172
*/
173173
private static function getAnchorTypeByOid($oid)
174174
{
175-
return self::getAnchorTypesMap()[$oid] ?: YotiAnchor::TYPE_UNKNOWN_NAME;
175+
$anchorTypesMap = self::getAnchorTypesMap();
176+
return isset($anchorTypesMap[$oid]) ? $anchorTypesMap[$oid] : YotiAnchor::TYPE_UNKNOWN_NAME;
176177
}
177178

178179
/**
@@ -184,7 +185,8 @@ private static function getAnchorTypeByOid($oid)
184185
*/
185186
private static function getAnchorTypeKey($type)
186187
{
187-
return array_flip(self::getAnchorTypesMap())[$type] ?: YotiAnchor::TYPE_UNKNOWN_NAME;
188+
$anchorTypesMap = array_flip(self::getAnchorTypesMap());
189+
return !empty($anchorTypesMap[$type]) ? $anchorTypesMap[$type] : YotiAnchor::TYPE_UNKNOWN_NAME;
188190
}
189191

190192
/**

src/Yoti/Util/Profile/AnchorListConverter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public static function convert(Traversable $anchorList)
1111
$yotiAnchorsMap = [];
1212

1313
foreach ($anchorList as $protobufAnchor) {
14-
if ($parsedAnchors = AnchorConverter::convertAnchors($protobufAnchor)) {
14+
if ($parsedAnchors = AnchorConverter::convertAnchor($protobufAnchor)) {
1515
$yotiAnchorsMap = array_merge_recursive($yotiAnchorsMap, $parsedAnchors);
1616
}
1717
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<?php
2+
3+
namespace YotiTest\Util\Profile;
4+
5+
use Yoti\Entity\Anchor;
6+
use YotiTest\TestCase;
7+
use Yoti\Util\Profile\AnchorConverter;
8+
9+
/**
10+
* @coversDefaultClass \Yoti\Util\Profile\AnchorListConverter
11+
*/
12+
class AnchorConverterTest extends TestCase
13+
{
14+
/**
15+
* @covers ::convertAnchor
16+
*/
17+
public function testConvertingSourceAnchor()
18+
{
19+
$anchorsData = $this->parseFromBase64String(TestAnchors::SOURCE_PP_ANCHOR);
20+
$anchor = $anchorsData[Anchor::TYPE_SOURCE_OID][0];
21+
22+
$this->assertEquals('Source', $anchor->getType());
23+
$this->assertEquals('OCR', $anchor->getSubtype());
24+
$this->assertEquals(
25+
'2018-04-12 13:14:32.835537',
26+
$anchor->getSignedTimestamp()->getTimestamp()->format('Y-m-d H:i:s.u')
27+
);
28+
$this->assertEquals('PASSPORT', $anchor->getValue());
29+
30+
$this->assertSerialNumber($anchor, '277870515583559162487099305254898397834');
31+
$this->assertIssuer($anchor, 'id-at-commonName', 'passport-registration-server');
32+
}
33+
34+
/**
35+
* @covers ::convertAnchor
36+
*/
37+
public function testConvertingVerifierAnchor()
38+
{
39+
$anchorsData = $this->parseFromBase64String(TestAnchors::VERIFIER_YOTI_ADMIN_ANCHOR);
40+
$anchor = $anchorsData[Anchor::TYPE_VERIFIER_OID][0];
41+
42+
$this->assertEquals('Verifier', $anchor->getType());
43+
$this->assertEquals('', $anchor->getSubtype());
44+
$this->assertEquals(
45+
'2018-04-11 12:13:04.095238',
46+
$anchor->getSignedTimestamp()->getTimestamp()->format('Y-m-d H:i:s.u')
47+
);
48+
$this->assertEquals('YOTI_ADMIN', $anchor->getValue());
49+
50+
$this->assertSerialNumber($anchor, '256616937783084706710155170893983549581');
51+
$this->assertIssuer($anchor, 'id-at-commonName', 'driving-licence-registration-server');
52+
}
53+
54+
/**
55+
* @covers ::convertAnchor
56+
*/
57+
public function testConvertingUnknownAnchor()
58+
{
59+
$anchorsData = $this->parseFromBase64String(TestAnchors::UNKNOWN_ANCHOR);
60+
$anchor = $anchorsData[Anchor::TYPE_UNKNOWN_NAME][0];
61+
62+
$this->assertEquals('UNKNOWN', $anchor->getType());
63+
$this->assertEquals('', $anchor->getSubtype());
64+
$this->assertEquals(
65+
'2018-04-11 12:13:03.923537',
66+
$anchor->getSignedTimestamp()->getTimestamp()->format('Y-m-d H:i:s.u')
67+
);
68+
$this->assertEquals('', $anchor->getValue());
69+
70+
$this->assertSerialNumber($anchor, '46131813624213904216516051554755262812');
71+
$this->assertIssuer($anchor, 'id-at-commonName', 'driving-licence-registration-server');
72+
}
73+
74+
/**
75+
* @covers ::convert
76+
*/
77+
public function testConvert()
78+
{
79+
$anchor = new \Attrpubapi\Anchor();
80+
$anchor->mergeFromString(base64_decode(TestAnchors::SOURCE_PP_ANCHOR));
81+
$anchorMap = AnchorConverter::convert($anchor);
82+
$this->assertEquals(Anchor::TYPE_SOURCE_OID, $anchorMap['oid']);
83+
$this->assertEquals('PASSPORT', $anchorMap['yoti_anchor']->getValue());
84+
}
85+
86+
/**
87+
* @param string $anchorString
88+
*
89+
* @return array $anchors
90+
*/
91+
private function parseFromBase64String($anchorString)
92+
{
93+
$anchor = new \Attrpubapi\Anchor();
94+
$anchor->mergeFromString(base64_decode($anchorString));
95+
return AnchorConverter::convertAnchor($anchor);
96+
}
97+
98+
/**
99+
* @param Anchor $anchor
100+
* @param string $serial_number
101+
*/
102+
private function assertSerialNumber($anchor, $serial_number)
103+
{
104+
$cert = $anchor->getOriginServerCerts()[0];
105+
$this->assertEquals($serial_number, $cert->tbsCertificate->serialNumber->value);
106+
}
107+
108+
/**
109+
* @param Anchor $anchor
110+
* @param string $type
111+
* @param string $value
112+
*/
113+
private function assertIssuer($anchor, $type, $value)
114+
{
115+
$cert = $anchor->getOriginServerCerts()[0];
116+
$issuer = $cert->tbsCertificate->issuer;
117+
$this->assertEquals($type, $issuer->rdnSequence[0][0]->type);
118+
$this->assertEquals($value, $issuer->rdnSequence[0][0]->value->printableString);
119+
}
120+
}

tests/Util/Profile/AnchorListConverterTest.php

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,57 +15,53 @@ class AnchorListConverterTest extends TestCase
1515
/**
1616
* @covers ::convert
1717
*/
18-
public function testConvertingSourceAnchor()
18+
public function testConvertingTwoSources()
1919
{
20-
$anchorsData = $this->parseFromBase64String(TestAnchors::SOURCE_PP_ANCHOR);
21-
$this->assertEquals('PASSPORT', $anchorsData[Anchor::TYPE_SOURCE_OID][0]->getValue());
22-
}
20+
$anchorsData = AnchorListConverter::convert(new ArrayObject([
21+
$this->parseFromBase64String(TestAnchors::SOURCE_PP_ANCHOR),
22+
$this->parseFromBase64String(TestAnchors::SOURCE_DL_ANCHOR),
23+
]));
2324

24-
/**
25-
* @covers ::convert
26-
*/
27-
public function testConvertingVerifierAnchor()
28-
{
29-
$anchorsData = $this->parseFromBase64String(TestAnchors::VERIFIER_YOTI_ADMIN_ANCHOR);
30-
$anchorVerifiersObj = $anchorsData[Anchor::TYPE_VERIFIER_OID][0];
31-
$this->assertEquals('YOTI_ADMIN', $anchorVerifiersObj->getValue());
25+
$anchorSource1 = $anchorsData[Anchor::TYPE_SOURCE_OID][0];
26+
$anchorSource2 = $anchorsData[Anchor::TYPE_SOURCE_OID][1];
27+
28+
$this->assertEquals('PASSPORT', $anchorSource1->getValue());
29+
$this->assertEquals('DRIVING_LICENCE', $anchorSource2->getValue());
3230
}
3331

3432
/**
3533
* @covers ::convert
3634
*/
37-
public function testConvertingTwoSources()
35+
public function testConvertingAnyAnchor()
3836
{
39-
$passportAnchor = new \Attrpubapi\Anchor();
40-
$passportAnchor->mergeFromString(base64_decode(TestAnchors::SOURCE_PP_ANCHOR));
37+
$anchorsData = AnchorListConverter::convert(new ArrayObject([
38+
$this->parseFromBase64String(TestAnchors::SOURCE_DL_ANCHOR),
39+
$this->parseFromBase64String(TestAnchors::VERIFIER_YOTI_ADMIN_ANCHOR),
40+
$this->parseFromBase64String(TestAnchors::UNKNOWN_ANCHOR),
41+
]));
4142

42-
$dlAnchor = new \Attrpubapi\Anchor();
43-
$dlAnchor->mergeFromString(base64_decode(TestAnchors::SOURCE_DL_ANCHOR));
43+
$anchorSource = $anchorsData[Anchor::TYPE_SOURCE_OID][0];
44+
$this->assertEquals('Source', $anchorSource->getType());
45+
$this->assertEquals('DRIVING_LICENCE', $anchorSource->getValue());
4446

45-
$collection = new ArrayObject([$passportAnchor, $dlAnchor]);
46-
$anchorsData = AnchorListConverter::convert($collection);
47-
$anchorSource1 = $anchorsData[Anchor::TYPE_SOURCE_OID][0]->getValue();
48-
$anchorSource2 = $anchorsData[Anchor::TYPE_SOURCE_OID][1]->getValue();
49-
$expectedAnchors = ['PASSPORT', 'DRIVING_LICENCE'];
47+
$anchorVerifier = $anchorsData[Anchor::TYPE_VERIFIER_OID][0];
48+
$this->assertEquals('Verifier', $anchorVerifier->getType());
49+
$this->assertEquals('YOTI_ADMIN', $anchorVerifier->getValue());
5050

51-
$this->assertEquals(
52-
json_encode($expectedAnchors),
53-
json_encode([$anchorSource1, $anchorSource2])
54-
);
51+
$anchorUnknown = $anchorsData[Anchor::TYPE_UNKNOWN_NAME][0];
52+
$this->assertEquals('UNKNOWN', $anchorUnknown->getType());
53+
$this->assertEquals('', $anchorUnknown->getValue());
5554
}
5655

5756
/**
5857
* @param string $anchorString
5958
*
6059
* @return array $anchors
6160
*/
62-
public function parseFromBase64String($anchorString)
61+
private function parseFromBase64String($anchorString)
6362
{
6463
$anchor = new \Attrpubapi\Anchor();
6564
$anchor->mergeFromString(base64_decode($anchorString));
66-
67-
$collection = new ArrayObject([$anchor]);
68-
69-
return AnchorListConverter::convert($collection);
65+
return $anchor;
7066
}
7167
}

tests/Util/Profile/TestAnchors.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,44 @@ class TestAnchors
123123
. "b185Qe6PWL4Jl+DvbzN2C0wsUFKRQyRwgBEIaQ8PyYstoCGhyG6joGfHdvA8tGS+Ol98"
124124
. "igUHdLW56nhnGLovTMIhz+RsUWrtszSjWSim2/4vJAE8QjXJ98ou4AVzKUOg9EUklWSU"
125125
. "5HX0xJQ0VOQ0U=";
126+
127+
const UNKNOWN_ANCHOR = "CjdBTkMtRE9Dz8qdV2DSwFJicqASUbdSRfmYOsJzswHQ4hDnfOUXtYeRlVOeQnVr3an"
128+
. "ESmMH7e2HEqAIMIIEHDCCAoSgAwIBAgIQIrSqBBTTXWxgGf6OvVm5XDANBgkqhkiG9w0"
129+
. "BAQsFADAuMSwwKgYDVQQDEyNkcml2aW5nLWxpY2VuY2UtcmVnaXN0cmF0aW9uLXNlcnZ"
130+
. "lcjAeFw0xODA0MDUxNDI3MzZaFw0xODA0MTIxNDI3MzZaMC4xLDAqBgNVBAMTI2RyaXZ"
131+
. "pbmctbGljZW5jZS1yZWdpc3RyYXRpb24tc2VydmVyMIIBojANBgkqhkiG9w0BAQEFAAO"
132+
. "CAY8AMIIBigKCAYEA3u2JsiXZftQXRG255RiFHuknxzgGdQ1Qys6O+/Dn/nwEOPbzGBn"
133+
. "4VTMfT1tCl7lD96Eq/qf0v3M6jLWQNJYqt7FbqlH0qtfQLT8fHX04vKwWkJdAvcpOSVd"
134+
. "1i2iyO5wVsvoXCt2ODyMGhd7/6qHeNZei50ARV8zF8diqneNq87Fgg1seuF+YEVAj14y"
135+
. "bjNmTk+MQvKkONSh2OPYNYeF/2H+0pXNe+MXhyY+vJlcRrqXLS52s4VjdeksVc05o/oe"
136+
. "NVckeqgmNhmEnLUNRGQFNOptrB0+g+hcdDQBFOkgeS/dS8iiMp5VQUShKOyQ5/twWOEQ"
137+
. "oJ3ZYRZGIyN8cErUfOUCQBwJOfdspMgbwom3//b5z9+alNOeZDOQRkI5vgvV8s+CvtSn"
138+
. "nMVt9WZMXmY+4uUP9/wZXmw2oBwlJmS9kUKslIHiMNzU07t1y6xMUMhYugxR5GatSN5k"
139+
. "H+36ylJATWVyuuj3Ub/q88cnaiT0jYtsAS4cpJUcEi60+j8qyuc5dAgMBAAGjNjA0MA4"
140+
. "GA1UdDwEB/wQEAwIDmDAiBgsrBgEEAYLwFwEBAQQTMBGAD0RSSVZJTkdfTElDRU5DRTA"
141+
. "NBgkqhkiG9w0BAQsFAAOCAYEANly4rGh8NaE3OwX54kOB8WBO2z/FBDDSi5VByHmMl4V"
142+
. "Pd8Pz26F1kS8qhcKjG6DuaX5UnX33GM6DuLv3nP3uiWEnv/lcitma2LC+qgJp4ItCw2E"
143+
. "MBLiof+dKzms4HqTHyKcPBpxBO6RPkvY5YQDEF0YiW17O31O2ltZTsc9ZsX5M1IiVwbO"
144+
. "ieTDtHy2M/K6Bol/JU/H/L1lAfpZ7khADZmEymjh/6Aw2v18Re37SWl86HxU4t862VNf"
145+
. "ogWO1nlgmgEwoCDgQ6OzR6dhGHJQfXymCJCB3wpA2x3i9rd2L8qrzxX9p5uInCK4+WKS"
146+
. "mhggB31s6dJwS5vAp5D6/i19aMgJqVFfxq/FUA1wkx/flgoC/Xb8MMTDTLo4/ekINdXX"
147+
. "jbQboVii2PGZKAK6FQNZ0FYC7WlA65gBBCZzvQ8imLwBQuy/kLvWbWXVDF5lzMdohijB"
148+
. "nuo4O4fenbAcy51CUvxAjgK7G9FQCyZ39gCPrpy3VVAcjbr9Njk15plcs1yAbGoUDCAE"
149+
. "SgAO1NMBkegQwBTWooNohw8CgIQhfq6dqolvIYDlBIFWThZo34qmRIQe2KKS4SCrxHT5"
150+
. "syjX0X1jtmHPIjZNifbiEAy7Jzzn1xlNWIwetnVoJBcnNumx4r0nmqRrCkRZLlgP4wwM"
151+
. "hwBV56X4TQOUMF8H1ESfmrWIMM9O+vhEJB5QuoAFRPaMcNkYTvbeAvAkhwxfbb8Ac3IW"
152+
. "JPakxORI8jeSop73yc9blxfV1D2ki4yjB2fI7uEXkRBOP/IQ301e7m+fQFLTZ1m1nZiz"
153+
. "Hh+s5GBcApwn92AsfRvgRnSXrc24qoqqvthm4fp9RbnO0d89RqO4Pxu6f1y9BqJ5RMhV"
154+
. "A6Vl+5vsU0nNhiH4Jki9N8dGmX3CTnwf51VUK5aeQwLIgCWaPjE4xC7YX9Fd8WUnsp1/"
155+
. "JllMhAQF7fym40usrHuVt9htd5E2p8zxRidA8NqWNV2rXTGWO5hUSwCAMdfgz431BZSO"
156+
. "fLPZHHg+g4qu+dcLerBqvMggVQLsGB10omwv4oJwiACqFAwgBEoADohVhusZuxzj2ldV"
157+
. "MOKIw+v59l/vWwSgHEIYbIcHNg03EHNLWA7EzrEny+jXyaKERPK8pxASewVJTQo3qYm3"
158+
. "Ezr9QuEy5XG2WfATe1OZuchJxK+IpHRN7o1ZxHf9cCXa22KA4bAKUgb/gSKC6hr9bjMu"
159+
. "06qyb/P+TzWNLTv4OX51dE6iI4WwltsQnPg4BRcrWjvoqkgPi1AKVd+no4J3H2tc0b7a"
160+
. "s/KJCPgR7HMTtuxp/eooR0zPRB/bZFkywrdGbCECshb11G+j1iBYaFHc1ewcmcNjufZV"
161+
. "bZ60pR4JfZUcpiRZJO13ZNnfX7ugc2vK/tL1hM963Y4BfvKXnmQeiLojlpilPxOFET+n"
162+
. "1yodR8J/i1GWzV41Nwx2PFEQv0VofkOZp28mHgQsAM8omReGZqyKEf+oAWjFWY0l1M88"
163+
. "3URQSr0CV04U6iSbS6qeSzL5YkP4CNny0n4Pt79UJWyVA+nHAThnsz4relhfk82At5IL"
164+
. "ASx2zgOkeIJVm5UnTC2ywMkcIARDR0uX8mLLaAhocZv/4kdenjmzEE1nkHW7ks7qh+II"
165+
. "J0YbSPwVkGiIc7BbgXGE8cSGwKuul83Yy/z1InbhBl2B1drEuOjoA";
126166
}

0 commit comments

Comments
 (0)