Skip to content

Commit

Permalink
fix(insights): show deprecation warnings for old insights related pro…
Browse files Browse the repository at this point in the history
…perties and functions (#4524)

* chore(deprecate): show deprecation warnings for old insights related properties and functions

* Update src/helpers/get-insights-anonymous-user-token.ts

Co-authored-by: François Chalifour <[email protected]>

* update error message

* add more warnings

* add migration guide for analytics widget

Co-authored-by: François Chalifour <[email protected]>
  • Loading branch information
Eunjae Lee and francoischalifour authored Oct 7, 2020
1 parent 71ebada commit c93e1cf
Show file tree
Hide file tree
Showing 12 changed files with 166 additions and 6 deletions.
11 changes: 11 additions & 0 deletions src/helpers/__tests__/get-insights-anonymous-user-token-test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import getInsightsAnonymousUserToken, {
ANONYMOUS_TOKEN_COOKIE_KEY,
} from '../get-insights-anonymous-user-token';
import { warning } from '../../lib/utils';

const DAY = 86400000; /* 1 day in ms*/
const DATE_TOMORROW = new Date(Date.now() + DAY).toUTCString();
Expand Down Expand Up @@ -34,4 +35,14 @@ describe('getInsightsAnonymousUserToken', () => {
document.cookie = `BAD_COOKIE=val%ue;expires=${DATE_TOMORROW};path=/`;
expect(getInsightsAnonymousUserToken()).toBe('anonymous-uuid');
});

it('should show deprecation warning', () => {
warning.cache = {};
expect(() => {
getInsightsAnonymousUserToken();
})
.toWarnDev(`[InstantSearch.js]: \`getInsightsAnonymousUserToken\` function has been deprecated. It is still supported in 4.x releases, but not further. It is replaced by the \`insights\` middleware.
For more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/`);
});
});
16 changes: 16 additions & 0 deletions src/helpers/__tests__/insights-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import insights, {
readDataAttributes,
hasDataAttributes,
} from '../insights';
import { warning } from '../../lib/utils';

const makeDomElement = (html: string): HTMLElement => {
const div = document.createElement('div');
Expand All @@ -21,6 +22,21 @@ describe('insights', () => {
`"data-insights-method=\\"clickedObjectIDsAfterSearch\\" data-insights-payload=\\"eyJvYmplY3RJRHMiOlsiMyJdLCJldmVudE5hbWUiOiJBZGQgdG8gQ2FydCJ9\\""`
);
});

it('shows a deprecation warning', () => {
warning.cache = {};

expect(() => {
insights('clickedObjectIDsAfterSearch', {
objectIDs: ['3'],
eventName: 'Add to Cart',
});
}).toWarnDev(
`[InstantSearch.js]: \`insights\` function has been deprecated. It is still supported in 4.x releases, but not further. It is replaced by the \`insights\` middleware.
For more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/`
);
});
});

