Skip to content
This repository has been archived by the owner on Apr 4, 2022. It is now read-only.

Commit

Permalink
Merge 2a9ea31 into d42812c
Browse files Browse the repository at this point in the history
  • Loading branch information
tboeckmann committed Aug 13, 2019
2 parents d42812c + 2a9ea31 commit 3c22549
Show file tree
Hide file tree
Showing 16 changed files with 1,447 additions and 61 deletions.
121 changes: 91 additions & 30 deletions src/app/inbox/inbox-compose/inbox-compose.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,107 @@ <h4>Compose <span class="fw-semi-bold">New</span></h4>

<form #mailForm="ngForm" id="message-compose" (ngSubmit)="onSubmit()" autocomplete="off">

<div class="form-group">
<label for="from">From:</label>
<select class="form-control" [(ngModel)]="model.from" name="from">
<option *ngFor="let address of fromAddresses; let i = index" [value]="address">
{{address}}
</option>
</select>
<!-- From Field -->
<div class="form-group row">
<label for="from" class="col-form-label col-sm-2 col-md- col-lg-2">From:</label>
<div class="col-md-10 col-lg-9">
<div class="input-group mb-2 row">
<div class="input-group-prepend">
<div class="input-group-text p-0">
<img class="rounded-circle addressIcon" src={{generateIdenticon(model.from)}} alt="">
</div>
</div>
<select class="form-control" [(ngModel)]="model.from" name="from">
<option *ngFor="let address of fromAddresses; let i = index" [value]="address">
{{address}}
</option>
</select>
</div>
</div>
</div>

<div class="form-group">
<label for="to">To:</label>
<input type="text" id="messageTo" placeholder="To" [(ngModel)]="model.to" name="to" class="input-transparent form-control" placeholder="e.g. 0x0000000...">
</div>
<!-- ./From Field -->


<!-- To Field -->
<div class="form-group">
<label for="subject">Subject:</label>
<input type="text" id="messageSubject" placeholder="Subject" [(ngModel)]="model.subject" name="subject" class="input-transparent form-control">
<div class="row">
<label for="to" class="col-form-label col-sm-2 col-md- col-lg-2">To:</label>
<div class="col-md-10 col-lg-9">
<div class="input-group row">
<div class="input-group-prepend">
<div class="input-group-text p-0">
<img class="rounded-circle addressIcon" src={{generateIdenticon(model.to)}} alt="">
</div>
</div>
<input type="text" id="messageTo" placeholder="To" name="to" class="form-control " placeholder="e.g. 0x0000...0000 or mailchain.eth" [(ngModel)]="messageToField" (keyup)="recipientResolve($event)">
</div>
</div>
</div>

<div class="row">
<div class="col-md-10 col-lg-9 offset-md-2 offset-sm-0">
<div class="row pl-2">
<p>
<i class="{{recipientLoadingIcon}}"></i>&nbsp;
<span>{{recipientLoadingText | titlecase}}</span>&nbsp;
<span *ngIf="currentRecipientValue != model.to">{{model.to}}</span>
</p>
</div>
</div>
</div>

</div>
<!-- ./To Field -->

<!-- Subject Field -->
<div class="form-group row">

<label for="subject" class="col-form-label col-sm-2 col-md- col-lg-2">Subject:</label>

<div class="col-md-10 col-lg-9">
<div class="input-group mb-2 row">
<input type="text" id="messageSubject" placeholder="Subject" [(ngModel)]="model.subject" name="subject" class="form-control">
</div>
</div>

<div class="form-group">
<textarea class="form-control courier" id="messageBody"
[(ngModel)]="model.body"
(keydown.enter)="supressEnterPropagation($event)"
name="body"
rows="18"
></textarea>
</div>
<!-- ./Subject Field -->

<!-- Body Field -->
<div class="form-group row">
<div class="col-md-10 col-lg-9 offset-md-2 offset-sm-0">
<div class="input-group mb-2 row">

<textarea class="form-control courier" id="messageBody"
[(ngModel)]="model.body"
(keydown.enter)="supressEnterPropagation($event)"
name="body"
rows="18"
></textarea>

<div class="clearfix">
<div class="btn-toolbar pull-right">
<div class="btn-group mr-2">
<button type="reset" class="btn btn-outline-secondary" (click)="returnToMessage()">Discard</button>
</div>
<div class="btn-group mr-2">
<button
type="submit"
class="btn btn-danger"
[disabled]="sendMessagesDisabled"
>&nbsp;&nbsp;&nbsp;Send&nbsp;&nbsp;&nbsp;</button>
</div>
</div>
<!-- ./Body Field -->

