@unito/integration-sdk
Version:
Integration SDK
185 lines (160 loc) • 6.34 kB
text/typescript
import { FieldValueTypes, OperatorTypes, Semantics } from '@unito/integration-api';
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import { buildCollectionQueryParams, getApplicableFilters } from '../src/helpers.js';
describe('Helpers', () => {
describe('getApplicableFilters', () => {
it('returns only filters for defined fields', () => {
const actual = getApplicableFilters(
{
filters: [
{ field: 'status', operator: OperatorTypes.EQUAL, values: ['active', 'pending'] },
{ field: 'email', operator: OperatorTypes.IS_NOT_NULL, values: [] },
],
},
[
{
name: 'status',
label: 'Status',
type: FieldValueTypes.STRING,
},
],
);
const expected = [{ field: 'status', operator: OperatorTypes.EQUAL, values: ['active', 'pending'] }];
assert.deepEqual(actual, expected);
});
it('translates semantics into field names', () => {
const actual = getApplicableFilters(
{
filters: [
{ field: 'semantic:displayName', operator: OperatorTypes.START_WITH, values: ['Bob'] },
{ field: 'semantic:createdAt', operator: OperatorTypes.EQUAL, values: ['2021-01-01'] },
],
},
[
{
name: 'name',
label: 'Name',
type: FieldValueTypes.STRING,
semantic: Semantics.DISPLAY_NAME,
},
],
);
const expected = [{ field: 'name', operator: OperatorTypes.START_WITH, values: ['Bob'] }];
assert.deepEqual(actual, expected);
});
it('gracefully handle garbage', () => {
const actual = getApplicableFilters(
{
filters: [
{ field: '...', operator: OperatorTypes.EQUAL, values: [] },
{ field: ':', operator: OperatorTypes.EQUAL, values: [] },
{ field: '', operator: OperatorTypes.EQUAL, values: [] },
],
},
[
{
name: 'status',
label: 'Status',
type: FieldValueTypes.STRING,
},
],
);
assert.deepEqual(actual, []);
});
});
describe('buildCollectionQueryParams', () => {
it('encodes a single filter with one value', () => {
const result = buildCollectionQueryParams({
filters: [{ field: 'status', operator: OperatorTypes.EQUAL, values: ['active'] }],
});
assert.equal(result.get('filter'), 'status=active');
assert.equal(result.get('select'), null);
});
it('encodes filter values with special characters', () => {
const result = buildCollectionQueryParams({
filters: [{ field: 'status', operator: OperatorTypes.EQUAL, values: ['foo,bar'] }],
});
assert.equal(result.get('filter'), 'status=foo%2Cbar');
});
it('encodes filter values containing pipe characters', () => {
const result = buildCollectionQueryParams({
filters: [{ field: 'tags', operator: OperatorTypes.EQUAL, values: ['a|b'] }],
});
assert.equal(result.get('filter'), 'tags=a%7Cb');
});
it('joins multiple values for one filter with |', () => {
const result = buildCollectionQueryParams({
filters: [{ field: 'status', operator: OperatorTypes.EQUAL, values: ['active', 'pending'] }],
});
assert.equal(result.get('filter'), 'status=active|pending');
});
it('joins multiple filters with ,', () => {
const result = buildCollectionQueryParams({
filters: [
{ field: 'status', operator: OperatorTypes.EQUAL, values: ['active'] },
{ field: 'name', operator: OperatorTypes.INCLUDE, values: ['john'] },
],
});
assert.equal(result.get('filter'), 'status=active,name*=john');
});
it('handles IS_NULL operator (no values)', () => {
const result = buildCollectionQueryParams({
filters: [{ field: 'status', operator: OperatorTypes.IS_NULL, values: [] }],
});
assert.equal(result.get('filter'), 'status!!');
});
it('handles IS_NULL operator with undefined values', () => {
const result = buildCollectionQueryParams({
filters: [{ field: 'status', operator: OperatorTypes.IS_NULL, values: undefined }],
});
assert.equal(result.get('filter'), 'status!!');
});
it('handles IS_NOT_NULL operator (no values)', () => {
const result = buildCollectionQueryParams({
filters: [{ field: 'assignee', operator: OperatorTypes.IS_NOT_NULL, values: [] }],
});
assert.equal(result.get('filter'), 'assignee!');
});
it('encodes selects', () => {
const result = buildCollectionQueryParams({
selects: ['name', 'dept.id'],
});
assert.equal(result.get('select'), 'name,dept.id');
assert.equal(result.get('filter'), null);
});
it('encodes selects with special characters', () => {
const result = buildCollectionQueryParams({
selects: ['field with spaces'],
});
assert.equal(result.get('select'), 'field%20with%20spaces');
});
it('encodes both filters and selects', () => {
const result = buildCollectionQueryParams({
filters: [{ field: 'status', operator: OperatorTypes.EQUAL, values: ['active'] }],
selects: ['name', 'status'],
});
assert.equal(result.get('filter'), 'status=active');
assert.equal(result.get('select'), 'name,status');
});
it('returns empty URLSearchParams when called with no arguments', () => {
const result = buildCollectionQueryParams();
assert.equal(result.toString(), '');
});
it('omits filter key for empty filters array', () => {
const result = buildCollectionQueryParams({ filters: [] });
assert.equal(result.get('filter'), null);
});
it('omits select key for empty selects array', () => {
const result = buildCollectionQueryParams({ selects: [] });
assert.equal(result.get('select'), null);
});
it('can be extended with additional params (e.g. cursor)', () => {
const result = buildCollectionQueryParams({
selects: ['name'],
});
result.append('cursor', 'abc123');
assert.equal(result.toString(), 'select=name&cursor=abc123');
});
});
});