Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

754 lines
44 KiB
JavaScript

/// <reference path="../Scripts/References.js" />
(function (global, upshot, undefined) {
module("Delete.tests.js", {
teardown: function () {
testHelper.unmockAjax();
}
});
function createDataSource(useLocal, result, bufferChanges) {
if (useLocal) {
var lds = new upshot.LocalDataSource({
source: createDataSource(false, null, !!bufferChanges),
result: result,
filter: [{ property: "Price", operator: ">", value: 300 }, { property: "Price", operator: "<", value: 700 }]
});
return lds;
} else {
return new upshot.RemoteDataSource({
providerParameters: { url: "unused", operationName: "" },
provider: upshot.riaDataProvider,
result: result,
bufferChanges: !!bufferChanges
});
}
}
function createProductsResult() {
return {
GetProductsResult: {
TotalCount: 5,
RootResults: [
{ ID: 1, Manufacturer: "Canon", Price: 200 },
{ ID: 2, Manufacturer: "Nikon", Price: 400 },
{ ID: 3, Manufacturer: "Pentax", Price: 500 },
{ ID: 4, Manufacturer: "Sony", Price: 600 },
{ ID: 5, Manufacturer: "Olympus", Price: 800 }
],
Metadata: [
{
type: "Product:#Sample.Models",
key: ["ID"],
fields: {
ID: { type: "Int32:#System" },
Manufacturer: { type: "String:#System" },
Price: { type: "Decimal:#System" }
},
rules: {
ID: { required: true },
Price: { range: [0, 1000] }
}
}
]
}
};
}
function createProfileResult() {
return {
GetProfileForProfileUpdateResult: {
TotalCount: -1,
IncludedResults: [
{ __type: "Friend:#BigShelf.Models", FriendId: 2, Id: 1, ProfileId: 1 },
{ __type: "Friend:#BigShelf.Models", FriendId: 3, Id: 2, ProfileId: 1 },
{ __type: "Friend:#BigShelf.Models", FriendId: 6, Id: 4, ProfileId: 1 },
{ __type: "Profile:#BigShelf.Models", AspNetUserGuid: "5ad7976c-7a95-47aa-87ba-29c3fc80643e", EmailAddress: "deepm@microsoft.com", Id: 2, Name: "Deepesh Mohnani" },
{ __type: "Profile:#BigShelf.Models", AspNetUserGuid: "9330619d-9a8c-4269-9bde-ba4cb1b7b354", EmailAddress: "jeffhand@microsoft.com", Id: 3, Name: "Jeff Handley" },
{ __type: "Profile:#BigShelf.Models", AspNetUserGuid: "990c62c5-30a4-4ca9-92c5-f248241f6d44", EmailAddress: "gblock@microsoft.com", Id: 6, Name: "Glenn Block" }
],
RootResults: [{ AspNetUserGuid: "3730F12D-1A2A-4499-859B-9F586B2858A4", EmailAddress: "demo@microsoft.com", Id: 1, Name: "Demo User"}],
Metadata: [
{
type: "Profile:#BigShelf.Models",
key: ["Id"],
fields: {
AspNetUserGuid: { type: "String:#System" },
EmailAddress: { type: "String:#System" },
Friends: { type: "Friend:#BigShelf.Models", array: true, association: { name: "Profile_Friend", thisKey: ["Id"], otherKey: ["ProfileId"], isForeignKey: false} },
Id: { type: "Int32:#System" },
Name: { type: "String:#System" }
},
rules: {
EmailAddress: { required: true, email: true },
Name: { required: true }
}
},
{
type: "Friend:#BigShelf.Models",
key: ["Id"],
fields: {
FriendId: { type: "Int32:#System" },
FriendProfile: { type: "Profile:#BigShelf.Models", association: { name: "Profile_Friend1", thisKey: ["FriendId"], otherKey: ["Id"], isForeignKey: true} },
Id: { type: "Int32:#System" },
Profile: { type: "Profile:#BigShelf.Models", association: { name: "Profile_Friend", thisKey: ["ProfileId"], otherKey: ["Id"], isForeignKey: true} },
ProfileId: { type: "Int32:#System" }
}
}
]
}
};
}
// "GetProfileForProfileUpdateResult":{"TotalCount":-1,"IncludedResults":[{"__type":"Friend:#BigShelf.Models","FriendId":2,"Id":1,"ProfileId":1},{"__type":"Friend:#BigShelf.Models","FriendId":3,"Id":2,"ProfileId":1},{"__type":"Friend:#BigShelf.Models","FriendId":6,"Id":4,"ProfileId":1},{"__type":"Profile:#BigShelf.Models","AspNetUserGuid":"5ad7976c-7a95-47aa-87ba-29c3fc80643e","EmailAddress":"deepm@microsoft.com","Id":2,"Name":"Deepesh Mohnani"},{"__type":"Profile:#BigShelf.Models","AspNetUserGuid":"9330619d-9a8c-4269-9bde-ba4cb1b7b354","EmailAddress":"jeffhand@microsoft.com","Id":3,"Name":"Jeff Handley"},{"__type":"Profile:#BigShelf.Models","AspNetUserGuid":"990c62c5-30a4-4ca9-92c5-f248241f6d44","EmailAddress":"gblock@microsoft.com","Id":6,"Name":"Glenn Block"}],"RootResults":[{"AspNetUserGuid":"3730F12D-1A2A-4499-859B-9F586B2858A4","EmailAddress":"demo@microsoft.com","Id":1,"Name":"Demo User"}],"Metadata":[{"type":"Profile:#BigShelf.Models","key":["Id"],"fields":{"AspNetUserGuid":{"type":"String:#System"},"Categories":{"type":"Category:#BigShelf.Models","array":true,"association":{"name":"Profile_Category","thisKey":["Id"],"otherKey":["ProfileId"],"isForeignKey":false}},"EmailAddress":{"type":"String:#System"},"FlaggedBooks":{"type":"FlaggedBook:#BigShelf.Models","array":true,"association":{"name":"Profile_FlaggedBook","thisKey":["Id"],"otherKey":["ProfileId"],"isForeignKey":false}},"Friends":{"type":"Friend:#BigShelf.Models","array":true,"association":{"name":"Profile_Friend","thisKey":["Id"],"otherKey":["ProfileId"],"isForeignKey":false}},"Id":{"type":"Int32:#System"},"Name":{"type":"String:#System"}},"rules":{"EmailAddress":{"required":true,"email":true},"Name":{"required":true}}},{"type":"Book:#BigShelf.Models","key":["Id"],"fields":{"AddedDate":{"type":"DateTime:#System"},"ASIN":{"type":"String:#System"},"Author":{"type":"String:#System"},"CategoryId":{"type":"Int32:#System"},"CategoryName":{"type":"CategoryName:#BigShelf.Models","association":{"name":"CategoryName_Book","thisKey":["CategoryId"],"otherKey":["Id"],"isForeignKey":true}},"Description":{"type":"String:#System"},"FlaggedBooks":{"type":"FlaggedBook:#BigShelf.Models","array":true,"association":{"name":"Book_FlaggedBook","thisKey":["Id"],"otherKey":["BookId"],"isForeignKey":false}},"Id":{"type":"Int32:#System"},"PublishDate":{"type":"DateTime:#System"},"Title":{"type":"String:#System"}}},{"type":"FlaggedBook:#BigShelf.Models","key":["Id"],"fields":{"Book":{"type":"Book:#BigShelf.Models","association":{"name":"Book_FlaggedBook","thisKey":["BookId"],"otherKey":["Id"],"isForeignKey":true}},"BookId":{"type":"Int32:#System"},"Id":{"type":"Int32:#System"},"IsFlaggedToRead":{"type":"Int32:#System"},"Profile":{"type":"Profile:#BigShelf.Models","association":{"name":"Profile_FlaggedBook","thisKey":["ProfileId"],"otherKey":["Id"],"isForeignKey":true}},"ProfileId":{"type":"Int32:#System"},"Rating":{"type":"Int32:#System"}}},{"type":"Friend:#BigShelf.Models","key":["Id"],"fields":{"FriendId":{"type":"Int32:#System"},"FriendProfile":{"type":"Profile:#BigShelf.Models","association":{"name":"Profile_Friend1","thisKey":["FriendId"],"otherKey":["Id"],"isForeignKey":true}},"Id":{"type":"Int32:#System"},"Profile":{"type":"Profile:#BigShelf.Models","association":{"name":"Profile_Friend","thisKey":["ProfileId"],"otherKey":["Id"],"isForeignKey":true}},"ProfileId":{"type":"Int32:#System"}}},{"type":"Category:#BigShelf.Models","key":["Id"],"fields":{"CategoryId":{"type":"Int32:#System"},"CategoryName":{"type":"CategoryName:#BigShelf.Models","association":{"name":"CategoryName_Category","thisKey":["CategoryId"],"otherKey":["Id"],"isForeignKey":true}},"Id":{"type":"Int32:#System"},"Profile":{"type":"Profile:#BigShelf.Models","association":{"name":"Profile_Category","thisKey":["ProfileId"],"otherKey":["Id"],"isForeignKey":true}},"ProfileId":{"type":"Int32:#System"}}},{"type":"CategoryName:#BigShelf.Models","key":["Id"],"fields":{"Books":{"type":"Book:#BigShelf.Models","array":true,"association":{"name":"CategoryName_Book","thisKey":["Id"],"otherKey":["CategoryId"],"isForeignKey":false}},"Categories":{"type":"Category:#BigShelf.Models","array":true,"association":{"name":"CategoryName_Category","thisKey":["Id"],"otherKey":["CategoryId"],"isForeignKey":false}},"Id":{"type":"Int32:#System"},"Name":{"type":"String:#System"}}}]}}" String
function createSubmitResult(results) {
var changeResult = [];
for (var i = 0; i < results.length; ++i) {
var result = {
Entity: results[i].entity,
EntityActions: null,
HasMemberChanges: false,
Id: i,
Operation: 4
};
if (results[i].errors) {
result.ValidationErrors = results[i].errors;
}
changeResult.push(result);
}
return { SubmitChangesResult: changeResult };
}
function deleteEntities(products, results, bufferChanges, destructive, revert) {
dsTestDriver.simulatePostSuccessService(createSubmitResult(results));
setTimeout(function () {
for (var i = 0; i < results.length; ++i) {
if (destructive) {
$.observable(products).remove(results[i].entity);
equal(upshot.EntitySource.as(products).getEntityState(results[i].entity), upshot.EntityState.ClientDeleted, "expect delete state");
} else {
upshot.EntitySource.as(products).deleteEntity(results[i].entity);
equal(upshot.EntitySource.as(products).getEntityState(results[i].entity), upshot.EntityState.ClientDeleted, "expect delete state");
}
}
if (bufferChanges) {
if (revert) {
upshot.EntitySource.as(products).revertChanges();
for (var i = 0; i < results.length; ++i) {
equal(upshot.EntitySource.as(products).getEntityState(results[i].entity), upshot.EntityState.Unmodified, "expect revert state");
}
revert();
} else {
upshot.EntitySource.as(products).commitChanges();
}
}
}, 10);
}
for (var d = 0; d < 1; ++d) { // TODO: Destructive delete tests disabled until we can redevelop this feature.
for (var b = 0; b < 2; ++b) {
(function (bufferChanges, destructive) {
test((!destructive ? "Non-destructive " : "Destructive ") + "LDS over RDS" + (bufferChanges ? " batch-" : " ") + "success", 7, function () {
stop();
dsTestDriver.simulateSuccessService(createProductsResult());
var rproducts = [];
var lproducts = [];
var refreshNeeded = 0;
var rds = createDataSource(false, rproducts, bufferChanges);
var lds = new upshot.LocalDataSource({
source: rds,
result: lproducts,
filter: [{ property: "Price", operator: ">", value: 300 }, { property: "Price", operator: "<", value: 700}]
});
$([lproducts]).bind("replaceAll", function () {
equal(lproducts.length, 3, "lcount matched");
equal(rproducts.length, 5, "rcount matched");
deleteEntities(rproducts, [{ entity: rproducts[1] }, { entity: rproducts[3]}], bufferChanges, destructive);
});
lds.bind({
refreshNeeded: function () {
++refreshNeeded;
}
});
rds.bind({
commitSuccess: function () {
// the lproducts is purged automatically thru purge sequence
equal(lproducts.length, 1, "lcount matched");
equal(rproducts.length, 3, "rcount matched");
equal(refreshNeeded, destructive ? 1 : 0, "refreshNeeded matched"); // Non-destructive will only trigger refreshNeeded when the LDS has paging parameters.
start();
}
});
lds.refresh({ all: true });
});
if (bufferChanges) {
test((!destructive ? "Non-destructive " : "Destructive ") + "LDS over RDS" + (bufferChanges ? " batch-" : " ") + "revert", 9, function () {
stop();
dsTestDriver.simulateSuccessService(createProductsResult());
var rproducts = [];
var lproducts = [];
var refreshNeeded = 0;
var rds = createDataSource(false, rproducts, bufferChanges);
var lds = new upshot.LocalDataSource({
source: rds,
result: lproducts,
filter: [{ property: "Price", operator: ">", value: 300 }, { property: "Price", operator: "<", value: 700 }]
});
$([lproducts]).bind("replaceAll", function () {
var revert = function () {
equal(lproducts.length, 3, "lcount matched");
equal(rproducts.length, destructive ? 3 : 5, "rcount matched");
equal(refreshNeeded, destructive ? 1 : 0, "refreshNeeded matched"); // Non-destructive will only see entity states change. No reason to refresh.
start();
}
equal(lproducts.length, 3, "lcount matched");
equal(rproducts.length, 5, "rcount matched");
deleteEntities(rproducts, [{ entity: rproducts[1] }, { entity: rproducts[3]}], bufferChanges, destructive, revert);
});
lds.bind({
refreshNeeded: function () {
++refreshNeeded;
}
});
lds.refresh({ all: true });
});
}
})(!!b, !!d);
}
}
for (var d = 0; d < 1; ++d) { // TODO: Destructive delete tests disabled until we can redevelop this feature.
for (var b = 0; b < 2; ++b) {
(function (bufferChanges, destructive) {
// AssociatedEntitiesView does not support batch commit
if (!bufferChanges) {
test((!destructive ? "Non-destructive " : "Destructive ") + "AssociatedEntitiesView" + (bufferChanges ? " batch-" : " ") + "success", 4, function () {
stop();
dsTestDriver.simulateSuccessService(createProfileResult());
var profiles = [];
var profile;
var rds = createDataSource(false, profiles, bufferChanges);
$([profiles]).bind("replaceAll", function () {
equal(profiles.length, 1, "profiles length");
profile = profiles[0];
var friends = profile.Friends;
equal(friends.length, 3, "friends length");
deleteEntities(friends, [{ entity: friends[1]}], bufferChanges, destructive);
});
rds.bind({
commitSuccess: function () {
// the lproducts is purged automatically thru purge sequence
var friends = profile.Friends;
equal(friends.length, 2, "friends length");
start();
}
});
rds.refresh();
});
}
if (bufferChanges) {
test((!destructive ? "Non-destructive " : "Destructive ") + "AssociatedEntitiesView" + (bufferChanges ? " batch-" : " ") + "revert", 5, function () {
stop();
dsTestDriver.simulateSuccessService(createProfileResult());
var profiles = [];
var profile;
var rds = createDataSource(false, profiles, bufferChanges);
$([profiles]).bind("replaceAll", function () {
equal(profiles.length, 1, "profiles length");
profile = profiles[0];
var friends = profile.Friends;
equal(friends.length, 3, "friends length");
var revert = function () {
// the lproducts is purged automatically thru purge sequence
var friends = profile.Friends;
equal(friends.length, destructive ? 2 : 3, "friends length");
start();
};
deleteEntities(friends, [{ entity: friends[1]}], bufferChanges, destructive, revert);
});
rds.refresh();
});
}
})(!!b, !!d);
}
}
// return; // TODO, suwatch: below tests multiple variations and scenarios.
// commented out for now as it might be hard to debug. Will only be run by me.
// Testing a combination of ..
// LDS vs. RDS
// Batch vs. Auto commit
// Destructive vs. Non-destructive delete
// success vs. failure (failure-revert vs. failure-recommit) vs. simply revert
for (var d = 0; d < 1; ++d) { // TODO: Destructive delete tests disabled until we can redevelop this feature.
for (var l = 0; l < 2; ++l) {
for (var b = 0; b < 2; ++b) {
(function (useLocal, bufferChanges, destructive) {
test((!destructive ? "Non-destructive " : "Destructive ") + (!!useLocal ? "LDS" : "RDS") + (bufferChanges ? " batch-" : " ") + "success", 13, function () {
stop();
dsTestDriver.simulateSuccessService(createProductsResult());
var products = [];
var removes = [];
var refreshNeeded = 0;
$([products]).bind("replaceAll", function () {
if (useLocal) {
equal(products.length, 3, "count matched");
deleteEntities(products, [{ entity: products[0] }, { entity: products[2]}], bufferChanges, destructive);
} else {
equal(products.length, 5, "count matched");
deleteEntities(products, [{ entity: products[1] }, { entity: products[3]}], bufferChanges, destructive);
}
});
$([products]).bind("remove insert", function (event, args) {
equal(event.type, "remove", "expect event");
removes.push(args.items[0]);
});
var ds = createDataSource(useLocal, products, bufferChanges);
var refreshNeededObserver = {
refreshNeeded: function () {
++refreshNeeded;
}
};
var commitObserver = {
commitSuccess: function () {
equal(removes.length, 2, "removes matched");
equal(removes[0].ID, 2, "REMOVE0 matched");
equal(removes[1].ID, 4, "REMOVE1 matched");
removes = [];
if (useLocal) {
equal(products.length, 1, "count matched");
equal(products[0].ID, 3, "ID0 matched");
equal(products[1], undefined, "ID1 matched");
equal(products[2], undefined, "ID2 matched");
} else {
equal(products.length, 3, "count matched");
equal(products[0].ID, 1, "ID0 matched");
equal(products[1].ID, 3, "ID1 matched");
equal(products[2].ID, 5, "ID2 matched");
}
equal(refreshNeeded, 0, "refreshNeeded event"); // Non-destructive will only trigger refreshNeeded when the LDS has paging parameters.
start();
}
};
if (useLocal) {
// LDS does not have Commit api
ds.commitChanges = ds.commitChanges || function () { ds._entitySource.commitChanges(); };
ds.bind(refreshNeededObserver);
ds._entitySource.bind(commitObserver);
} else {
ds.bind(commitObserver);
}
ds.refresh(useLocal && { all: true });
});
if (bufferChanges) {
test((!destructive ? "Non-destructive " : "Destructive ") + (!!useLocal ? "LDS" : "RDS") + " batch-revert", 8, function () {
stop();
dsTestDriver.simulateSuccessService(createProductsResult());
var products = [];
var removes = [];
var refreshNeeded = 0;
$([products]).bind("replaceAll", function () {
var revert = function () {
equal(removes.length, destructive ? 2 : 0, "removes length matched");
removes = [];
if (useLocal) {
equal(products.length, destructive ? 1 : 3, "count matched");
} else {
equal(products.length, destructive ? 3 : 5, "count matched");
}
// revert destructive should raise refreshNeeded event
equal(refreshNeeded, (useLocal && destructive) ? 1 : 0, "refreshNeeded event"); // Non-destructive will only see entity states change. No reason to refresh.
start();
};
if (useLocal) {
equal(products.length, 3, "count matched");
deleteEntities(products, [{ entity: products[0] }, { entity: products[2]}], bufferChanges, destructive, revert);
} else {
equal(products.length, 5, "count matched");
deleteEntities(products, [{ entity: products[1] }, { entity: products[3]}], bufferChanges, destructive, revert);
}
});
$([products]).bind("remove", function (event, args) {
//equal(event.type, "remove", "expect event");
removes.push(args.items[0]);
});
var ds = createDataSource(useLocal, products, bufferChanges);
if (useLocal) {
ds.bind({ refreshNeeded: function () { refreshNeeded++; } });
}
ds.refresh(useLocal && { all: true });
});
}
if (!destructive) {
test((!destructive ? "Non-destructive " : "Destructive ") + (!!useLocal ? "LDS" : "RDS") + (bufferChanges ? " batch-" : " ") + "failure-recommit", 21, function () {
stop();
dsTestDriver.simulateSuccessService(createProductsResult());
var products = [];
var removes = [];
var refreshNeeded = 0;
$([products]).bind("replaceAll", function () {
if (useLocal) {
equal(products.length, 3, "count matched");
deleteEntities(products, [{ entity: products[0] }, { entity: products[2], errors: [{ Message: "Simulated failure!"}]}], bufferChanges, destructive);
} else {
equal(products.length, 5, "count matched");
deleteEntities(products, [{ entity: products[1] }, { entity: products[3], errors: [{ Message: "Simulated failure!"}]}], bufferChanges, destructive);
}
});
$([products]).bind("remove", function (event, args) {
//equal(event.type, "remove", "expect event");
removes.push(args.items[0]);
});
var ds = createDataSource(useLocal, products, bufferChanges);
var refreshNeededObserver = {
refreshNeeded: function () {
++refreshNeeded;
}
};
var commitObserver = {
commitSuccess: function () {
equal(removes.length, 1, "removes matched");
equal(removes[0].ID, 4, "REMOVE0 matched");
removes = [];
if (useLocal) {
equal(products.length, 1, "count matched");
equal(products[0].ID, 3, "ID1 matched");
equal(products[1], undefined, "ID1 matched");
equal(products[2], undefined, "ID2 matched");
} else {
equal(products.length, 3, "count matched");
equal(products[0].ID, 1, "ID0 matched");
equal(products[1].ID, 3, "ID1 matched");
equal(products[2].ID, 5, "ID2 matched");
}
equal(refreshNeeded, (useLocal && destructive) ? 1 : 0, "refreshNeeded event"); // Non-destructive will only trigger refreshNeeded when the LDS has paging parameters.
start();
},
commitError: function (httpStatus, errorText) {
equal(removes.length, destructive ? 2 : 1, "removes matched");
equal(removes[0].ID, 2, "REMOVE0 matched");
var removed;
if (destructive) {
equal(removes[1].ID, 4, "REMOVE1 matched");
removed = removes[1];
} else {
equal(removes[1], undefined, "REMOVE1 matched");
}
removes = [];
if (useLocal) {
equal(products.length, destructive ? 1 : 2, "count matched");
equal(errorText, "Simulated failure!", "errorText matched");
equal(products[0].ID, 3, "ID0 matched");
if (destructive) {
equal(products[1], undefined, "ID1 matched");
equal(this.getEntityState(removed), upshot.EntityState.ClientDeleted, "state checked");
} else {
equal(products[1].ID, 4, "ID1 matched");
equal(this.getEntityState(products[1]), upshot.EntityState.ClientDeleted, "state checked");
}
equal(products[2], undefined, "ID2 matched");
equal(products[3], undefined, "ID3 matched");
deleteEntities(products, [{ entity: removed || products[1]}], bufferChanges, destructive);
} else {
equal(products.length, destructive ? 3 : 4, "count matched");
equal(errorText, "Simulated failure!", "errorText matched");
equal(products[0].ID, 1, "ID0 matched");
equal(products[1].ID, 3, "ID1 matched");
if (destructive) {
equal(products[2].ID, 5, "ID2 matched");
equal(products[3], undefined, "ID3 matched");
equal(this.getEntityState(removed), undefined, "state checked");
} else {
equal(products[2].ID, 4, "ID2 matched");
equal(products[3].ID, 5, "ID3 matched");
equal(this.getEntityState(products[2]), upshot.EntityState.ClientDeleted, "state checked");
}
deleteEntities(products, [{ entity: removed || products[2]}], bufferChanges, destructive);
}
}
};
if (useLocal) {
// LDS does not have Commit api
ds.commitChanges = ds.commitChanges || function () { ds._entitySource.commitChanges(); };
ds.bind(refreshNeededObserver);
ds._entitySource.bind(commitObserver);
} else {
ds.bind(commitObserver);
}
ds.refresh(useLocal && { all: true });
});
}
test((!destructive ? "Non-destructive " : "Destructive ") + (!!useLocal ? "LDS" : "RDS") + (bufferChanges ? " batch-" : " ") + "failure-revert", 15, function () {
stop();
dsTestDriver.simulateSuccessService(createProductsResult());
var products = [];
var removes = [];
var refreshNeeded = 0;
$([products]).bind("replaceAll", function () {
if (useLocal) {
equal(products.length, 3, "count matched");
deleteEntities(products, [{ entity: products[0] }, { entity: products[2], errors: [{ Message: "Simulated failure!"}]}], bufferChanges, destructive);
} else {
equal(products.length, 5, "count matched");
deleteEntities(products, [{ entity: products[1] }, { entity: products[3], errors: [{ Message: "Simulated failure!"}]}], bufferChanges, destructive);
}
});
$([products]).bind("remove", function (event, args) {
//equal(event.type, "remove", "expect event");
removes.push(args.items[0]);
});
var ds = createDataSource(useLocal, products, bufferChanges);
var refreshNeededObserver = {
refreshNeeded: function () {
refreshNeeded++;
}
};
var commitObserver = {
commitError: function (httpStatus, errorText) {
equal(removes.length, destructive ? 2 : 1, "removes matched");
equal(removes[0].ID, 2, "REMOVE0 matched");
var tmpProducts = [];
$.each(products, function (unused, product) {
tmpProducts.push(product);
});
if (destructive) {
equal(removes[1].ID, 4, "REMOVE1 matched");
tmpProducts.splice(useLocal ? 1 : 2, 0, removes[1]);
} else {
equal(removes[1], undefined, "REMOVE1 matched");
}
removes = [];
if (useLocal) {
equal(tmpProducts.length, 2, "count matched");
equal(errorText, "Simulated failure!", "errorText matched");
equal(tmpProducts[0].ID, 3, "ID0 matched");
equal(tmpProducts[1].ID, 4, "ID1 matched");
equal(tmpProducts[2], undefined, "ID2 matched");
equal(tmpProducts[3], undefined, "ID3 matched");
equal(this.getEntityState(tmpProducts[1]), upshot.EntityState.ClientDeleted, "state checked");
this.revertChanges();
equal(this.getEntityState(tmpProducts[1]), upshot.EntityState.Unmodified, "state checked");
} else {
equal(tmpProducts.length, 4, "count matched");
equal(errorText, "Simulated failure!", "errorText matched");
equal(tmpProducts[0].ID, 1, "ID0 matched");
equal(tmpProducts[1].ID, 3, "ID1 matched");
equal(tmpProducts[2].ID, 4, "ID2 matched");
equal(tmpProducts[3].ID, 5, "ID3 matched");
equal(this.getEntityState(tmpProducts[2]), upshot.EntityState.ClientDeleted, "state checked");
this.revertChanges();
equal(this.getEntityState(tmpProducts[2]), upshot.EntityState.Unmodified, "state checked");
}
equal(refreshNeeded, (useLocal && destructive) ? 1 : 0, "refreshNeeded event"); // Non-destructive will only see entity states change. No reason to refresh.
start();
}
};
if (useLocal) {
// LDS does not have Commit api
ds.commitChanges = ds.commitChanges || function () { ds._entitySource.commitChanges(); };
ds.bind(refreshNeededObserver);
ds._entitySource.bind(commitObserver);
} else {
ds.bind(commitObserver);
}
ds.refresh(useLocal && { all: true });
});
})(!!l, !!b, !!d);
}
}
}
for (var d = 0; d < 1; ++d) { // TODO: Destructive delete tests disabled until we can redevelop this feature.
for (var b = 0; b < 2; ++b) {
(function (bufferChanges, destructive) {
test((!destructive ? "Non-destructive " : "Destructive ") + "LDS over RDS" + (bufferChanges ? " batch-" : " ") + "success", 7, function () {
stop();
dsTestDriver.simulateSuccessService(createProductsResult());
var rproducts = [];
var lproducts = [];
var refreshNeeded = 0;
var rds = createDataSource(false, rproducts, bufferChanges);
var lds = new upshot.LocalDataSource({
source: rds,
result: lproducts,
filter: [{ property: "Price", operator: ">", value: 300 }, { property: "Price", operator: "<", value: 700 }]
});
$([lproducts]).bind("replaceAll", function () {
equal(lproducts.length, 3, "lcount matched");
equal(rproducts.length, 5, "rcount matched");
deleteEntities(rproducts, [{ entity: rproducts[1] }, { entity: rproducts[3]}], bufferChanges, destructive);
});
lds.bind({
refreshNeeded: function () {
++refreshNeeded;
}
});
rds.bind({
commitSuccess: function () {
// the lproducts is purged automatically thru purge sequence
equal(lproducts.length, 1, "lcount matched");
equal(rproducts.length, 3, "rcount matched");
equal(refreshNeeded, destructive ? 1 : 0, "refreshNeeded matched"); // Non-destructive will only trigger refreshNeeded when the LDS has paging parameters.
start();
}
});
lds.refresh({ all: true });
});
if (bufferChanges) {
test((!destructive ? "Non-destructive " : "Destructive ") + "LDS over RDS" + (bufferChanges ? " batch-" : " ") + "revert", 9, function () {
stop();
dsTestDriver.simulateSuccessService(createProductsResult());
var rproducts = [];
var lproducts = [];
var refreshNeeded = 0;
var rds = createDataSource(false, rproducts, bufferChanges);
var lds = new upshot.LocalDataSource({
source: rds,
result: lproducts,
filter: [{ property: "Price", operator: ">", value: 300 }, { property: "Price", operator: "<", value: 700 }]
});
$([lproducts]).bind("replaceAll", function () {
var revert = function () {
equal(lproducts.length, 3, "lcount matched");
equal(rproducts.length, destructive ? 3 : 5, "rcount matched");
equal(refreshNeeded, destructive ? 1 : 0, "refreshNeeded matched"); // Non-destructive will only see entity states change. No reason to refresh.
start();
}
equal(lproducts.length, 3, "lcount matched");
equal(rproducts.length, 5, "rcount matched");
deleteEntities(rproducts, [{ entity: rproducts[1] }, { entity: rproducts[3]}], bufferChanges, destructive, revert);
});
lds.bind({
refreshNeeded: function () {
++refreshNeeded;
}
});
lds.refresh({ all: true });
});
}
})(!!b, !!d);
}
}
for (var d = 0; d < 1; ++d) { // TODO: Destructive delete tests disabled until we can redevelop this feature.
for (var b = 0; b < 2; ++b) {
(function (bufferChanges, destructive) {
// AssociatedEntitiesView does not support batch commit
if (!bufferChanges) {
test((!destructive ? "Non-destructive " : "Destructive ") + "AssociatedEntitiesView" + (bufferChanges ? " batch-" : " ") + "success", 4, function () {
stop();
dsTestDriver.simulateSuccessService(createProfileResult());
var profiles = [];
var profile;
var rds = createDataSource(false, profiles, bufferChanges);
$([profiles]).bind("replaceAll", function () {
equal(profiles.length, 1, "profiles length");
profile = profiles[0];
var friends = profile.Friends;
equal(friends.length, 3, "friends length");
deleteEntities(friends, [{ entity: friends[1]}], bufferChanges, destructive);
});
rds.bind({
commitSuccess: function () {
// the lproducts is purged automatically thru purge sequence
var friends = profile.Friends;
equal(friends.length, 2, "friends length");
start();
}
});
rds.refresh();
});
}
if (bufferChanges) {
test((!destructive ? "Non-destructive " : "Destructive ") + "AssociatedEntitiesView" + (bufferChanges ? " batch-" : " ") + "revert", 5, function () {
stop();
dsTestDriver.simulateSuccessService(createProfileResult());
var profiles = [];
var profile;
var rds = createDataSource(false, profiles, bufferChanges);
$([profiles]).bind("replaceAll", function () {
equal(profiles.length, 1, "profiles length");
profile = profiles[0];
var friends = profile.Friends;
equal(friends.length, 3, "friends length");
var revert = function () {
// the lproducts is purged automatically thru purge sequence
var friends = profile.Friends;
equal(friends.length, destructive ? 2 : 3, "friends length");
start();
};
deleteEntities(friends, [{ entity: friends[1]}], bufferChanges, destructive, revert);
});
rds.refresh();
});
}
})(!!b, !!d);
}
}
})(this, upshot);