Skip to content

Commit

Permalink
[GSoC'24] M2.3 Add site analytics events, tests (oppia#20742)
Browse files Browse the repository at this point in the history
* Add events in site analytics

* fix coverage

* Add tests

* address comments 1

* Address comments 2

* fix backend tests

* updates

* Address comments 3

* Fix errors coming from merging develop
  • Loading branch information
AkashPaloju authored Aug 9, 2024
1 parent b65c974 commit a32bfc3
Show file tree
Hide file tree
Showing 38 changed files with 929 additions and 52 deletions.
1 change: 0 additions & 1 deletion assets/i18n/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,6 @@
"I18N_FOOTER_NEWSLETTER_TEXT": "كن جزء من مجتمع Oppia! نشرتنا الإخبارية نصف الأسبوعية تبقيك على اطلاع بالميزات الجديدة، والدروس، والتأثير الذي تحدثه Oppia في أنحاء العالم.",
"I18N_FOOTER_OPPIA_FOUNDATION": "مؤسسة أوبيا",
"I18N_FOOTER_OPPIA_MISSION": "تتمثل مهمة Oppia في توفير منصة تعليمية تلبي الاحتياجات الخاصة للمجتمعات ذات الموارد المحدودة.",
"I18N_FOOTER_OPPIA_MISSION_DONATE_VOLUNTEER": "<a href=\"/donate\">تبرع</a> أو <a href=\"/volunteer\">تطوع</a> اليوم!",
"I18N_FOOTER_PRIVACY_POLICY": "سياسة الخصوصية",
"I18N_FOOTER_TEACH": "التعليم مع أوبيا",
"I18N_FOOTER_TEACH_LEARN_ALL_CAPS": "تعليم/تعلم",
Expand Down
1 change: 0 additions & 1 deletion assets/i18n/br.json
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@
"I18N_FOOTER_NEWSLETTER_EMAIL": "Chomlec'h postel",
"I18N_FOOTER_NEWSLETTER_HEADING": "Koumanantiñ d'hol lizher-keloaouiñ",
"I18N_FOOTER_OPPIA_FOUNDATION": "An diazezadur Oppia",
"I18N_FOOTER_OPPIA_MISSION_DONATE_VOLUNTEER": "<a href=\"/donate\">Grit un donezon</a> pe deuit da vezañ un <a href=\"/volunteer\">den a-youl-vat</a> hiziv!",
"I18N_FOOTER_PRIVACY_POLICY": "Reolennoù prevezded",
"I18N_FOOTER_TEACH": "Kelenn gant Oppia",
"I18N_FOOTER_TEACH_LEARN_ALL_CAPS": "KELENN/DESKIÑ",
Expand Down
1 change: 0 additions & 1 deletion assets/i18n/el.json
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,6 @@
"I18N_FOOTER_NEWSLETTER_TEXT": "Γίνετε μέλος της κοινότητας της Oppia! Το newsletter μας κάθε δύο εβδομάδες, σας κρατά ενήμερους για τις καινούργιες δυνατότητες, μαθήματα και πώς η Oppia έχει παγκόσμια απήχηση.",
"I18N_FOOTER_OPPIA_FOUNDATION": "Το ίδρυμα Oppia",
"I18N_FOOTER_OPPIA_MISSION": "Ο στόχος της Oppia είναι να προσφέρει μια πλατφόρμα μάθησης που ανταποκρίνεται στις μοναδικές ανάγκες για κοινότητες με περιορισμένους πόρους.",
"I18N_FOOTER_OPPIA_MISSION_DONATE_VOLUNTEER": "<a href=\"/donate\">Κάντε μία δωρεά</a> ή <a href=\"/volunteer\">γίνετε εθελοντής</a> σήμερα!",
"I18N_FOOTER_PRIVACY_POLICY": "Πολιτική Ιδιωτικότητας",
"I18N_FOOTER_TEACH": "Διδάξτε με την Oppia",
"I18N_FOOTER_TEACH_LEARN_ALL_CAPS": "Διδάξτε/μάθετε",
Expand Down
2 changes: 1 addition & 1 deletion assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@
"I18N_FOOTER_NEWSLETTER_TEXT": "Be a part of the Oppia community! Our bi-weekly newsletter keeps you informed on new features, lessons and how Oppia is making a worldwide impact.",
"I18N_FOOTER_OPPIA_FOUNDATION": "The Oppia Foundation",
"I18N_FOOTER_OPPIA_MISSION": "Oppia’s mission is to provide a learning platform that meets the unique needs for under resourced communities.",
"I18N_FOOTER_OPPIA_MISSION_DONATE_VOLUNTEER": "<a href=\"/donate\">Donate</a> or <a href=\"/volunteer\">volunteer</a> today!",
"I18N_FOOTER_OPPIA_MISSION_DONATE_VOLUNTEER": "<a href=\"/donate\">Donate</a> or <a href=\"/volunteer\" (click)=\"navigateToVolunteerPage()\">volunteer</a> today!",
"I18N_FOOTER_PRIVACY_POLICY": "Privacy Policy",
"I18N_FOOTER_TEACH": "Teach with Oppia",
"I18N_FOOTER_TEACH_LEARN_ALL_CAPS": "TEACH/LEARN",
Expand Down
1 change: 0 additions & 1 deletion assets/i18n/fi.json
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,6 @@
"I18N_FOOTER_NEWSLETTER_HEADING": "Tilaa uutiskirjeemme",
"I18N_FOOTER_NEWSLETTER_TEXT": "Ole osa Oppia-yhteisöä! Joka toinen viikko ilmestyvä uutiskirjeemme pitää sinut ajan tasalla uusista ominaisuuksista, oppitunneista ja siitä, kuinka Oppia vaikuttaa maailmanlaajuisesti.",
"I18N_FOOTER_OPPIA_FOUNDATION": "Oppia Foundation",
"I18N_FOOTER_OPPIA_MISSION_DONATE_VOLUNTEER": "<a href=\"/donate\">Lahjoita</a> tai <a href=\"/volunteer\">ryhdy vapaaehtoiseksi</a> tänään!",
"I18N_FOOTER_PRIVACY_POLICY": "Tietosuojakäytäntö",
"I18N_FOOTER_TEACH": "Teach with Oppia",
"I18N_FOOTER_TEACH_LEARN_ALL_CAPS": "OPETA/OPI",
Expand Down
1 change: 0 additions & 1 deletion assets/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,6 @@
"I18N_FOOTER_NEWSLETTER_TEXT": "Faites partie de la communauté Oppia ! Notre lettre d'information bihebdomadaire vous tient informé des nouvelles fonctionnalités, des leçons et de la manière dont Oppia a un impact mondial.",
"I18N_FOOTER_OPPIA_FOUNDATION": "La Fondation Oppia",
"I18N_FOOTER_OPPIA_MISSION": "La mission d'Oppia est de fournir une plateforme d'apprentissage qui répond aux besoins uniques des communautés sous-financées.",
"I18N_FOOTER_OPPIA_MISSION_DONATE_VOLUNTEER": "<a href=\"/donate\">Faites un don</a> ou <a href=\"/volunteer\">faites du bénévolat</a> dès aujourd'hui !",
"I18N_FOOTER_PRIVACY_POLICY": "Politique de confidentialité",
"I18N_FOOTER_TEACH": "Enseigner avec Oppia",
"I18N_FOOTER_TEACH_LEARN_ALL_CAPS": "ENSEIGNER / APPRENDRE",
Expand Down
1 change: 0 additions & 1 deletion assets/i18n/pt-br.json
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,6 @@
"I18N_FOOTER_NEWSLETTER_TEXT": "Faça parte da comunidade Oppia!! Nosso informativo quinzenal te mantém informado sobre nossos recursos, lições e como a Oppia impacta o mundo positivamente.",
"I18N_FOOTER_OPPIA_FOUNDATION": "A Fundação Oppia",
"I18N_FOOTER_OPPIA_MISSION": "A missão da Oppia é proporcionar uma plataforma de aprendizado que atenda às necessidades específicas das comunidades com poucos recursos.",
"I18N_FOOTER_OPPIA_MISSION_DONATE_VOLUNTEER": "<a href=\"/donate\"> Doe </a> ou <a href=\"/volunteer\">seja voluntário (a)</a> hoje!",
"I18N_FOOTER_PRIVACY_POLICY": "Política de Privacidade",
"I18N_FOOTER_TEACH": "Ensine com Oppia",
"I18N_FOOTER_TEACH_LEARN_ALL_CAPS": "ENSINAR/APRENDER",
Expand Down
1 change: 0 additions & 1 deletion assets/i18n/zh-hant.json
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,6 @@
"I18N_FOOTER_NEWSLETTER_TEXT": "歡迎成為 Oppia 社群的一員!我們每兩週一次的電子報能讓您知悉新功能、課程內容,以及 Oppia 如何在全世界產生影響。",
"I18N_FOOTER_OPPIA_FOUNDATION": "Oppia 基金會",
"I18N_FOOTER_OPPIA_MISSION": "Oppia 的使命是提供一個學習平台,以滿足缺乏教育資源社區的特別需求。",
"I18N_FOOTER_OPPIA_MISSION_DONATE_VOLUNTEER": "今天就<a href=\"/donate\">捐款</a>或成為<a href=\"/volunteer\">志工</a>!",
"I18N_FOOTER_PRIVACY_POLICY": "隱私權政策",
"I18N_FOOTER_TEACH": "以 Oppia 教學",
"I18N_FOOTER_TEACH_LEARN_ALL_CAPS": "教學/學習",
Expand Down
13 changes: 13 additions & 0 deletions core/templates/app.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,4 +410,17 @@ export const AppConstants = {
},
],
},
LAST_PAGE_VIEW_TIME_LOCAL_STORAGE_KEYS_FOR_GA: {
ABOUT: 'lastAboutPageViewTime',
TEACH: 'lastTeachPageViewTime',
VOLUNTEER: 'lastVolunteerPageViewTime',
},
ONE_WEEK_IN_MILLIS: 7 * 24 * 60 * 60 * 1000,
ONE_MONTH_IN_MILLIS: 30 * 24 * 60 * 60 * 1000,
} as const;

