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

feat(qualtrics methods): displayQualtricsIntercept, setQualtricsProperties, isQualtricsInterceptAvailableForUser #185

Merged
merged 3 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
93 changes: 90 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1396,7 +1396,7 @@ in `localStorage`.

### requestDatamobDeviceAdmin

<kbd>App version >=25.x</kbd>
<kbd>App version >=25.0</kbd>

Datamob is a native library that offer developers a way to integrate security
and remote device control features into their applications.
Expand All @@ -1421,7 +1421,7 @@ https://github.com/user-attachments/assets/28095f42-76db-4ac2-9586-e350acef7e1d

### registerDatamobUser

<kbd>App version >=25.x</kbd>
<kbd>App version >=25.0</kbd>

The application that implements the Datamob should have an user registered. This
method is used to register one.
Expand Down Expand Up @@ -1449,7 +1449,7 @@ with the following type:

### validateDatamobRequirements

<kbd>App version >=25.x</kbd>
<kbd>App version >=25.0</kbd>

Datamob sdk allows to send remote commands to the user device. These remote
commands include actions such as locking the device screen (lock screen) or even
Expand Down Expand Up @@ -1479,6 +1479,93 @@ validateDatamobRequirements: ({phoneNumber: string, tokenPassword: string}) => P

- `requirements`: A map with the requirements.

### displayQualtricsIntercept

<kbd>App version >=24.12</kbd>
Copy link
Contributor

@dpastor dpastor Dec 12, 2024

Choose a reason for hiding this comment

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

All methods will be available only for iOS by the moment. In android it's expected to be integrated at some next version.
We can add a "Only for iOS" comment, and when it is integrated in android we can update the doc with the proper version.


Uses the Qualtrics SDK to display a survey intercept to the user if possible.

The native app will try to show the survey related to the provided `interceptId`

It will return a boolean (`displayed`) indicating if the survey has been
displayed or not.

```ts
displayQualtricsIntercept: ({interceptId: string}) => Promise<{displayed: boolean}>;
```

#### Error cases

```ts
{
code: 500;
reason: 'Internal Error'; // If an error occurred invoking the SDK;
}
```

```ts
{
code: 501;
reason: 'SDK not initialized';
}
```

### setQualtricsProperties

<kbd>App version >=24.12</kbd>

Method to set properties in Qualtrics SDK before displaying a survey.

```ts
setQualtricsProperties: ({
stringProperties: Array<QualtricsProperty<string>>;
numberProperties: Array<QualtricsProperty<number>>;
dateTimePropertyKeys: Array<string>;
}) => Promise<void>;
```

#### Error cases

```ts
{
code: 500;
reason: 'Internal Error'; // If an error occurred invoking the SDK;
}
```

```ts
{
code: 501;
reason: 'SDK not initialized';
}
```

### isQualtricsInterceptAvailableForUser

<kbd>App version >=24.12</kbd>

Check if a Qualtrics intercept is available for the user.

```ts
isQualtricsInterceptAvailableForUser: ({interceptId: string}) => Promise<{isAvailable: boolean}>;
```

#### Error cases

```ts
{
code: 500;
reason: 'Internal Error'; // If an error occurred invoking the SDK;
}
```

```ts
{
code: 501;
reason: 'SDK not initialized';
}
```

## Error handling

If an uncontrolled error occurs, promise will be rejected with an error object:
Expand Down
6 changes: 6 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,9 @@ export {
requestDatamobDeviceAdmin,
validateDatamobRequirements,
} from './src/datamob';

export {
displayQualtricsIntercept,
setQualtricsProperties,
isQualtricsInterceptAvailableForUser,
} from './src/qualtrics';
73 changes: 73 additions & 0 deletions src/__tests__/qualtrics-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {
displayQualtricsIntercept,
isQualtricsInterceptAvailableForUser,
setQualtricsProperties,
} from '../qualtrics';
import {createFakeAndroidPostMessage} from './fake-post-message';

