Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added propositions option to sendEvent command to make display notifications easier #985

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ module.exports = {
}
]
}
]
],
"no-underscore-dangle": ["error", { allow: ["_experience"] }]
},
globals: {
expectAsync: "readonly", // newer jasmine feature
Expand Down
5 changes: 5 additions & 0 deletions sandbox/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import RedirectedNewPage from "./RedirectedNewPage";
import PersonalizationAnalyticsClientSide from "./PersonalizationAnalyticsClientSide";
import PersonalizationFormBased from "./PersonalizationFormBased";
import Identity from "./Identity";
import TopBottom from "./TopBottom";
import AlloyVersion from "./components/AlloyVersion";
import ConfigOverrides from "./ConfigOverrides.jsx";

Expand Down Expand Up @@ -93,6 +94,9 @@ function BasicExample() {
<li>
<a href="/identity">Identity</a>
</li>
<li>
<a href="/topBottom">Top/Bottom</a>
</li>
<li>
<a href="/configOverrides">Config Overrides</a>
</li>
Expand Down Expand Up @@ -124,6 +128,7 @@ function BasicExample() {
<Route path="/redirectOffers" component={RedirectOffers} />
<Route path="/redirectedNewPage" component={RedirectedNewPage} />
<Route path="/identity" component={Identity} />
<Route path="/topBottom" component={TopBottom} />
<Route path="/configOverrides" component={ConfigOverrides} />
</div>
</Router>
Expand Down
47 changes: 47 additions & 0 deletions sandbox/src/TopBottom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React, { useEffect } from "react";
import ContentSecurityPolicy from "./components/ContentSecurityPolicy";

export default function TopBottom() {
useEffect(async () => {
let { propositions } = await window.alloy("sendEvent", {
renderDecisions: false,
personalization: {
decisionScopes: ["__view__"]
},
xdm: {
eventType: "decisioning.propositionFetch"
}
});

({ propositions } = await window.alloy("applyPropositions", {
propositions
}));

await window.alloy("sendEvent", {
xdm: {
eventType: "page-view"
},
propositions
});
}, []);

return (
<div>
<ContentSecurityPolicy />
<h1>Top/Bottom Example</h1>
<p>
This page tests rendering of activities using an AJO surface. If you
navigated here from another sandbox view, you will probably need to
refresh your browser because this is how to properly simulate a non-SPA
workflow.
</p>
<div
style={{ border: "1px solid red" }}
className="personalization-container"
>
This is the personalization placeholder. Personalized content has not
been loaded.
</div>
</div>
);
}
4 changes: 3 additions & 1 deletion sandbox/src/useSendPageViewEvent.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ export default ({
setPropositions
} = {}) => {
useEffect(() => {
xdm.eventType = "page-view";
if (!xdm.eventType) {
xdm.eventType = "page-view";
}

if (viewName) {
xdm.web = {
Expand Down
4 changes: 3 additions & 1 deletion src/components/DataCollector/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const createDataCollector = ({ eventManager, logger }) => {
decisionScopes = [], // Note: this option will soon be deprecated, please use personalization.decisionScopes instead
personalization = {},
datasetId,
propositions = [],
edgeConfigOverrides
} = options;
const event = eventManager.createEvent();
Expand All @@ -59,7 +60,8 @@ const createDataCollector = ({ eventManager, logger }) => {
const sendEventOptions = {
renderDecisions,
decisionScopes,
personalization
personalization,
propositions
};

if (edgeConfigOverrides) {
Expand Down
6 changes: 6 additions & 0 deletions src/components/DataCollector/validateUserEventOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ export default ({ options }) => {
}),
datasetId: string(),
mergeId: string(),
propositions: arrayOf(
objectOf({
id: string().required(),
scope: string().required()
})
),
edgeConfigOverrides: validateConfigOverride
})
.required()
Expand Down
22 changes: 22 additions & 0 deletions src/components/Personalization/createComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export default ({
renderDecisions,
decisionScopes = [],
personalization = {},
propositions,
onResponse = noop,
onRequestFailure = noop
}) {
Expand All @@ -64,6 +65,27 @@ export default ({
logger
});

if (propositions && propositions.length > 0) {
const propositionEventType =
event.getEventType() === "decisioning.propositionInteract" ||
event.getPropositionEventType() === "interact"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(non-blocking nitpick) Change this to PropositionEventType.DISPLAY and PropositionEventType.INTERACT from src/components/Personalization/constants/propositionEventType.js.

? "interact"
: "display";

event.mergeXdm({
_experience: {
decisioning: {
propositions: propositions.map(
({ id, scope, scopeDetails }) => ({ id, scope, scopeDetails })
),
propositionEventType: {
[propositionEventType]: 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does the 1 mean?

}
}
}
});
}

if (personalizationDetails.shouldFetchData()) {
const decisionsDeferred = defer();

Expand Down
23 changes: 22 additions & 1 deletion src/core/createEvent.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ OF ANY KIND, either express or implied. See the License for the specific languag
governing permissions and limitations under the License.
*/

import { isEmptyObject, deepAssign } from "../utils";
import { isEmptyObject, deepAssign, find } from "../utils";

export default () => {
const content = {};
Expand Down Expand Up @@ -121,6 +121,27 @@ export default () => {

return userXdm.web.webPageDetails.viewName;
},
getEventType() {
return (
(userXdm && userXdm.eventType) ||
(content.xdm && content.xdm.eventType) ||
undefined
);
},
getPropositionEventType() {
if (
!userXdm ||
!userXdm._experience ||
!userXdm._experience.decisioning ||
!userXdm._experience.decisioning.propositionEventType
) {
return undefined;
}
return find(
Object.keys(userXdm._experience.decisioning.propositionEventType),
key => userXdm._experience.decisioning.propositionEventType[key] === 1
);
},
toJSON() {
if (!isFinalized) {
throw new Error("toJSON called before finalize");
Expand Down
2 changes: 2 additions & 0 deletions src/core/createEventManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export default ({
const {
renderDecisions = false,
decisionScopes,
propositions,
edgeConfigOverrides: localConfigOverrides,
personalization
} = options;
Expand All @@ -70,6 +71,7 @@ export default ({
renderDecisions,
decisionScopes,
personalization,
propositions,
onResponse: onResponseCallbackAggregator.add,
onRequestFailure: onRequestFailureCallbackAggregator.add
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
/*
Copyright 2023 Adobe. All rights reserved.
This file is licensed 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 REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/
export default {
com_adobe_experience_platform: {
datasets: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
/*
Copyright 2023 Adobe. All rights reserved.
This file is licensed 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 REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/
export default {
com_adobe_experience_platform: {
datasets: {
Expand Down
11 changes: 11 additions & 0 deletions test/functional/specs/Config Overrides/C7437530.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
/*
Copyright 2023 Adobe. All rights reserved.
This file is licensed 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 REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/
import { t } from "testcafe";
import createNetworkLogger from "../../helpers/networkLogger";
import { responseStatus } from "../../helpers/assertions/index";
Expand Down
11 changes: 11 additions & 0 deletions test/functional/specs/Config Overrides/C7437531.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
/*
Copyright 2023 Adobe. All rights reserved.
This file is licensed 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 REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/
import { t } from "testcafe";
import createNetworkLogger from "../../helpers/networkLogger";
import { responseStatus } from "../../helpers/assertions/index";
Expand Down
11 changes: 11 additions & 0 deletions test/functional/specs/Config Overrides/C7437532.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
/*
Copyright 2023 Adobe. All rights reserved.
This file is licensed 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 REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/
import { t } from "testcafe";
import createNetworkLogger from "../../helpers/networkLogger";
import { responseStatus } from "../../helpers/assertions/index";
Expand Down
11 changes: 11 additions & 0 deletions test/functional/specs/Config Overrides/C7437533.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
/*
Copyright 2023 Adobe. All rights reserved.
This file is licensed 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 REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/
import { t } from "testcafe";
import createNetworkLogger from "../../helpers/networkLogger";
import { responseStatus } from "../../helpers/assertions/index";
Expand Down
63 changes: 63 additions & 0 deletions test/functional/specs/Personalization/C11001566.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { t } from "testcafe";
import createNetworkLogger from "../../helpers/networkLogger";
import { responseStatus } from "../../helpers/assertions/index";
import createFixture from "../../helpers/createFixture";
import {
compose,
orgMainConfigMain,
debugEnabled
} from "../../helpers/constants/configParts";
import { TEST_PAGE as TEST_PAGE_URL } from "../../helpers/constants/url";
import createAlloyProxy from "../../helpers/createAlloyProxy";

const networkLogger = createNetworkLogger();
const config = compose(orgMainConfigMain, debugEnabled);

createFixture({
title:
"C11001566: A display notification is sent when propositions are included in the sendEvent command",
url: `${TEST_PAGE_URL}?test=C11001566`,
requestHooks: [networkLogger.edgeEndpointLogs]
});

test.meta({
ID: "C11001566",
SEVERITY: "P0",
TEST_RUN: "Regression"
});

test("Test C11001566: A display notification is sent when propositions are included in the sendEvent command", async () => {
const alloy = createAlloyProxy();
await alloy.configure(config);
await alloy.sendEvent({
propositions: [
{
id: "C11001566",
scope: "myscope",
scopeDetails: {
type: "test"
}
}
]
});

await responseStatus(networkLogger.edgeEndpointLogs.requests, 200);
await t.expect(networkLogger.edgeEndpointLogs.requests.length).eql(1);

const sendEventRequest = networkLogger.edgeEndpointLogs.requests[0];
const requestBody = JSON.parse(sendEventRequest.request.body);
await t.expect(requestBody.events[0].xdm._experience.decisioning).eql({
propositionEventType: {
display: 1
},
propositions: [
{
id: "C11001566",
scope: "myscope",
scopeDetails: {
type: "test"
}
}
]
});
});
Loading