extjs-gpl
Version:
GPL licensed version of Sencha Ext JS
373 lines (327 loc) • 11.7 kB
JavaScript
// BelongsTo is not a real class, but is an alternate way of declaring ManyToOne.
// The purpose of these tests is to check that they set everything up correctly,
// functionality tested in ManyToOne.
describe("Ext.data.schema.BelongsTo", function() {
var Thread, Post, User;
function defineThread(options) {
var cfg = {
extend: 'Ext.data.Model',
fields: ['id', 'title']
};
if (options) {
cfg = Ext.apply(cfg, options);
}
Thread = Ext.define('spec.Thread', cfg);
}
function definePost(options) {
var cfg = {
extend: 'Ext.data.Model',
fields: ['id', 'title']
};
if (options) {
cfg = Ext.apply(cfg, options);
}
Post = Ext.define('spec.Post', cfg);
}
function defineUser(options) {
var cfg = {
extend: 'Ext.data.Model',
fields: ['id', 'title']
};
if (options) {
cfg = Ext.apply(cfg, options);
}
User = Ext.define('spec.User', cfg);
}
beforeEach(function() {
MockAjaxManager.addMethods();
Ext.data.Model.schema.setNamespace('spec');
});
afterEach(function() {
if (Post) {
Ext.undefine('spec.Post');
Post = null;
}
if (User) {
Ext.undefine('spec.User');
}
if (Thread) {
Ext.undefine('spec.Thread');
Thread = null;
}
Ext.data.Model.schema.clear(true);
MockAjaxManager.removeMethods();
});
function expectFn(name, o) {
o = o || Post;
expect(Ext.isFunction(o.prototype[name])).toBe(true);
}
function expectNotFn(name, o) {
o = o || Post;
expect(Ext.isFunction(o.prototype[name])).toBe(false);
}
describe("declarations", function() {
describe("Configuration of model only", function() {
it("should accept a string", function() {
defineThread();
definePost({
belongsTo: 'Thread'
});
expectFn('getThread');
expectFn('setThread');
expectFn('posts', Thread);
});
it("should accept an array of strings", function() {
defineThread();
defineUser();
definePost({
belongsTo: ['Thread', 'User']
});
expectFn('getThread');
expectFn('setThread');
expectFn('getUser');
expectFn('setUser');
expectFn('posts', Thread);
expectFn('posts', User);
});
it("should accept an object", function() {
defineThread();
definePost({
belongsTo: {
type: 'Thread'
}
});
expectFn('getThread');
expectFn('setThread');
expectFn('posts', Thread);
});
it("should accept an array of objects", function() {
defineThread();
defineUser();
definePost({
belongsTo: [{
type: 'Thread'
}, {
type: 'User'
}]
});
expectFn('getThread');
expectFn('setThread');
expectFn('getUser');
expectFn('setUser');
expectFn('posts', Thread);
expectFn('posts', User);
});
});
describe("extra configurations", function() {
describe("role", function() {
it("should add the specified role", function() {
defineThread();
definePost({
belongsTo: {
type: 'Thread',
role: 'discussion'
}
});
expectFn('getDiscussion');
expectFn('setDiscussion');
expectFn('discussionPosts', Thread);
});
});
describe("getterName", function() {
it("should allow a custom getterName", function() {
defineThread();
definePost({
belongsTo: {
type: 'Thread',
getterName: 'getDiscussion'
}
});
expectFn('getDiscussion');
expectFn('setThread');
expectFn('posts', Thread);
});
});
describe("setterName", function() {
it("should allow a custom setterName", function() {
defineThread();
definePost({
belongsTo: {
type: 'Thread',
setterName: 'setDiscussion'
}
});
expectFn('setDiscussion');
expectFn('getThread');
expectFn('posts', Thread);
});
});
describe("inverse", function() {
it("should be able to declare inverse configs", function() {
defineThread();
definePost({
belongsTo: {
type: 'Thread',
inverse: {
role: 'comments'
}
}
});
expectFn('getThread');
expectFn('setThread');
expectFn('comments', Thread);
expectNotFn('posts', Thread);
});
});
describe("parent", function() {
it("should be able to set parent", function() {
defineThread();
definePost({
belongsTo: {
parent: 'Thread'
}
});
expectFn('getThread');
expectFn('setThread');
expectFn('posts', Thread);
});
});
});
describe("timing", function() {
describe("when the owner class already exists", function() {
it("should setup methods on both classes", function() {
defineThread();
definePost({
belongsTo: 'Thread'
});
expectFn('getThread');
expectFn('setThread');
expectFn('posts', Thread);
});
});
describe("when the owner class does not exist", function() {
it("should setup methods on both classes when the owner arrives", function() {
definePost({
belongsTo: 'Thread'
});
expectNotFn('getThread');
expectNotFn('setThread');
defineThread();
expectFn('getThread');
expectFn('setThread');
expectFn('posts', Thread);
});
});
});
});
describe("instance related configs", function() {
describe("associationKey", function() {
it("should apply the associationKey for loading nested data", function() {
defineThread();
definePost({
belongsTo: {
type: 'Thread',
associationKey: 'discussion'
}
});
var post = Post.load(1);
Ext.Ajax.mockCompleteWithData({
id: 1,
thread: {
id: 101
}
});
// Key is discussion, should be nothing
expect(post.getThread()).toBeNull();
post = Post.load(2);
Ext.Ajax.mockCompleteWithData({
id: 2,
discussion: {
id: 101
}
});
expect(post.getThread().id).toBe(101);
});
});
describe("parent", function() {
it("should drop the child records when the owner is dropped", function() {
defineThread();
definePost({
belongsTo: {
parent: 'Thread'
}
});
var thread = new Thread({id: 1}),
post = new Post({id: 101});
thread.posts().add(post);
thread.drop();
expect(post.dropped).toBe(true);
});
});
});
describe("legacy functionality", function() {
describe("foreignKey", function() {
it("should recognize a default foreignKey as entity_id", function() {
defineThread();
definePost({
fields: ['id', 'name', 'thread_id'],
belongsTo: 'Thread'
});
var thread = new Thread({id: 1}),
post = new Post({id: 101});
thread.posts().add(post);
expect(post.get('thread_id')).toBe(1);
});
it("should recognize a custom foreignKey as entity_id", function() {
defineThread();
definePost({
fields: ['id', 'name', 'customField'],
belongsTo: {
type: 'Thread',
foreignKey: 'customField'
}
});
var thread = new Thread({id: 1}),
post = new Post({id: 101});
thread.posts().add(post);
expect(post.get('customField')).toBe(1);
});
});
it("should use the name parameter as the role", function() {
defineThread();
definePost({
belongsTo: {
model: 'Thread',
name: 'discussion'
}
});
expectFn('getDiscussion');
expectFn('setDiscussion');
expectFn('discussionPosts', Thread);
});
it("should use the associatedName parameter as the role", function() {
defineThread();
definePost({
belongsTo: {
model: 'Thread',
associatedName: 'discussion'
}
});
expectFn('getDiscussion');
expectFn('setDiscussion');
expectFn('discussionPosts', Thread);
});
it("should respect a role config when using model", function() {
defineThread();
definePost({
belongsTo: {
model: 'Thread',
role: 'discussion'
}
});
expectFn('getDiscussion');
expectFn('setDiscussion');
expectFn('discussionPosts', Thread);
});
});
});