FOSSology  4.4.0
Open Source License Compliance by Open Source Software
ClearingDaoTest.php
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2014-2015 Siemens AG
4  Author: Andreas Würl, Johannes Najjar
5 
6  SPDX-License-Identifier: GPL-2.0-only
7 */
8 
9 namespace Fossology\Lib\Dao;
10 
18 use Monolog\Logger;
19 use Monolog\Handler\ErrorLogHandler;
20 use Mockery as M;
21 use Mockery\MockInterface;
22 
23 class ClearingDaoTest extends \PHPUnit\Framework\TestCase
24 {
26  private $testDb;
28  private $dbManager;
30  private $uploadDao;
32  private $clearingDao;
34  private $now;
36  private $items;
37  private $groupId = 601;
38 
39 
40  protected function setUp() : void
41  {
42  $this->uploadDao = M::mock(UploadDao::class);
43  $this->uploadDao->shouldReceive('getUploadEntry')->withAnyArgs()->andReturn(["upload_fk" => 4]);
44 
45  $logger = new Logger('default');
46  $logger->pushHandler(new ErrorLogHandler());
47 
48  $this->testDb = new TestPgDb();
49  $this->dbManager = &$this->testDb->getDbManager();
50 
51  $this->clearingDao = new ClearingDao($this->dbManager, $this->uploadDao);
52 
53  $this->testDb->createPlainTables(
54  array(
55  'clearing_decision',
56  'clearing_decision_event',
57  'clearing_decision_type',
58  'clearing_event',
59  'clearing_licenses',
60  'highlight_bulk',
61  'license_ref',
62  'license_ref_bulk',
63  'license_set_bulk',
64  'users',
65  'uploadtree'
66  ));
67 
68  $this->testDb->createInheritedTables();
69 
70  $userArray = array(
71  array('myself', 1),
72  array('in_same_group', 2),
73  array('in_trusted_group', 3));
74  foreach ($userArray as $ur) {
75  $this->dbManager->insertInto('users', 'user_name, root_folder_fk', $ur);
76  }
77 
78  $refArray = array(
79  array(401, 'FOO', 'FOO', 'foo full', 'foo text'),
80  array(402, 'BAR', 'BAR', 'bar full', 'bar text'),
81  array(403, 'BAZ', 'BAZ', 'baz full', 'baz text'),
82  array(404, 'QUX', 'QUX', 'qux full', 'qux text')
83  );
84  foreach ($refArray as $params) {
85  $this->dbManager->insertInto('license_ref', 'rf_pk, rf_shortname, rf_spdx_id, rf_fullname, rf_text', $params, $logStmt = 'insert.ref');
86  }
87 
88  $modd = 536888320;
89  $modf = 33188;
90 
91  /* (pfile,item,lft,rgt)
92  upload101: upload101/ ( 0, 299, 1, 4)
93  Afile (201, 301, 1, 2)
94  Bfile (202, 302, 3, 4)
95  upload102: upload102/ ( 0, 300, 1, 8)
96  Afile (201, 303, 1, 2)
97  A-dir/ ( 0, 304, 3, 6)
98  A-dir/Afile (201, 305, 4, 5)
99  Bfile (202, 306, 7, 8)
100  */
101  $this->items = array(
102  299=>array(101, 299, 0, $modd, 1, 4, "upload101"),
103  300=>array(102, 300, 0, $modd, 1, 8, "upload102"),
104  301=>array(101, 301, 201, $modf, 1, 2, "Afile"),
105  302=>array(101, 302, 202, $modf, 3, 4, "Bfile"),
106  303=>array(102, 303, 201, $modf, 1, 2, "Afile"),
107  304=>array(102, 304, 0, $modd, 3, 6, "A-dir"),
108  305=>array(102, 305, 201, $modf, 4, 5, "Afile"),
109  306=>array(102, 306, 202, $modf, 7, 8, "Bfile"),
110  );
111  foreach ($this->items as $ur) {
112  $this->dbManager->insertInto('uploadtree', 'upload_fk,uploadtree_pk,pfile_fk,ufile_mode,lft,rgt,ufile_name', $ur);
113  }
114  $this->now = time();
115 
116  $bulkLicArray = array(
117  array(1, 401, 'TextFOO', false, 101, 299, $this->groupId),
118  array(2, 402, 'TextBAR', false, 101, 299, $this->groupId),
119  array(3, 403, 'TextBAZ', true, 101, 301, $this->groupId),
120  array(4, 403, 'TextBAZ', false, 101, 299, $this->groupId),
121  array(5, 404, 'TextQUX', true, 101, 299, $this->groupId),
122  array(6, 401, 'TexxFOO', true, 101, 302, $this->groupId),
123  array(7, 403, 'TextBAZ', false, 102, 300, $this->groupId),
124  array(8, 403, 'TextBAZ', true, 102, 306, $this->groupId)
125  );
126  foreach ($bulkLicArray as $params) {
127  $paramsRef = array($params[0], $params[2], $params[4], $params[5], $params[6]);
128  $paramsSet = array($params[0], $params[1], $params[3]);
129  $this->dbManager->insertInto('license_ref_bulk', 'lrb_pk, rf_text, upload_fk, uploadtree_fk, group_fk', $paramsRef, 'insert.bulkref');
130  $this->dbManager->insertInto('license_set_bulk', 'lrb_fk, rf_fk, removing', $paramsSet, 'insert.bulkset');
131  }
132 
133  $this->assertCountBefore = \Hamcrest\MatcherAssert::getCount();
134  }
135 
136  private function insertBulkEvents()
137  {
138  $bulkFindingsArray = array(
139  array(1, 5001),
140  array(1, 5001),// a second bulk match in the same file in a different place
141  array(1, 5002),
142  array(1, 5003),
143  array(4, 5004),
144  array(7, 5005)
145  );
146  foreach ($bulkFindingsArray as $params) {
147  $this->dbManager->insertInto('highlight_bulk', 'lrb_fk, clearing_event_fk', $params, $logStmt = 'insert.bulkfinds');
148  }
149 
150  $bulkClearingEvents = array(
151  array(5001, 301),
152  array(5002, 302),
153  array(5003, 303),
154  array(5004, 301),
155  array(5005, 305)
156  );
157  foreach ($bulkClearingEvents as $params) {
158  $this->dbManager->insertInto('clearing_event', 'clearing_event_pk, uploadtree_fk', $params, $logStmt = 'insert.bulkevents');
159  }
160  }
161 
162  private function buildProposals($licProp,$i=0)
163  {
164  foreach ($licProp as $lp) {
165  list($item,$user,$group,$rf,$isRm,$t) = $lp;
166  $this->dbManager->insertInto('clearing_event',
167  'clearing_event_pk, uploadtree_fk, user_fk, group_fk, rf_fk, removed, type_fk, date_added',
168  array($i,$item,$user,$group,$rf,$isRm,1, $this->getMyDate($this->now+$t)));
169  $i++;
170  }
171  }
172 
173  private function buildDecisions($cDec,$j=0)
174  {
175  foreach ($cDec as $cd) {
176  list($item,$user,$group,$type,$t,$scope,$eventIds) = $cd;
177  $this->dbManager->insertInto('clearing_decision',
178  'clearing_decision_pk, uploadtree_fk, pfile_fk, user_fk, group_fk, decision_type, date_added, scope',
179  array($j,$item,$this->items[$item][2],$user,$group,$type, $this->getMyDate($this->now+$t),$scope));
180  foreach ($eventIds as $eId) {
181  $this->dbManager->insertTableRow('clearing_decision_event', array('clearing_decision_fk' => $j, 'clearing_event_fk' => $eId));
182  }
183  $j++;
184  }
185  }
186 
187  function tearDown() : void
188  {
189  $this->testDb = null;
190  $this->dbManager = null;
191  $this->addToAssertionCount(\Hamcrest\MatcherAssert::getCount()-$this->assertCountBefore);
192  }
193 
194  private function getMyDate($ts)
195  {
196  return date('Y-m-d H:i:s T',$ts);
197  }
198 
199  public function testRelevantClearingEvents()
200  {
201  $groupId = 701;
202  $this->buildProposals(array(
203  array(301,1,$groupId,401,false,-99),
204  array(301,2,$groupId,402,true,-98),
205  array(301,2,$groupId,401,true,-97)
206  ),$firstEventId=0);
207  $this->buildDecisions(array(
208  array(301,1,$groupId,DecisionTypes::IDENTIFIED,-90,DecisionScopes::REPO,array($firstEventId,$firstEventId+1,$firstEventId+2))
209  ));
210  $itemTreeBounds = M::mock(ItemTreeBounds::class);
211  $itemTreeBounds->shouldReceive('getItemId')->andReturn(301);
212  $itemTreeBounds->shouldReceive('getUploadTreeTableName')->andReturn('uploadtree');
213  $itemTreeBounds->shouldReceive('containsFiles')->andReturn(false);
214  $itemTreeBounds->shouldReceive('getUploadId')->andReturn($this->items[301][0]);
215  $itemTreeBounds->shouldReceive('getLeft')->andReturn($this->items[301][4]);
216  $itemTreeBounds->shouldReceive('getRight')->andReturn($this->items[301][5]);
217  $this->uploadDao->shouldReceive('getGlobalDecisionSettingsFromInfo')
218  ->withArgs([$this->items[301][0]])->andReturn(false);
219 
220  $events1 = $this->clearingDao->getRelevantClearingEvents($itemTreeBounds, $groupId);
221 
222  assertThat($events1, arrayWithSize(2));
223  assertThat($events1, hasKeyInArray(401));
224  assertThat($events1, hasKeyInArray(402));
225  assertThat($events1[401], is(anInstanceOf(ClearingEvent::class)));
226  assertThat($events1[402]->getEventId(), is($firstEventId+1));
227  assertThat($events1[401]->getEventId(), is($firstEventId+2));
228  }
229 
230  function testWip()
231  {
232  $groupId = 701;
233  $this->buildProposals(array(
234  array(301,1,$groupId,401,false,-99),
235  array(301,1,$groupId,402,false,-98),
236  array(301,1,$groupId,401,true,-89),
237  ),$firstEventId=0);
238  $this->buildDecisions(array(
239  array(301,1,$groupId,DecisionTypes::IDENTIFIED,-90,DecisionScopes::REPO,array($firstEventId,$firstEventId+1))
240  ));
241  $watchThis = $this->clearingDao->isDecisionCheck(301, $groupId, DecisionTypes::WIP);
242  assertThat($watchThis,is(FALSE));
243  $watchOther = $this->clearingDao->isDecisionCheck(303, $groupId, DecisionTypes::WIP);
244  assertThat($watchOther,is(FALSE));
245  $this->buildProposals(array(
246  array(301,1,$groupId,403,false,-89),
247  ),$firstEventId+3);
248  $this->clearingDao->markDecisionAsWip(301, 1, $groupId);
249  $watchThisNow = $this->clearingDao->isDecisionCheck(301, $groupId, DecisionTypes::WIP);
250  assertThat($watchThisNow,is(TRUE));
251  $watchOtherNow = $this->clearingDao->isDecisionCheck(303, $groupId, DecisionTypes::WIP);
252  assertThat($watchOtherNow,is(FALSE));
253  }
254 
255  private function collectBulkLicenses($bulks)
256  {
257  $bulkLics = array();
258  foreach ($bulks as $bulk) {
259  if (array_key_exists('removedLicenses', $bulk)) {
260  $bulkLics = array_merge($bulkLics, $bulk['removedLicenses']);
261  }
262  if (array_key_exists('addedLicenses', $bulk)) {
263  $bulkLics = array_merge($bulkLics, $bulk['addedLicenses']);
264  }
265  }
266  return $bulkLics;
267  }
268 
269  public function testBulkHistoryWithoutMatches()
270  {
271  $treeBounds = M::mock(ItemTreeBounds::class);
272  $treeBounds->shouldReceive('getItemId')->andReturn(301);
273  $treeBounds->shouldReceive('getLeft')->andReturn(1);
274  $treeBounds->shouldReceive('getUploadTreeTableName')->andReturn("uploadtree");
275  $treeBounds->shouldReceive('getUploadId')->andReturn(101);
276  $bulks = $this->clearingDao->getBulkHistory($treeBounds, $this->groupId);
277 
278  $bulkMatched = array_map(function($bulk){
279  return $bulk['matched'];
280  }, $bulks);
281  $bulkText = array_map(function($bulk){
282  return $bulk['text'];
283  }, $bulks);
284 
285  assertThat($bulkMatched, arrayContaining(false, false, false, false, false));
286  assertThat($this->collectBulkLicenses($bulks), arrayContaining('FOO', 'BAR', 'BAZ', 'BAZ', 'QUX'));
287  assertThat($bulkText, arrayContaining('TextFOO', 'TextBAR', 'TextBAZ', 'TextBAZ', 'TextQUX'));
288  }
289 
290  public function testBulkHistoryWithoutMatchesFromDifferentFolder()
291  {
292  $treeBounds = M::mock(ItemTreeBounds::class);
293  $treeBounds->shouldReceive('getItemId')->andReturn(305);
294  $treeBounds->shouldReceive('getLeft')->andReturn(4);
295  $treeBounds->shouldReceive('getUploadTreeTableName')->andReturn("uploadtree");
296  $treeBounds->shouldReceive('getUploadId')->andReturn(102);
297  $bulks = $this->clearingDao->getBulkHistory($treeBounds, $this->groupId);
298 
299  $bulkMatched = array_map(function($bulk){
300  return $bulk['matched'];
301  }, $bulks);
302  assertThat($bulkMatched, arrayContaining(false));
303  }
304 
305  public function testBulkHistoryWithAMatch()
306  {
307  $this->insertBulkEvents();
308 
309  $treeBounds = M::mock(ItemTreeBounds::class);
310  $treeBounds->shouldReceive('getItemId')->andReturn(301);
311  $treeBounds->shouldReceive('getLeft')->andReturn(1);
312  $treeBounds->shouldReceive('getUploadTreeTableName')->andReturn("uploadtree");
313  $treeBounds->shouldReceive('getUploadId')->andReturn(101);
314  $bulks = $this->clearingDao->getBulkHistory($treeBounds, $this->groupId);
315 
316  $clearingEventIds = array_map(function($bulk){
317  return $bulk['id'];
318  }, $bulks);
319  $bulkMatched = array_map(function($bulk){
320  return $bulk['matched'];
321  }, $bulks);
322  $bulkLicDirs = array_map(function($bulk){
323  return count($bulk['removedLicenses'])>0;
324  }, $bulks);
325  $bulkTried = array_map(function($bulk){
326  return $bulk['tried'];
327  }, $bulks);
328 
329  assertThat($clearingEventIds, arrayContaining(5001, null, null, 5004, null));
330  assertThat($bulkMatched, arrayContaining(true, false, false, true, false));
331  assertThat($this->collectBulkLicenses($bulks), arrayContaining('FOO', 'BAR', 'BAZ', 'BAZ', 'QUX'));
332  assertThat($bulkLicDirs, arrayContaining(false, false, true, false, true));
333  assertThat($bulkTried, arrayContaining(true, true, true, true, true));
334  }
335 
336  public function testBulkHistoryWithAMatchReturningAlsoNotTried()
337  {
338  $this->insertBulkEvents();
339 
340  $treeBounds = M::mock(ItemTreeBounds::class);
341  $treeBounds->shouldReceive('getItemId')->andReturn(301);
342  $treeBounds->shouldReceive('getLeft')->andReturn(1);
343  $treeBounds->shouldReceive('getUploadTreeTableName')->andReturn("uploadtree");
344  $treeBounds->shouldReceive('getUploadId')->andReturn(101);
345  $bulks = $this->clearingDao->getBulkHistory($treeBounds, $this->groupId, false);
346 
347  $clearingEventIds = array_map(function($bulk){
348  return $bulk['id'];
349  }, $bulks);
350  $bulkMatched = array_map(function($bulk){
351  return $bulk['matched'];
352  }, $bulks);
353  $bulkLicDirs = array_map(function($bulk){
354  return count($bulk['removedLicenses'])>0;
355  }, $bulks);
356  $bulkTried = array_map(function($bulk){
357  return $bulk['tried'];
358  }, $bulks);
359 
360  assertThat($clearingEventIds, arrayContaining(5001, null, null, 5004, null, null));
361  assertThat($bulkMatched, arrayContaining(true, false, false, true, false, false));
362  assertThat($this->collectBulkLicenses($bulks), arrayContaining('FOO', 'BAR', 'BAZ', 'BAZ', 'QUX', 'FOO'));
363  assertThat($bulkLicDirs, arrayContaining(false, false, true, false, true, true));
364  assertThat($bulkTried, arrayContaining(true, true, true, true, true, false));
365  }
366 
367  public function testGetClearedLicenseMultiplicities()
368  {
369  $user = 1;
370  $groupId = 601;
371  $rf = 401;
372  $isRm = false;
373  $t = -10815;
374  $this->buildProposals(array(array(303,$user,$groupId,$rf,$isRm,$t),
375  array(305,$user,$groupId,$rf,$isRm,$t+1)),$eventId=0);
376  $type = DecisionTypes::IDENTIFIED;
377  $scope = DecisionScopes::ITEM;
378  $this->buildDecisions(array(array(303,$user,$groupId,$type,$t,$scope,array($eventId)),
379  array(305,$user,$groupId,$type,$t,$scope,array($eventId+1))));
380  $treeBounds = M::mock(ItemTreeBounds::class);
381 
382  $treeBounds->shouldReceive('getLeft')->andReturn(1);
383  $treeBounds->shouldReceive('getRight')->andReturn(8);
384  $treeBounds->shouldReceive('getUploadTreeTableName')->andReturn("uploadtree");
385  $treeBounds->shouldReceive('getUploadId')->andReturn(102);
386 
387  $this->uploadDao->shouldReceive('getGlobalDecisionSettingsFromInfo')
388  ->withArgs([102])->andReturn(false);
389 
390  $map = $this->clearingDao->getClearedLicenseIdAndMultiplicities($treeBounds, $groupId);
391  assertThat($map, is(array('FOO'=>array('count'=>2,'shortname'=>'FOO','spdx_id'=>'FOO','rf_pk'=>401))));
392  }
393 
394  public function testGetClearedLicenses()
395  {
396  $user = 1;
397  $groupId = 601;
398  $rf = 401;
399  $isRm = false;
400  $t = -10815;
401  $item = 303;
402  $this->buildProposals(array(array($item,$user,$groupId,$rf,$isRm,$t),
403  array($item,$user,$groupId,$rf+1,!$isRm,$t+1)),$eventId=0);
404  $type = DecisionTypes::IDENTIFIED;
405  $scope = DecisionScopes::ITEM;
406  $this->buildDecisions(array( array( $item,$user,$groupId,$type,$t,$scope,array($eventId,$eventId+1) ) ));
407  $treeBounds = M::mock(ItemTreeBounds::class);
408 
409  $treeBounds->shouldReceive('getLeft')->andReturn(1);
410  $treeBounds->shouldReceive('getRight')->andReturn(8);
411  $treeBounds->shouldReceive('getUploadTreeTableName')->andReturn("uploadtree");
412  $treeBounds->shouldReceive('getUploadId')->andReturn(102);
413 
414  $this->uploadDao->shouldReceive('getGlobalDecisionSettingsFromInfo')
415  ->withArgs([102])->andReturn(false);
416 
417  $map = $this->clearingDao->getClearedLicenses($treeBounds, $groupId);
418  assertThat($map, equalTo(array(new LicenseRef($rf,'FOO','foo full', 'FOO'))));
419  }
420 
421 
422  public function testMainLicenseIds()
423  {
424  $this->testDb->createPlainTables(array('upload_clearing_license'));
425  $uploadId = 101;
426  $mainLicIdsInitially = $this->clearingDao->getMainLicenseIds($uploadId, $this->groupId);
427  assertThat($mainLicIdsInitially, is(emptyArray()));
428 
429  $this->clearingDao->makeMainLicense($uploadId,$this->groupId,$licenseId=402);
430  $mainLicIdsAfterAddingOne = $this->clearingDao->getMainLicenseIds($uploadId, $this->groupId);
431  assertThat($mainLicIdsAfterAddingOne, arrayContaining(array($licenseId)));
432 
433  $this->clearingDao->makeMainLicense($uploadId,$this->groupId,$licenseId);
434  $mainLicIdsAfterAddingOneTwice = $this->clearingDao->getMainLicenseIds($uploadId, $this->groupId);
435  assertThat($mainLicIdsAfterAddingOneTwice, is(arrayWithSize(1)));
436 
437  $this->clearingDao->makeMainLicense($uploadId,$this->groupId,$licenseId2=403);
438  $mainLicIdsAfterAddingOther = $this->clearingDao->getMainLicenseIds($uploadId, $this->groupId);
439  assertThat($mainLicIdsAfterAddingOther, arrayContainingInAnyOrder(array($licenseId,$licenseId2)));
440 
441  $this->clearingDao->removeMainLicense($uploadId,$this->groupId,$licenseId2);
442  $mainLicIdsAfterRemovingOne = $this->clearingDao->getMainLicenseIds($uploadId, $this->groupId);
443  assertThat($mainLicIdsAfterRemovingOne, is(arrayWithSize(1)));
444 
445  $this->clearingDao->removeMainLicense($uploadId,$this->groupId,$licenseId2);
446  $mainLicIdAfterRemovingSomethingNotInSet = $this->clearingDao->getMainLicenseIds($uploadId, $this->groupId);
447  assertThat($mainLicIdAfterRemovingSomethingNotInSet, is(arrayWithSize(1)));
448 
449  $this->clearingDao->removeMainLicense($uploadId,$this->groupId+1,$licenseId);
450  $mainLicIdAfterInsertToOtherGroup = $this->clearingDao->getMainLicenseIds($uploadId, $this->groupId);
451  assertThat($mainLicIdAfterInsertToOtherGroup, is(arrayWithSize(1)));
452 
453  $this->clearingDao->removeMainLicense($uploadId+1,$this->groupId,$licenseId);
454  $mainLicIdAfterInsertToOtherUpload = $this->clearingDao->getMainLicenseIds($uploadId, $this->groupId);
455  assertThat($mainLicIdAfterInsertToOtherUpload, is(arrayWithSize(1)));
456  }
457 
458  public function testupdateClearingEvent()
459  {
460  $this->testDb->createSequences(array('clearing_event_clearing_event_pk_seq'));
461  $this->testDb->createConstraints(array('clearing_event_pkey'));
462  $this->dbManager->queryOnce("ALTER TABLE clearing_event ALTER COLUMN clearing_event_pk SET DEFAULT nextval('clearing_event_clearing_event_pk_seq'::regclass)");
463 
464  $this->clearingDao->updateClearingEvent($uploadTreeId=301, $userId=1, $groupId=1, $licenseId=402, $what='comment', $changeCom='abc123');
465  $rowPast = $this->dbManager->getSingleRow('SELECT * FROM clearing_event WHERE uploadtree_fk=$1 AND rf_fk=$2 ORDER BY clearing_event_pk DESC LIMIT 1',array($uploadTreeId,$licenseId),__METHOD__.'beforeReportinfo');
466  assertThat($rowPast['comment'],equalTo($changeCom));
467 
468  $this->clearingDao->updateClearingEvent($uploadTreeId, $userId, $groupId, $licenseId, $what='reportinfo', $changeRep='def456');
469  $rowFuture = $this->dbManager->getSingleRow('SELECT * FROM clearing_event WHERE uploadtree_fk=$1 AND rf_fk=$2 ORDER BY clearing_event_pk DESC LIMIT 1',array($uploadTreeId,$licenseId),__METHOD__.'afterReportinfo');
470  assertThat($rowFuture['comment'],equalTo($changeCom));
471  assertThat($rowFuture['reportinfo'],equalTo($changeRep));
472  }
473 }
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:16