Skip to content
Snippets Groups Projects
Commit 1bcc2bc8 authored by Henning's avatar Henning
Browse files

added project-config to configure the priority

parent ca6dd0b8
No related branches found
No related tags found
No related merge requests found
Showing
with 476 additions and 2 deletions
package de.fhmuenster.masterthesis.Testgenerator.rest.service.config;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import de.fhmuenster.masterthesis.Testgenerator.prioritization.PrioritizationService;
import de.fhmuenster.masterthesis.Testgenerator.rest.dto.BPMNFlowSetDTO;
import de.fhmuenster.masterthesis.Testgenerator.rest.service.project.Project;
import de.fhmuenster.masterthesis.Testgenerator.rest.service.project.ProjectService;
import de.fhmuenster.masterthesis.Testgenerator.utils.ProjectDirectoryUtils;
import de.fhmuenster.masterthesis.Testgenerator.yaml.MigrationYaml;
import de.fhmuenster.masterthesis.Testgenerator.yaml.YamlReader;
import de.fhmuenster.masterthesis.serialization.TestgeneratorDSLSerializer;
@RestController
@EnableWebMvc
public class ConfigController {
@Autowired
private ProjectService projectService;
YamlReader yamlReader = new YamlReader();
MigrationYaml yaml = yamlReader.loadMigrationYaml();
@RequestMapping(path = "/project/{projectId}/config", method = RequestMethod.GET)
public String[] getConfig(@PathVariable(required = true) Long projectId) throws IOException {
String[] priorityFormula = {
yaml.getPriority().getFormularPart0(),
yaml.getPriority().getFormularPart1(),
yaml.getPriority().getFormularPart2(),
yaml.getPriority().getFormularPart3(),
yaml.getPriority().getFormularPart4(),
yaml.getPriority().getFormularPart5(),
yaml.getPriority().getFormularPart6()
};
return priorityFormula;
}
@RequestMapping(path = "/project/{projectId}/config", method = RequestMethod.POST)
public void saveConfig(@PathVariable(required = true) Long projectId, @RequestBody List<String> arrayParams) throws IOException {
yaml.getPriority().setFormularPart0(arrayParams.get(0));
yaml.getPriority().setFormularPart1(arrayParams.get(1));
yaml.getPriority().setFormularPart2(arrayParams.get(2));
yaml.getPriority().setFormularPart3(arrayParams.get(3));
yaml.getPriority().setFormularPart4(arrayParams.get(4));
yaml.getPriority().setFormularPart5(arrayParams.get(5));
yaml.getPriority().setFormularPart6(arrayParams.get(6));
}
}
......@@ -5,6 +5,7 @@ public class MigrationYaml {
private Gateway gateway;
private Activity activity;
private Event event;
private Priority priority;
public MigrationYaml() {
......@@ -41,6 +42,14 @@ public class MigrationYaml {
public void setEvent(Event event) {
this.event = event;
}
public Priority getPriority() {
return priority;
}
public void setPriority(Priority priority) {
this.priority = priority;
}
......
package de.fhmuenster.masterthesis.Testgenerator.yaml;
public class Priority {
private String formularPart0;
private String formularPart1;
private String formularPart2;
private String formularPart3;
private String formularPart4;
private String formularPart5;
private String formularPart6;
public Priority() {
}
public String getFormularPart0() {
return formularPart0;
}
public void setFormularPart0(String formularPart0) {
this.formularPart0 = formularPart0;
}
public String getFormularPart1() {
return formularPart1;
}
public void setFormularPart1(String formularPart1) {
this.formularPart1 = formularPart1;
}
public String getFormularPart2() {
return formularPart2;
}
public void setFormularPart2(String formularPart2) {
this.formularPart2 = formularPart2;
}
public String getFormularPart3() {
return formularPart3;
}
public void setFormularPart3(String formularPart3) {
this.formularPart3 = formularPart3;
}
public String getFormularPart4() {
return formularPart4;
}
public void setFormularPart4(String formularPart4) {
this.formularPart4 = formularPart4;
}
public String getFormularPart5() {
return formularPart5;
}
public void setFormularPart5(String formularPart5) {
this.formularPart5 = formularPart5;
}
public String getFormularPart6() {
return formularPart6;
}
public void setFormularPart6(String formularPart6) {
this.formularPart6 = formularPart6;
}
}
\ No newline at end of file
......@@ -3,6 +3,14 @@ configuration:
green: 100
yellow: 200
red: 500
priority:
formularPart0: "Priority"
formularPart1: "="
formularPart2: "Flow size"
formularPart3: "+"
formularPart4: "Flow score"
formularPart5: "-"
formularPart6: "Flow dependency"
gateway:
deleteTests: true
add:
......
......@@ -19,7 +19,7 @@ import { UpdateProjectComponent } from './components/update-project/update-proje
import { PrioritizationOverviewComponent } from './prioritization-overview/prioritization-overview.component';
import { MigrationOverviewComponent } from './components/migration-overview/migration-overview.component';
import { MatchingFlowsComponent } from './components/matching-flows/matching-flows.component';
import { ProjectConfigComponent } from './components/project-config/project-config.component';
const routes: Routes = [
{ path: '', component: ProjectsComponent },
......@@ -41,6 +41,7 @@ const routes: Routes = [
{ path: 'project/:projectId/update/matchingFlows', component: MatchingFlowsComponent },
{ path: 'project/:projectId/update/prio', component: PrioritizationOverviewComponent },
{ path: 'project/:projectId/update', component: UpdateProjectComponent }, // new Update Component
{ path: 'project/:projectId/config', component: ProjectConfigComponent}, // new Project-Setting Component
{ path: 'impressum', component: ImprintComponent },
{ path: 'notfound', component: NotfoundComponent },
{ path: '**', redirectTo: 'notfound'} //has to be the last entry
......
......@@ -39,6 +39,7 @@ import { VariableConstraintsPipe } from './pipes/variable-constraints.pipe';
import {CdkAccordionModule} from '@angular/cdk/accordion';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {MatExpansionModule} from '@angular/material/expansion';
import { ProjectConfigComponent } from './components/project-config/project-config.component';
@NgModule({
declarations: [
......@@ -71,7 +72,8 @@ import {MatExpansionModule} from '@angular/material/expansion';
MatchingFlowsComponent,
FlagComponent,
VariableConstraintsPipe
VariableConstraintsPipe,
ProjectConfigComponent
],
imports: [
BrowserModule,
......
.padding-bottom {
padding-bottom: 20px;
}
.config {
position: relative;
width: 98%;
}
.config-header {
border: 10px solid #f7f7f9;
padding: 10px;
}
.saveConfig {
margin-top: 10px;
}
.dragItemBlocked {
font-size: 16px;
font-weight: 500;
}
.dragItem {
font-size: 16px;
}
.padding-last {
padding-bottom: 15px;
}
.config-header span {
font-weight: 600;
vertical-align: middle;
text-transform: uppercase;
color: #838383;
font-size: 18px;
}
.config-header i {
font-size: 16px;
}
.config-body {
padding: 10px;
background-color: #f7f7f9;
}
.alert {
margin-top: 20px;
}
.example-list {
width: 100%;
max-width: 100%;
border: solid 1px #ccc;
min-height: 60px;
display: flex;
flex-direction: row;
background: white;
border-radius: 4px;
overflow: hidden;
}
.example-box {
padding: 20px 10px;
border-right: solid 1px #ccc;
color: rgba(0, 0, 0, 0.87);
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
cursor: move;
background: white;
font-size: 14px;
flex-grow: 1;
flex-basis: 0;
}
.cdk-drag-preview {
box-sizing: border-box;
border-radius: 4px;
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
0 8px 10px 1px rgba(0, 0, 0, 0.14),
0 3px 14px 2px rgba(0, 0, 0, 0.12);
}
.cdk-drag-placeholder {
opacity: 0;
}
.cdk-drag-animating {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
.example-box:last-child {
border: none;
}
.example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder) {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
\ No newline at end of file
<div class="container bg-body rounded shadow-sm" *ngIf="!isProjectLoading && actualProjectConfig">
<div class="row">
<div class="col-md-12">
<h6 class="border-bottom pb-3 mb-0 headerTitle">
<a [routerLink]="['../']" i18n="projects header"><i class="fas fa-angle-left"></i> Back to overview</a>
</h6>
<p class="title" *ngIf="!isProjectLoading && actualProjectConfig" i18n="project header">Configuration Project "{{actualProjectConfig.projectName}}"</p>
</div>
</div>
<div class="row justify-content-md-center padding-last">
<div class="config">
<div class="config-header">
<span><i class="fas fa-cog"></i> Define the formula for calculating the test execution priority</span>
</div>
<div class="config-body">
<ul>
<li><b>Flow size:</b> Number of elements within a flow</li>
<li><b>Flow score:</b> Sum of element-flags within a flow</li>
<li><b>Flow dependency:</b> Calculated dependencies within a flow</li>
</ul>
<div cdkDropList cdkDropListOrientation="horizontal" class="example-list" (cdkDropListDropped)="drop($event)">
<ng-container *ngFor="let formulaPart of priorityFormula">
<!-- Blocked elements-->
<ng-container *ngIf="formulaPart.edit == false && formulaPart.input == false; else formularParts">
<div class="example-box" cdkDragDisabled cdkDrag >
<span class="dragItemBlocked">{{formulaPart.value}}</span>
</div>
</ng-container>
<ng-template #formularParts>
<ng-container *ngIf="formulaPart.edit == true && formulaPart.input == false; else formularOperators">
<div class="example-box" cdkDrag>
<span class="dragItem">{{formulaPart.value}}</span>
</div>
</ng-container>
</ng-template>
<ng-template #formularOperators>
<ng-container *ngIf="formulaPart.edit == false && formulaPart.input == true">
<div class="example-box" cdkDragDisabled cdkDrag>
<select class="form-select" aria-label="Default select example" (change)="onChange($event.target.value, formulaPart.name)">
<option value="{{formulaPart.value}}" selected>{{formulaPart.value}}</option>
<option *ngIf="formulaPart.value != '+'"value="+">+</option>
<option *ngIf="formulaPart.value != '-'"value="-">-</option>
<option *ngIf="formulaPart.value != '*'"value="*">*</option>
<option *ngIf="formulaPart.value != '/'"value="/">/</option>
</select>
</div>
</ng-container>
</ng-template>
</ng-container>
</div>
<div class="row lastRow">
<div class="col-md-12">
<button type="button" class="btn btn-primary saveConfig float-right" type="submit" (click)="saveConfig()">
Save configuration
<i *ngIf="configSaveSuccess == true" class="far fa-check-circle"></i>
<i *ngIf="configSaveSuccess == false" class="fas fa-times"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ProjectConfigComponent } from './project-config.component';
describe('ProjectConfigComponent', () => {
let component: ProjectConfigComponent;
let fixture: ComponentFixture<ProjectConfigComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ProjectConfigComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProjectConfigComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
import { FileService } from 'src/app/services/file.service';
import { Router, ActivatedRoute } from '@angular/router';
import { ProjectService } from 'src/app/services/project.service';
import { SingleProjectConfig } from 'src/app/models/single-project-config';
import { CdkDragDrop, moveItemInArray} from '@angular/cdk/drag-drop';
@Component({
selector: 'app-project-config',
templateUrl: './project-config.component.html',
styleUrls: ['./project-config.component.css']
})
export class ProjectConfigComponent implements OnInit {
actualProject: number;
actualProjectConfig: SingleProjectConfig;
isProjectLoading: boolean;
configSaveSuccess: boolean;
priorityFormula = [];
constructor(private projectService: ProjectService, private fileService: FileService, private router: Router, private route: ActivatedRoute) {
this.route.params.subscribe(params =>
this.actualProject = params['projectId']
)
}
drop(event: CdkDragDrop<string[]>) {
moveItemInArray(this.priorityFormula, event.previousIndex, event.currentIndex);
}
async ngOnInit() {
await this.loadProject();
}
async loadProject() {
this.isProjectLoading = true;
try {
let result = await this.projectService.getProject(this.actualProject);
let config = await this.projectService.getConfig(this.actualProject);
this.priorityFormula = [
{name: "priority", edit: false, input: false, value: config[0], type: "static"},
{name: "equals", edit: false, input: false, value: config[1], type: "static"},
{name: "flowSize", edit: true, input: false, value: config[2], type: "flowCalc"},
{name: "operator1", edit: false, input: true, value: config[3], type: "operator"},
{name: "flowScore", edit: true, input: false, value: config[4], type: "flowCalc"},
{name: "operator2", edit: false, input: true, value: config[5], type: "operator"},
{name: "flowDependency", edit: true, input: false, value: config[6], type: "flowCalc"},
];
this.actualProjectConfig = result;
} finally {
this.isProjectLoading = false;
}
}
async saveConfig() {
if(this.checkFormularSyntax())
{
let postArray = [];
this.priorityFormula.forEach(function (value) {
postArray.push(value.value);
})
this.projectService.saveConfig(this.actualProject, postArray);
this.configSaveSuccess = true;
}
else
{
this.configSaveSuccess = false;
return false;
}
}
checkFormularSyntax() {
if( this.priorityFormula[0].type == "static" &&
this.priorityFormula[1].type == "static" &&
this.priorityFormula[2].type == "flowCalc" &&
this.priorityFormula[3].type == "operator" &&
this.priorityFormula[4].type == "flowCalc" &&
this.priorityFormula[5].type == "operator" &&
this.priorityFormula[6].type == "flowCalc")
return true;
else
return false;
}
onChange(value, name) {
let index = this.priorityFormula.findIndex(( obj => obj.name == name));
this.priorityFormula[index].value = value;
}
}
......@@ -54,6 +54,14 @@
</div>
</div>
</div>
<div class="col-md-12">
<div class="card text-white bg-warning mb-3 clickable" [routerLink]="['project-config']">
<div class="card-header">Project Settings<i class="fas fa-hammer"></i></div>
<div class="card-body">
<p class="card-text">Set the project configuration ...</p>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
......@@ -41,4 +41,14 @@ export class ProjectService {
const url = `${environment.apiBaseUrl}project/${projectId}`;
return await this.http.delete<any>(url).toPromise();
}
public async getConfig(projectId: number): Promise<any> {
const url = `${environment.apiBaseUrl}project/${projectId}/config`;
return await this.http.get<any>(url).toPromise();
}
public async saveConfig(projectId: number, config:Array<String>): Promise<any> {
const url = `${environment.apiBaseUrl}project/${projectId}/config`;
return await this.http.post<any>(url, config).toPromise();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment