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

FLEXIN-74: changed endpoints for init and token refresh #46

Merged
merged 28 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a4592c0
FLEXIN-74: changed endpoints for init and token refresh
ashishkumarTWLO Aug 8, 2023
3d2147a
FLEXIN-74: added spaces
ashishkumarTWLO Aug 8, 2023
2d7a84c
FLEXIN-74: added deploymentKey and region to the apis
ashishkumarTWLO Aug 9, 2023
0d6c019
FLEXIN-74: updated deprecated event
ashishkumarTWLO Aug 9, 2023
93a237d
FLEXIN-74: updated test
ashishkumarTWLO Aug 9, 2023
9426d99
FLEXIN-74: updated test
ashishkumarTWLO Aug 9, 2023
1c29d80
FLEXIN-74: address PR comments
ashishkumarTWLO Aug 9, 2023
fe1d04b
FLEXIN-74: added validation
ashishkumarTWLO Aug 11, 2023
e935b78
FLEXIN-74: removed default value for setDeploymentKey()
ashishkumarTWLO Aug 11, 2023
fd6a707
FLEXIN-74: added msg to env variable
ashishkumarTWLO Aug 16, 2023
00df233
Merge branch 'flex-webchat-ui' into FLEXIN-74
ashishkumarTWLO Aug 17, 2023
15bd19e
FLEXIN-74: replaced console with logger framework
ashishkumarTWLO Aug 17, 2023
4d66a64
FLEXIN-74: using each
ashishkumarTWLO Aug 18, 2023
84bedfd
FLEXIN-74: POC changes
ashishkumarTWLO Oct 3, 2023
ee17eba
FLEXIN-74: POC changes 2
ashishkumarTWLO Oct 5, 2023
b7139ac
FLEXIN-74: POC changes 3
ashishkumarTWLO Oct 6, 2023
7465863
Merge branch 'flex-webchat-ui' into FLEXIN-74
ashishkumarTWLO Oct 10, 2023
5fca1f7
FLEXIN-74: corrections after merge conflicts
ashishkumarTWLO Oct 10, 2023
6fc69be
Merge branch 'flex-webchat-ui' into FLEXIN-74
ashishkumarTWLO Oct 10, 2023
ba6e1ba
FLEXIN-74: fixing unit tests
ashishkumarTWLO Oct 10, 2023
80cc23d
FLEXIN-74: fixing unit tests
ashishkumarTWLO Oct 11, 2023
d757719
FLEXIN-74: more fixing
ashishkumarTWLO Oct 11, 2023
807c1dc
FLEXIN-74: more fixing
ashishkumarTWLO Oct 11, 2023
2fece92
Merge branch 'flex-webchat-ui' into FLEXIN-74
ashishkumarTWLO Oct 12, 2023
3b4a1ea
Merge branch 'flex-webchat-ui' into FLEXIN-74
ashishkumarTWLO Oct 12, 2023
8db9c5f
Merge remote-tracking branch 'origin/flex-webchat-ui' into FLEXIN-74
ashishkumarTWLO Oct 16, 2023
4e750f7
FLEXIN-74: fixing more unit tests
ashishkumarTWLO Oct 16, 2023
b45928d
FLEXIN-74: removing log
ashishkumarTWLO Oct 16, 2023
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
8 changes: 2 additions & 6 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,9 @@ API_KEY=
API_SECRET=
ADDRESS_SID=
CONVERSATIONS_SERVICE_SID=
# ALLOWED_ORIGINS should be a comma-separated list of origins
ALLOWED_ORIGINS=http://localhost:3000
## base endpoint of your local server. By default it is "http://localhost:3001"
REACT_APP_SERVER_URL=http://localhost:3001
# Deployment key used to boot the webchat UI locally.
# Deployment key used to boot the Webchat UI locally.
# You can also pass this as part of query params to REACT_APP_SERVER_URL
REACT_APP_DEPLOYMENT_KEY=
# region for the host (i.e stage-us1, dev-us1, us1), defaults to us1(prod)
# Region for the host (i.e stage-us1, dev-us1, us1), defaults to us1(prod)
REACT_APP_REGION=''

10 changes: 9 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,13 @@
"import/no-duplicates": ["error"],
"spaced-comment": "warn",
"prefer-named-capture-group": "off"
}
},
"overrides": [
{
"files": ["src/definitions.ts"],
"rules": {
"camelcase": ["off"]
ashishkumarTWLO marked this conversation as resolved.
Show resolved Hide resolved
}
}
]
}
47 changes: 36 additions & 11 deletions src/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,22 @@ describe("Index", () => {
);
});

