Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add report level stub strategy #641

Merged
merged 12 commits into from
Aug 28, 2024
Merged
28 changes: 12 additions & 16 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { Location } from '@angular/common';
import { Title } from '@angular/platform-browser';
import { CompareComponent } from './compare/compare.component';
import { Report } from './shared/interfaces/report';
import { TestComponent } from './test/test.component';
import { DynamicService } from './shared/services/dynamic.service';
import { CompareData } from './compare/compare-data';
import { SettingsService } from './shared/services/settings.service';
import { TabService } from './shared/services/tab.service';
Expand All @@ -17,6 +15,8 @@ import { HelperService } from './shared/services/helper.service';
import { ToastComponent } from './shared/components/toast/toast.component';
import { ReportComponent } from './report/report.component';
import { CloseTab } from './shared/interfaces/close-tab';
import { HttpService } from './shared/services/http.service';
import { StubStrategyUtil } from './shared/enums/stub-strategy';

@Component({
selector: 'app-root',
Expand All @@ -25,7 +25,7 @@ import { CloseTab } from './shared/interfaces/close-tab';
standalone: true,
imports: [RouterLinkActive, RouterLink, RouterOutlet, ToastComponent],
})
export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
export class AppComponent implements OnInit, OnDestroy {
appVersion: string = '0.0.0';
@ViewChild(CompareComponent) compareComponent!: CompareComponent;
@ViewChild(TestComponent) testComponent!: TestComponent;
Expand All @@ -42,24 +42,21 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit {

constructor(
private titleService: Title,
private dynamicService: DynamicService,
//make sure settings are retrieved from localstorage on startup by initializing the service on startup
private settingsService: SettingsService,
private tabService: TabService,
private router: Router,
private helperService: HelperService,
private location: Location,
private httpService: HttpService,
) {
this.titleService.setTitle(`Ladybug - v${this.appVersion}`);
}

ngOnInit(): void {
this.fetchAndSetAppVersion();
this.subscribeToServices();
}

ngAfterViewInit(): void {
this.observeReportSave();
this.getStubStrategies();
}

ngOnDestroy(): void {
Expand Down Expand Up @@ -123,13 +120,6 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
this.router.navigate([ReportComponent.ROUTER_PATH, data.report.storageId]);
}

observeReportSave(): void {
this.dynamicService.getObservable().subscribe((report: Report) => {
const tabIndex: number = this.tabs.findIndex((tab: Tab): boolean => tab.id == String(report.storageId));
this.tabs[tabIndex].data = report;
});
}

openNewCompareTab(data: CompareData): void {
const tabId = this.helperService.createCompareTabId(data.originalReport, data.runResultReport);
const tabIndex: number = this.tabs.findIndex((tab: Tab): boolean => tab.id == tabId);
Expand Down Expand Up @@ -158,4 +148,10 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
event.preventDefault();
this.closeTab(tab);
}

getStubStrategies(): void {
this.httpService
.getStubStrategies()
.subscribe((response: string[]) => (StubStrategyUtil.reportStubStrategies = response));
}
}
MatthijsSmets marked this conversation as resolved.
Show resolved Hide resolved
29 changes: 20 additions & 9 deletions src/app/report/edit-display/edit-display.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,26 @@
><i class="fa fa-save"></i></button>
}
<app-encoding-button [selectedNode]="selectedNode" (updatedMessageEvent)="editor.setNewReport($event)"></app-encoding-button>
}
@if (ReportUtil.isCheckPoint(selectedNode)) {
<div class="w-fit mx-1 my-0">
<select class="form-control" [(ngModel)]="stubStrategy" (ngModelChange)="openStubDifferenceModal($event)">
<option [ngValue]="-1" [selected]="selectedNode.stub === -1">Use report level stub strategy</option>
<option [ngValue]="0" [selected]="selectedNode.stub === 0">Always stub this checkpoint</option>
<option [ngValue]="1" [selected]="selectedNode.stub === 1">Never stub this checkpoint</option>
</select>
</div>

@if (selectedNode) {
@if (ReportUtil.isReport(selectedNode)) {
MatthijsSmets marked this conversation as resolved.
Show resolved Hide resolved
<div class="w-fit mx-1 my-0">
<select class="form-control" [(ngModel)]="stubStrategy" (ngModelChange)="updateReportStubStrategy($event)">
@for (strategy of StubStrategyUtil.reportStubStrategies; track strategy) {
<option [ngValue]="strategy" [selected]="selectedNode.stubStrategy === strategy">{{ strategy }}</option>
}
</select>
</div>
} @else if (ReportUtil.isCheckPoint(selectedNode)) {
<div class="w-fit mx-1 my-0">
<select class="form-control" [(ngModel)]="stub" (ngModelChange)="updateCheckpointStubStrategy($event)">
@for (strategy of StubStrategyUtil.checkpointStubStrategyConst; track strategy; let index = $index) {
<option [ngValue]="index - 1" [selected]="selectedNode.stub === index - 1">{{ strategy }}</option>
}
</select>
</div>
}
}
}
<div
class="mr-2 cursor-pointer ml-auto"
Expand Down
122 changes: 72 additions & 50 deletions src/app/report/edit-display/edit-display.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { EncodingButtonComponent } from './encoding-button/encoding-button.compo
import { Checkpoint } from '../../shared/interfaces/checkpoint';
import { TestReportsService } from '../../test/test-reports.service';
import { DebugTabService } from '../../debug/debug-tab.service';
import { StubStrategyUtil } from '../../shared/enums/stub-strategy';

