http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/503b4417/tests/odata-read-crossdomain-functional-tests.js ---------------------------------------------------------------------- diff --git a/tests/odata-read-crossdomain-functional-tests.js b/tests/odata-read-crossdomain-functional-tests.js new file mode 100644 index 0000000..cf8b45c --- /dev/null +++ b/tests/odata-read-crossdomain-functional-tests.js @@ -0,0 +1,151 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +(function (window, undefined) { + + var unexpectedErrorHandler = function (err) { + djstest.assert(false, "Unexpected call to error handler with error: " + djstest.toString(err)); + djstest.done(); + }; + + var fixConstructors = function (obj) { + /** Fix the constructors of the supplied object graph. + */ + + /// When using IE9 or a non-IE browser, the JSONP support in the library creates objects in a separate IFRAME, + /// causing the constructor property to be different to that of objects created by the verifier. This function + /// stringifies and then re-parses the object, which fixes the constructors. + + if (!window.ActiveXObject || window.DOMParser) { + return window.JSON.parse(window.JSON.stringify(obj)); + } else { + return obj; + } + }; + + var handlerAcceptStrings = [ + "*/*", + "application/json", + undefined + ]; + + var formatJsonStrings = [ + "application/json", + "application/json;odata.metadata=none", + "application/json;odata.metadata=minimal", + "application/json;odata.metadata=full", // to do: all the full metadata scenarios fail currently, need to fix. + undefined + ]; + var azureOdataService = "http://odatasampleservices.azurewebsites.net/V4/OData/OData.svc/"; + var azureOdataFeed = azureOdataService + "Categories"; + var crossDomainTimeout = 45000; + + module("CrossDomain", { + setup: function () { + this.oldEnableJsonpCallback = window.odatajs.oData.net.defaultHttpClient.enableJsonpCallback; + window.odatajs.oData.net.defaultHttpClient.enableJsonpCallback = true; + }, + teardown: function () { + window.odatajs.oData.net.defaultHttpClient.enableJsonpCallback = this.oldEnableJsonpCallback; + } + }); + + for (var i = 0; i < handlerAcceptStrings.length; i++) { + for (var j = 0; j < formatJsonStrings.length; j++) { + djstest.addTest(function readCrossDomainFullFeedTest(params) { + djstest.assertsExpected(1); + var request = { requestUri: azureOdataFeed, headers: { Accept: params.handlerAccept}, enableJsonpCallback: true }; + if (params.formatJsonString != undefined) { + request.formatQueryString = "$format=" + params.formatJsonString; + } + + djstest.log("Reading data over the wire."); + odatajs.oData.read(request, function (data, response) { + djstest.log("Verifying data over the wire from verifiert."); + window.ODataVerifyReader.readFeed(azureOdataFeed, function (expectedData) { + data = fixConstructors(data); + djstest.assertWithoutMetadata(data, expectedData, "Response data not same as expected"); + djstest.done(); + }, params.formatJsonString); + }, unexpectedErrorHandler); + }, "Testing valid read of cross domain feed collection with " + handlerAcceptStrings[i] + "," + formatJsonStrings[j], { handlerAccept: handlerAcceptStrings[i], formatJsonString: formatJsonStrings[j] }, crossDomainTimeout); + } + + djstest.addTest(function readCrossDomainEntryTest(handlerAccept) { + var endPoint = azureOdataFeed + "(1)"; + djstest.assertsExpected(1); + djstest.log("Reading data over the wire."); + odatajs.oData.read({ requestUri: endPoint, headers: { Accept: handlerAccept} }, function (data, response) { + djstest.log("Verifying data over the wire from verifier."); + window.ODataVerifyReader.readEntry(endPoint, function (expectedData) { + data = fixConstructors(data); + djstest.assertWithoutMetadata(data, expectedData, "Response data not same as expected"); + djstest.done(); + }, "application/json"); + }, unexpectedErrorHandler); + }, "Testing valid read of cross domain entry with " + handlerAcceptStrings[i], handlerAcceptStrings[i], crossDomainTimeout); + } + + var prefetchSizes = [-1, 0, 15]; + var cacheSizes = [-1, 0, 15]; + var skipValues = [ + 0, + 14, // < pageSize + 15, // = pageSize + 16 // > pageSize but < pageSize + prefetchSize + ]; + + var createTestName = function (params) { + return "Testing ReadRange of " + params.feed + " skip " + params.skip + " take " + params.take + " with pageSize " + + params.pageSize + ", prefetch " + params.prefetchSize + " and cacheSize " + params.cacheSize; + }; + + var dataCacheReadRangeSingleTest = function (params) { + var options = { name: "cache", source: params.feed, pageSize: params.pageSize, prefetchSize: params.prefetchSize, cacheSize: params.cacheSize }; + window.odatajs.oData.net.defaultHttpClient.enableJsonpCallback = true; + var cache = odatajs.cache.createDataCache(options); + cache.readRange(params.skip, params.take).then(function (data) { + validateExpectedRange(cache, data, params.feed, params.skip, params.take); + }, unexpectedErrorHandler); + }; + + var validateExpectedRange = function (cache, data, feed, skipValue, takeValue) { + var expectedRangeUrl = feed + "?$skip=" + skipValue + "&$top=" + takeValue; + window.ODataVerifyReader.readFeed(expectedRangeUrl, function (expectedData) { + if (expectedData.results) { + expectedData = expectedData.results; + } + data = fixConstructors(data); + djstest.assertAreEqualDeep(data, expectedData, "Response data not same as expected"); + djstest.destroyCacheAndDone(cache); + }); + }; + + $.each(prefetchSizes, function (_, prefetchSizeValue) { + $.each(cacheSizes, function (_, cacheSizeValue) { + var parameters = { feed: "http://odatasampleservices.azurewebsites.net/V4/OData/OData.svc/Categories", skip: 0, take: 5, pageSize: 15, prefetchSize: prefetchSizeValue, cacheSize: cacheSizeValue }; + djstest.addTest(dataCacheReadRangeSingleTest, createTestName(parameters), parameters); + }); + }); + + $.each(skipValues, function (_, skipValue) { + var parameters = { feed: "http://odatasampleservices.azurewebsites.net/V4/OData/OData.svc/Categories", skip: skipValue, take: 14, pageSize: 5, prefetchSize: 5, cacheSize: 5 }; + djstest.addTest(dataCacheReadRangeSingleTest, createTestName(parameters), parameters, crossDomainTimeout); + }); +})(this);
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/503b4417/tests/odata-read-functional-tests.html ---------------------------------------------------------------------- diff --git a/tests/odata-read-functional-tests.html b/tests/odata-read-functional-tests.html new file mode 100644 index 0000000..7114113 --- /dev/null +++ b/tests/odata-read-functional-tests.html @@ -0,0 +1,49 @@ +<!-- +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. +*/ +--> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> + <title>OData tests against local service</title> + <meta http-equiv="cache-control" content="no-cache"/> + <meta http-equiv="pragma" content="no-cache"/> + <meta http-equiv="expires" content="-1"/> + + <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.10.0.css" type="text/css" /> + <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js"></script> + <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"></script> + <script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.10.0.js"></script> + <script type="text/javascript" src="common/ODataVerifyReader.js"></script> + <script type="text/javascript" src="common/TestSynchronizerClient.js"></script> + <script type="text/javascript"> + window.TestSynchronizer.init(QUnit); + </script> + <script type="text/javascript" src="../build/odatajs-4.0.0-beta-01.js"></script> + <script type="text/javascript" src="common/common.js"></script> + <script type="text/javascript" src="common/djstest.js"></script> + <script type="text/javascript" src="odata-read-functional-tests.js"></script> +</head> +<body> + <h1 id="qunit-header">OData.Read tests against local in-memory service</h1> + <h2 id="qunit-banner"></h2> + <h2 id="qunit-userAgent"></h2> + <ol id="qunit-tests"></ol> +</body> +</html> http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/503b4417/tests/odata-read-functional-tests.js ---------------------------------------------------------------------- diff --git a/tests/odata-read-functional-tests.js b/tests/odata-read-functional-tests.js new file mode 100644 index 0000000..29f28e4 --- /dev/null +++ b/tests/odata-read-functional-tests.js @@ -0,0 +1,594 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +(function (window, undefined) { + OData.defaultHandler.accept = "application/json;q=0.9, */*;q=0.1"; + var unexpectedErrorHandler = function (err) { + djstest.assert(false, "Unexpected call to error handler with error: " + djstest.toString(err)); + djstest.done(); + }; + + var validServiceDocumentAcceptHeaders = [ + "*/*", + "application/json", + undefined + ]; + + var validMetadataAcceptHeaders = [ + "*/*", + "application/xml", + undefined + ]; + + var invalidServiceDocumentAcceptHeaders = [ + "application/atom+xml" + ]; + + var invalidMetadataAcceptHeaders = [ + "application/json" + ]; + + var handlerAcceptStrings = [ + "*/*", + "application/json", + undefined + ]; + + var httpStatusCode = { + notFound: 404, + badRequest: 400, + unsupportedMediaType: 415 + }; + + var service = "./endpoints/FoodStoreDataServiceV4.svc/"; + var epmService = "./endpoints/EpmDataService.svc/"; + var feed = service + "Foods"; + var categoriesFeed = service + "Categories"; + + var expectedErrorMessage = "HTTP request failed"; + + module("Functional", { + setup: function () { + djstest.wait(function (done) { + $.post(service + "ResetData", done); + }); + window.odatajs.oData.json.jsonHandler.recognizeDates = false; + } + }); + + for (var i = 0; i < handlerAcceptStrings.length; i++) { + + djstest.addTest(function readFullFeedTest(handlerAccept) { + djstest.assertsExpected(1); + odatajs.oData.read({ requestUri: feed, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readFeed(feed, + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Response data not same as expected"); + djstest.done(); + }, handlerAccept + ); + }, + unexpectedErrorHandler + ); + }, "Testing valid read of full feed collection with " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function readMaxAndNullValueEntryTest(handlerAccept) { + var endPoint = feed + "(0)"; + djstest.assertsExpected(1); + odatajs.oData.read({ requestUri: endPoint, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readEntry(endPoint, + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Response data not same as expected"); + djstest.done(); + }, handlerAccept + ); + }, + unexpectedErrorHandler + ); + }, "Testing valid read of entry with max numbers, complex types, and null and empty strings " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function readMinAndZeroValueEntryTest(handlerAccept) { + var endPoint = feed + "(1)"; + djstest.assertsExpected(1); + odatajs.oData.read({ requestUri: "./endpoints/FoodStoreDataServiceV4.svc/Foods(1)", headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readEntry(endPoint, + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Response data not same as expected"); + djstest.done(); + }, handlerAccept + ); + }, + unexpectedErrorHandler); + }, "Testing valid read of minimum and zero values " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function readNullNestedComplexTypeEntryTest(handlerAccept) { + var endPoint = feed + "(2)"; + djstest.assertsExpected(1); + odatajs.oData.read({ requestUri: endPoint, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readEntry(endPoint, + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Response data not same as expected"); + djstest.done(); + }, handlerAccept + ); + }, + unexpectedErrorHandler + ); + }, "Testing valid read of null nested complex type and navigation property " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function readNullComplexTypeEntryTest(handlerAccept) { + var endPoint = feed + "(3)"; + djstest.assertsExpected(1); + odatajs.oData.read({ requestUri: endPoint, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readEntry(endPoint, + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Response data not same as expected"); + djstest.done(); + }, handlerAccept + ); + }, + unexpectedErrorHandler + ); + }, "Testing valid read of null top level complex type" + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function readNullPropertiesDerivedEntryTest(handlerAccept) { + djstest.assertsExpected(1); + var endPoint = feed + "(4)"; + odatajs.oData.read({ requestUri: endPoint, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readEntry(endPoint, + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Response data not same as expected"); + djstest.done(); + }, handlerAccept + ); + }, + unexpectedErrorHandler + ); + }, "Testing valid read of derived type null properties with " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function readNextComplexTypeDerivedEntryTest(handlerAccept) { + + djstest.assertsExpected(1); + var endPoint = feed + "(5)"; + odatajs.oData.read({ requestUri: endPoint, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readEntry(endPoint, + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Response data not same as expected"); + djstest.done(); + }, handlerAccept + ); + }, + unexpectedErrorHandler + ); + }, "Testing valid read of derived type with full nested complex type properties with " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function readEntryWithInlineFeedTest(handlerAccept) { + var endpoint = categoriesFeed + "(0)?$expand=Foods"; + djstest.assertsExpected(2); + odatajs.oData.read({ requestUri: endpoint, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readEntry(endpoint, + function (expectedData) { + djstest.assertAreEqualDeep(data.value, expectedData.value, "Verify inline feed"); + djstest.assertAreEqualDeep(data, expectedData, "Verify entry"); + djstest.done(); + }, handlerAccept + ); + }, + unexpectedErrorHandler + ); + }, "Testing read of entry with inline feed with " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function readFeedWithEmptyInlineFeedTest(handlerAccept) { + var endpoint = categoriesFeed + "?$filter=Name eq 'Empty Category'&$expand=Foods"; + djstest.assertsExpected(2); + odatajs.oData.read({ requestUri: endpoint, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readFeed(endpoint, + function (expectedData) { + djstest.assertAreEqualDeep(data.value, expectedData.value, "Verify inline feed"); + djstest.assertAreEqualDeep(data, expectedData, "Verify feed"); + djstest.done(); + }, handlerAccept + ); + }, + unexpectedErrorHandler + ); + }, "Testing read of entry with empty inline feed with " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function readEntryWithInlineEntryTest(handlerAccept) { + var endpoint = feed + "(0)?$expand=Category"; + djstest.assertsExpected(2); + odatajs.oData.read({ requestUri: endpoint, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readEntry(endpoint, + function (expectedData) { + djstest.assertAreEqualDeep(data.Category, expectedData.Category, "Verify inline entry"); + djstest.assertAreEqualDeep(data, expectedData, "Verify entry"); + djstest.done(); + }, handlerAccept + ); + }, + unexpectedErrorHandler + ); + }, "Testing read of entry with inline entry with " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function readFeedWithNullInlineEntryTest(handlerAccept) { + var endpoint = feed + "?$expand=Category&$filter=Category eq null"; + djstest.assertsExpected(2); + odatajs.oData.read({ requestUri: endpoint, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readFeed(endpoint, + function (expectedData) { + djstest.assertAreEqualDeep(data.value, expectedData.value, "Verify inline data"); + djstest.assertAreEqualDeep(data, expectedData, "Verify feed"); + djstest.done(); + }, handlerAccept); + }, + unexpectedErrorHandler + ); + }, "Testing read of feed with null inline entry with " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function readFeedWithInlineCountTest(handlerAccept) { + var endpoint = feed + "?$count=true"; + djstest.assertsExpected(2); + odatajs.oData.read({ requestUri: endpoint, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readFeed(endpoint, + function (expectedData) { + djstest.assertAreEqual(data["@odata.count"], expectedData["@odata.count"], "Verify count in response data"); + djstest.assertAreEqualDeep(data, expectedData, "Verify feed"); + djstest.done(); + }, handlerAccept + ); + }, + unexpectedErrorHandler + ); + }, "Testing read of collection with inline count with " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function selectSinglePropertyOnEntryTest(handlerAccept) { + var endpoint = feed + "(0)?$select=Name"; + djstest.assertsExpected(1); + odatajs.oData.read({ requestUri: endpoint, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readEntry(endpoint, + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Verify select result"); + djstest.done(); + }, handlerAccept + ); + }, + unexpectedErrorHandler); + }, "Select single property of entry " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function selectComplexTypeOnFeedTest(handlerAccept) { + var endpoint = feed + "?$select=Packaging"; + djstest.assertsExpected(1); + odatajs.oData.read({ requestUri: endpoint, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readFeed(endpoint, + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Verify select result"); + djstest.done(); + }, handlerAccept + ); + }, + unexpectedErrorHandler); + }, "Select single complex type property of feed " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function selectMultiplePropertiesOnEntryTest(handlerAccept) { + var endpoint = feed + "(3)?$select=Packaging,ExpirationDate,IsAvailable"; + djstest.assertsExpected(1); + odatajs.oData.read({ requestUri: endpoint, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readEntry(endpoint, + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Verify select result"); + djstest.done(); + }, handlerAccept + ); + }, + unexpectedErrorHandler); + }, "Select multiple primitive properties of feed " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function readPagedCategoriesCollectionTest(handlerAccept) { + var endpoint = categoriesFeed; + djstest.assertsExpected(1); + odatajs.oData.read({ requestUri: endpoint, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readFeed(endpoint, + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Verify response data"); + djstest.done(); + }, handlerAccept + ); + }, unexpectedErrorHandler); + }, "Testing read of paged collection with " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function readPagedCollectionWithInlineCountTest(handlerAccept) { + var endpoint = categoriesFeed + "?$count=true"; + djstest.assertsExpected(2); + odatajs.oData.read({ requestUri: endpoint, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readFeed(endpoint, + function (expectedData) { + djstest.assertAreEqual(data["@odata.context"], expectedData["@odata.context"], "Verify count in response data"); + djstest.assertAreEqualDeep(data, expectedData, "Verify feed"); + djstest.done(); + }, handlerAccept + ); + }, unexpectedErrorHandler); + }, "Testing read of paged collection with inline count with " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function readEntryWithNamedStreams(handlerAccept) { + var endpoint = feed + "(1)?$expand=Category"; + djstest.assertsExpected(1); + odatajs.oData.read({ requestUri: endpoint, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readEntry(endpoint, + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Verify entry"); + djstest.done(); + }, handlerAccept + ); + }, unexpectedErrorHandler); + }, "Testing read of entry with named streams " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function readEntryWithCollectionProperties(handlerAccept) { + var endpoint = feed + "(0)"; + djstest.assertsExpected(1); + odatajs.oData.read({ requestUri: endpoint, headers: { Accept: handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readEntry(endpoint, + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Verify entry"); + djstest.done(); + }, handlerAccept + ); + }, unexpectedErrorHandler); + }, "Testing read of entry with collection properties " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function invalidEntryReadTest(handlerAccept) { + var endPoint = feed + "(16)"; + djstest.assertsExpected(2); + odatajs.oData.read({ requestUri: endPoint, headers: { Accept: handlerAccept} }, + function (data, response) { + djstest.assert(false, "We should not get here because data is not valid."); + djstest.done() + }, + function (err) { + djstest.assertAreEqual(err.message, expectedErrorMessage, "Error message"); + djstest.assertAreEqual(err.response.statusCode, httpStatusCode.notFound, "Response status code"); + djstest.done(); + }); + }, "Testing invalid entry read with " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function invalidFeedReadTest(handlerAccept) { + var endPoint = feed + "Invalid"; + djstest.assertsExpected(2); + odatajs.oData.read({ requestUri: endPoint, headers: { Accept: handlerAccept} }, + function (data, response) { + djstest.assert(false, "We should not get here because data is not valid."); + djstest.done(); + }, + function (err) { + djstest.assertAreEqual(err.message, expectedErrorMessage, "Error message"); + djstest.assertAreEqual(err.response.statusCode, httpStatusCode.notFound, "Response status code"); + djstest.done(); + }); + }, "Testing invalid feed read with " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function standardErrorReadTest(handlerAccept) { + var endPoint = feed + "?$foo=bar"; + djstest.assertsExpected(2); + odatajs.oData.read({ requestUri: endPoint, headers: { Accept: handlerAccept} }, + function (data, response) { + djstest.assert(false, "We should not get here because data is not valid."); + djstest.done() + }, + function (err) { + djstest.assertAreEqual(err.message, expectedErrorMessage, "Error message"); + djstest.assertAreEqual(err.response.statusCode, httpStatusCode.badRequest, "Response status code"); + djstest.done(); + }); + }, "Testing standard error read with " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function inStreamErrorReadTest(handlerAccept) { + var endPoint = "./endpoints/ErrorDataService.svc/Entities"; + djstest.assertsExpected(1); + odatajs.oData.read({ requestUri: endPoint, headers: { Accept: handlerAccept} }, function (data, response) { + djstest.assert(false, "Unexpected call to success handler with response: " + djstest.toString(response)); + djstest.done() + }, function (err) { + djstest.assert(err.response.body.indexOf("An error occurred while processing this request") > -1, "Error handler was called with the correct response body"); + djstest.done(); + }); + }, "Testing in-stream error read with " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + var user = "djsUser"; + var password = "djsPassword"; + + djstest.addTest(function readFullFeedBasicAuthTest(handlerAccept) { + var endpoint = "./endpoints/BasicAuthDataService.svc/Customers"; + djstest.assertsExpected(1); + odatajs.oData.read({ requestUri: endpoint, headers: { Accept: handlerAccept }, user: user, password: password }, function (data, response) { + window.ODataVerifyReader.readFeed({ url: endpoint, user: user, password: password }, function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Response data not same as expected"); + djstest.done(); + }, handlerAccept); + }, unexpectedErrorHandler); + }, "Testing valid read of full feed collection on basic auth with " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + + djstest.addTest(function readEntryBasicAuthTest(handlerAccept) { + var endpoint = "./endpoints/BasicAuthDataService.svc/Customers(1)"; + djstest.assertsExpected(1); + odatajs.oData.read({ requestUri: endpoint, headers: { Accept: handlerAccept }, user: user, password: password }, function (data, response) { + window.ODataVerifyReader.readEntry({ url: endpoint, user: user, password: password }, function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Response data not same as expected"); + djstest.done(); + }, handlerAccept); + }, unexpectedErrorHandler); + }, "Testing valid read of entry on basic auth with " + handlerAcceptStrings[i], handlerAcceptStrings[i]); + } + + var services = [ + service, + epmService + ]; + + $.each(services, function (_, serviceName) { + $.each(validServiceDocumentAcceptHeaders, function (_, validServiceDocumentAcceptHeader) { + var parameters = { handlerAccept: validServiceDocumentAcceptHeader, serviceName: serviceName }; + + djstest.addTest(function validReadServiceDocumentTest(params) { + djstest.assertsExpected(1); + odatajs.oData.read({ requestUri: params.serviceName, headers: { Accept: params.handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readServiceDocument(serviceName, + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Response data not same as expected"); + djstest.done(); + }, params.handlerAccept + ); + }, + unexpectedErrorHandler + ); + }, "Testing valid read of service document " + parameters.handlerAccept + " on service " + parameters.serviceName, parameters); + }); + + $.each(invalidServiceDocumentAcceptHeaders, function (_, invalidServiceDocumentAcceptHeader) { + var parameters = { handlerAccept: invalidServiceDocumentAcceptHeader, serviceName: serviceName }; + + djstest.addTest(function invalidReadServiceDocumentTest(params) { + djstest.assertsExpected(2); + odatajs.oData.read({ requestUri: params.serviceName, headers: { Accept: params.handlerAccept} }, + function success(data, response) { + djstest.fail("Reading service document should produce error with " + params.handlerAccept); + djstest.done(); + }, + function (err) { + djstest.assertAreEqual(err.message, expectedErrorMessage, "Error message"); + djstest.assertAreEqual(err.response.statusCode, httpStatusCode.unsupportedMediaType, "Response status code"); + djstest.done(); + } + ); + }, "Testing read of service document with invalid MIME type " + parameters.invalidServiceDocumentAcceptHeader + " on service " + serviceName, parameters); + }); + + //to do: + $.each(validMetadataAcceptHeaders, function (_, validMetadataAcceptHeader) { + var parameters = { handlerAccept: validMetadataAcceptHeader, serviceName: serviceName }; + + djstest.addTest(function validReadMetadataTest(params) { + djstest.assertsExpected(1); + var endPoint = params.serviceName + "$metadata"; + odatajs.oData.read({ requestUri: endPoint, headers: { Accept: params.handlerAccept} }, + function (data, response) { + window.ODataVerifyReader.readMetadata(endPoint, + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Response data not same as expected"); + djstest.done(); + } + ); + }, + unexpectedErrorHandler, + OData.metadataHandler + ); + }, "Testing valid read metadata " + parameters.handlerAccept + " on service " + parameters.serviceName, parameters); + }); + + $.each(invalidMetadataAcceptHeaders, function (_, invalidMetadataAcceptHeader) { + var parameters = { handlerAccept: invalidMetadataAcceptHeader, serviceName: serviceName }; + djstest.addTest(function invlaidReadMetadataTest(params) { + djstest.assertsExpected(2); + var endPoint = params.serviceName + "$metadata"; + odatajs.oData.read({ requestUri: endPoint, headers: { Accept: params.handlerAccept} }, + function success(data, response) { + djstest.fail("Reading metadata should produce error with " + params.handlerAccept); + djstest.done(); + }, + function (err) { + djstest.assertAreEqual(err.message, expectedErrorMessage, "Error message"); + djstest.assertAreEqual(err.response.statusCode, httpStatusCode.unsupportedMediaType, "Response status code"); + djstest.done(); + }, + OData.metadataHandler + ); + }, "Testing read metadata with invalid MIME type " + parameters.handlerAccept + " on service " + parameters.serviceName, parameters); + }); + }); + + // To do: update the test data for enabling the annotation test + djstest.addFullTest(true, function metadataElementExtensionsTest() { + var csdlFile = "./endpoints/CustomAnnotations.xml"; + var modifyTypeHttpClient = {}; + var originalHttpClient = window.odatajs.oData.net.defaultHttpClient; + + // Modify the content-type of the response so that it is accepted by the metadataHandler. + // By default, the content-type of CustomAnnotations.xml comes back as text/xml + modifyTypeHttpClient.request = function (request, success, error) { + return originalHttpClient.request(request, function (response) { + response.headers["Content-Type"] = "application/xml"; + success(response); + }, error); + } + + window.odatajs.oData.net.defaultHttpClient = modifyTypeHttpClient; + + odatajs.oData.read({ requestUri: csdlFile, headers: { Accept: "text/xml"} }, + function (data) { + window.ODataVerifyReader.readMetadata(csdlFile, + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Response data not same as expected"); + djstest.done(); + } + ) + }, + unexpectedErrorHandler, OData.metadataHandler + ); + }); + + djstest.addTest(function verifyNonDefaultReadMethodCalled() { + var endPoint = feed + "(0)"; + djstest.assertsExpected(2); + odatajs.oData.read( + { requestUri: endPoint }, + function success(data, response) { + djstest.assert(true, "Test executed"); + djstest.done(); + }, + null, + { + read: function (response) { + djstest.assert(true, "Non-default read reached"); + djstest.done(); + }, + accept: "*/*" + } + ); + }, "Testing nondefault read is called."); + +})(this); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/503b4417/tests/odata-request-functional-tests.html ---------------------------------------------------------------------- diff --git a/tests/odata-request-functional-tests.html b/tests/odata-request-functional-tests.html new file mode 100644 index 0000000..331cf8c --- /dev/null +++ b/tests/odata-request-functional-tests.html @@ -0,0 +1,49 @@ +<!-- +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. +*/ +--> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> + <title>odata.request tests</title> + <meta http-equiv="cache-control" content="no-cache" /> + <meta http-equiv="pragma" content="no-cache" /> + <meta http-equiv="expires" content="-1" /> + <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.10.0.css" type="text/css" /> + <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js"></script> + <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"></script> + <script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.10.0.js"></script> + <script type="text/javascript" src="common/odataVerifyReader.js"></script> + <script type="text/javascript" src="common/TestSynchronizerClient.js"></script> + <script type="text/javascript"> + window.TestSynchronizer.init(QUnit); + </script> + + <script type="text/javascript" src="../build/odatajs-4.0.0-beta-01.js"></script> + <script type="text/javascript" src="common/common.js"></script> + <script type="text/javascript" src="common/djstest.js"></script> + <script type="text/javascript" src="odata-request-functional-tests.js"></script> +</head> +<body> + <h1 id="qunit-header">odata.request tests</h1> + <h2 id="qunit-banner"></h2> + <h2 id="qunit-userAgent"></h2> + <ol id="qunit-tests"></ol> +</body> +</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/503b4417/tests/odata-request-functional-tests.js ---------------------------------------------------------------------- diff --git a/tests/odata-request-functional-tests.js b/tests/odata-request-functional-tests.js new file mode 100644 index 0000000..eadb6a6 --- /dev/null +++ b/tests/odata-request-functional-tests.js @@ -0,0 +1,399 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +(function (window, undefined) { + OData.defaultHandler.accept = "application/json;q=0.9, */*;q=0.1"; + var unexpectedErrorHandler = function (err) { + djstest.assert(false, "Unexpected call to error handler with error: " + djstest.toString(err)); + djstest.done(); + }; + + var verifyRequest = function (request, done) { + if (request.method == "POST") { + verifyPost(request, done); + } + else if (request.method == "PUT") { + verifyPut(request, done); + } + else if (request.method == "PATCH") { + verifyPatch(request, done); + } + }; + + var tryRemoveOdataType = function (data) { + if (data && data["@odata.type"]) { + delete data["@odata.type"]; + } + + return data; + }; + + var verifyPost = function (request, done) { + var httpOperation = request.method + " " + request.requestUri; + djstest.log(httpOperation); + odatajs.oData.request(request, function (data, response) { + djstest.log("Status code:" + response.statusCode); + djstest.assertAreEqual(response.statusCode, httpStatusCode.created, "Verify response code: " + httpOperation); + djstest.log("Uri:" + request.requestUri); + ODataVerifyReader.readEntry(response.headers["Location"], function (expectedData) { + djstest.assertAreEqualDeep(response.data, expectedData, "Verify new entry against response: " + httpOperation); + done(); + }, request.headers.Accept); + }, unexpectedErrorHandler); + }; + + var verifyPut = function(request, done) { + var httpOperation = request.method + " " + request.requestUri; + djstest.log(httpOperation); + odatajs.oData.request(request, function(data, response) { + djstest.log("Status code:" + response.statusCode); + djstest.assertAreEqual(response.statusCode, httpStatusCode.noContent, "Verify response code: " + httpOperation); + djstest.log("Uri:" + request.requestUri); + ODataVerifyReader.readEntry(request.requestUri, function(actualData) { + var requestData = tryRemoveOdataType(request.data); + djstest.assertAreEqualDeep(subset(actualData, requestData), requestData, "Verify updated entry: " + httpOperation); + done(); + }, request.headers.Accept); + }, unexpectedErrorHandler); + }; + + var verifyPatch = function (request, done) { + var httpOperation = request.method + " " + request.requestUri; + djstest.log(httpOperation); + ODataVerifyReader.readEntry(request.requestUri, function (originalData) { + odatajs.oData.request(request, function (data, response) { + djstest.log("Status code:" + response.statusCode); + djstest.assertAreEqual(response.statusCode, httpStatusCode.noContent, "Verify response code"); + djstest.log("Uri:" + request.requestUri); + ODataVerifyReader.readEntry(request.requestUri, function (actualData) { + + // Merge the original data with the updated data to get the expected data + var expectedData = $.extend(true, {}, originalData, request.data); + djstest.assertAreEqualDeep(actualData, tryRemoveOdataType(expectedData), "Verify merged data"); + done(); + }, request.headers["Content-Type"]); + }, unexpectedErrorHandler); + }, request.headers["Content-Type"]); + }; + + // Returns a subset of object with the same set of properties (recursive) as the subsetObject + var subset = function (object, subsetObject) { + if (typeof (object) == "object" && typeof (subsetObject) == "object") { + var result = {}; + for (subsetProp in subsetObject) { + result[subsetProp] = subset(object[subsetProp], subsetObject[subsetProp]); + } + return result; + } + else { + return object; + } + }; + + var foodData = { + "@odata.type": "#DataJS.Tests.V4.Food", + FoodID: 42, + Name: "olive oil", + UnitPrice: 3.14, + ServingSize: 1, + MeasurementUnit: "", + ProteinGrams: 5, + FatGrams: 9, + CarbohydrateGrams: 2, + CaloriesPerServing: 6, + IsAvailable: true, + ExpirationDate: "2010-12-25T12:00:00Z", + ItemGUID: "27272727-2727-2727-2727-272727272727", + Weight: 10, + AvailableUnits: 1, + Packaging: { + Type: "Can", + Color: null, + NumberPerPackage: 1, + RequiresRefridgeration: false, + PackageDimensions: { + Length: 4, + Height: 3, + Width: 2, + Volume: 1 + }, + ShipDate: "2010-12-25T12:00:00Z" + } + }; + + var testServices = { + V4: "./endpoints/FoodStoreDataServiceV4.svc" + }; + + var testData = { + V4: $.extend(true, {}, foodData, { + AlternativeNames: ["name1", "name2"], + Providers: + [{ + Name: "Provider", + Aliases: ["alias1"], + Details: { + Telephone: "555-555-555", + PreferredCode: 999 + } + }, + { + Name: "Provider2", + Aliases: [], + Details: null + } + ] + }) + }; + + var mimeTypes = [undefined, "application/json;odata.metadata=minimal"]; + + var httpStatusCode = { + created: 201, + noContent: 204, + notFound: 404 + }; + + $.each(testServices, function (serviceName, service) { + var newFood = testData[serviceName]; + + var foodsFeed = service + "/Foods"; + var categoriesFeed = service + "/Categories"; + + module("Functional", { + setup: function () { + djstest.log("Resetting data"); + djstest.wait(function (done) { + $.post(service + "/ResetData", done); + }); + } + }); + + $.each(mimeTypes, function (_, mimeType) { + // Provide coverage for both undefined and specific DSVs + // For all other cases DSV = undefined is a valid scenario + var dataServiceVersions = ["4.0"]; + + $.each(dataServiceVersions, function (_, dataServiceVersion) { + var headers; + if (mimeType || dataServiceVersion) { + headers = { + "Content-Type": mimeType, + Accept: mimeType, + "OData-Version": dataServiceVersion + }; + } + + djstest.addTest(function addEntityTest(headers) { + var request = { + requestUri: categoriesFeed, + method: "POST", + headers: headers, + data: { + CategoryID: 42, + Name: "New Category" + } + }; + + djstest.assertsExpected(2); + verifyRequest(request, djstest.done); + }, "Add new entity to " + serviceName + " service using mimeType = " + mimeType + " and DSV = " + dataServiceVersion, headers); + + djstest.addTest(function addEntityWithUTF16CharTest(headers) { + var request = { + requestUri: categoriesFeed, + method: "POST", + headers: headers, + data: { + CategoryID: 42, + Name: "\u00f6 New Category \u00f1" + } + }; + + djstest.assertsExpected(2); + verifyRequest(request, djstest.done); + }, "Add new entity with UTF-16 character to " + serviceName + " service using mimeType = " + mimeType + " and DSV = " + dataServiceVersion, headers); + + djstest.addTest(function addLinkedEntityTest(headers) { + var request = { + requestUri: categoriesFeed + "(0)/Foods", + method: "POST", + headers: headers, + data: newFood + }; + + djstest.assertsExpected(2); + verifyRequest(request, djstest.done); + }, "Add new linked entity to " + serviceName + " service using mimeType = " + mimeType + " and DSV = " + dataServiceVersion, headers); + + djstest.addTest(function addEntityWithInlineFeedTest(headers) { + var request = { + requestUri: categoriesFeed, + method: "POST", + headers: headers, + data: { + CategoryID: 42, + Name: "Olive Products", + Foods: [newFood] + } + }; + + djstest.assertsExpected(3); + verifyRequest(request, function () { + ODataVerifyReader.readEntry(foodsFeed + "(" + newFood.FoodID + ")", function (actualData) { + djstest.assertAreEqual(actualData.Name, newFood.Name, "Verify inline entities were added"); + djstest.done(); + }, headers ? headers.Accept : undefined); + }); + }, "Add new entity with inline feed to " + serviceName + " service using mimeType = " + mimeType + " and DSV = " + dataServiceVersion, headers); + + djstest.addTest(function addEntityWithInlineEntryTest(headers) { + var request = { + requestUri: foodsFeed, + method: "POST", + headers: headers, + data: $.extend({}, newFood, { + Category: { + CategoryID: 42, + Name: "Olive Products" + } + }) + }; + + djstest.assertsExpected(3); + verifyRequest(request, function () { + ODataVerifyReader.readEntry(categoriesFeed + "(" + request.data.Category.CategoryID + ")", function (actualData) { + djstest.assertAreEqual(actualData.Name, request.data.Category.Name, "Verify inline entities were added"); + djstest.done(); + }, headers ? headers.Accept : undefined); + }); + }, "Add new entity with inline entry to " + serviceName + " service using mimeType = " + mimeType + " and DSV = " + dataServiceVersion, headers); + + djstest.addTest(function updateEntityTest(headers) { + var request = { + requestUri: categoriesFeed + "(0)", + method: "PUT", + headers: headers, + data: { + CategoryID: 0, + Name: "Updated Category" + } + }; + + djstest.assertsExpected(2); + verifyRequest(request, djstest.done); + }, "Update entity to " + serviceName + " service using mimeType = " + mimeType + " and DSV = " + dataServiceVersion, headers); + + if (serviceName === "V4") { + djstest.addTest(function updateEntityTest(headers) { + var request = { + requestUri: foodsFeed + "(0)", + method: "PATCH", + headers: headers, + data: { + "@odata.type": "#DataJS.Tests.V4.Food", + AlternativeNames: ["one", "two"] + } + }; + + djstest.assertsExpected(2); + verifyRequest(request, djstest.done); + }, "Update collection property to " + serviceName + " service using mimeType = " + mimeType + " and DSV = " + dataServiceVersion, headers); + } + + djstest.addTest(function updatePrimitivePropertyTest(headers) { + var request = { + requestUri: categoriesFeed + "(0)/Name", + method: "PUT", + headers: headers, + data: { value: "Updated Category" } + }; + + djstest.assertsExpected(2); + verifyRequest(request, djstest.done); + }, "Update primitive property to " + serviceName + " service using mimeType = " + mimeType + " and DSV = " + dataServiceVersion, headers); + + djstest.addTest(function updateLinkedEntityTest(headers) { + var request = { + requestUri: categoriesFeed + "(0)/Foods(0)", + method: "PUT", + headers: headers, + data: { + "@odata.type": "#DataJS.Tests.V4.Food", + Name: "Updated Food" + } + }; + + djstest.assertsExpected(2); + verifyRequest(request, djstest.done); + }, "Update linked entity to " + serviceName + " service using mimeType = " + mimeType + " and DSV = " + dataServiceVersion, headers); + + djstest.addTest(function mergeEntityTest(headers) { + var request = { + requestUri: categoriesFeed + "(0)", + method: "PATCH", + headers: headers, + data: { Name: "Merged Category" } + }; + + djstest.assertsExpected(2); + verifyRequest(request, djstest.done); + }, "Merge entity to " + serviceName + " service using mimeType = " + mimeType + " and DSV = " + dataServiceVersion, headers); + + djstest.addTest(function mergeLinkedEntityTest(headers) { + var request = { + requestUri: categoriesFeed + "(0)/Foods(0)", + method: "PATCH", + headers: headers, + data: { + "@odata.type": "#DataJS.Tests.V4.Food", + Name: "Merged Food" + } + }; + + djstest.assertsExpected(2); + verifyRequest(request, djstest.done); + }, "Merge linked entity to " + serviceName + " service using mimeType = " + mimeType + " and DSV = " + dataServiceVersion, headers); + + djstest.addTest(function deleteEntityTest(headers) { + var endpoint = categoriesFeed + "(0)"; + djstest.assertsExpected(2); + odatajs.oData.request({ + requestUri: endpoint, + method: "DELETE", + headers: headers + }, function (data, response) { + djstest.assertAreEqual(response.statusCode, httpStatusCode.noContent, "Verify response code"); + $.ajax({ + url: endpoint, + error: function (xhr) { + djstest.assertAreEqual(xhr.status, httpStatusCode.notFound, "Verify response code of attempted retrieval after delete"); + djstest.done(); + }, + success: function () { + djstest.fail("Delete failed: querying the endpoint did not return expected response code"); + djstest.done(); + } + }); + }, unexpectedErrorHandler); + }, "Delete entity from " + serviceName + " service using mimeType = " + mimeType + " and DSV = " + dataServiceVersion, headers); + }); + }); + }); +})(this); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/503b4417/tests/odata-roundtrip-functional-tests.js ---------------------------------------------------------------------- diff --git a/tests/odata-roundtrip-functional-tests.js b/tests/odata-roundtrip-functional-tests.js new file mode 100644 index 0000000..597c273 --- /dev/null +++ b/tests/odata-roundtrip-functional-tests.js @@ -0,0 +1,389 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +(function (window, undefined) { + var unexpectedErrorHandler = function (err) { + djstest.assert(false, "Unexpected call to error handler with error: " + djstest.toString(err)); + djstest.done(); + }; + + var verifyRequest = function (request, done) { + if (request.method == "POST") { + if (request.headers && request.headers["X-HTTP-Method"] == "MERGE") { + verifyMerge(request, done); + } + else { + verifyPost(request, done); + } + } + else if (request.method == "PUT") { + verifyPut(request, done); + } + }; + + var verifyPost = function (request, done) { + var httpOperation = request.method + " " + request.requestUri; + odatajs.oData.request(request, function (data, response) { + djstest.assertAreEqual(response.statusCode, httpStatusCode.created, "Verify response code: " + httpOperation); + ODataVerifyReader.readJson(data.__metadata.uri, function (expectedData) { + djstest.assertAreEqualDeep(response.data, expectedData, "Verify new entry against response: " + httpOperation); + done(); + }, request.headers.Accept); + }, unexpectedErrorHandler); + }; + + var verifyPut = function (request, done) { + var httpOperation = request.method + " " + request.requestUri; + odatajs.oData.request(request, function (data, response) { + djstest.assertAreEqual(response.statusCode, httpStatusCode.noContent, "Verify response code: " + httpOperation); + ODataVerifyReader.readJson(request.requestUri, function (actualData) { + djstest.assertAreEqualDeep(actualData, request.data, "Verify updated entry: " + httpOperation); + done(); + }, request.headers.Accept); + }, unexpectedErrorHandler); + } + + var verifyMerge = function (request, done) { + var httpOperation = request.method + " " + request.requestUri; + ODataVerifyReader.readJson(request.requestUri, function (originalData) { + odatajs.oData.request(request, function (data, response) { + djstest.assertAreEqual(response.statusCode, httpStatusCode.noContent, "Verify response code"); + ODataVerifyReader.readJson(request.requestUri, function (actualData) { + // Merge the original data with the updated data to get the expected data + var expectedData = $.extend(true, {}, originalData, request.data); + djstest.assertAreEqualDeep(actualData, expectedData, "Verify merged data"); + done(); + }, request.headers["Content-Type"]); + }, unexpectedErrorHandler); + }, request.headers["Content-Type"]); + } + + // Returns a subset of object with the same set of properties (recursive) as the subsetObject + var subset = function (object, subsetObject) { + if (typeof (object) == "object" && typeof (subsetObject) == "object") { + var result = {}; + for (subsetProp in subsetObject) { + result[subsetProp] = subset(object[subsetProp], subsetObject[subsetProp]); + } + return result; + } + else { + return object; + } + }; + + var service = "./endpoints/FoodStoreDataService.svc"; + var foodsFeed = service + "/Foods"; + var categoriesFeed = service + "/Categories"; + //var mimeTypes = [undefined, "application/json", "application/atom+xml"]; + var mimeTypes = ["application/json", "application/atom+xml"]; + + var httpStatusCode = { + created: 201, + noContent: 204, + notFound: 404 + }; + + var newFood = { + "__metadata": { + type: "DataJS.Tests.Food" + }, + FoodID: 42, + Name: "olive oil", + UnitPrice: 3.14, + ServingSize: "1", + MeasurementUnit: "Cup", + ProteinGrams: 5, + FatGrams: 9, + CarbohydrateGrams: 2, + CaloriesPerServing: "6", + IsAvailable: true, + ExpirationDate: new Date("2011/05/03 12:00:00 PM"), + ItemGUID: "27272727-2727-2727-2727-272727272727", + Weight: 10, + AvailableUnits: 1, + Packaging: { + Type: "Can", + Color: "White", + NumberPerPackage: 1, + RequiresRefridgeration: false, + PackageDimensions: { + Length: "4", + Height: 3, + Width: "2", + Volume: 1 + }, + ShipDate: new Date("2011/01/01 12:00:00 PM") + } + }; + + var newFoodLinks = { + uri: foodsFeed + "(1)" + } + + module("Functional", { + setup: function () { + $.ajax({ async: false, type: "POST", url: service + "/ResetData" }); + } + }); + + $.each(mimeTypes, function (_, mimeType) { + var headers = mimeType ? { "Content-Type": mimeType, Accept: mimeType} : undefined; + + djstest.addTest(function addEntityTest(headers) { + var request = { + requestUri: categoriesFeed, + method: "POST", + headers: headers, + data: { + CategoryID: 42, + Name: "New Category" + } + }; + + verifyRequest(request, function () { + odatajs.oData.read({ requestUri: categoriesFeed + "(42)", headers: { Accept: mimeType} }, function (actualData, response) { + actualData.CategoryID = 27; + var newRequest = { + requestUri: categoriesFeed, + method: "POST", + headers: headers, + data: actualData + }; + verifyRequest(newRequest, function () { djstest.done(); }); + }, request.headers["Content-Type"]); + }); + + }, "Post, read posted data, post read data (mimeType = " + mimeType + ")", headers); + + djstest.addTest(function addLinkedEntityTest(headers) { + var request = { + requestUri: categoriesFeed + "(0)/Foods", + method: "POST", + headers: headers, + data: newFood + }; + + verifyRequest(request, function () { + odatajs.oData.read({ requestUri: categoriesFeed + "(0)/Foods(42)", headers: { Accept: mimeType} }, function (actualData, response) { + actualData.FoodID = 94; + var newRequest = { + requestUri: categoriesFeed + "(0)/Foods", + method: "POST", + headers: headers, + data: actualData + }; + verifyRequest(newRequest, function () { djstest.done(); }); + }, request.headers["Content-Type"]); + }); + }, "POST, read, POST an entry " + mimeType + ")", headers); + + + djstest.addTest(function addLinkedEntityTest(headers) { + var request = { + requestUri: categoriesFeed + "(0)/Foods(0)", + method: "PUT", + headers: headers, + data: newFood + }; + + verifyRequest(request, function () { + odatajs.oData.read({ requestUri: categoriesFeed + "(0)/Foods(0)", headers: { Accept: mimeType} }, function (actualData, response) { + var newRequest = { + requestUri: categoriesFeed + "(0)/Foods(0)", + method: "PUT", + headers: headers, + data: { + "__metadata": { type: "DataJS.Tests.Food" }, + Name: "New Food" + } + }; + verifyRequest(newRequest, function () { djstest.done(); }); + }); + }); + }, "PUT, read, PUT a new linked entry " + mimeType + ")", headers); + + djstest.addTest(function addEntityWithInlineFeedTest(headers) { + var request = { + requestUri: categoriesFeed, + method: "POST", + headers: headers, + data: { + CategoryID: 42, + Name: "Olive Products", + Foods: [newFood] + } + }; + + verifyRequest(request, function () { + odatajs.oData.read({ requestUri: foodsFeed + "(" + newFood.FoodID + ")", headers: { Accept: mimeType} }, function (actualData, response) { + var newRequest = { + requestUri: categoriesFeed, + method: "POST", + headers: headers, + data: { + CategoryID: 27, + Name: "Olive Products", + Foods: [actualData] + } + }; + verifyRequest(newRequest, function () { djstest.done(); }); + }); + }); + + }, "POST, read, POST an entity with inline feed " + mimeType + ")", headers); + + djstest.addTest(function addEntityWithInlineEntryTest(headers) { + var request = { + requestUri: foodsFeed, + method: "POST", + headers: headers, + data: $.extend({}, newFood, { + Category: { + "__metadata": { uri: "" }, + CategoryID: 42, + Name: "Olive Products" + } + }) + }; + + verifyRequest(request, function () { + odatajs.oData.read({ requestUri: foodsFeed + "(" + newFood.FoodID + ")", headers: { Accept: mimeType} }, function (actualData, response) { + actualData.FoodID = 76; + var newRequest = { + requestUri: foodsFeed, + method: "POST", + headers: headers, + data: $.extend({}, actualData, { + Category: { + "__metadata": { uri: "" }, + CategoryID: 27, + Name: "Olive Products" + } + }) + }; + verifyRequest(newRequest, function () { djstest.done(); }); + }); + }); + }, "Add new entity with inline entry (mimeType = " + mimeType + ")", headers); + + djstest.addTest(function addEntityTest(headers) { + var request = { + requestUri: categoriesFeed + "(1)", + method: "PUT", + headers: headers, + data: { + CategoryID: 1, + Name: "New Category" + } + }; + + verifyRequest(request, function () { + odatajs.oData.read({ requestUri: categoriesFeed + "(1)", headers: { Accept: mimeType} }, function (actualData, response) { + actualData.CategoryID = 2; + var newRequest = { + requestUri: categoriesFeed + "(2)", + method: "PUT", + headers: headers, + data: actualData + }; + verifyRequest(newRequest, function () { djstest.done(); }); + }, request.headers["Content-Type"]); + }); + + }, "Put, read put data, put read data (mimeType = " + mimeType + ")", headers); + + djstest.addTest(function addEntityTest(headers) { + odatajs.oData.read({ requestUri: foodsFeed + "(0)", headers: { Accept: mimeType} }, + function (actualData, response) { + actualData.CategoryID = 216; + var request = { + requestUri: foodsFeed, + method: "POST", + headers: headers, + data: actualData + }; + verifyRequest(request, + function () { + odatajs.oData.read({ requestUri: foodsFeed + "(216)", headers: { Accept: mimeType} }, + function (data, response) { + ODataVerifyReader.readJson(foodsFeed + "(216)", + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Response data not same as expected"); + djstest.done(); + }); + }); + }); + }); + }, "Read data with dates, post read data with dates to new ID, read new ID data with dates" + mimeType + ")", headers); + + djstest.addTest(function addEntityTest(headers) { + odatajs.oData.read({ requestUri: categoriesFeed + "(0)", headers: { Accept: mimeType} }, + function (actualData, response) { + actualData.CategoryID = 81; + var request = { + requestUri: categoriesFeed, + method: "POST", + headers: headers, + data: actualData + }; + verifyRequest(request, + function () { + odatajs.oData.read({ requestUri: categoriesFeed + "(81)", headers: { Accept: mimeType} }, + function (data, response) { + ODataVerifyReader.readJson(categoriesFeed + "(81)", + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Response data not same as expected"); + djstest.done(); + } + ); + } + ); + } + ); + } + ); + }, "Read existing data, post existing data to new idea, read new ID data" + mimeType + ")", headers); + + + djstest.addTest(function addEntityTest(headers) { + odatajs.oData.read({ requestUri: categoriesFeed + "(0)", headers: { Accept: mimeType} }, + function (actualData, response) { + actualData.CategoryID = 81; + var request = { + requestUri: categoriesFeed, + method: "POST", + headers: headers, + data: actualData + }; + verifyRequest(request, + function () { + odatajs.oData.read({ requestUri: categoriesFeed + "(81)", headers: { Accept: mimeType} }, + function (data, response) { + ODataVerifyReader.readJson(categoriesFeed + "(81)", + function (expectedData) { + djstest.assertAreEqualDeep(data, expectedData, "Response data not same as expected"); + djstest.done(); + }); + }); + }); + }); + }, "Read existing data, post existing data to new idea, read new ID data" + mimeType + ")", headers); + }); +})(this); \ No newline at end of file
