test('get all the rows when batch is zero', async (assert) => {
    const migration = new Migration(new Config(), ioc.use('Database'))
    await migration._makeMigrationsTable()
    await ioc.use('Database').table('adonis_schema').insert([
      {
        batch: 1,
        name: 'foo'
      },
      {
        batch: 2,
        name: 'bar'
      },
      {
        batch: 3,
        name: 'joe'
      },
      {
        batch: 3,
        name: 'baz'
      }
    ])

    const rows = await migration._getAfterBatch(0)
    assert.lengthOf(rows, 4)
    assert.deepEqual(rows, ['bar', 'baz', 'foo', 'joe'])
  })
  group.before(async () => {
    ioc.bind('Adonis/Src/Config', () => {
      const config = new Config()
      config.set('database', {
        connection: 'testing',
        testing: helpers.getConfig()
      })
      return config
    })

    ioc.bind('Adonis/Src/Helpers', () => {
      return new Helpers(path.join(__dirname))
    })

    await fs.ensureDir(path.join(__dirname, 'database/migrations'))

    await registrar
      .providers([
        path.join(__dirname, '../../providers/LucidProvider'),
        path.join(__dirname, '../../providers/MigrationsProvider')
      ]).registerAndBoot()

    await fs.ensureDir(path.join(__dirname, '../unit/tmp'))
    await helpers.createTables(ioc.use('Database'))
    setupResolver()
  })
  test('bind custom callback for eagerload query', async (assert) => {
    class Car extends Model {
    }

    ioc.fake('App/Models/Car', () => Car)

    class User extends Model {
      cars () {
        return this.hasMany('App/Models/Car')
      }
    }

    Car._bootIfNotBooted()
    User._bootIfNotBooted()

    let carQuery = null
    Car.onQuery((query) => (carQuery = query))

    await ioc.use('Database').table('users').insert({ username: '******' })

    await User.query().with('cars', (builder) => {
      builder.eagerLoadQuery((query, fk, values) => {
        query.whereIn(fk, values).where('model', 'BMW')
      })
    }).fetch()

    assert.equal(carQuery.sql, helpers.formatQuery('select * from "cars" where "user_id" in (?) and "model" = ?'))
    assert.deepEqual(carQuery.bindings, helpers.formatBindings([1, 'BMW']))
  })
  test('throw schema file exceptions and cleanup', async (assert) => {
    assert.plan(3)
    const migration = new Migration(new Config(), ioc.use('Database'))

    class UserSchema extends Schema {
      up () {
        this.create('users', (table) => {
          table.increments()
          table.string('username')
        })
      }

      down () {
        this.drop('users')
      }
    }

    try {
      await migration.up({ '2017-08-10': UserSchema })
    } catch ({ message }) {
      assert.include(message, 'already exists')
      const hasLockTable = await ioc.use('Database').schema.hasTable('adonis_schema_lock')
      const migrated = await ioc.use('Database').table('adonis_schema')
      assert.lengthOf(migrated, 0)
      assert.isFalse(hasLockTable)
    }
  })
  test('save executed schemas to the migrations table', async (assert) => {
    const migration = new Migration(new Config(), ioc.use('Database'))

    class UserSchema extends Schema {
      up () {
        this.create('schema_users', (table) => {
          table.increments()
          table.string('username')
        })

        this.create('schema_profiles', (table) => {
          table.increments()
          table.integer('user_id').unsigned().references('schema_users.id')
          table.string('profile_name')
        })
      }
    }

    const result = await migration.up({ '2017-07-20': UserSchema })
    const schemas = await migration.db.table('adonis_schema')
    assert.lengthOf(schemas, 1)
    assert.equal(schemas[0].name, '2017-07-20')
    assert.equal(schemas[0].batch, 1)
    assert.deepEqual(result, { migrated: ['2017-07-20'], status: 'completed' })

    if (process.env.DB !== 'sqlite') {
      await ioc.use('Database').schema.table('schema_profiles', (table) => {
        table.dropForeign('user_id')
      })
    }
  })
  test('get first instance of related model via IoC container', async (assert) => {
    class Car extends Model {
    }

    ioc.fake('App/Models/Car', () => Car)

    class User extends Model {
      cars () {
        return this.hasMany('App/Models/Car')
      }
    }

    Car._bootIfNotBooted()
    User._bootIfNotBooted()

    let carQuery = null
    Car.onQuery((query) => (carQuery = query))

    await ioc.use('Database').table('users').insert({ username: '******' })
    await ioc.use('Database').table('cars').insert([
      { user_id: 1, name: 'merc', model: '1990' },
      { user_id: 1, name: 'audi', model: '2001' }
    ])

    const user = await User.find(1)
    const car = await user.cars().first()
    assert.instanceOf(car, Car)
    assert.equal(car.name, 'merc')
    assert.equal(carQuery.sql, helpers.formatQuery('select * from "cars" where "user_id" = ? limit ?'))
    assert.deepEqual(carQuery.bindings, helpers.formatBindings([1, 1]))
  })
  test('add constraints when eagerloading', async (assert) => {
    class Car extends Model {
    }

    class User extends Model {
      cars () {
        return this.hasMany(Car)
      }
    }

    Car._bootIfNotBooted()
    User._bootIfNotBooted()

    let carQuery = null
    Car.onQuery((query) => (carQuery = query))

    await ioc.use('Database').table('users').insert({ username: '******' })
    await ioc.use('Database').table('cars').insert([
      { user_id: 1, name: 'merc', model: '1990' },
      { user_id: 1, name: 'audi', model: '2001' }
    ])

    const users = await User.query().with('cars', (builder) => {
      builder.where('model', '>', '2000')
    }).fetch()
    const user = users.first()
    assert.equal(user.getRelated('cars').size(), 1)
    assert.equal(user.getRelated('cars').rows[0].name, 'audi')
    assert.equal(carQuery.sql, helpers.formatQuery('select * from "cars" where "model" > ? and "user_id" in (?)'))
    assert.deepEqual(carQuery.bindings, helpers.formatBindings(['2000', 1]))
  })
  test('eagerload relation', async (assert) => {
    class Car extends Model {
    }

    class User extends Model {
      cars () {
        return this.hasMany(Car)
      }
    }

    Car._bootIfNotBooted()
    User._bootIfNotBooted()

    let carQuery = null
    Car.onQuery((query) => (carQuery = query))

    await ioc.use('Database').table('users').insert({ username: '******' })
    await ioc.use('Database').table('cars').insert([
      { user_id: 1, name: 'merc', model: '1990' },
      { user_id: 1, name: 'audi', model: '2001' }
    ])

    const user = await User.query().with('cars').first()
    assert.instanceOf(user.getRelated('cars'), VanillaSerializer)
    assert.equal(user.getRelated('cars').size(), 2)
    assert.deepEqual(user.getRelated('cars').rows.map((car) => car.$parent), ['User', 'User'])
    assert.equal(carQuery.sql, helpers.formatQuery('select * from "cars" where "user_id" = ?'))
    assert.deepEqual(carQuery.bindings, helpers.formatBindings([1]))
  })
  test('execute schema actions in sequence', async (assert) => {
    const migration = new Migration(new Config(), ioc.use('Database'))

    class UserSchema extends Schema {
      up () {
        this.create('schema_users', (table) => {
          table.increments()
          table.string('username')
        })

        this.create('schema_profiles', (table) => {
          table.increments()
          table.integer('user_id').unsigned().references('schema_users.id')
          table.string('profile_name')
        })
      }
    }

    await migration.up({ '2017-07-20': UserSchema })
    await migration.db.schema.hasTable('schema_users')
    await migration.db.schema.hasTable('schema_profiles')

    if (process.env.DB !== 'sqlite') {
      await ioc.use('Database').schema.table('schema_profiles', (table) => {
        table.dropForeign('user_id')
      })
    }
  })
  test('add orWhereHas clause', async (assert) => {
    class Car extends Model {
    }

    class User extends Model {
      cars () {
        return this.hasMany(Car)
      }
    }

    Car._bootIfNotBooted()
    User._bootIfNotBooted()

    let userQuery = null
    User.onQuery((query) => (userQuery = query))

    await ioc.use('Database').table('users').insert([{ username: '******' }, { username: '******' }])
    await ioc.use('Database').table('cars').insert([
      { user_id: 1, name: 'mercedes', model: '1990' },
      { user_id: 1, name: 'audi', model: '2001' },
      { user_id: 2, name: 'audi', model: '2001' }
    ])

    const users = await User.query().whereHas('cars', (builder) => {
      return builder.where('name', 'audi')
    }, '>', 1).orWhereHas('cars', (builder) => builder.where('name', 'mercedes')).fetch()
    assert.equal(users.size(), 1)
    assert.equal(userQuery.sql, helpers.formatQuery('select * from "users" where (select count(*) from "cars" where "name" = ? and users.id = cars.user_id) > ? or exists (select * from "cars" where "name" = ? and users.id = cars.user_id)'))
  })
  test('define minimum count via has', async (assert) => {
    class Car extends Model {
    }

    class User extends Model {
      cars () {
        return this.hasMany(Car)
      }
    }

    Car._bootIfNotBooted()
    User._bootIfNotBooted()

    let userQuery = null
    User.onQuery((query) => (userQuery = query))

    await ioc.use('Database').table('users').insert([{ username: '******' }, { username: '******' }])
    await ioc.use('Database').table('cars').insert([
      { user_id: 1, name: 'mercedes', model: '1990' },
      { user_id: 1, name: 'audi', model: '2001' },
      { user_id: 2, name: 'audi', model: '2001' }
    ])

    const users = await User.query().has('cars', '>=', 2).fetch()
    assert.equal(users.size(), 1)
    assert.equal(userQuery.sql, helpers.formatQuery('select * from "users" where (select count(*) from "cars" where users.id = cars.user_id) >= ?'))
  })
  test('convert paginated records to json', async (assert) => {
    class Car extends Model {
    }

    class User extends Model {
      cars () {
        return this.hasMany(Car)
      }
    }

    Car._bootIfNotBooted()
    User._bootIfNotBooted()

    await ioc.use('Database').table('users').insert([{ username: '******' }, { username: '******' }])
    await ioc.use('Database').table('cars').insert([
      { user_id: 1, name: 'mercedes', model: '1990' },
      { user_id: 1, name: 'audi', model: '2001' },
      { user_id: 2, name: 'audi', model: '2001' }
    ])

    const users = await User.query().with('cars').paginate()
    const json = users.toJSON()
    assert.deepEqual(json.total, helpers.formatNumber(2))
    assert.deepEqual(json.perPage, 20)
    assert.deepEqual(json.page, 1)
    assert.deepEqual(json.lastPage, 1)
    assert.isArray(json.data)
    assert.isArray(json.data[0].cars)
    assert.isArray(json.data[1].cars)
  })
  test('get instance of has many when calling to relation method', async (assert) => {
    class Car extends Model {
    }

    class User extends Model {
      cars () {
        return this.hasMany(Car)
      }
    }

    Car._bootIfNotBooted()
    User._bootIfNotBooted()

    let carQuery = null
    Car.onQuery((query) => (carQuery = query))

    await ioc.use('Database').table('users').insert({ username: '******' })
    await ioc.use('Database').table('cars').insert([
      { user_id: 1, name: 'merc', model: '1990' },
      { user_id: 1, name: 'audi', model: '2001' }
    ])

    const user = await User.find(1)
    const cars = await user.cars().fetch()
    assert.instanceOf(cars, VanillaSerializer)
    assert.equal(cars.size(), 2)
    assert.equal(carQuery.sql, helpers.formatQuery('select * from "cars" where "user_id" = ?'))
    assert.deepEqual(carQuery.bindings, helpers.formatBindings([1]))
  })
  test('get relation count', async (assert) => {
    class Car extends Model {
    }

    class User extends Model {
      cars () {
        return this.hasMany(Car)
      }
    }

    Car._bootIfNotBooted()
    User._bootIfNotBooted()

    let userQuery = null
    User.onQuery((query) => (userQuery = query))

    await ioc.use('Database').table('users').insert({ username: '******' })
    await ioc.use('Database').table('cars').insert([
      { user_id: 1, name: 'mercedes', model: '1990' },
      { user_id: 1, name: 'audi', model: '2001' }
    ])

    const user = await User.query().withCount('cars').first()
    assert.deepEqual(user.$sideLoaded, { cars_count: helpers.formatNumber(2) })
    assert.equal(userQuery.sql, helpers.formatQuery('select *, (select count(*) from "cars" where users.id = cars.user_id) as "cars_count" from "users" limit ?'))
  })
  test('selected related rows', async (assert) => {
    class Post extends Model {
    }

    class Section extends Model {
      posts () {
        return this.belongsToMany(Post)
      }
    }

    class Category extends Model {
      posts () {
        return this.manyThrough(Section, 'posts')
      }
    }

    Category._bootIfNotBooted()
    Section._bootIfNotBooted()
    Post._bootIfNotBooted()

    await ioc.use('Database').table('categories').insert([{ name: 'Sql' }, { name: 'Javascript' }])
    await ioc.use('Database').table('sections').insert([
      { name: 'Loops', category_id: 2 },
      { name: 'Conditionals', category_id: 2 }
    ])
    await ioc.use('Database').table('posts').insert({ title: 'For each loop' })
    await ioc.use('Database').table('post_section').insert({ post_id: 1, section_id: 1 })

    const js = await Category.find(2)
    const posts = await js.posts().fetch()
    assert.equal(posts.size(), 1)
    assert.equal(posts.rows[0].title, 'For each loop')
  })
  test('paginate only filtered parent rows', async (assert) => {
    class Post extends Model {
    }

    class User extends Model {
      posts () {
        return this.hasMany(Post)
      }
    }

    class Country extends Model {
      posts () {
        return this.manyThrough(User, 'posts')
      }
    }

    User._bootIfNotBooted()
    Country._bootIfNotBooted()
    Post._bootIfNotBooted()

    let countryQuery = null
    Country.onQuery((query) => (countryQuery = query))

    await ioc.use('Database').table('countries').insert([{ name: 'India', id: 2 }, { name: 'UK', id: 3 }])
    await ioc.use('Database').table('users').insert([{ country_id: 2, id: 20, username: '******' }, { country_id: 3, username: '******' }])
    await ioc.use('Database').table('posts').insert({ user_id: 20, title: 'Adonis 101' })

    const countries = await Country.query().has('posts').paginate()
    assert.equal(countries.size(), 1)
    assert.equal(countries.first().name, 'India')
    assert.equal(countryQuery.sql, helpers.formatQuery('select * from "countries" where exists (select * from "posts" inner join "users" on "users"."id" = "posts"."user_id" where countries.id = users.country_id) limit ?'))
  })
  test('eagerload related rows', async (assert) => {
    class Post extends Model {
    }

    class User extends Model {
      posts () {
        return this.hasMany(Post)
      }
    }

    class Country extends Model {
      posts () {
        return this.manyThrough(User, 'posts')
      }
    }

    User._bootIfNotBooted()
    Country._bootIfNotBooted()
    Post._bootIfNotBooted()

    await ioc.use('Database').table('countries').insert({ name: 'India', id: 2 })
    await ioc.use('Database').table('users').insert({ country_id: 2, id: 20, username: '******' })
    await ioc.use('Database').table('posts').insert({ user_id: 20, title: 'Adonis 101' })

    const countries = await Country.query().with('posts', (builder) => {
      builder.selectThrough('id')
    }).fetch()

    assert.equal(countries.size(), 1)
    const country = countries.first()

    assert.instanceOf(country.getRelated('posts'), VanillaSerializer)
    assert.equal(country.getRelated('posts').size(), 1)
    assert.equal(country.getRelated('posts').toJSON()[0].__meta__.through_country_id, country.id)
  })
