diff --git a/.changeset/analytics-get-along-together.md b/.changeset/analytics-get-along-together.md new file mode 100644 index 0000000000..b6ad9e3019 --- /dev/null +++ b/.changeset/analytics-get-along-together.md @@ -0,0 +1,6 @@ +--- +'@backstage/test-utils': patch +--- + +Added a mock implementation of the `AnalyticsApi`, which can be used to make +assertions about captured analytics events. diff --git a/packages/test-utils/api-report.md b/packages/test-utils/api-report.md index 214c26c825..9c6bc4d999 100644 --- a/packages/test-utils/api-report.md +++ b/packages/test-utils/api-report.md @@ -3,7 +3,11 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { AnalyticsApi } from '@backstage/core-plugin-api'; +import { AnalyticsDomainValue } from '@backstage/core-plugin-api'; +import { AnalyticsTracker } from '@backstage/core-plugin-api'; import { ComponentType } from 'react'; +import { DomainDecoratedAnalyticsEvent } from '@backstage/core-plugin-api'; import { ErrorApi } from '@backstage/core-plugin-api'; import { ErrorContext } from '@backstage/core-plugin-api'; import { ExternalRouteRef } from '@backstage/core-plugin-api'; @@ -15,6 +19,20 @@ import { RouteRef } from '@backstage/core-plugin-api'; import { StorageApi } from '@backstage/core-plugin-api'; import { StorageValueChange } from '@backstage/core-plugin-api'; +// Warning: (ae-missing-release-tag) "MockAnalyticsApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class MockAnalyticsApi implements AnalyticsApi { + // (undocumented) + getDecoratedTracker({ + domain, + }: { + domain: AnalyticsDomainValue; + }): AnalyticsTracker; + // (undocumented) + getEvents(): DomainDecoratedAnalyticsEvent[]; +} + // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // Warning: (ae-missing-release-tag) "mockBreakpoint" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // diff --git a/packages/test-utils/src/testUtils/apis/AnalyticsApi/MockAnalyticsApi.test.ts b/packages/test-utils/src/testUtils/apis/AnalyticsApi/MockAnalyticsApi.test.ts new file mode 100644 index 0000000000..4113940072 --- /dev/null +++ b/packages/test-utils/src/testUtils/apis/AnalyticsApi/MockAnalyticsApi.test.ts @@ -0,0 +1,53 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed 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 CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { MockAnalyticsApi } from './MockAnalyticsApi'; + +describe('MockAnalyticsApi', () => { + const domain = { + pluginId: 'some-plugin', + }; + + it('should collect events', () => { + const api = new MockAnalyticsApi(); + const tracker = api.getDecoratedTracker({ domain }); + + tracker.captureEvent('verb-1', 'noun-1'); + tracker.captureEvent('verb-2', 'noun-2', 42); + tracker.captureEvent('verb-3', 'noun-3', 1337, { some: 'context' }); + + expect(api.getEvents()[0]).toMatchObject({ + noun: 'noun-1', + verb: 'verb-1', + domain, + }); + expect(api.getEvents()[1]).toMatchObject({ + noun: 'noun-2', + verb: 'verb-2', + value: 42, + domain, + }); + expect(api.getEvents()[2]).toMatchObject({ + noun: 'noun-3', + verb: 'verb-3', + value: 1337, + domain, + context: { + some: 'context', + }, + }); + }); +}); diff --git a/packages/test-utils/src/testUtils/apis/AnalyticsApi/MockAnalyticsApi.ts b/packages/test-utils/src/testUtils/apis/AnalyticsApi/MockAnalyticsApi.ts new file mode 100644 index 0000000000..7e8e19d438 --- /dev/null +++ b/packages/test-utils/src/testUtils/apis/AnalyticsApi/MockAnalyticsApi.ts @@ -0,0 +1,48 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed 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 CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + AnalyticsApi, + AnalyticsDomainValue, + AnalyticsTracker, + DomainDecoratedAnalyticsEvent, +} from '@backstage/core-plugin-api'; + +export class MockAnalyticsApi implements AnalyticsApi { + private events: DomainDecoratedAnalyticsEvent[] = []; + + getDecoratedTracker({ + domain, + }: { + domain: AnalyticsDomainValue; + }): AnalyticsTracker { + return { + captureEvent: (verb, noun, value, context) => { + this.events.push({ + verb, + noun, + domain, + ...(value !== undefined ? { value } : {}), + ...(context !== undefined ? { context } : {}), + }); + }, + }; + } + + getEvents(): DomainDecoratedAnalyticsEvent[] { + return this.events; + } +} diff --git a/packages/test-utils/src/testUtils/apis/AnalyticsApi/index.ts b/packages/test-utils/src/testUtils/apis/AnalyticsApi/index.ts new file mode 100644 index 0000000000..dc5fd062aa --- /dev/null +++ b/packages/test-utils/src/testUtils/apis/AnalyticsApi/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed 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 CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { MockAnalyticsApi } from './MockAnalyticsApi'; diff --git a/packages/test-utils/src/testUtils/apis/index.ts b/packages/test-utils/src/testUtils/apis/index.ts index 7bc1f74dcd..44b423a264 100644 --- a/packages/test-utils/src/testUtils/apis/index.ts +++ b/packages/test-utils/src/testUtils/apis/index.ts @@ -14,5 +14,6 @@ * limitations under the License. */ +export * from './AnalyticsApi'; export * from './ErrorApi'; export * from './StorageApi';