@adobe/acc-js-sdk 1.0.2 → 1.0.6

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.
@@ -27,7 +27,6 @@ const { HttpError } = require('../src/transport.js');
27
27
  describe('ACC Client', function () {
28
28
 
29
29
  describe('Init', function () {
30
-
31
30
  it('Should create client', async function () {
32
31
  const client = await Mock.makeClient();
33
32
  const NLWS = client.NLWS;
@@ -1193,13 +1192,13 @@ describe('ACC Client', function () {
1193
1192
 
1194
1193
  it("from default representation", async () => {
1195
1194
  const client = await Mock.makeClient();
1196
- var xml = DomUtil.toXMLString(client.fromRepresentation("root", {}));
1195
+ var xml = DomUtil.toXMLString(client._fromRepresentation("root", {}));
1197
1196
  expect(xml).toBe("<root/>");
1198
1197
  })
1199
1198
 
1200
1199
  it("from SimpleJson representation", async () => {
1201
1200
  const client = await Mock.makeClient();
1202
- var xml = DomUtil.toXMLString(client.fromRepresentation("root", {}, "SimpleJson"));
1201
+ var xml = DomUtil.toXMLString(client._fromRepresentation("root", {}, "SimpleJson"));
1203
1202
  expect(xml).toBe("<root/>");
1204
1203
  })
1205
1204
 
@@ -1208,14 +1207,14 @@ describe('ACC Client', function () {
1208
1207
  it("Should convert from BadgerFish to BadgerFish", async () => {
1209
1208
  const client = await Mock.makeClient();
1210
1209
  var from = { "@id": "1", "child": {} };
1211
- var to = client.convertToRepresentation(from, "BadgerFish", "BadgerFish");
1210
+ var to = client._convertToRepresentation(from, "BadgerFish", "BadgerFish");
1212
1211
  expect(to).toStrictEqual(from);
1213
1212
  })
1214
1213
 
1215
1214
  it("Should convert from BadgerFish to SimpleJson", async () => {
1216
1215
  const client = await Mock.makeClient();
1217
1216
  var from = { "@id": "1", "child": {} };
1218
- var to = client.convertToRepresentation(from, "BadgerFish", "SimpleJson");
1217
+ var to = client._convertToRepresentation(from, "BadgerFish", "SimpleJson");
1219
1218
  expect(to).toStrictEqual({ id: "1", child: {} });
1220
1219
  })
1221
1220
 
@@ -1224,20 +1223,20 @@ describe('ACC Client', function () {
1224
1223
 
1225
1224
  it("Compare representations", async () => {
1226
1225
  const client = await Mock.makeClient();
1227
- expect(() => { client.isSameRepresentation("json", "json") }).toThrow("SDK-000004");
1228
- expect(() => { client.isSameRepresentation("json", "BadgerFish") }).toThrow("SDK-000004");
1229
- expect(() => { client.isSameRepresentation("BadgerFish", "json") }).toThrow("SDK-000004");
1230
- expect(client.isSameRepresentation("SimpleJson", "SimpleJson")).toBeTruthy();
1231
- expect(client.isSameRepresentation("BadgerFish", "SimpleJson")).toBeFalsy();
1232
- expect(client.isSameRepresentation("SimpleJson", "BadgerFish")).toBeFalsy();
1233
- expect(client.isSameRepresentation("xml", "BadgerFish")).toBeFalsy();
1234
- expect(client.isSameRepresentation("SimpleJson", "xml")).toBeFalsy();
1235
- expect(() => { client.isSameRepresentation("Xml", "Xml") }).toThrow("SDK-000004");
1236
- expect(() => { client.isSameRepresentation("xml", "Xml") }).toThrow("SDK-000004");
1237
- expect(() => { client.isSameRepresentation("Xml", "xml") }).toThrow("SDK-000004");
1238
- expect(() => { client.isSameRepresentation("", "xml") }).toThrow("SDK-000004");
1239
- expect(() => { client.isSameRepresentation("xml", "") }).toThrow("SDK-000004");
1240
- expect(() => { client.isSameRepresentation("xml", null) }).toThrow("SDK-000004");
1226
+ expect(() => { client._isSameRepresentation("json", "json") }).toThrow("SDK-000004");
1227
+ expect(() => { client._isSameRepresentation("json", "BadgerFish") }).toThrow("SDK-000004");
1228
+ expect(() => { client._isSameRepresentation("BadgerFish", "json") }).toThrow("SDK-000004");
1229
+ expect(client._isSameRepresentation("SimpleJson", "SimpleJson")).toBeTruthy();
1230
+ expect(client._isSameRepresentation("BadgerFish", "SimpleJson")).toBeFalsy();
1231
+ expect(client._isSameRepresentation("SimpleJson", "BadgerFish")).toBeFalsy();
1232
+ expect(client._isSameRepresentation("xml", "BadgerFish")).toBeFalsy();
1233
+ expect(client._isSameRepresentation("SimpleJson", "xml")).toBeFalsy();
1234
+ expect(() => { client._isSameRepresentation("Xml", "Xml") }).toThrow("SDK-000004");
1235
+ expect(() => { client._isSameRepresentation("xml", "Xml") }).toThrow("SDK-000004");
1236
+ expect(() => { client._isSameRepresentation("Xml", "xml") }).toThrow("SDK-000004");
1237
+ expect(() => { client._isSameRepresentation("", "xml") }).toThrow("SDK-000004");
1238
+ expect(() => { client._isSameRepresentation("xml", "") }).toThrow("SDK-000004");
1239
+ expect(() => { client._isSameRepresentation("xml", null) }).toThrow("SDK-000004");
1241
1240
  })
1242
1241
  });
1243
1242
 
@@ -1310,7 +1309,7 @@ describe('ACC Client', function () {
1310
1309
 
1311
1310
  it("User agent string", async () => {
1312
1311
  const client = await Mock.makeClient();
1313
- const ua = client.getUserAgentString();
1312
+ const ua = client._getUserAgentString();
1314
1313
  expect(ua.startsWith("@adobe/acc-js-sdk/")).toBeTruthy();
1315
1314
  expect(ua.endsWith(" ACC Javascript SDK")).toBeTruthy();
1316
1315
  })
@@ -1877,4 +1876,327 @@ describe('ACC Client', function () {
1877
1876
  expect(calls[0][0].data).toMatch("Logon");
1878
1877
  });
1879
1878
  })
1879
+
1880
+ describe("Security token authentication", () => {
1881
+ // Security token authentication is used when embedding the SDK in Campaign: the session token
1882
+ // is provided by the browser as a cookie. The cookie is not readable by JavaScript code and
1883
+ // should be passed automatically by the browser, not by the SDK
1884
+ it("Should create logged client", async() => {
1885
+ const connectionParameters = sdk.ConnectionParameters.ofSecurityToken("http://acc-sdk:8080", "$security_token$");
1886
+ const client = await sdk.init(connectionParameters);
1887
+ client._transport = jest.fn();
1888
+ expect(client.isLogged()).toBeFalsy();
1889
+ await client.logon();
1890
+ expect(client.isLogged()).toBeTruthy();
1891
+ const logoff = client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
1892
+ await client.logoff();
1893
+ expect(client.isLogged()).toBeFalsy();
1894
+ // Ensure logoff has been called
1895
+ expect(logoff.mock.calls.length).toBe(1);
1896
+ })
1897
+ })
1898
+
1899
+ describe("Bearer token authentication", () => {
1900
+ // Bearer token authentication is used when embedding IMS for authentication
1901
+ it("Should create logged client", async() => {
1902
+ const connectionParameters = sdk.ConnectionParameters.ofBearerToken("http://acc-sdk:8080", "$token$");
1903
+ const client = await sdk.init(connectionParameters);
1904
+ client._transport = jest.fn();
1905
+ client._transport.mockReturnValueOnce(Mock.BEARER_LOGON_RESPONSE);
1906
+ expect(client.isLogged()).toBeFalsy();
1907
+ await client.logon();
1908
+ expect(client.isLogged()).toBeTruthy();
1909
+ const transport = client._transport.mockReturnValueOnce(Mock.LOGOFF_RESPONSE);
1910
+ await client.logoff();
1911
+ expect(client.isLogged()).toBeFalsy();
1912
+ // Ensure logoff has been called
1913
+ expect(transport.mock.calls.length).toBe(2);
1914
+ })
1915
+
1916
+ it("Call SAOP method", async () => {
1917
+ const connectionParameters = sdk.ConnectionParameters.ofBearerToken("http://acc-sdk:8080", "$token$");
1918
+ const client = await sdk.init(connectionParameters);
1919
+ client._transport = jest.fn();
1920
+ client._transport.mockReturnValueOnce(Mock.BEARER_LOGON_RESPONSE);
1921
+ await client.logon();
1922
+ client._transport.mockReturnValueOnce(Mock.GET_XTK_QUERY_SCHEMA_RESPONSE);
1923
+ var queryDef = {
1924
+ "schema": "nms:extAccount",
1925
+ "operation": "select",
1926
+ "select": {
1927
+ "node": [
1928
+ { "expr": "@id" },
1929
+ { "expr": "@name" }
1930
+ ]
1931
+ }
1932
+ };
1933
+
1934
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
1935
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:xtk:queryDef' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1936
+ <SOAP-ENV:Body>
1937
+ <ExecuteQueryResponse xmlns='urn:xtk:queryDef' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1938
+ <pdomOutput xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
1939
+ <extAccount-collection/>
1940
+ </pdomOutput></ExecuteQueryResponse>
1941
+ </SOAP-ENV:Body>
1942
+ </SOAP-ENV:Envelope>`));
1943
+
1944
+ // Select should return empty array
1945
+ var query = client.NLWS.xtkQueryDef.create(queryDef);
1946
+ var extAccount = await query.executeQuery();
1947
+ expect(extAccount).toEqual({ extAccount: [] });
1948
+ });
1949
+ })
1950
+
1951
+ describe("Logon should always return a promise", () => {
1952
+
1953
+ it("Should return a promise with UserPassword", async () => {
1954
+ const connectionParameters = sdk.ConnectionParameters.ofUserAndPassword("http://acc-sdk:8080", "$user$", "$password$");
1955
+ const client = await sdk.init(connectionParameters);
1956
+ client._transport = jest.fn();
1957
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
1958
+ const result = client.logon();
1959
+ expect(result instanceof Promise).toBe(true);
1960
+ await result;
1961
+ })
1962
+
1963
+ it("Should return a promise with bearer token", async () => {
1964
+ const connectionParameters = sdk.ConnectionParameters.ofBearerToken("http://acc-sdk:8080", "$token$");
1965
+ const client = await sdk.init(connectionParameters);
1966
+ client._transport = jest.fn();
1967
+ client._transport.mockReturnValueOnce(Mock.BEARER_LOGON_RESPONSE);
1968
+ const result = client.logon();
1969
+ expect(result instanceof Promise).toBe(true);
1970
+ await result;
1971
+ })
1972
+
1973
+ it("Should return a promise with UserAndServiceToken", async () => {
1974
+ const connectionParameters = sdk.ConnectionParameters.ofUserAndServiceToken("http://acc-sdk:8080", "$user$", "$service_token$");
1975
+ const client = await sdk.init(connectionParameters);
1976
+ client._transport = jest.fn();
1977
+ const result = client.logon();
1978
+ expect(result instanceof Promise).toBe(true);
1979
+ try {
1980
+ await result;
1981
+ } catch(ex) { /* result or exception is not handled */ }
1982
+ })
1983
+
1984
+ it("Should return a promise with SessionToken", async () => {
1985
+ const connectionParameters = sdk.ConnectionParameters.ofSessionToken("http://acc-sdk:8080", "$session_token$");
1986
+ const client = await sdk.init(connectionParameters);
1987
+ client._transport = jest.fn();
1988
+ const result = client.logon();
1989
+ expect(result instanceof Promise).toBe(true);
1990
+ await result;
1991
+ })
1992
+
1993
+ it("Should return a promise with SecurityToken", async () => {
1994
+ const connectionParameters = sdk.ConnectionParameters.ofSecurityToken("http://acc-sdk:8080", "$security_token$");
1995
+ const client = await sdk.init(connectionParameters);
1996
+ client._transport = jest.fn();
1997
+ const result = client.logon();
1998
+ expect(result instanceof Promise).toBe(true);
1999
+ await result;
2000
+ })
2001
+
2002
+ it("Should return a promise with AnonymousUser", async () => {
2003
+ const connectionParameters = sdk.ConnectionParameters.ofAnonymousUser("http://acc-sdk:8080");
2004
+ const client = await sdk.init(connectionParameters);
2005
+ client._transport = jest.fn();
2006
+ const result = client.logon();
2007
+ expect(result instanceof Promise).toBe(true);
2008
+ await result;
2009
+ })
2010
+ })
2011
+
2012
+
2013
+ describe("Should simulate server down", () => {
2014
+ it("Should simulate server down and up again", async () => {
2015
+ // Server is up and getOption
2016
+ const client = await Mock.makeClient();
2017
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2018
+ client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
2019
+ await client.NLWS.xtkSession.logon();
2020
+ client._transport.mockReturnValueOnce(Mock.GET_DATABASEID_RESPONSE);
2021
+ var databaseId = await client.getOption("XtkDatabaseId", false);
2022
+ expect(databaseId).toBe("uFE80000000000000F1FA913DD7CC7C480041161C");
2023
+
2024
+ // Now simulate a connection error (server is down)
2025
+ const error = new Error("connect ECONNREFUSED 3.225.73.178:8080");
2026
+ error.code="ECONNREFUSED";
2027
+ error.errno="ECONNREFUSED";
2028
+ client._transport.mockReturnValueOnce(Promise.reject(error));
2029
+ await expect(client.getOption("XtkDatabaseId", false)).rejects.toMatchObject({
2030
+ message: "500 - Error calling method 'xtk:session#GetOption': Error (connect ECONNREFUSED 3.225.73.178:8080)"
2031
+ });
2032
+
2033
+ // Server is back up again
2034
+ client._transport.mockReturnValueOnce(Mock.GET_DATABASEID_RESPONSE);
2035
+ databaseId = await client.getOption("XtkDatabaseId", false);
2036
+ expect(databaseId).toBe("uFE80000000000000F1FA913DD7CC7C480041161C")
2037
+ });
2038
+ })
2039
+
2040
+ describe("Connection options", () => {
2041
+ it("Should set options cache TTL", async () => {
2042
+ const client = await Mock.makeClient({ optionCacheTTL: -1 });
2043
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2044
+ client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
2045
+ await client.NLWS.xtkSession.logon();
2046
+ // Get Option and cache result. Check the value is in cache
2047
+ client._transport.mockReturnValueOnce(Mock.GET_DATABASEID_RESPONSE);
2048
+ await client.getOption("XtkDatabaseId", true);
2049
+ expect(client._optionCache._cache["XtkDatabaseId"].value).toMatchObject({ type: 6, rawValue: "uFE80000000000000F1FA913DD7CC7C480041161C" });
2050
+ // Get it again, it should not use the cache (=> it should make a SOAP call)
2051
+ // To test if the SOAP call is made, we mock the SOAP call answer with a different result
2052
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
2053
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:xtk:session' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
2054
+ <SOAP-ENV:Body>
2055
+ <GetOptionResponse xmlns='urn:xtk:session' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
2056
+ <pstrValue xsi:type='xsd:string'>uFE80000000000000F1FA913DD7CC7C48004116FF</pstrValue>
2057
+ <pbtType xsi:type='xsd:byte'>6</pbtType>
2058
+ </GetOptionResponse>
2059
+ </SOAP-ENV:Body>
2060
+ </SOAP-ENV:Envelope>`));
2061
+ await client.getOption("XtkDatabaseId", true);
2062
+ expect(client._optionCache._cache["XtkDatabaseId"].value).toMatchObject({ type: 6, rawValue: "uFE80000000000000F1FA913DD7CC7C48004116FF" });
2063
+ })
2064
+
2065
+ it("Should set default value for traceAPICalls", async () => {
2066
+ var client = await Mock.makeClient({ traceAPICalls: undefined });
2067
+ expect(client._traceAPICalls).toBeFalsy();
2068
+ client = await Mock.makeClient({ traceAPICalls: null });
2069
+ expect(client._traceAPICalls).toBeFalsy();
2070
+ client = await Mock.makeClient({ traceAPICalls: false });
2071
+ expect(client._traceAPICalls).toBeFalsy();
2072
+ client = await Mock.makeClient({ traceAPICalls: true });
2073
+ expect(client._traceAPICalls).toBeTruthy();
2074
+ })
2075
+
2076
+ it("Should set default transport", async () => {
2077
+ var client = await Mock.makeClient({ transport: async () => {
2078
+ return "Hello";
2079
+ }});
2080
+ await expect(client._transport()).resolves.toBe("Hello");
2081
+ });
2082
+ })
2083
+
2084
+
2085
+ describe("Local storage", () => {
2086
+ it("Shoud read from local storage", async () => {
2087
+ const storage = {
2088
+ getItem: jest.fn(),
2089
+ setItem: jest.fn(),
2090
+ }
2091
+ const client = await Mock.makeClient({ storage: storage });
2092
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2093
+ client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
2094
+ await client.NLWS.xtkSession.logon();
2095
+ storage.getItem.mockReturnValueOnce(JSON.stringify({value: { value: "Hello", type: 6 }, cachedAt: 1633715996021 }));
2096
+ const value = await client.getOption("XtkDatabaseId");
2097
+ expect(value).toBe("Hello");
2098
+ })
2099
+
2100
+ it("Should write to local storage", async () => {
2101
+ const storage = {
2102
+ getItem: jest.fn(),
2103
+ setItem: jest.fn(),
2104
+ }
2105
+ const client = await Mock.makeClient({ storage: storage });
2106
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2107
+ client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
2108
+ await client.NLWS.xtkSession.logon();
2109
+ storage.getItem.mockReturnValueOnce(JSON.stringify({value: { value: "Hello", type: 6 }, cachedAt: 1633715996021 }));
2110
+ client._transport.mockReturnValueOnce(Promise.resolve(`<?xml version='1.0'?>
2111
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:wpp:default' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
2112
+ <SOAP-ENV:Body>
2113
+ <WriteResponse xmlns='urn:wpp:default' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
2114
+ </WriteResponse>
2115
+ </SOAP-ENV:Body>
2116
+ </SOAP-ENV:Envelope>`));
2117
+ await client.setOption("XtkDatabaseId", "World");
2118
+ var call = undefined;
2119
+ for (var i=0; i<storage.setItem.mock.calls.length; i++) {
2120
+ if (storage.setItem.mock.calls[i][0].endsWith("OptionCache$XtkDatabaseId")) {
2121
+ call = storage.setItem.mock.calls[i];
2122
+ break;
2123
+ }
2124
+ }
2125
+ expect(JSON.parse(call[1])).toMatchObject({
2126
+ value: { value: "World", type: 6 }
2127
+ })
2128
+ });
2129
+
2130
+ it("Should ignore protocol for local storage root key", async () => {
2131
+ var connectionParameters = sdk.ConnectionParameters.ofUserAndPassword("http://acc-sdk:8080", "admin", "admin", {});
2132
+ var client = await sdk.init(connectionParameters);
2133
+ expect(client._optionCache._storage._rootKey).toBe("acc.js.sdk.1.0.6.acc-sdk:8080.cache.OptionCache$");
2134
+
2135
+ connectionParameters = sdk.ConnectionParameters.ofUserAndPassword("https://acc-sdk:8080", "admin", "admin", {});
2136
+ client = await sdk.init(connectionParameters);
2137
+ expect(client._optionCache._storage._rootKey).toBe("acc.js.sdk.1.0.6.acc-sdk:8080.cache.OptionCache$");
2138
+
2139
+ connectionParameters = sdk.ConnectionParameters.ofUserAndPassword("acc-sdk:8080", "admin", "admin", {});
2140
+ client = await sdk.init(connectionParameters);
2141
+ expect(client._optionCache._storage._rootKey).toBe("acc.js.sdk.1.0.6.acc-sdk:8080.cache.OptionCache$");
2142
+ })
2143
+
2144
+ it("Should support no storage", async () => {
2145
+ const storage = {
2146
+ getItem: jest.fn(),
2147
+ setItem: jest.fn(),
2148
+ }
2149
+ const client = await Mock.makeClient({ storage: storage, noStorage: true });
2150
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2151
+ client._transport.mockReturnValueOnce(Mock.GET_XTK_SESSION_SCHEMA_RESPONSE);
2152
+ await client.NLWS.xtkSession.logon();
2153
+ client._transport.mockReturnValueOnce(Mock.GET_DATABASEID_RESPONSE);
2154
+ const value = await client.getOption("XtkDatabaseId");
2155
+ expect(value).toBe('uFE80000000000000F1FA913DD7CC7C480041161C');
2156
+ expect(storage.getItem.mock.calls.length).toBe(0); // storage is disabled and should not have been called
2157
+ })
2158
+
2159
+ it("Should cache XML in storage", async () => {
2160
+ const map = {};
2161
+ const storage = {
2162
+ getItem: jest.fn((key) => map[key]),
2163
+ setItem: jest.fn((key, value) => map[key] = value)
2164
+ }
2165
+ let client = await Mock.makeClient({ storage: storage });
2166
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2167
+ await client.NLWS.xtkSession.logon();
2168
+ client._transport.mockReturnValueOnce(Mock.GET_NMS_EXTACCOUNT_SCHEMA_RESPONSE);
2169
+ await client.getSchema("nms:extAccount");
2170
+ // Schema should have been cached to local storage
2171
+ expect(storage.setItem.mock.calls.length).toBe(1);
2172
+ expect(storage.setItem.mock.calls[0][0]).toMatch("cache.XtkEntityCache$xtk:schema|nms:extAccount");
2173
+ // Value is the cached object, it should not be an empty object
2174
+ const cached = JSON.parse(storage.setItem.mock.calls[0][1]);
2175
+ expect(Object.keys(cached.value).length).toBeGreaterThan(0);
2176
+ expect(cached.value).toMatch("<schema");
2177
+
2178
+ // Now simulate reusing the local storage. We need a new client to make sure we do not reuse
2179
+ // the in-memory cache of the client.
2180
+ client = await Mock.makeClient({ storage: storage });
2181
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2182
+ await client.NLWS.xtkSession.logon();
2183
+ client._transport.mockReturnValueOnce(Mock.GET_NMS_EXTACCOUNT_SCHEMA_RESPONSE);
2184
+ await client.getSchema("nms:extAccount");
2185
+ })
2186
+ })
2187
+
2188
+ describe("Get Schema, cache and representations", () => {
2189
+ it("Should get schema with no cache", async () => {
2190
+ const client = await Mock.makeClient();
2191
+ client.clearAllCaches();
2192
+ client._transport.mockReturnValueOnce(Mock.LOGON_RESPONSE);
2193
+ await client.NLWS.xtkSession.logon();
2194
+
2195
+ client._transport.mockReturnValueOnce(Mock.GET_NMS_EXTACCOUNT_SCHEMA_RESPONSE);
2196
+ var schema = await client.getSchema("nms:extAccount");
2197
+ expect(schema["namespace"]).toBe("nms");
2198
+ expect(schema["name"]).toBe("extAccount");
2199
+ });
2200
+
2201
+ });
1880
2202
  });
@@ -523,4 +523,27 @@ describe('DomUtil', function() {
523
523
  });
524
524
  });
525
525
 
526
+ describe("Text and CDATA nodes", () => {
527
+ it("Should handle cdata node", () => {
528
+ const xml = DomUtil.parse(`<workflow-collection><workflow id="1840" internalName="cleanup" label="Database cleanup"><desc><![CDATA[Ensure that obsolete data are deleted from the database.]]></desc></workflow></workflow-collection>`);
529
+ const json = DomUtil.toJSON(xml);
530
+ expect(json.workflow[0]["$desc"]).toBe("Ensure that obsolete data are deleted from the database.");
531
+ expect(json.workflow[0]["desc"]).toBeUndefined();
532
+ });
533
+
534
+ it("Should handle text node", () => {
535
+ const xml = DomUtil.parse(`<workflow-collection><workflow id="1840" internalName="cleanup" label="Database cleanup"><desc>Ensure that obsolete data are deleted from the database.</desc></workflow></workflow-collection>`);
536
+ const json = DomUtil.toJSON(xml);
537
+ expect(json.workflow[0]["$desc"]).toBe("Ensure that obsolete data are deleted from the database.");
538
+ expect(json.workflow[0]["desc"]).toBeUndefined();
539
+ });
540
+
541
+ it("Should handle empty node", () => {
542
+ const xml = DomUtil.parse(`<workflow-collection><workflow id="1840" internalName="cleanup" label="Database cleanup"><desc/></workflow></workflow-collection>`);
543
+ const json = DomUtil.toJSON(xml);
544
+ expect(json.workflow[0]["$desc"]).toBeUndefined();
545
+ expect(json.workflow[0]["desc"]).toStrictEqual({});
546
+ });
547
+ });
548
+
526
549
  });
@@ -60,4 +60,19 @@ describe('ACC SDK', function() {
60
60
  });
61
61
  });
