From 26b0a20fefa1c4236f8ff62b0d9a7aec2bf01dfc Mon Sep 17 00:00:00 2001 From: ghe Date: Thu, 13 Oct 2022 19:11:20 +0100 Subject: [PATCH] fix: update targetAPI pagination --- src/lib/api/org/index.ts | 263 ++++--- src/lib/types.ts | 28 +- test/lib/org.test.ts | 1414 +++++++++++++++++++------------------- 3 files changed, 853 insertions(+), 852 deletions(-) diff --git a/src/lib/api/org/index.ts b/src/lib/api/org/index.ts index 3b3fc1d6..ac5804f3 100644 --- a/src/lib/api/org/index.ts +++ b/src/lib/api/org/index.ts @@ -1,12 +1,15 @@ import 'source-map-support/register'; import { requestsManager } from 'snyk-request-manager'; import * as debugLib from 'debug'; +import * as qs from 'querystring'; import { getApiToken } from '../../get-api-token'; import { getSnykHost } from '../../get-snyk-host'; -import { SnykProject, SnykTarget, TargetsResponse, RESTProjectData } from '../../types'; -import { StringNullableChain } from 'lodash'; -import { Console } from 'console'; -import { url } from 'inspector'; +import { + SnykProject, + RESTTargetResponse, + RESTProjectData, + SnykTarget, +} from '../../types'; const debug = debugLib('snyk:api-group'); @@ -143,7 +146,6 @@ interface ProjectsResponse { projects: SnykProject[]; } - interface RESTProjectsResponse { data: RESTProjectData[]; jsonapi: { @@ -160,13 +162,12 @@ interface RESTProjectsResponse { } interface ProjectsFilters { - name?: StringNullableChain; // If supplied, only projects that have a name that starts with this value will be returned + name?: string; // If supplied, only projects that have a name that starts with this value will be returned origin?: string; //If supplied, only projects that exactly match this origin will be returned type?: string; //If supplied, only projects that exactly match this type will be returned isMonitored?: boolean; // If set to true, only include projects which are monitored, if set to false, only include projects which are not monitored } - export async function listProjects( requestManager: requestsManager, orgId: string, @@ -183,58 +184,63 @@ export async function listProjects( ); } - const projects = await listAllProjects(requestManager, orgId, filters) - + const projects = await listAllProjects(requestManager, orgId, filters); + const snykProjectData: ProjectsResponse = { org: { id: orgId, }, - projects: projects - } + projects: projects, + }; return snykProjectData; } -async function listAllProjects(requestManager: requestsManager, +async function listAllProjects( + requestManager: requestsManager, orgId: string, filters?: ProjectsFilters, - ): Promise { - - let lastPage = false; - let projectsList: SnykProject[] = []; - let pageCount = 1; - let nextPageLink: string | undefined = undefined; - while (!lastPage) { - try { - const { - projects, - next, - }: { - projects: SnykProject[]; - next?: string; - } = await getProject(requestManager, orgId, filters, nextPageLink); - - projectsList = projectsList.concat(projects); - next - ? ((lastPage = false), (nextPageLink = next)) - : ((lastPage = true), (nextPageLink = '')); - pageCount++; - } catch (e) { - debug('Failed to update notification settings for ', orgId, e); - throw e; +): Promise { + let lastPage = false; + const projectsList: SnykProject[] = []; + let pageCount = 1; + let nextPageLink: string | undefined = undefined; + while (!lastPage) { + try { + debug( + `Fetching page ${pageCount} to list all projects for org ${orgId}\n`, + ); + const { + projects, + next, + }: { + projects: SnykProject[]; + next?: string; + } = await getProject(requestManager, orgId, filters, nextPageLink); + + projectsList.push(...projects); + next + ? ((lastPage = false), (nextPageLink = next)) + : ((lastPage = true), (nextPageLink = '')); + pageCount++; + } catch (e) { + debug('Failed to update notification settings for ', orgId, e); + throw e; } } - return projectsList + return projectsList; } -async function getProject(requestManager: requestsManager, +async function getProject( + requestManager: requestsManager, orgId: string, filters?: ProjectsFilters, nextPageLink?: string, - ): Promise< { projects: SnykProject[], next?: string } > { - - const url = nextPageLink ? nextPageLink : `/orgs/${orgId.trim()}/projects?version=2022-06-08~beta` - const res = await requestManager.request({ +): Promise<{ projects: SnykProject[]; next?: string }> { + const url = nextPageLink + ? nextPageLink + : `/orgs/${orgId.trim()}/projects?version=2022-06-08~beta`; + const res = await requestManager.request({ verb: 'get', url: url, body: JSON.stringify(filters), @@ -248,44 +254,45 @@ async function getProject(requestManager: requestsManager, JSON.stringify({ data: res.data, status: statusCode }), ); } - - const RESTresponseData = res.data as RESTProjectsResponse - const projects = convertToSnykProject(RESTresponseData.data) - const next = RESTresponseData.links.next + const RESTresponseData = res.data as RESTProjectsResponse; - return { projects, next} + const projects = convertToSnykProject(RESTresponseData.data); + const next = RESTresponseData.links.next; + return { projects, next }; } -function convertToSnykProject(projectData: RESTProjectData[]) : SnykProject[] { - +function convertToSnykProject(projectData: RESTProjectData[]): SnykProject[] { const projects: SnykProject[] = []; - for (const project of projectData) { + for (const project of projectData) { const projectTmp: SnykProject = { - id : project.id, - branch : project.attributes.targetReference , - created : project.attributes.created, - origin : project.attributes.origin, - name : project.attributes.name, - type: project.attributes.type, - } - projects.push(projectTmp) + id: project.id, + branch: project.attributes.targetReference, + created: project.attributes.created, + origin: project.attributes.origin, + name: project.attributes.name, + type: project.attributes.type, + }; + projects.push(projectTmp); } - - return projects -} + return projects; +} +interface TargetFilters { + remoteUrl?: string; + limit?: number; + isPrivate?: boolean; + origin?: string; + displayName?: string; + excludeEmpty?: boolean; +} export async function listTargets( requestManager: requestsManager, orgId: string, - config?: { - limit?: number, - isEmpty?: boolean, - origin?: string, - } -): Promise { + config?: TargetFilters, +): Promise<{ targets: SnykTarget[] }> { getApiToken(); getSnykHost(); debug(`Listing all targets for org: ${orgId}`); @@ -296,76 +303,69 @@ export async function listTargets( \nFor more information see: https://apidocs.snyk.io/?version=2022-09-15%7Ebeta#get-/orgs/-org_id-/targets`, ); } - - const targets = await listAllSnykTarget(requestManager, orgId, config) - return {targets: targets}; + const targets = await listAllSnykTarget(requestManager, orgId, config); + + return { targets }; } -export async function listAllSnykTarget(requestManager: requestsManager, +export async function listAllSnykTarget( + requestManager: requestsManager, orgId: string, - config?: { - limit?: number, - isEmpty?: boolean, - origin?: string, - } - ): Promise { - - let lastPage = false; - let SnykTargetList: SnykTarget[] = []; - let pageCount = 1; - let nextPageLink: string | undefined = undefined; - while (!lastPage) { - try { - debug(`Fetching page ${pageCount} of get target for ${orgId}\n`); - const { - SnykTarget, - next, - }: { - SnykTarget: SnykTarget[]; - next?: string; - } = await getSnykTarget(requestManager, orgId, nextPageLink, config); - - SnykTargetList = SnykTargetList.concat(SnykTarget); - next - ? ((lastPage = false), (nextPageLink = next)) - : ((lastPage = true), (nextPageLink = '')); - pageCount++; - } catch (e) { - debug('Failed to get targets for ', orgId, e); - throw e; + config?: TargetFilters, +): Promise { + let lastPage = false; + const targetsList: SnykTarget[] = []; + let pageCount = 1; + let nextPageLink: string | undefined = undefined; + while (!lastPage) { + try { + debug(`Fetching page ${pageCount} of get target for ${orgId}\n`); + const { + targets, + next, + }: { targets: SnykTarget[]; next?: string } = await getSnykTarget( + requestManager, + orgId, + nextPageLink, + config, + ); + + targetsList.push(...targets); + next + ? ((lastPage = false), (nextPageLink = next)) + : ((lastPage = true), (nextPageLink = undefined)); + pageCount++; + } catch (e) { + debug('Failed to get targets for ', orgId, e); + throw e; } } - return SnykTargetList + return targetsList; } -export async function getSnykTarget(requestManager: requestsManager, +export async function getSnykTarget( + requestManager: requestsManager, orgId: string, - nextPageLink?: string, - config?: { - limit?: number, - isEmpty?: boolean, - origin?: string, - }): Promise< { SnykTarget: SnykTarget[], next?: string } > { - - const link = nextPageLink ? nextPageLink : `https://api.dev.snyk.io/rest/orgs/${orgId.trim()}/targets?version=2022-09-15~beta` - const url = new URL(link) - - if (config) { - if (config.isEmpty) { - url.searchParams.set('isEmpty', String(config.isEmpty)) - } - if (config.limit) { - url.searchParams.set('limit', String(config.limit)) - } - if (config.origin) { - url.searchParams.set('origin', config.origin) - } - } - - const res = await requestManager.request({ + nextPageLink?: string, + config: { + limit?: number; + excludeEmpty?: boolean; + origin?: string; + } = { + limit: 20, + excludeEmpty: true, + }, +): Promise<{ targets: SnykTarget[]; next?: string }> { + const query = qs.stringify({ + version: '2022-09-15~beta', + ...config, + }); + const url = nextPageLink ?? `/orgs/${orgId.trim()}/targets?${query}`; + + const res = await requestManager.request({ verb: 'get', - url: url.toString(), + url: url, body: undefined, useRESTApi: true, }); @@ -377,11 +377,10 @@ export async function getSnykTarget(requestManager: requestsManager, JSON.stringify({ data: res.data, status: statusCode }), ); } - - const responseData = res.data - const SnykTarget = responseData.data - const next = responseData.links.next - return { SnykTarget, next } + const responseData = res.data as RESTTargetResponse; + const targets = responseData.data; + const { next } = responseData.links; + return { targets, next }; } diff --git a/src/lib/types.ts b/src/lib/types.ts index 84758f72..0fd2a3ff 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -118,12 +118,12 @@ export interface CommandResult { } export interface SnykProject { - name: string; - id: string; - created: string; - origin: string; - type: string; - branch: string | null; + name: string; + id: string; + created: string; + origin: string; + type: string; + branch: string | null; } @@ -200,20 +200,20 @@ export interface SnykTargetRelationships { } } -export interface SnykTargetData { +export interface SnykTarget { attributes: { - displayName: string; - isPrivate: boolean; + displayName: string; + isPrivate: boolean; origin: string; remoteUrl: string | null; } - id: string; + id: string; relationships: SnykTargetRelationships; type: string; } -export interface SnykTarget { - data: SnykTargetData[]; +export interface RESTTargetResponse { + data: SnykTarget[]; jsonapi: { version: string; } @@ -226,7 +226,3 @@ export interface SnykTarget { self?: string; }; } - -export interface TargetsResponse { - targets: SnykTarget[] -} \ No newline at end of file diff --git a/test/lib/org.test.ts b/test/lib/org.test.ts index 0e8451ac..226c6b3f 100644 --- a/test/lib/org.test.ts +++ b/test/lib/org.test.ts @@ -1,6 +1,9 @@ - import { requestsManager } from 'snyk-request-manager'; -import { listProjects, setNotificationPreferences, listTargets } from '../../src/lib'; +import { + listProjects, + setNotificationPreferences, + listTargets, +} from '../../src/lib'; const ORG_ID = process.env.TEST_ORG_ID as string; const SNYK_API_TEST = process.env.SNYK_API_TEST as string; @@ -86,7 +89,6 @@ describe('listProjects', () => { }, 5000); }); - describe('listTargets', () => { const requestManager = new requestsManager({ userAgentPrefix: 'snyk-api-import:tests', @@ -96,761 +98,765 @@ describe('listTargets', () => { }, 1000); it('list the targets in a given Org without pagination - mock', async () => { - jest.spyOn(requestManager, 'request').mockResolvedValue( - { - statusCode : 200, - data: - { - jsonapi: { version: '1.0' }, - data: [ - { - "type": "target", - "id": "8d7f3e14-3e31-4f56-9b9f-5100d97bexxx", - "attributes": { - "isPrivate": true, - "origin": "github-enterprise", - "displayName": "api-import-circle-test/js-nested-manifest", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" - }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - { - "type": "target", - "id": "6bc6d051-34a4-4883-becc-c0d658efexxx", - "attributes": { - "isPrivate": true, - "origin": "github-enterprise", - "displayName": "api-import-circle-test/ruby-with-versions", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" - }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - { - "type": "target", - "id": "5f3f0648-a18c-49eb-b415-56a591afcxxx", - "attributes": { - "isPrivate": true, - "origin": "bitbucket-server", - "displayName": "antoine-snyk-demo/TestRepoAntoine", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" - }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - { - "type": "target", - "id": "7fab7f61-0ed9-4696-a878-8c14122b8xxx", - "attributes": { - "isPrivate": true, - "origin": "bitbucket-cloud", - "displayName": "snyk-test-scm/dotnet-mixed-manifests", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" - }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - { - "type": "target", - "id": "3300bafb-cb25-45de-9833-321b3620xxxx", - "attributes": { - "isPrivate": false, - "origin": "bitbucket-cloud", - "displayName": "snyk-test-scm/npm-lockfiles", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" - }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - { - "type": "target", - "id": "1fd5033d-0e55-422f-b76e-9b25d7b9xxxx", - "attributes": { - "isPrivate": true, - "origin": "bitbucket-cloud", - "displayName": "snyk-test-scm/test-spaces", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" - }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - { - "type": "target", - "id": "72ec5dcf-9982-4bfa-86aa-06e2516axxxx", - "attributes": { - "isPrivate": false, - "origin": "azure-repos", - "displayName": "Test 105/goof.git", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" - }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - { - "type": "target", - "id": "da026d55-5ea5-47f8-a81c-86d9bf7fxxxx", - "attributes": { - "isPrivate": false, - "origin": "github", - "displayName": "snyk-fixtures/composer-with-vulns", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" - }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - { - "type": "target", - "id": "7fe02681-8deb-4f3b-a2d3-0c9990f7xxxx", - "attributes": { - "isPrivate": false, - "origin": "github", - "displayName": "snyk-fixtures/js-nested-manifest", - "remoteUrl": "null" - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" - }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - } - ], - links: { - } - } - } - ) + jest.spyOn(requestManager, 'request').mockResolvedValue({ + statusCode: 200, + data: { + jsonapi: { version: '1.0' }, + data: [ + { + type: 'target', + id: '8d7f3e14-3e31-4f56-9b9f-5100d97bexxx', + attributes: { + isPrivate: true, + origin: 'github-enterprise', + displayName: 'api-import-circle-test/js-nested-manifest', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', + }, + }, + }, + }, + }, + { + type: 'target', + id: '6bc6d051-34a4-4883-becc-c0d658efexxx', + attributes: { + isPrivate: true, + origin: 'github-enterprise', + displayName: 'api-import-circle-test/ruby-with-versions', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', + }, + }, + }, + }, + }, + { + type: 'target', + id: '5f3f0648-a18c-49eb-b415-56a591afcxxx', + attributes: { + isPrivate: true, + origin: 'bitbucket-server', + displayName: 'antoine-snyk-demo/TestRepoAntoine', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', + }, + }, + }, + }, + }, + { + type: 'target', + id: '7fab7f61-0ed9-4696-a878-8c14122b8xxx', + attributes: { + isPrivate: true, + origin: 'bitbucket-cloud', + displayName: 'snyk-test-scm/dotnet-mixed-manifests', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', + }, + }, + }, + }, + }, + { + type: 'target', + id: '3300bafb-cb25-45de-9833-321b3620xxxx', + attributes: { + isPrivate: false, + origin: 'bitbucket-cloud', + displayName: 'snyk-test-scm/npm-lockfiles', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', + }, + }, + }, + }, + }, + { + type: 'target', + id: '1fd5033d-0e55-422f-b76e-9b25d7b9xxxx', + attributes: { + isPrivate: true, + origin: 'bitbucket-cloud', + displayName: 'snyk-test-scm/test-spaces', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', + }, + }, + }, + }, + }, + { + type: 'target', + id: '72ec5dcf-9982-4bfa-86aa-06e2516axxxx', + attributes: { + isPrivate: false, + origin: 'azure-repos', + displayName: 'Test 105/goof.git', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', + }, + }, + }, + }, + }, + { + type: 'target', + id: 'da026d55-5ea5-47f8-a81c-86d9bf7fxxxx', + attributes: { + isPrivate: false, + origin: 'github', + displayName: 'snyk-fixtures/composer-with-vulns', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', + }, + }, + }, + }, + }, + { + type: 'target', + id: '7fe02681-8deb-4f3b-a2d3-0c9990f7xxxx', + attributes: { + isPrivate: false, + origin: 'github', + displayName: 'snyk-fixtures/js-nested-manifest', + remoteUrl: 'null', + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', + }, + }, + }, + }, + }, + ], + links: {}, + }, + }); const res = await listTargets(requestManager, ORG_ID); - expect(res).toMatchSnapshot() + expect(res).toMatchSnapshot(); }, 5000); it('list the targets in a given Org with filter - mock', async () => { - const req = jest.spyOn(requestManager, 'request') - - req.mockResolvedValue( - { - statusCode : 200, - data: - { - jsonapi: { version: '1.0' }, - data: [ - { - "type": "target", - "id": "8d7f3e14-3e31-4f56-9b9f-5100d97bexxx", - "attributes": { - "isPrivate": true, - "origin": "github-enterprise", - "displayName": "api-import-circle-test/js-nested-manifest", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" - }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - { - "type": "target", - "id": "6bc6d051-34a4-4883-becc-c0d658efexxx", - "attributes": { - "isPrivate": true, - "origin": "github-enterprise", - "displayName": "api-import-circle-test/ruby-with-versions", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" - }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - ], - links: { - } - } - } - ) + const req = jest.spyOn(requestManager, 'request'); + + req.mockResolvedValue({ + statusCode: 200, + data: { + jsonapi: { version: '1.0' }, + data: [ + { + type: 'target', + id: '8d7f3e14-3e31-4f56-9b9f-5100d97bexxx', + attributes: { + isPrivate: true, + origin: 'github-enterprise', + displayName: 'api-import-circle-test/js-nested-manifest', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', + }, + }, + }, + }, + }, + { + type: 'target', + id: '6bc6d051-34a4-4883-becc-c0d658efexxx', + attributes: { + isPrivate: true, + origin: 'github-enterprise', + displayName: 'api-import-circle-test/ruby-with-versions', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', + }, + }, + }, + }, + }, + ], + links: {}, + }, + }); - const res = await listTargets(requestManager, ORG_ID, {origin: "github-enterprise"}); - expect(req).toBeCalledWith({"body": undefined, "url": "https://api.dev.snyk.io/rest/orgs/74e2f385-a54f-491e-9034-76c53e72927a/targets?version=2022-09-15%7Ebeta&origin=github-enterprise", "useRESTApi": true, "verb": "get"}) - expect(res).toMatchSnapshot() + const res = await listTargets(requestManager, ORG_ID, { + origin: 'github-enterprise', + }); + expect(req).toBeCalledWith({ + body: undefined, + url: + '/orgs/74e2f385-a54f-491e-9034-76c53e72927a/targets?version=2022-09-15~beta&origin=github-enterprise', + useRESTApi: true, + verb: 'get', + }); + expect(res).toMatchSnapshot(); }, 5000); it('list the targets in a given Org with pagination - mock', async () => { - const req = jest.spyOn(requestManager, 'request') + const req = jest.spyOn(requestManager, 'request'); - req.mockResolvedValueOnce({ - statusCode : 200, - data: - { - jsonapi: { version: '1.0' }, - data: [ + req + .mockResolvedValueOnce({ + statusCode: 200, + data: { + jsonapi: { version: '1.0' }, + data: [ { - "type": "target", - "id": "8d7f3e14-3e31-4f56-9b9f-5100d97bexxx", - "attributes": { - "isPrivate": true, - "origin": "github-enterprise", - "displayName": "api-import-circle-test/js-nested-manifest", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + type: 'target', + id: '8d7f3e14-3e31-4f56-9b9f-5100d97bexxx', + attributes: { + isPrivate: true, + origin: 'github-enterprise', + displayName: 'api-import-circle-test/js-nested-manifest', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } + }, + }, + }, }, { - "type": "target", - "id": "6bc6d051-34a4-4883-becc-c0d658efexxx", - "attributes": { - "isPrivate": true, - "origin": "github-enterprise", - "displayName": "api-import-circle-test/ruby-with-versions", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + type: 'target', + id: '6bc6d051-34a4-4883-becc-c0d658efexxx', + attributes: { + isPrivate: true, + origin: 'github-enterprise', + displayName: 'api-import-circle-test/ruby-with-versions', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } + }, + }, + }, }, { - "type": "target", - "id": "5f3f0648-a18c-49eb-b415-56a591afcxxx", - "attributes": { - "isPrivate": true, - "origin": "bitbucket-server", - "displayName": "antoine-snyk-demo/TestRepoAntoine", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + type: 'target', + id: '5f3f0648-a18c-49eb-b415-56a591afcxxx', + attributes: { + isPrivate: true, + origin: 'bitbucket-server', + displayName: 'antoine-snyk-demo/TestRepoAntoine', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } + }, + }, + }, }, { - "type": "target", - "id": "7fab7f61-0ed9-4696-a878-8c14122b8xxx", - "attributes": { - "isPrivate": true, - "origin": "bitbucket-cloud", - "displayName": "snyk-test-scm/dotnet-mixed-manifests", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + type: 'target', + id: '7fab7f61-0ed9-4696-a878-8c14122b8xxx', + attributes: { + isPrivate: true, + origin: 'bitbucket-cloud', + displayName: 'snyk-test-scm/dotnet-mixed-manifests', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } + }, + }, + }, }, { - "type": "target", - "id": "3300bafb-cb25-45de-9833-321b3620xxxx", - "attributes": { - "isPrivate": false, - "origin": "bitbucket-cloud", - "displayName": "snyk-test-scm/npm-lockfiles", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + type: 'target', + id: '3300bafb-cb25-45de-9833-321b3620xxxx', + attributes: { + isPrivate: false, + origin: 'bitbucket-cloud', + displayName: 'snyk-test-scm/npm-lockfiles', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } + }, + }, + }, }, { - "type": "target", - "id": "1fd5033d-0e55-422f-b76e-9b25d7b9xxxx", - "attributes": { - "isPrivate": true, - "origin": "bitbucket-cloud", - "displayName": "snyk-test-scm/test-spaces", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + type: 'target', + id: '1fd5033d-0e55-422f-b76e-9b25d7b9xxxx', + attributes: { + isPrivate: true, + origin: 'bitbucket-cloud', + displayName: 'snyk-test-scm/test-spaces', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } + }, + }, + }, }, { - "type": "target", - "id": "72ec5dcf-9982-4bfa-86aa-06e2516axxxx", - "attributes": { - "isPrivate": false, - "origin": "azure-repos", - "displayName": "Test 105/goof.git", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + type: 'target', + id: '72ec5dcf-9982-4bfa-86aa-06e2516axxxx', + attributes: { + isPrivate: false, + origin: 'azure-repos', + displayName: 'Test 105/goof.git', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } + }, + }, + }, }, { - "type": "target", - "id": "da026d55-5ea5-47f8-a81c-86d9bf7fxxxx", - "attributes": { - "isPrivate": false, - "origin": "github", - "displayName": "snyk-fixtures/composer-with-vulns", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + type: 'target', + id: 'da026d55-5ea5-47f8-a81c-86d9bf7fxxxx', + attributes: { + isPrivate: false, + origin: 'github', + displayName: 'snyk-fixtures/composer-with-vulns', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } + }, + }, + }, }, { - "type": "target", - "id": "7fe02681-8deb-4f3b-a2d3-0c9990f7xxxx", - "attributes": { - "isPrivate": false, - "origin": "github", - "displayName": "snyk-fixtures/js-nested-manifest", - "remoteUrl": "null" - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + type: 'target', + id: '7fe02681-8deb-4f3b-a2d3-0c9990f7xxxx', + attributes: { + isPrivate: false, + origin: 'github', + displayName: 'snyk-fixtures/js-nested-manifest', + remoteUrl: 'null', + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - } + }, + }, + }, + }, ], - links: { - "first": "https://api.dev.snyk.io/rest/orgs/74e2f385-a54f-491e-9034-76c53e72927a/targets?version=2022-09-15~beta", - "last": "https://api.dev.snyk.io/rest/orgs/74e2f385-a54f-491e-9034-76c53e72927a/targets?version=2022-09-15~betapage=2", - "next": "https://api.dev.snyk.io/rest/orgs/74e2f385-a54f-491e-9034-76c53e72927a/targets?version=2022-09-15~betapage=2", - "self": "https://api.dev.snyk.io/rest/orgs/74e2f385-a54f-491e-9034-76c53e72927a/targets?version=2022-09-15~beta" - } - } - }).mockResolvedValueOnce( - { - statusCode : 200, - data: - { + links: { + first: + '/orgs/74e2f385-a54f-491e-9034-76c53e72927a/targets?version=2022-09-15~beta', + last: + '/orgs/74e2f385-a54f-491e-9034-76c53e72927a/targets?version=2022-09-15~beta&starting_after=v1.eyg', + next: + '/orgs/74e2f385-a54f-491e-9034-76c53e72927a/targets?version=2022-09-15~beta&starting_after=v1.eyJ', + self: + '/orgs/74e2f385-a54f-491e-9034-76c53e72927a/targets?version=2022-09-15~beta', + }, + }, + }) + .mockResolvedValueOnce({ + statusCode: 200, + data: { jsonapi: { version: '1.0' }, data: [ - { - "type": "target", - "id": "8d7f3e14-3e31-4f56-9b9f-5100d97bexxx", - "attributes": { - "isPrivate": true, - "origin": "github-enterprise", - "displayName": "api-import-circle-test/js-nested-manifest", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + { + type: 'target', + id: '8d7f3e14-3e31-4f56-9b9f-5100d97bexxx', + attributes: { + isPrivate: true, + origin: 'github-enterprise', + displayName: 'api-import-circle-test/js-nested-manifest', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - { - "type": "target", - "id": "6bc6d051-34a4-4883-becc-c0d658efexxx", - "attributes": { - "isPrivate": true, - "origin": "github-enterprise", - "displayName": "api-import-circle-test/ruby-with-versions", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + }, + }, + }, + }, + { + type: 'target', + id: '6bc6d051-34a4-4883-becc-c0d658efexxx', + attributes: { + isPrivate: true, + origin: 'github-enterprise', + displayName: 'api-import-circle-test/ruby-with-versions', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - { - "type": "target", - "id": "5f3f0648-a18c-49eb-b415-56a591afcxxx", - "attributes": { - "isPrivate": true, - "origin": "bitbucket-server", - "displayName": "antoine-snyk-demo/TestRepoAntoine", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + }, + }, + }, + }, + { + type: 'target', + id: '5f3f0648-a18c-49eb-b415-56a591afcxxx', + attributes: { + isPrivate: true, + origin: 'bitbucket-server', + displayName: 'antoine-snyk-demo/TestRepoAntoine', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - { - "type": "target", - "id": "7fab7f61-0ed9-4696-a878-8c14122b8xxx", - "attributes": { - "isPrivate": true, - "origin": "bitbucket-cloud", - "displayName": "snyk-test-scm/dotnet-mixed-manifests", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + }, + }, + }, + }, + { + type: 'target', + id: '7fab7f61-0ed9-4696-a878-8c14122b8xxx', + attributes: { + isPrivate: true, + origin: 'bitbucket-cloud', + displayName: 'snyk-test-scm/dotnet-mixed-manifests', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - { - "type": "target", - "id": "3300bafb-cb25-45de-9833-321b3620xxxx", - "attributes": { - "isPrivate": false, - "origin": "bitbucket-cloud", - "displayName": "snyk-test-scm/npm-lockfiles", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + }, + }, + }, + }, + { + type: 'target', + id: '3300bafb-cb25-45de-9833-321b3620xxxx', + attributes: { + isPrivate: false, + origin: 'bitbucket-cloud', + displayName: 'snyk-test-scm/npm-lockfiles', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - { - "type": "target", - "id": "1fd5033d-0e55-422f-b76e-9b25d7b9xxxx", - "attributes": { - "isPrivate": true, - "origin": "bitbucket-cloud", - "displayName": "snyk-test-scm/test-spaces", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + }, + }, + }, + }, + { + type: 'target', + id: '1fd5033d-0e55-422f-b76e-9b25d7b9xxxx', + attributes: { + isPrivate: true, + origin: 'bitbucket-cloud', + displayName: 'snyk-test-scm/test-spaces', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - { - "type": "target", - "id": "72ec5dcf-9982-4bfa-86aa-06e2516axxxx", - "attributes": { - "isPrivate": false, - "origin": "azure-repos", - "displayName": "Test 105/goof.git", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + }, + }, + }, + }, + { + type: 'target', + id: '72ec5dcf-9982-4bfa-86aa-06e2516axxxx', + attributes: { + isPrivate: false, + origin: 'azure-repos', + displayName: 'Test 105/goof.git', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - { - "type": "target", - "id": "da026d55-5ea5-47f8-a81c-86d9bf7fxxxx", - "attributes": { - "isPrivate": false, - "origin": "github", - "displayName": "snyk-fixtures/composer-with-vulns", - "remoteUrl": null - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + }, + }, + }, + }, + { + type: 'target', + id: 'da026d55-5ea5-47f8-a81c-86d9bf7fxxxx', + attributes: { + isPrivate: false, + origin: 'github', + displayName: 'snyk-fixtures/composer-with-vulns', + remoteUrl: null, + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - }, - { - "type": "target", - "id": "7fe02681-8deb-4f3b-a2d3-0c9990f7xxxx", - "attributes": { - "isPrivate": false, - "origin": "github", - "displayName": "snyk-fixtures/js-nested-manifest", - "remoteUrl": "null" - }, - "relationships": { - "org": { - "data": { - "id": "e661d4ef-5ad5-4cef-ad16-5157cefa8xxx", - "type": "org" + }, + }, + }, + }, + { + type: 'target', + id: '7fe02681-8deb-4f3b-a2d3-0c9990f7xxxx', + attributes: { + isPrivate: false, + origin: 'github', + displayName: 'snyk-fixtures/js-nested-manifest', + remoteUrl: 'null', + }, + relationships: { + org: { + data: { + id: 'e661d4ef-5ad5-4cef-ad16-5157cefa8xxx', + type: 'org', + }, + links: { + self: { + href: '/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx', }, - "links": { - "self": { - "href": "/v3/orgs/e661d4ef-5ad5-4cef-ad16-5157cefaxxx" - } - } - } - } - } - ], + }, + }, + }, + }, + ], links: { - "first": "https://api.dev.snyk.io/rest/orgs/74e2f385-a54f-491e-9034-76c53e72927a/targets?version=2022-09-15~beta", - "last": "https://api.dev.snyk.io/rest/orgs/74e2f385-a54f-491e-9034-76c53e72927a/targets?version=2022-09-15~betapage=2", - "self": "https://api.dev.snyk.io/rest/orgs/74e2f385-a54f-491e-9034-76c53e72927a/targets?version=2022-09-15~betapage=2" - } - } - } - ) + first: + '/orgs/74e2f385-a54f-491e-9034-76c53e72927a/targets?version=2022-09-15~beta', + last: + '/orgs/74e2f385-a54f-491e-9034-76c53e72927a/targets?version=2022-09-15~betapage=2', + self: + '/orgs/74e2f385-a54f-491e-9034-76c53e72927a/targets?version=2022-09-15~betapage=2', + }, + }, + }); const res = await listTargets(requestManager, ORG_ID); - expect(res).toMatchSnapshot() + expect(res).toMatchSnapshot(); }, 5000); it('Error if the requests fails', async () => { + jest + .spyOn(requestManager, 'request') + .mockResolvedValue({ statusCode: 500, data: {} }); - jest.spyOn(requestManager, 'request').mockResolvedValue({statusCode : 500, data: {}}) - - expect(async () => {await listTargets(requestManager, ORG_ID)}).rejects.toThrowError('Expected a 200 response, instead received: {"data":{},"status":500}') - + expect(async () => { + await listTargets(requestManager, ORG_ID); + }).rejects.toThrowError( + 'Expected a 200 response, instead received: {"data":{},"status":500}', + ); }, 5000); - - - }); - -