Example #18
0
 test('add new row for a given batch', async (assert) => {
   const migration = new Migration(new Config(), ioc.use('Database'))
   await migration._makeMigrationsTable()
   await migration._addForBatch('foo', 1)
   const migrations = await ioc.use('Database').table('adonis_schema')
   assert.equal(migrations[0].name, 'foo')
   assert.equal(migrations[0].batch, 1)
 })
Example #19
0
 test('add lock to lock table', async (assert) => {
   const migration = new Migration(new Config(), ioc.use('Database'))
   await migration._makeMigrationsTable()
   await migration._makeLockTable()
   await migration._addLock()
   const lock = await ioc.use('Database').table('adonis_schema_lock')
   assert.deepEqual(lock, [{ id: 1, is_locked: helpers.formatBoolean(true) }])
 })
 group.after(async () => {
   await helpers.dropTables(ioc.use('Adonis/Src/Database'))
   ioc.use('Database').close()
   try {
     await fs.remove(path.join(__dirname, './tmp'))
   } catch (error) {
     if (process.platform !== 'win32' || error.code !== 'EBUSY') {
       throw error
     }
   }
 }).timeout(0)
Example #21
0
 test('get diff of schema not executed yet', async (assert) => {
   const migration = new Migration(new Config(), ioc.use('Database'))
   await migration._makeMigrationsTable()
   await ioc.use('Database').table('adonis_schema').insert([
     {
       batch: 1,
       name: '2017-30-20'
     }
   ])
   const diff = await migration._getDiff(['2017-30-20', '2017-30-19'])
   assert.deepEqual(diff, ['2017-30-19'])
 })
