mirror of https://github.com/BTCPrivate/copay.git
Merge pull request #7025 from gabrielbazan7/feat/getAddrTest
Ref Receive view
This commit is contained in:
commit
094a6837f1
|
@ -27,6 +27,7 @@ import { CopayApp } from './app.component';
|
||||||
import { TabsPage } from '../pages/tabs/tabs';
|
import { TabsPage } from '../pages/tabs/tabs';
|
||||||
import { AddPage } from '../pages/add/add';
|
import { AddPage } from '../pages/add/add';
|
||||||
import { CreateWalletPage } from '../pages/add/create-wallet/create-wallet';
|
import { CreateWalletPage } from '../pages/add/create-wallet/create-wallet';
|
||||||
|
import { CopayersPage } from '../pages/copayers/copayers';
|
||||||
import { ImportWalletPage } from '../pages/add/import-wallet/import-wallet';
|
import { ImportWalletPage } from '../pages/add/import-wallet/import-wallet';
|
||||||
import { JoinWalletPage } from '../pages/add/join-wallet/join-wallet';
|
import { JoinWalletPage } from '../pages/add/join-wallet/join-wallet';
|
||||||
import { BackupRequestPage } from '../pages/onboarding/backup-request/backup-request';
|
import { BackupRequestPage } from '../pages/onboarding/backup-request/backup-request';
|
||||||
|
@ -89,6 +90,7 @@ export function createTranslateLoader(http: Http) {
|
||||||
let pages: any = [
|
let pages: any = [
|
||||||
AddPage,
|
AddPage,
|
||||||
CreateWalletPage,
|
CreateWalletPage,
|
||||||
|
CopayersPage,
|
||||||
ImportWalletPage,
|
ImportWalletPage,
|
||||||
JoinWalletPage,
|
JoinWalletPage,
|
||||||
BackupWarningPage,
|
BackupWarningPage,
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<ion-header>
|
||||||
|
<ion-navbar>
|
||||||
|
</ion-navbar>
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
<ion-content padding>
|
||||||
|
|
||||||
|
</ion-content>
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'page-copayers',
|
||||||
|
templateUrl: 'copayers.html',
|
||||||
|
})
|
||||||
|
export class CopayersPage {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +1,21 @@
|
||||||
<ion-header>
|
<ion-header>
|
||||||
<ion-navbar>
|
<ion-navbar>
|
||||||
<ion-title>{{ "Receive" | translate }}</ion-title>
|
<ion-title>{{'Receive'|translate}}</ion-title>
|
||||||
|
<ion-buttons *ngIf="showShareButton" (click)="shareAddress()" end>
|
||||||
|
<ion-icon name="share"></ion-icon>
|
||||||
|
</ion-buttons>
|
||||||
</ion-navbar>
|
</ion-navbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
||||||
<ion-content padding>
|
<ion-content>
|
||||||
<div *ngIf="wallet" class="qr-container">
|
<div ng-if="wallet && wallet.isComplete() && wallet.needsBackup" (click)="openBackupNeededModal()" class="needs-backup-container">
|
||||||
|
<div class="backup">
|
||||||
|
<ion-icon name="alert"></ion-icon>
|
||||||
|
<span translate>Wallet not backed up</span>
|
||||||
|
<ion-icon name="arrow-forward"></ion-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="wallet && wallet.isComplete()" class="qr-container">
|
||||||
<qr-code *ngIf="address" [value]="qrAddress" [level]="M" [size]="220" [foreground]="'#334'"></qr-code>
|
<qr-code *ngIf="address" [value]="qrAddress" [level]="M" [size]="220" [foreground]="'#334'"></qr-code>
|
||||||
<div>
|
<div>
|
||||||
<span>{{ address }}</span>
|
<span>{{ address }}</span>
|
||||||
|
@ -22,6 +32,21 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div *ngIf="wallet && !wallet.isComplete()" class="incomplete-wallet-container">
|
||||||
|
<div class="title">
|
||||||
|
<span translate>Incomplete wallet</span>
|
||||||
|
</div>
|
||||||
|
<div class="subtitle">
|
||||||
|
<span translate>All signing devices must be added to this multisig wallet before bitcoin addresses can be created.</span>
|
||||||
|
</div>
|
||||||
|
<button ion-button (click)="goCopayers()" translate>Open wallet</button>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="wallets" class="wallets-container" (click)="showWallets()">
|
||||||
|
<img src="assets/img/icon-wallet.svg" class="icon-wallet">
|
||||||
|
<div class="wallet-text">
|
||||||
|
<div>{{wallet.name}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div *ngIf="!wallet">
|
<div *ngIf="!wallet">
|
||||||
<ion-card>
|
<ion-card>
|
||||||
<ion-item>
|
<ion-item>
|
||||||
|
|
|
@ -1,5 +1,27 @@
|
||||||
page-receive {
|
page-receive {
|
||||||
$v-text-accent-color: #1abb9b;
|
$v-text-accent-color: #1abb9b;
|
||||||
|
.incomplete-wallet-container {
|
||||||
|
.title {
|
||||||
|
padding-top: 10%;
|
||||||
|
font-size: 25px;
|
||||||
|
color: #444;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.subtitle {
|
||||||
|
padding: 20px;
|
||||||
|
color: #444;
|
||||||
|
margin-top: 10%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.needs-backup-container {
|
||||||
|
.backup {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: orange;
|
||||||
|
color: #fff;
|
||||||
|
padding: 5px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
.qr-container {
|
.qr-container {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
@ -22,4 +44,47 @@ page-receive {
|
||||||
color: $v-text-accent-color;
|
color: $v-text-accent-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.wallets-container {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0rem;
|
||||||
|
width: 100%;
|
||||||
|
border-top: solid 1px rgb(242, 242, 242);
|
||||||
|
min-height: 78px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
img.icon-wallet {
|
||||||
|
width: 35px !important;
|
||||||
|
background-color: #647ce8;
|
||||||
|
}
|
||||||
|
.wallet-text {
|
||||||
|
padding-left: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin wallets-list {
|
||||||
|
height: 4rem;
|
||||||
|
width: 4rem;
|
||||||
|
content: " ";
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-shadow: 0px 6px 12px 0px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wallets::before {
|
||||||
|
@include wallets-list;
|
||||||
|
background: #647ce8 url('../assets/img/icon-wallet.svg') no-repeat 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-sheet-container {
|
||||||
|
.action-sheet-button {
|
||||||
|
display: flex;
|
||||||
|
justify-content: baseline;
|
||||||
|
align-items: center;
|
||||||
|
padding: 2.5rem;
|
||||||
|
.button-inner {
|
||||||
|
padding-left: 5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,18 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { NavController, NavParams } from 'ionic-angular';
|
import { NavController, NavParams, Events, ActionSheetController, ModalController } from 'ionic-angular';
|
||||||
|
|
||||||
|
//native
|
||||||
|
import { SocialSharing } from '@ionic-native/social-sharing';
|
||||||
|
|
||||||
|
//pages
|
||||||
import { AmountPage } from '../send/amount/amount';
|
import { AmountPage } from '../send/amount/amount';
|
||||||
|
import { CopayersPage } from '../copayers/copayers';
|
||||||
|
import { BackupWarningModalPage } from '../backup/backup-warning-modal/backup-warning-modal';
|
||||||
|
//providers
|
||||||
import { WalletProvider } from '../../providers/wallet/wallet';
|
import { WalletProvider } from '../../providers/wallet/wallet';
|
||||||
import { ProfileProvider } from '../../providers/profile/profile';
|
import { ProfileProvider } from '../../providers/profile/profile';
|
||||||
|
import { PopupProvider } from '../../providers/popup/popup';
|
||||||
|
import { PlatformProvider } from '../../providers/platform/platform';
|
||||||
|
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
|
@ -17,12 +27,19 @@ export class ReceivePage {
|
||||||
public qrAddress: string;
|
public qrAddress: string;
|
||||||
public wallets: any;
|
public wallets: any;
|
||||||
public wallet: any;
|
public wallet: any;
|
||||||
|
public showShareButton: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private navCtrl: NavController,
|
private navCtrl: NavController,
|
||||||
private navParams: NavParams,
|
private navParams: NavParams,
|
||||||
private profileProvider: ProfileProvider,
|
private profileProvider: ProfileProvider,
|
||||||
private walletProvider: WalletProvider
|
private walletProvider: WalletProvider,
|
||||||
|
private popupProvider: PopupProvider,
|
||||||
|
private platformProvider: PlatformProvider,
|
||||||
|
private events: Events,
|
||||||
|
private actionSheetCtrl: ActionSheetController,
|
||||||
|
private socialSharing: SocialSharing,
|
||||||
|
private modalCtrl: ModalController
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +51,15 @@ export class ReceivePage {
|
||||||
this.wallets = this.profileProvider.getWallets();
|
this.wallets = this.profileProvider.getWallets();
|
||||||
this.updateQrAddress();
|
this.updateQrAddress();
|
||||||
this.onSelect(this.checkSelectedWallet(this.wallet, this.wallets));
|
this.onSelect(this.checkSelectedWallet(this.wallet, this.wallets));
|
||||||
|
this.showShareButton = this.platformProvider.isCordova;
|
||||||
|
this.events.subscribe('bwsEvent', (e, walletId, type, n) => {
|
||||||
|
// Update current address
|
||||||
|
if (this.wallet && walletId == this.wallet.id && type == 'NewIncomingTx') this.setAddress(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ionViewWillLeave() {
|
||||||
|
this.events.unsubscribe('bwsEvent');
|
||||||
}
|
}
|
||||||
|
|
||||||
private onSelect(wallet: any): any {
|
private onSelect(wallet: any): any {
|
||||||
|
@ -45,7 +71,7 @@ export class ReceivePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
private setProtocolHandler(): void {
|
private setProtocolHandler(): void {
|
||||||
this.protocolHandler = this.walletProvider.getProtocolHandler(this.wallet);
|
this.protocolHandler = this.walletProvider.getProtocolHandler(this.wallet.coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkSelectedWallet(wallet: any, wallets: any): any {
|
private checkSelectedWallet(wallet: any, wallets: any): any {
|
||||||
|
@ -62,11 +88,14 @@ export class ReceivePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
private setAddress(newAddr?: boolean): void {
|
private setAddress(newAddr?: boolean): void {
|
||||||
|
|
||||||
this.walletProvider.getAddress(this.wallet, newAddr).then((addr) => {
|
this.walletProvider.getAddress(this.wallet, newAddr).then((addr) => {
|
||||||
this.address = addr;
|
this.address = addr;
|
||||||
this.updateQrAddress();
|
this.updateQrAddress();
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.log(err);
|
if (err) {
|
||||||
|
this.popupProvider.ionicAlert(err);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,4 +103,46 @@ export class ReceivePage {
|
||||||
this.qrAddress = this.protocolHandler + ":" + this.address;
|
this.qrAddress = this.protocolHandler + ":" + this.address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public shareAddress(): void {
|
||||||
|
let protocol = 'bitcoin';
|
||||||
|
if (this.wallet.coin == 'bch') protocol += 'cash';
|
||||||
|
this.socialSharing.share(protocol + ':' + this.address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public showWallets(): void {
|
||||||
|
let buttons: Array<any> = [];
|
||||||
|
let coinClass: string = "wallets";
|
||||||
|
|
||||||
|
this.wallets.forEach((wallet, index) => {
|
||||||
|
|
||||||
|
let walletButton: Object = {
|
||||||
|
text: wallet.credentials.walletName,
|
||||||
|
cssClass: coinClass,
|
||||||
|
handler: () => {
|
||||||
|
this.onSelect(wallet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buttons.push(walletButton);
|
||||||
|
});
|
||||||
|
|
||||||
|
const actionSheet = this.actionSheetCtrl.create({
|
||||||
|
title: 'Select a wallet',
|
||||||
|
buttons: buttons
|
||||||
|
});
|
||||||
|
|
||||||
|
actionSheet.present();
|
||||||
|
}
|
||||||
|
|
||||||
|
public goCopayers(): void {
|
||||||
|
this.navCtrl.push(CopayersPage, { walletId: this.wallet.credentials.walletId });
|
||||||
|
};
|
||||||
|
|
||||||
|
public openBackupNeededModal(): void {
|
||||||
|
const myModal = this.modalCtrl.create(BackupWarningModalPage, {}, {
|
||||||
|
showBackdrop: true,
|
||||||
|
enableBackdropDismiss: true,
|
||||||
|
});
|
||||||
|
myModal.present();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
import { TestBed, async } from '@angular/core/testing';
|
||||||
|
import { HttpModule } from '@angular/http';
|
||||||
|
import { ConfigProvider } from '../config/config';
|
||||||
|
import { WalletProvider } from './wallet';
|
||||||
|
import { Logger, Level as LoggerLevel } from '@nsalaun/ng-logger';
|
||||||
|
import { BwcProvider } from '../bwc/bwc';
|
||||||
|
import { TxFormatProvider } from '../tx-format/tx-format';
|
||||||
|
import { PersistenceProvider } from '../persistence/persistence';
|
||||||
|
import { BwcErrorProvider } from '../bwc-error/bwc-error';
|
||||||
|
import { RateProvider } from '../rate/rate';
|
||||||
|
import { Filter } from '../filter/filter';
|
||||||
|
import { PopupProvider } from '../popup/popup';
|
||||||
|
import { OnGoingProcess } from '../on-going-process/on-going-process';
|
||||||
|
import { TouchIdProvider } from '../touchid/touchid';
|
||||||
|
|
||||||
|
describe('Provider: Wallet Provider', () => {
|
||||||
|
let walletProvider: WalletProvider;
|
||||||
|
|
||||||
|
class BwcProviderMock {
|
||||||
|
constructor() {
|
||||||
|
};
|
||||||
|
getErrors() {
|
||||||
|
return "error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PersistenceProviderMock {
|
||||||
|
constructor() {
|
||||||
|
};
|
||||||
|
getLastAddress(walletId: any) {
|
||||||
|
return Promise.resolve('storedAddress');
|
||||||
|
}
|
||||||
|
storeLastAddress(walletId: any, address: any) {
|
||||||
|
return Promise.resolve(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [HttpModule],
|
||||||
|
providers: [
|
||||||
|
WalletProvider,
|
||||||
|
{ provide: ConfigProvider },
|
||||||
|
{ provide: PersistenceProvider, useClass: PersistenceProviderMock },
|
||||||
|
{ provide: Logger, useValue: new Logger(LoggerLevel.DEBUG) },
|
||||||
|
{ provide: TxFormatProvider },
|
||||||
|
{ provide: BwcProvider, useClass: BwcProviderMock },
|
||||||
|
{ provide: BwcErrorProvider },
|
||||||
|
{ provide: RateProvider },
|
||||||
|
{ provide: Filter },
|
||||||
|
{ provide: PopupProvider },
|
||||||
|
{ provide: OnGoingProcess },
|
||||||
|
{ provide: TouchIdProvider },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
walletProvider = TestBed.get(WalletProvider);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Function: Get Address Function', () => {
|
||||||
|
|
||||||
|
it('should get the last address stored', () => {
|
||||||
|
let wallet = {
|
||||||
|
isComplete: function () {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let force = false;
|
||||||
|
walletProvider.getAddress(wallet, force).then((address) => {
|
||||||
|
expect(address).toEqual('storedAddress');
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should reject to generate new address if wallet is not complete', () => {
|
||||||
|
let wallet = {
|
||||||
|
isComplete: function () {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let force = true;
|
||||||
|
walletProvider.getAddress(wallet, force).catch((err) => {
|
||||||
|
expect(err).toEqual('WALLET_NOT_COMPLETE');
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should force to generate new address', () => {
|
||||||
|
let wallet = {
|
||||||
|
isComplete: function () {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
createAddress: function ({ }, cb) {
|
||||||
|
return cb(null, { address: 'newAddress' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let force = true;
|
||||||
|
walletProvider.getAddress(wallet, force).then((address) => {
|
||||||
|
expect(address).toEqual('newAddress');
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Function: Get Protocol Handler Function', () => {
|
||||||
|
|
||||||
|
it('should return bitcoincash if coin is bch', () => {
|
||||||
|
let coin = 'bch';
|
||||||
|
let protocol = walletProvider.getProtocolHandler(coin);
|
||||||
|
expect(protocol).toEqual('bitcoincash');
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return bitcoin if coin is btc', () => {
|
||||||
|
let coin = 'btc';
|
||||||
|
let protocol = walletProvider.getProtocolHandler(coin);
|
||||||
|
expect(protocol).toEqual('bitcoin');
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
|
@ -1252,8 +1252,8 @@ export class WalletProvider {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
public getProtocolHandler(wallet: any): string {
|
public getProtocolHandler(coin: string): string {
|
||||||
if (wallet.coin == 'bch') return 'bitcoincash';
|
if (coin == 'bch') return 'bitcoincash';
|
||||||
else return 'bitcoin';
|
else return 'bitcoin';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue