Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/workflows/canary.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: SDK Monorepo Canary Release

on:
issue_comment:
types:
- created

jobs:
trigger-deploy:
name: Canary Deploy
uses: jupiterone/github-internal/.github/workflows/monorepo-canary-release.yaml@v1
secrets: inherit
4,455 changes: 3,404 additions & 1,051 deletions package-lock.json

Large diffs are not rendered by default.

93 changes: 50 additions & 43 deletions packages/cli/src/__tests__/cli-import.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as runtime from '@jupiterone/integration-sdk-runtime';
import axios from 'axios';
import { vol } from 'memfs';
import { randomUUID as uuid } from 'crypto';
import globby from 'globby';
Expand All @@ -18,7 +17,6 @@ import * as log from '../log';
import { createCli } from '..';

jest.mock('@jupiterone/integration-sdk-runtime');
jest.mock('axios');
jest.mock('fs');
jest.mock('globby');
jest.mock('../pause');
Expand All @@ -36,9 +34,25 @@ jest.mock('ora', () => {
});

const mockedCreateApiClient = jest.mocked(runtime.createApiClient);
const mockedAxios = jest.mocked(axios);
const mockedGlobby = jest.mocked(globby);

// Mock RequestClient
const mockPost = jest.fn();
const mockGet = jest.fn();
const mockApiClient = {
post: mockPost,
get: mockGet,
put: jest.fn(),
patch: jest.fn(),
delete: jest.fn(),
head: jest.fn(),
options: jest.fn(),
interceptors: {
request: { use: jest.fn(), eject: jest.fn() },
response: { use: jest.fn(), eject: jest.fn() },
},
};