Example #22
0
  test('remove a given row', async (assert) => {
    const migration = new Migration(new Config(), ioc.use('Database'))
    await migration._makeMigrationsTable()

    await migration._addForBatch('foo', 1)
    let migrations = await ioc.use('Database').table('adonis_schema')
    assert.equal(migrations[0].name, 'foo')
    assert.equal(migrations[0].batch, 1)

    await migration._remove('foo')
    migrations = await ioc.use('Database').table('adonis_schema')
    assert.lengthOf(migrations, 0)
  })
  group.after(async () => {
    await helpers.dropTables(ioc.use('Database'))
    await ioc.use('Database').schema.dropTableIfExists('adonis_schema')
    ioc.use('Database').close()

    try {
      await fs.remove(path.join(__dirname, '../unit/tmp'))
      await fs.remove(path.join(__dirname, 'database'))
    } catch (error) {
      if (process.platform !== 'win32' || error.code !== 'EBUSY') {
        throw error
      }
    }
  }).timeout(0)
  group.before(async () => {
    ioc.singleton('Adonis/Src/Database', function () {
      const config = new Config()
      config.set('database', {
        connection: 'testing',
        testing: helpers.getConfig()
      })
      return new DatabaseManager(config)
    })
    ioc.alias('Adonis/Src/Database', 'Database')

    await fs.ensureDir(path.join(__dirname, './tmp'))
    await helpers.createTables(ioc.use('Adonis/Src/Database'))
  })
  test('add constraints when eager loading', async (assert) => {
    class Post extends Model {
    }

    class Section extends Model {
      posts () {
        return this.belongsToMany(Post)
      }
    }

    class Category extends Model {
      posts () {
        return this.manyThrough(Section, 'posts')
      }
    }

    Category._bootIfNotBooted()
    Section._bootIfNotBooted()
    Post._bootIfNotBooted()

    let postsQuery = null
    Post.onQuery((query) => (postsQuery = query))

    await ioc.use('Database').table('categories').insert([{ name: 'Sql' }, { name: 'Javascript' }])

    await ioc.use('Database').table('sections').insert([
      { name: 'Loops', category_id: 2, is_active: true },
      { name: 'Conditionals', category_id: 2, is_active: true },
      { name: 'Transactions', category_id: 1 }
    ])

    await ioc.use('Database').table('posts').insert([{ title: 'For each loop' }, { title: 'Transactions 101' }])

    await ioc.use('Database').table('post_section').insert([
      { post_id: 1, section_id: 1 },
      { post_id: 2, section_id: 3 }
    ])

    const categories = await Category.query().with('posts', (builder) => {
      builder.where('sections.is_active', true)
    }).orderBy('id', 'asc').fetch()

    assert.equal(postsQuery.sql, helpers.formatQuery('select "posts".*, "sections"."category_id" as "through_category_id" from "posts" inner join "post_section" on "posts"."id" = "post_section"."post_id" inner join "sections" on "sections"."id" = "post_section"."section_id" where "sections"."is_active" = ? and "sections"."category_id" in (?, ?)'))
    assert.instanceOf(categories, VanillaSerializer)
    assert.equal(categories.size(), 2)
    assert.equal(categories.last().getRelated('posts').size(), 1)
    assert.equal(categories.last().getRelated('posts').toJSON()[0].title, 'For each loop')
    assert.equal(categories.first().getRelated('posts').size(), 0)
  })
  test('add constraints to delete query', async (assert) => {
    class Car extends Model {
    }

    class User extends Model {
      cars () {
        return this.hasMany(Car)
      }
    }

    Car._bootIfNotBooted()
    User._bootIfNotBooted()
    let carQuery = null
    Car.onQuery((query) => (carQuery = query))

    const user = new User()
    user.username = '******'

    await user.cars().createMany([{ name: 'mercedes', model: '1992' }, { name: 'ferrari', model: '2002' }])
    await user.cars().where('name', 'mercedes').delete()
    const cars = await ioc.use('Database').table('cars')
    assert.lengthOf(cars, 1)
    assert.equal(cars[0].name, 'ferrari')
    assert.equal(carQuery.sql, helpers.formatQuery('delete from "cars" where "name" = ? and "user_id" = ?'))
  })