it("sets endpoint correctly", () => {
const setEndpointSpy = jest.spyOn(sessionDataHandler, "setEndpoint");
it("sets region correctly", () => {
const setRegionSpy = jest.spyOn(sessionDataHandler, "setRegion");

const serverUrl = "serverUrl";
initWebchat({ serverUrl, deploymentKey: "CV000000" });
const region = "Foo";
initWebchat({ deploymentKey: "CV000000", region });

expect(setEndpointSpy).toBeCalledWith(serverUrl);
expect(setRegionSpy).toBeCalledWith(region);
});

it("sets deployment key correctly", () => {
const setDeploymentKeySpy = jest.spyOn(sessionDataHandler, "setDeploymentKey");

const deploymentKey = "Foo";
initWebchat({ deploymentKey });

expect(setDeploymentKeySpy).toBeCalledWith(deploymentKey);
});

it("initializes config", () => {
Expand All @@ -59,27 +68,43 @@ describe("Index", () => {
it("initializes config with provided config merged with default config", () => {
const initConfigSpy = jest.spyOn(initActions, "initConfig");

const serverUrl = "serverUrl";
initWebchat({ serverUrl, deploymentKey: "CV000000" });
const deploymentKey = "CV000000";
initWebchat({ deploymentKey });

expect(initConfigSpy).toBeCalledWith(expect.objectContaining({ deploymentKey, theme: { isLight: true } }));
});

it("gives error when deploymentKey is missing", () => {
const logger = window.Twilio.getLogger("InitWebChat");
const errorLoggerSpy = jest.spyOn(logger, "error");
initWebchat();
expect(errorLoggerSpy).toBeCalledTimes(1);
expect(errorLoggerSpy).toHaveBeenCalledWith("deploymentKey must exist to connect to Webchat servers");
});

expect(initConfigSpy).toBeCalledWith(expect.objectContaining({ serverUrl, theme: { isLight: true } }));
it("gives warning when unsupported params are passed", () => {
const logger = window.Twilio.getLogger("InitWebChat");
const warningSpy = jest.spyOn(logger, "warn");
initWebchat({ deploymentKey: "xyz", someKey: "abc" });
expect(warningSpy).toBeCalledTimes(1);
expect(warningSpy).toHaveBeenCalledWith("someKey is not supported.");
});

it("triggers expaneded true if appStatus is open", () => {
it("triggers expanded true if appStatus is open", () => {
const changeExpandedStatusSpy = jest.spyOn(genericActions, "changeExpandedStatus");

initWebchat({ deploymentKey: "CV000000", appStatus: "open" });
expect(changeExpandedStatusSpy).toHaveBeenCalledWith({ expanded: true });
});

it("triggers expaneded false if appStatus is closed", () => {
it("triggers expanded false if appStatus is closed", () => {
AnudeepChPaul marked this conversation as resolved.
Show resolved Hide resolved
const changeExpandedStatusSpy = jest.spyOn(genericActions, "changeExpandedStatus");

initWebchat({ deploymentKey: "CV000000", appStatus: "closed" });
expect(changeExpandedStatusSpy).toHaveBeenCalledWith({ expanded: false });
});

it("triggers expaneded false with default appStatus", () => {
it("triggers expanded false with default appStatus", () => {
const changeExpandedStatusSpy = jest.spyOn(genericActions, "changeExpandedStatus");

initWebchat({ deploymentKey: "CV000000" });
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/logger.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { initLogger , getLogger } from "../logger";
import { initLogger, getLogger } from "../logger";

describe("loggerManager", () => {
it("should show a proper message if an invalid log level `DEBUG` is selected", () => {
Expand Down
50 changes: 39 additions & 11 deletions src/__tests__/sessionDataHandler.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fetchMock from "fetch-mock-jest";

import { sessionDataHandler } from "../sessionDataHandler";
import { sessionDataHandler, contactBackend } from "../sessionDataHandler";
import WebChatLogger from "../logger";

jest.mock("../logger");
Expand All @@ -26,9 +26,44 @@ describe("session data handler", () => {
jest.clearAllMocks();
});

it("should set an endpoint", () => {
sessionDataHandler.setEndpoint("foo");
expect(sessionDataHandler.getEndpoint()).toBe("foo");
it("should set the region", () => {
sessionDataHandler.setRegion("Foo");
expect(sessionDataHandler.getRegion()).toBe("Foo");
});

it("should set the deployment key", () => {
sessionDataHandler.setDeploymentKey("key1");
expect(sessionDataHandler.getDeploymentKey()).toBe("key1");
});

describe("contactBackend", () => {
beforeEach(() => () => {
sessionDataHandler.setRegion("");
AnudeepChPaul marked this conversation as resolved.
Show resolved Hide resolved
});

afterEach(() => {
sessionDataHandler.setRegion("");
fetchMock.reset();
});

it("should call correct stage url", async () => {
const mockFetch = Promise.resolve({ ok: true, json: async () => Promise.resolve("okay") });
const fetchSpy = jest
.spyOn(window, "fetch")
.mockImplementation(async (): Promise<never> => mockFetch as Promise<never>);
mdeshpande12 marked this conversation as resolved.
Show resolved Hide resolved
sessionDataHandler.setRegion("stage");
await contactBackend("/Webchat/Tokens/Refresh", { formData: {} });
AnudeepChPaul marked this conversation as resolved.
Show resolved Hide resolved
expect(fetchSpy.mock.calls[0][0]).toEqual("https://flex-api.stage.twilio.com/v2/Webchat/Tokens/Refresh");
});

it("should call correct prod url", async () => {
const mockFetch = Promise.resolve({ ok: true, json: async () => Promise.resolve("okay") });
const fetchSpy = jest
.spyOn(window, "fetch")
.mockImplementation(async (): Promise<never> => mockFetch as Promise<never>);
await contactBackend("/Webchat/Tokens/Refresh", { formData: {} });
expect(fetchSpy.mock.calls[0][0]).toEqual("https://flex-api.twilio.com/v2/Webchat/Tokens/Refresh");
});
});

describe("fetch and store new session", () => {
Expand Down Expand Up @@ -196,13 +231,6 @@ describe("session data handler", () => {
expect(spyRemove).toHaveBeenCalled();
});

describe("endpoint", () => {
it("should be able to store endpoint", () => {
sessionDataHandler.setEndpoint("http://localhost:4000");
expect(sessionDataHandler.getEndpoint()).toEqual("http://localhost:4000");
});
});

describe("contactBackend", () => {
it("should", async () => {
jest.spyOn(window, "fetch").mockRejectedValueOnce("ForcedFailure");
Expand Down
4 changes: 2 additions & 2 deletions src/components/PreEngagementFormPhase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const PreEngagementFormPhase = () => {
dispatch(
initSession({
token: data.token,
conversationSid: data.conversationSid
conversationSid: data.conversation_sid
})
);
} catch (err) {
Expand Down Expand Up @@ -97,7 +97,7 @@ export const PreEngagementFormPhase = () => {
data-test="pre-engagement-chat-form-query-textarea"
value={query}
onChange={(e) => dispatch(updatePreEngagementData({ query: e.target.value }))}
onKeyPress={handleKeyPress}
onKeyDown={handleKeyPress}
vinesh-kumar marked this conversation as resolved.
Show resolved Hide resolved
required
/>
</Box>
Expand Down
9 changes: 2 additions & 7 deletions src/components/WebchatWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,10 @@ export function WebchatWidget() {
if (data) {
try {
logger.info("Initializing session.");
dispatch(
initSession({
token: data.token,
conversationSid: data.conversationSid
})
);
dispatch(initSession({ token: data.token, conversationSid: data.conversation_sid }));
} catch (e) {
// if initSession fails, go to changeEngagement phase - most likely there's something wrong with the store token or conversation sis
logger.error("Something wrong with the store token or conversation sis. Changing engagement phase.");
logger.error("Something wrong with the store token or conversation_sid. Changing engagement phase.");
dispatch(changeEngagementPhase({ phase: EngagementPhase.PreEngagementForm }));
}
} else {
Expand Down
10 changes: 5 additions & 5 deletions src/components/__tests__/PreEngagementFormPhase.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import { sessionDataHandler } from "../../sessionDataHandler";
import { store } from "../../store/store";

const token = "token";
const conversationSid = "sid";
const conversation_sid = "sid";
jest.mock("../../sessionDataHandler", () => ({
sessionDataHandler: {
fetchAndStoreNewSession: () => ({ token, conversationSid }),
fetchAndStoreNewSession: () => ({ token, conversation_sid }),
getRegion: jest.fn()
}
}));
Expand Down Expand Up @@ -91,7 +91,7 @@ describe("Pre Engagement Form Phase", () => {
fireEvent.submit(formBox);

await waitFor(() => {
expect(initAction.initSession).toHaveBeenCalledWith({ token, conversationSid });
expect(initAction.initSession).toHaveBeenCalledWith({ token, conversationSid: conversation_sid });
});
});

Expand Down Expand Up @@ -144,7 +144,7 @@ describe("Pre Engagement Form Phase", () => {
const { container } = render(withStore(<PreEngagementFormPhase />));

const textArea = container.querySelector("textarea") as Element;
fireEvent.keyPress(textArea, { key: "Enter", code: "Enter", charCode: 13, shiftKey: false });
fireEvent.keyDown(textArea, { key: "Enter", code: "Enter", charCode: 13, shiftKey: false });

expect(fetchAndStoreNewSessionSpy).toHaveBeenCalled();
});
Expand All @@ -154,7 +154,7 @@ describe("Pre Engagement Form Phase", () => {
const { container } = render(withStore(<PreEngagementFormPhase />));

const textArea = container.querySelector("textarea") as Element;
fireEvent.keyPress(textArea, { key: "Enter", code: "Enter", charCode: 13, shiftKey: true });
fireEvent.keyDown(textArea, { key: "Enter", code: "Enter", charCode: 13, shiftKey: true });

expect(fetchAndStoreNewSessionSpy).not.toHaveBeenCalled();
});
Expand Down
7 changes: 5 additions & 2 deletions src/components/__tests__/WebchatWidget.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ afterEach(() => {
describe("Webchat Lite", () => {
const sessionData = {
token: "token",
conversationSid: "sid"
conversation_sid: "sid"
};
const region = "stage";

Expand All @@ -77,7 +77,10 @@ describe("Webchat Lite", () => {

render(<WebchatWidget />);

expect(initSessionSpy).toHaveBeenCalledWith(sessionData);
expect(initSessionSpy).toHaveBeenCalledWith({
token: sessionData.token,
conversationSid: sessionData.conversation_sid
});
});

it("start pre-engagement form if no pre-existing session data", () => {
Expand Down
2 changes: 1 addition & 1 deletion src/definitions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export type TokenResponse = {
token: string;
conversationSid: string;
conversation_sid: string;
AnudeepChPaul marked this conversation as resolved.
Show resolved Hide resolved
identity: string;
expiration: string;
};
Expand Down
23 changes: 9 additions & 14 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,24 @@ const defaultConfig: ConfigState = {
};

const initWebchat = async (userConfig: UserConfig) => {
// eslint-disable-next-line no-warning-comments
// TODO: serverUrl needs to be removed with PR #74
const validKeys = ["deploymentKey", "region", "theme", "serverUrl", "appStatus"];
const validKeys = ["deploymentKey", "region", "theme", "appStatus"];
const logger = window.Twilio.getLogger(`InitWebChat`);

// eslint-disable-next-line no-warning-comments
// TODO: Returning from here if no deployment key with PR #74
if (!userConfig?.deploymentKey) {
logger.error(`deploymentKey must exist to connect to webchat servers`);
if (!userConfig || !userConfig.deploymentKey) {
AnudeepChPaul marked this conversation as resolved.
Show resolved Hide resolved
logger.error(`deploymentKey must exist to connect to Webchat servers`);
}

Object.keys(userConfig).forEach((userConfigKey) => {
if (!validKeys.includes(userConfigKey)) {
logger.warn(`${userConfigKey} is not supported.`);
for (const key in userConfig) {
if (!validKeys.includes(key)) {
logger.warn(`${key} is not supported.`);
}
});
}

store.dispatch(changeExpandedStatus({ expanded: userConfig.appStatus === "open" }));
delete userConfig.appStatus;
store.dispatch(changeExpandedStatus({ expanded: userConfig?.appStatus === "open" }));
AnudeepChPaul marked this conversation as resolved.
Show resolved Hide resolved
delete userConfig?.appStatus;

const webchatConfig = merge({}, defaultConfig, userConfig);

sessionDataHandler.setEndpoint(webchatConfig.serverUrl);
sessionDataHandler.setRegion(webchatConfig.region);
sessionDataHandler.setDeploymentKey(webchatConfig.deploymentKey);

Expand Down
Loading