@Component({
selector: 'app-edit-display',
Expand Down Expand Up @@ -68,7 +69,8 @@ import { DebugTabService } from '../../debug/debug-tab.service';
export class EditDisplayComponent {
protected readonly ReportUtil = ReportUtil;
protected readonly Number: NumberConstructor = Number;
@Input() id: string = '';
protected readonly StubStrategyUtil = StubStrategyUtil;

@Input() containerHeight!: number;
@Input({ required: true }) currentView!: View;
@Input() newTab: boolean = true;
Expand All @@ -82,7 +84,8 @@ export class EditDisplayComponent {
rerunResult?: TestResult;
selectedNode?: Report | Checkpoint;
displayReport: boolean = false;
stubStrategy?: number;
stub?: number;
stubStrategy?: string;

constructor(
private modalService: NgbModal,
Expand All @@ -97,8 +100,9 @@ export class EditDisplayComponent {
showReport(node: Report | Checkpoint): void {
this.disableEditing();
this.selectedNode = node;
this.stubStrategy = node.stub;
this.stub = node.stub;
if (ReportUtil.isReport(this.selectedNode)) {
this.stubStrategy = this.selectedNode.stubStrategy;
this.editor.setNewReport(this.selectedNode.xml);
} else if (ReportUtil.isCheckPoint(this.selectedNode)) {
this.editor.setNewReport(this.convertMessage(this.selectedNode));
Expand Down Expand Up @@ -177,8 +181,8 @@ export class EditDisplayComponent {
}
}

getReportValues(checkpointId: string): UpdateReport | UpdateCheckpoint {
return this.editingRootNode ? this.getReportValuesForRootNode() : this.getReportValuesForChildNode(checkpointId);
getReportValues(checkpointId?: string): UpdateReport | UpdateCheckpoint {
return checkpointId ? this.getReportValuesForChildNode(checkpointId) : this.getReportValuesForRootNode();
}

getReportValuesForRootNode(): UpdateReport {
Expand Down Expand Up @@ -211,59 +215,77 @@ export class EditDisplayComponent {
this.editingEnabled = false;
}

openStubDifferenceModal(stubStrategy: number): void {
if ((this.selectedNode as Checkpoint).message == this.editor.getValue()) {
let reportDifferences: ReportDifference[] = [];
const stubStrategies: string[] = [
'Use report level stub strategy',
'Always stub this checkpoint',
'Never stub this checkpoint',
];
if (this.selectedNode && this.selectedNode.stub !== +stubStrategy) {
reportDifferences.push({
name: 'message',
originalValue: stubStrategies[this.selectedNode.stub + 1],
// @ts-ignore
difference: stubStrategies[stubStrategy + 1],
});
}
if (reportDifferences.length > 0) {
this.differenceModal.open(reportDifferences, 'save', true);
}
} else {
updateReportStubStrategy(strategy: string): void {
if (ReportUtil.isReport(this.selectedNode) && this.selectedNode.stubStrategy !== strategy) {
this.openStubDifferenceModal(this.selectedNode.stubStrategy, strategy);
}
}

updateCheckpointStubStrategy(strategy: number): void {
if (this.selectedNode && this.selectedNode.stub !== strategy) {
this.openStubDifferenceModal(
StubStrategyUtil.checkpointStubStrategyConst[this.selectedNode.stub + 1],
StubStrategyUtil.checkpointStubStrategyConst[strategy + 1],
);
}
}

openStubDifferenceModal(originalValue: string, difference: string): void {
if (this.editingEnabled) {
this.toastService.showWarning('Save or discard your changes before updating the stub strategy');
} else {
const reportDifferences: ReportDifference[] = [];
reportDifferences.push({
name: 'message',
originalValue: originalValue,
// @ts-ignore
difference: difference,
});
this.differenceModal.open(reportDifferences, 'save', true);
}
}

saveChanges(stubChange: boolean): void {
const node: Report | Checkpoint = this.selectedNode!;
let checkpointId: string = '';
let storageId: string;
if (ReportUtil.isReport(node)) {
storageId = String(node.storageId);
} else if (ReportUtil.isCheckPoint(node)) {
storageId = node.uid.split('#')[0];
checkpointId = node.uid.split('#')[1];
if (this.selectedNode) {
const node: Report | Checkpoint = this.selectedNode;
let checkpointId: string | undefined;
let storageId: string;
if (ReportUtil.isReport(node)) {
storageId = String(node.storageId);
} else if (ReportUtil.isCheckPoint(node)) {
storageId = node.uid.split('#')[0];
checkpointId = node.uid.split('#')[1];
} else {
return;
}
let body;
if (stubChange) {
body = checkpointId ? { stub: this.stub, checkpointId: checkpointId } : { stubStrategy: this.stubStrategy };
} else {
body = this.getReportValues(checkpointId);
}
this.updateReport(storageId, body, node);
} else {
return;
this.toastService.showWarning('Please select a node in the debug tree');
}
const body = stubChange
? { stub: this.stubStrategy ?? '', checkpointId: checkpointId }
: this.getReportValues(checkpointId);
}

this.httpService.updateReport(storageId, body, this.currentView.storageName).subscribe({
next: (response: UpdateReportResponse) => {
response.report.xml = response.xml;
if (ReportUtil.isCheckPoint(node)) {
this.selectedNode = ReportUtil.getCheckpointFromReport(response.report, node.uid);
} else if (ReportUtil.isReport(node)) {
this.selectedNode = response.report;
}
this.disableEditing();
this.debugTab.refreshAll([+storageId]);
},
error: () => catchError(this.errorHandler.handleError()),
});
updateReport(storageId: string, body: UpdateReport | UpdateCheckpoint, node: Report | Checkpoint): void {
this.httpService
.updateReport(storageId, body, this.currentView.storageName)
.pipe(catchError(this.errorHandler.handleError()))
.subscribe({
next: (response: UpdateReportResponse) => {
response.report.xml = response.xml;
if (ReportUtil.isCheckPoint(node)) {
this.selectedNode = ReportUtil.getCheckpointFromReport(response.report, node.uid);
} else if (ReportUtil.isReport(node)) {
this.selectedNode = response.report;
}
this.disableEditing();
this.debugTab.refreshAll([+storageId]);
},
});
}

discardChanges(): void {
Expand Down
1 change: 0 additions & 1 deletion src/app/report/edit-form/edit-form.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export class EditFormComponent implements OnInit {

getDifference(name: keyof Report): ReportDifference {
const originalValue = this.report[name] ?? '';
// @ts-ignore
const difference = new DiffMatchPatch().diff_main(originalValue, this.editForm.get(name)?.value ?? '');
return {
name: name,
Expand Down
8 changes: 8 additions & 0 deletions src/app/shared/enums/stub-strategy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export let StubStrategyUtil = {
ricklue marked this conversation as resolved.
Show resolved Hide resolved
reportStubStrategies: [] as string[],
checkpointStubStrategyConst: [
'Use report level stub strategy',
'Always stub this checkpoint',
'Never stub this checkpoint',
],
};
3 changes: 2 additions & 1 deletion src/app/shared/interfaces/update-checkpoint.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface UpdateCheckpoint {
checkpointId: string;
checkpointMessage: string;
checkpointMessage?: string;
stub?: number;
}
11 changes: 6 additions & 5 deletions src/app/shared/interfaces/update-report.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
export interface UpdateReport {
name: string;
path: string;
description: string;
transformation: string;
variables: string;
name?: string;
path?: string;
description?: string;
transformation?: string;
variables?: string;
stubStrategy?: string;
}
8 changes: 7 additions & 1 deletion src/app/shared/services/http.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export class HttpService {

updateReport(
reportId: string,
body: UpdateReport | UpdateCheckpoint | { stub: string | number; checkpointId: string },
body: UpdateReport | UpdateCheckpoint,
storage: string,
): Observable<UpdateReportResponse> {
return this.http
Expand Down Expand Up @@ -228,4 +228,10 @@ export class HttpService {
responseType: 'text',
});
}

getStubStrategies(): Observable<string[]> {
return this.http.get<string[]>(`api/testtool/stub-strategies`, {
headers: this.headers,
});
}
}
Loading