@mindful-web/marko-web-omeda-identity-x 1.90.1 → 1.90.2

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/README.md CHANGED
@@ -166,10 +166,14 @@ Two caveats:
166
166
  - **Each hook names the value differently.** `onLoginLinkSent` receives `source`,
167
167
  `onAuthenticationSuccess` receives `loginSource`, `onUserProfileUpdate` receives `actionSource`.
168
168
  Pass whichever local holds it.
169
- - **`onUserProfileUpdate` has no reliable source.** Neither `routes/profile.js` nor
170
- `routes/progressive-profile.js` passes one; `actionSource` only arrives if a client put it in
171
- `additionalEventData`, and is usually `undefined`. Overrides on that hook are inert whenever it
172
- is the value resolves to the base config.
169
+ - **`onUserProfileUpdate` reports which surface saved the profile, not a registration source.**
170
+ Both routes that fire it now pass one: `routes/profile.js` sends `profileUpdate` and
171
+ `routes/progressive-profile.js` sends `progressiveProfile` (a client-supplied
172
+ `additionalEventData.actionSource` still wins over either). Neither is in any conversion bucket,
173
+ so **only an exact-source key matches them** — a `newsletter` or `contentGating` bucket override
174
+ will never apply to this hook. Before mindful-web#341 no route passed a source at all and every
175
+ override here was inert; if you are reading an older tenant config that relied on that, it now
176
+ resolves.
173
177
 
174
178
  An unrecognized, empty or missing source is never an error: the set of login sources is open (any
175
179
  site template can introduce a new `source="…"`), so it resolves to the base config.
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
- marko_componentType = "/@mindful-web/marko-web-omeda-identity-x$1.90.1/components/identify.marko",
5
+ marko_componentType = "/@mindful-web/marko-web-omeda-identity-x$1.90.2/components/identify.marko",
6
6
  marko_component = require("./identify.marko"),
7
7
  marko_renderer = require("marko/dist/runtime/components/renderer"),
8
8
  module_getCookieId = require("@mindful-web/marko-web-omeda-identity-x/utils/get-cookie-id"),
@@ -51,7 +51,7 @@ marko_template._ = marko_renderer(render, {
51
51
  }, marko_component);
52
52
 
53
53
  marko_template.meta = {
54
- id: "/@mindful-web/marko-web-omeda-identity-x$1.90.1/components/identify.marko",
54
+ id: "/@mindful-web/marko-web-omeda-identity-x$1.90.2/components/identify.marko",
55
55
  component: "./identify.marko",
56
56
  tags: [
57
57
  "@mindful-web/marko-web-identity-x/components/identify.marko",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindful-web/marko-web-omeda-identity-x",
3
- "version": "1.90.1",
3
+ "version": "1.90.2",
4
4
  "description": "Marko Omeda+IdentityX integration tools",
5
5
  "repository": "https://github.com/parameter1/mindful-web/tree/main/packages/marko-web-omeda-identity-x",
6
6
  "author": "Josh Worden <josh@parameter1.com>",
@@ -13,7 +13,7 @@
13
13
  "test": "yarn compile --no-clean && yarn lint && mocha --reporter spec"
14
14
  },
15
15
  "dependencies": {
16
- "@mindful-web/marko-web-identity-x": "^1.89.2",
16
+ "@mindful-web/marko-web-identity-x": "^1.90.2",
17
17
  "@mindful-web/marko-web-omeda": "^1.88.0",
18
18
  "@mindful-web/object-path": "^1.83.1",
19
19
  "@mindful-web/utils": "^1.83.1",
@@ -33,5 +33,5 @@
33
33
  "chai": "^4.3.7",
34
34
  "mocha": "^6.2.3"
35
35
  },
36
- "gitHead": "e0185d370d34b4d465ceedae9e453b1925e5e6f5"
36
+ "gitHead": "0e498d1c31b3c6a8856b9d75cd9233a121fa173b"
37
37
  }
