Skip to content

Commit

Permalink
add error status on participant form entry (hyperledger-archives#2152)
Browse files Browse the repository at this point in the history
  • Loading branch information
nklincoln authored Sep 15, 2017
1 parent 87413b8 commit 8f164f4
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@ <h1>Issue New Identity</h1>
<input required type="text" [(ngModel)]="userID" id="userID" name="userID" autocomplete="off">
</div>

<div class="justified-input">
<label class="required" for="participantFQI">Participant<abbr title="required">*</abbr></label>
<input required type="text" [(ngModel)]="participantFQI" id="participantFQI" name="participantFQI" [ngbTypeahead]="search" [resultTemplate]="participantTypeaheadResult" autocomplete="off">
<div class="keyValue">
<label class="key" for="participantFQI">Participant<abbr title="required">*</abbr></label>
<div class="value">
<input [ngClass]="{'error-underline': !isParticipant}" required type="text" [(ngModel)]="participantFQI" id="participantFQI" name="participantFQI" [ngbTypeahead]="search" [resultTemplate]="participantTypeaheadResult" autocomplete="off" (ngModelChange)="isValidParticipant()">
<div *ngIf="!isParticipant" class="error-message" style="position: absolute; top: 165px;">
{{ noMatchingParticipant }}
</div>
</div>
</div>

<div>
Expand All @@ -43,7 +48,7 @@ <h1>Issue New Identity</h1>
<button type="button" class="secondary" (click)="activeModal.close();">
<span>Cancel</span>
</button>
<button type="submit" form="issue-identity-form" class="primary" [disabled]="!issueIdentityForm.form.valid || issueInProgress">
<button type="submit" form="issue-identity-form" class="primary" [disabled]="!issueIdentityForm.form.valid || issueInProgress || !isParticipant">
<div *ngIf="!issueInProgress">
<span>Create New</span>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ issue-identity-modal {
}
}

.keyValue {
display: flex;

.key {
flex: 1;
font-weight: 700;
}

.value {
display: flex;
flex: 5;
flex-direction: column;
}
}

