442 lines
17 KiB
JavaScript
Raw Normal View History

/// <reference path="../Scripts/References.js" />
(function (upshot, $, ko, undefined) {
var obsOld = upshot.observability.configuration;
module("mapping.tests.js", {
teardown: function () {
upshot.observability.configuration = obsOld;
testHelper.unmockAjax();
}
});
function createRemoteDataSource(options) {
options = $.extend({ providerParameters: { url: "unused", operationName: ""} }, options);
return new upshot.RemoteDataSource(options);
}
function createCustomersResult() {
return [
{
ID: 1,
Name: "Joe",
Orders: [
{ ID: 97, ProductName: "Smarties", CustomerID: 1 }
]
},
{
ID: 2,
Name: "Stan",
Orders: [
{ ID: 99, ProductName: "Shreddies", CustomerID: 2 }
]
},
{
ID: 3,
Name: "Fred",
Orders: [
{ ID: 98, ProductName: "Wheatabix", CustomerID: 3 },
{ ID: 96, ProductName: "Red Rose Tea", CustomerID: 3 }
]
}
];
}
var customersMetadata = {
Customer_Mapping: {
key: ["ID"],
fields: {
ID: { type: "Int32:#System" },
Name: { type: "String:#System" },
Orders: {
type: "Order_Mapping",
array: true,
association: {
thisKey: ["ID"],
otherKey: ["CustomerID"]
}
}
}
},
Order_Mapping: {
key: ["ID"],
fields: {
ID: { type: "Int32:#System" },
ProductName: { type: "String:#System" },
CustomerID: { type: "Int32:#System" },
Customer: {
type: "Customer_Mapping",
association: {
isForeignKey: true,
thisKey: ["CustomerID"],
otherKey: ["ID"]
}
}
}
},
Entity_Mapping: {
key: ["Id"],
fields: {
Id: { type: "Int32:#System" },
String: { type: "String:#System" },
Number: { type: "Int32:#System" }
}
},
CT_Mapping: {
fields: {
String: { type: "String:#System" },
Number: { type: "Int32:#System" },
CT: { type: "CT_Mapping" }
}
}
};
function happyMapper(entityType) {
return function (data) {
var mapped = upshot.map(data, entityType);
mapped.Happy = true;
return mapped;
}
}
(function () {
var mappingOptions = [
{
entityType: "Customer_Mapping",
mapping: happyMapper("Customer_Mapping")
},
{
entityType: "Customer_Mapping",
mapping: {
map: happyMapper("Customer_Mapping"),
unmap: function () { throw "Not reached"; }
}
},
{
entityType: "Customer_Mapping",
mapping: {
Customer_Mapping: happyMapper("Customer_Mapping")
}
},
{
entityType: "Customer_Mapping",
mapping: {
Customer_Mapping: {
map: happyMapper("Customer_Mapping"),
unmap: function () { throw "Not reached"; }
}
}
}
];
for (var i = 0; i < mappingOptions.length; i++) {
(function (options) {
test("Verify customer parent mapping, default child mapping", 3, function () {
stop();
upshot.observability.configuration = upshot.observability.knockout;
upshot.metadata(customersMetadata);
dsTestDriver.simulateSuccessService(createCustomersResult());
var rds = createRemoteDataSource(options);
rds.refresh(function (entities) {
equal(entities[1].Orders()[0].ProductName(), "Shreddies", "Mapping and associations applied");
equal($.grep(entities, function (entity) { return entity.Happy; }).length, 3, "Customers mapped with custom mapping");
equal($.grep(rds.getDataContext().getEntitySet("Order_Mapping").getEntities()(), function (entity) { return entity.Happy; }).length, 0, "Orders mapped with default mapping");
start();
});
});
})(mappingOptions[i]);
}
})();
(function () {
var mappingOptions = [
{
entityType: "Customer_Mapping",
mapping: {
Order_Mapping: happyMapper("Order_Mapping")
}
},
{
entityType: "Customer_Mapping",
mapping: {
Order_Mapping: {
map: happyMapper("Order_Mapping"),
unmap: function () { throw "Not reached"; }
}
}
}
];
for (var i = 0; i < mappingOptions.length; i++) {
(function (options) {
test("Verify default parent mapping, custom child mapping", 3, function () {
stop();
upshot.observability.configuration = upshot.observability.knockout;
upshot.metadata(customersMetadata);
dsTestDriver.simulateSuccessService(createCustomersResult());
var rds = createRemoteDataSource(options);
rds.refresh(function (entities) {
equal(entities[1].Orders()[0].ProductName(), "Shreddies", "Mapping and associations applied");
equal($.grep(entities, function (entity) { return entity.Happy; }).length, 0, "Customers mapped with default mapping");
equal($.grep(rds.getDataContext().getEntitySet("Order_Mapping").getEntities()(), function (entity) { return entity.Happy; }).length, 4, "Orders mapped with custom mapping");
start();
});
});
})(mappingOptions[i]);
}
})();
function Customer(data) {
this.ID = ko.observable(data.ID);
this.Orders = upshot.map(data.Orders, "Order_Mapping");
this.Happy = true;
}
test("Verify use of ctor as map", 3, function () {
stop();
upshot.observability.configuration = upshot.observability.knockout;
upshot.metadata(customersMetadata);
dsTestDriver.simulateSuccessService(createCustomersResult());
var rds = createRemoteDataSource({
entityType: "Customer_Mapping",
mapping: Customer
});
rds.refresh(function (entities) {
equal(entities[1].Orders()[0].ProductName(), "Shreddies", "Mapping and associations applied");
equal($.grep(entities, function (entity) { return entity.Happy; }).length, 3, "Customers mapped with custom mapping");
equal($.grep(rds.getDataContext().getEntitySet("Order_Mapping").getEntities()(), function (entity) { return entity.Happy; }).length, 0, "Orders mapped with default mapping");
start();
});
});
// TODO: Factor our KO test setup elsewhere and move this test to a better home.
test("LDS over ASEV produces correct filtered result", 2, function () {
stop();
upshot.observability.configuration = upshot.observability.knockout;
upshot.metadata(customersMetadata);
dsTestDriver.simulateSuccessService(createCustomersResult());
var rds = createRemoteDataSource({
entityType: "Customer_Mapping",
mapping: Customer
});
rds.refresh(function (entities) {
var lds = new upshot.LocalDataSource({
source: entities[2].Orders,
filter: { property: "ProductName", value: "Wheatabix" }
});
lds.refresh(function (entities2) {
ok(entities2.length === 1 && entities2[0].ProductName() === "Wheatabix", "Correct LDS refresh result");
var lds2 = new upshot.LocalDataSource({
source: upshot.EntitySource.as(entities[2].Orders),
filter: { property: "ProductName", value: "Wheatabix" }
});
lds2.refresh(function (entities3) {
ok(entities3.length === 1 && entities3[0].ProductName() === "Wheatabix", "Correct LDS refresh result");
start();
});
});
});
});
test("Default knockout mapping adds entity and updated properties", 2, function () {
upshot.observability.configuration = upshot.observability.knockout;
upshot.metadata(customersMetadata);
var entity = upshot.map({
Id: 1,
String: "String",
Number: 1
}, "Entity_Mapping");
equal(entity.hasOwnProperty("EntityState"), true, "Entity should have 'EntityState' property");
equal(entity.String.hasOwnProperty("IsUpdated"), true, "String should have 'IsUpdated' property");
});
test("Default knockout mapping for a complex type adds updated properties", 4, function () {
upshot.observability.configuration = upshot.observability.knockout;
upshot.metadata(customersMetadata);
var ct = upshot.map({
String: "String",
Number: 1,
CT: {
String: "String2",
Number: 2,
CT: null
}
}, "CT_Mapping");
equal(ct.hasOwnProperty("EntityState"), false, "CT should not have 'EntityState' property");
equal(ct.String.hasOwnProperty("IsUpdated"), true, "String should have 'IsUpdated' property");
equal(ct.CT().hasOwnProperty("EntityState"), false, "Nested CT should not have 'EntityState' property");
equal(ct.CT().String.hasOwnProperty("IsUpdated"), true, "Nested String should have 'IsUpdated' property");
});
test("upshot.addEntityProperties for knockout adds entity properties", 12, function () {
upshot.observability.configuration = upshot.observability.knockout;
upshot.metadata(customersMetadata);
var entity = upshot.map({
Id: 1,
String: "String",
Number: 1
}, "Entity_Mapping");
equal(entity.hasOwnProperty("EntityState"), true, "Entity should have 'EntityState' property");
equal(entity.EntityState(), upshot.EntityState.Unmodified, "EntityState should be unmodified");
equal(entity.hasOwnProperty("EntityError"), true, "Entity should have 'EntityError' property");
equal(entity.EntityError(), null, "EntityError should be null");
equal(entity.hasOwnProperty("IsUpdated"), true, "Entity should have 'IsUpdated' property");
equal(entity.IsUpdated(), false, "IsUpdated should be false");
equal(entity.hasOwnProperty("IsAdded"), true, "Entity should have 'IsAdded' property");
equal(entity.IsAdded(), false, "IsAdded should be false");
equal(entity.hasOwnProperty("IsDeleted"), true, "Entity should have 'IsDeleted' property");
equal(entity.IsDeleted(), false, "IsDeleted should be false");
equal(entity.hasOwnProperty("IsChanged"), true, "Entity should have 'IsChanged' property");
equal(entity.IsChanged(), false, "IsChanged should be false");
});
test("upshot.addUpdatedProperties for knockout adds updated properties", 6, function () {
upshot.observability.configuration = upshot.observability.knockout;
upshot.metadata(customersMetadata);
var entity = upshot.map({
Id: 1,
String: "String",
Number: 1
}, "Entity_Mapping");
equal(entity.Id.hasOwnProperty("IsUpdated"), true, "Id should have 'IsUpdated' property");
equal(entity.Id.IsUpdated(), false, "Id.IsUpdated should be false");
equal(entity.String.hasOwnProperty("IsUpdated"), true, "String should have 'IsUpdated' property");
equal(entity.String.IsUpdated(), false, "String.IsUpdated should be false");
equal(entity.Number.hasOwnProperty("IsUpdated"), true, "Number should have 'IsUpdated' property");
equal(entity.Number.IsUpdated(), false, "Number.IsUpdated should be false");
});
function getEntityStates() {
var states = {};
$.each(upshot.EntityState, function (key, value) {
if (typeof value === "string") {
states[value] = false;
}
});
return states;
}
test("knockout entity.IsUpdated should reflect EntityState", 8, function () {
upshot.observability.configuration = upshot.observability.knockout;
upshot.metadata(customersMetadata);
var entity = upshot.map({
Id: 1,
String: "String",
Number: 1
}, "Entity_Mapping");
var states = getEntityStates();
states[upshot.EntityState.ClientUpdated] = true;
states[upshot.EntityState.ServerUpdating] = true;
$.each(states, function (key, value) {
entity.EntityState(key);
equal(entity.IsUpdated(), value, "IsUpdated should be " + value + " for state " + key);
});
});
test("knockout entity.IsAdded should reflect EntityState", 8, function () {
upshot.observability.configuration = upshot.observability.knockout;
upshot.metadata(customersMetadata);
var entity = upshot.map({
Id: 1,
String: "String",
Number: 1
}, "Entity_Mapping");
var states = getEntityStates();
states[upshot.EntityState.ClientAdded] = true;
states[upshot.EntityState.ServerAdding] = true;
$.each(states, function (key, value) {
entity.EntityState(key);
equal(entity.IsAdded(), value, "IsAdded should be " + value + " for state " + key);
});
});
test("knockout entity.IsDeleted should reflect EntityState", 8, function () {
upshot.observability.configuration = upshot.observability.knockout;
upshot.metadata(customersMetadata);
var entity = upshot.map({
Id: 1,
String: "String",
Number: 1
}, "Entity_Mapping");
var states = getEntityStates();
states[upshot.EntityState.ClientDeleted] = true;
states[upshot.EntityState.ServerDeleting] = true;
states[upshot.EntityState.Deleted] = true;
$.each(states, function (key, value) {
entity.EntityState(key);
equal(entity.IsDeleted(), value, "IsDeleted should be " + value + " for state " + key);
});
});
test("knockout entity.IsChanged should reflect EntityState", 8, function () {
upshot.observability.configuration = upshot.observability.knockout;
upshot.metadata(customersMetadata);
var entity = upshot.map({
Id: 1,
String: "String",
Number: 1
}, "Entity_Mapping");
var states = getEntityStates();
states[upshot.EntityState.Unmodified] = true;
states[upshot.EntityState.Deleted] = true;
$.each(states, function (key, value) {
entity.EntityState(key);
equal(entity.IsChanged(), !value, "IsChanged should be " + !value + " for state " + key);
});
});
test("upshot.registerType and upshot.type use", 4, function () {
upshot.registerType("FooType", function () { return Foo; });
function Foo() {};
equal(upshot.type(Foo), "FooType", "upshot.registerType works before key declaration");
function Foo2() {};
upshot.registerType("FooType", function () { return Foo2; });
equal(upshot.type(Foo2), "FooType", "upshot.registerType works after key declaration");
upshot.registerType({ Bar1Type: function () { return Bar1; }, Bar2Type: function () { return Bar2; } });
function Bar1() {};
function Bar2() {};
ok(upshot.type(Bar1) === "Bar1Type" && upshot.type(Bar2) === "Bar2Type", "upshot.registerType supports multiple registrations");
var exception;
try {
function Zip() {};
upshot.type(Zip);
} catch (ex) {
exception = true;
}
ok(!!exception, "upshot.type with no preceding upshot.registerType throws exception");
});
})(upshot, jQuery, ko);