2023-01-04 17:22:49 +03:00
const ObjectId = require ( 'bson-objectid' ) . default ;
2023-01-04 18:06:40 +03:00
const sinon = require ( 'sinon' ) ;
2022-11-21 12:29:53 +03:00
2023-01-04 17:22:49 +03:00
const createModel = ( propertiesAndRelations ) => {
2023-01-10 16:58:50 +03:00
const id = propertiesAndRelations . id ? ? ObjectId ( ) . toHexString ( ) ;
2023-01-04 17:22:49 +03:00
return {
2023-01-10 16:58:50 +03:00
id ,
2023-01-04 17:22:49 +03:00
getLazyRelation : ( relation ) => {
2023-01-11 14:13:13 +03:00
propertiesAndRelations . loaded = propertiesAndRelations . loaded ? ? [ ] ;
if ( ! propertiesAndRelations . loaded . includes ( relation ) ) {
propertiesAndRelations . loaded . push ( relation ) ;
}
if ( Array . isArray ( propertiesAndRelations [ relation ] ) ) {
return Promise . resolve ( {
2023-03-22 13:52:41 +03:00
models : propertiesAndRelations [ relation ] ,
toJSON : ( ) => {
return propertiesAndRelations [ relation ] . map ( m => m . toJSON ( ) ) ;
}
2023-01-11 14:13:13 +03:00
} ) ;
}
2023-01-04 17:22:49 +03:00
return Promise . resolve ( propertiesAndRelations [ relation ] ) ;
} ,
2023-01-11 14:13:13 +03:00
related : ( relation ) => {
if ( ! Object . keys ( propertiesAndRelations ) . includes ( 'loaded' ) ) {
throw new Error ( ` Model.related(' ${ relation } '): When creating a test model via createModel you must include 'loaded' to specify which relations are already loaded and useable via Model.related. ` ) ;
}
if ( ! propertiesAndRelations . loaded . includes ( relation ) ) {
2023-03-28 13:26:57 +03:00
//throw new Error(`Model.related('${relation}') was used on a test model that didn't explicitly loaded that relation.`);
2023-01-11 14:13:13 +03:00
}
2023-03-22 13:52:41 +03:00
if ( Array . isArray ( propertiesAndRelations [ relation ] ) ) {
const arr = [ ... propertiesAndRelations [ relation ] ] ;
arr . toJSON = ( ) => {
return arr . map ( m => m . toJSON ( ) ) ;
} ;
return arr ;
}
2023-03-28 13:26:57 +03:00
// Simulate weird bookshelf behaviour of returning a new model
if ( ! propertiesAndRelations [ relation ] ) {
const m = createModel ( {
loaded : [ ]
} ) ;
m . id = null ;
return m ;
}
2023-01-11 14:13:13 +03:00
return propertiesAndRelations [ relation ] ;
} ,
2023-01-04 17:22:49 +03:00
get : ( property ) => {
return propertiesAndRelations [ property ] ;
} ,
save : ( properties ) => {
Object . assign ( propertiesAndRelations , properties ) ;
return Promise . resolve ( ) ;
2023-01-10 16:58:50 +03:00
} ,
toJSON : ( ) => {
return {
id ,
... propertiesAndRelations
} ;
2023-01-04 17:22:49 +03:00
}
} ;
} ;
2022-11-21 12:29:53 +03:00
2023-01-04 17:22:49 +03:00
const createModelClass = ( options = { } ) => {
return {
... options ,
2023-03-28 13:26:57 +03:00
options ,
2023-01-04 17:22:49 +03:00
add : async ( properties ) => {
return Promise . resolve ( createModel ( properties ) ) ;
} ,
findOne : async ( data , o ) => {
if ( options . findOne === null && o . require ) {
return Promise . reject ( new Error ( 'NotFound' ) ) ;
}
if ( options . findOne === null ) {
return Promise . resolve ( null ) ;
}
return Promise . resolve (
createModel ( { ... options . findOne , ... data } )
) ;
2023-01-10 16:58:50 +03:00
} ,
findAll : async ( data ) => {
2023-03-27 11:17:03 +03:00
const models = ( options . findAll ? ? [ ] ) . map ( f => createModel ( { ... f , ... data } ) ) ;
return Promise . resolve ( {
models ,
map : models . map . bind ( models ) ,
2023-06-09 09:50:53 +03:00
filter : models . filter . bind ( models ) ,
2023-03-27 11:17:03 +03:00
length : models . length
} ) ;
2023-01-10 16:58:50 +03:00
} ,
2023-03-20 16:30:42 +03:00
findPage : async ( data ) => {
const all = options . findAll ? ? [ ] ;
const limit = data . limit ? ? 15 ;
const page = data . page ? ? 1 ;
2023-03-27 11:17:03 +03:00
const start = ( page - 1 ) * ( limit === 'all' ? all . length : limit ) ;
const end = limit === 'all' ? all . length : ( start + limit ) ;
2023-03-20 16:30:42 +03:00
const pageData = all . slice ( start , end ) ;
return Promise . resolve (
{
data : pageData . map ( f => createModel ( { ... f , ... data } ) ) ,
meta : {
page ,
limit
}
}
) ;
} ,
2023-01-10 16:58:50 +03:00
transaction : async ( callback ) => {
const transacting = { transacting : 'transacting' } ;
return await callback ( transacting ) ;
} ,
where : function ( ) {
return this ;
} ,
save : async function ( ) {
return Promise . resolve ( ) ;
2023-01-04 17:22:49 +03:00
}
} ;
} ;
2023-01-10 18:36:41 +03:00
const createDb = ( { first , all } = { } ) => {
2023-01-10 16:58:50 +03:00
let a = all ;
2023-01-04 18:06:40 +03:00
const db = {
knex : function ( ) {
return this ;
} ,
where : function ( ) {
return this ;
} ,
whereNull : function ( ) {
return this ;
} ,
select : function ( ) {
return this ;
} ,
2023-01-10 16:58:50 +03:00
limit : function ( n ) {
a = all . slice ( 0 , n ) ;
return this ;
} ,
2023-01-04 18:06:40 +03:00
update : sinon . stub ( ) . resolves ( ) ,
2023-01-10 16:58:50 +03:00
orderByRaw : function ( ) {
return this ;
} ,
insert : function ( ) {
return this ;
} ,
2023-01-04 18:06:40 +03:00
first : ( ) => {
return Promise . resolve ( first ) ;
2023-01-10 16:58:50 +03:00
} ,
then : function ( resolve ) {
resolve ( a ) ;
} ,
transacting : function ( ) {
return this ;
2023-01-04 18:06:40 +03:00
}
} ;
db . knex . raw = function ( ) {
return this ;
} ;
return db ;
} ;
2023-01-10 16:58:50 +03:00
const sleep = ( ms ) => {
return new Promise ( ( resolve ) => {
setTimeout ( resolve , ms ) ;
} ) ;
} ;
2023-01-04 17:22:49 +03:00
module . exports = {
createModel ,
2023-01-04 18:06:40 +03:00
createModelClass ,
2023-01-10 16:58:50 +03:00
createDb ,
sleep
2023-01-04 17:22:49 +03:00
} ;