Example #27
0
  test('return encrypted tokens via database serializer', async (assert) => {
    const User = helpers.getUserModel()

    const config = {
      primaryKey: 'id',
      table: 'users',
      tokensTable: 'tokens',
      uid: 'email',
      foreignKey: 'user_id',
      password: '******',
      options: {
        secret: SECRET
      }
    }

    const database = new DatabaseSerializer(ioc.use('Hash'))
    database.setConfig(config)

    const user = await User.create({ email: '*****@*****.**', password: '******' })

    const jwt = new Jwt(Encryption)
    jwt.setOptions(config, database)
    const payload = await jwt.withRefreshToken().generate(user)

    const tokensList = await jwt.listTokensForUser({ id: 1 }, 'jwt_refresh_token')
    assert.deepEqual(tokensList[0].token, payload.refreshToken)
  })
Example #28
0
  test('login as client', async (assert) => {
    assert.plan(2)

    const config = {
      primaryKey: 'id',
      table: 'users',
      tokensTable: 'tokens',
      uid: 'email',
      foreignKey: 'user_id',
      password: '******',
      options: {
        secret: SECRET
      }
    }

    const database = new DatabaseSerializer(ioc.use('Hash'))
    database.setConfig(config)

    const jwt = new Jwt(Encryption)
    jwt.setOptions(config, database)

    const headerFn = function (key, value) {
      assert.equal(key, 'authorization')
      assert.include(value, 'Bearer')
    }

    await jwt.clientLogin(headerFn, null, { id: 1 })
  })
