PageRenderTime 61ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/test/unit/lucid.spec.js

https://bitbucket.org/skrabakl/lucid-cloudant
JavaScript | 1923 lines | 1567 code | 325 blank | 31 comment | 28 complexity | a29577bb95b56e16038bed8fb84652b6 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. 'use strict'
  2. /*
  3. * adonis-lucid
  4. *
  5. * (c) Harminder Virk <virk@adonisjs.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. require('../../lib/iocResolver').setFold(require('@adonisjs/fold'))
  11. const test = require('japa')
  12. const fs = require('fs-extra')
  13. const path = require('path')
  14. const moment = require('moment')
  15. // const _ = require('lodash')
  16. const { ioc } = require('@adonisjs/fold')
  17. const { Config, setupResolver } = require('@adonisjs/sink')
  18. const helpers = require('./helpers')
  19. const Model = require('../../src/LucidMongo/Model')
  20. const DatabaseManager = require('../../src/Database/Manager')
  21. const VanillaSerializer = require('../../src/LucidMongo/Serializers/Vanilla')
  22. test.group('Model', (group) => {
  23. group.before(async () => {
  24. ioc.singleton('Adonis/Src/Database', function () {
  25. const config = new Config()
  26. config.set('database', {
  27. connection: 'testing',
  28. testing: helpers.getConfig()
  29. })
  30. return new DatabaseManager(config)
  31. })
  32. ioc.alias('Adonis/Src/Database', 'Database')
  33. await fs.ensureDir(path.join(__dirname, './tmp'))
  34. await helpers.createCollections(ioc.use('Database'))
  35. setupResolver()
  36. })
  37. group.afterEach(async () => {
  38. await ioc.use('Database').collection('users').delete()
  39. await ioc.use('Database').collection('my_users').delete()
  40. })
  41. group.after(async () => {
  42. await helpers.dropCollections(ioc.use('Database'))
  43. ioc.use('Database').close()
  44. try {
  45. await fs.remove(path.join(__dirname, './tmp'))
  46. } catch (error) {
  47. if (process.platform !== 'win32' || error.code !== 'EBUSY') {
  48. throw error
  49. }
  50. }
  51. }).timeout(0)
  52. test('run queries using query builder', (assert) => {
  53. class User extends Model { }
  54. User._bootIfNotBooted()
  55. const query = User.query()
  56. assert.deepEqual(query.query._conditions, { })
  57. })
  58. test('define different collection for a model', (assert) => {
  59. class User extends Model {
  60. static get collection () {
  61. return 'my_users'
  62. }
  63. }
  64. User._bootIfNotBooted()
  65. const query = User.query()
  66. assert.equal(query.collection, 'my_users')
  67. })
  68. test('define collection prefix for a model', (assert) => {
  69. class User extends Model {
  70. static get prefix () {
  71. return 'my_'
  72. }
  73. }
  74. User._bootIfNotBooted()
  75. const query = User.query()
  76. assert.equal(query.collection, 'my_users')
  77. })
  78. test('call the boot method only once', (assert) => {
  79. let callCounts = 0
  80. class User extends Model {
  81. static boot () {
  82. super.boot()
  83. callCounts++
  84. }
  85. }
  86. User._bootIfNotBooted()
  87. User._bootIfNotBooted()
  88. assert.equal(callCounts, 1)
  89. })
  90. test('should be able to define model attributes on model instance', (assert) => {
  91. class User extends Model {
  92. }
  93. User._bootIfNotBooted()
  94. const user = new User()
  95. user.fill({ username: 'virk', age: 22 })
  96. assert.deepEqual(user.$attributes, { username: 'virk', age: 22 })
  97. })
  98. test('do not remove attribute values when calling merge', (assert) => {
  99. class User extends Model {
  100. }
  101. User._bootIfNotBooted()
  102. const user = new User()
  103. user.fill({ username: 'virk', age: 22 })
  104. user.merge({ age: 23 })
  105. assert.deepEqual(user.$attributes, { username: 'virk', age: 23 })
  106. })
  107. test('call setters when defining attributes via merge', (assert) => {
  108. class User extends Model {
  109. setUsername (username) {
  110. return username.toUpperCase()
  111. }
  112. }
  113. User._bootIfNotBooted()
  114. const user = new User()
  115. user.merge({ username: 'virk', age: 22 })
  116. assert.deepEqual(user.$attributes, { username: 'VIRK', age: 22 })
  117. })
  118. test('remove existing attributes when calling fill', (assert) => {
  119. class User extends Model {
  120. }
  121. User._bootIfNotBooted()
  122. const user = new User()
  123. user.fill({ username: 'virk', age: 22 })
  124. user.fill({ username: 'virk' })
  125. assert.deepEqual(user.$attributes, { username: 'virk' })
  126. })
  127. test('call setters when defining attributes via fill', (assert) => {
  128. class User extends Model {
  129. setUsername (username) {
  130. return username.toUpperCase()
  131. }
  132. }
  133. User._bootIfNotBooted()
  134. const user = new User()
  135. user.fill({ username: 'virk', age: 22 })
  136. assert.deepEqual(user.$attributes, { username: 'VIRK', age: 22 })
  137. })
  138. test('call setters when defining attributes manually', (assert) => {
  139. class User extends Model {
  140. setUsername (username) {
  141. return username.toUpperCase()
  142. }
  143. }
  144. User._bootIfNotBooted()
  145. const user = new User()
  146. user.username = 'virk'
  147. assert.deepEqual(user.$attributes, { username: 'VIRK' })
  148. })
  149. test('save attributes to the database and update model state', async (assert) => {
  150. class User extends Model {
  151. }
  152. User._bootIfNotBooted()
  153. const user = new User()
  154. user.username = 'virk'
  155. await user.save()
  156. assert.isTrue(user.$persisted)
  157. assert.isFalse(user.isNew)
  158. })
  159. test('return proper primary key value using primaryKeyValue getter', async (assert) => {
  160. class User extends Model {
  161. }
  162. User._bootIfNotBooted()
  163. const user = new User()
  164. user.username = 'virk'
  165. await user.save()
  166. assert.isNotNull(user.primaryKeyValue)
  167. })
  168. // test('define different primary key for a given model', async (assert) => {
  169. // class User extends Model {
  170. // static get primaryKey () {
  171. // return 'uuid'
  172. // }
  173. // static get collection () {
  174. // return 'my_users'
  175. // }
  176. // static get incrementing () {
  177. // return false
  178. // }
  179. // }
  180. // User._bootIfNotBooted()
  181. // const user = new User()
  182. // user.username = 'virk'
  183. // user.uuid = 112000
  184. // await user.save()
  185. // assert.equal(user.primaryKeyValue, 112000)
  186. // assert.equal(user.primaryKeyValue, user.uuid)
  187. // })
  188. test('add hook for a given type', async (assert) => {
  189. class User extends Model {
  190. }
  191. User._bootIfNotBooted()
  192. User.addHook('beforeCreate', function () { })
  193. User.addHook('afterCreate', function () { })
  194. assert.lengthOf(User.$hooks.before._handlers.create, 1)
  195. assert.lengthOf(User.$hooks.after._handlers.create, 1)
  196. })
  197. test('add hooks as an array', async (assert) => {
  198. class User extends Model {
  199. }
  200. User._bootIfNotBooted()
  201. User.addHook('beforeCreate', [function () { }, function () { }])
  202. assert.lengthOf(User.$hooks.before._handlers.create, 2)
  203. })
  204. test('throw exception when hook cycle is invalid', async (assert) => {
  205. class User extends Model {
  206. }
  207. User._bootIfNotBooted()
  208. const fn = () => User.addHook('orCreate', function () {
  209. })
  210. assert.throw(fn, 'E_INVALID_PARAMETER: Invalid hook event {orCreate}')
  211. })
  212. test('call before and after create hooks when saving the model for first time', async (assert) => {
  213. class User extends Model {
  214. }
  215. User._bootIfNotBooted()
  216. const stack = []
  217. User.addHook('beforeCreate', function () {
  218. stack.push('before')
  219. })
  220. User.addHook('afterCreate', function () {
  221. stack.push('after')
  222. })
  223. const user = new User()
  224. await user.save()
  225. assert.deepEqual(stack, ['before', 'after'])
  226. })
  227. test('abort insert if before create throws an exception', async (assert) => {
  228. assert.plan(2)
  229. class User extends Model {
  230. }
  231. User._bootIfNotBooted()
  232. User.addHook('beforeCreate', function () {
  233. throw new Error('Something bad happened')
  234. })
  235. User.addHook('afterCreate', function () { })
  236. const user = new User()
  237. try {
  238. await user.save()
  239. } catch ({ message }) {
  240. assert.equal(message, 'Something bad happened')
  241. const users = await ioc.use('Database').collection('users').find()
  242. assert.lengthOf(users, 0)
  243. }
  244. })
  245. test('update model when already persisted', async (assert) => {
  246. class User extends Model {
  247. }
  248. User._bootIfNotBooted()
  249. const user = new User()
  250. user.username = 'virk'
  251. await user.save()
  252. user.username = 'nikk'
  253. await user.save()
  254. const users = await ioc.use('Database').collection('users').find()
  255. assert.lengthOf(users, 1)
  256. assert.equal(users[0].username, user.username)
  257. assert.equal(String(users[0]._id), String(user.primaryKeyValue))
  258. })
  259. test('only update when there are dirty values', async (assert) => {
  260. class User extends Model {
  261. }
  262. User._bootIfNotBooted()
  263. const queries = []
  264. User.onQuery((query) => queries.push(query))
  265. const user = new User()
  266. user.username = 'virk'
  267. await user.save()
  268. await user.save()
  269. // assert.lengthOf(queries, 1)
  270. })
  271. test('update model for multiple times', async (assert) => {
  272. class User extends Model {
  273. }
  274. User._bootIfNotBooted()
  275. const queries = []
  276. User.onQuery((query) => queries.push(query))
  277. const user = new User()
  278. user.username = 'virk'
  279. await user.save()
  280. user.username = 'nikk'
  281. await user.save()
  282. user.username = 'virk'
  283. await user.save()
  284. // assert.lengthOf(queries, 3)
  285. assert.deepEqual(user.dirty, {})
  286. })
  287. test('set timestamps automatically', async (assert) => {
  288. class User extends Model {
  289. }
  290. User._bootIfNotBooted()
  291. const user = new User()
  292. user.username = 'virk'
  293. await user.save()
  294. assert.isDefined(user.created_at)
  295. assert.isDefined(user.updated_at)
  296. })
  297. test('do not set timestamps when columns are not defined', async (assert) => {
  298. class User extends Model {
  299. static get createdAtColumn () {
  300. return null
  301. }
  302. }
  303. User._bootIfNotBooted()
  304. const user = new User()
  305. user.username = 'virk'
  306. await user.save()
  307. assert.isUndefined(user.created_at)
  308. assert.isDefined(user.updated_at)
  309. })
  310. test('return serializer instance when calling fetch', async (assert) => {
  311. class User extends Model {
  312. }
  313. User._bootIfNotBooted()
  314. await ioc.use('Database').collection('users').insert({ username: 'virk' })
  315. const users = await User.query().fetch()
  316. assert.instanceOf(users, VanillaSerializer)
  317. })
  318. test('cast all dates to moment objects after fetch', async (assert) => {
  319. class User extends Model {
  320. }
  321. User._bootIfNotBooted()
  322. const user = new User()
  323. user.username = 'virk'
  324. await user.save()
  325. const users = await User.query().fetch()
  326. assert.instanceOf(users.first().created_at, moment)
  327. })
  328. test('collection toJSON should call model toJSON and getters', async (assert) => {
  329. class User extends Model {
  330. getCreatedAt (date) {
  331. return date.fromNow()
  332. }
  333. }
  334. User._bootIfNotBooted()
  335. const user = new User()
  336. user.username = 'virk'
  337. await user.save()
  338. const users = await User.query().fetch()
  339. const json = users.toJSON()
  340. assert.equal(json[0].created_at, 'a few seconds ago')
  341. })
  342. test('update model over insert when fetched from database', async (assert) => {
  343. class User extends Model {
  344. }
  345. User._bootIfNotBooted()
  346. await ioc.use('Database').collection('users').insert({ username: 'virk' })
  347. const users = await User.query().fetch()
  348. const user = users.first()
  349. user.username = 'nikk'
  350. await user.save()
  351. })
  352. test('call update hooks when updating model', async (assert) => {
  353. const stack = []
  354. class User extends Model {
  355. static boot () {
  356. super.boot()
  357. this.addHook('beforeUpdate', function () {
  358. stack.push('before')
  359. })
  360. this.addHook('afterUpdate', function () {
  361. stack.push('after')
  362. })
  363. }
  364. }
  365. User._bootIfNotBooted()
  366. const user = new User()
  367. user.username = 'nikk'
  368. await user.save()
  369. user.username = 'virk'
  370. await user.save()
  371. assert.deepEqual(stack, ['before', 'after'])
  372. })
  373. test('call save hooks when updating or creating model', async (assert) => {
  374. const stack = []
  375. class User extends Model {
  376. static boot () {
  377. super.boot()
  378. this.addHook('beforeSave', function (model) {
  379. stack.push(`before:${model.$persisted}`)
  380. })
  381. this.addHook('afterSave', function () {
  382. stack.push('after')
  383. })
  384. }
  385. }
  386. User._bootIfNotBooted()
  387. const user = new User()
  388. user.username = 'nikk'
  389. await user.save()
  390. user.username = 'virk'
  391. await user.save()
  392. assert.deepEqual(stack, ['before:false', 'after', 'before:true', 'after'])
  393. })
  394. test('update updated_at timestamp for mass updates', async (assert) => {
  395. class User extends Model {
  396. static get dates () {
  397. const dates = super.dates
  398. dates.push('login_at')
  399. return dates
  400. }
  401. }
  402. User._bootIfNotBooted()
  403. await ioc.use('Database').collection('users').insert([{ username: 'virk' }, { username: 'nikk' }])
  404. await User.query().where('username', 'virk').update({ login_at: new Date() })
  405. const users = await ioc.use('Database').collection('users').find()
  406. assert.equal(moment(users[0].updated_at).format('YYYY-MM-DD'), moment().format('YYYY-MM-DD'))
  407. })
  408. test('attach computed properties to the final output', async (assert) => {
  409. class User extends Model {
  410. static get computed () {
  411. return ['full_name']
  412. }
  413. getFullName ({ username }) {
  414. return `Mr. ${username}`
  415. }
  416. }
  417. User._bootIfNotBooted()
  418. await ioc.use('Database').collection('users').insert([{ username: 'virk' }, { username: 'nikk' }])
  419. const users = await User.query().where('username', 'virk').fetch()
  420. assert.equal(users.first().toObject().full_name, 'Mr. virk')
  421. })
  422. test('only pick visible fields', async (assert) => {
  423. class User extends Model {
  424. static get visible () {
  425. return ['created_at']
  426. }
  427. }
  428. User._bootIfNotBooted()
  429. let user = await User.create({ username: 'virk' })
  430. assert.deepEqual(Object.keys(user.toObject()), ['created_at'])
  431. await User.createMany([{ username: 'virk' }, { username: 'nikk' }])
  432. const users = await User.query().where('username', 'virk').fetch()
  433. user = users.first()
  434. assert.deepEqual(Object.keys(user.toObject()), ['created_at'])
  435. user.reload()
  436. assert.deepEqual(Object.keys(user.toObject()), ['created_at'])
  437. user = await User.find(users.first()._id)
  438. assert.deepEqual(Object.keys(user.toObject()), ['created_at'])
  439. await user.reload()
  440. assert.deepEqual(Object.keys(user.toObject()), ['created_at'])
  441. })
  442. test('omit hidden fields', async (assert) => {
  443. class User extends Model {
  444. static get hidden () {
  445. return ['created_at']
  446. }
  447. }
  448. User._bootIfNotBooted()
  449. let user = await User.create({ username: 'virk' })
  450. assert.deepEqual(Object.keys(user.toObject()).sort(), [
  451. '_id', 'username', 'updated_at'
  452. ].sort())
  453. await User.createMany([{ username: 'virk' }, { username: 'nikk' }])
  454. const users = await User.query().where('username', 'virk').fetch()
  455. user = users.first()
  456. assert.deepEqual(Object.keys(user.toObject()).sort(), [
  457. '_id', 'username', 'updated_at'
  458. ].sort())
  459. await user.reload()
  460. assert.deepEqual(Object.keys(users.first().toObject()).sort(), [
  461. '_id', 'username', 'updated_at'
  462. ].sort())
  463. user = await User.find(user._id)
  464. assert.deepEqual(Object.keys(users.first().toObject()).sort(), [
  465. '_id', 'username', 'updated_at'
  466. ].sort())
  467. await user.reload()
  468. assert.deepEqual(Object.keys(users.first().toObject()).sort(), [
  469. '_id', 'username', 'updated_at'
  470. ].sort())
  471. })
  472. test('apply all global scopes to the query builder', async (assert) => {
  473. class User extends Model {
  474. }
  475. User._bootIfNotBooted()
  476. User.addGlobalScope(function (builder) {
  477. builder.where('deleted_at', null)
  478. })
  479. const query = User.query().where('username', 'virk')._applyScopes()
  480. assert.deepEqual(query.query._conditions, { 'username': 'virk', 'deleted_at': null })
  481. })
  482. test('instruct query builder to ignore all query scopes', async (assert) => {
  483. class User extends Model {
  484. }
  485. User._bootIfNotBooted()
  486. User.addGlobalScope(function (builder) {
  487. builder.where('deleted_at', null)
  488. })
  489. const query = User.query().where('username', 'virk').ignoreScopes()._applyScopes()
  490. assert.deepEqual(query.query._conditions, { 'username': 'virk' })
  491. })
  492. test('instruct query builder to ignore selected scopes', async (assert) => {
  493. class User extends Model {
  494. }
  495. User._bootIfNotBooted()
  496. User.addGlobalScope(function (builder) {
  497. builder.where('deleted_at', null)
  498. }, 'softDeletes')
  499. User.addGlobalScope(function (builder) {
  500. builder.where('login_at', '>=', '2017')
  501. }, 'loggedOnce')
  502. const query = User.query().where('username', 'virk').ignoreScopes(['softDeletes'])._applyScopes()
  503. assert.deepEqual(query.query._conditions, { 'username': 'virk', 'login_at': { '$gte': '2017' } })
  504. })
  505. test('define local scopes', async (assert) => {
  506. class User extends Model {
  507. static scopeIsLogged (builder) {
  508. builder.whereNotNull('login_at')
  509. }
  510. }
  511. User._bootIfNotBooted()
  512. const query = User.query().where('username', 'virk').isLogged()
  513. assert.deepEqual(query.query._conditions, { 'username': 'virk', 'login_at': { '$exists': true } })
  514. })
  515. test('pass arguments to local scopes', async (assert) => {
  516. class User extends Model {
  517. static scopeIsLogged (builder, time) {
  518. builder.where('login_at', '>', time)
  519. }
  520. }
  521. User._bootIfNotBooted()
  522. const date = new Date()
  523. const query = User.query().where('username', 'virk').isLogged(date)
  524. assert.deepEqual(query.query._conditions, { 'username': 'virk', 'login_at': { '$gt': moment(date).toDate() } })
  525. })
  526. test('find model instance using find method', async (assert) => {
  527. class User extends Model {
  528. }
  529. User._bootIfNotBooted()
  530. const result = await ioc.use('Database').collection('users').insert({ username: 'virk' })
  531. const user = await User.find(result.insertedIds[0])
  532. assert.instanceOf(user, User)
  533. assert.equal(user.username, 'virk')
  534. assert.isFalse(user.isNew)
  535. assert.isFalse(user.isDirty)
  536. })
  537. test('find with a single where clause', async (assert) => {
  538. class User extends Model {
  539. }
  540. User._bootIfNotBooted()
  541. await ioc.use('Database').collection('users').insert({ username: 'virk' })
  542. const user = await User.findBy('username', 'virk')
  543. assert.instanceOf(user, User)
  544. assert.equal(user.username, 'virk')
  545. assert.isFalse(user.isNew)
  546. assert.isFalse(user.isDirty)
  547. })
  548. test('call after find hooks on findBy', async (assert) => {
  549. class User extends Model {
  550. }
  551. User._bootIfNotBooted()
  552. const stack = []
  553. User.addHook('afterFind', async function () {
  554. await helpers.sleep(1)
  555. stack.push('afterFind')
  556. })
  557. await ioc.use('Database').collection('users').insert({ username: 'virk' })
  558. await User.findBy('username', 'virk')
  559. assert.deepEqual(stack, ['afterFind'])
  560. })
  561. test('pass model instance to after find hook', async (assert) => {
  562. class User extends Model {
  563. }
  564. User._bootIfNotBooted()
  565. let hookInstance = null
  566. User.addHook('afterFind', function (model) {
  567. hookInstance = model
  568. })
  569. await ioc.use('Database').collection('users').insert({ username: 'virk' })
  570. const user = await User.findBy('username', 'virk')
  571. assert.deepEqual(hookInstance, user)
  572. })
  573. test('return everything from the database', async (assert) => {
  574. class User extends Model {
  575. }
  576. User._bootIfNotBooted()
  577. await ioc.use('Database').collection('users').insert({ username: 'virk' })
  578. const users = await User.all()
  579. assert.instanceOf(users, VanillaSerializer)
  580. })
  581. test('pick x number of rows from database', async (assert) => {
  582. class User extends Model {
  583. }
  584. User._bootIfNotBooted()
  585. await ioc.use('Database').collection('users').insert([{ username: 'virk' }, { username: 'nikk' }])
  586. const users = await User.pick(1)
  587. assert.instanceOf(users, VanillaSerializer)
  588. assert.equal(users.first().username, 'virk')
  589. })
  590. test('pick inverse x number of rows from database', async (assert) => {
  591. class User extends Model {
  592. }
  593. User._bootIfNotBooted()
  594. await ioc.use('Database').collection('users').insert([{ username: 'virk' }, { username: 'nikk' }])
  595. const users = await User.pickInverse(1)
  596. assert.instanceOf(users, VanillaSerializer)
  597. assert.equal(users.first().username, 'nikk')
  598. })
  599. test('return an array of ids from the database', async (assert) => {
  600. class User extends Model {
  601. }
  602. User._bootIfNotBooted()
  603. await ioc.use('Database').collection('users').insert([{ username: 'virk' }, { username: 'nikk' }])
  604. const userIds = await User.ids()
  605. assert.lengthOf(userIds, 2)
  606. })
  607. test('return a pair of key/values from the database', async (assert) => {
  608. class User extends Model {
  609. }
  610. User._bootIfNotBooted()
  611. await ioc.use('Database').collection('users').insert([{ username: 'virk' }, { username: 'nikk' }])
  612. const users = await User.pair('_id', 'username')
  613. assert.deepEqual(Object.values(users), ['virk', 'nikk'])
  614. })
  615. test('paginate model', async (assert) => {
  616. class User extends Model {
  617. }
  618. User._bootIfNotBooted()
  619. await ioc.use('Database').collection('users').insert([{ username: 'virk' }, { username: 'nikk' }])
  620. const users = await User.query().paginate(1, 1)
  621. assert.instanceOf(users, VanillaSerializer)
  622. assert.deepEqual(users.pages, { perPage: 1, total: helpers.formatNumber(2), page: 1, lastPage: 2 })
  623. assert.equal(users.first().username, 'virk')
  624. })
  625. test('return first row from database on calling static method', async (assert) => {
  626. class User extends Model {
  627. }
  628. User._bootIfNotBooted()
  629. await ioc.use('Database').collection('users').insert([{ username: 'virk' }, { username: 'nikk' }])
  630. const user = await User.first()
  631. assert.instanceOf(user, User)
  632. assert.equal(user.username, 'virk')
  633. })
  634. test('return find static method', async (assert) => {
  635. class User extends Model {
  636. }
  637. User._bootIfNotBooted()
  638. const result = await ioc.use('Database').collection('users').insert([{ username: 'virk' }, { username: 'nikk' }])
  639. const user = await User.find(result.insertedIds[0])
  640. assert.instanceOf(user, User)
  641. assert.equal(user.username, 'virk')
  642. })
  643. test('auto format dates via formatDates when creating', async (assert) => {
  644. const formatting = []
  645. class User extends Model {
  646. static formatDates (key, value) {
  647. const formattedValue = super.formatDates(key, value)
  648. formatting.push({ key, value: formattedValue })
  649. }
  650. }
  651. User._bootIfNotBooted()
  652. const user = new User()
  653. user.username = 'virk'
  654. await user.save()
  655. const keys = formatting.map((item) => item.key)
  656. const values = formatting.map((item) => moment(item.value, 'YYYY-MM-DD HH:mm:ss', true).isValid())
  657. assert.deepEqual(keys, ['created_at', 'updated_at'])
  658. assert.deepEqual(values, [true, true])
  659. })
  660. test('auto format just updated_at via formatDates when updating', async (assert) => {
  661. const formatting = []
  662. class User extends Model {
  663. static formatDates (key, value) {
  664. const formattedValue = super.formatDates(key, value)
  665. formatting.push({ key, value: formattedValue })
  666. }
  667. }
  668. User._bootIfNotBooted()
  669. await ioc.use('Database').collection('users').insert({ username: 'virk' })
  670. const user = await User.first()
  671. user.username = 'nikk'
  672. await user.save()
  673. const keys = formatting.map((item) => item.key)
  674. const values = formatting.map((item) => moment(item.value, 'YYYY-MM-DD HH:mm:ss', true).isValid())
  675. assert.deepEqual(keys, ['updated_at'])
  676. assert.deepEqual(values, [true])
  677. })
  678. test('auto format when bulk updating', async (assert) => {
  679. const formatting = []
  680. class User extends Model {
  681. static formatDates (key, value) {
  682. const formattedValue = super.formatDates(key, value)
  683. formatting.push({ key, value: formattedValue })
  684. }
  685. }
  686. User._bootIfNotBooted()
  687. await ioc.use('Database').collection('users').insert({ username: 'virk' })
  688. await User.query().where('username', 'virk').update({ username: 'nikk' })
  689. const keys = formatting.map((item) => item.key)
  690. const values = formatting.map((item) => moment(item.value, 'YYYY-MM-DD HH:mm:ss', true).isValid())
  691. assert.deepEqual(keys, ['updated_at'])
  692. assert.deepEqual(values, [true])
  693. })
  694. test('do not mutate bulk updates object', async (assert) => {
  695. class User extends Model {
  696. }
  697. User._bootIfNotBooted()
  698. await ioc.use('Database').collection('users').insert({ username: 'virk' })
  699. const updates = { username: 'nikk' }
  700. await User.query().where('username', 'virk').update(updates)
  701. assert.deepEqual(updates, { username: 'nikk' })
  702. })
  703. test('do not call formatDates when setters for them are defined', async (assert) => {
  704. const formatting = []
  705. class User extends Model {
  706. static formatDates (key, value) {
  707. const formattedValue = super.formatDates(key, value)
  708. formatting.push({ key, value: formattedValue })
  709. return formattedValue
  710. }
  711. setCreatedAt () {
  712. return null
  713. }
  714. }
  715. User._bootIfNotBooted()
  716. const user = new User()
  717. user.username = 'virk'
  718. await user.save()
  719. const keys = formatting.map((item) => item.key)
  720. const values = formatting.map((item) => moment(item.value, 'YYYY-MM-DD HH:mm:ss', true).isValid())
  721. assert.deepEqual(keys, ['updated_at'])
  722. assert.deepEqual(values, [true])
  723. assert.isNull(user.created_at)
  724. })
  725. test('do not call formatDates when not part of dates', async (assert) => {
  726. const formatting = []
  727. class User extends Model {
  728. static formatDates (key, value) {
  729. const formattedValue = super.formatDates(key, value)
  730. formatting.push({ key, value: formattedValue })
  731. return formattedValue
  732. }
  733. static get createdAtColumn () {
  734. return null
  735. }
  736. }
  737. User._bootIfNotBooted()
  738. const user = new User()
  739. user.username = 'virk'
  740. await user.save()
  741. const keys = formatting.map((item) => item.key)
  742. const values = formatting.map((item) => moment(item.value, 'YYYY-MM-DD HH:mm:ss', true).isValid())
  743. assert.deepEqual(keys, ['updated_at'])
  744. assert.deepEqual(values, [true])
  745. assert.isUndefined(user.created_at)
  746. })
  747. test('use setter value when bulk updating and do not call formatDates', async (assert) => {
  748. const formatting = []
  749. class User extends Model {
  750. static formatDates (key, value) {
  751. const formattedValue = super.formatDates(key, value)
  752. formatting.push({ key, value: formattedValue })
  753. return formattedValue
  754. }
  755. setUpdatedAt () {
  756. return null
  757. }
  758. }
  759. User._bootIfNotBooted()
  760. await ioc.use('Database').collection('users').insert({ username: 'virk' })
  761. await User.query().where('username', 'virk').update({ username: 'nikk' })
  762. const users = await User.query().pair('_id', 'updated_at')
  763. assert.deepEqual(formatting, [])
  764. assert.isObject(users)
  765. })
  766. test('call castDates when toJSON or toObject is called', async (assert) => {
  767. const casting = []
  768. class User extends Model {
  769. static castDates (key, value) {
  770. const formattedValue = super.castDates(key, value)
  771. casting.push({ key, value: formattedValue })
  772. return formattedValue
  773. }
  774. }
  775. User._bootIfNotBooted()
  776. await ioc.use('Database')
  777. .collection('users')
  778. .insert({ username: 'virk', created_at: new Date(), updated_at: new Date() })
  779. const user = await User.first()
  780. const json = user.toObject()
  781. assert.isTrue(moment(json.created_at, 'YYYY-MM-DD HH:mm:ss', true).isValid())
  782. assert.isTrue(moment(json.updated_at, 'YYYY-MM-DD HH:mm:ss', true).isValid())
  783. assert.deepEqual(casting.map((field) => field.key), ['created_at', 'updated_at'])
  784. })
  785. test('do not cast date when field not defined as date', async (assert) => {
  786. const casting = []
  787. class User extends Model {
  788. static castDates (key, value) {
  789. const formattedValue = value.format('YYYY-MM-DD')
  790. casting.push({ key, value: formattedValue })
  791. return formattedValue
  792. }
  793. static get createdAtColumn () {
  794. return null
  795. }
  796. }
  797. User._bootIfNotBooted()
  798. await ioc.use('Database')
  799. .collection('users')
  800. .insert({ username: 'virk', created_at: new Date(), updated_at: new Date() })
  801. const user = await User.first()
  802. const json = user.toObject()
  803. assert.isFalse(moment(json.created_at.toString(), 'YYYY-MM-DD', true).isValid())
  804. assert.isTrue(moment(json.updated_at.toString(), 'YYYY-MM-DD', true).isValid())
  805. assert.deepEqual(casting.map((field) => field.key), ['updated_at'])
  806. })
  807. test('do not cast date when field has a getter', async (assert) => {
  808. const casting = []
  809. class User extends Model {
  810. static castDates (key, value) {
  811. const formattedValue = super.castDates(key, value)
  812. casting.push({ key, value: formattedValue })
  813. return formattedValue
  814. }
  815. getCreatedAt (value) {
  816. return value.fromNow(true)
  817. }
  818. }
  819. User._bootIfNotBooted()
  820. await ioc.use('Database')
  821. .collection('users')
  822. .insert({ username: 'virk', created_at: new Date(), updated_at: new Date() })
  823. const user = await User.first()
  824. const json = user.toObject()
  825. assert.equal(json.created_at, 'a few seconds')
  826. assert.deepEqual(casting.map((field) => field.key), ['updated_at'])
  827. })
  828. test('cast dates should work for custom dates as well', async (assert) => {
  829. const casting = []
  830. class User extends Model {
  831. static castDates (key, value) {
  832. const formattedValue = super.castDates(key, value)
  833. casting.push({ key, value: formattedValue })
  834. return formattedValue
  835. }
  836. static get dates () {
  837. const existingDates = super.dates
  838. existingDates.push('login_at')
  839. return existingDates
  840. }
  841. }
  842. User._bootIfNotBooted()
  843. await ioc.use('Database')
  844. .collection('users')
  845. .insert({ username: 'virk', created_at: new Date(), updated_at: new Date(), login_at: new Date() })
  846. const user = await User.first()
  847. const json = user.toObject()
  848. assert.isTrue(moment(json.created_at, 'YYYY-MM-DD HH:mm:ss', true).isValid())
  849. assert.isTrue(moment(json.updated_at, 'YYYY-MM-DD HH:mm:ss', true).isValid())
  850. assert.isTrue(moment(json.login_at, 'YYYY-MM-DD HH:mm:ss', true).isValid())
  851. assert.deepEqual(casting.map((field) => field.key), ['created_at', 'updated_at', 'login_at'])
  852. })
  853. test('create model instance and persist it to database', async (assert) => {
  854. class User extends Model {
  855. }
  856. User._bootIfNotBooted()
  857. const user = await User.create({ username: 'virk' })
  858. assert.isTrue(user.$persisted)
  859. assert.isFalse(user.isNew)
  860. })
  861. test('further changes to instance returned by create should update the model', async (assert) => {
  862. class User extends Model {
  863. }
  864. User._bootIfNotBooted()
  865. const user = await User.create({ username: 'virk' })
  866. assert.isTrue(user.$persisted)
  867. assert.isFalse(user.isNew)
  868. user.username = 'nikk'
  869. await user.save()
  870. })
  871. test('should be able to delete the model instance', async (assert) => {
  872. class User extends Model {
  873. }
  874. User._bootIfNotBooted()
  875. const user = await User.create({ username: 'virk' })
  876. assert.isTrue(user.$persisted)
  877. assert.isFalse(user.isNew)
  878. await user.delete()
  879. const fn = () => {
  880. user.username = 'virk'
  881. }
  882. assert.isTrue(user.isDeleted)
  883. assert.throw(fn, 'E_DELETED_MODEL: Cannot edit deleted model instance for User model')
  884. })
  885. test('ignore global scopes when deleting model', async (assert) => {
  886. class User extends Model {
  887. }
  888. User._bootIfNotBooted()
  889. User.addGlobalScope(function (builder) {
  890. builder.where('username', 'virk')
  891. })
  892. const user = await User.create({ username: 'virk' })
  893. assert.isTrue(user.$persisted)
  894. assert.isFalse(user.isNew)
  895. await user.delete()
  896. const fn = () => {
  897. user.username = 'virk'
  898. }
  899. assert.isTrue(user.isDeleted)
  900. assert.throw(fn, 'E_DELETED_MODEL: Cannot edit deleted model instance for User model')
  901. })
  902. test('create an array of models', async (assert) => {
  903. class User extends Model {
  904. }
  905. User._bootIfNotBooted()
  906. const users = await User.createMany([{ username: 'virk' }, { username: 'nikk' }])
  907. assert.isArray(users)
  908. assert.isTrue(users[0].$persisted)
  909. assert.isFalse(users[0].isNew)
  910. assert.isTrue(users[1].$persisted)
  911. assert.isFalse(users[1].isNew)
  912. })
  913. test('run create hooks for all the models to be created via createMany', async (assert) => {
  914. const stack = []
  915. class User extends Model {
  916. }
  917. User._bootIfNotBooted()
  918. User.addHook('beforeCreate', (ctx) => {
  919. stack.push(ctx.username)
  920. })
  921. await User.createMany([{ username: 'virk' }, { username: 'nikk' }])
  922. assert.deepEqual(stack, ['virk', 'nikk'])
  923. })
  924. test('throw an exception when createMany doesn\'t recieves an array', async (assert) => {
  925. assert.plan(1)
  926. class User extends Model {
  927. }
  928. User._bootIfNotBooted()
  929. try {
  930. await User.createMany({ username: 'virk' })
  931. } catch ({ message }) {
  932. assert.equal(message, 'E_INVALID_PARAMETER: User.createMany expects an array of values instead received object')
  933. }
  934. })
  935. test('throw exception when unable to find row', async (assert) => {
  936. assert.plan(1)
  937. class User extends Model {
  938. }
  939. try {
  940. await User.findOrFail(1)
  941. } catch ({ message }) {
  942. assert.equal(message, 'E_MISSING_DATABASE_ROW: Cannot find database row for User model')
  943. }
  944. })
  945. test('throw exception when unable to find row via findByOrFail', async (assert) => {
  946. assert.plan(1)
  947. class User extends Model {
  948. }
  949. try {
  950. await User.findByOrFail('username', 'virk')
  951. } catch ({ message }) {
  952. assert.equal(message, 'E_MISSING_DATABASE_ROW: Cannot find database row for User model')
  953. }
  954. })
  955. test('throw exception via firstOrFail', async (assert) => {
  956. assert.plan(1)
  957. class User extends Model {
  958. }
  959. try {
  960. await User.firstOrFail()
  961. } catch ({ message }) {
  962. assert.equal(message, 'E_MISSING_DATABASE_ROW: Cannot find database row for User model')
  963. }
  964. })
  965. test('return model instance findByOrFail finds row', async (assert) => {
  966. assert.plan(1)
  967. class User extends Model {
  968. }
  969. User._bootIfNotBooted()
  970. await ioc.use('Database').collection('users').insert({ username: 'virk' })
  971. const user = await User.findByOrFail('username', 'virk')
  972. assert.instanceOf(user, User)
  973. })
  974. test('delete existing model instance', async (assert) => {
  975. assert.plan(2)
  976. class User extends Model {
  977. }
  978. User._bootIfNotBooted()
  979. const user = new User()
  980. user.username = 'virk'
  981. await user.save()
  982. await user.delete()
  983. assert.isTrue(user.$frozen)
  984. try {
  985. user.username = 'foo'
  986. } catch ({ message }) {
  987. assert.equal(message, 'E_DELETED_MODEL: Cannot edit deleted model instance for User model')
  988. }
  989. })
  990. test('allow to unfreeze model instance', async (assert) => {
  991. assert.plan(1)
  992. class User extends Model {
  993. }
  994. const user = new User()
  995. user.freeze()
  996. user.unfreeze()
  997. assert.isFalse(user.$frozen)
  998. })
  999. test('dates should be an empty array when createdAtColumn and updatedAtColumn is not defined', async (assert) => {
  1000. class User extends Model {
  1001. static get createdAtColumn () {
  1002. return null
  1003. }
  1004. static get updatedAtColumn () {
  1005. return null
  1006. }
  1007. }
  1008. User._bootIfNotBooted()
  1009. assert.deepEqual(User.dates, [])
  1010. })
  1011. test('do not populate dates when columns are set to null', async (assert) => {
  1012. class User extends Model {
  1013. static get createdAtColumn () {
  1014. return null
  1015. }
  1016. static get updatedAtColumn () {
  1017. return null
  1018. }
  1019. }
  1020. User._bootIfNotBooted()
  1021. const user = new User()
  1022. user.username = 'virk'
  1023. await user.save()
  1024. assert.isUndefined(user.created_at)
  1025. assert.isUndefined(user.updated_at)
  1026. })
  1027. test('throw exception when onQuery doesn\'t recieves as callback', (assert) => {
  1028. assert.plan(1)
  1029. class User extends Model {
  1030. static boot () {
  1031. super.boot()
  1032. }
  1033. }
  1034. const fn = () => User.onQuery('foo')
  1035. assert.throw(fn, 'E_INVALID_PARAMETER: Model.onQuery expects a closure as first parameter')
  1036. })
  1037. test('throw exception when addGlobalScope doesn\'t recieves as callback', (assert) => {
  1038. assert.plan(1)
  1039. class User extends Model {
  1040. static boot () {
  1041. super.boot()
  1042. }
  1043. }
  1044. const fn = () => User.addGlobalScope('foo')
  1045. assert.throw(fn, 'E_INVALID_PARAMETER: Model.addGlobalScope expects a closure as first parameter')
  1046. })
  1047. test('refresh model state', async (assert) => {
  1048. class User extends Model {
  1049. static boot () {
  1050. super.boot()
  1051. }
  1052. }
  1053. User._bootIfNotBooted()
  1054. const user = new User()
  1055. user.username = 'virk'
  1056. await user.save()
  1057. assert.isUndefined(user.type)
  1058. await ioc.use('Database').collection('users').update({ type: 'admin' })
  1059. await user.reload()
  1060. assert.equal(user.type, 'admin')
  1061. })
  1062. test('do not reload when isNew', async (assert) => {
  1063. class User extends Model {
  1064. static boot () {
  1065. super.boot()
  1066. }
  1067. }
  1068. User._bootIfNotBooted()
  1069. const user = new User()
  1070. user.username = 'virk'
  1071. assert.isUndefined(user.type)
  1072. await user.reload()
  1073. assert.isUndefined(user.type)
  1074. })
  1075. test('throw exception when on reloas the row is missing', async (assert) => {
  1076. assert.plan(2)
  1077. class User extends Model {
  1078. static boot () {
  1079. super.boot()
  1080. }
  1081. }
  1082. User._bootIfNotBooted()
  1083. const user = new User()
  1084. user.username = 'virk'
  1085. await user.save()
  1086. assert.isUndefined(user.type)
  1087. await ioc.use('Database').collection('users').delete()
  1088. try {
  1089. await user.reload()
  1090. } catch ({ message }) {
  1091. assert.isString(message)
  1092. }
  1093. })
  1094. test('do not reload when model is deleted', async (assert) => {
  1095. assert.plan(2)
  1096. class User extends Model {
  1097. static boot () {
  1098. super.boot()
  1099. }
  1100. }
  1101. User._bootIfNotBooted()
  1102. const user = new User()
  1103. user.username = 'virk'
  1104. await user.save()
  1105. assert.isUndefined(user.type)
  1106. await user.delete()
  1107. try {
  1108. await user.reload()
  1109. } catch ({ message }) {
  1110. assert.equal(message, 'E_RUNTIME_ERROR: Cannot reload a deleted model instance')
  1111. }
  1112. })
  1113. test('define after fetch hook', async (assert) => {
  1114. class User extends Model {
  1115. }
  1116. User._bootIfNotBooted()
  1117. const fn = async function () { }
  1118. User.addHook('afterFetch', fn)
  1119. assert.deepEqual(User.$hooks.after._handlers.fetch, [{ handler: fn, name: undefined }])
  1120. })
  1121. test('call after fetch hook when fetching data', async (assert) => {
  1122. assert.plan(2)
  1123. class User extends Model {
  1124. }
  1125. User._bootIfNotBooted()
  1126. const fn = async function (instances) {
  1127. instances.forEach((instance) => {
  1128. assert.instanceOf(instance, User)
  1129. })
  1130. }
  1131. User.addHook('afterFetch', fn)
  1132. await ioc.use('Database').collection('users').insert([{ username: 'virk' }, { username: 'nikk' }])
  1133. await User.all('username', 'virk')
  1134. })
  1135. test('create a new row when unable to find one', async (assert) => {
  1136. class User extends Model {
  1137. }
  1138. User._bootIfNotBooted()
  1139. const existing = await User.first()
  1140. assert.isNull(existing)
  1141. const user = await User.findOrCreate({ username: 'foo' })
  1142. assert.isTrue(user.$persisted)
  1143. assert.equal(user.username, 'foo')
  1144. })
  1145. test('return existing row when found one', async (assert) => {
  1146. class User extends Model {
  1147. }
  1148. User._bootIfNotBooted()
  1149. await ioc.use('Database').collection('users').insert({ username: 'foo' })
  1150. const user = await User.findOrCreate({ username: 'foo' })
  1151. assert.isTrue(user.$persisted)
  1152. assert.equal(user.username, 'foo')
  1153. })
  1154. test('pass different payload for create', async (assert) => {
  1155. class User extends Model {
  1156. }
  1157. User._bootIfNotBooted()
  1158. const user = await User.findOrCreate({ username: 'foo' }, { username: 'foo', vid: 2 })
  1159. assert.isTrue(user.$persisted)
  1160. assert.equal(user.username, 'foo')
  1161. assert.equal(user.vid, 2)
  1162. })
  1163. test('new up a row when old doesn\'t exists', async (assert) => {
  1164. class User extends Model {
  1165. }
  1166. User._bootIfNotBooted()
  1167. const user = await User.findOrNew({ username: 'foo' }, { username: 'foo', vid: 2 })
  1168. assert.isFalse(user.$persisted)
  1169. assert.equal(user.username, 'foo')
  1170. assert.equal(user.vid, 2)
  1171. })
  1172. test('should update sub attribute', async (assert) => {
  1173. class User extends Model {
  1174. static get dates () { return [...super.dates, 'birthDate', 'joinDate'] }
  1175. }
  1176. User._bootIfNotBooted()
  1177. const user = await User.create({
  1178. name: 'vik',
  1179. age: 10,
  1180. birthDate: '2000-12-12',
  1181. joinDate: '2000-12-12',
  1182. address: {
  1183. line: 'foo',
  1184. city: 'bar'
  1185. }
  1186. })
  1187. user.address.city = 'hnn'
  1188. user.age = 20
  1189. user.birthDate = '2001-12-12'
  1190. assert.deepEqual(user.dirty, {
  1191. address: {
  1192. line: 'foo',
  1193. city: 'hnn'
  1194. },
  1195. age: 20,
  1196. birthDate: moment('2001-12-12')
  1197. })
  1198. })
  1199. })
  1200. test.group('Lucid | Query builder', (group) => {
  1201. group.before(async () => {
  1202. ioc.singleton('Adonis/Src/Database', function () {
  1203. const config = new Config()
  1204. config.set('database', {
  1205. connection: 'testing',
  1206. testing: helpers.getConfig()
  1207. })
  1208. return new DatabaseManager(config)
  1209. })
  1210. ioc.alias('Adonis/Src/Database', 'Database')
  1211. await fs.ensureDir(path.join(__dirname, './tmp'))
  1212. await helpers.createCollections(ioc.use('Database'))
  1213. setupResolver()
  1214. })
  1215. group.afterEach(async () => {
  1216. await ioc.use('Database').collection('users').delete()
  1217. await ioc.use('Database').collection('my_users').delete()
  1218. })
  1219. group.after(async () => {
  1220. await helpers.dropCollections(ioc.use('Database'))
  1221. ioc.use('Database').close()
  1222. try {
  1223. await fs.remove(path.join(__dirname, './tmp'))
  1224. } catch (error) {
  1225. if (process.platform !== 'win32' || error.code !== 'EBUSY') {
  1226. throw error
  1227. }
  1228. }
  1229. }).timeout(0)
  1230. test('query where and', (assert) => {
  1231. class User extends Model { }
  1232. User._bootIfNotBooted()
  1233. const query = User.where({ and: [{ name: 'vik' }, { age: { gte: 30 } }] })
  1234. assert.deepEqual(query.query._conditions, { $and: [{ name: 'vik' }, { age: { gte: 30 } }] })
  1235. })
  1236. test('query where or', (assert) => {
  1237. class User extends Model { }
  1238. User._bootIfNotBooted()
  1239. const query = User.where({ or: [{ name: 'vik' }, { age: { gte: 30 } }] })
  1240. assert.deepEqual(query.query._conditions, { $or: [{ name: 'vik' }, { age: { gte: 30 } }] })
  1241. })
  1242. test('query where near', (assert) => {
  1243. class User extends Model { }
  1244. User._bootIfNotBooted()
  1245. const query = User.where({ location: { near: { latitude: 1, longitude: 2 }, maxDistance: 1000 } })
  1246. assert.deepEqual(query.query._conditions, {
  1247. location: {
  1248. $near: [2, 1],
  1249. $maxDistance: 1000
  1250. }
  1251. })
  1252. })
  1253. test('query where near sphere', (assert) => {
  1254. class User extends Model {
  1255. static get geometries () { return ['location'] }
  1256. }
  1257. User._bootIfNotBooted()
  1258. const query = User.where({ location: { nearSphere: { latitude: 1, longitude: 2 }, maxDistance: 1000 } })
  1259. assert.deepEqual(query.query._conditions, {
  1260. 'location': {
  1261. '$near': {
  1262. '$geometry': {
  1263. 'type': 'Point',
  1264. 'coordinates': [2, 1],
  1265. 'spherical': true
  1266. },
  1267. '$maxDistance': 1000
  1268. }
  1269. }
  1270. })
  1271. })
  1272. test('through exception if method does not support', (assert) => {
  1273. class User extends Model { }
  1274. User._bootIfNotBooted()
  1275. const fn = () => User.where({ name: { foo: 1 } })
  1276. assert.throw(fn, 'Method "$foo" is not support by query builder')
  1277. })
  1278. test('query where with callback', (assert) => {
  1279. class User extends Model { }
  1280. User._bootIfNotBooted()
  1281. const query = User.where(function () {
  1282. this.where('name', 'vik').limit(10)
  1283. })
  1284. assert.deepEqual(query.query._conditions, { name: 'vik' })
  1285. assert.deepEqual(query.query.options, { limit: 10 })
  1286. })
  1287. test('where method similar sql', (assert) => {
  1288. class User extends Model { }
  1289. User._bootIfNotBooted()
  1290. const query = User
  1291. .where('name', '=', 'vik')
  1292. .where('field1', '>', 20)
  1293. .where('field2', '<', 20)
  1294. .where('field3', '>=', 20)
  1295. .where('field4', '<=', 20)
  1296. .where('field5', '<>', 'disabled')
  1297. assert.deepEqual(query.query._conditions, {
  1298. name: 'vik',
  1299. field1: { $gt: 20 },
  1300. field2: { $lt: 20 },
  1301. field3: { $gte: 20 },
  1302. field4: { $lte: 20 },
  1303. field5: { $ne: 'disabled' }
  1304. })
  1305. })
  1306. test('call chain mquery', (assert) => {
  1307. class User extends Model { }
  1308. User._bootIfNotBooted()
  1309. const query = User.where('name').eq('vik').where('age').gte(20)
  1310. assert.deepEqual(query.query._conditions, { name: 'vik', age: { $gte: 20 } })
  1311. })
  1312. test('whereNull method', (assert) => {
  1313. class User extends Model { }
  1314. User._bootIfNotBooted()
  1315. const query = User.query().whereNull('name')
  1316. assert.deepEqual(query.query._conditions, { name: { $exists: false } })
  1317. })
  1318. test('whereNotNull method', (assert) => {
  1319. class User extends Model { }
  1320. User._bootIfNotBooted()
  1321. const query = User.query().whereNotNull('name')
  1322. assert.deepEqual(query.query._conditions, { name: { $exists: true } })
  1323. })
  1324. })
  1325. test.group('Lucid | Query update', (group) => {
  1326. group.before(async () => {
  1327. ioc.singleton('Adonis/Src/Database', function () {
  1328. const config = new Config()
  1329. config.set('database', {
  1330. connection: 'testing',
  1331. testing: helpers.getConfig()
  1332. })
  1333. return new DatabaseManager(config)
  1334. })
  1335. ioc.alias('Adonis/Src/Database', 'Database')
  1336. await fs.ensureDir(path.join(__dirname, './tmp'))
  1337. await helpers.createCollections(ioc.use('Database'))
  1338. setupResolver()
  1339. })
  1340. group.afterEach(async () => {
  1341. await ioc.use('Database').collection('users').delete()
  1342. await ioc.use('Database').collection('my_users').delete()
  1343. })
  1344. group.after(async () => {
  1345. await helpers.dropCollections(ioc.use('Database'))
  1346. ioc.use('Database').close()
  1347. try {
  1348. await fs.remove(path.join(__dirname, './tmp'))
  1349. } catch (error) {
  1350. if (process.platform !== 'win32' || error.code !== 'EBUSY') {
  1351. throw error
  1352. }
  1353. }
  1354. }).timeout(0)
  1355. test('Should update all', async (assert) => {
  1356. class User extends Model { }
  1357. User._bootIfNotBooted()
  1358. const users = [{ name: 'vik', isActive: true }, { name: 'nik', isActive: true }]
  1359. await ioc.use('Database').collection('users').insert(users)
  1360. await User.query().update({ isActive: false })
  1361. const newUsers = await User.where({ isActive: false }).fetch()
  1362. assert.lengthOf(newUsers.rows, 2)
  1363. })
  1364. test('should update with condition', async (assert) => {
  1365. class User extends Model { }
  1366. User._bootIfNotBooted()
  1367. const users = [{ name: 'vik' }, { name: 'vik' }, { name: 'nik' }, { name: 'nik' }]
  1368. await ioc.use('Database').collection('users').insert(users)
  1369. await User.query().where({ name: 'vik' }).update({ isActive: true })
  1370. const newUsers = await User.where({ isActive: true }).fetch()
  1371. assert.lengthOf(newUsers.rows, 2)
  1372. })
  1373. })
  1374. test.group('Lucid | Query delete', (group) => {
  1375. group.before(async () => {
  1376. ioc.singleton('Adonis/Src/Database', function () {
  1377. const config = new Config()
  1378. config.set('database', {
  1379. connection: 'testing',
  1380. testing: helpers.getConfig()
  1381. })
  1382. return new DatabaseManager(config)
  1383. })
  1384. ioc.alias('Adonis/Src/Database', 'Database')
  1385. await fs.ensureDir(path.join(__dirname, './tmp'))
  1386. await helpers.createCollections(ioc.use('Database'))
  1387. setupResolver()
  1388. })
  1389. group.afterEach(async () => {
  1390. await ioc.use('Database').collection('users').delete()
  1391. await ioc.use('Database').collection('my_users').delete()
  1392. })
  1393. group.after(async () => {
  1394. await helpers.dropCollections(ioc.use('Database'))
  1395. ioc.use('Database').close()
  1396. try {
  1397. await fs.remove(path.join(__dirname, './tmp'))
  1398. } catch (error) {
  1399. if (process.platform !== 'win32' || error.code !== 'EBUSY') {
  1400. throw error
  1401. }
  1402. }
  1403. }).timeout(0)
  1404. test('Should delete all', async (assert) => {
  1405. class User extends Model { }
  1406. User._bootIfNotBooted()
  1407. const users = [{ name: 'vik', isActive: true }, { name: 'nik', isActive: true }]
  1408. await ioc.use('Database').collection('users').insert(users)
  1409. await User.query().delete()
  1410. const newUsers = await User.all()
  1411. assert.lengthOf(newUsers.rows, 0)
  1412. })
  1413. test('should delete items match with condition', async (assert) => {
  1414. class User extends Model { }
  1415. User._bootIfNotBooted()
  1416. const users = [{ name: 'vik' }, { name: 'vik' }, { name: 'nik' }, { name: 'nik' }]
  1417. await ioc.use('Database').collection('users').insert(users)
  1418. await User.query().where({ name: 'vik' }).delete()
  1419. const newUsers = await User.all()
  1420. assert.lengthOf(newUsers.rows, 2)
  1421. })
  1422. test('call after paginate hook when calling paginate method', async (assert) => {
  1423. assert.plan(3)
  1424. class User extends Model {
  1425. }
  1426. User._bootIfNotBooted()
  1427. const fn = async function (instances, pages) {
  1428. assert.deepEqual(pages, { perPage: 20, total: helpers.formatNumber(2), page: 1, lastPage: 1 })
  1429. instances.forEach((instance) => {

Large files files are truncated, but you can click here to view the full file