Skip to content

Commit

Permalink
Has many validator should work with simple arrays/objects
Browse files Browse the repository at this point in the history
  • Loading branch information
Offir Golan committed Feb 12, 2016
1 parent 1e9cd57 commit 2bb1416
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 34 deletions.
2 changes: 1 addition & 1 deletion addon/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export var validator = Validator;
*
* export default Ember.Route.extend({
* model() {
* User.create(
* return User.create(
* getOwner(this).ownerInjection(),
* { username: 'John' }
* );
Expand Down
33 changes: 29 additions & 4 deletions app/validators/belongs-to.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@ const {


/**
* Identifies a `belongs-to` relationship in an Ember Data Model. This is used to create a link to the validations object of the child model.
* Identifies a `belongs-to` relationship in an Ember Data Model or Ember.Object.
* This is used to create a link to the validations object of the child model.
*
* _**Note:** Validations must exist on **both** models_
* _**Note:** Validations must exist on **both** models/objects_
*
* ### Ember Model
*
* ```javascript
* // model/users.js
*
* var Validations = buildValidations({
* const Validations = buildValidations({
* details: validator('belongs-to')
* });
*
Expand All @@ -32,7 +35,7 @@ const {
* ```javascript
* // model/user-details.js
*
* var Validations = buildValidations({
* const Validations = buildValidations({
* firstName: validator('presence', true),
* lastName: validator('presence', true)
* });
Expand All @@ -43,6 +46,28 @@ const {
* });
* ```
*
* ### Ember Object
*
* ```javascript
* // model/users.js
*
* import UserDetails from '../user-details';
*
* const Validations = buildValidations({
* details: validator('belongs-to')
* });
*
* export default Ember.Object.extend(Validations, {
* details: null,
*
* init() {
* this._super(...arguments);
* let owner = Ember.getOwner(this);
* this.set('details', UserDetails.create(owner.ownerInjection()));
* }
* });
* ```
*
* From our `user` model, we can now check any validation propery on the `user-details` model.
*
* ```javascript
Expand Down
30 changes: 23 additions & 7 deletions app/validators/has-many.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,39 @@ import Base from 'ember-cp-validations/validators/base';

const {
canInvoke,
A: emberArray
} = Ember;

/**
* Identifies a `has-many` relationship in an Ember Data Model. This is used to create a validation collection of the `has-many` validations.
* Identifies a `has-many` relationship in an Ember Data Model or Ember.Object.
* This is used to create a validation collection of the `has-many` validations.
*
* _**Note:** Validations must exist on **all** models_
* _**Note:** Validations must exist on **all** models/objects_
*
* ### Ember Models
*
* ```javascript
* // model/users.js
*
* var Validations = buildValidations({
* const Validations = buildValidations({
* friends: validator('has-many')
* });
*
* export default DS.Model.extend(Validations, {
* 'friends': DS.hasMany('user')
* friends: DS.hasMany('user')
* });
* ```
*
* ### Ember Objects
*
* ```javascript
* // model/users.js
*
* const Validations = buildValidations({
* friends: validator('has-many')
* });
*
* export default Ember.Object.extend(Validations, {
* friends: null
* });
* ```
*
Expand All @@ -44,10 +60,10 @@ export default Base.extend({
if (value) {
if (canInvoke(value, 'then')) {
return value.then((models) => {
return emberArray(models).getEach('validations');
return models.map(m => m.get('validations'));
});
} else {
return value.toArray().getEach('validations');
return value.map(m => m.get('validations'));
}
}

Expand Down
2 changes: 1 addition & 1 deletion tests/integration/validations/factory-general-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import LengthValidator from 'dummy/validators/length';
import { validator, buildValidations } from 'ember-cp-validations';
import { moduleFor, test } from 'ember-qunit';

var Validators = {
const Validators = {
presence(value, options, model, attr) {
var isValid = !Ember.isNone(value);
if (Ember.isNone(value)) {
Expand Down
80 changes: 59 additions & 21 deletions tests/integration/validations/model-relationships-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import PresenceValidator from 'dummy/validators/presence';
import { validator, buildValidations } from 'ember-cp-validations';
import { moduleFor, test } from 'ember-qunit';

var Validators = {
const Validators = {
presence(value, options, model, attr) {
var isValid = !Ember.isNone(value);
if (Ember.isNone(value)) {
Expand All @@ -23,6 +23,14 @@ var Validations = buildValidations({
lastName: validator(Validators.presence)
});

const BelongsToValidations = buildValidations({
friend: validator('belongs-to')
});

const HasManyValidations = buildValidations({
friends: validator('has-many')
});

moduleFor('foo', 'Integration | Validations | Model Relationships', {
integration: true,
beforeEach() {
Expand All @@ -33,10 +41,6 @@ moduleFor('foo', 'Integration | Validations | Model Relationships', {
test("belong to validation - no cycle", function(assert) {
this.register('validator:belongs-to', BelongsToValidator);

var BelongsToValidations = buildValidations({
friend: validator('belongs-to')
});

var user2 = setupObject(this, Ember.Object.extend(Validations), {
firstName: 'John'
});
Expand Down Expand Up @@ -64,10 +68,6 @@ test("belong to validation - no cycle", function(assert) {
test("belong to validation - with cycle", function(assert) {
this.register('validator:belongs-to', BelongsToValidator);

var BelongsToValidations = buildValidations({
friend: validator('belongs-to')
});

var user = setupObject(this, Ember.Object.extend(BelongsToValidations));
user.set('friend', user);

Expand All @@ -87,13 +87,59 @@ test("belong to validation - with cycle", function(assert) {

});

test("has-many relationship is async", function(assert) {
this.register('validator:has-many', HasManyValidator);
test("has-many relationship is sync", function(assert) {
this.register('validator:belongs-to', BelongsToValidator);

var friend = setupObject(this, Ember.Object.extend(Validations), {
firstName: 'John'
});

var user = setupObject(this, Ember.Object.extend(HasManyValidations), {
friends: [friend]
});

const {
validations,
model
} = user.get('validations').validateSync();

assert.equal(model, user, 'expected model to be the correct model');
assert.deepEqual(validations.get('content').getEach('attribute').sort(), ['friends'].sort());

let friends = validations.get('content').findBy('attribute', 'friends');

assert.equal(friends.get('isValid'), false);
assert.equal(friends.get('message'), 'lastName should be present');
});

test("has-many relationship is sync with proxy", function(assert) {
this.register('validator:belongs-to', BelongsToValidator);

var HasManyValidations = buildValidations({
friends: validator('has-many')
var friend = setupObject(this, Ember.Object.extend(Validations), {
firstName: 'John'
});

var user = setupObject(this, Ember.Object.extend(HasManyValidations), {
friends: Ember.ArrayProxy.create({ content: Ember.A([friend]) })
});

const {
validations,
model
} = user.get('validations').validateSync();

assert.equal(model, user, 'expected model to be the correct model');
assert.deepEqual(validations.get('content').getEach('attribute').sort(), ['friends'].sort());

let friends = validations.get('content').findBy('attribute', 'friends');

assert.equal(friends.get('isValid'), false);
assert.equal(friends.get('message'), 'lastName should be present');
});

test("has-many relationship is async", function(assert) {
this.register('validator:has-many', HasManyValidator);

var friend = setupObject(this, Ember.Object.extend(Validations), {
firstName: 'Offir'
});
Expand Down Expand Up @@ -126,10 +172,6 @@ test("has-many relationship is async", function(assert) {
test("belongs-to relationship is async", function(assert) {
this.register('validator:belongs-to', BelongsToValidator);

var BelongsToValidations = buildValidations({
friend: validator('belongs-to')
});

var friend = setupObject(this, Ember.Object.extend(Validations), {
firstName: 'Offir'
});
Expand Down Expand Up @@ -163,10 +205,6 @@ test("belongs-to relationship is async", function(assert) {
test("belongs-to relationship returns undefined", function(assert) {
this.register('validator:belongs-to', BelongsToValidator);

var BelongsToValidations = buildValidations({
friend: validator('belongs-to')
});

var user = setupObject(this, Ember.Object.extend(BelongsToValidations), {
friend: new Ember.RSVP.Promise((resolve, reject) => {
resolve({}); // validations object will be undefined
Expand Down

0 comments on commit 2bb1416

Please sign in to comment.