62
62
 
63
+
64
+ describe("IP", () => {
65
+ it("Should get IP address", async () => {
66
+ const t = jest.fn();
67
+ const old = sdk._transport(t);
68
+ try {
69
+ t.mockReturnValueOnce(Promise.resolve({ "ipAddress":"AAA.BBB.CCC.DDD","continentCode":"EU","continentName":"Europe","countryCode":"FR","countryName":"France","stateProv":"Centre-Val de Loire","city":"Bourges" }));
70
+ const ip = await sdk.ip();
71
+ expect(ip).toMatchObject({ "ipAddress":"AAA.BBB.CCC.DDD" });
72
+ } finally {
73
+ sdk._transport(old);
74
+ }
75
+ });
76
+ })
77
+
63
78
  });
package/test/mock.js CHANGED
@@ -21,14 +21,16 @@ governing permissions and limitations under the License.
21
21
  async function makeAnonymousClient(options) {
22
22
  const connectionParameters = sdk.ConnectionParameters.ofAnonymousUser("http://acc-sdk:8080", options);
23
23
  const client = await sdk.init(connectionParameters);
24
- client._transport = jest.fn();
24
+ if (!options || !options.transport) // allow tests to explicitely set the transport
25
+ client._transport = jest.fn();
25
26
  return client;
26
27
  }
