Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #263 - Introduce custom Jest test matcher for matching collecte… #264

Merged
merged 3 commits into from
Aug 3, 2020
Merged
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
6 changes: 3 additions & 3 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@jupiterone/cli",
"version": "2.6.0",
"version": "2.7.0",
"description": "The JupiterOne cli",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
Expand All @@ -22,8 +22,8 @@
"prepack": "yarn build:dist"
},
"dependencies": {
"@jupiterone/integration-sdk-core": "^2.6.0",
"@jupiterone/integration-sdk-runtime": "^2.6.0",
"@jupiterone/integration-sdk-core": "^2.7.0",
"@jupiterone/integration-sdk-runtime": "^2.7.0",
"@lifeomic/attempt": "^3.0.0",
"commander": "^5.0.0",
"globby": "^11.0.1",
Expand Down
6 changes: 3 additions & 3 deletions packages/integration-sdk-cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@jupiterone/integration-sdk-cli",
"version": "2.6.0",
"version": "2.7.0",
"description": "The SDK for developing JupiterOne integrations",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
Expand All @@ -22,15 +22,15 @@
"prepack": "yarn build:dist"
},
"dependencies": {
"@jupiterone/integration-sdk-runtime": "^2.6.0",
"@jupiterone/integration-sdk-runtime": "^2.7.0",
"commander": "^5.0.0",
"globby": "^11.0.0",
"lodash": "^4.17.19",
"upath": "^1.2.0",
"vis": "^4.21.0-EOL"
},
"devDependencies": {
"@jupiterone/integration-sdk-private-test-utils": "^2.6.0",
"@jupiterone/integration-sdk-private-test-utils": "^2.7.0",
"@pollyjs/adapter-node-http": "^4.0.4",
"@pollyjs/core": "^4.0.4",
"@pollyjs/persister-fs": "^4.0.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/integration-sdk-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@jupiterone/integration-sdk-core",
"version": "2.6.0",
"version": "2.7.0",
"description": "The SDK for developing JupiterOne integrations",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
Expand Down
4 changes: 2 additions & 2 deletions packages/integration-sdk-dev-tools/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@jupiterone/integration-sdk-dev-tools",
"version": "2.6.0",
"version": "2.7.0",
"description": "A collection of developer tools that will assist with building integrations.",
"repository": "[email protected]:JupiterOne/sdk.git",
"author": "JupiterOne <[email protected]>",
Expand All @@ -15,7 +15,7 @@
"access": "public"
},
"dependencies": {
"@jupiterone/integration-sdk-cli": "^2.6.0",
"@jupiterone/integration-sdk-cli": "^2.7.0",
"@types/jest": "^25.2.3",
"@types/node": "^14.0.5",
"@typescript-eslint/eslint-plugin": "^3.0.2",
Expand Down
4 changes: 2 additions & 2 deletions packages/integration-sdk-private-test-utils/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@jupiterone/integration-sdk-private-test-utils",
"private": true,
"version": "2.6.0",
"version": "2.7.0",
"description": "The SDK for developing JupiterOne integrations",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand All @@ -12,7 +12,7 @@
"node": "10.x || 12.x || 14.x"
},
"dependencies": {
"@jupiterone/integration-sdk-core": "^2.6.0",
"@jupiterone/integration-sdk-core": "^2.7.0",
"lodash": "^4.17.15",
"uuid": "^7.0.3"
},
Expand Down
6 changes: 3 additions & 3 deletions packages/integration-sdk-runtime/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@jupiterone/integration-sdk-runtime",
"version": "2.6.0",
"version": "2.7.0",
"description": "The SDK for developing JupiterOne integrations",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
Expand All @@ -23,7 +23,7 @@
"prepack": "yarn build:dist"
},
"dependencies": {
"@jupiterone/integration-sdk-core": "^2.6.0",
"@jupiterone/integration-sdk-core": "^2.7.0",
"@lifeomic/alpha": "^1.1.3",
"async-sema": "^3.1.0",
"axios": "^0.19.2",
Expand All @@ -42,7 +42,7 @@
"uuid": "^7.0.3"
},
"devDependencies": {
"@jupiterone/integration-sdk-private-test-utils": "^2.6.0",
"@jupiterone/integration-sdk-private-test-utils": "^2.7.0",
"@types/uuid": "^7.0.2",
"get-port": "^5.1.1",
"memfs": "^3.2.0",
Expand Down
8 changes: 4 additions & 4 deletions packages/integration-sdk-testing/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@jupiterone/integration-sdk-testing",
"version": "2.6.0",
"version": "2.7.0",
"description": "Testing utilities for JupiterOne integrations",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
Expand All @@ -23,8 +23,8 @@
"prepack": "yarn build:dist"
},
"dependencies": {
"@jupiterone/integration-sdk-core": "^2.6.0",
"@jupiterone/integration-sdk-runtime": "^2.6.0",
"@jupiterone/integration-sdk-core": "^2.7.0",
"@jupiterone/integration-sdk-runtime": "^2.7.0",
"@pollyjs/adapter-node-http": "^4.0.4",
"@pollyjs/core": "^4.0.4",
"@pollyjs/persister-fs": "^4.0.4",
Expand All @@ -35,7 +35,7 @@
"lodash": "^4.17.15"
},
"devDependencies": {
"@jupiterone/integration-sdk-private-test-utils": "^2.6.0",
"@jupiterone/integration-sdk-private-test-utils": "^2.7.0",
"@types/lodash": "^4.14.149",
"get-port": "^5.1.1",
"memfs": "^3.2.0"
Expand Down
171 changes: 171 additions & 0 deletions packages/integration-sdk-testing/src/__tests__/jest.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
import { Entity } from '@jupiterone/integration-sdk-core';
import { toMatchGraphObjectSchema, GraphObjectSchema } from '../jest';

function generateCollectedEntity(partial?: Partial<Entity>): Entity {
return {
name: 'appengine.googleapis.com',
_class: ['Service'],
_type: 'google_cloud_api_service',
_key:
'google_cloud_api_service_projects/123/services/appengine.googleapis.com',
displayName: 'App Engine Admin API',
category: ['infrastructure'],
description: "Provisions and manages developers' App Engine applications.",
state: 'ENABLED',
enabled: true,
usageRequirements: ['serviceusage.googleapis.com/tos/cloud'],
_rawData: [
{
name: 'default',
rawData: {
name: 'projects/123/services/appengine.googleapis.com',
config: {
name: 'appengine.googleapis.com',
title: 'App Engine Admin API',
documentation: {
summary:
"Provisions and manages developers' App Engine applications.",
},
quota: {},
authentication: {},
usage: {
requirements: ['serviceusage.googleapis.com/tos/cloud'],
},
},
state: 'ENABLED',
parent: 'projects/123',
},
},
],
...partial,
};
}

function generateGraphObjectSchema(
partialProperties?: Record<string, any>,
): GraphObjectSchema {
return {
additionalProperties: false,
properties: {
_type: { const: 'google_cloud_api_service' },
category: { const: ['infrastructure'] },
state: {
type: 'string',
enum: ['STATE_UNSPECIFIED', 'DISABLED', 'ENABLED'],
},
enabled: { type: 'boolean' },
usageRequirements: {
type: 'array',
items: { type: 'string' },
},
_rawData: {
type: 'array',
items: { type: 'object' },
},
...partialProperties,
},
};
}

describe('#toMatchGraphObjectSchema', () => {
test('should match custom entity schema with single class', () => {
const result = toMatchGraphObjectSchema(generateCollectedEntity(), {
_class: 'Service',
schema: generateGraphObjectSchema(),
});

expect(result).toEqual({
message: expect.any(Function),
pass: true,
});

expect(result.message()).toEqual('Success!');
});

test('should match custom entity schema with array of classes', () => {
const result = toMatchGraphObjectSchema(generateCollectedEntity(), {
_class: ['Service'],
schema: generateGraphObjectSchema(),
});

expect(result).toEqual({
message: expect.any(Function),
pass: true,
});

expect(result.message()).toEqual('Success!');
});

test('should match array of custom entities using schema', () => {
const result = toMatchGraphObjectSchema(
[generateCollectedEntity(), generateCollectedEntity()],
{
_class: ['Service'],
schema: generateGraphObjectSchema(),
},
);

expect(result).toEqual({
message: expect.any(Function),
pass: true,
});

expect(result.message()).toEqual('Success!');
});

test('should not pass if entity does not match schema', () => {
const data = generateCollectedEntity();
const result = toMatchGraphObjectSchema(data, {
_class: ['Service'],
schema: generateGraphObjectSchema({
enabled: { type: 'string' },
}),
});

expect(result).toEqual({
message: expect.any(Function),
pass: false,
});

const expectedSerialzedErrors = JSON.stringify(
[
{
keyword: 'type',
dataPath: '.enabled',
schemaPath: '#/properties/enabled/type',
params: {
type: 'string',
},
message: 'should be string',
},
],
null,
2,
);

expect(result.message()).toEqual(
`Error validating graph object against schema (data=${JSON.stringify(
data,
null,
2,
)}, errors=${expectedSerialzedErrors}, index=0)`,
);
});

test('should not pass if using an unknown class', () => {
const data = generateCollectedEntity();
const result = toMatchGraphObjectSchema(data, {
_class: ['INVALID_DATA_MODEL_CLASS'],
schema: generateGraphObjectSchema(),
});

expect(result).toEqual({
message: expect.any(Function),
pass: false,
});

expect(result.message()).toEqual(
`Error loading schemas for class (err=Invalid _class passed in schema for "toMatchGraphObjectSchema" (_class=#INVALID_DATA_MODEL_CLASS))`,
);
});
});
1 change: 1 addition & 0 deletions packages/integration-sdk-testing/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './context';
export * from './logger';
export * from './recording';
export * from './jobState';
export * from './jest';
Loading