Example #29
0
  test('revoke tokens for a given user', async (assert) => {
    const User = helpers.getUserModel()

    const config = {
      model: User,
      uid: 'email',
      password: '******',
      options: {
        secret: SECRET
      }
    }

    const lucid = new LucidSerializer(ioc.use('Hash'))
    lucid.setConfig(config)

    const user = await User.create({ email: '*****@*****.**', password: '******' })
    await user.tokens().create({ type: 'jwt_refresh_token', token: '22', is_revoked: false })

    const jwt = new Jwt(Encryption)
    jwt.setOptions(config, lucid)
    await jwt.revokeTokensForUser(user, ['22'])

    const token = await user.tokens().first()
    assert.equal(token.is_revoked, true)
    assert.equal(token.token, '22')
  })
  test('rollback migrations by requiring all schema files', async (assert) => {
    ace.addCommand(MigrationRun)
    ace.addCommand(MigrationRollback)

    await fs.writeFile(path.join(__dirname, 'database/migrations/User.js'), `
      const Schema = use('Schema')
      class User extends Schema {
        up () {
          this.createTable('schema_users', (table) => {
            table.increments()
            table.string('username')
          })
        }

        down () {
          this.drop('schema_users')
        }
      }

      module.exports = User
    `)

    await ace.call('migration:run')
    const result = await ace.call('migration:rollback')
    assert.deepEqual(result, { migrated: ['User'], status: 'completed', queries: undefined })
    const migrations = await ioc.use('Database').table('adonis_schema')
    assert.lengthOf(migrations, 0)
  })