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

FIX: Delete Value UI Bug #171

Merged
merged 13 commits into from Sep 14, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion e2e/src/app.e2e-spec.ts
Expand Up @@ -37,7 +37,7 @@ describe('Test App', () => {

await page.navigateTo('modify');

const valueEleComp: WebElement = await page.getComponentBySelector('dsp-int-value', timeout);
let valueEleComp: WebElement = await page.getComponentBySelector('dsp-int-value', timeout);

const displayEditComp: WebElement = await page.getDisplayEditComponentFromValueComponent(valueEleComp);

Expand All @@ -64,6 +64,8 @@ describe('Test App', () => {
await browser.wait(EC.presenceOf(element(by.css('.rm-value'))), timeout,
'Wait for read value to be visible.');

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a comment that this is necessary because the DOM element has been re-created

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added in 4768a6b

valueEleComp = await page.getComponentBySelector('dsp-int-value', timeout);

const readEle = await page.getReadValueFieldFromValueComponent(valueEleComp);
expect(await readEle.getText()).toEqual('3');

Expand Down
Expand Up @@ -19,7 +19,7 @@ import {
import { of, throwError } from 'rxjs';
import { AjaxError } from 'rxjs/ajax';
import { DspApiConnectionToken } from '../../../core';
import { EmitEvent, Events, ValueOperationEventService } from '../../services/value-operation-event.service';
import { EmitEvent, Events, ValueOperationEventService, EventValues } from '../../services/value-operation-event.service';
import { AddValueComponent } from './add-value.component';


Expand Down Expand Up @@ -283,7 +283,7 @@ describe('AddValueComponent', () => {
expect(valuesSpy.v2.values.getValue).toHaveBeenCalledWith(testHostComponent.readResource.id, 'uuid');

expect(valueEventSpy.emit).toHaveBeenCalledTimes(1);
expect(valueEventSpy.emit).toHaveBeenCalledWith(new EmitEvent(Events.ValueAdded, newReadValue));
expect(valueEventSpy.emit).toHaveBeenCalledWith(new EmitEvent(Events.ValueAdded, new EventValues(newReadValue)));

});

Expand Down
Expand Up @@ -18,7 +18,7 @@ import {
} from '@dasch-swiss/dsp-js';
import { mergeMap } from 'rxjs/operators';
import { DspApiConnectionToken } from '../../../core/core.module';
import { EmitEvent, Events, ValueOperationEventService } from '../../services/value-operation-event.service';
import { EmitEvent, Events, EventValues, ValueOperationEventService } from '../../services/value-operation-event.service';
import { ValueTypeService } from '../../services/value-type.service';
import { BaseValueComponent } from '../../values/base-value.component';

Expand Down Expand Up @@ -110,7 +110,8 @@ export class AddValueComponent implements OnInit, AfterViewInit {
// emit a ValueAdded event to the listeners in:
// property-view component to hide the add value form
// resource-view component to trigger a refresh of the resource
this._valueOperationEventService.emit(new EmitEvent(Events.ValueAdded, res2.getValues(updateRes.property)[0]));
this._valueOperationEventService.emit(
new EmitEvent(Events.ValueAdded, new EventValues(res2.getValues(updateRes.property)[0])));

// hide the progress indicator
this.submittingValue = false;
Expand Down
Expand Up @@ -5,7 +5,7 @@ import { Component, Inject, Input, OnInit, ViewChild } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { MatButtonHarness } from '@angular/material/button/testing';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { MatDialogModule, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { MatDialogHarness } from '@angular/material/dialog/testing';
import { MatIconModule } from '@angular/material/icon';
import { By } from '@angular/platform-browser';
Expand Down Expand Up @@ -39,12 +39,10 @@ import {
import { of, throwError } from 'rxjs';
import { AjaxError } from 'rxjs/ajax';
import { DspApiConnectionToken } from '../../../core';
import { EmitEvent, Events, ValueOperationEventService } from '../../services/value-operation-event.service';
import { EmitEvent, Events, EventValues, ValueOperationEventService } from '../../services/value-operation-event.service';
import { ValueTypeService } from '../../services/value-type.service';
import { DisplayEditComponent } from './display-edit.component';



@Component({
selector: `dsp-text-value-as-string`,
template: ``
Expand Down Expand Up @@ -578,79 +576,88 @@ describe('DisplayEditComponent', () => {

it('should save a new version of a value', () => {

const valuesSpy = TestBed.inject(DspApiConnectionToken);
const valueEventSpy = TestBed.inject(ValueOperationEventService);

(valuesSpy.v2.values as jasmine.SpyObj<ValuesEndpointV2>).updateValue.and.callFake(
() => {
const valuesSpy = TestBed.inject(DspApiConnectionToken);

const response = new WriteValueResponse();
(valueEventSpy as jasmine.SpyObj<ValueOperationEventService>).emit.and.stub();

response.id = 'newID';
response.type = 'type';
response.uuid = 'uuid';
(valuesSpy.v2.values as jasmine.SpyObj<ValuesEndpointV2>).updateValue.and.callFake(
() => {

return of(response);
}
);
const response = new WriteValueResponse();

(valuesSpy.v2.values as jasmine.SpyObj<ValuesEndpointV2>).getValue.and.callFake(
() => {
response.id = 'newID';
response.type = 'type';
response.uuid = 'uuid';

const updatedVal = new ReadIntValue();
return of(response);
}
);

updatedVal.id = 'newID';
updatedVal.int = 1;
(valuesSpy.v2.values as jasmine.SpyObj<ValuesEndpointV2>).getValue.and.callFake(
() => {

const resource = new ReadResource();
const updatedVal = new ReadIntValue();

resource.properties = {
'http://0.0.0.0:3333/ontology/0001/anything/v2#hasInteger': [updatedVal]
};
updatedVal.id = 'newID';
updatedVal.int = 1;

return of(resource);
}
);
const resource = new ReadResource();

testHostComponent.displayEditValueComponent.canModify = true;
testHostComponent.displayEditValueComponent.editModeActive = true;
testHostComponent.displayEditValueComponent.mode = 'update';
resource.properties = {
'http://0.0.0.0:3333/ontology/0001/anything/v2#hasInteger': [updatedVal]
};

testHostComponent.displayEditValueComponent.displayValueComponent.form.controls.test.clearValidators();
testHostComponent.displayEditValueComponent.displayValueComponent.form.controls.test.updateValueAndValidity();
return of(resource);
}
);

testHostFixture.detectChanges();
testHostComponent.displayEditValueComponent.canModify = true;
testHostComponent.displayEditValueComponent.editModeActive = true;
testHostComponent.displayEditValueComponent.mode = 'update';

const saveButtonDebugElement = displayEditComponentDe.query(By.css('button.save'));
const saveButtonNativeElement = saveButtonDebugElement.nativeElement;
testHostComponent.displayEditValueComponent.displayValueComponent.form.controls.test.clearValidators();
testHostComponent.displayEditValueComponent.displayValueComponent.form.controls.test.updateValueAndValidity();

expect(saveButtonNativeElement.disabled).toBeFalsy();
testHostFixture.detectChanges();

saveButtonNativeElement.click();
const saveButtonDebugElement = displayEditComponentDe.query(By.css('button.save'));
const saveButtonNativeElement = saveButtonDebugElement.nativeElement;

testHostFixture.detectChanges();
expect(saveButtonNativeElement.disabled).toBeFalsy();

const expectedUpdateResource = new UpdateResource();
saveButtonNativeElement.click();

expectedUpdateResource.id = 'http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw';
expectedUpdateResource.type = 'http://0.0.0.0:3333/ontology/0001/anything/v2#Thing';
expectedUpdateResource.property = 'http://0.0.0.0:3333/ontology/0001/anything/v2#hasInteger';
testHostFixture.detectChanges();

const expectedUpdateVal = new UpdateIntValue();
expectedUpdateVal.id = 'http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/dJ1ES8QTQNepFKF5-EAqdg';
expectedUpdateVal.int = 1;
const expectedUpdateResource = new UpdateResource();

expectedUpdateResource.value = expectedUpdateVal;
expectedUpdateResource.id = 'http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw';
expectedUpdateResource.type = 'http://0.0.0.0:3333/ontology/0001/anything/v2#Thing';
expectedUpdateResource.property = 'http://0.0.0.0:3333/ontology/0001/anything/v2#hasInteger';

expect(valuesSpy.v2.values.updateValue).toHaveBeenCalledWith(expectedUpdateResource);
expect(valuesSpy.v2.values.updateValue).toHaveBeenCalledTimes(1);
const expectedUpdateVal = new UpdateIntValue();
expectedUpdateVal.id = 'http://rdfh.ch/0001/H6gBWUuJSuuO-CilHV8kQw/values/dJ1ES8QTQNepFKF5-EAqdg';
expectedUpdateVal.int = 1;

expectedUpdateResource.value = expectedUpdateVal;

expect(valuesSpy.v2.values.updateValue).toHaveBeenCalledWith(expectedUpdateResource);
expect(valuesSpy.v2.values.updateValue).toHaveBeenCalledTimes(1);

expect(valueEventSpy.emit).toHaveBeenCalledTimes(1);
expect(valueEventSpy.emit).toHaveBeenCalledWith(new EmitEvent(Events.ValueUpdated, new EventValues(
testHostComponent.readValue, testHostComponent.displayEditValueComponent.displayValue)));

expect(valuesSpy.v2.values.getValue).toHaveBeenCalledTimes(1);
expect(valuesSpy.v2.values.getValue).toHaveBeenCalledWith(testHostComponent.readResource.id, 'uuid');

expect(testHostComponent.displayEditValueComponent.displayValue.id).toEqual('newID');
expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue.id).toEqual('newID');
expect(testHostComponent.displayEditValueComponent.mode).toEqual('read');

expect(valuesSpy.v2.values.getValue).toHaveBeenCalledTimes(1);
expect(valuesSpy.v2.values.getValue).toHaveBeenCalledWith(testHostComponent.readResource.id,
'uuid');

expect(testHostComponent.displayEditValueComponent.displayValue.id).toEqual('newID');
expect(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue.id).toEqual('newID');
expect(testHostComponent.displayEditValueComponent.mode).toEqual('read');

});

Expand Down Expand Up @@ -743,8 +750,6 @@ describe('DisplayEditComponent', () => {
});

it('should display a comment button if the value has a comment', () => {
//console.log(testHostComponent.displayEditValueComponent.displayValueComponent.displayValue);

expect(testHostComponent.displayEditValueComponent.editModeActive).toBeFalsy();
expect(testHostComponent.displayEditValueComponent.shouldShowCommentToggle).toBeTruthy()

Expand Down Expand Up @@ -888,15 +893,6 @@ describe('DisplayEditComponent', () => {
}
);

// const deleteButtonDebugElement = displayEditComponentDe.query(By.css('button.delete'));
// const deleteButtonNativeElement = deleteButtonDebugElement.nativeElement;

// expect(deleteButtonNativeElement.disabled).toBeFalsy();

// deleteButtonNativeElement.click();

// testHostFixture.detectChanges();

const deleteButton = await rootLoader.getHarness(MatButtonHarness.with({selector: '.delete'}));
await deleteButton.click();

Expand Down Expand Up @@ -925,7 +921,7 @@ describe('DisplayEditComponent', () => {
expect(valuesSpy.v2.values.deleteValue).toHaveBeenCalledTimes(1);

expect(valueEventSpy.emit).toHaveBeenCalledTimes(1);
expect(valueEventSpy.emit).toHaveBeenCalledWith(new EmitEvent(Events.ValueDeleted, deleteVal));
expect(valueEventSpy.emit).toHaveBeenCalledWith(new EmitEvent(Events.ValueDeleted, new EventValues(deleteVal)));
});

});
Expand Down
Expand Up @@ -20,7 +20,7 @@ import {
ConfirmationDialogData
} from '../../../action/components/confirmation-dialog/confirmation-dialog.component';
import { DspApiConnectionToken } from '../../../core/core.module';
import { EmitEvent, Events, ValueOperationEventService } from '../../services/value-operation-event.service';
import { EmitEvent, Events, EventValues, ValueOperationEventService } from '../../services/value-operation-event.service';
import { ValueTypeService } from '../../services/value-type.service';
import { BaseValueComponent } from '../../values/base-value.component';

Expand Down Expand Up @@ -152,6 +152,10 @@ export class DisplayEditComponent implements OnInit {
})
).subscribe(
(res2: ReadResource) => {
this._valueOperationEventService.emit(
new EmitEvent(Events.ValueUpdated, new EventValues(
this.displayValue, res2.getValues(this.displayValue.property)[0])));

this.displayValue = res2.getValues(this.displayValue.property)[0];
this.mode = 'read';

Expand Down Expand Up @@ -220,7 +224,7 @@ export class DisplayEditComponent implements OnInit {
this._dspApiConnection.v2.values.deleteValue(updateRes as UpdateResource<DeleteValue>).pipe(
mergeMap((res: DeleteValueResponse) => {
// emit a ValueDeleted event to the listeners in resource-view component to trigger an update of the UI
this._valueOperationEventService.emit(new EmitEvent(Events.ValueDeleted, deleteVal));
this._valueOperationEventService.emit(new EmitEvent(Events.ValueDeleted, new EventValues(deleteVal)));
return res.result;
})).subscribe();
}
Expand Down
Expand Up @@ -17,29 +17,38 @@ export class ValueOperationEventService {

// Used in the listening component.
// i.e. this.valueOperationEventSubscription = this._valueOperationEventService.on(Events.ValueAdded, () => doSomething());
on(event: Events, action: (newValue) => void): Subscription {
on(event: Events, action: (newValue: any) => void): Subscription {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of any, could you use a more restrictive type annotation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in fd17180

return this._subject$
.pipe(
// Filter down based on event name to any events that are emitted out of the subject from the emit method below.
filter((e: EmitEvent) => e.name === event),
map((e: EmitEvent) => e.value)
map((e: EmitEvent) => e.value),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the comma is not required

)
.subscribe(action); // Subscribe to the subject to get the data.
}

// Used in the emitting component.
// i.e. this.valueOperationEventService.emit(new EmitEvent(Events.ValueAdded));
// i.e. this.valueOperationEventService.emit(new EmitEvent(Events.ValueAdded, new EventValues(new ReadValue()));
emit(event: EmitEvent) {
this._subject$.next(event);
}
}

export class EmitEvent {
constructor(public name: any, public value?: BaseValue) { }
constructor(public name: any, public value?: EventValues) { }
}

// Possible events that can be emitted.
export enum Events {
ValueAdded,
ValueDeleted
ValueDeleted,
ValueUpdated
}

/**
* @param currentValue the current value
* @param newValue value to update the current value with
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain why the current value would have to be updated with the new value?

*/
export class EventValues {
constructor(public currentValue: BaseValue, public newValue?: BaseValue) { }
}