<!-- <div class="clearfix"> -->
<div class="form-group row">
<div class="col-md-10 col-lg-9 offset-md-2 offset-sm-0">

<div class="float-right mt-2 mr-3">
<div class="btn-group mr-2">
<button type="reset" class="btn btn-outline-secondary" (click)="returnToMessage()">Discard</button>
</div>
<div class="btn-group">
<button
type="submit"
class="btn btn-danger"
[disabled]="sendMessagesDisabled"
>&nbsp;&nbsp;&nbsp;Send&nbsp;&nbsp;&nbsp;</button>
</div>
</div>

</div>
</div>
</form>
Expand Down
14 changes: 14 additions & 0 deletions src/app/inbox/inbox-compose/inbox-compose.component.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
.courier {
font-family: 'Courier New', Courier, monospace
}

.addressIcon{
width: 100%;
max-width: 32px;
}

.compose-form {
max-width: 950px;
}

.address-box {
padding-top: 5px;
padding-bottom: 5px;
}
165 changes: 165 additions & 0 deletions src/app/inbox/inbox-compose/inbox-compose.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { RouterTestingModule } from '@angular/router/testing';
import { SendService } from 'src/app/services/mailchain/messages/send.service';
import { OutboundMail } from 'src/app/models/outbound-mail';
import { MailchainService } from 'src/app/services/mailchain/mailchain.service';
import { NameserviceService } from 'src/app/services/mailchain/nameservice/nameservice.service';

