From 6a201b2f07ccce43a7e50e809c06129666d92c4c Mon Sep 17 00:00:00 2001 From: Thomas Jaede Date: Mon, 13 Nov 2017 09:20:46 -0800 Subject: [PATCH] Add support for RawPropertyValueToObjectConverter.foreignDescriptor to be descriptor or reference --- .jshintrc | 1 - .../raw-property-value-to-object-converter.js | 11 +- data/service/data-service.js | 4 +- data/service/expression-data-mapping.js | 12 +- data/service/http-service.js | 47 ++++++-- data/service/raw-data-service.js | 38 +++++- test/all.js | 4 +- test/spec/data/http-service.js | 114 ++++++++++++++---- 8 files changed, 178 insertions(+), 53 deletions(-) diff --git a/.jshintrc b/.jshintrc index 1431d2a1a5..ca0f1d710a 100644 --- a/.jshintrc +++ b/.jshintrc @@ -128,7 +128,6 @@ "Map": true, "Set": true, "URL": true, - "console": true, "Promise": true, "Event": true, "CustomEvent": true, diff --git a/data/converter/raw-property-value-to-object-converter.js b/data/converter/raw-property-value-to-object-converter.js index 05e9e80f22..55a031808a 100644 --- a/data/converter/raw-property-value-to-object-converter.js +++ b/data/converter/raw-property-value-to-object-converter.js @@ -49,8 +49,10 @@ exports.RawPropertyValueToObjectConverter = Converter.specialize( /** @lends Raw } value = deserializer.getProperty("foreignDescriptor"); - if (value) { + if (value instanceof ObjectDescriptorReference) { this._foreignDescriptorReference = value; + } else if (value) { + this.foreignDescriptor = value; } value = deserializer.getProperty("service"); @@ -188,10 +190,13 @@ exports.RawPropertyValueToObjectConverter = Converter.specialize( /** @lends Raw foreignDescriptor: { serializable: false, get: function () { - return this._foreignDescriptorReference && this._foreignDescriptorReference.promise(require); + var isReference = this._foreignDescriptor instanceof ObjectDescriptorReference; + return isReference ? this._foreignDescriptor : + this._foreignDescriptor ? Promise.resolve(this._foreignDescriptor) : + this._foreignDescriptorReference && this._foreignDescriptorReference.promise(require); }, set: function (descriptor) { - this._foreignDescriptorReference = new ObjectDescriptorReference().initWithValue(descriptor); + this._foreignDescriptor = descriptor; } }, diff --git a/data/service/data-service.js b/data/service/data-service.js index f21e40142a..83904ef430 100644 --- a/data/service/data-service.js +++ b/data/service/data-service.js @@ -1464,9 +1464,7 @@ exports.DataService = Montage.specialize(/** @lends DataService.prototype */ { }, _dataIdentifierByObject: { - get: function() { - return this.__objectsByDataIdentifier || (this.__objectsByDataIdentifier = new WeakMap()); - } + value: new WeakMap() }, /** diff --git a/data/service/expression-data-mapping.js b/data/service/expression-data-mapping.js index 9f72422439..7b9f4a5e2e 100644 --- a/data/service/expression-data-mapping.js +++ b/data/service/expression-data-mapping.js @@ -432,10 +432,6 @@ exports.ExpressionDataMapping = DataMapping.specialize(/** @lends ExpressionData requiredObjectProperties = rule ? rule.requirements : [], promise; - if (property === "position" || property === "childPosition") { - console.log(object, rule); - debugger; - } if (prefetchRequirements) { promise = this.service.rootService.getObjectPropertyExpressions(object, requiredObjectProperties); @@ -541,7 +537,7 @@ exports.ExpressionDataMapping = DataMapping.specialize(/** @lends ExpressionData value = value.then(function (data) { self._assignDataToObjectProperty(object, propertyDescriptor, data); if (inverse) { - self._assignObjectAsInverseProperty(object, propertyDescriptor, data, inverse) + self._assignObjectAsInverseProperty(object, descriptor, data, inverse) } return null; }); @@ -754,9 +750,6 @@ exports.ExpressionDataMapping = DataMapping.specialize(/** @lends ExpressionData rawRule = rawRules[propertyName]; if (this._shouldMapRule(rawRule, true)) { rule = this._makeRuleFromRawRule(rawRule, propertyName, true, true); - if (!rule.targetPath) { - debugger; - } this._ownObjectMappingRules.set(rule.targetPath, rule); } @@ -789,9 +782,6 @@ exports.ExpressionDataMapping = DataMapping.specialize(/** @lends ExpressionData rawRule = rawRules[propertyName]; if (this._shouldMapRule(rawRule, false)) { rule = this._makeRuleFromRawRule(rawRule, propertyName, false, false); - if (!rule.targetPath) { - debugger; - } this._ownObjectMappingRules.set(rule.targetPath, rule); } if (this._shouldMapRule(rawRule, true)) { diff --git a/data/service/http-service.js b/data/service/http-service.js index ef2425220d..fb421ad11a 100644 --- a/data/service/http-service.js +++ b/data/service/http-service.js @@ -317,8 +317,7 @@ var HttpService = exports.HttpService = RawDataService.specialize(/** @lends Htt error = HttpError.withRequestAndURL(request, parsed.url); reject(error); }; - method = self.methodForParsedArguments(parsed); - request.open(method, parsed.url, true); + request.open(parsed.body ? "POST" : "GET", parsed.url, true); self.setHeadersForQuery(parsed.headers, parsed.query, parsed.url); @@ -371,26 +370,26 @@ var HttpService = exports.HttpService = RawDataService.specialize(/** @lends Htt } }, - methodForParsedArguments: { - value: function (parsed) { - return parsed.body ? "POST" : "GET"; - } - }, + + /** * @private * @method */ _parseFetchHttpRawDataArguments: { - value: function (/* url [, headers [, body [, types]]][, sendCredentials] */) { + value: function (/* url [, headers [, body [, types [, query [, method]]]]][, sendCredentials] */) { var parsed, last, i, n; // Parse the url argument, setting the "last" argument index to -1 // if the URL is invalid. + parsed = {url: arguments[0]}; last = typeof parsed.url === "string" ? arguments.length - 1 : -1; if (last < 0) { console.warn(new Error("Invalid URL for fetchHttpRawData()")); } + + // Parse the sendCredentials argument, which must be the last // argument if it is provided, and set the "last" argument index to // point just past the last non-sendCredentials argument. @@ -439,17 +438,47 @@ var HttpService = exports.HttpService = RawDataService.specialize(/** @lends Htt } } - if (last === 5 && arguments[4] instanceof DataQuery) { parsed.query = arguments[4]; + } else if (last === 5 && typeof arguments[4] === "string") { + parsed.method = arguments[4]; } else if (last === 4 && arguments[3] instanceof DataQuery) { parsed.query = arguments[3]; + } else if (last === 4 && typeof arguments[3] === "string") { + parsed.method = arguments[3]; + } else if (last === 3 && typeof arguments[2] === "string") { + parsed.method = arguments[2]; } + // Return the parsed arguments. return last >= 0 ? parsed : undefined; } }, + createHttpRawData: { + value: function () { + + } + }, + + deleteHttpRawData: { + value: function () { + + } + }, + + readHttpRawData: { + value: function () { + return this.fetchHttpRawData.apply(this, arguments); + } + }, + + updateHttpRawData: { + value: function () { + + } + }, + /** * @private * @method diff --git a/data/service/raw-data-service.js b/data/service/raw-data-service.js index 23db731c80..8cd98befad 100644 --- a/data/service/raw-data-service.js +++ b/data/service/raw-data-service.js @@ -229,6 +229,27 @@ exports.RawDataService = DataService.specialize(/** @lends RawDataService.protot } }, + createRawData: { + value: function (object) { + return this.nullPromise; + } + }, + + //deleteRawData already exists.. + + readRawData: { + value: function (stream) { + return this.fetchRawData(stream); + } + }, + + updateRawData: { + value: function (stream) { + return this.fetchRawData(stream); + } + }, + + /** * Called through MainService when consumer has indicated that he has lost interest in the passed DataStream. * This will allow the RawDataService feeding the stream to take appropriate measures. @@ -262,9 +283,20 @@ exports.RawDataService = DataService.specialize(/** @lends RawDataService.protot */ deleteDataObject: { value: function (object) { - var record = {}; - this._mapObjectToRawData(object, record); - return this.deleteRawData(record, object); + var self = this, + record = {}, + mapResult = this._mapObjectToRawData(object, record), + result; + + if (mapResult instanceof Promise) { + result = mapResult.then(function () { + return self.deleteRawData(record, object); + }); + } else { + result = this.deleteRawData(record, object); + } + + return result; } }, diff --git a/test/all.js b/test/all.js index 086b61b1f7..ef58a6d2f2 100644 --- a/test/all.js +++ b/test/all.js @@ -120,9 +120,9 @@ module.exports = require("montage-testing").run(require, [ // {name: "spec/data/data-selector"}, // {name: "spec/data/data-service"}, // {name: "spec/data/data-stream"}, - {name: "spec/data/expression-data-mapping"}, + // {name: "spec/data/expression-data-mapping"}, // {name: "spec/data/enumeration"}, - // {name: "spec/data/http-service"}, + {name: "spec/data/http-service"}, // {name: "spec/data/object-descriptor"}, // {name: "spec/data/property-descriptor"}, // {name: "spec/data/raw-data-service"}, diff --git a/test/spec/data/http-service.js b/test/spec/data/http-service.js index 2eb1800431..6bf0de6213 100644 --- a/test/spec/data/http-service.js +++ b/test/spec/data/http-service.js @@ -1,5 +1,6 @@ var DataService = require("montage/data/service/data-service").DataService, HttpService = require("montage/data/service/http-service").HttpService, + DataQuery = require("montage/data/model/data-query").DataQuery, DataSelector = require("montage/data/service/data-selector").DataSelector, Criteria = require("montage/core/criteria").Criteria, WeatherReport = require("./logic/model/weather-report").WeatherReport, @@ -8,26 +9,97 @@ var DataService = require("montage/data/service/data-service").DataService, describe("An HttpService", function() { - it("needs to be tested", function (done) { - - var dataExpression = "city = $city && unit = $unit && country = $country"; - var dataParameters = { - city: 'San-Francisco', - country: 'us', - unit: 'imperial' - }; - var dataCriteria = new Criteria().initWithExpression(dataExpression, dataParameters); - var dataType = WeatherReport.TYPE; - var dataQuery = DataSelector.withTypeAndCriteria(dataType, dataCriteria); - - var mainService = new DataService(); - //TODO: Test with addChildService in addition to registerChildService - mainService.registerChildService(new WeatherService()).then(function () { - mainService.fetchData(dataQuery).then(function (weatherReports) { - expect(typeof weatherReports[0].temp).toBe('number'); - done(); - }); - }) - }); + // it("needs to be tested", function (done) { + + // var dataExpression = "city = $city && unit = $unit && country = $country"; + // var dataParameters = { + // city: 'San-Francisco', + // country: 'us', + // unit: 'imperial' + // }; + // var dataCriteria = new Criteria().initWithExpression(dataExpression, dataParameters); + // var dataType = WeatherReport.TYPE; + // var dataQuery = DataSelector.withTypeAndCriteria(dataType, dataCriteria); + + // var mainService = new DataService(); + // //TODO: Test with addChildService in addition to registerChildService + // mainService.registerChildService(new WeatherService()).then(function () { + // mainService.fetchData(dataQuery).then(function (weatherReports) { + // expect(typeof weatherReports[0].temp).toBe('number'); + // done(); + // }); + // }) + // }); + + describe("fetch http arguments", function () { + it("can be parsed with query", function () { + var service = new HttpService(), + url = "http://montagestudio.com", + headers = service.FORM_URL_ENCODED, + body = null, + types = [], + query = new DataQuery(), + sendCredentials = false, + parsed; + + parsed = service._parseFetchHttpRawDataArguments(url, headers, body, types, query, sendCredentials); + + expect(parsed.url).toEqual(url); + expect(parsed.headers["Content-Type"]).toBe("application/x-www-form-urlencoded"); + expect(parsed.body).toBe(undefined); + expect(parsed.types).toBeDefined(); + expect(parsed.types.length).toEqual(1); + expect(parsed.types[0]).toBe(HttpService.DataType.JSON); + expect(parsed.query).toBe(query); + expect(parsed.credentials).toEqual(sendCredentials); + + parsed = service._parseFetchHttpRawDataArguments(url, headers, body, query, sendCredentials); + + expect(parsed.url).toEqual(url); + expect(parsed.headers["Content-Type"]).toBe("application/x-www-form-urlencoded"); + expect(parsed.body).toBe(undefined); + expect(parsed.types).toBeDefined(); + expect(parsed.types.length).toEqual(1); + expect(parsed.types[0]).toBe(HttpService.DataType.JSON); + expect(parsed.query).toBe(query); + expect(parsed.credentials).toEqual(sendCredentials); + }); + + + it("can be parsed with method", function () { + var service = new HttpService(), + url = "http://montagestudio.com", + headers = service.FORM_URL_ENCODED, + body = null, + types = [], + method = "GET", + sendCredentials = false, + parsed; + + parsed = service._parseFetchHttpRawDataArguments(url, headers, body, types, method, sendCredentials); + + expect(parsed.url).toEqual(url); + expect(parsed.headers["Content-Type"]).toBe("application/x-www-form-urlencoded"); + expect(parsed.body).toBe(undefined); + expect(parsed.types).toBeDefined(); + expect(parsed.types.length).toEqual(1); + expect(parsed.types[0]).toBe(HttpService.DataType.JSON); + expect(parsed.method).toEqual(method); + expect(parsed.credentials).toEqual(sendCredentials); + + parsed = service._parseFetchHttpRawDataArguments(url, headers, body, method, sendCredentials); + + expect(parsed.url).toEqual(url); + expect(parsed.headers["Content-Type"]).toBe("application/x-www-form-urlencoded"); + expect(parsed.body).toBe(undefined); + expect(parsed.types).toBeDefined(); + expect(parsed.types.length).toEqual(1); + expect(parsed.types[0]).toBe(HttpService.DataType.JSON); + expect(parsed.method).toEqual(method); + expect(parsed.credentials).toEqual(sendCredentials); + }); + }) + + });