Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
197 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
'use strict' | ||
|
||
/* | ||
* adonis-lucid | ||
* | ||
* (c) Harminder Virk <virk@adonisjs.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
/** | ||
* This class exposes the validator rules | ||
* related to database | ||
*/ | ||
class ValidatorRules { | ||
constructor (Database) { | ||
this.Database = Database | ||
} | ||
|
||
/** | ||
* Verify whether a field inside the database is unique | ||
* or not. | ||
* | ||
* @method unique | ||
* | ||
* @param {Object} data | ||
* @param {String} field | ||
* @param {String} message | ||
* @param {Array} args | ||
* @param {Function} get | ||
* | ||
* @return {Promise} | ||
* | ||
* @example | ||
* ```js | ||
* email: 'unique:users' // define table | ||
* email: 'unique:users,user_email' // define table + field | ||
* email: 'unique:users,user_email,id:1' // where id !== 1 | ||
* | ||
* // Via new rule method | ||
* email: [rule('unique', ['users', 'user_email', 'id', 1])] | ||
* ``` | ||
*/ | ||
unique (data, field, message, args, get) { | ||
return new Promise((resolve, reject) => { | ||
const value = get(data, field) | ||
|
||
/** | ||
* if value is not defined, then skip the validation | ||
* since required rule should be added for required | ||
* fields | ||
*/ | ||
if (!value) { | ||
return resolve('validation skipped') | ||
} | ||
|
||
/** | ||
* Extracting values of the args array | ||
*/ | ||
const [ table, fieldName, ignoreKey, ignoreValue ] = args | ||
|
||
/** | ||
* Base query to select where key=value | ||
*/ | ||
const query = this.Database.table(table).where(fieldName || field, value) | ||
|
||
/** | ||
* If a ignore key and value is defined, then add a whereNot clause | ||
*/ | ||
if (ignoreKey && ignoreValue) { | ||
query.whereNot(ignoreKey, ignoreValue) | ||
} | ||
|
||
query | ||
.then((rows) => { | ||
/** | ||
* Unique validation fails when a row has been found | ||
*/ | ||
if (rows && rows.length) { | ||
return reject(message) | ||
} | ||
resolve('validation passed') | ||
}) | ||
.catch(reject) | ||
}) | ||
} | ||
} | ||
|
||
module.exports = ValidatorRules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
'use strict' | ||
|
||
/* | ||
* adonis-lucid | ||
* | ||
* (c) Harminder Virk <virk@adonisjs.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
const test = require('japa') | ||
const fs = require('fs-extra') | ||
const _ = require('lodash') | ||
const path = require('path') | ||
const Database = require('../../src/Database') | ||
const Validator = require('../../src/Validator') | ||
const helpers = require('./helpers') | ||
const message = 'unique validation failed' | ||
|
||
test.group('Validator | Unique', (group) => { | ||
group.before(async () => { | ||
await fs.ensureDir(path.join(__dirname, './tmp')) | ||
this.database = new Database(helpers.getConfig()) | ||
await helpers.createTables(this.database) | ||
}) | ||
|
||
group.beforeEach(async () => { | ||
await this.database.truncate('users') | ||
}) | ||
|
||
group.after(async () => { | ||
await helpers.dropTables(this.database) | ||
this.database.close() | ||
try { | ||
await fs.remove(path.join(__dirname, './tmp')) | ||
} catch (error) { | ||
if (process.platform !== 'win32' || error.code !== 'EBUSY') { | ||
throw error | ||
} | ||
} | ||
}).timeout(0) | ||
|
||
test('pass validation when row is found', async (assert) => { | ||
const validator = new Validator(this.database) | ||
const result = await validator.unique({ email: 'foo@bar.com' }, 'email', message, ['users'], _.get) | ||
assert.equal(result, 'validation passed') | ||
}) | ||
|
||
test('skip validation when data does not have field', async (assert) => { | ||
const validator = new Validator(this.database) | ||
const result = await validator.unique({}, 'email', message, ['users'], _.get) | ||
assert.equal(result, 'validation skipped') | ||
}) | ||
|
||
test('throw exception when there is a row', async (assert) => { | ||
assert.plan(1) | ||
const validator = new Validator(this.database) | ||
await this.database.table('users').insert({ username: 'foo' }) | ||
try { | ||
await validator.unique({ username: 'foo' }, 'username', message, ['users'], _.get) | ||
} catch (error) { | ||
assert.equal(error, 'unique validation failed') | ||
} | ||
}) | ||
|
||
test('pass when whereNot key/value pairs are passed', async (assert) => { | ||
const validator = new Validator(this.database) | ||
await this.database.table('users').insert({ username: 'foo' }) | ||
const args = ['users', 'username', 'id', 1] | ||
const result = await validator.unique({ username: 'foo' }, 'username', message, args, _.get) | ||
assert.equal(result, 'validation passed') | ||
}) | ||
}) |