diff --git a/src/app/features/project/project.component.spec.ts b/src/app/features/project/project.component.spec.ts index 88b558a8c..832d3d66b 100644 --- a/src/app/features/project/project.component.spec.ts +++ b/src/app/features/project/project.component.spec.ts @@ -2,7 +2,7 @@ import { Store } from '@ngxs/store'; import { MockProvider } from 'ng-mocks'; -import { TestBed } from '@angular/core/testing'; +import { fakeAsync, TestBed } from '@angular/core/testing'; import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; import { HelpScoutService } from '@core/services/help-scout.service'; @@ -95,6 +95,7 @@ function setup(overrides: SetupOverrides = {}) { { selector: ContributorsSelectors.getBibliographicContributors, value: [] }, { selector: ContributorsSelectors.isBibliographicContributorsLoading, value: false }, { selector: CurrentResourceSelectors.getCurrentResource, value: null }, + { selector: CurrentResourceSelectors.hasNoPermissions, value: false }, ]; const signals = mergeSignalOverrides(defaultSignals, overrides.selectorOverrides); @@ -227,16 +228,20 @@ describe('Component: Project', () => { expect(metaTagsService.updateMetaTags).not.toHaveBeenCalled(); }); - it('should send analytics on NavigationEnd', () => { - const { routerBuilder, analyticsService } = setup(); - + it('should send analytics on NavigationEnd', fakeAsync(() => { + const mockResource = { id: 'project-1' }; + const { routerBuilder, analyticsService } = setup({ + selectorOverrides: [ + { selector: CurrentResourceSelectors.getCurrentResource, value: mockResource }, + { selector: CurrentResourceSelectors.hasNoPermissions, value: true }, + ], + }); routerBuilder.emit(new NavigationEnd(1, '/project-1', '/project-1/overview')); - expect(analyticsService.sendCountedUsageForRegistrationAndProjects).toHaveBeenCalledWith( '/project-1/overview', - null + mockResource ); - }); + })); it('should call unsetResourceType on destroy', () => { const { component, helpScoutService } = setup(); diff --git a/src/app/features/project/project.component.ts b/src/app/features/project/project.component.ts index bbcec1410..9829312f2 100644 --- a/src/app/features/project/project.component.ts +++ b/src/app/features/project/project.component.ts @@ -52,6 +52,7 @@ export class ProjectComponent implements OnDestroy { private readonly router = inject(Router); private readonly analyticsService = inject(AnalyticsService); + readonly hasNoPermissions = select(CurrentResourceSelectors.hasNoPermissions); readonly currentResource = select(CurrentResourceSelectors.getCurrentResource); readonly currentProject = select(ProjectOverviewSelectors.getProject); readonly isProjectLoading = select(ProjectOverviewSelectors.getProjectLoading); @@ -143,10 +144,12 @@ export class ProjectComponent implements OnDestroy { .subscribe((event: NavigationEnd) => { this.canonicalPath.set(this.getCanonicalPathFromSnapshot()); this.isFileDetailRoute.set(this.isFileDetailRouteFromSnapshot()); - this.analyticsService.sendCountedUsageForRegistrationAndProjects( - event.urlAfterRedirects, - this.currentResource() - ); + if (this.currentResource()?.id && this.hasNoPermissions()) { + this.analyticsService.sendCountedUsageForRegistrationAndProjects( + event.urlAfterRedirects, + this.currentResource() + ); + } }); } diff --git a/src/app/features/registry/registry.component.spec.ts b/src/app/features/registry/registry.component.spec.ts index 2c8ab38a9..2c9f0e3f0 100644 --- a/src/app/features/registry/registry.component.spec.ts +++ b/src/app/features/registry/registry.component.spec.ts @@ -3,7 +3,7 @@ import { Store } from '@ngxs/store'; import { MockProvider } from 'ng-mocks'; import { PLATFORM_ID, Provider } from '@angular/core'; -import { TestBed } from '@angular/core/testing'; +import { fakeAsync, TestBed } from '@angular/core/testing'; import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; import { HelpScoutService } from '@core/services/help-scout.service'; @@ -32,7 +32,7 @@ import { MetaTagsBuilderServiceMockFactory } from '@testing/providers/meta-tags- import { PrerenderReadyServiceMockFactory } from '@testing/providers/prerender-ready.service.mock'; import { ActivatedRouteMockBuilder } from '@testing/providers/route-provider.mock'; import { RouterMockBuilder } from '@testing/providers/router-provider.mock'; -import { provideMockStore } from '@testing/providers/store-provider.mock'; +import { mergeSignalOverrides, provideMockStore, SignalOverride } from '@testing/providers/store-provider.mock'; interface SetupOverrides { registryId?: string; @@ -40,6 +40,7 @@ interface SetupOverrides { identifiers?: IdentifierModel[]; canonicalPath?: string; platform?: string; + selectorOverrides?: SignalOverride[]; } function setup(overrides: SetupOverrides = {}) { @@ -72,6 +73,20 @@ function setup(overrides: SetupOverrides = {}) { }) as MetaTagsData ); + const defaultSignals: SignalOverride[] = [ + { selector: RegistrySelectors.getRegistry, value: registry }, + { selector: RegistrySelectors.isRegistryLoading, value: false }, + { selector: RegistrySelectors.getIdentifiers, value: identifiers }, + { selector: RegistrySelectors.getLicense, value: { name: 'MIT' } }, + { selector: RegistrySelectors.isLicenseLoading, value: false }, + { selector: ContributorsSelectors.getBibliographicContributors, value: [] }, + { selector: ContributorsSelectors.isBibliographicContributorsLoading, value: false }, + { selector: CurrentResourceSelectors.getCurrentResource, value: null }, + { selector: CurrentResourceSelectors.hasNoPermissions, value: false }, + ]; + + const signals = mergeSignalOverrides(defaultSignals, overrides.selectorOverrides); + const providers: Provider[] = [ provideOSFCore(), MockProvider(HelpScoutService, helpScoutService), @@ -82,18 +97,7 @@ function setup(overrides: SetupOverrides = {}) { MockProvider(AnalyticsService, analyticsService), MockProvider(ActivatedRoute, routeBuilder.build()), MockProvider(Router, mockRouter), - provideMockStore({ - signals: [ - { selector: RegistrySelectors.getRegistry, value: registry }, - { selector: RegistrySelectors.isRegistryLoading, value: false }, - { selector: RegistrySelectors.getIdentifiers, value: identifiers }, - { selector: RegistrySelectors.getLicense, value: { name: 'MIT' } }, - { selector: RegistrySelectors.isLicenseLoading, value: false }, - { selector: ContributorsSelectors.getBibliographicContributors, value: [] }, - { selector: ContributorsSelectors.isBibliographicContributorsLoading, value: false }, - { selector: CurrentResourceSelectors.getCurrentResource, value: null }, - ], - }), + provideMockStore({ signals }), ]; if (overrides.platform) { @@ -225,16 +229,20 @@ describe('RegistryComponent', () => { expect(metaTagsService.updateMetaTags).not.toHaveBeenCalled(); }); - it('should send analytics on NavigationEnd event', () => { - const { routerBuilder, analyticsService } = setup(); - + it('should send analytics on NavigationEnd event', fakeAsync(() => { + const mockResource = { id: 'registry-1' }; + const { routerBuilder, analyticsService } = setup({ + selectorOverrides: [ + { selector: CurrentResourceSelectors.getCurrentResource, value: mockResource }, + { selector: CurrentResourceSelectors.hasNoPermissions, value: true }, + ], + }); routerBuilder.emit(new NavigationEnd(1, '/registries/registry-1', '/registries/registry-1')); - expect(analyticsService.sendCountedUsageForRegistrationAndProjects).toHaveBeenCalledWith( '/registries/registry-1', - null + mockResource ); - }); + })); it('should unset helpScout and clear provider on destroy', () => { const { component, store, helpScoutService } = setup(); diff --git a/src/app/features/registry/registry.component.ts b/src/app/features/registry/registry.component.ts index 6b37a90c7..70a7bf693 100644 --- a/src/app/features/registry/registry.component.ts +++ b/src/app/features/registry/registry.component.ts @@ -65,6 +65,7 @@ export class RegistryComponent implements OnDestroy { }); private readonly registryId = toSignal(this.route.params.pipe(map((params) => params['id']))); + readonly hasNoPermissions = select(CurrentResourceSelectors.hasNoPermissions); private readonly currentResource = select(CurrentResourceSelectors.getCurrentResource); private readonly registry = select(RegistrySelectors.getRegistry); private readonly isRegistryLoading = select(RegistrySelectors.isRegistryLoading); @@ -141,10 +142,12 @@ export class RegistryComponent implements OnDestroy { .subscribe((event) => { this.canonicalPath.set(this.getCanonicalPathFromSnapshot()); this.isFileDetailRoute.set(this.isFileDetailRouteFromSnapshot()); - this.analyticsService.sendCountedUsageForRegistrationAndProjects( - event.urlAfterRedirects, - this.currentResource() - ); + if (this.currentResource()?.id && this.hasNoPermissions()) { + this.analyticsService.sendCountedUsageForRegistrationAndProjects( + event.urlAfterRedirects, + this.currentResource() + ); + } }); }