From f72ef76066f582e4b8be274314109a7000b154d3 Mon Sep 17 00:00:00 2001 From: Nick Dowmon Date: Thu, 10 Feb 2022 14:20:09 -0500 Subject: [PATCH 1/2] Add optional _type and _class args to toMatchDirectRelationshipSchema --- CHANGELOG.md | 10 +++ .../src/__tests__/jest.test.ts | 62 +++++++++++++++++++ packages/integration-sdk-testing/src/jest.ts | 34 +++++++--- 3 files changed, 97 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ccf9e2c4..faab262ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,16 @@ and this project adheres to ### Added +- Added optional `_type` and `_class` arguments to + `.toMatchDirectRelationshipSchema` matcher. This enables developers to simply + pass the `StepRelationshipMetadata` interface to this matcher. Usage: + + ```ts + expect(collectedRelationships).toMatchDirectRelationshipSchema( + Relationships.ACCOUNT_HAS_USER, + ); + ``` + - Added optional `schema` property to `StepGraphObjectMetadata`. This allows developers to provide the property schema to expect on entities, relationships, and mapped relationships. This serves two uses: diff --git a/packages/integration-sdk-testing/src/__tests__/jest.test.ts b/packages/integration-sdk-testing/src/__tests__/jest.test.ts index 33c399aeb..55a5ab353 100644 --- a/packages/integration-sdk-testing/src/__tests__/jest.test.ts +++ b/packages/integration-sdk-testing/src/__tests__/jest.test.ts @@ -597,6 +597,68 @@ Find out more about JupiterOne schemas: https://github.com/JupiterOne/data-model Find out more about JupiterOne schemas: https://github.com/JupiterOne/data-model/tree/main/src/schemas `); }); + + test('should require matching `_type` if `_type` is provided', () => { + const relationship = generateCollectedDirectRelationship({ + string: 'abc', + number: 123, + boolean: true, + null: null, + _type: 'relationship-type', + }); + + const result = toMatchDirectRelationshipSchema(relationship, { + _type: 'different-relationship-type', + }); + + expect(result).toEqual({ + message: expect.any(Function), + pass: false, + }); + + expect(result.message()).toMatch(`errors=[ + { + "instancePath": "/_type", + "schemaPath": "#/properties/_type/const", + "keyword": "const", + "params": { + "allowedValue": "different-relationship-type" + }, + "message": "must be equal to constant" + } +]`); + }); + + test('should require matching `_class` if `_class` is provided', () => { + const relationship = generateCollectedDirectRelationship({ + string: 'abc', + number: 123, + boolean: true, + null: null, + _class: RelationshipClass.HAS, + }); + + const result = toMatchDirectRelationshipSchema(relationship, { + _class: RelationshipClass.IS, + }); + + expect(result).toEqual({ + message: expect.any(Function), + pass: false, + }); + + expect(result.message()).toMatch(`errors=[ + { + "instancePath": "/_class", + "schemaPath": "#/properties/_class/const", + "keyword": "const", + "params": { + "allowedValue": "IS" + }, + "message": "must be equal to constant" + } +]`); + }); }); describe('#toTargetEntities', () => { diff --git a/packages/integration-sdk-testing/src/jest.ts b/packages/integration-sdk-testing/src/jest.ts index 2559c34b9..2eb5d8b43 100644 --- a/packages/integration-sdk-testing/src/jest.ts +++ b/packages/integration-sdk-testing/src/jest.ts @@ -9,6 +9,7 @@ import { IntegrationSpecConfig, IntegrationStepExecutionContext, MappedRelationship, + RelationshipClass, Step, } from '@jupiterone/integration-sdk-core'; import { getMatchers } from 'expect/build/jestMatchersObject'; @@ -22,7 +23,7 @@ declare global { ): R; toMatchDirectRelationshipSchema( - params: ToMatchRelationshipSchemaParams, + params?: ToMatchRelationshipSchemaParams, ): R; toTargetEntities(entities: Entity[]): R; @@ -352,6 +353,8 @@ export function toMatchGraphObjectSchema( } export interface ToMatchRelationshipSchemaParams { + _class?: RelationshipClass; + _type?: string; /** * The schema that should be used to validate the input data against */ @@ -394,14 +397,27 @@ export function toMatchDirectRelationshipSchema( ], }; - return toMatchSchema( - received, - generateGraphObjectSchemaFromDataModelSchemas([ - ...graphObjectSchemas.reverse(), - directRelationshipSchema, - schema, - ]), - ); + const newRelationshipSchema = generateGraphObjectSchemaFromDataModelSchemas([ + ...graphObjectSchemas.reverse(), + directRelationshipSchema, + schema, + ]); + + if (params?._class) { + if (!newRelationshipSchema.properties) { + newRelationshipSchema.properties = {}; + } + newRelationshipSchema.properties._class = { const: params._class }; + } + + if (params?._type) { + if (!newRelationshipSchema.properties) { + newRelationshipSchema.properties = {}; + } + newRelationshipSchema.properties._type = { const: params._type }; + } + + return toMatchSchema(received, newRelationshipSchema); } function toMatchSchema( From 34336e2d2f1afba0b54e58c251275b85d384cf0f Mon Sep 17 00:00:00 2001 From: Nick Dowmon Date: Thu, 10 Feb 2022 14:28:06 -0500 Subject: [PATCH 2/2] Add optional _type arg to toMatchGraphObjectSchema --- CHANGELOG.md | 12 ++++++-- .../src/__tests__/jest.test.ts | 29 +++++++++++++++++++ packages/integration-sdk-testing/src/jest.ts | 6 +++- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index faab262ce..005d23aab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,11 +11,17 @@ and this project adheres to ### Added -- Added optional `_type` and `_class` arguments to - `.toMatchDirectRelationshipSchema` matcher. This enables developers to simply - pass the `StepRelationshipMetadata` interface to this matcher. Usage: +- Updated jest matchers in the following way: + + - added optional `_type` argument to `.toMatchGraphObjectSchema` matcher + - added optional `_type` and `_class` arguments to + `.toMatchDirectRelationshipSchema` matcher + + This enables developers to simply pass the `StepEntityMetadata` and + `StepRelationshipMetadata` interfaces to these matchers. Usage: ```ts + expect(collectedEntities).toMatchGraphObjectSchema(Entities.USER); expect(collectedRelationships).toMatchDirectRelationshipSchema( Relationships.ACCOUNT_HAS_USER, ); diff --git a/packages/integration-sdk-testing/src/__tests__/jest.test.ts b/packages/integration-sdk-testing/src/__tests__/jest.test.ts index 55a5ab353..a2da91076 100644 --- a/packages/integration-sdk-testing/src/__tests__/jest.test.ts +++ b/packages/integration-sdk-testing/src/__tests__/jest.test.ts @@ -103,6 +103,35 @@ describe('#toMatchGraphObjectSchema', () => { expect(result.message()).toEqual('Success!'); }); + test('should require matching `_type` if `_type` is provided', () => { + const entity = generateCollectedEntity({ + _class: 'Service', + _type: 'entity-type', + }); + + const result = toMatchGraphObjectSchema(entity, { + _class: entity._class, + _type: 'different-entity-type', + }); + + expect(result).toEqual({ + message: expect.any(Function), + pass: false, + }); + + expect(result.message()).toMatch(`errors=[ + { + "instancePath": "/_type", + "schemaPath": "#/properties/_type/const", + "keyword": "const", + "params": { + "allowedValue": "different-entity-type" + }, + "message": "must be equal to constant" + } +]`); + }); + test('should match class schema with no custom schema', () => { const result = toMatchGraphObjectSchema( generateCollectedEntity({ _class: 'Service' }), diff --git a/packages/integration-sdk-testing/src/jest.ts b/packages/integration-sdk-testing/src/jest.ts index 2eb5d8b43..977eb3857 100644 --- a/packages/integration-sdk-testing/src/jest.ts +++ b/packages/integration-sdk-testing/src/jest.ts @@ -229,6 +229,7 @@ export interface ToMatchGraphObjectSchemaParams { * The JupiterOne hierarchy class or classes from the data model that will be used to generate a new schema to be validated against. See: https://github.com/JupiterOne/data-model/tree/main/src/schemas */ _class: string | string[]; + _type?: string; /** * The schema that should be used to validate the input data against */ @@ -305,7 +306,7 @@ export function toMatchGraphObjectSchema( * The data received from the test assertion. (e.g. expect(DATA_HERE).toMatchGraphObjectSchema(...) */ received: T | T[], - { _class, schema, disableClassMatch }: ToMatchGraphObjectSchemaParams, + { _class, _type, schema, disableClassMatch }: ToMatchGraphObjectSchemaParams, ) { // Copy this so that we do not interfere with globals. // NOTE: The data-model should actuall expose a function for generating @@ -347,6 +348,9 @@ export function toMatchGraphObjectSchema( newEntitySchema.properties._class = { const: _class, }; + if (_type) { + newEntitySchema.properties._type = { const: _type }; + } } return toMatchSchema(received, newEntitySchema);