@@ -0,0 +1,65 @@
1
+ const { describe, it } = require('mocha');
2
+ const { expect } = require('chai');
3
+ const buildBehaviorFactory = require('../utils/build-behavior');
4
+
5
+ // A realistic tenant behavior config (PMMI's, trimmed). Note what `actionSource` does NOT map:
6
+ // there is no `valueId` fallback on it and no entry for the profile-update sources, which is the
7
+ // property the tests below pin.
8
+ const behaviors = { logIn: 103, verifyEmail: 104, submitProfile: 105 };
9
+ const behaviorAttributes = {
10
+ website: { id: 8, valueId: 12345 },
11
+ actionSource: {
12
+ id: 11,
13
+ valueIds: {
14
+ default: 199623,
15
+ newsletterSignup: 199625,
16
+ comments: 199626,
17
+ contentGate: 199620,
18
+ },
19
+ },
20
+ };
21
+
22
+ const buildBehaviorFor = buildBehaviorFactory({ behaviors, behaviorAttributes });
23
+ const attrsById = (behavior) => behavior.attributes.reduce((o, { id, valueId }) => ({
24
+ ...o,
25
+ [id]: valueId,
26
+ }), {});
27
+
28
+ describe('utils/build-behavior', () => {
29
+ it('maps each hook to its behavior id', () => {
30
+ expect(buildBehaviorFor('onLoginLinkSent', {}).id).to.equal(103);
31
+ expect(buildBehaviorFor('onAuthenticationSuccess', {}).id).to.equal(104);
32
+ expect(buildBehaviorFor('onUserProfileUpdate', {}).id).to.equal(105);
33
+ expect(buildBehaviorFor('onSomethingElse', {})).to.equal(undefined);
34
+ });
35
+
36
+ it('resolves a mapped action source to its value id', () => {
37
+ const attrs = attrsById(buildBehaviorFor('onLoginLinkSent', { actionSource: 'contentGate' }));
38
+ expect(attrs[11]).to.equal(199620);
39
+ });
40
+
41
+ // This is the guarantee that let `routes/profile.js` start passing a real `actionSource`
42
+ // (mindful-web#341) without touching a single tenant's Omeda behavior data. `profileUpdate` and
43
+ // `progressiveProfile` are mapped by no tenant, and an unmapped source must be OMITTED — it must
44
+ // never fall through to `valueIds.default` (which would silently relabel every profile save as a
45
+ // default-source action) and must never emit an undefined value id to Omeda.
46
+ //
47
+ // If a tenant later adds `valueIds.profileUpdate`, that is an opt-in and this test still holds:
48
+ // it asserts the behavior for a config that does not map the source.
49
+ ['profileUpdate', 'progressiveProfile', 'somethingNobodyMapped'].forEach((actionSource) => {
50
+ it(`omits the action source attribute for unmapped source '${actionSource}'`, () => {
51
+ const behavior = buildBehaviorFor('onUserProfileUpdate', { actionSource });
52
+ expect(behavior.id).to.equal(105);
53
+ expect(behavior.attributes.map(({ id }) => id)).to.not.include(11);
54
+ // The website attribute has a `valueId` fallback, so it still rides along.
55
+ expect(attrsById(behavior)[8]).to.equal(12345);
56
+ });
57
+ });
58
+
59
+ it('omits the action source attribute when no source is passed at all', () => {
60
+ // The pre-#341 behavior of `routes/profile.js`. Identical to the unmapped case above, which is
61
+ // precisely why passing a source is safe.
62
+ const behavior = buildBehaviorFor('onUserProfileUpdate', {});
63
+ expect(behavior.attributes.map(({ id }) => id)).to.not.include(11);
64
+ });
65
+ });
@@ -46,8 +46,12 @@ const isPlainObject = (v) => Boolean(v) && typeof v === 'object' && !Array.isArr
46
46
  *
47
47
  * Note the three hooks name this value differently in their formatter args: `onLoginLinkSent`
48
48
  * receives `source`, `onAuthenticationSuccess` receives `loginSource`, and `onUserProfileUpdate`
49
- * receives `actionSource` (which is client-supplied and frequently `undefined` — overrides on that
50
- * hook are inert whenever it is). Pass whichever local holds the value.
49
+ * receives `actionSource`. Pass whichever local holds the value.
50
+ *
51
+ * `actionSource` carries the surface that saved the profile — `profileUpdate` from
52
+ * `routes/profile.js`, `progressiveProfile` from `routes/progressive-profile.js`, or whatever a
53
+ * client put in `additionalEventData`. Neither route value belongs to a conversion bucket, so on
54
+ * that hook only an exact-source key can match.
51
55
  *
52
56
  * @param {object} params
53
57
  * @param {object} [params.optInHooks] The site's `identityXOptInHooks` config.