27
28
 
28
29
  async function makeClient(options) {
29
30
  const connectionParameters = sdk.ConnectionParameters.ofUserAndPassword("http://acc-sdk:8080", "admin", "admin", options);
30
31
  const client = await sdk.init(connectionParameters);
31
- client._transport = jest.fn();
32
+ if (!options || !options.transport) // allow tests to explicitely set the transport
33
+ client._transport = jest.fn();
32
34
  return client;
33
35
  }
34
36
 
@@ -61,7 +63,7 @@ const LOGON_RESPONSE = Promise.resolve(`<?xml version='1.0'?>
61
63
  <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:xtk:session' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
62
64
  <SOAP-ENV:Body>
63
65
  <LogonResponse xmlns='urn:xtk:session' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
64
- <pstrSessionToken xsi:type='xsd:string'>___C8B4A541-48DC-4C97-95AD-066930FD3892</pstrSessionToken>
66
+ <pstrSessionToken xsi:type='xsd:string'>___$session_token$</pstrSessionToken>
65
67
  <pSessionInfo xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
66
68
  <sessionInfo>
67
69
  <serverInfo advisedClientBuildNumber="0" allowSQL="false" buildNumber="9219" commitId="f5f3ec3" databaseId="uFE80000000000000F1FA913DD7CC7C480041161C" defaultNameSpace="cus" fohVersion="2" instanceName="ffdamkt" majNumber="6" minClientBuildNumber="8969" minNumber="7" minNumberTechnical="0" releaseName="20.3" securityTimeOut="86400" serverDate="2020-07-05 14:11:31.986Z" servicePack="0" sessionTimeOut="86400" useVault="false"/>
@@ -73,11 +75,32 @@ const LOGON_RESPONSE = Promise.resolve(`<?xml version='1.0'?>
73
75
  </userInfo>
74
76
  </sessionInfo>
75
77
  </pSessionInfo>
76
- <pstrSecurityToken xsi:type='xsd:string'>@mMBSMLXIpQd56agsZ5X7OGXWz8Q476qMq6FimwqCdT1wByRDq3pQtaYSY4uJnAbCgXIvpXA5TrxHu-3YjUad5g==</pstrSecurityToken>
78
+ <pstrSecurityToken xsi:type='xsd:string'>@$security_token$==</pstrSecurityToken>
77
79
  </LogonResponse>
78
80
  </SOAP-ENV:Body>
79
81
  </SOAP-ENV:Envelope>`);
80
82
 
83
+ const BEARER_LOGON_RESPONSE = Promise.resolve(`<?xml version='1.0'?>
84
+ <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:xtk:session' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
85
+ <SOAP-ENV:Body>
86
+ <BearerTokenLogonResponse xmlns='urn:xtk:session' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
87
+ <pstrSessionToken xsi:type='xsd:string'>___$session_token$</pstrSessionToken>
88
+ <pSessionInfo xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
89
+ <sessionInfo>
90
+ <serverInfo advisedClientBuildNumber="0" allowSQL="false" buildNumber="9219" commitId="f5f3ec3" databaseId="uFE80000000000000F1FA913DD7CC7C480041161C" defaultNameSpace="cus" fohVersion="2" instanceName="ffdamkt" majNumber="6" minClientBuildNumber="8969" minNumber="7" minNumberTechnical="0" releaseName="20.3" securityTimeOut="86400" serverDate="2020-07-05 14:11:31.986Z" servicePack="0" sessionTimeOut="86400" useVault="false"/>
91
+ <userInfo datakitInDatabase="true" homeDir="" instanceLocale="en" locale="en" login="admin" loginCS="Administrator (admin)" loginId="1059" noConsoleCnx="false" orgUnitId="0" theme="" timezone="Europe/Paris">
92
+ <login-group id="1060"/>
93
+ <login-right right="admin"/>
94
+ <installed-package name="campaign" namespace="nms"/>
95
+ <installed-package name="core" namespace="nms"/>
96
+ </userInfo>
97
+ </sessionInfo>
98
+ </pSessionInfo>
99
+ <pstrSecurityToken xsi:type='xsd:string'>@$security_token$==</pstrSecurityToken>
100
+ </BearerTokenLogonResponse>
101
+ </SOAP-ENV:Body>
102
+ </SOAP-ENV:Envelope>`);
103
+
81
104
  const LOGON_RESPONSE_NO_USERINFO = Promise.resolve(`<?xml version='1.0'?>
82
105
  <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='urn:xtk:session' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
83
106
  <SOAP-ENV:Body>
@@ -576,6 +599,7 @@ exports.Mock = {
576
599
  MC_PING: MC_PING,
577
600
  MC_PING_ERROR: MC_PING_ERROR,
578
601
  LOGON_RESPONSE: LOGON_RESPONSE,
602
+ BEARER_LOGON_RESPONSE: BEARER_LOGON_RESPONSE,
579
603
  LOGON_RESPONSE_NO_SESSIONTOKEN: LOGON_RESPONSE_NO_SESSIONTOKEN,
580
604
  LOGON_RESPONSE_NO_SECURITYTOKEN: LOGON_RESPONSE_NO_SECURITYTOKEN,
581
605
  LOGOFF_RESPONSE: LOGOFF_RESPONSE,
package/test/soap.test.js CHANGED
@@ -150,14 +150,15 @@ describe('SOAP', function() {
150
150
  assert.equal(request.headers["Content-type"], "application/soap+xml");
151
151
  assert.equal(request.headers["SoapAction"], "xtk:session#Empty");
152
152
  assert.equal(request.headers["X-Security-Token"], "");
153
- assert.equal(request.headers["Cookie"], "__sessiontoken=");
153
+ expect(request.headers["Cookie"]).toBeUndefined();
154
154
  const env = DomUtil.parse(request.data).documentElement;
155
155
  const header = hasChildElement(env, "SOAP-ENV:Header");
156
- hasChildElement(header, "Cookie", "__sessiontoken=");
156
+ expect(DomUtil.findElement(header, "Cookie")).toBeFalsy();
157
157
  hasChildElement(header, "X-Security-Token");
158
158
  const body = hasChildElement(env, "SOAP-ENV:Body");
159
159
  const method = hasChildElement(body, "m:Empty", undefined, "xmlns:m", "urn:xtk:session", "SOAP-ENV:encodingStyle", "http://schemas.xmlsoap.org/soap/encoding/");
160
- hasChildElement(method, "sessiontoken", "", "xsi:type", "xsd:string");
160
+ // sessiontoken is always required as first parameter, even if not set
161
+ expect(DomUtil.findElement(method, "sessiontoken")).toBeTruthy();
161
162
  });
162
163
 
163
164
  it('Should have set authentication tokens', function() {
@@ -791,5 +792,18 @@ describe("Campaign exception", () => {
791
792
  })
792
793
  })
793
794
 
795
+ it("CampaignException should hide sensitive information", () => {
796
+ const call = makeSoapMethodCall(undefined, "xtk:session", "Date", "$session$", "$security$", "My User Agent");
797
+ call.finalize("http://ffdamkt:8080/nl/jsp/soaprouter.jsp")
798
+ const ex = makeCampaignException(call, new Error("Failed"));
799
+ const req = ex.methodCall.request;
800
+ expect(req.data.indexOf("$session$")).toBe(-1);
801
+ expect(req.data.indexOf("$security$")).toBe(-1);
802
+ expect(req.headers.Cookie.indexOf("$session$")).toBe(-1);
803
+ expect(req.headers.Cookie.indexOf("$security$")).toBe(-1);
804
+ expect(req.headers["X-Security-Token"].indexOf("$session$")).toBe(-1);
805
+ expect(req.headers["X-Security-Token"].indexOf("$security$")).toBe(-1);
806
+ })
807
+
794
808
  });
795
809