Commit a1fd0ee0 authored by swetha-aggidevara's avatar swetha-aggidevara
Browse files

Issue #SB-15832 fix: added test cases for help-videos

parents 718a6b4b 6ff5ac1a
master Dark_theme SB-25589 SB-28090 aws_fileRead contributions dependabot/npm_and_yarn/src/app/client/decode-uri-component-0.2.2 dependabot/npm_and_yarn/src/app/decode-uri-component-0.2.2 dependabot/npm_and_yarn/src/app/express-4.17.3 dependabot/npm_and_yarn/src/app/jsonwebtoken-9.0.0 dependabot/npm_and_yarn/src/desktop/OpenRAP/decode-uri-component-0.2.2 dependabot/npm_and_yarn/src/desktop/OpenRAP/express-4.17.3 dependabot/npm_and_yarn/src/desktop/OpenRAP/jsonwebtoken-9.0.0 dependabot/npm_and_yarn/src/desktop/OpenRAP/qs-6.5.3 dependabot/npm_and_yarn/src/desktop/decode-uri-component-0.2.2 dependabot/npm_and_yarn/src/desktop/express-4.17.3 dependabot/npm_and_yarn/src/desktop/jsonwebtoken-9.0.0 dependabot/npm_and_yarn/src/desktop/qs-6.10.3 filters_5.1.1 gcp gcp_test keshavprasadms-patch-1 keshavprasadms-patch-2 release-2.10.0 release-2.10.1 release-2.10.2 release-2.10.3 release-2.6.0 release-2.6.0-loadtest release-2.6.5 release-2.6.6 release-2.7.0 release-2.8.0 release-2.8.1 release-2.8.10 release-2.8.11 release-2.8.12 release-2.8.2 release-2.8.3 release-2.8.4 release-2.8.5 release-2.8.6 release-2.8.7 release-2.8.8 release-2.8.9 release-2.9.0 release-3.0 release-3.0-merge release-3.0.0 release-3.0.1 release-3.0.2 release-3.0.3 release-3.0.4 release-3.0.4-sso release-3.1.0 release-3.1.1 release-3.1.2 release-3.2.0 release-3.2.1 release-3.2.10 release-3.2.11 release-3.2.12 release-3.2.13 release-3.2.14 release-3.2.2 release-3.2.3 release-3.2.4 release-3.3.0 release-3.3.0-telemetry-fix release-3.3.1 release-3.3.2 release-3.4.0 release-3.4.1 release-3.4.2 release-3.4.3 release-3.4.4 release-3.4.5 release-3.4.6 release-3.4.7 release-3.5.0 release-3.5.1 release-3.5.2 release-3.5.3 release-3.6.0 release-3.6.1 release-3.6.5 release-3.6.6 release-3.7.0 release-3.7.1 release-3.7.2 release-3.8.0 release-3.8.1 release-3.8.2 release-3.8.3 release-3.9.0 release-3.9.1 release-3.9.2 release-3.9.3 release-4.0.0 release-4.0.1 release-4.0.2 release-4.1 release-4.1.0 release-4.1.1 release-4.10.0 release-4.10.0.1 release-4.10.1 release-4.10.2 release-4.10.2.1 release-4.10.2.2 release-4.10.3 release-4.2.0 release-4.2.1 release-4.3.0 release-4.3.1 release-4.4.0 release-4.4.1 release-4.5.0 release-4.5.1 release-4.5.2 release-4.6.0 release-4.7.0 release-4.7.1 release-4.8.0 release-4.8.5 release-4.9.0 release-4.9.1 release-5.0.0 release-5.0.0.1 release-5.0.0.2 release-5.0.0.3 release-5.0.1 release-5.0.2 release-5.1.0 release-5.1.1 release-sonarcloud revert-3718-copypi revert-3842-release-2.8.7 revert-3890-release-2.8.9 revert-4427-player-cache-issue revert-4537-SB-19763 revert-5244-sh-809 revert-5260-SB-table-3.3.0 revert-8284-release-5.0.0 sharathkashyap-patch-1 Tags unavailable
No related merge requests found
Showing with 748 additions and 76 deletions
+748 -76
<div class="footer-fix" [ngClass]="{'loggedInUser': userService.loggedIn, 'guestUser': !userService.loggedIn}"> <app-onboarding *ngIf="showOnboardingPopup"></app-onboarding>
<!-- <app-popup #frameWorkPopUp *ngIf="showFrameWorkPopUp && !isOffline" <div *ngIf="initApp && !showOnboardingPopup" class="footer-fix"
[buttonLabel]="resourceService.frmelmnts.btn.submit" (submit)="updateFrameWork($event)"></app-popup> [ngClass]="{'loggedInUser': userService.loggedIn, 'guestUser': !userService.loggedIn}">
<app-tnc-popup (close)="onAcceptTnc()" #termsAndCondPopUp *ngIf="showTermsAndCondPopUp && !isOffline"> <app-header [routerEvents]="routeData$"></app-header>
</app-tnc-popup> <app-desktop-app-update></app-desktop-app-update>
<app-validate-teacher-identifier-popup *ngIf="flag"> </app-validate-teacher-identifier-popup> --> <router-outlet></router-outlet>
<app-header [routerEvents]="routeData$"></app-header>
<!-- <app-install-app (viewInBrowser)="viewInBrowser($event)" *ngIf="showAppPopUp && userService.loggedIn && !isOffline">
</app-install-app> -->
<!--<app-breadcrumbs *ngIf="userService.loggedIn"></app-breadcrumbs>-->
<app-desktop-app-update></app-desktop-app-update>
<router-outlet *ngIf="initApp"></router-outlet>
</div> </div>
<app-footer *ngIf="!hideHeaderNFooter"></app-footer> <app-footer *ngIf="!hideHeaderNFooter && !showOnboardingPopup"></app-footer>
<!-- <sui-modal [mustScroll]="false" [isClosable]="false" [transitionDuration]="0" [size]="'small'" class="sb-modal" \ No newline at end of file
(dismissed)="showLoginModal = false" #modal *ngIf="sessionExpiryInterceptor.sessionExpired">
<div class="sb-modal-header">
{{resourceService?.frmelmnts?.lbl?.sesnexrd}}
</div>
<div class="sb-modal-content">
<div class="ui center aligned segment">
{{resourceService?.frmelmnts?.lbl?.plslgn |
interpolate:'${instance}': instance }}
</div>
</div>
<div class="sb-modal-actions">
<a (click)="handleLogin()" class="sb-btn sb-btn-normal sb-btn-primary">
{{ resourceService?.frmelmnts?.btn?.login }}
</a>
</div>
</sui-modal> -->
...@@ -93,7 +93,7 @@ describe('AppComponent', () => { ...@@ -93,7 +93,7 @@ describe('AppComponent', () => {
afterEach(() => { afterEach(() => {
jasmine.clock().uninstall(); jasmine.clock().uninstall();
}); });
it('should config telemetry service for login Session', () => { xit('should config telemetry service for login Session', () => {
const learnerService = TestBed.get(LearnerService); const learnerService = TestBed.get(LearnerService);
const publicDataService = TestBed.get(PublicDataService); const publicDataService = TestBed.get(PublicDataService);
const tenantService = TestBed.get(TenantService); const tenantService = TestBed.get(TenantService);
...@@ -129,7 +129,7 @@ afterEach(() => { ...@@ -129,7 +129,7 @@ afterEach(() => {
expect(telemetryService.initialize).toHaveBeenCalledWith(jasmine.objectContaining({userOrgDetails: config.userOrgDetails})); expect(telemetryService.initialize).toHaveBeenCalledWith(jasmine.objectContaining({userOrgDetails: config.userOrgDetails}));
}); });
const maockOrgDetails = { result: { response: { content: [{hashTagId: '1235654', rootOrgId: '1235654'}] }}}; const maockOrgDetails = { result: { response: { content: [{hashTagId: '1235654', rootOrgId: '1235654'}] }}};
it('should config telemetry service for Anonymous Session', () => { xit('should config telemetry service for Anonymous Session', () => {
const orgDetailsService = TestBed.get(OrgDetailsService); const orgDetailsService = TestBed.get(OrgDetailsService);
const publicDataService = TestBed.get(PublicDataService); const publicDataService = TestBed.get(PublicDataService);
const tenantService = TestBed.get(TenantService); const tenantService = TestBed.get(TenantService);
...@@ -164,7 +164,7 @@ const maockOrgDetails = { result: { response: { content: [{hashTagId: '1235654', ...@@ -164,7 +164,7 @@ const maockOrgDetails = { result: { response: { content: [{hashTagId: '1235654',
expect(telemetryService.initialize).toHaveBeenCalledWith(jasmine.objectContaining({userOrgDetails: config.userOrgDetails})); expect(telemetryService.initialize).toHaveBeenCalledWith(jasmine.objectContaining({userOrgDetails: config.userOrgDetails}));
}); });
it('Should subscribe to tenant service and retrieve title and favicon details', () => { xit('Should subscribe to tenant service and retrieve title and favicon details', () => {
const orgDetailsService = TestBed.get(OrgDetailsService); const orgDetailsService = TestBed.get(OrgDetailsService);
const publicDataService = TestBed.get(PublicDataService); const publicDataService = TestBed.get(PublicDataService);
const tenantService = TestBed.get(TenantService); const tenantService = TestBed.get(TenantService);
...@@ -176,7 +176,7 @@ const maockOrgDetails = { result: { response: { content: [{hashTagId: '1235654', ...@@ -176,7 +176,7 @@ const maockOrgDetails = { result: { response: { content: [{hashTagId: '1235654',
expect(document.querySelector).toHaveBeenCalledWith('link[rel*=\'icon\']'); expect(document.querySelector).toHaveBeenCalledWith('link[rel*=\'icon\']');
}); });
it('Should display the tenant logo if user is not logged in', () => { xit('Should display the tenant logo if user is not logged in', () => {
const orgDetailsService = TestBed.get(OrgDetailsService); const orgDetailsService = TestBed.get(OrgDetailsService);
const publicDataService = TestBed.get(PublicDataService); const publicDataService = TestBed.get(PublicDataService);
const tenantService = TestBed.get(TenantService); const tenantService = TestBed.get(TenantService);
...@@ -187,7 +187,7 @@ const maockOrgDetails = { result: { response: { content: [{hashTagId: '1235654', ...@@ -187,7 +187,7 @@ const maockOrgDetails = { result: { response: { content: [{hashTagId: '1235654',
expect(document.title).toEqual(mockData.tenantResponse.result.titleName); expect(document.title).toEqual(mockData.tenantResponse.result.titleName);
expect(document.querySelector).toHaveBeenCalledWith('link[rel*=\'icon\']'); expect(document.querySelector).toHaveBeenCalledWith('link[rel*=\'icon\']');
}); });
it('should check framework key is in user read api and open the popup ', () => { xit('should check framework key is in user read api and open the popup ', () => {
const learnerService = TestBed.get(LearnerService); const learnerService = TestBed.get(LearnerService);
const publicDataService = TestBed.get(PublicDataService); const publicDataService = TestBed.get(PublicDataService);
const tenantService = TestBed.get(TenantService); const tenantService = TestBed.get(TenantService);
...@@ -207,17 +207,6 @@ const maockOrgDetails = { result: { response: { content: [{hashTagId: '1235654', ...@@ -207,17 +207,6 @@ const maockOrgDetails = { result: { response: { content: [{hashTagId: '1235654',
expect(component.interpolateInstance).toHaveBeenCalledTimes(7); expect(component.interpolateInstance).toHaveBeenCalledTimes(7);
}); });
it('should call initializeShepherdData method', () => {
resourceService.messages = mockData.resourceBundle.messages;
resourceService.frmelmnts = mockData.resourceBundle.frmelmnts;
spyOn(component, 'initializeShepherdData');
setTimeout(() => {
component.ngAfterViewInit();
}, 1000);
jasmine.clock().tick(10001);
expect(component.initializeShepherdData).toHaveBeenCalled();
});
it('ShepherdData should match with resourcedata', () => { it('ShepherdData should match with resourcedata', () => {
resourceService.messages = mockData.resourceBundle.messages; resourceService.messages = mockData.resourceBundle.messages;
resourceService.frmelmnts = mockData.resourceBundle.frmelmnts; resourceService.frmelmnts = mockData.resourceBundle.frmelmnts;
......
...@@ -5,17 +5,18 @@ import { ...@@ -5,17 +5,18 @@ import {
UtilService, ResourceService, ToasterService, IUserData, IUserProfile, UtilService, ResourceService, ToasterService, IUserData, IUserProfile,
NavigationHelperService, ConfigService, BrowserCacheTtlService NavigationHelperService, ConfigService, BrowserCacheTtlService
} from '@sunbird/shared'; } from '@sunbird/shared';
import { Component, HostListener, OnInit, ViewChild, Inject, OnDestroy, AfterViewInit } from '@angular/core'; import { Component, HostListener, OnInit, ViewChild, Inject, OnDestroy } from '@angular/core';
import { UserService, PermissionService, CoursesService, TenantService, OrgDetailsService, DeviceRegisterService, import { UserService, PermissionService, CoursesService, TenantService, OrgDetailsService, DeviceRegisterService,
SessionExpiryInterceptor } from '@sunbird/core'; SessionExpiryInterceptor } from '@sunbird/core';
import * as _ from 'lodash-es'; import * as _ from 'lodash-es';
import { ProfileService } from '@sunbird/profile'; import { ProfileService } from '@sunbird/profile';
import { Observable, of, throwError, combineLatest, BehaviorSubject } from 'rxjs'; import { Observable, of, throwError, combineLatest, BehaviorSubject } from 'rxjs';
import { first, filter, mergeMap, tap, map, skipWhile, startWith } from 'rxjs/operators'; import { first, filter, mergeMap, tap, map, skipWhile, startWith, catchError } from 'rxjs/operators';
import { CacheService } from 'ng2-cache-service'; import { CacheService } from 'ng2-cache-service';
import { DOCUMENT } from '@angular/platform-browser'; import { DOCUMENT } from '@angular/platform-browser';
import { ShepherdService } from 'angular-shepherd'; import { ShepherdService } from 'angular-shepherd';
import {builtInButtons, defaultStepOptions} from './shepherd-data'; import {builtInButtons, defaultStepOptions} from './shepherd-data';
import { OnboardingService } from '@sunbird/offline';
...@@ -27,7 +28,7 @@ import {builtInButtons, defaultStepOptions} from './shepherd-data'; ...@@ -27,7 +28,7 @@ import {builtInButtons, defaultStepOptions} from './shepherd-data';
selector: 'app-root', selector: 'app-root',
templateUrl: './app.component.html' templateUrl: './app.component.html'
}) })
export class AppComponent implements OnInit, OnDestroy, AfterViewInit { export class AppComponent implements OnInit, OnDestroy {
@ViewChild('frameWorkPopUp') frameWorkPopUp; @ViewChild('frameWorkPopUp') frameWorkPopUp;
/** /**
* user profile details. * user profile details.
...@@ -86,6 +87,7 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit { ...@@ -86,6 +87,7 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
telemetryContextData: any ; telemetryContextData: any ;
didV2: boolean; didV2: boolean;
flag = false; flag = false;
showOnboardingPopup = false;
constructor(private cacheService: CacheService, private browserCacheTtlService: BrowserCacheTtlService, constructor(private cacheService: CacheService, private browserCacheTtlService: BrowserCacheTtlService,
public userService: UserService, private navigationHelperService: NavigationHelperService, public userService: UserService, private navigationHelperService: NavigationHelperService,
private permissionService: PermissionService, public resourceService: ResourceService, private permissionService: PermissionService, public resourceService: ResourceService,
...@@ -94,7 +96,7 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit { ...@@ -94,7 +96,7 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
private orgDetailsService: OrgDetailsService, private activatedRoute: ActivatedRoute, private orgDetailsService: OrgDetailsService, private activatedRoute: ActivatedRoute,
private profileService: ProfileService, private toasterService: ToasterService, public utilService: UtilService, private profileService: ProfileService, private toasterService: ToasterService, public utilService: UtilService,
@Inject(DOCUMENT) private _document: any, public sessionExpiryInterceptor: SessionExpiryInterceptor, @Inject(DOCUMENT) private _document: any, public sessionExpiryInterceptor: SessionExpiryInterceptor,
private shepherdService: ShepherdService) { private shepherdService: ShepherdService, public onboardingService: OnboardingService) {
this.instance = (<HTMLInputElement>document.getElementById('instance')) this.instance = (<HTMLInputElement>document.getElementById('instance'))
? (<HTMLInputElement>document.getElementById('instance')).value : 'sunbird'; ? (<HTMLInputElement>document.getElementById('instance')).value : 'sunbird';
} }
...@@ -123,6 +125,7 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit { ...@@ -123,6 +125,7 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
this.didV2 = (localStorage && localStorage.getItem('fpDetails_v2')) ? true : false; this.didV2 = (localStorage && localStorage.getItem('fpDetails_v2')) ? true : false;
const queryParams$ = this.activatedRoute.queryParams.pipe( const queryParams$ = this.activatedRoute.queryParams.pipe(
filter( queryParams => queryParams && queryParams.clientId === 'android' && queryParams.context), filter( queryParams => queryParams && queryParams.clientId === 'android' && queryParams.context),
first(),
tap(queryParams => { tap(queryParams => {
this.telemetryContextData = JSON.parse(decodeURIComponent(queryParams.context)); this.telemetryContextData = JSON.parse(decodeURIComponent(queryParams.context));
}), }),
...@@ -130,7 +133,7 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit { ...@@ -130,7 +133,7 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
); );
this.handleHeaderNFooter(); this.handleHeaderNFooter();
this.resourceService.initialize(); this.resourceService.initialize();
combineLatest(queryParams$, this.setSlug(), this.setDeviceId()) combineLatest(queryParams$, this.setSlug(), this.setDeviceId(), this.getDesktopUserData())
.pipe( .pipe(
mergeMap(data => { mergeMap(data => {
this.navigationHelperService.initialize(); this.navigationHelperService.initialize();
...@@ -141,6 +144,10 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit { ...@@ -141,6 +144,10 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
this.userService.startSession(); this.userService.startSession();
return this.setUserDetails(); return this.setUserDetails();
} else { } else {
_.isEmpty(data[3]) ? this.showOnboardingPopup = true : this.initializeTourTravel();
this.onboardingService.onboardCompletion.subscribe(event => {
event !== 'SUCCESS' ? this.showOnboardingPopup = true : this.initializeTourTravel();
});
return this.setOrgDetails(); return this.setOrgDetails();
} }
})) }))
...@@ -157,9 +164,7 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit { ...@@ -157,9 +164,7 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
}); });
this.changeLanguageAttribute(); this.changeLanguageAttribute();
if (this.isOffline) { document.body.classList.add('sb-offline');
document.body.classList.add('sb-offline');
}
} }
setFingerPrintTelemetry() { setFingerPrintTelemetry() {
...@@ -418,23 +423,6 @@ setFingerPrintTelemetry() { ...@@ -418,23 +423,6 @@ setFingerPrintTelemetry() {
}); });
} }
ngAfterViewInit() {
setTimeout(() => {
this.initializeShepherdData();
if (this.isOffline) {
this.shepherdService.defaultStepOptions = defaultStepOptions;
this.shepherdService.disableScroll = true;
this.shepherdService.modal = true;
this.shepherdService.confirmCancel = false;
this.shepherdService.addSteps(this.shepherdData);
if ((localStorage.getItem('TakeOfflineTour') !== 'show')) {
localStorage.setItem('TakeOfflineTour', 'show');
this.shepherdService.start();
}
}
}, 1000);
}
initializeShepherdData() { initializeShepherdData() {
this.shepherdData = [ this.shepherdData = [
{ {
...@@ -495,6 +483,7 @@ setFingerPrintTelemetry() { ...@@ -495,6 +483,7 @@ setFingerPrintTelemetry() {
} }
}]; }];
} }
ngOnDestroy() { ngOnDestroy() {
if (this.resourceDataSubscription) { if (this.resourceDataSubscription) {
this.resourceDataSubscription.unsubscribe(); this.resourceDataSubscription.unsubscribe();
...@@ -503,4 +492,27 @@ setFingerPrintTelemetry() { ...@@ -503,4 +492,27 @@ setFingerPrintTelemetry() {
interpolateInstance(message) { interpolateInstance(message) {
return message.replace('{instance}', _.upperCase(this.instance)); return message.replace('{instance}', _.upperCase(this.instance));
} }
initializeTourTravel() {
this.showOnboardingPopup = false;
setTimeout(() => {
this.initializeShepherdData();
this.shepherdService.defaultStepOptions = defaultStepOptions;
this.shepherdService.disableScroll = true;
this.shepherdService.modal = true;
this.shepherdService.confirmCancel = false;
this.shepherdService.addSteps(this.shepherdData);
if ((localStorage.getItem('TakeOfflineTour') !== 'show')) {
localStorage.setItem('TakeOfflineTour', 'show');
this.shepherdService.start();
}
}, 1000);
}
getDesktopUserData() {
return this.onboardingService.getUser().pipe(
tap(data => {
}), catchError(error => {
return of(undefined);
}));
}
} }
...@@ -11,3 +11,5 @@ export * from './offline-faq/offline-faq.component'; ...@@ -11,3 +11,5 @@ export * from './offline-faq/offline-faq.component';
export * from './desktop-header/desktop-header.component'; export * from './desktop-header/desktop-header.component';
export * from './library/library.component'; export * from './library/library.component';
export * from './library-filters/library-filters.component'; export * from './library-filters/library-filters.component';
export * from './onboarding/onboarding.component';
export * from './onboarding-location/onboarding-location.component';
<div class="loginform__content" [appTelemetryImpression]="telemetryImpression">
<div class="loginform__content__header">
<img src="assets/images/SUNBIRD.svg" alt="SUNBIRD">
</div>
<!-- Slides -->
<div class="d-flex">
<div class="swiper-slide">
<label
class="swiper-slide__title p-0 m-0 sb-color-primary">{{resourceService?.messages?.imsg?.m0075}}</label>
<div class="swiper-slide__para pt-8">{{resourceService?.messages?.imsg?.m0074}} </div>
<div class="d-flex flex-dc fields-selection">
<div class="sb-field">
<sui-select class="selection" labelField="name" [isSearchable]="true" [(ngModel)]="selectedState"
(ngModelChange)="onOptionChanges(selectedState)" placeholder="Select State" [options]="stateList"
#states>
<sui-select-option *ngFor="let state of states.filteredOptions" [value]="state">
</sui-select-option>
</sui-select>
</div>
<div class="sb-field" *ngIf="districtList.length">
<sui-select class="selection mt-10" labelField="name" [isSearchable]="true"
[(ngModel)]="selectedDistrict" (ngModelChange)="onOptionChanges(selectedDistrict)"
placeholder="Select District" [options]="districtList" #districts>
<sui-select-option *ngFor="let district of districts.filteredOptions" [value]="district">
</sui-select-option>
</sui-select>
</div>
</div>
</div>
</div>
<div class="bullets-container">
<div class="circle active"></div>
<div class="circle update"></div>
</div>
<button type="button" [disabled]="disableContinueBtn" class="sb-btn sb-btn-primary sb-btn-sm"
(click)="handleSubmitButton()" appTelemetryInteract [telemetryInteractEdata]= "telemetryInteractEdata">
{{continueLabel}}
<span class='arrow-icon'><i class="arrow right icon"></i></span></button>
</div>
\ No newline at end of file
export const onboarding_location_test = {
filters: {
state: {
'code': 'FT_State_Code-1553105654910',
'name': 'state_location_nameYn3sEugPju',
'id': 'b6381e02-5a79-45ec-8e1a-a2e74fc29da3',
'type': 'state'
},
district: {
'code': 'FT_District_Code-1553105653081',
'name': 'state_location_nameicXqsmPn3V',
'id': 'bc3a0e4c-c203-4fd5-a8b7-3bb39c2a5e4b',
'type': 'district',
'parentId': 'b6381e02-5a79-45ec-8e1a-a2e74fc29da3'
}
},
statesList: {
'id': 'api.location.search',
'ver': '1.0',
'ts': '2019-11-23T11:03:57.740Z',
'params': {
'resmsgid': '2aa54e34-2318-412f-8985-f6c79829ca93',
'msgid': '526e5c18-bbfa-4236-8808-6a31a2e68265',
'status': 'successful',
'err': null,
'errmsg': null
},
'responseCode': 'OK',
'result': {
'response': [
{
'code': '1',
'name': 'Jammu And Kashmir',
'id': 'f138e9c2-adae-4e5b-ab3c-0527ff6a2b5f',
'type': 'state'
},
{
'code': '29',
'name': 'Karnataka',
'id': '4a6d77a1-6653-4e30-9be8-93371b6b53b5',
'type': 'state'
},
]
}
},
districtList: {
'id': 'api.location.search',
'ver': '1.0',
'ts': '2019-11-23T11:11:25.444Z',
'params': {
'resmsgid': '6415fba5-1ced-4b4f-8229-6d508b20ec8d',
'msgid': '44fefbfe-492e-4cdd-98f8-ca3d999d23e1',
'status': 'successful',
'err': null,
'errmsg': null
},
'responseCode': 'OK',
'result': {
'response': [
{
'code': '2907',
'name': 'KOPPAL',
'id': 'cde02789-5803-424b-a3f5-10db347280e9',
'type': 'district',
'parentId': '4a6d77a1-6653-4e30-9be8-93371b6b53b5'
},
{
'code': '2909',
'name': 'DHARWAD',
'id': '3ac37fb2-d833-45bf-a579-a2656b0cce62',
'type': 'district',
'parentId': '4a6d77a1-6653-4e30-9be8-93371b6b53b5'
},
{
'code': '2918',
'name': 'TUMAKURU',
'id': 'ed622a46-17bb-42c0-b0a0-50c02b38a05c',
'type': 'district',
'parentId': '4a6d77a1-6653-4e30-9be8-93371b6b53b5'
}
]
}
},
saveLocation: {
'id': 'api.location.save',
'ver': '1.0',
'ts': '2019-11-23T11:19:42.475Z',
'params': {
'resmsgid': '80815f7f-a6d3-42fa-9594-b2ae2d373835',
'msgid': '9c1b0de0-ff92-4301-8e7e-dd7e561a1b34',
'status': 'successful',
'err': null,
'errmsg': null
},
'responseCode': 'OK',
'result': true
},
error: {
'error': {
'id': 'api.location.save',
'ver': '1.0',
'ts': '2019-10-25T09:39:51.560Z',
'params': {
'resmsgid': '9652a082-9677-4ccf-91e9-f138fd80c410',
'msgid': 'c246387b-a3a6-4a98-b150-73b1bbab7665',
'status': 'failed',
'err': 'ERR_INTERNAL_SERVER_ERROR',
'errmsg': 'Error while processing the request'
},
'responseCode': 'INTERNAL_SERVER_ERROR',
'result': {}
}
}
};
import { By } from '@angular/platform-browser';
import { of as observableOf, throwError } from 'rxjs';
import { onboarding_location_test } from './onboarding-location.component.spec.data';
import { ActivatedRoute, Router } from '@angular/router';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
import { SuiModule } from 'ng2-semantic-ui';
import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
import { OnboardingLocationComponent } from './onboarding-location.component';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { TelemetryModule } from '@sunbird/telemetry';
import { SharedModule, ResourceService } from '@sunbird/shared';
describe('OnboardingLocationComponent', () => {
let component: OnboardingLocationComponent;
let fixture: ComponentFixture<OnboardingLocationComponent>;
const resourceBundle = {
frmelmnts: {
lbl: {
continue: 'Continue'
}
},
messages: {
emsg: {
m0021: 'Unable to save location. please try again after some time.',
},
smsg: {
m0057: 'Location saved successfully...'
}
}
};
class ActivatedRouteStub {
}
class RouterStub {
navigate = jasmine.createSpy('navigate');
}
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ OnboardingLocationComponent ],
imports: [SharedModule.forRoot(), HttpClientTestingModule, TelemetryModule.forRoot(), SuiModule, FormsModule, ReactiveFormsModule],
providers: [
{ provide: ResourceService, useValue: resourceBundle },
{ provide: ActivatedRoute, useClass: ActivatedRouteStub },
{ provide: Router, useClass: RouterStub },
],
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(OnboardingLocationComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should call getAllStates', () => {
spyOn(component, 'getAllStates');
component.ngOnInit();
expect(component.getAllStates).toHaveBeenCalled();
});
it('should call allDistrict', () => {
spyOn(component, 'getAllDistricts');
component.onOptionChanges(onboarding_location_test.filters.state);
expect(component.getAllDistricts).toHaveBeenCalled();
});
it('should not call allDistrict', () => {
spyOn(component, 'getAllDistricts');
component.onOptionChanges(onboarding_location_test.filters.district);
expect(component.getAllDistricts).not.toHaveBeenCalled();
expect(component.disableContinueBtn).toBeFalsy();
});
it('should call searchLocation (to get states) in onboarding service', () => {
spyOn(component.onboardingService, 'searchLocation').and.returnValue(observableOf(onboarding_location_test.statesList));
component.getAllStates();
expect(component.onboardingService.searchLocation).toHaveBeenCalled();
});
it('should call searchLocation (to get districts) in onboarding service', () => {
spyOn(component.onboardingService, 'searchLocation').and.returnValue(observableOf(onboarding_location_test.districtList));
const parentId = onboarding_location_test.statesList.result.response[1]['id'];
component.getAllDistricts(parentId);
expect(component.onboardingService.searchLocation).toHaveBeenCalled();
expect(parentId).toEqual('4a6d77a1-6653-4e30-9be8-93371b6b53b5');
});
it('should call saveLocation (successful) in onboarding service', () => {
spyOn(component.onboardingService, 'saveLocation').and.returnValue(observableOf(onboarding_location_test.saveLocation));
spyOn(component.locationSaved, 'emit').and.returnValue(observableOf('SUCCESS'));
spyOn(component.toasterService, 'success').and.returnValue(observableOf(resourceBundle.messages.smsg.m0057));
component.handleSubmitButton();
expect(component.onboardingService.saveLocation).toHaveBeenCalled();
expect(component.disableContinueBtn).toBeFalsy();
expect(component.locationSaved.emit).toHaveBeenCalled();
expect(component.toasterService.success).toHaveBeenCalled();
});
it('should call saveLocation (error) in onboarding service', () => {
spyOn(component.onboardingService, 'saveLocation').and.returnValue(throwError(onboarding_location_test.error));
spyOn(component.locationSaved, 'emit').and.returnValue(observableOf('ERROR'));
spyOn(component.toasterService, 'error').and.returnValue(throwError(resourceBundle.messages.emsg.m0021));
component.handleSubmitButton();
expect(component.onboardingService.saveLocation).toHaveBeenCalled();
expect(component.disableContinueBtn).toBeTruthy();
expect(component.locationSaved.emit).toHaveBeenCalled();
expect(component.toasterService.error).toHaveBeenCalled();
});
});
import { Router } from '@angular/router';
import { DeviceRegisterService } from '@sunbird/core';
import { ResourceService, ToasterService } from '@sunbird/shared';
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { OnboardingService } from './../../services';
import { IImpressionEventInput, IInteractEventEdata } from '@sunbird/telemetry';
import * as _ from 'lodash-es';
@Component({
selector: 'app-onboarding-location',
templateUrl: './onboarding-location.component.html',
styleUrls: ['./onboarding-location.component.scss']
})
export class OnboardingLocationComponent implements OnInit {
selectedState: any;
selectedDistrict: any;
stateList = [];
districtList = [];
@Output() locationSaved = new EventEmitter();
disableContinueBtn = true;
telemetryInteractEdata: IInteractEventEdata;
public telemetryImpression: IImpressionEventInput;
continueLabel = _.upperCase(this.resourceService.frmelmnts.lbl.continue);
constructor(public onboardingService: OnboardingService,
public resourceService: ResourceService, public toasterService: ToasterService, private router: Router) {
}
ngOnInit() {
this.getAllStates();
this.setTelemetryData();
}
onOptionChanges(option) {
if (option.type === 'state') {
this.selectedDistrict = {};
this.districtList = [];
this.getAllDistricts(option.id);
} else {
this.disableContinueBtn = false;
}
}
getAllStates() {
this.onboardingService.searchLocation({ type: 'state' })
.subscribe(data => {
this.stateList = _.get(data, 'result.response');
});
}
getAllDistricts(parentId) {
this.onboardingService.searchLocation({ type: 'district', parentId: parentId })
.subscribe(data => {
this.districtList = _.get(data, 'result.response');
});
}
handleSubmitButton() {
this.disableContinueBtn = true;
const requestParams = {
request: {
state: this.selectedState,
city: this.selectedDistrict
}
};
this.onboardingService.saveLocation(requestParams).subscribe(() => {
this.disableContinueBtn = false;
this.locationSaved.emit('SUCCESS');
this.toasterService.success(_.get(this.resourceService, 'messages.smsg.m0057') || 'SUCCESS');
}, error => {
this.disableContinueBtn = true;
this.locationSaved.emit('ERROR');
this.toasterService.error(this.resourceService.messages.emsg.m0021);
});
}
setTelemetryData () {
this.telemetryImpression = {
context: { env: 'offline' },
edata: {
type: 'view',
pageid: 'onboarding_location_setting',
uri: this.router.url
}
};
this.telemetryInteractEdata = {
id: 'onboarding_location',
type: 'click',
pageid: 'onboarding_location_setting'
};
}
}
<div class="bg-image">
<div class="loginform">
<app-onboarding-location *ngIf="slide === 'location'" (locationSaved)="handleLocationSaveEvent($event)"></app-onboarding-location>
</div>
</div>
\ No newline at end of file
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { OnboardingComponent } from './onboarding.component';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { TelemetryModule } from '@sunbird/telemetry';
import { SharedModule } from '@sunbird/shared';
import { Router } from '@angular/router';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
describe('OnboardingComponent', () => {
let component: OnboardingComponent;
let fixture: ComponentFixture<OnboardingComponent>;
class RouterStub {
navigate = jasmine.createSpy('navigate');
}
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ OnboardingComponent ],
imports: [SharedModule.forRoot(), HttpClientTestingModule, TelemetryModule.forRoot()],
providers: [
{ provide: Router, useClass: RouterStub }
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(OnboardingComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { IImpressionEventInput, IInteractEventEdata } from '@sunbird/telemetry';
import { ToasterService } from '@sunbird/shared';
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import * as _ from 'lodash-es';
import { OnboardingService } from './../../services';
@Component({
selector: 'app-onboarding',
templateUrl: './onboarding.component.html',
styleUrls: ['./onboarding.component.scss']
})
export class OnboardingComponent implements OnInit {
slide = 'location';
constructor(public toasterService: ToasterService, public onboardingService: OnboardingService) {
}
ngOnInit() {
document.body.classList.add('o-y-hidden');
}
handleLocationSaveEvent(event) {
if (event === 'SUCCESS') {
// this.slide = 'contentPreference';
document.body.classList.remove('o-y-hidden');
this.onboardingService.onboardCompletion.emit('SUCCESS');
}
}
}
...@@ -12,7 +12,8 @@ import { ...@@ -12,7 +12,8 @@ import {
ContentImportHeaderComponent, WatchVideoComponent, NetworkStatusComponent, ContentImportHeaderComponent, WatchVideoComponent, NetworkStatusComponent,
BrowseComponent, ContentManagerComponent, OfflineHelpCenterComponent, DesktopAppUpdateComponent, BrowseComponent, ContentManagerComponent, OfflineHelpCenterComponent, DesktopAppUpdateComponent,
LibraryComponent, DesktopHeaderComponent, LibraryFiltersComponent, LibraryComponent, DesktopHeaderComponent, LibraryFiltersComponent,
OfflineFaqComponent, OfflineReportIssuesComponent, OfflineHelpVideosComponent OfflineFaqComponent, OfflineReportIssuesComponent, OfflineHelpVideosComponent, OnboardingComponent,
OnboardingLocationComponent
} from './components'; } from './components';
import { WebExtensionModule } from '@project-sunbird/web-extensions'; import { WebExtensionModule } from '@project-sunbird/web-extensions';
import { FileSizeModule } from 'ngx-filesize'; import { FileSizeModule } from 'ngx-filesize';
...@@ -54,7 +55,9 @@ import { CommonConsumptionModule } from '@project-sunbird/common-consumption'; ...@@ -54,7 +55,9 @@ import { CommonConsumptionModule } from '@project-sunbird/common-consumption';
LibraryFiltersComponent, LibraryFiltersComponent,
OfflineFaqComponent, OfflineFaqComponent,
OfflineReportIssuesComponent, OfflineReportIssuesComponent,
OfflineHelpVideosComponent OfflineHelpVideosComponent,
OnboardingComponent,
OnboardingLocationComponent,
], ],
entryComponents: [ entryComponents: [
ContentImportHeaderComponent, ContentImportHeaderComponent,
...@@ -64,6 +67,7 @@ import { CommonConsumptionModule } from '@project-sunbird/common-consumption'; ...@@ -64,6 +67,7 @@ import { CommonConsumptionModule } from '@project-sunbird/common-consumption';
WatchVideoComponent, WatchVideoComponent,
ContentImportHeaderComponent, ContentImportHeaderComponent,
], ],
exports: [DesktopAppUpdateComponent, DesktopHeaderComponent, LibraryFiltersComponent] exports: [DesktopAppUpdateComponent, DesktopHeaderComponent, LibraryFiltersComponent, OnboardingComponent,
OnboardingLocationComponent]
}) })
export class OfflineModule { } export class OfflineModule { }
...@@ -2,3 +2,4 @@ export * from './connection-service/connection.service'; ...@@ -2,3 +2,4 @@ export * from './connection-service/connection.service';
export * from './content-manager/content-manager.service'; export * from './content-manager/content-manager.service';
export * from './electron-dialog/electron-dialog.service'; export * from './electron-dialog/electron-dialog.service';
export * from './app-update/app-update.service'; export * from './app-update/app-update.service';
export * from './onboarding/onboarding.service';
import { TestBed } from '@angular/core/testing';
import { OnboardingService } from './onboarding.service';
xdescribe('OnboardingService', () => {
beforeEach(() => TestBed.configureTestingModule({}));
it('should be created', () => {
const service: OnboardingService = TestBed.get(OnboardingService);
expect(service).toBeTruthy();
});
});
import { PublicDataService } from '@sunbird/core';
import { ConfigService, ServerResponse } from '@sunbird/shared';
import { Injectable, EventEmitter } from '@angular/core';
import { Observable } from 'rxjs';
import * as _ from 'lodash-es';
@Injectable({
providedIn: 'root'
})
export class OnboardingService {
onboardCompletion = new EventEmitter();
userData;
constructor(public configService: ConfigService, public publicDataService: PublicDataService) { }
searchLocation(filters): Observable<ServerResponse> {
const options = {
url: this.configService.urlConFig.URLS.USER.LOCATION_SEARCH,
data: {
request: {
filters
}
}
};
return this.publicDataService.post(options);
}
getUser() {
const options = {
url: this.configService.urlConFig.URLS.OFFLINE.READ_USER
};
return this.publicDataService.get(options);
}
saveLocation(request): Observable<ServerResponse> {
const options = {
url: this.configService.urlConFig.URLS.OFFLINE.LOCATION_SAVE,
data: request
};
return this.publicDataService.post(options);
}
}
...@@ -182,7 +182,10 @@ ...@@ -182,7 +182,10 @@
"CANCEL_IMPORT":"content/v1/import/cancel", "CANCEL_IMPORT":"content/v1/import/cancel",
"PAUSE_IMPORT":"content/v1/import/pause", "PAUSE_IMPORT":"content/v1/import/pause",
"REPORT_OTHER_ISSUE":"help/v1/report/issue", "REPORT_OTHER_ISSUE":"help/v1/report/issue",
"READ_FAQ": "faqs/v1/read" "READ_FAQ": "faqs/v1/read",
"CREATE_USER": "desktop/user/v1/create",
"READ_USER": "desktop/user/v1/read",
"LOCATION_SAVE": "data/v1/location/save"
}, },
"ACCOUNT_RECOVERY": { "ACCOUNT_RECOVERY": {
"FUZZY_SEARCH": "user/v1/fuzzy/search", "FUZZY_SEARCH": "user/v1/fuzzy/search",
......
...@@ -22,6 +22,7 @@ export class TelemetryInteractDirective { ...@@ -22,6 +22,7 @@ export class TelemetryInteractDirective {
@Input() telemetryInteractEdata: IInteractEventEdata; @Input() telemetryInteractEdata: IInteractEventEdata;
@Input() telemetryInteractCdata: Array<{}>; @Input() telemetryInteractCdata: Array<{}>;
@Input() telemetryInteractContext;
@HostListener('click', ['$event']) @HostListener('click', ['$event'])
...@@ -30,7 +31,7 @@ export class TelemetryInteractDirective { ...@@ -30,7 +31,7 @@ export class TelemetryInteractDirective {
if (this.telemetryInteractEdata) { if (this.telemetryInteractEdata) {
this.appTelemetryInteractData = { this.appTelemetryInteractData = {
context: { context: {
env: _.get(this.activatedRoute, 'snapshot.root.firstChild.data.telemetry.env') || env: _.get(this.telemetryInteractContext, 'env') || _.get(this.activatedRoute, 'snapshot.root.firstChild.data.telemetry.env') ||
_.get(this.activatedRoute, 'snapshot.data.telemetry.env') || _.get(this.activatedRoute, 'snapshot.data.telemetry.env') ||
_.get(this.activatedRoute.snapshot.firstChild, 'children[0].data.telemetry.env') , _.get(this.activatedRoute.snapshot.firstChild, 'children[0].data.telemetry.env') ,
cdata: this.telemetryInteractCdata || [], cdata: this.telemetryInteractCdata || [],
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment