Milestone 0: import zappier billing, Verae middleware, and Zapier research
Compose-ready workspace: packages/zappier (rate card, portal, Stripe), packages/verae-zapier-middleware (timestamp + NATS), packages/verae-zapier (CLI app), vendor/zapier-platform, and research/zapier vendor corpus. Gate 0 structure checks pass. Product code and research are not yet wired.
This commit is contained in:
commit
b4150c8250
1364 changed files with 6814366 additions and 0 deletions
446
vendor/zapier-platform/packages/schema/test/functional-constraints/inputFieldGroupsConstraints.js
vendored
Normal file
446
vendor/zapier-platform/packages/schema/test/functional-constraints/inputFieldGroupsConstraints.js
vendored
Normal file
|
|
@ -0,0 +1,446 @@
|
|||
'use strict';
|
||||
|
||||
require('should');
|
||||
const schema = require('../../schema');
|
||||
|
||||
describe('inputFieldGroupsConstraints', () => {
|
||||
const baseDefinition = {
|
||||
version: '1.0.0',
|
||||
platformVersion: '17.2.0',
|
||||
};
|
||||
|
||||
describe('Action Types Validation', () => {
|
||||
it('should pass when group fields reference valid inputFieldGroups in triggers', () => {
|
||||
const definition = {
|
||||
...baseDefinition,
|
||||
triggers: {
|
||||
test_trigger: {
|
||||
key: 'test_trigger',
|
||||
noun: 'Test',
|
||||
display: {
|
||||
label: 'Test Trigger',
|
||||
description: 'A test trigger',
|
||||
},
|
||||
operation: {
|
||||
perform: '$func$2$f$',
|
||||
inputFieldGroups: [
|
||||
{
|
||||
key: 'contact',
|
||||
label: 'Contact Information',
|
||||
emphasize: false,
|
||||
},
|
||||
{ key: 'address', label: 'Address Information' },
|
||||
],
|
||||
inputFields: [
|
||||
{ key: 'name', group: 'contact' },
|
||||
{ key: 'email', group: 'contact' },
|
||||
{ key: 'street', group: 'address' },
|
||||
{ key: 'city', group: 'address' },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const results = schema.validateAppDefinition(definition);
|
||||
results.errors.should.have.length(0);
|
||||
});
|
||||
|
||||
it('should error when group reference does not exist in inputFieldGroups', () => {
|
||||
const definition = {
|
||||
...baseDefinition,
|
||||
searches: {
|
||||
test_search: {
|
||||
key: 'test_search',
|
||||
noun: 'Test',
|
||||
display: {
|
||||
label: 'Test Search',
|
||||
description: 'A test search',
|
||||
},
|
||||
operation: {
|
||||
perform: '$func$2$f$',
|
||||
inputFieldGroups: [
|
||||
{ key: 'contact', label: 'Contact Information' },
|
||||
],
|
||||
inputFields: [
|
||||
{ key: 'name', group: 'contact' },
|
||||
{ key: 'email', group: 'nonexistent' }, // This group doesn't exist
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const results = schema.validateAppDefinition(definition);
|
||||
results.errors.should.have.length(1);
|
||||
results.errors[0].name.should.equal('invalidGroupReference');
|
||||
results.errors[0].message.should.match(
|
||||
/Group "nonexistent" is not defined in inputFieldGroups/,
|
||||
);
|
||||
});
|
||||
|
||||
it('should error when groups are used in children fields', () => {
|
||||
const definition = {
|
||||
...baseDefinition,
|
||||
creates: {
|
||||
test_create: {
|
||||
key: 'test_create',
|
||||
noun: 'Test',
|
||||
display: {
|
||||
label: 'Test Create',
|
||||
description: 'A test create',
|
||||
},
|
||||
operation: {
|
||||
perform: '$func$2$f$',
|
||||
inputFieldGroups: [{ key: 'items', label: 'Item Details' }],
|
||||
inputFields: [
|
||||
{
|
||||
key: 'line_items',
|
||||
children: [
|
||||
{
|
||||
key: 'product',
|
||||
group: 'items', // Groups not allowed in children
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const results = schema.validateAppDefinition(definition);
|
||||
results.errors.should.have.length(1);
|
||||
results.errors[0].name.should.equal('groupInChildren');
|
||||
results.errors[0].message.should.match(
|
||||
/Group fields are not allowed in children fields/,
|
||||
);
|
||||
});
|
||||
|
||||
it('should error when inputFieldGroups has duplicate keys', () => {
|
||||
const definition = {
|
||||
...baseDefinition,
|
||||
triggers: {
|
||||
test_trigger: {
|
||||
key: 'test_trigger',
|
||||
noun: 'Test',
|
||||
display: {
|
||||
label: 'Test Trigger',
|
||||
description: 'A test trigger',
|
||||
},
|
||||
operation: {
|
||||
perform: '$func$2$f$',
|
||||
inputFieldGroups: [
|
||||
{ key: 'contact', label: 'Contact Information' },
|
||||
{ key: 'address', label: 'Address Information' },
|
||||
{ key: 'contact', label: 'Duplicate Contact' }, // Duplicate key
|
||||
],
|
||||
inputFields: [{ key: 'name', group: 'contact' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const results = schema.validateAppDefinition(definition);
|
||||
results.errors.should.have.length(1);
|
||||
results.errors[0].name.should.equal('duplicateGroupKey');
|
||||
results.errors[0].message.should.match(
|
||||
/Duplicate group key "contact" found in inputFieldGroups/,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Resources Validation', () => {
|
||||
it('should pass when resource methods have valid group references', () => {
|
||||
const definition = {
|
||||
...baseDefinition,
|
||||
resources: {
|
||||
contact: {
|
||||
key: 'contact',
|
||||
noun: 'Contact',
|
||||
list: {
|
||||
display: {
|
||||
label: 'List Contacts',
|
||||
description: 'List all contacts',
|
||||
},
|
||||
operation: {
|
||||
perform: '$func$2$f$',
|
||||
inputFieldGroups: [{ key: 'filter', label: 'Filter Options' }],
|
||||
inputFields: [
|
||||
{ key: 'status', group: 'filter' },
|
||||
{ key: 'type', group: 'filter' },
|
||||
],
|
||||
},
|
||||
},
|
||||
create: {
|
||||
display: {
|
||||
label: 'Create Contact',
|
||||
description: 'Create a new contact',
|
||||
},
|
||||
operation: {
|
||||
perform: '$func$2$f$',
|
||||
inputFieldGroups: [
|
||||
{ key: 'personal', label: 'Personal Info' },
|
||||
{ key: 'business', label: 'Business Info' },
|
||||
],
|
||||
inputFields: [
|
||||
{ key: 'firstName', group: 'personal' },
|
||||
{ key: 'lastName', group: 'personal' },
|
||||
{ key: 'company', group: 'business' },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const results = schema.validateAppDefinition(definition);
|
||||
results.errors.should.have.length(0);
|
||||
});
|
||||
|
||||
it('should error when resource method has invalid group reference', () => {
|
||||
const definition = {
|
||||
...baseDefinition,
|
||||
resources: {
|
||||
contact: {
|
||||
key: 'contact',
|
||||
noun: 'Contact',
|
||||
search: {
|
||||
display: {
|
||||
label: 'Search Contacts',
|
||||
description: 'Search for contacts',
|
||||
},
|
||||
operation: {
|
||||
perform: '$func$2$f$',
|
||||
inputFieldGroups: [
|
||||
{ key: 'criteria', label: 'Search Criteria' },
|
||||
],
|
||||
inputFields: [
|
||||
{ key: 'name', group: 'criteria' },
|
||||
{ key: 'email', group: 'invalid_group' }, // Invalid group reference
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const results = schema.validateAppDefinition(definition);
|
||||
results.errors.should.have.length(1);
|
||||
results.errors[0].name.should.equal('invalidGroupReference');
|
||||
results.errors[0].message.should.match(
|
||||
/Group "invalid_group" is not defined in inputFieldGroups/,
|
||||
);
|
||||
results.errors[0].property.should.equal(
|
||||
'instance.resources.contact.search.operation.inputFields[1].group',
|
||||
);
|
||||
});
|
||||
|
||||
it('should error when resource method has duplicate group keys', () => {
|
||||
const definition = {
|
||||
...baseDefinition,
|
||||
resources: {
|
||||
project: {
|
||||
key: 'project',
|
||||
noun: 'Project',
|
||||
get: {
|
||||
display: {
|
||||
label: 'Get Project',
|
||||
description: 'Get a project by ID',
|
||||
},
|
||||
operation: {
|
||||
perform: '$func$2$f$',
|
||||
inputFieldGroups: [
|
||||
{ key: 'options', label: 'Options' },
|
||||
{ key: 'settings', label: 'Settings' },
|
||||
{ key: 'options', label: 'Duplicate Options' }, // Duplicate key
|
||||
],
|
||||
inputFields: [{ key: 'includeArchived', group: 'options' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const results = schema.validateAppDefinition(definition);
|
||||
results.errors.should.have.length(1);
|
||||
results.errors[0].name.should.equal('duplicateGroupKey');
|
||||
results.errors[0].message.should.match(
|
||||
/Duplicate group key "options" found in inputFieldGroups/,
|
||||
);
|
||||
results.errors[0].property.should.equal(
|
||||
'instance.resources.project.get.operation.inputFieldGroups[2].key',
|
||||
);
|
||||
});
|
||||
|
||||
it('should error when resource method has groups in children fields', () => {
|
||||
const definition = {
|
||||
...baseDefinition,
|
||||
resources: {
|
||||
order: {
|
||||
key: 'order',
|
||||
noun: 'Order',
|
||||
create: {
|
||||
display: {
|
||||
label: 'Create Order',
|
||||
description: 'Create a new order',
|
||||
},
|
||||
operation: {
|
||||
perform: '$func$2$f$',
|
||||
inputFieldGroups: [{ key: 'items', label: 'Order Items' }],
|
||||
inputFields: [
|
||||
{
|
||||
key: 'lineItems',
|
||||
children: [
|
||||
{
|
||||
key: 'product',
|
||||
group: 'items', // Groups not allowed in children
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const results = schema.validateAppDefinition(definition);
|
||||
results.errors.should.have.length(1);
|
||||
results.errors[0].name.should.equal('groupInChildren');
|
||||
results.errors[0].message.should.match(
|
||||
/Group fields are not allowed in children fields/,
|
||||
);
|
||||
results.errors[0].property.should.equal(
|
||||
'instance.resources.order.create.operation.inputFields[0].children[0].group',
|
||||
);
|
||||
});
|
||||
|
||||
it('should validate multiple resource methods independently', () => {
|
||||
const definition = {
|
||||
...baseDefinition,
|
||||
resources: {
|
||||
user: {
|
||||
key: 'user',
|
||||
noun: 'User',
|
||||
list: {
|
||||
display: {
|
||||
label: 'List Users',
|
||||
description: 'List all users',
|
||||
},
|
||||
operation: {
|
||||
perform: '$func$2$f$',
|
||||
inputFieldGroups: [{ key: 'filter', label: 'Filter Options' }],
|
||||
inputFields: [{ key: 'active', group: 'filter' }],
|
||||
},
|
||||
},
|
||||
search: {
|
||||
display: {
|
||||
label: 'Search Users',
|
||||
description: 'Search for users',
|
||||
},
|
||||
operation: {
|
||||
perform: '$func$2$f$',
|
||||
inputFieldGroups: [
|
||||
{ key: 'criteria', label: 'Search Criteria' },
|
||||
],
|
||||
inputFields: [
|
||||
{ key: 'email', group: 'nonexistent' }, // Invalid reference
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const results = schema.validateAppDefinition(definition);
|
||||
results.errors.should.have.length(1);
|
||||
results.errors[0].name.should.equal('invalidGroupReference');
|
||||
results.errors[0].property.should.equal(
|
||||
'instance.resources.user.search.operation.inputFields[0].group',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Mixed Validation', () => {
|
||||
it('should validate both action types and resources together', () => {
|
||||
const definition = {
|
||||
...baseDefinition,
|
||||
triggers: {
|
||||
user_trigger: {
|
||||
key: 'user_trigger',
|
||||
noun: 'User',
|
||||
display: {
|
||||
label: 'User Trigger',
|
||||
description: 'Trigger on user events',
|
||||
},
|
||||
operation: {
|
||||
perform: '$func$2$f$',
|
||||
inputFieldGroups: [{ key: 'filter', label: 'Filter' }],
|
||||
inputFields: [{ key: 'status', group: 'filter' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
resources: {
|
||||
contact: {
|
||||
key: 'contact',
|
||||
noun: 'Contact',
|
||||
create: {
|
||||
display: {
|
||||
label: 'Create Contact',
|
||||
description: 'Create a new contact',
|
||||
},
|
||||
operation: {
|
||||
perform: '$func$2$f$',
|
||||
inputFieldGroups: [{ key: 'personal', label: 'Personal Info' }],
|
||||
inputFields: [{ key: 'name', group: 'personal' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const results = schema.validateAppDefinition(definition);
|
||||
results.errors.should.have.length(0);
|
||||
});
|
||||
|
||||
it('should handle empty inputFieldGroups correctly', () => {
|
||||
const definition = {
|
||||
...baseDefinition,
|
||||
triggers: {
|
||||
test_trigger: {
|
||||
key: 'test_trigger',
|
||||
noun: 'Test',
|
||||
display: {
|
||||
label: 'Test Trigger',
|
||||
description: 'A test trigger',
|
||||
},
|
||||
operation: {
|
||||
perform: '$func$2$f$',
|
||||
inputFields: [{ key: 'name' }, { key: 'email' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
resources: {
|
||||
item: {
|
||||
key: 'item',
|
||||
noun: 'Item',
|
||||
list: {
|
||||
display: {
|
||||
label: 'List Items',
|
||||
description: 'List all items',
|
||||
},
|
||||
operation: {
|
||||
perform: '$func$2$f$',
|
||||
inputFields: [{ key: 'category' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const results = schema.validateAppDefinition(definition);
|
||||
results.errors.should.have.length(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue