Skip to content
Open
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
21 changes: 21 additions & 0 deletions src/services/MetaService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,13 @@ export class MetaService {
const exists = this.fields.find((f: any) => f.name === field.name);
if (!exists) {
this.fields.push(field);
} else if (field.associatedEntity && field.associatedEntity.fields) {
for (const assocEntityField of field.associatedEntity.fields) {
const assocEntityFieldExists = exists.associatedEntity.fields.find((f: { name: string }) => f.name === assocEntityField.name);
if (!assocEntityFieldExists) {
exists.associatedEntity.fields.push(assocEntityField);
}
}
}
if (typeof field !== 'string') {
this.memory[field.name] = field;
Expand Down Expand Up @@ -256,6 +263,12 @@ export class MetaService {
const meta: any = this.memory[cleaned];
if (!meta) {
result.push(cleaned);
} else if (
meta.dataSpecialization === 'INLINE_EMBEDDED'
&& meta.associatedEntity
&& meta.associatedEntity.fields
&& this.getSubFields(field).some(subField => !meta.associatedEntity.fields.find(aef => aef.name === subField))) {
result.push(cleaned);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something i might have missed earlier is that we are pushing cleaned that seems wrong because all the default fields would have to be included, Maybe that is true for INLINE_EMBEDDED.

was think something more like

  private missing(fields): string[] {
    if (!this.memory) {
      return fields;
    }
    if (fields && fields[0] === '*' && this.allFieldsLoaded) {
      return [];
    }
    const result: string[] = [];
    for (const field of fields) {
      const cleaned: string = this._clean(field);
      const meta: any = this.memory[cleaned];
      if (!meta) {
        // We can't push `cleaned` field because that wouldn't request subField
        result.push(field);
      } else if (meta.associatedEntity) {
        const aefs = meta.associatedEntity.fields.map(aef => aef.name);
        // filter out any existing associatedEntity fields
        // but this probably needs to be recursive or the subfields need to be cleaned
        const missingSubFields = this.getSubFields(field).filter(sub => !aefs.includes(sub));
        // construct field with missing sub fields
        result.push(`${cleaned}(${missingSubFields.join()})`);
      }
    }
    return result;
  }

}
}
return result;
Expand All @@ -268,6 +281,14 @@ export class MetaService {
.split('(')[0];
}

getSubFields(field: string): string[] {
return field
// Remove spaces, [] and {} bracket contents from fields if present
.replace(/\s|(\{[^\}]*?\})|(\[[^\]]*?\])/gi, '')
.match(/(?:\(([^)]*)\))/gi)[0]
.match(/[^,\(\)]+/gi) || [];
}

/**
* Get specific meta data properties
*/
Expand Down
171 changes: 129 additions & 42 deletions test/MetaService.spec.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,134 @@
import { MetaService } from '../src';

