@masterportal/masterportalapi 2.40.0 → 2.40.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -18,6 +18,15 @@
18
18
 
19
19
  ---
20
20
 
21
+ ## 2.41.0 - 2024-11-05
22
+
23
+ ### Fixed
24
+ - Tileset-Layer: custom tileset filename is allowed
25
+ - WFS-Layer: url for describeFeatureType requests respects questionmark.
26
+ - Issue #1279: Fixed keyboardEventTarget, so that keyboard interactions like KeyboardZoom and KeyboardPan work, if keyboardEventTarget id defined in config
27
+
28
+ ---
29
+
21
30
  ## 2.40.0 - 2024-07-17
22
31
 
23
32
  ### Added
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@masterportal/masterportalapi",
3
3
  "author": "Implementierungspartnerschaft Masterportal <info@masterportal.org> (https://www.masterportal.org)",
4
- "version": "2.40.0",
4
+ "version": "2.40.1",
5
5
  "license": "MIT",
6
6
  "description": "Basic functions of the Masterportal as api",
7
7
  "repository": {
@@ -1,19 +1,22 @@
1
1
  /**
2
2
  * Creates the tileset.
3
+ * @param {Object} mpapiTileset - masterportal API Tileset object
3
4
  * @param {Object} rawLayer attributes of the layer
4
5
  * @param {string} [rawLayer.url] - the URL of the Cesium terrain server
5
6
  * @param {string} [rawLayer.cesiumTerrainProviderOptions] - see https://cesiumjs.org/Cesium/Build/Documentation/CesiumTerrainProvider.html
6
7
  * @returns {Cesium.Cesium3DTileset} the tileset
7
8
  */
8
- function createTileSet (rawLayer) {
9
- const url = rawLayer.url.split("?")[0] + "/tileset.json",
9
+ function createTileSet (mpapiTileset, rawLayer) {
10
+ const baseUrl = rawLayer.url.split("?")[0],
11
+ // when no json file is given by url, use tileset.json as default
12
+ url = baseUrl + (baseUrl.endsWith(".json") ? "" : "/tileset.json"),
10
13
  options = {};
11
14
 
15
+ mpapiTileset.url = url;
12
16
 
13
17
  if (rawLayer.cesium3DTilesetOptions) {
14
18
  Object.assign(options, rawLayer.cesium3DTilesetOptions);
15
19
  }
16
-
17
20
  return Promise.resolve(Cesium.Cesium3DTileset.fromUrl(url, options));
18
21
  }
19
22
 
@@ -33,7 +36,7 @@ export default function Tileset (rawLayer) {
33
36
  typ: rawLayer.typ
34
37
  };
35
38
  if (Cesium) {
36
- this.tileset = Promise.resolve(createTileSet(rawLayer));
39
+ this.tileset = Promise.resolve(createTileSet(this, rawLayer));
37
40
  this.tileset.then(function (tileset) {
38
41
  if (tileset) {
39
42
  tileset.layerReferenceId = rawLayer.id;
package/src/layer/wfs.js CHANGED
@@ -339,11 +339,12 @@ async function sendTransaction (srsName, feature, url, layer, transactionMethod)
339
339
  xmlDocument = null,
340
340
  transactionSummary = null,
341
341
  data = null;
342
+ const baseUrl = new URL(url),
342
343
 
343
- const {featureNS, featurePrefix, featureType, version} = layer;
344
+ {featureNS, featurePrefix, featureType, version} = layer;
344
345
 
345
346
  try {
346
- response = await fetch(url, {
347
+ response = await fetch(baseUrl, {
347
348
  method: "POST",
348
349
  headers: {"Content-Type": "text/xml"},
349
350
  credentials: layer.isSecured ? "include" : "omit",
@@ -358,6 +359,9 @@ async function sendTransaction (srsName, feature, url, layer, transactionMethod)
358
359
 
359
360
  xmlDocument = new DOMParser().parseFromString(data, "text/xml");
360
361
  transactionSummary = xmlDocument.getElementsByTagName("wfs:TransactionSummary");
362
+ if (transactionSummary.length === 0) {
363
+ transactionSummary = xmlDocument.getElementsByTagName("TransactionSummary");
364
+ }
361
365
 
362
366
  // NOTE: WFS-T services respond errors with the transaction as an XML response, even though it's the http code indicates different...
363
367
  if (transactionSummary.length === 0) {
@@ -453,6 +457,27 @@ function parseDescribeFeatureTypeResponse (responseData, featureType) {
453
457
  return [];
454
458
  }
455
459
 
460
+ /**
461
+ * Creates the Url to get possible properties from.
462
+ *
463
+ * @param {string} url from the WFS-T
464
+ * @param {string} version of the WFS-T
465
+ * @param {string} featureType Name of the FeatureType according to the capabilities document
466
+ * @returns {URL} the created url
467
+ */
468
+ function createReceivePossiblePropertiesUrl (url, version, featureType) {
469
+ const baseUrl = new URL(decodeURI(url));
470
+
471
+ baseUrl.searchParams.set("SERVICE", "WFS");
472
+ baseUrl.searchParams.set("REQUEST", "DescribeFeatureType");
473
+ baseUrl.searchParams.set("TYPENAME", featureType);
474
+ if (!baseUrl.searchParams.has("VERSION") && !baseUrl.searchParams.has("version")) {
475
+ baseUrl.searchParams.set("VERSION", version);
476
+ }
477
+
478
+ return baseUrl;
479
+ }
480
+
456
481
  /**
457
482
  * Requests the possible properties of a feature and further values;
458
483
  * for more {@see FeatureProperty}.
@@ -464,8 +489,8 @@ function parseDescribeFeatureTypeResponse (responseData, featureType) {
464
489
  * @returns {Promise<Array>} If the request is successful, an array of prepared feature properties.
465
490
  */
466
491
  async function receivePossibleProperties (url, version, featureType, isSecured) {
467
- const baseUrl = `${url}?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=${version}&TYPENAME=${featureType}`;
468
- let response;
492
+ const baseUrl = createReceivePossiblePropertiesUrl(url, version, featureType);
493
+ let response = null;
469
494
 
470
495
  try {
471
496
  response = await fetch(baseUrl, {
@@ -499,4 +524,4 @@ function loadFeaturesManually (layerAttributes, layerSource) {
499
524
  });
500
525
  }
501
526
 
502
- export default {createLayerSource, createLayer, sendTransaction, receivePossibleProperties, parseDescribeFeatureTypeResponse, writeTransactionBody, loadFeaturesManually};
527
+ export default {createLayerSource, createLayer, createReceivePossiblePropertiesUrl, sendTransaction, receivePossibleProperties, parseDescribeFeatureTypeResponse, writeTransactionBody, loadFeaturesManually};
@@ -164,7 +164,7 @@ export function createMap (config = defaults, {mapParams, callback, errorCallbac
164
164
  ]),
165
165
  controls: [],
166
166
  view: createMapView(config),
167
- keyboardEventTarget: config.mapInteractions?.keyboardEventTarget ? config.mapInteractions?.keyboardEventTarget : false
167
+ keyboardEventTarget: config.mapInteractions?.keyboardEventTarget ? document : false
168
168
  }, mapParams));
169
169
 
170
170
  map.set("mapMode", "2D");
@@ -73,6 +73,17 @@ describe("tileset.js", function () {
73
73
  checkAttributes(layer2, attr2);
74
74
  expect(cesium3DTilesetSpy).toHaveBeenCalledTimes(2);
75
75
  });
76
+ it("add tileset.json to url, when url is not pointing to json file", function () {
77
+ const layer = new Tileset(attr);
78
+
79
+ expect(layer.url).toEqual(attr.url + "/tileset.json");
80
+ });
81
+ it("should not add tileset.json to url, when url is pointing to json file", function () {
82
+ const attr2 = Object.assign({}, attr, {url: "https://url/root.json"}),
83
+ layer = new Tileset(attr2);
84
+
85
+ expect(layer.url).toEqual(attr2.url);
86
+ });
76
87
  });
77
88
  describe("setOpacity", function () {
78
89
  it("calls setOpacity sets opacity to terrain style", function (done) {
@@ -1,4 +1,3 @@
1
- import {enableFetchMocks} from "jest-fetch-mock";
2
1
  import VectorLayer from "ol/layer/Vector.js";
3
2
  import VectorSource from "ol/source/Vector.js";
4
3
  import Cluster from "ol/source/Cluster.js";
@@ -43,11 +42,6 @@ describe("wfs.js", function () {
43
42
  console.error = originalConsoleError;
44
43
  });
45
44
 
46
- beforeEach(() => {
47
- enableFetchMocks();
48
- fetch.resetMocks();
49
- });
50
-
51
45
  describe("createLayer", function () {
52
46
  it("creates a VectorLayer without id", function () {
53
47
  const layer = wfs.createLayer({version: "1.1.0"});
@@ -145,11 +139,6 @@ describe("wfs.js", function () {
145
139
  });
146
140
  });
147
141
  describe("createLayerSource", function () {
148
- beforeEach(() => {
149
- if (global.fetch) {
150
- global.fetch.mockClear();
151
- }
152
- });
153
142
 
154
143
  it("creates a VectorSource and beforeLoading, afterLoading and featuresFilter are called", function () {
155
144
  global.fetch = jest.fn().mockImplementation(() => {
@@ -758,9 +747,9 @@ describe("wfs.js", function () {
758
747
  "</xsd:schema>";
759
748
 
760
749
  it("should receive the possible properties", async () => {
761
- fetch.mockResponseOnce(exampleDescribeFeatureType);
762
-
763
- const properties = await wfs.receivePossibleProperties("https://team-waas-was-here.lgln", "1.1.0", "wfstpolygon", false),
750
+ let properties = null;
751
+ const baseUrl = new URL("https://team-waas-was-here.lgln/?SERVICE=WFS&REQUEST=DescribeFeatureType&TYPENAME=wfstpolygon&VERSION=1.1.0"),
752
+ options = {"credentials": "omit", "responseType": "text/xml"},
764
753
  exampleProperties = [
765
754
  {
766
755
  key: "name",
@@ -799,6 +788,22 @@ describe("wfs.js", function () {
799
788
  }
800
789
  ];
801
790
 
791
+ baseUrl.searchParams.set("SERVICE", "WFS");
792
+ baseUrl.searchParams.set("REQUEST", "DescribeFeatureType");
793
+ global.fetch = jest.fn().mockImplementation(() => {
794
+ return new Promise((resolve) => {
795
+ resolve({
796
+ ok: true,
797
+ status: 200,
798
+ text: () => {
799
+ return exampleDescribeFeatureType;
800
+ }
801
+ });
802
+ });
803
+ });
804
+
805
+ properties = await wfs.receivePossibleProperties("https://team-waas-was-here.lgln", "1.1.0", "wfstpolygon", false);
806
+
802
807
  expect(Array.isArray(properties)).toBe(true);
803
808
  expect(properties.length).toEqual(5);
804
809
  exampleProperties.forEach(property => {
@@ -807,14 +812,14 @@ describe("wfs.js", function () {
807
812
  expect(parsedProperty).not.toEqual(undefined);
808
813
  expect(parsedProperty).toEqual(property);
809
814
  });
810
- expect(fetch).toHaveBeenCalledWith("https://team-waas-was-here.lgln?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.1.0&TYPENAME=wfstpolygon", {"responseType": "text/xml", "credentials": "omit"});
811
815
 
816
+ expect(global.fetch).toHaveBeenCalledWith(baseUrl, options);
812
817
  });
813
818
 
814
819
  it("should receive the possible properties from a geoserver", async () => {
815
- fetch.mockResponseOnce(geoserverDescribeFeatureType);
816
-
817
- const properties = await wfs.receivePossibleProperties("https://team-waas-was-here.lgln", "1.1.0", "test_polygon", false),
820
+ let properties = null;
821
+ const baseUrl = new URL("https://team-waas-was-here.lgln/?SERVICE=WFS&REQUEST=DescribeFeatureType&TYPENAME=test_polygon&VERSION=1.1.0"),
822
+ options = {"credentials": "omit", "responseType": "text/xml"},
818
823
  exampleProperties = [
819
824
  {
820
825
  key: "id",
@@ -839,6 +844,22 @@ describe("wfs.js", function () {
839
844
  }
840
845
  ];
841
846
 
847
+ baseUrl.searchParams.set("SERVICE", "WFS");
848
+ baseUrl.searchParams.set("REQUEST", "DescribeFeatureType");
849
+ global.fetch = jest.fn().mockImplementation(() => {
850
+ return new Promise((resolve) => {
851
+ resolve({
852
+ ok: true,
853
+ status: 200,
854
+ text: () => {
855
+ return geoserverDescribeFeatureType;
856
+ }
857
+ });
858
+ });
859
+ });
860
+ properties = await wfs.receivePossibleProperties("https://team-waas-was-here.lgln", "1.1.0", "test_polygon", false);
861
+
862
+
842
863
  expect(Array.isArray(properties)).toBe(true);
843
864
  expect(properties.length).toEqual(3);
844
865
  exampleProperties.forEach(property => {
@@ -847,14 +868,14 @@ describe("wfs.js", function () {
847
868
  expect(parsedProperty).not.toEqual(undefined);
848
869
  expect(parsedProperty).toEqual(property);
849
870
  });
850
- expect(fetch).toHaveBeenCalledWith("https://team-waas-was-here.lgln?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.1.0&TYPENAME=test_polygon", {"responseType": "text/xml", "credentials": "omit"});
871
+ expect(global.fetch).toHaveBeenCalledWith(baseUrl, options);
851
872
 
852
873
  });
853
874
 
854
875
  it("should receive the possible properties with credentials", async () => {
855
- fetch.mockResponseOnce(exampleDescribeFeatureType);
856
-
857
- const properties = await wfs.receivePossibleProperties("https://team-waas-was-here.lgln", "1.1.0", "wfstpolygon", true),
876
+ let properties = null;
877
+ const baseUrl = new URL("https://team-waas-was-here.lgln/?SERVICE=WFS&REQUEST=DescribeFeatureType&TYPENAME=wfstpolygon&VERSION=1.1.0"),
878
+ options = {"credentials": "include", "responseType": "text/xml"},
858
879
  exampleProperties = [
859
880
  {
860
881
  key: "name",
@@ -893,6 +914,21 @@ describe("wfs.js", function () {
893
914
  }
894
915
  ];
895
916
 
917
+ baseUrl.searchParams.set("SERVICE", "WFS");
918
+ baseUrl.searchParams.set("REQUEST", "DescribeFeatureType");
919
+ global.fetch = jest.fn().mockImplementation(() => {
920
+ return new Promise((resolve) => {
921
+ resolve({
922
+ ok: true,
923
+ status: 200,
924
+ text: () => {
925
+ return exampleDescribeFeatureType;
926
+ }
927
+ });
928
+ });
929
+ });
930
+
931
+ properties = await wfs.receivePossibleProperties("https://team-waas-was-here.lgln", "1.1.0", "wfstpolygon", true);
896
932
  expect(Array.isArray(properties)).toBe(true);
897
933
  expect(properties.length).toEqual(5);
898
934
  exampleProperties.forEach(property => {
@@ -901,16 +937,8 @@ describe("wfs.js", function () {
901
937
  expect(parsedProperty).not.toEqual(undefined);
902
938
  expect(parsedProperty).toEqual(property);
903
939
  });
904
- expect(fetch).toHaveBeenCalledWith("https://team-waas-was-here.lgln?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.1.0&TYPENAME=wfstpolygon", {"responseType": "text/xml", "credentials": "include"});
905
-
906
- });
940
+ expect(global.fetch).toHaveBeenCalledWith(baseUrl, options);
907
941
 
908
- it("should throw an error if the properties can not be fetched", async () => {
909
- fetch.mockAbortOnce();
910
-
911
- await expect(async () => {
912
- await wfs.receivePossibleProperties("https://team-waas-was-here.lgln", "1.1.0", "wfstgeom", false);
913
- }).rejects.toThrow(Error);
914
942
  });
915
943
  });
916
944
 
@@ -968,14 +996,6 @@ describe("wfs.js", function () {
968
996
  " </wfs:Feature>\n" +
969
997
  " </wfs:InsertResults>\n" +
970
998
  "</wfs:TransactionResponse>",
971
- fetchResponseUpdate = "<?xml version='1.0' encoding='UTF-8'?>\n" +
972
- "<wfs:TransactionResponse xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd\" xmlns:wfs=\"http://www.opengis.net/wfs\" xmlns:ogc=\"http://www.opengis.net/ogc\" version=\"1.1.0\">\n" +
973
- " <wfs:TransactionSummary>\n" +
974
- " <wfs:totalInserted>0</wfs:totalInserted>\n" +
975
- " <wfs:totalUpdated>1</wfs:totalUpdated>\n" +
976
- " <wfs:totalDeleted>0</wfs:totalDeleted>\n" +
977
- " </wfs:TransactionSummary>\n" +
978
- "</wfs:TransactionResponse>",
979
999
  fetchResponseDelete = "<?xml version='1.0' encoding='UTF-8'?>\n" +
980
1000
  "<wfs:TransactionResponse xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd\" xmlns:wfs=\"http://www.opengis.net/wfs\" xmlns:ogc=\"http://www.opengis.net/ogc\" version=\"1.1.0\">\n" +
981
1001
  " <wfs:TransactionSummary>\n" +
@@ -986,40 +1006,84 @@ describe("wfs.js", function () {
986
1006
  "</wfs:TransactionResponse>";
987
1007
 
988
1008
  it("should return the inserted feature if the transaction was successful", async function () {
989
- fetch.mockResponseOnce(fetchResponseInsert);
1009
+ global.fetch = jest.fn().mockImplementation(() => {
1010
+ return new Promise((resolve) => {
1011
+ resolve({
1012
+ ok: true,
1013
+ status: 200,
1014
+ text: () => {
1015
+ return fetchResponseInsert;
1016
+ }
1017
+ });
1018
+ });
1019
+ });
990
1020
 
991
1021
  expect(await wfs.sendTransaction(srsName, feature, url, layer, insertTransaction)).toEqual(feature);
992
1022
  });
993
1023
 
994
1024
  it("should return the inserted feature if the transaction was successful", async function () {
995
- fetch.mockResponseOnce(fetchResponseInsert);
1025
+ global.fetch = jest.fn().mockImplementation(() => {
1026
+ return new Promise((resolve) => {
1027
+ resolve({
1028
+ ok: true,
1029
+ status: 200,
1030
+ text: () => {
1031
+ return fetchResponseInsert;
1032
+ }
1033
+ });
1034
+ });
1035
+ });
996
1036
  layer.isSecured = true;
997
1037
 
998
1038
  expect(await wfs.sendTransaction(srsName, feature, url, layer, insertTransaction)).toEqual(feature);
999
1039
  });
1000
1040
 
1001
1041
  it("should return the updated feature if the transaction was successful", async function () {
1002
- fetch.mockResponseOnce(fetchResponseUpdate);
1042
+ global.fetch = jest.fn().mockImplementation(() => {
1043
+ return new Promise((resolve) => {
1044
+ resolve({
1045
+ ok: true,
1046
+ status: 200,
1047
+ text: () => {
1048
+ return fetchResponseInsert;
1049
+ }
1050
+ });
1051
+ });
1052
+ });
1003
1053
  feature.setId(1);
1004
1054
 
1005
1055
  expect(await wfs.sendTransaction(srsName, feature, url, layer, updateTransaction)).toEqual(feature);
1006
1056
  });
1007
1057
 
1008
1058
  it("should return the deleted feature if the transaction was successful", async function () {
1009
- fetch.mockResponseOnce(fetchResponseDelete);
1059
+ global.fetch = jest.fn().mockImplementation(() => {
1060
+ return new Promise((resolve) => {
1061
+ resolve({
1062
+ ok: true,
1063
+ status: 200,
1064
+ text: () => {
1065
+ return fetchResponseDelete;
1066
+ }
1067
+ });
1068
+ });
1069
+ });
1010
1070
  feature.setId(1);
1011
1071
 
1012
1072
  expect(await wfs.sendTransaction(srsName, feature, url, layer, deleteTransaction)).toEqual(feature);
1013
1073
  });
1014
1074
 
1015
- it("should throw an error if fetch fails", async function () {
1016
- fetch.mockAbortOnce();
1017
-
1018
- await expect(async () => wfs.sendTransaction(srsName, feature, url, layer, insertTransaction)).rejects.toThrow(Error);
1019
- });
1020
-
1021
1075
  it("should throw an error if transaction type is not insert, selectedUpdate or delete", async function () {
1022
- fetch.mockResponseOnce(fetchResponseDelete);
1076
+ global.fetch = jest.fn().mockImplementation(() => {
1077
+ return new Promise((resolve) => {
1078
+ resolve({
1079
+ ok: true,
1080
+ status: 200,
1081
+ text: () => {
1082
+ return fetchResponseDelete;
1083
+ }
1084
+ });
1085
+ });
1086
+ });
1023
1087
  feature.setId(1);
1024
1088
 
1025
1089
  await expect(async () => wfs.sendTransaction(srsName, feature, url, layer, "löschen")).rejects.toThrow(Error);
@@ -1033,7 +1097,17 @@ describe("wfs.js", function () {
1033
1097
  " </ows:Exception>\n" +
1034
1098
  "</ows:ExceptionReport>";
1035
1099
 
1036
- fetch.mockResponseOnce(failedResponse);
1100
+ global.fetch = jest.fn().mockImplementation(() => {
1101
+ return new Promise((resolve) => {
1102
+ resolve({
1103
+ ok: true,
1104
+ status: 200,
1105
+ text: () => {
1106
+ return failedResponse;
1107
+ }
1108
+ });
1109
+ });
1110
+ });
1037
1111
 
1038
1112
  await expect(async () => wfs.sendTransaction(srsName, feature, url, layer, insertTransaction)).rejects.toThrow(Error);
1039
1113
  });
@@ -1046,12 +1120,79 @@ describe("wfs.js", function () {
1046
1120
  " </ows:Exception>\n" +
1047
1121
  "</ows:ExceptionReport>";
1048
1122
 
1049
- fetch.mockResponseOnce(failedResponse);
1123
+ global.fetch = jest.fn().mockImplementation(() => {
1124
+ return new Promise((resolve) => {
1125
+ resolve({
1126
+ ok: true,
1127
+ status: 200,
1128
+ text: () => {
1129
+ return failedResponse;
1130
+ }
1131
+ });
1132
+ });
1133
+ });
1050
1134
 
1051
1135
  await expect(async () => wfs.sendTransaction(srsName, feature, url, layer, insertTransaction)).rejects.toThrow("Cannot perform insert operation: Error in XML document (line: 1, column: 234, character offset: 233): Feature type \"{wrong}wfst\" is unknown.");
1052
1136
  });
1053
1137
  });
1138
+ describe("createReceivePossiblePropertiesUrl", function () {
1139
+ it("url without backslash at the end", () => {
1140
+ const url = "https://team-waas-was-here.lgln",
1141
+ version = "1.1.0",
1142
+ featureType = "featureType",
1143
+ createdUrl = wfs.createReceivePossiblePropertiesUrl(url, version, featureType);
1144
+
1145
+ expect(createdUrl.origin).toEqual(url);
1146
+ expect(createdUrl.searchParams.get("SERVICE")).toEqual("WFS");
1147
+ expect(createdUrl.searchParams.get("REQUEST")).toEqual("DescribeFeatureType");
1148
+ expect(createdUrl.searchParams.get("TYPENAME")).toEqual(featureType);
1149
+ expect(createdUrl.searchParams.get("VERSION")).toEqual(version);
1150
+ });
1151
+
1152
+ it("url with backslash at the end", () => {
1153
+ const url = "https://team-waas-was-here.lgln/",
1154
+ version = "1.1.0",
1155
+ featureType = "featureType",
1156
+ createdUrl = wfs.createReceivePossiblePropertiesUrl(url, version, featureType);
1157
+
1158
+ expect(createdUrl.origin).toEqual("https://team-waas-was-here.lgln");
1159
+ expect(createdUrl.searchParams.get("SERVICE")).toEqual("WFS");
1160
+ expect(createdUrl.searchParams.get("REQUEST")).toEqual("DescribeFeatureType");
1161
+ expect(createdUrl.searchParams.get("TYPENAME")).toEqual(featureType);
1162
+ expect(createdUrl.searchParams.get("VERSION")).toEqual(version);
1163
+ });
1164
+
1165
+ it("createUrl should respect questionmark in url", () => {
1166
+ const url = "https://mapservice.regensburg.de/cgi-bin/mapserv?map=wfs.map",
1167
+ version = "1.1.0",
1168
+ featureType = "featureType",
1169
+ createdUrl = wfs.createReceivePossiblePropertiesUrl(url, version, featureType);
1170
+
1171
+ expect(createdUrl.origin).toEqual("https://mapservice.regensburg.de");
1172
+ expect(createdUrl.pathname).toEqual("/cgi-bin/mapserv");
1173
+ expect(createdUrl.searchParams.get("map")).toEqual("wfs.map");
1174
+ expect(createdUrl.searchParams.get("SERVICE")).toEqual("WFS");
1175
+ expect(createdUrl.searchParams.get("REQUEST")).toEqual("DescribeFeatureType");
1176
+ expect(createdUrl.searchParams.get("TYPENAME")).toEqual(featureType);
1177
+ expect(createdUrl.searchParams.get("VERSION")).toEqual(version);
1178
+ });
1179
+
1180
+ it("createUrl should respect version in url", () => {
1181
+ const url = "https://www.geosnap.info/cgi-bin/qgis_mapserv.fcgi?VERSION=1.3.0&MAP=/var/www/data/gis_data/LRARW_Burgergis/buergergis.qgz",
1182
+ version = "1.1.0",
1183
+ featureType = "featureType",
1184
+ createdUrl = wfs.createReceivePossiblePropertiesUrl(url, version, featureType);
1185
+
1186
+ expect(createdUrl.origin).toEqual("https://www.geosnap.info");
1187
+ expect(createdUrl.pathname).toEqual("/cgi-bin/qgis_mapserv.fcgi");
1188
+ expect(createdUrl.searchParams.get("MAP")).toEqual("/var/www/data/gis_data/LRARW_Burgergis/buergergis.qgz");
1189
+ expect(createdUrl.searchParams.get("SERVICE")).toEqual("WFS");
1190
+ expect(createdUrl.searchParams.get("REQUEST")).toEqual("DescribeFeatureType");
1191
+ expect(createdUrl.searchParams.get("TYPENAME")).toEqual(featureType);
1192
+ expect(createdUrl.searchParams.get("VERSION")).toEqual("1.3.0");
1193
+ });
1054
1194
 
1195
+ });
1055
1196
  describe("loadFeaturesManually", function () {
1056
1197
  let tick;
1057
1198
 
@@ -1061,10 +1202,6 @@ describe("wfs.js", function () {
1061
1202
  setTimeout(resolve, 0);
1062
1203
  });
1063
1204
  };
1064
-
1065
- if (global.fetch) {
1066
- global.fetch.mockClear();
1067
- }
1068
1205
  });
1069
1206
 
1070
1207
  it("load features manually", async function () {
@@ -1079,8 +1216,33 @@ describe("wfs.js", function () {
1079
1216
  });
1080
1217
  });
1081
1218
  });
1082
-
1083
- const format = new WFS(),
1219
+ const feature = new Feature({
1220
+ geometry: new Polygon([
1221
+ [
1222
+ [
1223
+ 9.17782024967994,
1224
+ 50.20836600730087
1225
+ ],
1226
+ [
1227
+ 9.200676227149245,
1228
+ 50.20836600730087
1229
+ ],
1230
+ [
1231
+ 9.200676227149245,
1232
+ 50.20873353776312
1233
+ ],
1234
+ [
1235
+ 9.17782024967994,
1236
+ 50.20873353776312
1237
+ ],
1238
+ [
1239
+ 9.17782024967994,
1240
+ 50.20836600730087
1241
+ ]
1242
+ ]]),
1243
+ name: "My Polygon"
1244
+ }),
1245
+ format = new WFS(),
1084
1246
  source = new VectorSource({
1085
1247
  format: format,
1086
1248
  url: "https://url.de",
@@ -1094,6 +1256,10 @@ describe("wfs.js", function () {
1094
1256
  url: "https://url.de"
1095
1257
  };
1096
1258
 
1259
+ source.getFormat().readFeatures = jest.fn().mockImplementation(() => {
1260
+ return [feature];
1261
+ });
1262
+
1097
1263
  wfs.loadFeaturesManually(layerAttributes, source);
1098
1264
  await tick();
1099
1265
  expect(source.getFeatures()).toHaveLength(1);