diff --git a/__tests__/components/__snapshots__/components.test.js.snap b/__tests__/components/__snapshots__/components.test.js.snap
index ad718fd..11db7c9 100644
--- a/__tests__/components/__snapshots__/components.test.js.snap
+++ b/__tests__/components/__snapshots__/components.test.js.snap
@@ -302,8 +302,27 @@ Array [
]
`;
+exports[`test Collect And Reveal Elements Components test RevealElement component rendering 1`] = `
+Array [
+
+ Card Number
+ ,
+
+ XXXX XXXX XXXX XXXX
+ ,
+ ,
+]
+`;
+
exports[`test Collect And Reveal Elements Components test skyflow provider 1`] = `
- Provider Childern
+ Provider Children
`;
diff --git a/__tests__/components/components.test.js b/__tests__/components/components.test.js
index aa2fb49..207df89 100644
--- a/__tests__/components/components.test.js
+++ b/__tests__/components/components.test.js
@@ -21,6 +21,7 @@ import { Text } from 'react-native';
import SkyflowError from '../../src/utils/skyflow-error';
import SKYFLOW_ERROR_CODE from '../../src/utils/skyflow-error-code';
import { ContainerType, ElementType } from '../../src/utils/constants';
+import { act } from 'react-test-renderer';
const testSkyflowClient = new Skyflow({
vaultID: '1234',
@@ -598,6 +599,84 @@ describe('test Collect And Reveal Elements Components', () => {
}
});
+ it('test RevealElement component rendering', () => {
+ const revealSetMethodMock = jest.fn();
+ const revealSetTokenMock = jest.fn();
+ const revealContainer = new RevealContainer(testSkyflowClient);
+
+ jest.spyOn(revealContainer, 'create').mockImplementation(() => ({
+ setMethods: revealSetMethodMock,
+ setToken: revealSetTokenMock,
+ }));
+
+ const revealElement = render(
+
+ );
+
+ expect(revealElement).toMatchSnapshot();
+ expect(revealSetMethodMock).toBeCalledTimes(1);
+
+ render(
+
+ );
+ expect(screen.getByText('test_token_no_alt')).toBeTruthy();
+
+ try {
+ render();
+ } catch (err) {
+ expect(err).toEqual(
+ new SkyflowError(
+ SKYFLOW_ERROR_CODE.CONTAINER_OBJECT_IS_REQUIRED,
+ ['Reveal', 'useRevealContainer()'],
+ true
+ )
+ );
+ }
+ });
+
+ it('test RevealElement setToken via ref updates UI and internal element', () => {
+ const revealSetMethodMock = jest.fn();
+ const revealSetTokenMock = jest.fn();
+ const revealContainer = new RevealContainer(testSkyflowClient);
+
+ jest.spyOn(revealContainer, 'create').mockImplementation(() => ({
+ setMethods: revealSetMethodMock,
+ setToken: revealSetTokenMock,
+ }));
+
+ const ref = React.createRef();
+ const initialToken = 'initial_token_123';
+ const newToken = 'updated_token_456';
+
+ const { getByText } = render(
+
+ );
+
+ expect(getByText(initialToken)).toBeTruthy();
+
+ act(() => {
+ ref.current.setToken(newToken);
+ });
+
+ expect(revealSetTokenMock).toHaveBeenCalledWith(newToken);
+
+ expect(getByText(newToken)).toBeTruthy();
+ });
+
it('test skyflow provider', () => {
const testSkyflowConfig = {
vaultID: '1234',
@@ -607,7 +686,7 @@ describe('test Collect And Reveal Elements Components', () => {
const providerElement = render(
- Provider Childern
+ Provider Children
);
expect(providerElement).toMatchSnapshot();
diff --git a/__tests__/core/RevealContainer.test.js b/__tests__/core/RevealContainer.test.js
index a126ee6..9fb5530 100644
--- a/__tests__/core/RevealContainer.test.js
+++ b/__tests__/core/RevealContainer.test.js
@@ -146,4 +146,56 @@ describe('test RevealConatiner Class', () => {
}
});
});
+
+ it('test reveal method uses updated token when setToken is called', (done) => {
+ const initialToken = 'initial_token';
+ const updatedToken = 'updated_token';
+
+ const revealElement = revealContainer.create({
+ token: initialToken,
+ });
+
+ const revealSuccessValue = {
+ records: [
+ {
+ token: updatedToken,
+ value: 'revealed_value',
+ },
+ ],
+ };
+
+ const fetchSpy = jest
+ .spyOn(revealUtils, 'fetchRecordsByTokenId')
+ .mockResolvedValue(revealSuccessValue);
+
+ const setValueMock = jest.fn();
+ const setErrorMock = jest.fn();
+ revealElement.setMethods(setValueMock, setErrorMock);
+
+ revealElement.setToken(updatedToken);
+
+ revealContainer
+ .reveal()
+ .then((res) => {
+ try {
+ expect(fetchSpy).toHaveBeenCalledWith(
+ expect.anything(),
+ expect.arrayContaining([
+ expect.objectContaining({
+ token: updatedToken,
+ elementId: revealElement.elementId,
+ }),
+ ])
+ );
+
+ expect(res).toEqual({ success: [{ token: updatedToken }] });
+ done();
+ } catch (assertionError) {
+ done(assertionError);
+ }
+ })
+ .catch((err) => {
+ done(err);
+ });
+ });
});
diff --git a/src/components/RevealElement/index.tsx b/src/components/RevealElement/index.tsx
index d08872a..41ab521 100644
--- a/src/components/RevealElement/index.tsx
+++ b/src/components/RevealElement/index.tsx
@@ -1,16 +1,16 @@
/*
Copyright (c) 2022 Skyflow, Inc.
*/
-import React, { useEffect } from "react";
+import React, { useEffect, useImperativeHandle, forwardRef } from "react";
import { Text } from "react-native";
import RevealSkyflowElement from "../../core/RevealSkyflowElement";
import { RevealElementProps } from "../../utils/constants"
import SkyflowError from "../../utils/skyflow-error";
import SKYFLOW_ERROR_CODE from "../../utils/skyflow-error-code";
-
-const RevealElement: React.FC = ({ container, label, ...rest }) => {
- const [element, setElement] = React.useState(undefined);
+const RevealElement = forwardRef((props: RevealElementProps, ref) => {
+ const { container, label, ...rest } = props;
+ const [element, setElement] = React.useState(undefined);
const [errorText, setErrorText] = React.useState('');
const [value, setValue] = React.useState(rest?.altText || rest.token);
@@ -25,12 +25,26 @@ const RevealElement: React.FC = ({ container, label, ...rest
}, []);
- return <>
- {label}
- {value}
- {errorText}
- >
+ useImperativeHandle(ref, () => ({
+ setToken: (newToken: string) => {
+ if (element) {
+ element.setToken(newToken);
+ setValue(newToken);
+ } else {
+ throw new SkyflowError(SKYFLOW_ERROR_CODE.ELEMENT_NOT_FOUND, ['RevealElement'], true);
+ }
+ }
+ }), [element]);
+
+ return (
+ <>
+ {label}
+ {value}
+ {errorText}
+ >
+ );
+});
-}
+RevealElement.displayName = 'RevealElement';
export default RevealElement;
\ No newline at end of file
diff --git a/src/core/RevealContainer/index.ts b/src/core/RevealContainer/index.ts
index 35552ae..bd20cc4 100644
--- a/src/core/RevealContainer/index.ts
+++ b/src/core/RevealContainer/index.ts
@@ -70,7 +70,22 @@ class RevealContainer extends Container {
try {
validateInitConfig(this.#skyflowClient.getSkyflowConfig());
validateRevealElementRecords(this.#revealRecords);
- fetchRecordsByTokenId(this.#skyflowClient, this.#tokensList).then(
+
+ const freshTokensList = this.#tokensList.map((record) => {
+ const elementInstance = this.#elementList.find(
+ (e) => e.elementId === record.elementId
+ );
+
+ if (elementInstance) {
+ return {
+ ...record,
+ token: elementInstance.getToken(),
+ };
+ }
+ return record;
+ });
+
+ fetchRecordsByTokenId(this.#skyflowClient, freshTokensList).then(
(resolvedResult) => {
const formattedResult = formatRecordsForIframe(resolvedResult);
this.setRevealValuesInElements(formattedResult);
diff --git a/src/core/RevealSkyflowElement/index.ts b/src/core/RevealSkyflowElement/index.ts
index bd4986c..c56e984 100644
--- a/src/core/RevealSkyflowElement/index.ts
+++ b/src/core/RevealSkyflowElement/index.ts
@@ -27,6 +27,10 @@ class RevealSkyflowElement extends SkyflowElement {
this.#setErrorText(REVEAL_ELEMENT_ERROR_TEXT);
}
+ setToken(newToken: string) {
+ this.#token = newToken;
+ }
+
getToken() {
return this.#token;
}
diff --git a/src/utils/logs/index.ts b/src/utils/logs/index.ts
index fb6a125..622246f 100644
--- a/src/utils/logs/index.ts
+++ b/src/utils/logs/index.ts
@@ -133,6 +133,8 @@ const logs = {
`Skyflow ${SDK_NAME_VERSION} initialization failed - SkyflowProvider config is missing. `,
CONTAINER_OBJECT_IS_REQUIRED:
`${SDK_NAME_VERSION} cannot create %s1 element without container object, create a container using %s2 hook.`,
+ ELEMENT_NOT_FOUND:
+ `${SDK_NAME_VERSION} %s1 not found. The specified element does not exist in the container.`,
INVALID_UPSERT_OPTION_TYPE:
`${SDK_NAME_VERSION} Validation error. Invalid \'upsert\' key in insert options. Specify a value of type array instead`,
EMPTY_UPSERT_OPTIONS_ARRAY:
diff --git a/src/utils/skyflow-error-code/index.ts b/src/utils/skyflow-error-code/index.ts
index 14e93eb..333351f 100644
--- a/src/utils/skyflow-error-code/index.ts
+++ b/src/utils/skyflow-error-code/index.ts
@@ -190,6 +190,10 @@ const SKYFLOW_ERROR_CODE = {
code: 400,
description: logs.errorLogs.CONTAINER_OBJECT_IS_REQUIRED,
},
+ ELEMENT_NOT_FOUND: {
+ code: 400,
+ description: logs.errorLogs.ELEMENT_NOT_FOUND,
+ },
INVALID_UPSERT_OPTION_TYPE: {
code: 400,
description: logs.errorLogs.INVALID_UPSERT_OPTION_TYPE,