Skip to content

Commit

Permalink
working for driver except for integers
Browse files Browse the repository at this point in the history
  • Loading branch information
YizYah committed Jul 6, 2021
1 parent 527e3ef commit 74f059c
Show file tree
Hide file tree
Showing 9 changed files with 3,973 additions and 124 deletions.
3,663 changes: 3,583 additions & 80 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,15 @@
"@types/node": "^14.14.19",
"deep-equal": "^2.0.5",
"neo4j-driver": "^4.3.1",
"neo4j-driver-core": "^4.3.1",
"path": "^0.12.7",
"tslib": "^2.0.3"
},
"devDependencies": {
"@neo4j/graphql": "^1.1.0",
"@typescript-eslint/eslint-plugin": "^4.21.0",
"@typescript-eslint/parser": "^4.21.0",
"apollo-server": "^2.25.2",
"ava": "^3.15.0",
"commitizen": "^4.2.3",
"cz-conventional-changelog": "^3.2.0",
Expand Down
8 changes: 8 additions & 0 deletions src/custom/records/dataFromRecord.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function dataFromRecord(record: Record<any, any>): object {
const output: any = {}
record.keys.map((key: string)=>{
const fieldLookup = record._fieldLookup[key]
output[key]=record._fields[fieldLookup].properties
})
return output
}
6 changes: 6 additions & 0 deletions src/custom/records/dataFromRecordList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import {dataFromRecord} from "./dataFromRecord";
// const Record = require('neo4j-driver').types.Record ;

export function dataFromRecordList(records: Record<any, any>[]): object[] {
return records.map(record => dataFromRecord(record))
}
108 changes: 65 additions & 43 deletions src/custom/session/mockSessionFromQuerySet.ts
Original file line number Diff line number Diff line change
@@ -1,58 +1,80 @@
import {QuerySpec} from "../types/QuerySpec";
import { QuerySpec } from '../types/QuerySpec';
import Session from 'neo4j-driver-core/types/session';
import {mockResultsFromCapturedOutput} from '../results/mockResultsFromCapturedOutput';
import { mockResultsFromCapturedOutput } from '../results/mockResultsFromCapturedOutput';

const neo4j = require('neo4j-driver');
const mockDatabaseInfo = {
URI: 'neo4j+s://84751e18.databases.neo4j.io',
USER: 'faker',
PASSWORD: 'thisIsAfakeDatabase',
URI: 'neo4j+s://84751e18.databases.neo4j.io',
USER: 'faker',
PASSWORD: 'thisIsAfakeDatabase',
};

function mockSessionFromQuerySet(querySet: QuerySpec[]): Session {
const driver = neo4j.driver(
mockDatabaseInfo.URI,
neo4j.auth.basic(
mockDatabaseInfo.USER,
mockDatabaseInfo.PASSWORD
)
)


const fakeSession = driver.session()
const mockRun = async (query: string, params: any) => {
let output: any = ''
querySet.map((querySpec: QuerySpec) => {
if (querySpec.query === query &&
JSON.stringify(querySpec.params) === JSON.stringify(params)) {
output = mockResultsFromCapturedOutput(querySpec.output)
}
})
if (output !== '') return output
throw new Error(`the query set provided does not contain the given query and params:
query provided = ${query}.`)
}
const driver = neo4j.driver(
mockDatabaseInfo.URI,
neo4j.auth.basic(
mockDatabaseInfo.USER,
mockDatabaseInfo.PASSWORD,
),
);


const mockBeginTransaction = () => {
let _isOpen = true;
return {
run: mockRun,
commit: () => {
_isOpen = false;
return Promise.resolve()
},
rollback: () => {
_isOpen = false;
return Promise.resolve();
},
isOpen: () => _isOpen
const fakeSession = driver.session();
const mockRun = async (query: string, params: any) => {
let queryMatched = false;
let output: any = '';
querySet.map((querySpec: QuerySpec) => {
if (querySpec.query.trim() === query.trim()) {
queryMatched = true;
if (JSON.stringify(querySpec.params) === JSON.stringify(params)) {
output = mockResultsFromCapturedOutput(querySpec.output);
}
}
});

if (output !== '') return output;
if (queryMatched) {
let paramsString = JSON.stringify(params)
const MAX_LENGTH = 150
if (paramsString.length > MAX_LENGTH) paramsString = paramsString.substring(0, MAX_LENGTH) + '...'
throw new Error(`your query was matched in your QuerySpec. But your params were not matched.
query:
-----------------
${query.trim()}
-----------------
params: ${paramsString}
`)
}

fakeSession.run = mockRun
fakeSession._beginTransaction = mockBeginTransaction
throw new Error(`the query set provided does not contain the given query:
-----------------
${query.trim()}
-----------------
`);
};

const mockBeginTransaction = () => {
let _isOpen = true;
return {
run: mockRun,
commit: () => {
_isOpen = false;
return Promise.resolve();
},
rollback: () => {
_isOpen = false;
return Promise.resolve();
},
isOpen: () => _isOpen,
};
};

fakeSession.run = mockRun;
fakeSession._beginTransaction = mockBeginTransaction;

return fakeSession
return fakeSession;
}

module.exports = mockSessionFromQuerySet;
107 changes: 107 additions & 0 deletions test/custom/data/helpers/serverQuerySet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { QuerySpec } from '../../../../src/custom/types/QuerySpec';

// general server param constants
export const cypherParams = { 'currentUserId': 'f5224bcb-12d7-48d3-8943-4fa862afa1ec' };

export const auth = {
'isAuthenticated': false,
'roles': [],
};


// `

// specific movie query info
export const movieQuery = `
WITH apoc.cypher.runFirstColumn("match (movie:Movie {title:$title}) return movie", {auth: $auth, cypherParams: $cypherParams, title: $title}, true) as x
UNWIND x as this
RETURN this { .title, .released } AS this
`

export const movieParams = {
title: "Forrest Gump",
auth,
cypherParams,
}
export const movieOutput = {
records: [
{
"keys": [
"movie"
],
"length": 1,
"_fields": [
{
"identity": {
"low": 32,
"high": 0
},
"labels": [
"Movie"
],
"properties": {
"title": "Forrest Gump",
"released": {
"low": 1994,
"high": 0
}
}
}
],
"_fieldLookup": {
"movie": 0
}
},
]
}

export const movieOutputWithoutReleased = {
records: [
{
"keys": [
"movie"
],
"length": 1,
"_fields": [
{
"identity": {
"low": 32,
"high": 0
},
"labels": [
"Movie"
],
"properties": {
"title": "Forrest Gump",
}
}
],
"_fieldLookup": {
"movie": 0
}
},
]
}

const movieQueryWithoutReleased = `
WITH apoc.cypher.runFirstColumn("match (movie:Movie {title:$title}) return movie", {auth: $auth, cypherParams: $cypherParams, title: $title}, true) as x
UNWIND x as this
RETURN this { .title } AS this
`


export const querySet: QuerySpec[] = [
{
query: movieQueryWithoutReleased,
params: movieParams,
output: movieOutputWithoutReleased,
},
{
query: movieQuery,
params: movieParams,
output: movieOutput,
}
]
3 changes: 2 additions & 1 deletion test/custom/mockSessionFromQuerySet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,6 @@ test('mockSessionFromQuerySet returns error with false input', async (t) => {
const error = await t.throwsAsync(async () => {
const output = await session.run(query, ['bar','baz'])
});
t.regex(error.message, /does not contain the given query and params/);
// t.regex(error.message, /does not contain the given query and params/);
t.regex(error.message, /your params were not matched./);
})
107 changes: 107 additions & 0 deletions test/custom/server.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { mockResultsFromCapturedOutput } from '../../src/custom/results/mockResultsFromCapturedOutput';

require('dotenv').config();
const test = require('ava');

import {
cypherParams,
movieOutput,
movieOutputWithoutReleased,
movieParams,
movieQuery,
querySet,
} from './data/helpers/serverQuerySet';
import { Neo4jGraphQL } from '@neo4j/graphql';
import { ApolloServer } from 'apollo-server';
// import { dataFromRecordList } from '../../src/custom/records/dataFromRecordList';

const neo4j = require('neo4j-driver');

const mockSessionFromQuerySet = require('../../src/custom/session/mockSessionFromQuerySet');

function mockDriver() {
const driver = neo4j.driver(
process.env.URI,
neo4j.auth.basic(
process.env.USER_NAME,
process.env.PASSWORD,
),
{ disableLosslessIntegers: true }
);

driver.session = () => mockSessionFromQuerySet(querySet);
driver.verifyConnectivity = () => Promise.resolve({});
driver.supportsMultiDb = () => Promise.resolve(true);
driver.supportsTransactionConfig = () => Promise.resolve(true);
return driver;
}

const user = {
'id': 'f5224bcb-12d7-48d3-8943-4fa862afa1ec',
'roles': ['moderator'],
};

const typeDefs = `
type Movie {
title: String!
released: Int
}
type Query {
getMovies (title: String!): [Movie] @cypher(statement: "match (movie:Movie {title:$title}) return movie")
}
`;

const schema = new Neo4jGraphQL({
typeDefs,
}).schema;

const driver = mockDriver();

function context({ event, context }: { event: any, context: any }): any {
return ({
event,
context,
driver,
user,
cypherParams,
});
}

const server = new ApolloServer(
{
schema,
context,
cors: {
origin: '*',
methods: 'GET,HEAD,POST',
},
introspection: true,
});

const MOVIES = `
query GetMovies($title: String!){
getMovies(title: $title){
title
#released
}
}
`;

test('SSS [spoof simple server]', async (t: any) => {
const result = await server.executeOperation({
query: MOVIES,
variables: movieParams,
});
console.log(`result=${JSON.stringify(result)}`);
// console.log(`movieOutput.records=${JSON.stringify(movieOutput.records)}`);
// console.log(`mockResultsFromCapturedOutput(movieOutput).records=${JSON.stringify(mockResultsFromCapturedOutput(movieOutput).records)}`);
t.true(!result.errors);

t.deepEqual(
// @ts-ignore
result.data.getMovies,
mockResultsFromCapturedOutput(movieOutputWithoutReleased)
.records.map(record=> record.get('movie').properties)
);
});
Loading

0 comments on commit 74f059c

Please sign in to comment.