a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
754 lines
44 KiB
JavaScript
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);
|