export enum NavbarAndFooterGATrackingPages {
ABOUT = 'About',
VOLUNTEER = 'Volunteer',
TEACH = 'Teach',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright 2024 The Oppia Authors. All Rights Reserved.
//
// 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.

/**
* @fileoverview Unit tests for thanks for subscribing modal component.
*/

import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import {MockTranslatePipe} from 'tests/unit-test-utils';
import {FooterDonateVolunteerComponent} from './footer-donate-volunteer.component';
import {SiteAnalyticsService} from 'services/site-analytics.service';
import {WindowRef} from 'services/contextual/window-ref.service';
import {NavbarAndFooterGATrackingPages} from 'app.constants';

class MockWindowRef {
nativeWindow = {
location: {
pathname: '/learn/math',
href: '',
},
gtag: () => {},
};
}

describe('Thanks for subscribing modal component', function () {
let component: FooterDonateVolunteerComponent;
let fixture: ComponentFixture<FooterDonateVolunteerComponent>;
let siteAnalyticsService: SiteAnalyticsService;
let mockWindowRef: MockWindowRef;

beforeEach(waitForAsync(() => {
mockWindowRef = new MockWindowRef();
TestBed.configureTestingModule({
declarations: [MockTranslatePipe, FooterDonateVolunteerComponent],
providers: [
{
provide: WindowRef,
useValue: mockWindowRef,
},
],
}).compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(FooterDonateVolunteerComponent);
component = fixture.componentInstance;
siteAnalyticsService = TestBed.inject(SiteAnalyticsService);
});

it('should register Volunteer footer link click event', () => {
spyOn(siteAnalyticsService, 'registerClickFooterButtonEvent');
expect(mockWindowRef.nativeWindow.location.href).toBe('');

component.navigateToVolunteerPage();

expect(
siteAnalyticsService.registerClickFooterButtonEvent
).toHaveBeenCalledWith(NavbarAndFooterGATrackingPages.VOLUNTEER);

expect(mockWindowRef.nativeWindow.location.href).toBe('/volunteer');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,27 @@

import {Component, ViewEncapsulation} from '@angular/core';
import {downgradeComponent} from '@angular/upgrade/static';
import {WindowRef} from 'services/contextual/window-ref.service';
import {SiteAnalyticsService} from 'services/site-analytics.service';
import {NavbarAndFooterGATrackingPages} from 'app.constants';

@Component({
selector: 'oppia-footer-donate-volunteer',
templateUrl: './footer-donate-volunteer.component.html',
encapsulation: ViewEncapsulation.None,
})
export class FooterDonateVolunteerComponent {
constructor() {}
constructor(
private windowRef: WindowRef,
private siteAnalyticsService: SiteAnalyticsService
) {}

navigateToVolunteerPage(): void {
this.siteAnalyticsService.registerClickFooterButtonEvent(
NavbarAndFooterGATrackingPages.VOLUNTEER
);
this.windowRef.nativeWindow.location.href = '/volunteer';
}
}

angular.module('oppia').directive(
Expand Down
4 changes: 2 additions & 2 deletions core/templates/base-components/oppia-footer.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ <h2>{{ 'I18N_FOOTER_NEWSLETTER_HEADING' | translate }}</h2>
<p>{{ 'I18N_FOOTER_ABOUT_ALL_CAPS' | translate }}</p>
<ul>
<li>
<a href="/about"
<a (click)="navigateToAboutPage()"
class="e2e-test-footer-about-link"
[smartRouterLink]="'/' + PAGES_REGISTERED_WITH_FRONTEND.ABOUT.ROUTE">
{{ 'I18N_FOOTER_ABOUT' | translate }}
Expand Down Expand Up @@ -73,7 +73,7 @@ <h2>{{ 'I18N_FOOTER_NEWSLETTER_HEADING' | translate }}</h2>
</a>
</li>
<li>
<a href="/teach"
<a (click)="navigateToTeachPage()"
class="e2e-test-teach-link"
[smartRouterLink]="'/' + PAGES_REGISTERED_WITH_FRONTEND.TEACH.ROUTE">
{{ 'I18N_FOOTER_TEACH_PAGE' | translate }}
Expand Down
47 changes: 47 additions & 0 deletions core/templates/base-components/oppia-footer.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,24 @@ import {
import {Router} from '@angular/router';

import {AppConstants} from 'app.constants';
import {NavbarAndFooterGATrackingPages} from 'app.constants';
import {MockTranslatePipe} from 'tests/unit-test-utils';
import {MailingListBackendApiService} from 'domain/mailing-list/mailing-list-backend-api.service';
import {AlertsService} from 'services/alerts.service';
import {HttpClientTestingModule} from '@angular/common/http/testing';
import {OppiaFooterComponent} from './oppia-footer.component';
import {SiteAnalyticsService} from 'services/site-analytics.service';
import {WindowRef} from 'services/contextual/window-ref.service';

class MockWindowRef {
nativeWindow = {
location: {
pathname: '/learn/math',
href: '',
},
gtag: () => {},
};
}

class MockRouter {
url = '/about';
Expand All @@ -43,8 +56,11 @@ describe('OppiaFooterComponent', () => {
let fixture: ComponentFixture<OppiaFooterComponent>;
let mailingListBackendApiService: MailingListBackendApiService;
let alertsService: AlertsService;
let siteAnalyticsService: SiteAnalyticsService;
let mockWindowRef: MockWindowRef;

beforeEach(waitForAsync(() => {
mockWindowRef = new MockWindowRef();
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
declarations: [OppiaFooterComponent, MockTranslatePipe],
Expand All @@ -53,6 +69,10 @@ describe('OppiaFooterComponent', () => {
provide: Router,
useClass: MockRouter,
},
{
provide: WindowRef,
useValue: mockWindowRef,
},
],
schemas: [NO_ERRORS_SCHEMA],
}).compileComponents();
Expand All @@ -63,6 +83,7 @@ describe('OppiaFooterComponent', () => {
alertsService = TestBed.inject(AlertsService);
mailingListBackendApiService = TestBed.inject(MailingListBackendApiService);
component = fixture.componentInstance;
siteAnalyticsService = TestBed.inject(SiteAnalyticsService);
});

it('should get the siteFeedbackFormURL', () => {
Expand Down Expand Up @@ -145,4 +166,30 @@ describe('OppiaFooterComponent', () => {
10000
);
}));

it('should register About footer link click event', () => {
spyOn(siteAnalyticsService, 'registerClickFooterButtonEvent');
expect(mockWindowRef.nativeWindow.location.href).toBe('');

component.navigateToAboutPage();

expect(
siteAnalyticsService.registerClickFooterButtonEvent
).toHaveBeenCalledWith(NavbarAndFooterGATrackingPages.ABOUT);

expect(mockWindowRef.nativeWindow.location.href).toBe('/about');
});

it('should register Teach footer link click event', () => {
spyOn(siteAnalyticsService, 'registerClickFooterButtonEvent');
expect(mockWindowRef.nativeWindow.location.href).toBe('');

component.navigateToTeachPage();

expect(
siteAnalyticsService.registerClickFooterButtonEvent
).toHaveBeenCalledWith(NavbarAndFooterGATrackingPages.TEACH);

expect(mockWindowRef.nativeWindow.location.href).toBe('/teach');
});
});
21 changes: 20 additions & 1 deletion core/templates/base-components/oppia-footer.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ import {PlatformFeatureService} from 'services/platform-feature.service';

import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
import {AppConstants} from 'app.constants';
import {NavbarAndFooterGATrackingPages} from 'app.constants';
import {AlertsService} from 'services/alerts.service';
import {ThanksForSubscribingModalComponent} from './thanks-for-subscribing-modal.component';
import {MailingListBackendApiService} from 'domain/mailing-list/mailing-list-backend-api.service';
import {WindowRef} from 'services/contextual/window-ref.service';
import {SiteAnalyticsService} from 'services/site-analytics.service';

import './oppia-footer.component.css';

Expand Down Expand Up @@ -53,7 +56,9 @@ export class OppiaFooterComponent {
private ngbModal: NgbModal,
private mailingListBackendApiService: MailingListBackendApiService,
private platformFeatureService: PlatformFeatureService,
private router: Router
private router: Router,
private windowRef: WindowRef,
private siteAnalyticsService: SiteAnalyticsService
) {}

getOppiaBlogUrl(): string {
Expand Down Expand Up @@ -95,6 +100,20 @@ export class OppiaFooterComponent {
);
});
}

navigateToAboutPage(): void {
this.siteAnalyticsService.registerClickFooterButtonEvent(
NavbarAndFooterGATrackingPages.ABOUT
);
this.windowRef.nativeWindow.location.href = '/about';
}

navigateToTeachPage(): void {
this.siteAnalyticsService.registerClickFooterButtonEvent(
NavbarAndFooterGATrackingPages.TEACH
);
this.windowRef.nativeWindow.location.href = '/teach';
}
}

angular.module('oppia').directive(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@
</a>
</div>
<div class="oppia-sidebar-submenu-upperborder">
<a tabindex="-1" href="/volunteer" smartRouterLink="/volunteer" class="e2e-mobile-test-sidebar-get-involved-menu-volunteer-button">
<a tabindex="-1" (click)="navigateToVolunteerPage()" smartRouterLink="/volunteer" class="e2e-mobile-test-sidebar-get-involved-menu-volunteer-button">
<i class="fas fa-user-friends oppia-sidebar-submenu-icon volunteer-icon"></i>
<span class="oppia-sidebar-submenu-title">{{ 'I18N_SIDEBAR_VOLUNTEER' | translate }}</span>
<p class="oppia-sidebar-submenu-text">{{ 'I18N_SIDEBAR_VOLUNTEER_DESCRIPTION' | translate }}</p>
Expand Down Expand Up @@ -301,12 +301,12 @@
</div>
<div [hidden]="!aboutSubmenuIsShown">
<div class="oppia-sidebar-submenu-upperborder">
<a tabindex="-1" href="/about" [smartRouterLink]="'/' + PAGES_REGISTERED_WITH_FRONTEND.ABOUT.ROUTE" class="oppia-sidebar-menu-link e2e-mobile-test-sidebar-about-button">
<a tabindex="-1" (click)="navigateToAboutPage()" [smartRouterLink]="'/' + PAGES_REGISTERED_WITH_FRONTEND.ABOUT.ROUTE" class="oppia-sidebar-menu-link e2e-mobile-test-sidebar-about-button">
<span class="oppia-sidebar-submenu-title">{{ 'I18N_SIDEBAR_ABOUT_LINK' | translate }}</span>
</a>
</div>
<div class="oppia-sidebar-submenu-upperborder">
<a tabindex="-1" href="/teach" [smartRouterLink]="'/' + PAGES_REGISTERED_WITH_FRONTEND.TEACH.ROUTE" class="oppia-sidebar-menu-link e2e-mobile-test-sidebar-teach-button">
<a tabindex="-1" (click)="navigateToTeachPage()" [smartRouterLink]="'/' + PAGES_REGISTERED_WITH_FRONTEND.TEACH.ROUTE" class="oppia-sidebar-menu-link e2e-mobile-test-sidebar-teach-button">
<span class="oppia-sidebar-submenu-title">{{ 'I18N_SIDEBAR_TEACH' | translate }}</span>
</a>
</div>
Expand Down
Loading

0 comments on commit a32bfc3

Please sign in to comment.