svg {
vertical-align: text-top;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ describe('IssueIdentityComponent', () => {
tick();

// Check we load the participants
let expected = ['resource:org.doge.Doge#DOGE_1', 'resource:org.doge.Doge#DOGE_2'];
let expected = ['org.doge.Doge#DOGE_1', 'org.doge.Doge#DOGE_2'];
component['participantFQIs'].should.deep.equal(expected);

}));
Expand Down Expand Up @@ -191,7 +191,7 @@ describe('IssueIdentityComponent', () => {

describe('#issueIdentity', () => {

it('should generate and return an identity using internally held state information', fakeAsync(() => {
it('should generate and return an identity using internally held state information with partially qualified name', fakeAsync(() => {

mockClientService.issueIdentity.returns(Promise.resolve({
participant: 'uniqueName',
Expand All @@ -206,6 +206,38 @@ describe('IssueIdentityComponent', () => {

tick();

// What was it called with
mockClientService.issueIdentity.should.have.been.calledWith('userId', 'resource:uniqueName', {issuer: false, affiliation: undefined});

// Did we return the expected result to the modal on close
let expected = {
participant: 'uniqueName',
userID: 'userId',
options: {issuer: false, affiliation: undefined}
};
mockActiveModal.close.should.be.calledWith(expected);

}));

it('should generate and return an identity using internally held state information with fully qualified name', fakeAsync(() => {

mockClientService.issueIdentity.returns(Promise.resolve({
participant: 'uniqueName',
userID: 'userId',
options: {issuer: false, affiliation: undefined}
}));

component['participantFQI'] = 'resource:uniqueName';
component['userID'] = 'userId';

component['issueIdentity']();

tick();

// What was it called with
mockClientService.issueIdentity.should.have.been.calledWith('userId', 'resource:uniqueName', {issuer: false, affiliation: undefined});

// Did we return the expected result to the modal on close
let expected = {
participant: 'uniqueName',
userID: 'userId',
Expand All @@ -217,6 +249,9 @@ describe('IssueIdentityComponent', () => {

it('should dismiss modal and pass error on failure', fakeAsync(() => {
mockClientService.issueIdentity.returns(Promise.reject('some error'));

component['participantFQI'] = 'uniqueName';

component['issueIdentity']();

tick();
Expand All @@ -225,6 +260,63 @@ describe('IssueIdentityComponent', () => {
}));
});

describe('#isValidParticipant', () => {

it('should set valid if empty string', () => {
component['participantFQI'] = '';
component['isParticipant'] = false;

component.isValidParticipant();

component['isParticipant'].should.be.true;
});

it('should set valid if particpant exists when prepended with `resource:`', () => {
let p1 = new Resource('resource1');
let p2 = new Resource('resource2');
component['participants'].set('bob', p1);
component['participants'].set('sally', p2);

component['participantFQI'] = 'resource:bob';

component['isParticipant'] = false;

component.isValidParticipant();

component['isParticipant'].should.be.true;

});

it('should set valid if particpant exists when not prepended with `resource:`', () => {
let p1 = new Resource('resource1');
let p2 = new Resource('resource2');
component['participants'].set('bob', p1);
component['participants'].set('sally', p2);

component['participantFQI'] = 'sally';

component['isParticipant'] = false;

component.isValidParticipant();

component['isParticipant'].should.be.true;

});

it('should set invalid if not empty string and participant does not exist', () => {
component['participantFQI'] = 'not-person';
let mockGet = sinon.stub(component, 'getParticipant');
mockGet.returns(false);

component['isParticipant'] = true;

component.isValidParticipant();

component['isParticipant'].should.be.false;
});

});

describe('#getParticipant', () => {
it('should get the specified participant', () => {
let mockParticipant1 = sinon.createStubInstance(Resource);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export class IssueIdentityComponent implements OnInit {
private participantFQIs: string[] = [];
private participants: Map<string, Resource> = new Map<string, Resource>();
private issuer: boolean = false;
private isParticipant: boolean = true;
private noMatchingParticipant = 'Named Participant does not exist in Participant Registry.';

constructor(private activeModal: NgbActiveModal,
private alertService: AlertService,
Expand Down Expand Up @@ -52,7 +54,7 @@ export class IssueIdentityComponent implements OnInit {
})
.then((allParticipants) => {
return Promise.all(allParticipants.map((registryParticipant) => {
return this.participants.set('resource:' + registryParticipant.getFullyQualifiedIdentifier(), registryParticipant);
return this.participants.set(registryParticipant.getFullyQualifiedIdentifier(), registryParticipant);
}));
})
.then(() => {
Expand All @@ -72,11 +74,11 @@ export class IssueIdentityComponent implements OnInit {
.map((term) => term === '' ? []
: this.participantFQIs.filter((v) => new RegExp(term, 'gi').test(v)).slice(0, 10));

private issueIdentity(): void {
issueIdentity(): void {
this.issueInProgress = true;

let options = {issuer: this.issuer, affiliation: undefined};
this.clientService.issueIdentity(this.userID, this.participantFQI, options)
let participant = this.participantFQI.startsWith('resource:') ? this.participantFQI : 'resource:' + this.participantFQI;
this.clientService.issueIdentity(this.userID, participant, options)
.then((identity) => {
this.issueInProgress = false;
this.activeModal.close(identity);
Expand All @@ -87,7 +89,16 @@ export class IssueIdentityComponent implements OnInit {
});
}

private getParticipant(fqi: string): any {
isValidParticipant() {
let participant = this.participantFQI.startsWith('resource:') ? this.participantFQI.slice(9) : this.participantFQI;
if (this.participantFQI === '' || this.getParticipant(participant)) {
this.isParticipant = true;
} else {
this.isParticipant = false;
}
}

getParticipant(fqi: string): any {
return this.participants.get(fqi);
}
}

0 comments on commit 8f164f4

Please sign in to comment.