UNPKG

js-node-arango

Version:
252 lines (229 loc) 9.12 kB
import { ArangoBaseQueryBuilder } from '../querybuilder/base-query-builder'; import { ArangoDocumentQueryBuilder } from '../querybuilder/document-query-builder'; import { ArangoEdgeQueryBuilder } from '../querybuilder/edge-query-builder'; import { Direction } from '../types/arango-query-options.interface'; describe('arangodb/querybuilder', () => { it('should prepare query when complex related query 1', () => { // arrange const builder = new ArangoDocumentQueryBuilder({ documentCollection: 'manifest', filterBy: { filter: { gitRepoInfo: { owner: 'Tospaa' } } }, }) .addAdditionalQuery( 'one_data_source', new ArangoDocumentQueryBuilder({ documentCollection: 'data_sources', limitBy: { limit: 1, offset: 0 } }), ) .addAdditionalQuery( 'related', new ArangoEdgeQueryBuilder({ edgeCollections: 'tospaa', relatedCollections: 'afyon', startingVertexId: 'deneme/1-2', limitBy: { limit: 2, offset: 3, }, sortBy: { field: 'foo.bar', order: 'ASC', }, withCount: true, }), ); // act const query = builder.prepareQuery(); // assert expect(query).toStrictEqual({ bindVars: { '@collection_1': 'manifest', '@collection_5': 'data_sources', '@edge_8': 'tospaa', '@target_4': 'afyon', depth_10: 1, filter_3: 'Tospaa', limitByLimit_14: 2, limitByLimit_7: 1, limitByOffset_13: 3, limitByOffset_6: 0, path_2: ['gitRepoInfo', 'owner'], sortField_11: ['foo', 'bar'], sortOrder_12: 'ASC', starting_vertex_9: 'deneme/1-2', }, query: 'WITH @@target_4 FOR doc IN @@collection_1 FILTER doc.@path_2 == @filter_3 LET one_data_source = FIRST(FOR doc IN @@collection_5 LIMIT @limitByOffset_6, @limitByLimit_7 RETURN doc) LET related = FIRST(LET total = FIRST(FOR vertex IN 1..@depth_10 ANY @starting_vertex_9 @@edge_8 COLLECT WITH COUNT INTO length RETURN length) LET docs = (FOR vertex IN 1..@depth_10 ANY @starting_vertex_9 @@edge_8 SORT vertex.@sortField_11 @sortOrder_12 LIMIT @limitByOffset_13, @limitByLimit_14 RETURN vertex) RETURN { docs, total }) RETURN MERGE(doc, { one_data_source, related })', }); }); it('should prepare query when complex related query 2', () => { // arrange const builder = new ArangoDocumentQueryBuilder({ documentCollection: 'manifest', filterBy: { filter: { gitRepoInfo: { owner: 'Tospaa' } } }, }).addAdditionalQuery( 'last_execution', new ArangoEdgeQueryBuilder({ edgeCollections: 'related_execution_infos', relatedCollections: 'execution_info', limitBy: { limit: 1, offset: 0, }, sortBy: { field: 'createdTs', order: 'DESC', }, }), ); // act const query = builder.prepareQuery(); // assert expect(query).toStrictEqual({ bindVars: { '@collection_1': 'manifest', '@edge_5': 'related_execution_infos', '@target_4': 'execution_info', depth_6: 1, filter_3: 'Tospaa', limitByLimit_10: 1, limitByOffset_9: 0, path_2: ['gitRepoInfo', 'owner'], sortField_7: ['createdTs'], sortOrder_8: 'DESC', }, query: 'WITH @@target_4 FOR doc IN @@collection_1 FILTER doc.@path_2 == @filter_3 LET last_execution = FIRST(FOR vertex IN 1..@depth_6 ANY doc._id @@edge_5 SORT vertex.@sortField_7 @sortOrder_8 LIMIT @limitByOffset_9, @limitByLimit_10 RETURN vertex) RETURN MERGE(doc, { last_execution })', }); }); it('should throw when startingVertexId is not ArangoID', () => { // arrange const builder = new ArangoEdgeQueryBuilder({ depth: 2, direction: Direction.Outbound, relatedCollections: 'related', edgeCollections: 'edge', startingVertexId: 'invalid', }); // act & assert expect(() => builder.prepareQuery()).toThrowError( 'startingVertexId must be an ArangoDB document ID. For example: manifest/2df48bfb-48ab-4a95-84cc-0802c7f842b9', ); }); it('should throw when no parent and no root doc nor startingVertexId is set', () => { // arrange const builder = new ArangoEdgeQueryBuilder({ relatedCollections: 'related', edgeCollections: 'edge', }); // act & assert expect(() => builder.prepareQuery()).toThrowError('You must provide startingVertexId in options'); }); it('should throw when using base class', () => { // arrange const builder = new ArangoBaseQueryBuilder({ documentCollection: 'some' }); // act & assert expect(() => builder.prepareQuery()).toThrowError('Override this method'); }); it('should throw when using same variable name with the root doc selector', () => { // arrange const builder = new ArangoDocumentQueryBuilder({ documentCollection: 'some' }); // act & assert expect(() => builder.addAdditionalQuery('doc', new ArangoDocumentQueryBuilder({ documentCollection: 'other' })), ).toThrowError('Additional query variable name cannot be same with doc selector'); }); it('should prepare query when only edge query', () => { // arrange const builder = new ArangoEdgeQueryBuilder({ edgeCollections: 'related_execution_infos', relatedCollections: ['execution_info', 'data_sources'], filterBy: { filter: { gitRepoInfo: { owner: 'Tospaa' } } }, startingVertexId: 'deneme/1-2', direction: Direction.Outbound, depth: 4, }); // act const query = builder.prepareQuery(); // assert expect(query).toStrictEqual({ bindVars: { '@edge_1': 'related_execution_infos', '@target_6': 'execution_info', '@target_7': 'data_sources', depth_3: 4, filter_5: 'Tospaa', path_4: ['gitRepoInfo', 'owner'], starting_vertex_2: 'deneme/1-2', }, query: 'WITH @@target_6, @@target_7 FOR vertex IN 1..@depth_3 OUTBOUND @starting_vertex_2 @@edge_1 FILTER vertex.@path_4 == @filter_5 RETURN vertex', }); }); it('should throw when trying to set unsafe doc selector', () => { // arrange const builder = new ArangoDocumentQueryBuilder({ documentCollection: 'some' }); // act & assert expect(() => builder.setDocSelector('doc//')).toThrowError( 'This phrase does not seem safe and cannot be used in the query: doc//', ); }); it('should prepare query when complex related query 2', () => { // arrange const builder = new ArangoDocumentQueryBuilder({ documentCollection: 'manifest', filterBy: { filter: { gitRepoInfo: { owner: 'Tospaa' } } }, }).addAdditionalQuery( 'executions', new ArangoDocumentQueryBuilder({ documentCollection: 'execution_info', limitBy: { limit: 1, offset: 0, }, sortBy: { field: 'createdTs', order: 'DESC', }, }) .setDocSelector('doc2') .addAdditionalQuery( 'inner', new ArangoEdgeQueryBuilder({ edgeCollections: 'inner_edge', relatedCollections: 'inner_related', }).addAdditionalQuery( 'innermost', new ArangoEdgeQueryBuilder({ edgeCollections: 'innermost_edge', relatedCollections: 'innermost_related', sortBy: { field: 'dateCreated', order: 'ASC' }, }).setDocSelector('doc3'), ), ), ); // act const query = builder.prepareQuery(); // assert expect(query).toStrictEqual({ bindVars: { '@collection_1': 'manifest', '@collection_6': 'execution_info', '@edge_11': 'inner_edge', '@edge_13': 'innermost_edge', '@target_4': 'inner_related', '@target_5': 'innermost_related', depth_12: 1, depth_14: 1, filter_3: 'Tospaa', limitByLimit_10: 1, limitByOffset_9: 0, path_2: ['gitRepoInfo', 'owner'], sortField_15: ['dateCreated'], sortField_7: ['createdTs'], sortOrder_16: 'ASC', sortOrder_8: 'DESC', }, query: 'WITH @@target_4, @@target_5 FOR doc IN @@collection_1 FILTER doc.@path_2 == @filter_3 LET executions = FIRST(FOR doc2 IN @@collection_6 SORT doc2.@sortField_7 @sortOrder_8 LIMIT @limitByOffset_9, @limitByLimit_10 LET inner = (FOR vertex IN 1..@depth_12 ANY doc._id @@edge_11 LET innermost = (FOR doc3 IN 1..@depth_14 ANY doc._id @@edge_13 SORT doc3.@sortField_15 @sortOrder_16 RETURN doc3) RETURN MERGE(vertex, { innermost })) RETURN MERGE(doc2, { inner })) RETURN MERGE(doc, { executions })', }); }); });