test('displayQualtricsIntercept', async () => {
createFakeAndroidPostMessage({
checkMessage: (msg) => {
expect(msg.type).toBe('DISPLAY_QUALTRICS_INTERCEPT');
expect(msg.payload).toEqual({interceptId: 'anyInterceptId'});
},
getResponse: (msg) => ({
type: 'DISPLAY_QUALTRICS_INTERCEPT',
id: msg.id,
payload: {
displayed: true,
},
}),
});

const res = await displayQualtricsIntercept({
interceptId: 'anyInterceptId',
});
expect(res).toEqual({displayed: true});
});

test('setQualtricsProperties', async () => {
createFakeAndroidPostMessage({
checkMessage: (msg) => {
expect(msg.type).toBe('SET_QUALTRICS_PROPERTIES');
expect(msg.payload).toEqual({
stringProperties: [{key: 'stringKey', value: 'stringValue'}],
numberProperties: [{key: 'numberKey', value: 42}],
dateTimePropertyKeys: ['dateTimeKey'],
});
},
getResponse: (msg) => ({
type: 'SET_QUALTRICS_PROPERTIES',
id: msg.id,
}),
});

const res = await setQualtricsProperties({
stringProperties: [{key: 'stringKey', value: 'stringValue'}],
numberProperties: [{key: 'numberKey', value: 42}],
dateTimePropertyKeys: ['dateTimeKey'],
});

expect(res).toBeUndefined();
});

test('isQualtricsInterceptAvailableForUser', async () => {
createFakeAndroidPostMessage({
checkMessage: (msg) => {
expect(msg.type).toBe('IS_QUALTRICS_INTERCEPT_AVAILABLE_FOR_USER');
expect(msg.payload).toEqual({interceptId: 'anyInterceptId'});
},
getResponse: (msg) => ({
type: 'IS_QUALTRICS_INTERCEPT_AVAILABLE_FOR_USER',
id: msg.id,
payload: {
isAvailable: true,
},
}),
});

const res = await isQualtricsInterceptAvailableForUser({
interceptId: 'anyInterceptId',
});
expect(res).toEqual({isAvailable: true});
});
15 changes: 15 additions & 0 deletions src/post-message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,21 @@ export type ResponsesFromNativeApp = {
};
};
};
DISPLAY_QUALTRICS_INTERCEPT: {
type: 'DISPLAY_QUALTRICS_INTERCEPT';
id: string;
payload: {displayed: true};
};
SET_QUALTRICS_PROPERTIES: {
type: 'SET_QUALTRICS_PROPERTIES';
id: string;
payload: void;
};
IS_QUALTRICS_INTERCEPT_AVAILABLE_FOR_USER: {
type: 'IS_QUALTRICS_INTERCEPT_AVAILABLE_FOR_USER';
id: string;
payload: {isAvailable: boolean};
};
};

export type NativeAppResponsePayload<
Expand Down
40 changes: 40 additions & 0 deletions src/qualtrics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {postMessageToNativeApp} from './post-message';

export const displayQualtricsIntercept = ({
interceptId,
}: {
interceptId: string;
}): Promise<{displayed: true}> =>
postMessageToNativeApp({
type: 'DISPLAY_QUALTRICS_INTERCEPT',
payload: {interceptId},
});

type QualtricsProperty<T> = {
key: string;
value: T;
};

export const setQualtricsProperties = ({
stringProperties,
numberProperties,
dateTimePropertyKeys,
}: {
stringProperties: Array<QualtricsProperty<string>>;
numberProperties: Array<QualtricsProperty<number>>;
dateTimePropertyKeys: Array<string>;
Copy link
Contributor

@dpastor dpastor Dec 12, 2024

Choose a reason for hiding this comment

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

I see we didn't specified that in the spec, but probably is interesting to give these properties a default value (empty array) from js side? WDYT @dhidalgofadrique

Copy link
Contributor Author

Choose a reason for hiding this comment

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

lgtm, done

}): Promise<void> =>
postMessageToNativeApp({
type: 'SET_QUALTRICS_PROPERTIES',
payload: {stringProperties, numberProperties, dateTimePropertyKeys},
});

export const isQualtricsInterceptAvailableForUser = ({
interceptId,
}: {
interceptId: string;
}): Promise<{isAvailable: boolean}> =>
postMessageToNativeApp({
type: 'IS_QUALTRICS_INTERCEPT_AVAILABLE_FOR_USER',
payload: {interceptId},
});
Loading