describe('MetaService', () => {
describe('function: hasMemory', () => {
it('should be defined', () => {
const meta: MetaService = new MetaService('Candidate');
const actual = meta.hasMemory;
expect(actual).toBeDefined();
});
it('should return false when memory is undefined', () => {
const meta: MetaService = new MetaService('Candidate');
meta.memory = undefined;
const actual = meta.hasMemory();
expect(actual).toEqual(false);
});
it('should return false when memory is null', () => {
const meta: MetaService = new MetaService('Candidate');
meta.memory = null;
const actual = meta.hasMemory();
expect(actual).toEqual(false);
});
it('should return false when memory is false', () => {
const meta: MetaService = new MetaService('Candidate');
meta.memory = false;
const actual = meta.hasMemory();
expect(actual).toEqual(false);
});
it('should return false when memory is not an Object', () => {
const meta: MetaService = new MetaService('Candidate');
meta.memory = [];
const actual = meta.hasMemory();
expect(actual).toEqual(false);
});
it('should return false when memory is an empty Object', () => {
const meta: MetaService = new MetaService('Candidate');
meta.memory = {};
const actual = meta.hasMemory();
expect(actual).toEqual(false);
});
it('should return true when memory is a non-empty Object', () => {
const meta: MetaService = new MetaService('Candidate');
meta.memory = { test: 'test' };
const actual = meta.hasMemory();
expect(actual).toEqual(true);
});
describe('function: hasMemory', () => {
it('should be defined', () => {
const meta: MetaService = new MetaService('Candidate');
const actual = meta.hasMemory;
expect(actual).toBeDefined();
});
it('should return false when memory is undefined', () => {
const meta: MetaService = new MetaService('Candidate');
meta.memory = undefined;
const actual = meta.hasMemory();
expect(actual).toEqual(false);
});
it('should return false when memory is null', () => {
const meta: MetaService = new MetaService('Candidate');
meta.memory = null;
const actual = meta.hasMemory();
expect(actual).toEqual(false);
});
it('should return false when memory is false', () => {
const meta: MetaService = new MetaService('Candidate');
meta.memory = false;
const actual = meta.hasMemory();
expect(actual).toEqual(false);
});
it('should return false when memory is not an Object', () => {
const meta: MetaService = new MetaService('Candidate');
meta.memory = [];
const actual = meta.hasMemory();
expect(actual).toEqual(false);
});
it('should return false when memory is an empty Object', () => {
const meta: MetaService = new MetaService('Candidate');
meta.memory = {};
const actual = meta.hasMemory();
expect(actual).toEqual(false);
});
it('should return true when memory is a non-empty Object', () => {
const meta: MetaService = new MetaService('Candidate');
meta.memory = {test: 'test'};
const actual = meta.hasMemory();
expect(actual).toEqual(true);
});
});

describe('function: getSubFields', () => {
it('should be defined', () => {
const meta: MetaService = new MetaService('EarnCodeGroup');
const actual = meta.getSubFields;
expect(actual).toBeDefined();
});
it('should return array of fields case 1', () => {
const meta: MetaService = new MetaService('EarnCodeGroup');
const field = 'jobOrders(id,title,status)';
const res = meta.getSubFields(field);
expect(res[0]).toBe('id');
expect(res[1]).toBe('title');
expect(res[2]).toBe('status');
});
it('should return array of fields case 1', () => {
const meta: MetaService = new MetaService('EarnCodeGroup');
const field = 'jobOrders(id,title,status)';
const res = meta.getSubFields(field);
expect(res[0]).toBe('id');
expect(res[1]).toBe('title');
expect(res[2]).toBe('status');
});
it('should return array of fields case 2', () => {
const meta: MetaService = new MetaService('EarnCodeGroup');
const field = 'jobOrders[3](id,title,status)';
const res = meta.getSubFields(field);
expect(res[0]).toBe('id');
expect(res[1]).toBe('title');
expect(res[2]).toBe('status');
});
it('should return array of fields case 3', () => {
const meta: MetaService = new MetaService('EarnCodeGroup');
const field = 'jobOrders{status=\'closed\'}(id,title,status)';
const res = meta.getSubFields(field);
expect(res[0]).toBe('id');
expect(res[1]).toBe('title');
expect(res[2]).toBe('status');
});
it('should return array of fields case 4', () => {
const meta: MetaService = new MetaService('EarnCodeGroup');
const field = 'jobOrders(id, title, status)';
const res = meta.getSubFields(field);
expect(res[0]).toBe('id');
expect(res[1]).toBe('title');
expect(res[2]).toBe('status');
});
it('should return array of fields case 5', () => {
const meta: MetaService = new MetaService('EarnCodeGroup');
const fields = 'businessSectors[3](name,id){name=\'Insurance\'},category';
const res = meta.getSubFields(fields);
expect(res[0]).toBe('name');
expect(res[1]).toBe('id');
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think you are missing a test that get the fields inside a nested field
ie. meta.getSubFields('businessSectors[3](name,id){name=\'Insurance\'}')
and meta.getSubFields('placement(candidate(id,name))

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We made a change to this, to only target 'INLINE_EMBEDDED' entities. The only entity that is configured that way it defaultEanCode, and the other earn code entities. The fields for these, do not ever have double nested fields, so the current logic should be able to handle that.

});

describe('function: _clean', () => {
it('should be defined', () => {
const meta: MetaService = new MetaService('Candidate');
const actual = meta._clean;
expect(actual).toBeDefined();
});
it('should return a field name case 1', () => {
const meta: MetaService = new MetaService('Candidate');
const field = 'name';
const res = meta._clean(field);
expect(res).toBe('name');
});
it('should return a field name case 2', () => {
const meta: MetaService = new MetaService('Candidate');
const field = 'jobOrder(id,title)';
const res = meta._clean(field);
expect(res).toBe('jobOrder');
});
it('should return a field name case 3', () => {
const meta: MetaService = new MetaService('Candidate');
const field = 'jobOrder[3](id,title)';
const res = meta._clean(field);
expect(res).toBe('jobOrder');
});
it('should return a field name case 4', () => {
const meta: MetaService = new MetaService('Candidate');
const field = 'jobOrder.title';
const res = meta._clean(field);
expect(res).toBe('jobOrder');
});
});
});