extjs-gpl
Version:
GPL licensed version of Sencha Ext JS
382 lines (338 loc) • 12 kB
JavaScript
// HasOne is not a real class, but is an alternate way of declaring OneToOne.
// The purpose of these tests is to check that they set everything up correctly,
// functionality tested in OneToOne.
describe("Ext.data.schema.HasOne", function() {
var Key, User, Avatar;
function defineUser(options) {
var cfg = {
extend: 'Ext.data.Model',
fields: ['id', 'name']
};
if (options) {
cfg = Ext.apply(cfg, options);
}
User = Ext.define('spec.User', cfg);
}
function defineKey(options) {
var cfg = {
extend: 'Ext.data.Model',
fields: ['id', 'salt']
};
if (options) {
cfg = Ext.apply(cfg, options);
}
Key = Ext.define('spec.Key', cfg);
}
function defineAvatar(options) {
var cfg = {
extend: 'Ext.data.Model',
fields: ['id', 'src']
};
if (options) {
cfg = Ext.apply(cfg, options);
}
Avatar = Ext.define('spec.Avatar', cfg);
}
beforeEach(function() {
MockAjaxManager.addMethods();
Ext.data.Model.schema.setNamespace('spec');
});
afterEach(function() {
if (Avatar) {
Ext.undefine('spec.Avatar');
Avatar = null;
}
if (Key) {
Ext.undefine('spec.Key');
}
if (User) {
Ext.undefine('spec.User');
User = null;
}
Ext.data.Model.schema.clear(true);
MockAjaxManager.removeMethods();
});
function expectFn(name, o) {
o = o || User;
expect(Ext.isFunction(o.prototype[name])).toBe(true);
}
function expectNotFn(name, o) {
o = o || User;
expect(Ext.isFunction(o.prototype[name])).toBe(false);
}
describe("declarations", function() {
describe("Configuration of model only", function() {
it("should accept a string", function() {
defineKey();
defineUser({
hasOne: 'Key'
});
expectFn('getKey');
expectFn('setKey');
expectFn('getUser', Key);
expectFn('setUser', Key);
});
it("should accept an array of strings", function() {
defineKey();
defineAvatar();
defineUser({
hasOne: ['Key', 'Avatar']
});
expectFn('getKey');
expectFn('setKey');
expectFn('getUser', Key);
expectFn('setUser', Key);
expectFn('getUser', Avatar);
expectFn('setUser', Avatar);
});
it("should accept an object", function() {
defineKey();
defineUser({
hasOne: {
type: 'Key'
}
});
expectFn('getKey');
expectFn('setKey');
expectFn('getUser', Key);
expectFn('setUser', Key);
});
it("should accept an array of objects", function() {
defineKey();
defineAvatar();
defineUser({
hasOne: [{
type: 'Key'
}, {
type: 'Avatar'
}]
});
expectFn('getKey');
expectFn('setKey');
expectFn('getUser', Key);
expectFn('setUser', Key);
expectFn('getUser', Avatar);
expectFn('setUser', Avatar);
});
});
describe("extra configurations", function() {
describe("role", function() {
it("should add the specified role", function() {
defineKey();
defineUser({
hasOne: {
type: 'Key',
role: 'authenticator'
}
});
expectFn('getAuthenticator');
expectFn('setAuthenticator');
expectFn('getAuthenticatorUser', Key);
expectFn('setAuthenticatorUser', Key);
});
});
describe("getterName", function() {
it("should allow a custom getterName", function() {
defineKey();
defineUser({
hasOne: {
type: 'Key',
getterName: 'getAuthenticator'
}
});
expectFn('getAuthenticator');
expectFn('setKey');
expectFn('getUser', Key);
expectFn('setUser', Key);
});
});
describe("setterName", function() {
it("should allow a custom setterName", function() {
defineKey();
defineUser({
hasOne: {
type: 'Key',
setterName: 'setAuthenticator'
}
});
expectFn('getKey');
expectFn('setAuthenticator');
expectFn('getUser', Key);
expectFn('setUser', Key);
});
});
describe("inverse", function() {
it("should be able to declare inverse configs", function() {
defineKey();
defineUser({
hasOne: {
type: 'Key',
inverse: {
role: 'owner'
}
}
});
expectFn('getKey');
expectFn('setKey');
expectFn('getOwner', Key);
expectFn('setOwner', Key);
});
});
describe("child", function() {
it("should be able to set child", function() {
defineKey();
defineUser({
hasOne: {
child: 'Key'
}
});
expectFn('getKey');
expectFn('setKey');
expectFn('getUser', Key);
expectFn('setUser', Key);
});
});
});
describe("timing", function() {
describe("when the owner class already exists", function() {
it("should setup methods on both classes", function() {
defineKey();
defineUser({
hasOne: 'Key'
});
expectFn('getKey');
expectFn('setKey');
expectFn('getUser', Key);
expectFn('setUser', Key);
});
});
describe("when the owner class does not exist", function() {
it("should setup methods on both classes when the owner arrives", function() {
defineUser({
hasOne: 'Key'
});
expectNotFn('getKey');
expectNotFn('setKey');
defineKey();
expectFn('getKey');
expectFn('setKey');
expectFn('getUser', Key);
expectFn('setUser', Key);
});
});
});
});
describe("instance related configs", function() {
describe("associationKey", function() {
it("should apply the associationKey for loading nested data", function() {
defineKey();
defineUser({
hasOne: {
type: 'Key',
associationKey: 'authenticator'
}
});
var user = User.load(1);
Ext.Ajax.mockCompleteWithData({
id: 1,
key: {
id: 101
}
});
// Key is discussion, should be nothing
expect(user.getKey()).toBeNull();
user = User.load(2);
Ext.Ajax.mockCompleteWithData({
id: 2,
authenticator: {
id: 101
}
});
expect(user.getKey().id).toBe(101);
});
});
describe("child", function() {
it("should drop the child records when the owner is dropped", function() {
defineKey();
defineUser({
hasOne: {
child: 'Key'
}
});
var user = new User({id: 1}),
key = new Key({id: 101});
user.setKey(key);
user.drop();
expect(key.dropped).toBe(true);
});
});
});
describe("legacy functionality", function() {
describe("foreignKey", function() {
it("should recognize a default foreignKey as entity_id", function() {
defineKey();
defineUser({
fields: ['id', 'name', 'key_id'],
hasOne: 'Key'
});
var user = new User({id: 1}),
key = new Key({id: 101});
user.setKey(key);
expect(user.get('key_id')).toBe(101);
});
it("should recognize a custom foreignKey as entity_id", function() {
defineKey();
defineUser({
fields: ['id', 'name', 'customField'],
hasOne: {
type: 'Key',
foreignKey: 'customField'
}
});
var user = new User({id: 1}),
key = new Key({id: 101});
user.setKey(key);
expect(user.get('customField')).toBe(101);
});
});
it("should use the name parameter as the role", function() {
defineKey();
defineUser({
hasOne: {
model: 'Key',
name: 'authenticator'
}
});
expectFn('getAuthenticator');
expectFn('setAuthenticator');
expectFn('getAuthenticatorUser', Key);
expectFn('setAuthenticatorUser', Key);
});
it("should use the associatedName parameter as the role", function() {
defineKey();
defineUser({
hasOne: {
model: 'Key',
associatedName: 'authenticator'
}
});
expectFn('getAuthenticator');
expectFn('setAuthenticator');
expectFn('getAuthenticatorUser', Key);
expectFn('setAuthenticatorUser', Key);
});
it("should respect a role config when using model", function() {
defineKey();
defineUser({
hasOne: {
model: 'Key',
role: 'authenticator'
}
});
expectFn('getAuthenticator');
expectFn('setAuthenticator');
expectFn('getAuthenticatorUser', Key);
expectFn('setAuthenticatorUser', Key);
});
});
});