describe('InboxComposeComponent', () => {
let component: InboxComposeComponent;
Expand All @@ -21,9 +22,11 @@ describe('InboxComposeComponent', () => {
let publicKeyService: PublicKeyService
let sendService : SendService
let mailchainService: MailchainService
let nameserviceService: NameserviceService

const currentAccount = '0x0123456789012345678901234567890123456789';
const currentAccount2 = '0x0123456789abcdef0123456789abcdef01234567';
const ensName = 'mailchain.eth';
const addresses = [currentAccount, currentAccount2];

class AddressesServiceStub {
Expand All @@ -41,6 +44,13 @@ describe('InboxComposeComponent', () => {
return of([])
}
}
class NameserviceServiceStub {
resolveName(value) {
return of(
{ body: { address: currentAccount } }
)
}
}


beforeEach(async(() => {
Expand All @@ -54,6 +64,7 @@ describe('InboxComposeComponent', () => {
{ provide: AddressesService, useClass: AddressesServiceStub },
{ provide: PublicKeyService, useClass: PublicKeyServiceStub },
{ provide: SendService, useClass: SendServiceStub },
{ provide: NameserviceService, useClass: NameserviceServiceStub },

],
imports: [
Expand All @@ -67,6 +78,7 @@ describe('InboxComposeComponent', () => {
publicKeyService = TestBed.get(PublicKeyService);
sendService = TestBed.get(SendService);
mailchainService = TestBed.get(MailchainService);
nameserviceService = TestBed.get(NameserviceService);

}));

Expand Down Expand Up @@ -152,6 +164,159 @@ describe('InboxComposeComponent', () => {
});
});
});

describe('recipientResolve', () => {
it('should clear the recipientLoadingIcon if the event target value is empty', ()=>{
let event = {target: { value: "" } }
spyOn(component,'setRecipientLoadingIcon').and.callThrough()

component.recipientResolve(event)
expect(component.setRecipientLoadingIcon).toHaveBeenCalledWith('clear')
expect(component.recipientLoadingIcon).toEqual("")
})
it('should clear the setRecipientLoadingText if the event target value is empty', ()=>{
let event = {target: { value: "" } }
spyOn(component,'setRecipientLoadingText').and.callThrough()

component.recipientResolve(event)
expect(component.setRecipientLoadingText).toHaveBeenCalled()
expect(component.recipientLoadingText).toEqual("")
})
it('should reset the model.to field if the event target value is empty', ()=>{
let event = {target: { value: "" } }
spyOn(component,'resetModelToField').and.callThrough()

component.recipientResolve(event)
expect(component.resetModelToField).toHaveBeenCalled()
expect(component.model.to).toEqual("")
})

it('should set the recipientLoadingIcon to loading if the event target value is different to the currentRecipientValue', ()=>{
let event = {target: { value: "alice.eth" } }
spyOn(component,'setRecipientLoadingIcon').and.callThrough()
component.currentRecipientValue = "bob.eth"

component.recipientResolve(event)
expect(component.setRecipientLoadingIcon).toHaveBeenCalledWith('loading')
expect(component.recipientLoadingIcon).not.toEqual("")
})
it('should clear the setRecipientLoadingText if the event target value is empty', ()=>{
let event = {target: { value: "alice.eth" } }
spyOn(component,'setRecipientLoadingText').and.callThrough()
component.currentRecipientValue = "bob.eth"

component.recipientResolve(event)
expect(component.setRecipientLoadingText).toHaveBeenCalled()
expect(component.recipientLoadingText).toEqual("")
})
it('should reset the model.to field if the event target value is empty', ()=>{
let event = {target: { value: "alice.eth" } }
spyOn(component,'resetModelToField').and.callThrough()
component.currentRecipientValue = "bob.eth"

component.recipientResolve(event)
expect(component.resetModelToField).toHaveBeenCalled()
expect(component.model.to).toEqual("")
})
it('should set the currentRecipientValue to event target value when given a name-like value', ()=>{
let event = {target: { value: "alice.eth" } }

component.recipientResolve(event)
expect(component.currentRecipientValue).toEqual("alice.eth")
})
xit('should call the resolveAddress thru the private recipientAddressChanged subscription next function with the event.target.value', ()=>{
let event = {target: { value: "alice.eth" } }
spyOn(component,'resolveAddress').and.callThrough()
// todo: track recipientAddressChanged call
})
})

describe('setRecipientLoadingIcon', () => {
it('should set the recipientLoadingIcon for variable: "loading"', ()=>{
component.recipientLoadingIcon = ""
component.setRecipientLoadingIcon('loading')
expect(component.recipientLoadingIcon).toBe ("fa fa-spinner fa-pulse")
})
it('should set the recipientLoadingIcon for variable: "valid"', ()=>{
component.recipientLoadingIcon = ""
component.setRecipientLoadingIcon('valid')
expect(component.recipientLoadingIcon).toBe ("fa fa-check-circle text-success")
})
it('should set the recipientLoadingIcon for variable: "invalid"', ()=>{
component.recipientLoadingIcon = ""
component.setRecipientLoadingIcon('invalid')
expect(component.recipientLoadingIcon).toBe ("fa fa-times-circle text-danger")
})
it('should set the recipientLoadingIcon for variable: "clear"', ()=>{
component.recipientLoadingIcon = ""
component.setRecipientLoadingIcon('clear')
expect(component.recipientLoadingIcon).toBe ("")
})
})

describe('setRecipientLoadingText', () => {
it('should set the text to the input value', ()=>{
component.setRecipientLoadingText("My message")
expect(component.recipientLoadingText).toEqual("My message")
})
it('should set the text to empty when no value is provided', ()=>{
component.setRecipientLoadingText()
expect(component.recipientLoadingText).toEqual("")
})
})

describe('setupRecipientAddressLookupSubscription', () => {
xit('should ', ()=>{
// todo: needs help
})
})

describe('resetModelToField', () => {
it('should reset the model.to field', ()=>{
component.model.to = "0x0000000"
component.resetModelToField()
expect(component.model.to).toEqual("")
})
})

describe('resolveAddress', () => {
it('should call nameserviceService.resolveName if given a name-like value', ()=>{
spyOn(nameserviceService,'resolveName').and.callThrough()
component.resolveAddress(ensName)
expect(nameserviceService.resolveName).toHaveBeenCalled()

})
it('should call nameserviceService.resolveName with params for protocol, network & name-like value', ()=>{
spyOn(nameserviceService,'resolveName').and.callThrough()
component.resolveAddress(ensName)
expect(nameserviceService.resolveName).toHaveBeenCalledWith(
component.currentProtocol,
component.currentNetwork,
ensName
)
})
it('should return an observable with body containing address hash if given a name-like value', async()=>{
let obs = await component.resolveAddress(ensName)
let expectedBody = {address: currentAccount}
obs.subscribe(res => {
expect(res['body']).toEqual(expectedBody)
})
})
it('should return an observable with body containing address hash if given an address-like value', async()=>{
let obs = await component.resolveAddress(currentAccount)
let expectedBody = {address: currentAccount}
obs.subscribe(res => {
expect(res['body']).toEqual(expectedBody)
})
})
it('should return an observable with body containing empty address hash if given a value that is not name-like or address-like', async()=>{
let obs = await component.resolveAddress('string')
let expectedBody = {address: ''}
obs.subscribe(res => {
expect(res['body']).toEqual(expectedBody)
})
})
})

describe('returnToInboxMessages', () => {
it('should call goToInboxMessages.emit() to change the view to "messages"', () => {
Expand Down
Loading

0 comments on commit 3c22549

Please sign in to comment.