Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion make/DEBIAN/control
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Package: Testrun
Version: 2.4.0-beta.3
Version: 2.4.0-beta.5
Architecture: amd64
Maintainer: Google <ssm-orcas@google.com>
Homepage: https://github.com/google/testrun
Expand Down
3 changes: 2 additions & 1 deletion modules/ui/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@
</div>
<app-version
[consentShown]="vm.consentShown"
(consentShownEvent)="consentShown()"></app-version>
(consentShownEvent)="consentShown()"
(navigateToRouteEvent)="navigateToRoute($event)"></app-version>
</div>
</mat-drawer>
<mat-drawer-content class="app-content" role="region">
Expand Down
4 changes: 4 additions & 0 deletions modules/ui/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,10 @@ export class AppComponent implements AfterViewInit {
}
}

navigateToRoute(route: Routes): void {
this.route.navigate([route]);
}

private subscribeToNavigation() {
this.route.events
.pipe(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ <h2 tabindex="-1">Welcome to Testrun!</h2>
>
to share you thoughts
</li>
<li>Risk Profile was lastly updated in 2026 V2.4.0</li>
</ul>
</section>

Expand Down Expand Up @@ -82,6 +81,32 @@ <h2 tabindex="-1">Welcome to Testrun!</h2>
</app-callout>
</section>
}
<section class="section-container">
<app-callout [type]="CalloutType.Warning">
Risk assessment questionnaire was lastly updated in version 2.4.0. Visit
the
<a
id="devices-link"
(click)="confirm(optOut, Routes.Devices)"
(keydown.enter)="confirm(optOut, Routes.Devices)"
tabindex="0"
role="button"
class="message-link">
Devices
</a>
and
<a
id="risk-profiles-link"
(click)="confirm(optOut, Routes.RiskAssessment)"
(keydown.enter)="confirm(optOut, Routes.RiskAssessment)"
tabindex="0"
role="button"
class="message-link">
Risk Profiles
</a>
pages to update.
</app-callout>
</section>
<section class="section-container-info">
<app-callout [type]="CalloutType.Info">
Testrun uses Google Analytics to learn about how our users use the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { MatButtonModule } from '@angular/material/button';
import { of } from 'rxjs';
import { NEW_VERSION, VERSION } from '../../../mocks/version.mock';
import { MatIconTestingModule } from '@angular/material/icon/testing';
import { Routes } from '../../../model/routes';

describe('ConsentDialogComponent', () => {
let component: ConsentDialogComponent;
Expand Down Expand Up @@ -72,7 +73,7 @@ describe('ConsentDialogComponent', () => {
const confirmButton = compiled.querySelector(
'.confirm-button'
) as HTMLButtonElement;
const dialogRes = { grant: true };
const dialogRes = { grant: true, route: undefined };

confirmButton?.click();

Expand All @@ -88,7 +89,7 @@ describe('ConsentDialogComponent', () => {
const confirmButton = compiled.querySelector(
'.confirm-button'
) as HTMLButtonElement;
const dialogRes = { grant: false };
const dialogRes = { grant: false, route: undefined };

confirmButton?.click();

Expand All @@ -97,6 +98,38 @@ describe('ConsentDialogComponent', () => {
closeSpy.calls.reset();
});

it('should close dialog with devices route on device link click', () => {
component.optOut = true;
fixture.detectChanges();
const closeSpy = spyOn(component.dialogRef, 'close');
const devicesLink = compiled.querySelector(
'#devices-link'
) as HTMLButtonElement;
const dialogRes = { grant: false, route: Routes.Devices };

devicesLink?.click();

expect(closeSpy).toHaveBeenCalledWith(dialogRes);

closeSpy.calls.reset();
});

it('should close dialog with risk profiles route on risk profiles link click', () => {
component.optOut = true;
fixture.detectChanges();
const closeSpy = spyOn(component.dialogRef, 'close');
const devicesLink = compiled.querySelector(
'#risk-profiles-link'
) as HTMLButtonElement;
const dialogRes = { grant: false, route: Routes.RiskAssessment };

devicesLink?.click();

expect(closeSpy).toHaveBeenCalledWith(dialogRes);

closeSpy.calls.reset();
});

it('should not close dialog on download link click', () => {
const closeSpy = spyOn(component.dialogRef, 'close');
const confirmButton = compiled.querySelector(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { CalloutType } from '../../../model/callout-type';
import { MatCheckbox } from '@angular/material/checkbox';
import { FormsModule } from '@angular/forms';
import { timer } from 'rxjs';
import { Routes } from '../../../model/routes';

type DialogData = {
version: Version;
Expand All @@ -51,11 +52,13 @@ export class ConsentDialogComponent {

public readonly CalloutType = CalloutType;
optOut = this.data.optOut;
public readonly Routes = Routes;

confirm(optOut: boolean) {
confirm(optOut: boolean, route?: Routes) {
// dialog should be closed with opposite value to grant or deny access to GA
const dialogResult: ConsentDialogResult = {
grant: !optOut,
route,
};
this.dialogRef.close(dialogResult);
timer(100).subscribe(() => {
Expand Down
22 changes: 22 additions & 0 deletions modules/ui/src/app/components/version/version.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { of } from 'rxjs';
import { MatDialogRef } from '@angular/material/dialog';
import { ConsentDialogComponent } from './consent-dialog/consent-dialog.component';
import { MatIconTestingModule } from '@angular/material/icon/testing';
import { Routes } from '../../model/routes';

describe('VersionComponent', () => {
let component: VersionComponent;
Expand All @@ -43,6 +44,8 @@ describe('VersionComponent', () => {
const versionBehaviorSubject$ = new BehaviorSubject<Version | null>(null);

beforeEach(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(<any>window).gtag = jasmine.createSpy('gtag');
// @ts-expect-error data layer should be defined
window.dataLayer = window.dataLayer || [];
mockService = jasmine.createSpyObj(['getVersion', 'fetchVersion']);
Expand Down Expand Up @@ -103,6 +106,25 @@ describe('VersionComponent', () => {
expect(openSpy).toHaveBeenCalled();
});

it('should emit navigateToRouteEvent when dialogResult contains a route', () => {
const navigateToRouteEventSpy = spyOn(
component.navigateToRouteEvent,
'emit'
);
const mockDialogResult = {
grant: true,
route: Routes.Devices,
};
spyOn(component.dialog, 'open').and.returnValue({
afterClosed: () => of(mockDialogResult),
} as MatDialogRef<typeof ConsentDialogComponent>);

component.openConsentDialog(VERSION);

expect(navigateToRouteEventSpy).toHaveBeenCalledTimes(1);
expect(navigateToRouteEventSpy).toHaveBeenCalledWith(Routes.Devices);
});

describe('update is not available', () => {
beforeEach(() => {
versionBehaviorSubject$.next(VERSION);
Expand Down
7 changes: 6 additions & 1 deletion modules/ui/src/app/components/version/version.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { takeUntil } from 'rxjs/internal/operators/takeUntil';
import { filter, timer } from 'rxjs';
import { ConsentDialogComponent } from './consent-dialog/consent-dialog.component';
import { LocalStorageService } from '../../services/local-storage.service';
import { Routes } from '../../model/routes';

export const INSTALLED_VERSION = 'INSTALLED_VERSION';

Expand All @@ -56,6 +57,7 @@ export class VersionComponent implements OnInit, OnDestroy {

@Input() consentShown!: boolean;
@Output() consentShownEvent = new EventEmitter<void>();
@Output() navigateToRouteEvent = new EventEmitter<Routes>();
version$!: Observable<Version | null>;
private destroy$: Subject<boolean> = new Subject<boolean>();

Expand Down Expand Up @@ -122,7 +124,10 @@ export class VersionComponent implements OnInit, OnDestroy {
gtag('consent', 'update', {
analytics_storage: dialogResult.grant ? 'granted' : 'denied',
});
this.localStorageService.setGAConsent(dialogResult.grant);

if (dialogResult.route) {
this.navigateToRouteEvent.emit(dialogResult.route);
}
});
}

Expand Down
3 changes: 3 additions & 0 deletions modules/ui/src/app/model/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* limitations under the License.
*/

import { Routes } from './routes';

export interface Version {
installed_version: string;
update_available: boolean;
Expand All @@ -23,4 +25,5 @@ export interface Version {

export interface ConsentDialogResult {
grant: boolean;
route?: Routes;
}