diff --git a/frontend/src/app/models/perfomance-aspect.model.ts b/frontend/src/app/models/perfomance-aspect.model.ts index 35feb3984d..0fed7d1b2f 100644 --- a/frontend/src/app/models/perfomance-aspect.model.ts +++ b/frontend/src/app/models/perfomance-aspect.model.ts @@ -5,6 +5,7 @@ export interface PerformanceAspect { id: number pageId: number jobGroupId: number + browserId: number measurand: SelectableMeasurand performanceAspectType: string } diff --git a/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-inspect/performance-aspect-inspect.component.html b/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-inspect/performance-aspect-inspect.component.html index aba250940a..df35eb6c2b 100644 --- a/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-inspect/performance-aspect-inspect.component.html +++ b/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-inspect/performance-aspect-inspect.component.html @@ -1,47 +1,21 @@
-
+ {{"frontend.de.iteratec.osm.performance-aspect." + performanceAspectWrapped?.data?.performanceAspectType + ".user-centric-question" | translate}} -
+ +
-
- -
{{"frontend.de.iteratec.isr.measurand." + (selectedMetric$ | async)?.name | translate}}
-
-
-
-
-
- -
-
+ +
- - - - - - - - - -
- {{"frontend.de.iteratec.osm.performance-aspect-metric" | translate}} {{"frontend.de.iteratec.osm.performance-aspect." + performanceAspectWrapped?.data?.performanceAspectType | translate}} + class="text-info">{{"frontend.de.iteratec.osm.performance-aspect." + performanceAspectWrapped?.data?.performanceAspectType + ".description" | translate}}
diff --git a/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-inspect/performance-aspect-inspect.component.scss b/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-inspect/performance-aspect-inspect.component.scss index fb088a93b4..7551aa20b8 100644 --- a/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-inspect/performance-aspect-inspect.component.scss +++ b/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-inspect/performance-aspect-inspect.component.scss @@ -1,26 +1,32 @@ .edit-container { display: grid; - grid-template-columns: repeat(5, 1fr); + grid-template-columns: 1fr 3fr; grid-auto-columns: max-content; grid-template-rows: 1fr; grid-gap: 0.8em; } -.aspect-label{ - font-size: 14px; +@media (max-width:768px) { + .edit-container { + grid-template-columns: 2fr 2fr; + } +} + +.aspect-label { + font-size: 12px; color: #555555; - margin: 0 0 2px 2px; + font-weight: lighter; } .aspect-type { grid-column-start: 1; - //grid-column-end: span 2; + grid-column-end: span 1; } .measurand { grid-column-start: 2; grid-column-end: span 2; - align-self: end; + align-self: start; } .buttons { @@ -33,3 +39,7 @@ margin: 0 0.5em; width: 8em; } + +.performance-aspect-type { + font-size: 15px; +} diff --git a/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-inspect/performance-aspect-inspect.component.ts b/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-inspect/performance-aspect-inspect.component.ts index b14ed4d4a9..85d83c6b72 100644 --- a/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-inspect/performance-aspect-inspect.component.ts +++ b/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-inspect/performance-aspect-inspect.component.ts @@ -1,10 +1,8 @@ -import {Component, Input, OnChanges, OnInit} from '@angular/core'; +import {Component, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core'; import {PerformanceAspect} from "../../../../../models/perfomance-aspect.model"; -import {TranslateService} from "@ngx-translate/core"; import {ReplaySubject} from "rxjs"; import {ResponseWithLoadingState} from "../../../../../models/response-with-loading-state.model"; import {SelectableMeasurand} from "../../../../../models/measurand.model"; -import {ApplicationService} from "../../../../../services/application.service"; @Component({ selector: 'osm-performance-aspect-inspect', @@ -13,51 +11,30 @@ import {ApplicationService} from "../../../../../services/application.service"; }) export class PerformanceAspectInspectComponent implements OnInit, OnChanges { @Input() performanceAspectWrapped: ResponseWithLoadingState; - selectedMetric$: ReplaySubject = new ReplaySubject(); - editMode: boolean = false; - performanceAspectInEditing: PerformanceAspect; + @Output() onSelect: EventEmitter = new EventEmitter(); + metric$: ReplaySubject = new ReplaySubject(); - constructor(private translateService: TranslateService, private applicationService: ApplicationService) { + constructor() { } ngOnInit() { if(this.performanceAspectWrapped){ - this.setAspectInEditing(); this.updateSelectedMetric(); } } ngOnChanges(){ if(this.performanceAspectWrapped){ - this.setAspectInEditing(); this.updateSelectedMetric(); } } private updateSelectedMetric() { - this.selectedMetric$.next(this.performanceAspectWrapped.data.measurand); - } - - private setAspectInEditing() { - this.performanceAspectInEditing = Object.assign({}, this.performanceAspectWrapped.data); - } - - edit() { - this.setAspectInEditing(); - this.editMode = true; - } - - cancel() { - this.setAspectInEditing(); - this.editMode = false; - } - - save() { - this.applicationService.createOrUpdatePerformanceAspect(this.performanceAspectInEditing); - this.editMode = false; + this.metric$.next(this.performanceAspectWrapped.data.measurand); } selectMeasurandForAspect(measurand: SelectableMeasurand) { - this.performanceAspectInEditing.measurand = measurand; + this.performanceAspectWrapped.data.measurand = measurand; + this.onSelect.emit(this.performanceAspectWrapped.data); } } diff --git a/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-management.component.html b/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-management.component.html index da81b94912..c3d3e4ad4f 100644 --- a/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-management.component.html +++ b/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-management.component.html @@ -1,15 +1,24 @@ -
+
- -

{{"frontend.de.iteratec.osm.performance-aspect.mgmt" | translate}} {{pageName}} + +

+ {{"frontend.de.iteratec.osm.performance-aspect.title" | translate}} {{ performanceAspectMgmtModal.getData() }}


-
- +
+
+ +
+
+
+ diff --git a/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-management.component.scss b/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-management.component.scss index 9b182098ed..38bbb38c85 100644 --- a/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-management.component.scss +++ b/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-management.component.scss @@ -1,17 +1,34 @@ .aspect-management-modal{ - max-width: 1200px; + max-width: 910px; } .aspect-management-box{ display: grid; grid-template-rows: 1fr 1fr 1fr; - grid-template-columns: 1fr 1fr 1fr; - //grid-gap: 8px; - grid-gap: 0.3em; + grid-template-columns: 1fr 1fr; + grid-gap: 1em; } .aspect-inspect{ grid-column-start: 1; - grid-column-end: span 3; + grid-column-end: span 2; } +.aspect-management-modal > .nsm-content > .nsm-body { + margin: 20px 20px 0 20px; +} + +.buttons { + height: 2.5em; + a { + float: right; + width: 100px; + margin: 0 5px 0 10px; + } +} + +.btn-init-dialog { + cursor: pointer; + font-size: 14px; + color: rgb(189, 188, 188); +} diff --git a/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-management.component.ts b/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-management.component.ts index 1d23514110..aaa14b6c4c 100644 --- a/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-management.component.ts +++ b/frontend/src/app/modules/application-dashboard/components/performance-aspect-management/performance-aspect-management.component.ts @@ -16,22 +16,38 @@ export class PerformanceAspectManagementComponent implements OnInit { @Input() pageId: number; @Input() pageName: string; performanceAspects$: Subject[]>; + changedMetrics: Map; - constructor(private ngxSmartModalService: NgxSmartModalService, private measurandsService: ResultSelectionService, private applicationService: ApplicationService) { - this.performanceAspects$ = this.applicationService.performanceAspectForPage$ + constructor(public ngxSmartModalService: NgxSmartModalService, private measurandsService: ResultSelectionService, private applicationService: ApplicationService) { + this.performanceAspects$ = this.applicationService.performanceAspectForPage$; } ngOnInit() { + this.changedMetrics = new Map(); } - initDialog(){ - this.measurandsService.updatePages([{id: this.pageId, name: "does-not-matter"}]); - this.applicationService.updatePage({id: this.pageId, name: "does-not-matter"}); - this.ngxSmartModalService.open('preformanceAspectMgmtModal'); + initDialog() { + this.ngxSmartModalService.setModalData(this.pageName, "performanceAspectMgmtModal"); + this.measurandsService.updatePages([{id: this.pageId, name: this.pageName}]); + this.applicationService.updatePage({id: this.pageId, name: this.pageName}); + this.ngxSmartModalService.open('performanceAspectMgmtModal'); } - cancel(){ + resetModalData() { + this.changedMetrics.clear(); + this.ngxSmartModalService.resetModalData('performanceAspectMgmtModal'); + } + + updatePerformanceAspect(performanceAspect: PerformanceAspect) { + let key: string = performanceAspect.jobGroupId + "." + performanceAspect.pageId + "." + performanceAspect.performanceAspectType; + this.changedMetrics.set(key, performanceAspect); + } + saveAndClose() { + this.changedMetrics.forEach((performanceAspect: PerformanceAspect) => { + this.applicationService.createOrUpdatePerformanceAspect(performanceAspect); + }); + this.ngxSmartModalService.close('performanceAspectMgmtModal'); } } diff --git a/frontend/src/app/modules/application-dashboard/models/location.model.ts b/frontend/src/app/modules/application-dashboard/models/location.model.ts new file mode 100644 index 0000000000..5f44f3d161 --- /dev/null +++ b/frontend/src/app/modules/application-dashboard/models/location.model.ts @@ -0,0 +1,9 @@ +export interface BrowserDto { + id: number + name: string +} +export interface LocationDto { + id: Number + name: string + parent: BrowserDto +} diff --git a/frontend/src/app/modules/landing/landing.component.spec.ts b/frontend/src/app/modules/landing/landing.component.spec.ts index e22897df72..d42e62cb39 100644 --- a/frontend/src/app/modules/landing/landing.component.spec.ts +++ b/frontend/src/app/modules/landing/landing.component.spec.ts @@ -8,7 +8,6 @@ import {By} from "@angular/platform-browser"; import {Application} from "../../models/application.model"; import {CsiValueSmallComponent} from "../shared/components/csi-value/csi-value-small/csi-value-small.component"; import {ApplicationCsi} from "../../models/application-csi.model"; -import { of } from 'rxjs'; describe('LandingComponent', () => { let component: LandingComponent; @@ -79,40 +78,55 @@ describe('LandingComponent', () => { expect(fixture.debugElement.query(By.css(".clickable-list"))).toBeTruthy(); const links = fixture.debugElement.queryAll(By.css(".clickable-list a")); expect(links.length).toBe(2); - expect(links[0].nativeElement.href).toMatch(".*/applicationDashboard/1"); - expect(links[0].query(By.css(".title")).nativeElement.textContent.trim()).toEqual("TestOne"); + + const linkHrefs = [".*/applicationDashboard/1", ".*/applicationDashboard/2"]; + const linkTitles = ["TestOne", "TestTwo"]; + expect(links.some(element => element.nativeElement.href.match(linkHrefs[0]))); + expect(links.some(element => element.query(By.css(".title")).nativeElement.textContent.trim().match(linkTitles[0]))); + expect(links.some(element => element.nativeElement.href.match(linkHrefs[1]))); + expect(links.some(element => element.query(By.css(".title")).nativeElement.textContent.trim().match(linkTitles[1]))); expect(links[0].query(By.directive(CsiValueSmallComponent)).componentInstance.showLoading).toBeTruthy(); - expect(links[1].nativeElement.href).toMatch(".*/applicationDashboard/2"); - expect(links[1].query(By.css(".title")).nativeElement.textContent.trim()).toEqual("TestTwo"); expect(links[1].query(By.directive(CsiValueSmallComponent)).componentInstance.showLoading).toBeTruthy(); }); - it('should show a list of applications if existing, with CSI values', () => { + it('should show a list of applications if existing, with CSI values (in descending order)', () => { applicationService.applications$.next({ isLoading: false, data: [ new Application({id: 1, name: "TestOne"}), - new Application({id: 2, name: "TestTwo"}) + new Application({id: 2, name: "TestTwo"}), + new Application({id: 3, name: "TestThree"}), + new Application({id: 4, name: "TestFour"}) ] }); applicationService.applicationCsiById$.next({ isLoading: false, 1: new ApplicationCsi({csiValues: [{csiDocComplete: 50}, {csiDocComplete: 60}]}), - 2: new ApplicationCsi({csiValues: [{csiDocComplete: 60}, {csiDocComplete: 70}]}) + 2: new ApplicationCsi({csiValues: [{csiDocComplete: 60}, {csiDocComplete: 70}]}), + 3: new ApplicationCsi({csiValues: [{csiDocComplete: 70}, {csiDocComplete: 80}]}), + 4: new ApplicationCsi({csiValues: []}) }); fixture.detectChanges(); expect(fixture.debugElement.query(By.css("main")).classes.center).toBeFalsy(); expect(fixture.debugElement.query(By.css(".clickable-list"))).toBeTruthy(); const links = fixture.debugElement.queryAll(By.css(".clickable-list a")); - expect(links.length).toBe(2); - expect(links[0].nativeElement.href).toMatch(".*/applicationDashboard/1"); - expect(links[0].query(By.css(".title")).nativeElement.textContent.trim()).toEqual("TestOne"); + expect(links.length).toBe(4); + expect(links[0].nativeElement.href).toMatch(".*/applicationDashboard/3"); + expect(links[0].query(By.css(".title")).nativeElement.textContent.trim()).toEqual("TestThree"); expect(links[0].query(By.directive(CsiValueSmallComponent)).componentInstance.showLoading).toBeFalsy(); - expect(links[0].query(By.directive(CsiValueSmallComponent)).componentInstance.csiValue).toEqual(60); + expect(links[0].query(By.directive(CsiValueSmallComponent)).componentInstance.csiValue).toEqual(80); expect(links[1].nativeElement.href).toMatch(".*/applicationDashboard/2"); expect(links[1].query(By.css(".title")).nativeElement.textContent.trim()).toEqual("TestTwo"); expect(links[1].query(By.directive(CsiValueSmallComponent)).componentInstance.showLoading).toBeFalsy(); expect(links[1].query(By.directive(CsiValueSmallComponent)).componentInstance.csiValue).toEqual(70); + expect(links[2].nativeElement.href).toMatch(".*/applicationDashboard/1"); + expect(links[2].query(By.css(".title")).nativeElement.textContent.trim()).toEqual("TestOne"); + expect(links[2].query(By.directive(CsiValueSmallComponent)).componentInstance.showLoading).toBeFalsy(); + expect(links[2].query(By.directive(CsiValueSmallComponent)).componentInstance.csiValue).toEqual(60); + expect(links[3].nativeElement.href).toMatch(".*/applicationDashboard/4"); + expect(links[3].query(By.css(".title")).nativeElement.textContent.trim()).toEqual("TestFour"); + expect(links[3].query(By.directive(CsiValueSmallComponent)).componentInstance.showLoading).toBeFalsy(); + expect(links[3].query(By.directive(CsiValueSmallComponent)).componentInstance.csiValue).toEqual(undefined); }); it('should show a button to view all jobs', () => { diff --git a/frontend/src/app/modules/landing/landing.component.ts b/frontend/src/app/modules/landing/landing.component.ts index 5405842ea1..7d2815bc57 100644 --- a/frontend/src/app/modules/landing/landing.component.ts +++ b/frontend/src/app/modules/landing/landing.component.ts @@ -26,7 +26,15 @@ export class LandingComponent { ); this.applications$ = combineLatest(this.applicationService.applications$, this.applicationService.applicationCsiById$).pipe( filter(([applications]) => !applications.isLoading && !!applications.data), - map(([applications, csiById]) => applications.data.map(app => new ApplicationWithCsi(app, csiById[app.id], csiById.isLoading))) + map(([applications, csiById]) => applications.data.map(app => new ApplicationWithCsi(app, csiById[app.id], csiById.isLoading)).sort((a, b) => { + if (!b.recentCsi.csiDocComplete) { + return -1; + } else if (!a.recentCsi.csiDocComplete && !b.recentCsi.csiDocComplete) { + return 0; + } else { + return b.recentCsi.csiDocComplete - a.recentCsi.csiDocComplete; + } + })) ); this.applicationService.loadApplications(); this.applicationService.loadRecentCsiForApplications(); diff --git a/frontend/src/app/modules/result-selection/components/measurand-select/measurand-select.component.html b/frontend/src/app/modules/result-selection/components/measurand-select/measurand-select.component.html index 8df8664369..6125d31dd0 100644 --- a/frontend/src/app/modules/result-selection/components/measurand-select/measurand-select.component.html +++ b/frontend/src/app/modules/result-selection/components/measurand-select/measurand-select.component.html @@ -2,8 +2,8 @@ [compareWith]="compareMeasurands"> -
diff --git a/src/main/groovy/de/iteratec/osm/result/dao/EventResultQueryBuilder.groovy b/src/main/groovy/de/iteratec/osm/result/dao/EventResultQueryBuilder.groovy index f32b2f7f86..4e52cf48a6 100644 --- a/src/main/groovy/de/iteratec/osm/result/dao/EventResultQueryBuilder.groovy +++ b/src/main/groovy/de/iteratec/osm/result/dao/EventResultQueryBuilder.groovy @@ -4,11 +4,9 @@ import de.iteratec.osm.csi.Page import de.iteratec.osm.measurement.schedule.JobGroup import de.iteratec.osm.result.CachedView import de.iteratec.osm.result.MeasurandGroup +import de.iteratec.osm.result.PerformanceAspectType import de.iteratec.osm.result.SelectedMeasurand -import de.iteratec.osm.result.dao.query.EventResultQueryExecutor -import de.iteratec.osm.result.dao.query.MeasurandTrim -import de.iteratec.osm.result.dao.query.ProjectionProperty -import de.iteratec.osm.result.dao.query.TrimQualifier +import de.iteratec.osm.result.dao.query.* import de.iteratec.osm.result.dao.query.projector.MeasurandAverageDataProjector import de.iteratec.osm.result.dao.query.projector.MeasurandRawDataProjector import de.iteratec.osm.result.dao.query.projector.UserTimingAverageDataProjector @@ -28,6 +26,7 @@ class EventResultQueryBuilder { private Set baseProjections private List trims = [] private PerformanceLoggingService performanceLoggingService + private AspectUtil aspectUtil private EventResultQueryExecutor measurandQueryExecutor = new EventResultQueryExecutor() private EventResultQueryExecutor userTimingQueryExecutor = new EventResultQueryExecutor() @@ -36,6 +35,7 @@ class EventResultQueryBuilder { performanceLoggingService = new PerformanceLoggingService() filters.add(initBaseClosure()) baseProjections = [] + aspectUtil = new AspectUtil() } private Closure initBaseClosure() { @@ -78,10 +78,12 @@ class EventResultQueryBuilder { } EventResultQueryBuilder withJobGroupIdsIn(List jobGroupIds, boolean project = true) { + this.aspectUtil.setJobGroupIds(jobGroupIds) return withAssociatedDomainIdsIn(jobGroupIds, 'jobGroup', project) } EventResultQueryBuilder withPageIdsIn(List pageIds, boolean project = true) { + this.aspectUtil.setPageIds(pageIds) return withAssociatedDomainIdsIn(pageIds, 'page', project) } @@ -98,17 +100,25 @@ class EventResultQueryBuilder { } EventResultQueryBuilder withJobGroupIn(List jobGroups, boolean project = true) { - return withAssociatedDomainIdsIn(jobGroups.collect { it.ident() }, 'jobGroup', project) + List jobGroupIds = jobGroups.collect { it.ident() } + this.aspectUtil.setJobGroupIds(jobGroupIds) + return withAssociatedDomainIdsIn(jobGroupIds, 'jobGroup', project) } EventResultQueryBuilder withPageIn(List pages, boolean project = true) { - return withAssociatedDomainIdsIn(pages.collect { it.ident() }, 'page', project) + List pageIds = pages.collect { it.ident() } + this.aspectUtil.setPageIds(pageIds) + return withAssociatedDomainIdsIn(pageIds, 'page', project) } EventResultQueryBuilder withoutPagesIn(List pages) { return withAssociatedDomainIdsNotIn(pages.collect { it.ident() }, 'page') } + EventResultQueryBuilder withPerformanceAspects(List aspectTypes) { + this.aspectUtil.setAspectTypes(aspectTypes) + } + EventResultQueryBuilder withCachedView(CachedView cachedView) { filters.add({ 'eq' 'cachedView', cachedView @@ -228,7 +238,21 @@ class EventResultQueryBuilder { return getResults() } + private getResultsWithAspects() { + + } + private getResults() { + + performanceLoggingService.logExecutionTime(PerformanceLoggingService.LogLevel.DEBUG, 'getting event-results - add missing aspect metrics', 3) { + aspectUtil.addMissingAspectMeasurands(userTimingQueryExecutor.selectedMeasurands) { SelectedMeasurand measurand -> + measurand.selectedType.isUserTiming() + } + aspectUtil.addMissingAspectMeasurands(measurandQueryExecutor.selectedMeasurands) { SelectedMeasurand measurand -> + !measurand.selectedType.isUserTiming() + } + } + List userTimingsResult = userTimingQueryExecutor.getResultFor(filters, trims, baseProjections, performanceLoggingService) List measurandResult = measurandQueryExecutor.getResultFor(filters, trims, baseProjections, performanceLoggingService) diff --git a/src/main/groovy/de/iteratec/osm/result/dao/query/AspectUtil.groovy b/src/main/groovy/de/iteratec/osm/result/dao/query/AspectUtil.groovy new file mode 100644 index 0000000000..3ce1af2e9e --- /dev/null +++ b/src/main/groovy/de/iteratec/osm/result/dao/query/AspectUtil.groovy @@ -0,0 +1,40 @@ +package de.iteratec.osm.result.dao.query + + +import de.iteratec.osm.result.PerformanceAspect +import de.iteratec.osm.result.PerformanceAspectType +import de.iteratec.osm.result.SelectedMeasurand +import de.iteratec.osm.result.dao.EventResultProjection +import groovy.transform.EqualsAndHashCode +/** + * @author nkuhn + */ +class AspectUtil { + + List jobGroupIds = [] + List pageIds = [] + List aspectTypes = [] + + void addMissingAspectMeasurands(List measurands, Closure validFn) { + getAspects().each {PerformanceAspect aspect -> + SelectedMeasurand aspectMetric = aspect.getMetric() + if (!measurands.contains(aspectMetric) && validFn(aspectMetric)) { + measurands.add(aspectMetric) + } + } + } + + List getAspects() { + if (jobGroupIds.size() == 0 || pageIds.size() == 0 || this.aspectTypes.size() == 0) return [] + return PerformanceAspect.createCriteria().list { + 'in'('jobGroup', this.jobGroupIds) + 'in'('page', this.pageIds) + 'in'('performanceAspectType', this.aspectTypes) + } + } + + void appendAspectMetrics(List metricsFromBuilder){ + + } + +} diff --git a/src/main/groovy/de/iteratec/osm/result/dao/query/EventResultQueryExecutor.groovy b/src/main/groovy/de/iteratec/osm/result/dao/query/EventResultQueryExecutor.groovy index baa23b1e8b..0c71751ed9 100644 --- a/src/main/groovy/de/iteratec/osm/result/dao/query/EventResultQueryExecutor.groovy +++ b/src/main/groovy/de/iteratec/osm/result/dao/query/EventResultQueryExecutor.groovy @@ -14,6 +14,7 @@ class EventResultQueryExecutor { private EventResultTrimmer trimmer List selectedMeasurands + void setUserTimings(List selectedMeasurands) { this.selectedMeasurands = selectedMeasurands.findAll { it.selectedType.isUserTiming() } } diff --git a/src/test/groovy/de/iteratec/osm/result/PerformanceAspectSpec.groovy b/src/test/groovy/de/iteratec/osm/result/PerformanceAspectSpec.groovy index a2c4bc0ea5..96185890a1 100644 --- a/src/test/groovy/de/iteratec/osm/result/PerformanceAspectSpec.groovy +++ b/src/test/groovy/de/iteratec/osm/result/PerformanceAspectSpec.groovy @@ -1,15 +1,17 @@ package de.iteratec.osm.result import de.iteratec.osm.csi.Page +import de.iteratec.osm.measurement.environment.Browser import de.iteratec.osm.measurement.schedule.JobGroup import grails.buildtestdata.BuildDataTest import grails.buildtestdata.mixin.Build import spock.lang.Specification -@Build([JobGroup, Page, PerformanceAspect]) +@Build([JobGroup, Page, PerformanceAspect, Browser]) class PerformanceAspectSpec extends Specification implements BuildDataTest { Page page1, page2 JobGroup jobGroup1, jobGroup2 + Browser browser1, browser2 SelectedMeasurand metric def setup() { @@ -17,6 +19,8 @@ class PerformanceAspectSpec extends Specification implements BuildDataTest { jobGroup1 = JobGroup.build() page2 = Page.build() jobGroup2 = JobGroup.build() + browser1 = Browser.build() + browser2 = Browser.build() metric = new SelectedMeasurand(Measurand.DOC_COMPLETE_TIME.name(), CachedView.CACHED) } @@ -29,21 +33,30 @@ class PerformanceAspectSpec extends Specification implements BuildDataTest { PerformanceAspect.build( page: page1, jobGroup: jobGroup1, + browser: browser1, performanceAspectType: PerformanceAspectType.PAGE_CONSTRUCTION_STARTED, metric: metric).save(flush: true) when: "a potential duplicate to the first aspect is created" - PerformanceAspect duplicateAspect = new PerformanceAspect(page: Page.findById(inputPageId), jobGroup: JobGroup.findById(inputJobGroupId), performanceAspectType: performanceAspectType, metric: metric) + PerformanceAspect duplicateAspect = new PerformanceAspect( + page: Page.findById(inputPageId), + jobGroup: JobGroup.findById(inputJobGroupId), + browser: Browser.findById(inputBrowserId), + performanceAspectType: performanceAspectType, + metric: metric) then: "its validation only fails if it is really a duplicate" duplicateAspect.validate() == valid where: "there are real duplicates and no real duplicates" - inputPageId | inputJobGroupId | performanceAspectType | valid - 1 | 1 | PerformanceAspectType.PAGE_CONSTRUCTION_STARTED | false - 2 | 1 | PerformanceAspectType.PAGE_CONSTRUCTION_STARTED | true - 1 | 2 | PerformanceAspectType.PAGE_CONSTRUCTION_STARTED | true - 1 | 1 | PerformanceAspectType.PAGE_SHOWS_USEFUL_CONTENT | true + inputPageId | inputJobGroupId | inputBrowserId | performanceAspectType || valid + 1 | 1 | 1 | PerformanceAspectType.PAGE_CONSTRUCTION_STARTED || false + 2 | 1 | 1 | PerformanceAspectType.PAGE_CONSTRUCTION_STARTED || true + 1 | 2 | 1 | PerformanceAspectType.PAGE_CONSTRUCTION_STARTED || true + 1 | 1 | 2 | PerformanceAspectType.PAGE_CONSTRUCTION_STARTED || true + 2 | 1 | 2 | PerformanceAspectType.PAGE_CONSTRUCTION_STARTED || true + 1 | 2 | 2 | PerformanceAspectType.PAGE_CONSTRUCTION_STARTED || true + 1 | 1 | 1 | PerformanceAspectType.PAGE_SHOWS_USEFUL_CONTENT || true } void "ensure metric survives database"() { @@ -51,6 +64,7 @@ class PerformanceAspectSpec extends Specification implements BuildDataTest { PerformanceAspect.build( page: page1, jobGroup: jobGroup1, + browser: browser1, performanceAspectType: PerformanceAspectType.PAGE_CONSTRUCTION_STARTED, metric: metric).save(flush: true)