const type1Entities = [
createEntity({
id: '1',
Expand Down Expand Up @@ -67,7 +81,9 @@ const type1Relationships = [
];

beforeEach(async () => {
mockedCreateApiClient.mockReturnValue(axios);
mockedCreateApiClient.mockReturnValue(mockApiClient as any);
mockPost.mockReset();
mockGet.mockReset();
vol.reset();
vol.fromJSON({
[`${TEST_STORAGE_LOCATION}/csv/entities/entity_type_1/${uuid()}.csv`]:
Expand Down Expand Up @@ -96,8 +112,8 @@ beforeEach(async () => {

test('should import json assets', async () => {
const jobId = uuid();
mockedAxios.post.mockResolvedValue({ data: { job: { id: jobId } } });
mockedAxios.get.mockResolvedValue({
mockPost.mockResolvedValue({ data: { job: { id: jobId } } });
mockGet.mockResolvedValue({
data: { job: { id: jobId, status: 'FINISHED' } },
});

Expand All @@ -112,35 +128,32 @@ test('should import json assets', async () => {
`--api-base-url=https://api.TEST.jupiterone.io`,
]);

expect(mockedAxios.post).toHaveBeenCalledWith(
'/persister/synchronization/jobs',
{
source: 'api',
scope,
},
);
expect(mockedAxios.post).toHaveBeenCalledWith(
expect(mockPost).toHaveBeenCalledWith('/persister/synchronization/jobs', {
source: 'api',
scope,
});
expect(mockPost).toHaveBeenCalledWith(
`/persister/synchronization/jobs/${jobId}/relationships?ignoreDuplicates=true&ignoreIllegalProperties=true`,
await parseToCsv(type1Relationships),
{
headers: { 'Content-Type': 'text/csv' },
},
);
expect(mockedAxios.post).toHaveBeenCalledWith(
expect(mockPost).toHaveBeenCalledWith(
`/persister/synchronization/jobs/${jobId}/entities?ignoreDuplicates=true&ignoreIllegalProperties=true`,
await parseToCsv(type1Entities),
{
headers: { 'Content-Type': 'text/csv' },
},
);
expect(mockedAxios.post).toHaveBeenCalledWith(
expect(mockPost).toHaveBeenCalledWith(
`/persister/synchronization/jobs/${jobId}/entities?ignoreDuplicates=true&ignoreIllegalProperties=true`,
await parseToCsv(type2Entities),
{
headers: { 'Content-Type': 'text/csv' },
},
);
expect(mockedAxios.post).toHaveBeenCalledWith(
expect(mockPost).toHaveBeenCalledWith(
`/persister/synchronization/jobs/${jobId}/finalize`,
);
expect(mockedCreateApiClient).toBeCalledWith({
Expand All @@ -152,8 +165,8 @@ test('should import json assets', async () => {

test('should exclude relationships when specified', async () => {
const jobId = uuid();
mockedAxios.post.mockResolvedValue({ data: { job: { id: jobId } } });
mockedAxios.get.mockResolvedValue({
mockPost.mockResolvedValue({ data: { job: { id: jobId } } });
mockGet.mockResolvedValue({
data: { job: { id: jobId, status: 'FINISHED' } },
});

Expand All @@ -168,43 +181,40 @@ test('should exclude relationships when specified', async () => {
`--no-include-relationships`,
]);

expect(mockedAxios.post).toHaveBeenCalledWith(
'/persister/synchronization/jobs',
{
source: 'api',
scope,
},
);
expect(mockedAxios.post).toHaveBeenCalledWith(
expect(mockPost).toHaveBeenCalledWith('/persister/synchronization/jobs', {
source: 'api',
scope,
});
expect(mockPost).toHaveBeenCalledWith(
`/persister/synchronization/jobs/${jobId}/entities?ignoreDuplicates=true&ignoreIllegalProperties=true`,
await parseToCsv(type1Entities),
{
headers: { 'Content-Type': 'text/csv' },
},
);
expect(mockedAxios.post).toHaveBeenCalledWith(
expect(mockPost).toHaveBeenCalledWith(
`/persister/synchronization/jobs/${jobId}/entities?ignoreDuplicates=true&ignoreIllegalProperties=true`,
await parseToCsv(type2Entities),
{
headers: { 'Content-Type': 'text/csv' },
},
);
expect(mockedAxios.post).not.toHaveBeenCalledWith(
expect(mockPost).not.toHaveBeenCalledWith(
`/persister/synchronization/jobs/${jobId}/relationships?ignoreDuplicates=true&ignoreIllegalProperties=true`,
expect.anything(),
{
headers: { 'Content-Type': 'text/csv' },
},
);
expect(mockedAxios.post).toHaveBeenCalledWith(
expect(mockPost).toHaveBeenCalledWith(
`/persister/synchronization/jobs/${jobId}/finalize`,
);
});

test('should exclude relationships when specified', async () => {
const jobId = uuid();
mockedAxios.post.mockResolvedValue({ data: { job: { id: jobId } } });
mockedAxios.get.mockResolvedValue({
mockPost.mockResolvedValue({ data: { job: { id: jobId } } });
mockGet.mockResolvedValue({
data: { job: { id: jobId, status: 'FINISHED' } },
});

Expand All @@ -219,28 +229,25 @@ test('should exclude relationships when specified', async () => {
`--no-include-entities`,
]);

expect(mockedAxios.post).toHaveBeenCalledWith(
'/persister/synchronization/jobs',
{
source: 'api',
scope,
},
);
expect(mockedAxios.post).not.toHaveBeenCalledWith(
expect(mockPost).toHaveBeenCalledWith('/persister/synchronization/jobs', {
source: 'api',
scope,
});
expect(mockPost).not.toHaveBeenCalledWith(
`/persister/synchronization/jobs/${jobId}/entities?ignoreDuplicates=true&ignoreIllegalProperties=true`,
expect.anything(),
{
headers: { 'Content-Type': 'text/csv' },
},
);
expect(mockedAxios.post).toHaveBeenCalledWith(
expect(mockPost).toHaveBeenCalledWith(
`/persister/synchronization/jobs/${jobId}/relationships?ignoreDuplicates=true&ignoreIllegalProperties=true`,
await parseToCsv(type1Relationships),
{
headers: { 'Content-Type': 'text/csv' },
},
);
expect(mockedAxios.post).toHaveBeenCalledWith(
expect(mockPost).toHaveBeenCalledWith(
`/persister/synchronization/jobs/${jobId}/finalize`,
);
});
Expand Down Expand Up @@ -276,7 +283,7 @@ test('should throw error when missing account', async () => {

test('should log error when import fails', async () => {
const error = new Error();
mockedAxios.post.mockRejectedValue(error);
mockPost.mockRejectedValue(error);

await expect(
createCli().parseAsync([
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/import/importAssetsFromCsv.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import globby from 'globby';
import upath from 'upath';
import createSpinner from 'ora';
import type { Alpha } from '@lifeomic/alpha';
import type { RequestClient } from '@jupiterone/platform-sdk-fetch';
import path from 'path';
import pMap from 'p-map';
import { retry } from '@lifeomic/attempt';
Expand Down Expand Up @@ -33,7 +33,7 @@ async function waitForSyncCompletion({ jobId, apiClient, progress }) {

interface ImportAssetsTypeParams {
storageDirectory: string;
apiClient: Alpha;
apiClient: RequestClient;
jobId: string;
assetType: 'entities' | 'relationships';
progress: (currentFile: string) => void;
Expand Down
2 changes: 1 addition & 1 deletion packages/integration-sdk-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
},
"dependencies": {
"@jupiterone/integration-sdk-core": "^17.2.1",
"@lifeomic/alpha": "^5.2.0",
"@jupiterone/platform-sdk-fetch": "6.0.3-canary-487-1.0",
"@lifeomic/attempt": "^3.0.3",
"async-sema": "^3.1.0",
"bunyan": "^1.8.12",
Expand Down
Loading
Loading