@@ -146,6 +146,38 @@ public function testWithPagination(): void
146146 $ this ->assertSame (Severity::MEDIUM , $ advisories [1 ]->severity );
147147 }
148148
149+ public function testDuplicateCvePerPackage (): void
150+ {
151+ $ responseFactory = function (string $ method , string $ url , array $ options ) {
152+ $ this ->assertSame ('POST ' , $ method );
153+ $ this ->assertSame ('https://api.github.com/graphql ' , $ url );
154+ $ this ->assertSame ('{"query":"query{securityVulnerabilities(ecosystem:COMPOSER,first:100){nodes{advisory{summary,permalink,publishedAt,withdrawnAt,severity,identifiers{type,value},references{url}},vulnerableVersionRange,package{name}},pageInfo{hasNextPage,endCursor}}}"} ' , $ options ['body ' ]);
155+
156+ return new MockResponse (json_encode ($ this ->getGraphQLResultPageWithMultipleCvePerPackage ()), ['http_code ' => 200 , 'response_headers ' => ['Content-Type ' => 'application/json; charset=utf-8 ' ]]);
157+ };
158+ $ client = new MockHttpClient ($ responseFactory );
159+
160+ $ source = new GitHubSecurityAdvisoriesSource ($ client , new NullLogger (), $ this ->providerManager , [], $ this ->doctrine );
161+ $ package = $ this ->getPackage ();
162+ $ advisoryCollection = $ source ->getAdvisories (new BufferIO ());
163+
164+ $ this ->assertNotNull ($ advisoryCollection );
165+ $ this ->assertSame (1 , $ client ->getRequestsCount ());
166+
167+ $ advisories = $ advisoryCollection ->getAdvisoriesForPackageName ($ package ->getName ());
168+ $ this ->assertCount (1 , $ advisories );
169+
170+ $ this ->assertSame ('GHSA-h58v-c6rf-abcd ' , $ advisories [0 ]->id );
171+ $ this ->assertSame ('Insert tag injection ' , $ advisories [0 ]->title );
172+ $ this ->assertSame ('vendor/package ' , $ advisories [0 ]->packageName );
173+ $ this ->assertSame ('=4.10.0 ' , $ advisories [0 ]->affectedVersions );
174+ $ this ->assertSame ('https://github.com/advisories/GHSA-h58v-c6rf-abcd ' , $ advisories [0 ]->link );
175+ $ this ->assertSame ('CVE-2020-25768 ' , $ advisories [0 ]->cve );
176+ $ this ->assertSame ('2021-07-01T17:00:04+0000 ' , $ advisories [0 ]->date ->format (\DateTimeInterface::ISO8601 ));
177+ $ this ->assertNull ($ advisories [0 ]->composerRepository );
178+ $ this ->assertSame (Severity::MEDIUM , $ advisories [0 ]->severity );
179+ }
180+
149181 private function getPackage (): Package
150182 {
151183 $ package = new Package ();
@@ -191,6 +223,24 @@ private function getGraphQLResultSecondPage(): array
191223 ];
192224 }
193225
226+ private function getGraphQLResultPageWithMultipleCvePerPackage (): array
227+ {
228+ return [
229+ 'data ' => [
230+ 'securityVulnerabilities ' => [
231+ 'nodes ' => [
232+ $ this ->graphQlPackageNode ('GHSA-h58v-c6rf-abcd ' , 'vendor/package ' , '= 4.10.0 ' , 'CVE-2020-25768 ' , 'Insert tag injection ' , '2021-07-01T17:00:04Z ' ),
233+ $ this ->graphQlPackageNode ('GHSA-f7wm-x4gw-abcd ' , 'vendor/package ' , '= 4.10.0 ' , 'CVE-2020-25768 ' , 'Insert tag injection in forms ' , '2020-09-24T16:23:54Z ' ),
234+ ],
235+ 'pageInfo ' => [
236+ 'hasNextPage ' => false ,
237+ 'endCursor ' => 'Y3Vyc29yOnYyOpK5MjAxOS0xMi0xN1QyMDozNTozMSswMTowMM0LWQ== ' ,
238+ ],
239+ ],
240+ ],
241+ ];
242+ }
243+
194244 private function graphQlPackageNode (string $ advisoryId , string $ packageName , string $ range , string $ cve , string $ summary , string $ publishedAt ): array
195245 {
196246 return [
0 commit comments