* @copyright Copyright (c) 2019, Branko Kokanovic * * @author Branko Kokanovic * * @license GNU AGPL version 3 or any later version * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * */ namespace OCA\FaceRecognition\Tests\Integration; use OC; use OCP\IConfig; use OCP\IUser; use OCP\AppFramework\App; use OCP\AppFramework\Db\DoesNotExistException; use OCA\FaceRecognition\BackgroundJob\FaceRecognitionContext; use OCA\FaceRecognition\BackgroundJob\FaceRecognitionLogger; use OCA\FaceRecognition\BackgroundJob\Tasks\CreateClustersTask; use OCA\FaceRecognition\Db\Face; use OCA\FaceRecognition\Db\Image; use OCA\FaceRecognition\Db\Person; use OCA\FaceRecognition\Model\ModelManager; use Test\TestCase; class MergeClusterToDatabaseTest extends IntegrationTestCase { public function testMergeEmptyClusterToDatabase() { $personMapper = $this->container->query('OCA\FaceRecognition\Db\PersonMapper'); $personMapper->mergeClusterToDatabase($this->user->getUid(), array(), array()); $personCount = $personMapper->countPersons($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(0, $personCount); } /** * Test when [] changes to p1=>[f1] * (test that new person is created) */ public function testCreatePerson() { $personMapper = $this->container->query('OCA\FaceRecognition\Db\PersonMapper'); $image = $this->createImage(); $face = $this->createFace($image->getId()); $personMapper->mergeClusterToDatabase($this->user->getUid(), array(), array(100=>[$face->getId()])); $personId = $this->assertOnePerson(); $this->assertFaces([$personId => [$face->getId()]]); } /** * Test when p1=>[f1] changes to p1=>[f1] * (test that nothing happens when input and output clusters are the same) */ public function testSamePerson() { $personMapper = $this->container->query('OCA\FaceRecognition\Db\PersonMapper'); $person = $this->createPerson(); $image = $this->createImage(); $face = $this->createFace($image->getId(), $person->getId()); $personMapper->invalidatePersons($image->getId()); $personMapper->mergeClusterToDatabase($this->user->getUid(), array($person->getId() => [$face->getId()]), array($person->getId() => [$face->getId()])); $personId = $this->assertOnePerson("foo"); $this->assertFaces([$personId => [$face->getId()]]); } /** * Test when p1=>[f1] changes to p2=>[f1] * (test that new person is created and old one deleted when face changes person) */ public function testChangePerson() { $personMapper = $this->container->query('OCA\FaceRecognition\Db\PersonMapper'); $person = $this->createPerson(); $image = $this->createImage(); $face = $this->createFace($image->getId(), $person->getId()); $personMapper->invalidatePersons($image->getId()); $personMapper->mergeClusterToDatabase($this->user->getUid(), array($person->getId() => [$face->getId()]), array($person->getId()+1 => [$face->getId()]) ); $this->assertPersonDoNotExist($person->getId()); $personId = $this->assertOnePerson(); $this->assertFaces([$personId => [$face->getId()]]); } /** * Test when p1=>[f1] changes to [] * (old person p1 should be deleted and face f1 resets its personId to null) */ public function testNoPersons() { $personMapper = $this->container->query('OCA\FaceRecognition\Db\PersonMapper'); $faceMapper = $this->container->query('OCA\FaceRecognition\Db\FaceMapper'); $person = $this->createPerson(); $image = $this->createImage(); $face = $this->createFace($image->getId(), $person->getId()); $personMapper->mergeClusterToDatabase($this->user->getUid(), array($person->getId() => [$face->getId()]), array()); $personCount = $personMapper->countPersons($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(0, $personCount); $persons = $personMapper->findAll($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(0, count($persons)); $this->assertPersonDoNotExist($person->getId()); $this->assertFaces([null => [$face->getId()]]); $faceCount = $faceMapper->countFaces($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(1, $faceCount); $faces = $faceMapper->getFaces($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(1, count($faces)); $this->assertNull($faces[0]->getPerson()); $faces = $faceMapper->findFromCluster($this->user->getUID(), $person->getId(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(0, count($faces)); } /** * Test when p1=>[f1, f2] changes to p2=>[f1], p3=>[f2] * (old person p1 should be deleted, and p2, p3 should be created) */ public function testSplitToNewPersons() { $personMapper = $this->container->query('OCA\FaceRecognition\Db\PersonMapper'); $person = $this->createPerson(); $image = $this->createImage(); $face1 = $this->createFace($image->getId(), $person->getId()); $face2 = $this->createFace($image->getId(), $person->getId()); $personMapper->invalidatePersons($image->getId()); $personMapper->mergeClusterToDatabase($this->user->getUid(), array( $person->getId() => [$face1->getId(), $face2->getId()] ), array( $person->getId()+1 => [$face1->getId()], $person->getId()+2 => [$face2->getId()] ) ); $clusterCount = $personMapper->countClusters($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(2, $clusterCount); $persons = $personMapper->findAll($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(2, count($persons)); usort($persons, function($p1, $p2) { return $p1->getId() - $p2->getId(); }); $this->assertTrue(is_null($persons[0]->getName())); $this->assertTrue(is_null($persons[1]->getName())); $this->assertTrue($persons[0]->getIsValid()); $this->assertTrue($persons[1]->getIsValid()); $this->assertPersonDoNotExist($person->getId()); $person1Id = $persons[0]->getId(); $person2Id = $persons[1]->getId(); $this->assertFaces([$person1Id => [$face1->getId()], $person2Id => [$face2->getId()]]); } /** * Test when p1=>[f1, f2] changes to p1=>[f1], p2=>[f2] * (new person p2 should be created, f2 should change person) */ public function testSplitToSamePerson() { $personMapper = $this->container->query('OCA\FaceRecognition\Db\PersonMapper'); $person = $this->createPerson(); $image = $this->createImage(); $face1 = $this->createFace($image->getId(), $person->getId()); $face2 = $this->createFace($image->getId(), $person->getId()); $personMapper->invalidatePersons($image->getId()); $personMapper->mergeClusterToDatabase($this->user->getUid(), array( $person->getId() => [$face1->getId(), $face2->getId()] ), array( $person->getId() => [$face1->getId()], $person->getId()+1 => [$face2->getId()] ) ); $clusterCount = $personMapper->countClusters($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(2, $clusterCount); $persons = $personMapper->findAll($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(2, count($persons)); usort($persons, function($p1, $p2) { return $p1->getId() - $p2->getId(); }); $this->assertTrue($persons[0]->getName() === 'foo'); $this->assertTrue($persons[1]->getName() === null); $this->assertTrue($persons[0]->getIsValid()); $this->assertTrue($persons[1]->getIsValid()); $person1Id = $persons[0]->getId(); $person2Id = $persons[1]->getId(); $this->assertEquals($person1Id, $person->getId()); $this->assertFaces([$person1Id => [$face1->getId()], $person2Id => [$face2->getId()]]); } /** * Test when p1=>[f1], p2=>[f2] changes to p1=>[f1, f2], p2=>[] * (old person p2 should be deleted, and p1 should be re-populated with both faces) */ public function testMergeToSamePersons() { $personMapper = $this->container->query('OCA\FaceRecognition\Db\PersonMapper'); $faceMapper = $this->container->query('OCA\FaceRecognition\Db\FaceMapper'); $person1 = $this->createPerson('foo'); $person2 = $this->createPerson('bar'); $image = $this->createImage(); $face1 = $this->createFace($image->getId(), $person1->getId()); $face2 = $this->createFace($image->getId(), $person2->getId()); $personMapper->invalidatePersons($image->getId()); $personMapper->mergeClusterToDatabase($this->user->getUid(), array( $person1->getId() => [$face1->getId()], $person2->getId() => [$face2->getId()], ), array( $person1->getId() => [$face1->getId(), $face2->getId()] ) ); $this->assertPersonDoNotExist($person2->getId()); $personId = $this->assertOnePerson('foo'); $this->assertEquals($personId, $person1->getId()); $this->assertFaces([$personId => [$face1->getId(), $face2->getId()]]); } /** * Test when p1=>[f1], p2=>[f2] changes to p1=>[], p2=[], p3=>[f1, f2] * (old persons p1 and p2 should be deleted, and p3 should be re-populated with both faces) */ public function testMergeToNewPersons() { $personMapper = $this->container->query('OCA\FaceRecognition\Db\PersonMapper'); $faceMapper = $this->container->query('OCA\FaceRecognition\Db\FaceMapper'); $person1 = $this->createPerson('foo'); $person2 = $this->createPerson('bar'); $image = $this->createImage(); $face1 = $this->createFace($image->getId(), $person1->getId()); $face2 = $this->createFace($image->getId(), $person2->getId()); $personMapper->invalidatePersons($image->getId()); $personMapper->mergeClusterToDatabase($this->user->getUid(), array( $person1->getId() => [$face1->getId()], $person2->getId() => [$face2->getId()], ), array( $person1->getId()+5 => [$face1->getId(), $face2->getId()] ) ); $this->assertPersonDoNotExist($person1->getId()); $this->assertPersonDoNotExist($person2->getId()); $personId = $this->assertOnePerson(); $this->assertFaces([$personId => [$face1->getId(), $face2->getId()]]); } /** * Test when p1=>[f1], p2=>[f2] changes to p1=>[f2], p2=>[f1] * (both persons and faces stay, but they change who is who) */ public function testSwap() { $personMapper = $this->container->query('OCA\FaceRecognition\Db\PersonMapper'); $faceMapper = $this->container->query('OCA\FaceRecognition\Db\FaceMapper'); $person1 = $this->createPerson('foo'); $person2 = $this->createPerson('bar'); $image = $this->createImage(); $face1 = $this->createFace($image->getId(), $person1->getId()); $face2 = $this->createFace($image->getId(), $person2->getId()); $personMapper->invalidatePersons($image->getId()); $personMapper->mergeClusterToDatabase($this->user->getUid(), array( $person1->getId() => [$face1->getId()], $person2->getId() => [$face2->getId()], ), array( $person1->getId() => [$face2->getId()], $person2->getId() => [$face1->getId()], ) ); $personCount = $personMapper->countPersons($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(2, $personCount); $persons = $personMapper->findAll($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(2, count($persons)); usort($persons, function($p1, $p2) { return $p1->getId() - $p2->getId(); }); $this->assertTrue(strpos($persons[0]->getName(), 'foo') !== false); $this->assertTrue(strpos($persons[1]->getName(), 'bar') !== false); $this->assertTrue($persons[0]->getIsValid()); $this->assertTrue($persons[1]->getIsValid()); $this->assertEquals($person1->getId(), $persons[0]->getId()); $this->assertEquals($person2->getId(), $persons[1]->getId()); $this->assertFaces([$person1->getId() => [$face2->getId()], $person2->getId() => [$face1->getId()]]); } /** * Test when p1=>[f1], p2=>[f2] changes to p1=>[f2], p3=>[f1] * (p2 is lost and p3 is created. f2 is swapped to existing person p1) */ public function testHalfSwap() { $personMapper = $this->container->query('OCA\FaceRecognition\Db\PersonMapper'); $faceMapper = $this->container->query('OCA\FaceRecognition\Db\FaceMapper'); $person1 = $this->createPerson('foo'); $person2 = $this->createPerson('bar'); $image = $this->createImage(); $face1 = $this->createFace($image->getId(), $person1->getId()); $face2 = $this->createFace($image->getId(), $person2->getId()); $personMapper->invalidatePersons($image->getId()); $personMapper->mergeClusterToDatabase($this->user->getUid(), array( $person1->getId() => [$face1->getId()], $person2->getId() => [$face2->getId()], ), array( $person1->getId() => [$face2->getId()], $person2->getId()+5 => [$face1->getId()], ) ); $clusterCount = $personMapper->countClusters($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(2, $clusterCount); $persons = $personMapper->findAll($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(2, count($persons)); usort($persons, function($p1, $p2) { return $p1->getId() - $p2->getId(); }); $this->assertTrue($persons[0]->getName() === 'foo'); $this->assertTrue($persons[1]->getName() === null); $this->assertTrue($persons[0]->getIsValid()); $this->assertTrue($persons[1]->getIsValid()); $this->assertEquals($person1->getId(), $persons[0]->getId()); $person3Id = $persons[1]->getId(); $this->assertFaces([$person1->getId() => [$face2->getId()], $person3Id => [$face1->getId()]]); } /** * Same test as MergeClustersTest::testMergeClustersComplex * p1=>[f1,f2,f3,f4], p2=>[f5,f6,f7,f8], p3=>[f9,f10,f11,f12], p4=>[f13,f14,f15,f16] * is changed to * p1=>[f1,f2,f3,f4] (same as before) * p2=>[f5,f6,f7,f8,f17] (added f17) * p3=>[f9,f10,f11] (removed f12) * p4=>[f13,f14,f15] (removed f16) * p5=>[f16,f18] (new person, moved f16 here plus new face f18) * p6=>[f19,f20,f21] (new person, all new faces) */ public function testComplexToSamePerson() { $personMapper = $this->container->query('OCA\FaceRecognition\Db\PersonMapper'); $faceMapper = $this->container->query('OCA\FaceRecognition\Db\FaceMapper'); $person1 = $this->createPerson('foo-p1'); $person2 = $this->createPerson('foo-p2'); $person3 = $this->createPerson('foo-p3'); $person4 = $this->createPerson('foo-p4'); $image = $this->createImage(); $face1 = $this->createFace($image->getId(), $person1->getId()); $face2 = $this->createFace($image->getId(), $person1->getId()); $face3 = $this->createFace($image->getId(), $person1->getId()); $face4 = $this->createFace($image->getId(), $person1->getId()); $face5 = $this->createFace($image->getId(), $person2->getId()); $face6 = $this->createFace($image->getId(), $person2->getId()); $face7 = $this->createFace($image->getId(), $person2->getId()); $face8 = $this->createFace($image->getId(), $person2->getId()); $face9 = $this->createFace($image->getId(), $person3->getId()); $face10 = $this->createFace($image->getId(), $person3->getId()); $face11 = $this->createFace($image->getId(), $person3->getId()); $face12 = $this->createFace($image->getId(), $person3->getId()); $face13 = $this->createFace($image->getId(), $person4->getId()); $face14 = $this->createFace($image->getId(), $person4->getId()); $face15 = $this->createFace($image->getId(), $person4->getId()); $face16 = $this->createFace($image->getId(), $person4->getId()); $face17 = $this->createFace($image->getId()); $face18 = $this->createFace($image->getId()); $face19 = $this->createFace($image->getId()); $face20 = $this->createFace($image->getId()); $face21 = $this->createFace($image->getId()); $personMapper->invalidatePersons($image->getId()); // First person is not invalid (it will remain same, so change it back to valid) $person1->setIsValid(true); $personMapper->update($person1); $personMapper->mergeClusterToDatabase($this->user->getUid(), array( $person1->getId() => [$face1->getId(), $face2->getId(), $face3->getId(), $face4->getId()], $person2->getId() => [$face5->getId(), $face6->getId(), $face7->getId(), $face8->getId()], $person3->getId() => [$face9->getId(), $face10->getId(), $face11->getId(), $face12->getId()], $person4->getId() => [$face13->getId(), $face14->getId(), $face15->getId(), $face16->getId()], ), array( $person1->getId() => [$face1->getId(), $face2->getId(), $face3->getId(), $face4->getId()], $person2->getId() => [$face5->getId(), $face6->getId(), $face7->getId(), $face8->getId(), $face17->getId()], $person3->getId() => [$face9->getId(), $face10->getId(), $face11->getId()], $person4->getId() => [$face13->getId(), $face14->getId(), $face15->getId()], $person1->getId() + 100 => [$face16->getId(), $face18->getId()], $person1->getId() + 101 => [$face19->getId(), $face20->getId(), $face21->getId()], ) ); $clusterCount = $personMapper->countClusters($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(6, $clusterCount); $persons = $personMapper->findAll($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(6, count($persons)); usort($persons, function($p1, $p2) { return $p1->getId() - $p2->getId(); }); $this->assertTrue($persons[0]->getName() === 'foo-p1'); $this->assertTrue($persons[1]->getName() === 'foo-p2'); $this->assertTrue($persons[2]->getName() === 'foo-p3'); $this->assertTrue($persons[3]->getName() === 'foo-p4'); $this->assertTrue($persons[4]->getName() === null); $this->assertTrue($persons[5]->getName() === null); foreach ($persons as $person) { $this->assertTrue($person->getIsValid()); } $this->assertEquals($person1->getId(), $persons[0]->getId()); $this->assertEquals($person2->getId(), $persons[1]->getId()); $this->assertEquals($person3->getId(), $persons[2]->getId()); $this->assertEquals($person4->getId(), $persons[3]->getId()); $person5Id = $persons[4]->getId(); $person6Id = $persons[5]->getId(); $this->assertFaces([ $person1->getId() => [$face1->getId(), $face2->getId(), $face3->getId(), $face4->getId()], $person2->getId() => [$face5->getId(), $face6->getId(), $face7->getId(), $face8->getId(), $face17->getId()], $person3->getId() => [$face9->getId(), $face10->getId(), $face11->getId()], $person4->getId() => [$face13->getId(), $face14->getId(), $face15->getId()], $person5Id => [$face16->getId(), $face18->getId()], $person6Id => [$face19->getId(), $face20->getId(), $face21->getId()], null => [$face12->getId()] ]); } /** * Same test as MergeClustersTest::testMergeClustersComplex * and here same as testComplexToSamePerson, but with a twist that all persons are new. * p1=>[f1,f2,f3,f4], p2=>[f5,f6,f7,f8], p3=>[f9,f10,f11,f12], p4=>[f13,f14,f15,f16] * is changed to * p5=>[f1,f2,f3,f4] (same as before) * p6=>[f5,f6,f7,f8,f17] (added f17) * p7=>[f9,f10,f11] (removed f12) * p8=>[f13,f14,f15] (removed f16) * p9=>[f16,f18] (new person, moved f16 here plus new face f18) * p10=>[f19,f20,f21] (new person, all new faces) */ public function testComplexToNewPerson() { $personMapper = $this->container->query('OCA\FaceRecognition\Db\PersonMapper'); $faceMapper = $this->container->query('OCA\FaceRecognition\Db\FaceMapper'); $person1 = $this->createPerson(); $person2 = $this->createPerson(); $person3 = $this->createPerson(); $person4 = $this->createPerson(); $image = $this->createImage(); $face1 = $this->createFace($image->getId(), $person1->getId()); $face2 = $this->createFace($image->getId(), $person1->getId()); $face3 = $this->createFace($image->getId(), $person1->getId()); $face4 = $this->createFace($image->getId(), $person1->getId()); $face5 = $this->createFace($image->getId(), $person2->getId()); $face6 = $this->createFace($image->getId(), $person2->getId()); $face7 = $this->createFace($image->getId(), $person2->getId()); $face8 = $this->createFace($image->getId(), $person2->getId()); $face9 = $this->createFace($image->getId(), $person3->getId()); $face10 = $this->createFace($image->getId(), $person3->getId()); $face11 = $this->createFace($image->getId(), $person3->getId()); $face12 = $this->createFace($image->getId(), $person3->getId()); $face13 = $this->createFace($image->getId(), $person4->getId()); $face14 = $this->createFace($image->getId(), $person4->getId()); $face15 = $this->createFace($image->getId(), $person4->getId()); $face16 = $this->createFace($image->getId(), $person4->getId()); $face17 = $this->createFace($image->getId()); $face18 = $this->createFace($image->getId()); $face19 = $this->createFace($image->getId()); $face20 = $this->createFace($image->getId()); $face21 = $this->createFace($image->getId()); $personMapper->invalidatePersons($image->getId()); $personMapper->mergeClusterToDatabase($this->user->getUid(), array( $person1->getId() => [$face1->getId(), $face2->getId(), $face3->getId(), $face4->getId()], $person2->getId() => [$face5->getId(), $face6->getId(), $face7->getId(), $face8->getId()], $person3->getId() => [$face9->getId(), $face10->getId(), $face11->getId(), $face12->getId()], $person4->getId() => [$face13->getId(), $face14->getId(), $face15->getId(), $face16->getId()], ), array( $person1->getId() + 100 => [$face1->getId(), $face2->getId(), $face3->getId(), $face4->getId()], $person1->getId() + 101 => [$face5->getId(), $face6->getId(), $face7->getId(), $face8->getId(), $face17->getId()], $person1->getId() + 102 => [$face9->getId(), $face10->getId(), $face11->getId()], $person1->getId() + 103 => [$face13->getId(), $face14->getId(), $face15->getId()], $person1->getId() + 104 => [$face16->getId(), $face18->getId()], $person1->getId() + 105 => [$face19->getId(), $face20->getId(), $face21->getId()], ) ); $clusterCount = $personMapper->countClusters($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(6, $clusterCount); $persons = $personMapper->findAll($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(6, count($persons)); usort($persons, function($p1, $p2) { return $p1->getId() - $p2->getId(); }); $this->assertPersonDoNotExist($person1->getId()); $this->assertPersonDoNotExist($person2->getId()); $this->assertPersonDoNotExist($person3->getId()); $this->assertPersonDoNotExist($person4->getId()); $this->assertTrue($persons[0]->getName() === null); $this->assertTrue($persons[1]->getName() === null); $this->assertTrue($persons[2]->getName() === null); $this->assertTrue($persons[3]->getName() === null); $this->assertTrue($persons[4]->getName() === null); $this->assertTrue($persons[5]->getName() === null); foreach ($persons as $person) { $this->assertTrue($person->getIsValid()); } $person5Id = $persons[0]->getId(); $person6Id = $persons[1]->getId(); $person7Id = $persons[2]->getId(); $person8Id = $persons[3]->getId(); $person9Id = $persons[4]->getId(); $person10Id = $persons[5]->getId(); $this->assertFaces([ $person5Id => [$face1->getId(), $face2->getId(), $face3->getId(), $face4->getId()], $person6Id => [$face5->getId(), $face6->getId(), $face7->getId(), $face8->getId(), $face17->getId()], $person7Id => [$face9->getId(), $face10->getId(), $face11->getId()], $person8Id => [$face13->getId(), $face14->getId(), $face15->getId()], $person9Id => [$face16->getId(), $face18->getId()], $person10Id => [$face19->getId(), $face20->getId(), $face21->getId()], null => [$face12->getId()] ]); } private function createPerson($name = 'foo'): Person { $personMapper = $this->container->query('OCA\FaceRecognition\Db\PersonMapper'); $person = new Person(); $person->setUser($this->user->getUID()); $person->setName($name); $person->setIsValid(true); $personMapper->insert($person); return $person; } private function createImage(): Image { $imageMapper = $this->container->query('OCA\FaceRecognition\Db\ImageMapper'); $image = new Image(); $image->setUser($this->user->getUid()); $image->setFile(1); $image->setModel(ModelManager::DEFAULT_FACE_MODEL_ID); $imageMapper->insert($image); return $image; } private function createFace($imageId, $personId = null) { $faceMapper = $this->container->query('OCA\FaceRecognition\Db\FaceMapper'); $face = Face::fromModel($imageId, array("left"=>0, "right"=>100, "top"=>0, "bottom"=>100, "detection_confidence"=>1.0)); if ($personId !== null) { $face->setPerson($personId); } $faceMapper->insertFace($face); return $face; } private function assertOnePerson($name = null): int { $personMapper = $this->container->query('OCA\FaceRecognition\Db\PersonMapper'); $clusterCount = $personMapper->countClusters($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(1, $clusterCount); $persons = $personMapper->findAll($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(1, count($persons)); if ($name !== null) { // check that retains the name $this->assertTrue($persons[0]->getName() === $name); $personCount = $personMapper->countPersons($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(1, $personCount); // Check that it can be found using this method too $persons = $personMapper->findByName($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID, $name); $this->assertEquals(1, count($persons)); } // Check that it can be found using this method too $personMapper->find($this->user->getUID(), $persons[0]->getId()); // After clustering, person must be valid $this->assertTrue($persons[0]->getIsValid()); return $persons[0]->getId(); } private function assertPersonDoNotExist(int $personId) { $personMapper = $this->container->query('OCA\FaceRecognition\Db\PersonMapper'); try { $personMapper->find($this->user->getUID(), $personId); $this->fail('Person still exist'); } catch (DoesNotExistException $e) { } } /** * Checks given array of faces exist in database and nothing more, and checks that faces are associated to persons. * Keys in arrray are person IDs, and values are arrays with face IDs: * [p1=>[f1], p2=>[f2, f3]...] * It does as much asserts as possible by getting data from database. If key is empty, that means that face do not have person. */ private function assertFaces(array $personToFaces) { $totalFaces = 0; foreach ($personToFaces as $person=>$faces) { $totalFaces += count($faces); } // Check total faces in DB $faceMapper = $this->container->query('OCA\FaceRecognition\Db\FaceMapper'); $faceCount = $faceMapper->countFaces($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals($totalFaces, $faceCount); // Check those faces have given persons $facesDb = $faceMapper->getFaces($this->user->getUID(), ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals($totalFaces, count($facesDb)); foreach($facesDb as $faceDb) { foreach ($personToFaces as $person=>$faces) { if (in_array($faceDb->getId(), $faces)) { if ($person !== "") { $this->assertEquals($faceDb->getPerson(), $person); } else { $this->assertNull($faceDb->getPerson()); } } } } // Check that each person have those faces (and no more) foreach($personToFaces as $person=>$faces) { if ($person === "") { continue; } $facesFromPerson = $faceMapper->findFromCluster($this->user->getUID(), $person, ModelManager::DEFAULT_FACE_MODEL_ID); $this->assertEquals(count($faces), count($facesFromPerson)); usort($facesFromPerson, function($f1, $f2) { return $f1->getId() - $f2->getId(); }); for ($i = 0; $i < count($faces); $i++) { $this->assertEquals($faces[$i], $facesFromPerson[$i]->getId()); } } } }