describe('writeDataAttributes', () => {
Expand Down
17 changes: 16 additions & 1 deletion src/helpers/get-insights-anonymous-user-token.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { warning } from '../lib/utils';

export const ANONYMOUS_TOKEN_COOKIE_KEY = '_ALGOLIA';

function getCookie(name: string): string | undefined {
Expand All @@ -15,6 +17,19 @@ function getCookie(name: string): string | undefined {
return undefined;
}

export default function getInsightsAnonymousUserToken(): string | undefined {
export function getInsightsAnonymousUserTokenInternal(): string | undefined {
return getCookie(ANONYMOUS_TOKEN_COOKIE_KEY);
}

/**
* @deprecated This function will be still supported in 4.x releases, but not further. It is replaced by the `insights` middleware. For more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/
*/
export default function getInsightsAnonymousUserToken(): string | undefined {
warning(
false,
`\`getInsightsAnonymousUserToken\` function has been deprecated. It is still supported in 4.x releases, but not further. It is replaced by the \`insights\` middleware.
For more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/`
);
return getInsightsAnonymousUserTokenInternal();
}
5 changes: 4 additions & 1 deletion src/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ export * from './snippet';
export { default as highlight } from './highlight';
export { default as snippet } from './snippet';
export { default as insights } from './insights';
export { default as getInsightsAnonymousUserToken } from './get-insights-anonymous-user-token';
export {
default as getInsightsAnonymousUserToken,
getInsightsAnonymousUserTokenInternal,
} from './get-insights-anonymous-user-token';
10 changes: 10 additions & 0 deletions src/helpers/insights.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { InsightsClientMethod, InsightsClientPayload } from '../types';
import { warning } from '../lib/utils';

export function readDataAttributes(
domElement: HTMLElement
Expand Down Expand Up @@ -56,9 +57,18 @@ export function writeDataAttributes({
return `data-insights-method="${method}" data-insights-payload="${serializedPayload}"`;
}

/**
* @deprecated This function will be still supported in 4.x releases, but not further. It is replaced by the `insights` middleware. For more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/
*/
export default function insights(
method: InsightsClientMethod,
payload: Partial<InsightsClientPayload>
): string {
warning(
false,
`\`insights\` function has been deprecated. It is still supported in 4.x releases, but not further. It is replaced by the \`insights\` middleware.
For more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/`
);
return writeDataAttributes({ method, payload });
}
9 changes: 9 additions & 0 deletions src/lib/InstantSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ export type InstantSearchOptions = {
/**
* the instance of search-insights to use for sending insights events inside
* widgets like `hits`.
*
* @deprecated This property will be still supported in 4.x releases, but not further. It is replaced by the `insights` middleware. For more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/
*/
insightsClient?: AlgoliaInsightsClient;
};
Expand Down Expand Up @@ -183,6 +185,13 @@ See: https://www.algolia.com/doc/guides/building-search-ui/going-further/backend
searchClient.addAlgoliaAgent(`instantsearch.js (${version})`);
}

warning(
insightsClient === null,
`\`insightsClient\` property has been deprecated. It is still supported in 4.x releases, but not further. It is replaced by the \`insights\` middleware.
For more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/`
);

warning(
Boolean(insightsClient) || !hasDetectedInsightsClient(),
withUsage(`InstantSearch detected the Insights client in the global scope.
Expand Down
23 changes: 23 additions & 0 deletions src/lib/__tests__/InstantSearch-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ beforeEach(() => {
});

describe('Usage', () => {
beforeEach(() => {
warning.cache = {};
});

it('throws without indexName', () => {
expect(() => {
// eslint-disable-next-line no-new
Expand Down Expand Up @@ -298,6 +302,25 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/instantsear
search.use(middleware);
}).not.toWarnDev();
});

it('warns dev when insightsClient is given', () => {
const searchClient = createSearchClient({
addAlgoliaAgent: jest.fn(),
});

expect(() => {
// eslint-disable-next-line no-new
new InstantSearch({
indexName: 'indexName',
searchClient,
insightsClient: () => {},
});
}).toWarnDev(
`[InstantSearch.js]: \`insightsClient\` property has been deprecated. It is still supported in 4.x releases, but not further. It is replaced by the \`insights\` middleware.
For more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/`
);
});
});

describe('InstantSearch', () => {
Expand Down
38 changes: 38 additions & 0 deletions src/lib/insights/__tests__/client-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import withInsights from '../client';
import { warning } from '../../utils';

describe('withInsights', () => {
it('shows a deprecation warning', () => {
warning.cache = {};

const renderer = ({ insights }) => {
insights('convertedObjectIDsAfterSearch', {
objectIDs: ['1'],
eventName: 'Add to basket',
});
};
const connector = renderFn => () => ({
init() {
renderFn({
results: {},
hits: [
{ objectID: '1', __queryID: 'theQueryID', __position: 9 },
{ objectID: '2', __queryID: 'theQueryID', __position: 10 },
{ objectID: '3', __queryID: 'theQueryID', __position: 11 },
{ objectID: '4', __queryID: 'theQueryID', __position: 12 },
],
instantSearchInstance: { insightsClient: () => {} },
});
},
});
const makeWidget = withInsights(connector)(renderer);
const widget = makeWidget();
expect(() => {
widget.init();
}).toWarnDev(
`[InstantSearch.js]: \`insights\` function has been deprecated. It is still supported in 4.x releases, but not further. It is replaced by the \`insights\` middleware.
For more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/`
);
});
});
17 changes: 16 additions & 1 deletion src/lib/insights/client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { SearchResults } from 'algoliasearch-helper';
import { uniq, find, createDocumentationMessageGenerator } from '../utils';
import {
uniq,
find,
createDocumentationMessageGenerator,
warning,
} from '../utils';
import {
Hits,
InsightsClient,
Expand Down Expand Up @@ -79,6 +84,12 @@ const wrapInsightsClient = (
method: InsightsClientMethod,
payload: Partial<InsightsClientPayload>
) => {
warning(
false,
`\`insights\` function has been deprecated. It is still supported in 4.x releases, but not further. It is replaced by the \`insights\` middleware.
For more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/`
);
if (!aa) {
const withInstantSearchUsage = createDocumentationMessageGenerator({
name: 'instantsearch',
Expand All @@ -101,6 +112,10 @@ const wrapInsightsClient = (
aa(method, { ...inferredPayload, ...payload } as any);
};

/**
* @deprecated This function will be still supported in 4.x releases, but not further. It is replaced by the `insights` middleware. For more information, visit https://www.algolia.com/doc/guides/getting-insights-and-analytics/search-analytics/click-through-and-conversions/how-to/send-click-and-conversion-events-with-instantsearch/js/
* It passes `insights` to `HitsWithInsightsListener` and `InfiniteHitsWithInsightsListener`.
*/
export default function withInsights<TRendererOptions, TConnectorParams>(
connector: Connector<TRendererOptions, TConnectorParams>
): Connector<TRendererOptions, TConnectorParams> {
Expand Down
4 changes: 2 additions & 2 deletions src/middlewares/createInsightsMiddleware.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { InsightsClient, InsightsClientMethod, Middleware } from '../types';
import { getInsightsAnonymousUserToken } from '../helpers';
import { getInsightsAnonymousUserTokenInternal } from '../helpers';
import { warning, noop, getAppIdAndApiKey } from '../lib/utils';

export type InsightsEvent = {
Expand Down Expand Up @@ -79,7 +79,7 @@ aa('setUserToken', 'your-user-token');
if (hasInsightsClient) {
// When `aa('init', { ... })` is called, it creates an anonymous user token in cookie.
// We can set it as userToken.
setUserTokenToSearch(getInsightsAnonymousUserToken());
setUserTokenToSearch(getInsightsAnonymousUserTokenInternal());
}

if (Array.isArray((insightsClient as any).queue)) {
Expand Down
12 changes: 12 additions & 0 deletions src/widgets/analytics/__tests__/analytics-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,16 @@ describe('Usage', () => {
See documentation: https://www.algolia.com/doc/api-reference/widgets/analytics/js/"
`);
});

it('shows deprecation warning message.', () => {
expect(() => {
analytics({
pushFunction: () => {},
});
}).toWarnDev(
`[InstantSearch.js]: \`analytics\` widget has been deprecated. It is still supported in 4.x releases, but not further. It is replaced by the \`insights\` middleware.
For the migration, visit https://www.algolia.com/doc/guides/building-search-ui/upgrade-guides/js/#analytics-widget`
);
});
});
10 changes: 9 additions & 1 deletion src/widgets/analytics/analytics.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SearchParameters, SearchResults } from 'algoliasearch-helper';
import { createDocumentationMessageGenerator } from '../../lib/utils';
import { createDocumentationMessageGenerator, warning } from '../../lib/utils';
import { WidgetFactory } from '../../types';

export type AnalyticsWidgetParamsPushFunction = (
Expand Down Expand Up @@ -63,6 +63,7 @@ const withUsage = createDocumentationMessageGenerator({ name: 'analytics' });

export type AnalyticsWidget = WidgetFactory<{}, AnalyticsWidgetParams>;

// @major this widget will be removed from the next major version.
const analytics: AnalyticsWidget = function analytics(widgetParams) {
const {
pushFunction,
Expand All @@ -76,6 +77,13 @@ const analytics: AnalyticsWidget = function analytics(widgetParams) {
throw new Error(withUsage('The `pushFunction` option is required.'));
}

warning(
false,
`\`analytics\` widget has been deprecated. It is still supported in 4.x releases, but not further. It is replaced by the \`insights\` middleware.
For the migration, visit https://www.algolia.com/doc/guides/building-search-ui/upgrade-guides/js/#analytics-widget`
);

type AnalyticsState = {
results: SearchResults;
state: SearchParameters;
Expand Down

0 comments on commit c93e1cf

Please sign in to comment.