Merge pull request #8082 from SonicWizard/testing

Testing
This commit is contained in:
Gabriel Edgardo Bazán 2018-02-22 09:44:07 -03:00 committed by GitHub
commit 128cb726d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 749 additions and 62 deletions

View File

@ -69,7 +69,6 @@ export class HomePage {
public showIntegration: any;
private isNW: boolean;
private isWindowsPhoneApp: boolean;
private updatingWalletId: object;
private zone: any;
@ -99,7 +98,6 @@ export class HomePage {
this.updatingWalletId = {};
this.cachedBalanceUpdateOn = '';
this.isNW = this.platformProvider.isNW;
this.isWindowsPhoneApp = this.platformProvider.isWP;
this.showReorderBtc = false;
this.showReorderBch = false;
this.zone = new NgZone({ enableLongStackTrace: false });
@ -197,10 +195,6 @@ export class HomePage {
private checkFeedbackInfo() {
this.persistenceProvider.getFeedbackInfo().then((info: any) => {
if (this.isWindowsPhoneApp) {
this.showRateCard = false;
return;
}
if (!info) {
this.initFeedBackInfo();
} else {

View File

@ -54,7 +54,6 @@ export class ConfirmPage {
// Platform info
public isCordova: boolean;
public isWindowsPhoneApp: boolean;
// custom fee flag
public usingCustomFee: boolean = false;
@ -86,7 +85,6 @@ export class ConfirmPage {
this.config = this.configProvider.get();
this.configFeeLevel = this.config.wallet.settings.feeLevel ? this.config.wallet.settings.feeLevel : 'normal';
this.isCordova = this.platformProvider.isCordova;
this.isWindowsPhoneApp = this.platformProvider.isCordova && this.platformProvider.isWP;
}
ionViewWillEnter() {
@ -253,23 +251,11 @@ export class ConfirmPage {
private setButtonText(isMultisig: boolean, isPayPro: boolean): void {
if (isPayPro) {
// if (this.isCordova && !this.isWindowsPhoneApp) {
// this.buttonText = this.translate.instant('Slide to pay');
// } else {
this.buttonText = this.translate.instant('Click to pay');
// }
} else if (isMultisig) {
// if (this.isCordova && !this.isWindowsPhoneApp) {
// this.buttonText = this.translate.instant('Slide to accept');
// } else {
this.buttonText = this.translate.instant('Click to accept');
// }
} else {
// if (this.isCordova && !this.isWindowsPhoneApp) {
// this.buttonText = this.translate.instant('Slide to send');
// } else {
this.buttonText = this.translate.instant('Click to send');
// }
}
}

View File

@ -24,7 +24,7 @@
Send feedback
</ion-item>
<ion-item *ngIf="isCordova && !isWindowsPhoneApp" (click)="openFeedbackCompletePage()">
<ion-item *ngIf="isCordova" (click)="openFeedbackCompletePage()">
<ion-icon name="ios-heart-outline" item-start></ion-icon>
Share {{ appName }}
</ion-item>

View File

@ -43,7 +43,6 @@ export class SettingsPage {
public config: any;
public selectedAlternative: any;
public isCordova: boolean;
public isWindowsPhoneApp: boolean;
public lockMethod: string;
public exchangeServices: any[] = [];
public bitpayCardEnabled: boolean = false;
@ -65,7 +64,6 @@ export class SettingsPage {
this.walletsBch = [];
this.walletsBtc = [];
this.isCordova = this.platformProvider.isCordova;
this.isWindowsPhoneApp = this.platformProvider.isWP;
}
ionViewDidLoad() {

View File

@ -42,7 +42,6 @@ export class TxpDetailsPage {
private GLIDERA_LOCK_TIME: number;
private countDown: any;
private isCordova: boolean;
private isWindowsPhoneApp: boolean;
constructor(
private navParams: NavParams,
@ -70,7 +69,6 @@ export class TxpDetailsPage {
this.currentSpendUnconfirmed = config.spendUnconfirmed;
this.loading = false;
this.isCordova = this.platformProvider.isCordova;
this.isWindowsPhoneApp = this.platformProvider.isCordova && this.platformProvider.isWP;
this.copayers = this.wallet.status.wallet.copayers;
this.copayerId = this.wallet.credentials.copayerId;
this.isShared = this.wallet.credentials.n > 1;
@ -120,18 +118,10 @@ export class TxpDetailsPage {
}).length == this.tx.requiredSignatures - 1;
if (lastSigner) {
// if (this.isCordova && !this.isWindowsPhoneApp) {
// this.buttonText = this.translate.instant('Slide to send');
// } else {
this.buttonText = this.translate.instant('Click to send');
// }
this.successText = this.translate.instant('Payment Sent');
} else {
// if (this.isCordova && !this.isWindowsPhoneApp) {
// this.buttonText = this.translate.instant('Slide to accept');
// } else {
this.buttonText = this.translate.instant('Click to accept');
// }
this.successText = this.translate.instant('Payment Accepted');
}
}

View File

@ -0,0 +1,45 @@
import { TestBed, inject, async } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { XHRBackend, Response, ResponseOptions } from '@angular/http';
import { MockBackend, MockConnection } from '@angular/http/testing';
import { AppProvider } from './app';
import { NgLoggerModule, Level } from '@nsalaun/ng-logger';
import { Logger } from '../../providers/logger/logger';
import {
TranslateModule,
TranslateService,
TranslateLoader,
TranslateFakeLoader
} from '@ngx-translate/core';
import { LanguageProvider } from '../../providers/language/language';
import { ConfigProvider } from '../../providers/config/config';
import { PersistenceProvider } from '../../providers/persistence/persistence';
import { PlatformProvider } from '../platform/platform';
import { Platform } from 'ionic-angular';
import { File } from '@ionic-native/file';
describe('AppProvider', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule,
NgLoggerModule.forRoot(Level.LOG),
TranslateModule.forRoot({
loader: { provide: TranslateLoader, useClass: TranslateFakeLoader }
})
],
providers: [
AppProvider,
Logger,
LanguageProvider,
ConfigProvider,
PersistenceProvider,
PlatformProvider,
Platform,
File,
{provide: XHRBackend, useClass: MockBackend}
]
});
});
});

View File

@ -0,0 +1,59 @@
import { TestBed, inject, async } from '@angular/core/testing';
import { NgLoggerModule, Level } from '@nsalaun/ng-logger';
import { Logger } from '../../providers/logger/logger';
import {
TranslateModule,
TranslateService,
TranslateLoader,
TranslateFakeLoader
} from '@ngx-translate/core';
import { PersistenceProvider } from '../../providers/persistence/persistence';
import { PlatformProvider } from '../platform/platform';
import { Platform } from 'ionic-angular';
import { File } from '@ionic-native/file';
import { ConfigProvider } from './config';
describe('Config Provider', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
NgLoggerModule.forRoot(Level.LOG),
TranslateModule.forRoot({
loader: { provide: TranslateLoader, useClass: TranslateFakeLoader }
})
],
providers: [
ConfigProvider,
PersistenceProvider,
PlatformProvider,
Platform,
File,
Logger
]
});
});
it('should get defaults', inject([ConfigProvider], (configProvider: ConfigProvider) => {
let defaults = configProvider.getDefaults();
expect(defaults).not.toBeNull();
}));
it('should get cache', inject([ConfigProvider], (configProvider: ConfigProvider) => {
let cache = configProvider.get();
expect(cache).not.toBeNull();
console.log('cache', cache);
}));
it('should load', inject([ConfigProvider], (configProvider: ConfigProvider) => {
configProvider.load();
}));
it('should set options with an object', inject([ConfigProvider], (configProvider: ConfigProvider) => {
let defaults = configProvider.getDefaults();
//configProvider.set(defaults);
}));
it('should set options with a string', inject([ConfigProvider], (configProvider: ConfigProvider) => {
//configProvider.set('{"option1":"a","option2":"b"}');
}));
});

View File

@ -235,7 +235,10 @@ export class ConfigProvider {
});
}
public set(newOpts: object) {
/**
* @param newOpts object or string (JSON)
*/
public set(newOpts: any) {
let config = _.cloneDeep(configDefault);
if (_.isString(newOpts)) {

View File

@ -63,8 +63,16 @@ describe('Derivation Path Helper Provider', () => {
/* Unsupported paths */
it('should fail trying to parse an unsupported derivation path', () => {
const result: any = service.parse("p/145'/0'/0'");
expect(result).toBeDefined();
expect(result).toBeFalsy;
let result: any = service.parse("p/145'/0'/0'");
expect(result).toBe(false);
result = service.parse("m/145'/0'/0'");
expect(result).toBe(false);
result = service.parse("m/44'/9'/0'");
expect(result).toBe(false);
result = service.parse("m/44'/0'/a'");
expect(result).toBe(false);
});
});

View File

@ -10,7 +10,7 @@ export class DerivationPathHelperProvider {
this.defaultTestnet = "m/44'/1'/0'";
}
parse(str: string) {
parse(str: string): any {
var arr = str.split('/');
var ret = {
derivationStrategy: '',
@ -56,4 +56,4 @@ export class DerivationPathHelperProvider {
return ret;
};
}
}

View File

@ -0,0 +1,148 @@
import { TestBed, getTestBed, inject, async } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { NgLoggerModule, Level } from '@nsalaun/ng-logger';
import { Logger } from '../../providers/logger/logger';
import {
TranslateModule,
TranslateService,
TranslateLoader,
TranslateFakeLoader
} from '@ngx-translate/core';
import { Platform } from 'ionic-angular';
fdescribe('LoggerProvider', () => {
let injector: TestBed;
let service: Logger;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule,
NgLoggerModule.forRoot(Level.LOG),
TranslateModule.forRoot({
loader: { provide: TranslateLoader, useClass: TranslateFakeLoader }
})
],
providers: [
Logger,
Platform
]
});
injector = getTestBed();
service = injector.get(Logger);
httpMock = injector.get(HttpTestingController);
});
it('should be able use optional params for errors', () => {
service.error('So long and thanks for all the fish!', 'dolphins', 'mice', 'humans');
});
it('should be able use optional params for debug', () => {
service.debug('The answer to life, the universe, and everything is 42.', 'dolphins', 'mice', 'humans');
});
it('should be able use optional params for warnings', () => {
service.warn('Mostly harmless', 'dolphins', 'mice', 'humans');
});
it('should be able use optional params for info', () => {
service.info("Who's going to dinner at the restaurant at the end of the universe?", 'Arthur', 'Zaphod', 'Trillian');
});
it('should get levels', () => {
const levels = service.getLevels();
expect(levels).toEqual([
{ level: 'error', weight: 1, label: 'Error' },
{ level: 'warn', weight: 2, label: 'Warning' },
{ level: 'info', weight: 3, label: 'Info', default: true },
{ level: 'debug', weight: 4, label: 'Debug' }
]);
});
it('should get weight', () => {
let weight = service.getWeight(1);
expect(weight).toEqual(
{ level: 'error', weight: 1, label: 'Error' }
);
weight = service.getWeight(2);
expect(weight).toEqual(
{ level: 'warn', weight: 2, label: 'Warning' }
);
weight = service.getWeight(3);
expect(weight).toEqual(
{ level: 'info', weight: 3, label: 'Info', default: true }
);
weight = service.getWeight(4);
expect(weight).toEqual(
{ level: 'debug', weight: 4, label: 'Debug' }
);
});
it('should get the defaul weight', () => {
let defaultWeight = service.getDefaultWeight();
expect(defaultWeight).toEqual(
{ level: 'info', weight: 3, label: 'Info', default: true }
);
});
it('should get logs by filtered weight', () => {
let filteredLogs;
service.debug('Heart of Gold');
service.debug('Volgon ship');
filteredLogs = service.get(4);
expect(filteredLogs.length).toBe(2);
service.info("Don't panic");
service.info("Take peanuts");
service.info("Don't forget a towel");
filteredLogs = service.get(3);
expect(filteredLogs.length).toBe(3);
console.log(filteredLogs);
service.error('Planet not found');
filteredLogs = service.get(1);
expect(filteredLogs.length).toBe(1);
});
it('should get logs when not filtered by weight', () => {
service.warn('Beware the Bugblatter Beast of Traal');
service.error('Heart of Gold has been stolen');
service.info('Zaphod is President');
service.debug('Marvin is depressed');
let logs = service.get();
expect(logs[0].msg).toEqual('Beware the Bugblatter Beast of Traal');
expect(logs[1].msg).toEqual('Heart of Gold has been stolen');
expect(logs[2].msg).toEqual('Zaphod is President');
expect(logs[3].msg).toEqual('Marvin is depressed');
});
it('should process args', () => {
let processedArgs = service.processingArgs(['bulldozer', 'bathrobe', 'satchel']);
expect(processedArgs).toEqual('bulldozer bathrobe satchel');
processedArgs = service.processingArgs('babel fish');
expect(processedArgs).toEqual('b a b e l f i s h');
processedArgs = service.processingArgs(['babel', undefined, 'fish']);
expect(processedArgs).toEqual('babel undefined fish');
processedArgs = service.processingArgs(['babel', false, 'fish']);
expect(processedArgs).toEqual('babel null fish');
processedArgs = service.processingArgs(['babel', { message: 'Save the Humans' }, 'fish']);
expect(processedArgs).toEqual('babel Save the Humans fish');
processedArgs = service.processingArgs(['babel', { 'improbability': 'infinite' }, 'fish']);
expect(processedArgs).toEqual('babel {"improbability":"infinite"} fish');
// cyclical reference; yeah, baby! to break JSON.stringify
let a = { b: { a: { } } };
a.b.a = a;
processedArgs = service.processingArgs(['babel', a, 'fish']);
expect(processedArgs).toEqual('babel undefined fish');
});
});

View File

@ -50,7 +50,7 @@ export class Logger {
this.add('warn', args);
}
public getLevels(): void {
public getLevels(): any {
return this.levels;
}
@ -75,6 +75,10 @@ export class Logger {
});
}
/**
* Returns logs of <= to filteredWeight
* @param {number} filteredWeight Weight (1-4) to use when filtering logs. optional
*/
public get(filterWeight?: number): any {
let filteredLogs = this.logs;
if (filterWeight != undefined) {

View File

@ -39,6 +39,43 @@ describe('Persistence Provider', () => {
expect(persistenceProvider.storage.constructor.name).toBe('FileStorage');
});
});
describe('without local storage', () => {
let localStorageBackup;
beforeEach(() => {
// remove window.localStorage
localStorageBackup = window.localStorage;
console.log('before clearing', window.localStorage);
Object.defineProperties(window, {
localStorage: {
value: null,
writable: true
}
});
console.log('after clearing', window.localStorage);
});
afterEach(() => {
// restore window.localStorage
console.log('before restoring', window.localStorage);
Object.defineProperties(window, {
localStorage: {
value: localStorageBackup,
writable: false
}
});
console.log('after restoring', window.localStorage);
});
it('should throw an error if local storage is not available', () => {
expect(() => {
platformMock.isCordova = false;
createAndLoad();
} ).toThrow(new Error('localstorage not available'));
});
});
describe('When platform is not Cordova', () => {
beforeEach(() => {
platformMock.isCordova = false;
@ -73,5 +110,24 @@ describe('Persistence Provider', () => {
expect(err.message).toEqual('Key already exists');
});
});
it('should be able to delete a profile', (done) => {
let p = { name: 'My profile' };
persistenceProvider
.storeNewProfile(p)
.catch(err => expect(err).toBeNull)
.then(() => {
return persistenceProvider.getProfile();
})
.then(profile => {
expect(typeof profile).toEqual('object');
expect(profile.name).toEqual('My profile');
return persistenceProvider.deleteProfile();
}).then(() => {
return persistenceProvider.getProfile();
}).then(profile => {
expect(profile).toBeNull();
}).then(done);
});
});
});

View File

@ -0,0 +1,127 @@
import { PlatformProvider } from './platform';
import { TestBed, getTestBed, inject, async } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { NgLoggerModule, Level } from '@nsalaun/ng-logger';
import { Logger } from '../../providers/logger/logger';
import {
TranslateModule,
TranslateService,
TranslateLoader,
TranslateFakeLoader
} from '@ngx-translate/core';
import { Platform } from 'ionic-angular';
describe('PlatformProvider', () => {
let injector: TestBed;
let service: PlatformProvider;
let httpMock: HttpTestingController;
let userAgent;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule,
NgLoggerModule.forRoot(Level.LOG),
TranslateModule.forRoot({
loader: { provide: TranslateLoader, useClass: TranslateFakeLoader }
})
],
providers: [
PlatformProvider,
Logger,
Platform
]
});
injector = getTestBed();
service = injector.get(PlatformProvider);
httpMock = injector.get(HttpTestingController);
});
it('should get browser name', () => {
let name = service.getBrowserName();
expect(name).toBe('chrome');
});
it('should return "unknown" if browser is unknown', () => {
// change userAgent
userAgent = window.navigator.userAgent;
console.log('before changing userAgent', window.navigator.userAgent);
Object.defineProperties(window.navigator, {
userAgent: {
value: 'someUnknownCoolBrowser v1.0',
writable: true
}
});
console.log('after changing userAgent', window.navigator.userAgent);
let name = service.getBrowserName();
expect(name).toBe('unknown');
// restore userAgent
console.log('before restoring userAgent', window.navigator.userAgent);
Object.defineProperties(window.navigator, {
userAgent: {
value: userAgent,
writable: false
}
});
console.log('after restoring userAgent', window.navigator.userAgent);
});
});
describe('PlatformProvider without navigator', () => {
let injector: TestBed;
let service: PlatformProvider;
let httpMock: HttpTestingController;
let navi;
beforeEach(() => {
navi = window.navigator;
console.log('before changing navigator', window.navigator);
// change navigator
Object.defineProperties(window, {
navigator: {
value: null,
writable: true
}
});
console.log('after changing navigator', window.navigator);
});
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule,
NgLoggerModule.forRoot(Level.LOG),
TranslateModule.forRoot({
loader: { provide: TranslateLoader, useClass: TranslateFakeLoader }
})
],
providers: [
PlatformProvider,
Logger,
Platform
]
});
injector = getTestBed();
service = injector.get(PlatformProvider);
httpMock = injector.get(HttpTestingController);
});
afterEach(() => {
console.log('before restoring navigator', window.navigator);
Object.defineProperties(window, {
navigator: {
value: navi,
writable: false
}
});
console.log('after restoring navigator', window.navigator);
});
it('should have a dummy user agent', () => {
let ua = service.ua;
expect(ua).toBe('dummy user-agent');
});
});

View File

@ -6,7 +6,6 @@ import { Platform } from 'ionic-angular';
export class PlatformProvider {
public isAndroid: boolean;
public isIOS: boolean;
public isWP: boolean;
public isSafari: boolean;
public isCordova: boolean;
public isNW: boolean;
@ -30,7 +29,6 @@ export class PlatformProvider {
this.isAndroid = this.platform.is('android');
this.isIOS = this.platform.is('ios');
this.isWP = this.platform.is('windows') && this.platform.is('mobile');
this.ua = ua;
this.isCordova = this.platform.is('cordova');
this.isNW = this.isNodeWebkit();
@ -54,13 +52,10 @@ export class PlatformProvider {
}
public isNodeWebkit(): boolean {
let isNode = (typeof process !== "undefined" && typeof require !== "undefined");
if (isNode) {
try {
return (typeof require('nw.gui') !== "undefined");
} catch (e) {
return false;
}
try {
return (typeof require('nw.gui') !== "undefined");
} catch (e) {
return false;
}
}
}

View File

@ -0,0 +1,48 @@
import { TestBed, inject, async } from '@angular/core/testing';
import {
AlertController,
App,
Config,
Platform
} from 'ionic-angular';
import { NgLoggerModule, Level } from '@nsalaun/ng-logger';
import { Logger } from '../../providers/logger/logger';
import {
TranslateModule,
TranslateService,
TranslateLoader,
TranslateFakeLoader
} from '@ngx-translate/core';
import { PopupProvider } from './popup';
describe('PopupProvider', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
NgLoggerModule.forRoot(Level.LOG),
TranslateModule.forRoot({
loader: { provide: TranslateLoader, useClass: TranslateFakeLoader }
})
],
providers: [
PopupProvider,
AlertController,
App,
Config,
Platform,
Logger,
TranslateService
]
});
});
it('should exist', inject([PopupProvider], (popupProvider: PopupProvider) => {
expect(popupProvider).not.toBeUndefined();
}));
it('should have an alert', inject([PopupProvider], (popupProvider: PopupProvider) => {
spyOn(popupProvider, 'ionicAlert');
popupProvider.ionicAlert('title', 'subtitle', 'ok text');
expect(popupProvider.ionicAlert).toHaveBeenCalledWith('title', 'subtitle', 'ok text');
}));
});

View File

@ -39,7 +39,7 @@ export class PushNotificationsProvider {
this.logger.info('PushNotificationsProvider initialized.');
this.isIOS = this.platformProvider.isIOS;
this.isAndroid = this.platformProvider.isAndroid;
this.usePushNotifications = this.platformProvider.isCordova && !this.platformProvider.isWP;
this.usePushNotifications = this.platformProvider.isCordova;
if (this.usePushNotifications) {

View File

@ -0,0 +1,215 @@
import { TestBed, getTestBed, inject, async } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { RateProvider } from './rate';
import { NgLoggerModule, Level } from '@nsalaun/ng-logger';
import { Logger } from '../../providers/logger/logger';
import {
TranslateModule,
TranslateService,
TranslateLoader,
TranslateFakeLoader
} from '@ngx-translate/core';
describe('RateProvider', () => {
let injector: TestBed;
let service: RateProvider;
let httpMock: HttpTestingController;
const btcResponse = [{"code":"BTC","name":"Bitcoin","rate":1},{"code":"USD","name":"US Dollar","rate":11535.74},{"code":"BCH","name":"Bitcoin Cash","rate":7.65734}];
const bchResponse = [{"code":"BTC","name":"Bitcoin","rate":0.130377},{"code":"USD","name":"US Dollar","rate":1503.3},{"code":"BCH","name":"Bitcoin Cash","rate":1}];
let btcUrl: string = 'https://bitpay.com/api/rates';
let bchUrl: string = 'https://bitpay.com/api/rates/bch';
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule,
NgLoggerModule.forRoot(Level.LOG),
TranslateModule.forRoot({
loader: { provide: TranslateLoader, useClass: TranslateFakeLoader }
})
],
providers: [
RateProvider,
Logger
]
});
injector = getTestBed();
service = injector.get(RateProvider);
httpMock = injector.get(HttpTestingController);
});
it('should see if rates are available', () => {
service.updateRatesBtc().then(response => {
expect(service.isAvailable()).toBe(true);
});
httpMock.match(btcUrl)[1].flush(btcResponse);
httpMock.match(bchUrl)[0].flush(bchResponse);
httpMock.verify();
});
it('should get BTC rates', () => {
service.updateRatesBtc().then(response => {
expect(service.isAvailable()).toBe(true);
expect(service.getRate('BTC')).toEqual(1);
expect(service.getRate('USD')).toEqual(11535.74);
expect(service.getRate('BCH')).toEqual(7.65734);
});
httpMock.match(btcUrl)[1].flush(btcResponse);
httpMock.match(bchUrl)[0].flush(bchResponse);
httpMock.verify();
});
it('should get BCH rates', () => {
service.updateRatesBch().then(response => {
expect(service.isAvailable()).toBe(true);
expect(service.getRate('BTC', 'bch')).toEqual(0.130377);
expect(service.getRate('USD', 'bch')).toEqual(1503.3);
expect(service.getRate('BCH', 'bch')).toEqual(1);
});
httpMock.match(btcUrl)[0].flush(btcResponse);
httpMock.match(bchUrl)[1].flush(bchResponse);
httpMock.verify();
});
it('should catch an error on when call to update btc rates fails', () => {
service.getBCH = (): Promise<any> => {
let prom = new Promise((resolve, reject) => {
reject('test rejection');
});
return prom;
};
service.updateRatesBch()
.catch((err: any) => {
expect(err).not.toBeNull();
});
});
it('should catch an error on when call to update bch rates fails', () => {
service.getBTC = (): Promise<any> => {
let prom = new Promise((resolve, reject) => {
reject('test rejection');
});
return prom;
};
service.updateRatesBtc()
.catch((err: any) => {
expect(err).not.toBeNull();
});
});
it('should covert BCH satoshis to fiat', () => {
// before we have rates
expect(service.toFiat(0.25*1e+8, 'USD', 'bch')).toBeNull();
// after we have rates
service.updateRatesBch().then(response => {
expect(service.isAvailable()).toBe(true);
expect(service.toFiat(1*1e+8, 'USD', 'bch')).toEqual(1503.3);
expect(service.toFiat(0.5*1e+8, 'USD', 'bch')).toEqual(751.65);
expect(service.toFiat(0.25*1e+8, 'USD', 'bch')).toEqual(375.825);
});
httpMock.match(btcUrl)[0].flush(btcResponse);
httpMock.match(bchUrl)[1].flush(bchResponse);
httpMock.verify();
});
it('should covert fiat to BCH satoshis', () => {
// before we have rates
expect(service.fromFiat(0.25*1e+8, 'USD', 'bch')).toBeNull();
// after we have rates
service.updateRatesBch().then(response => {
expect(service.isAvailable()).toBe(true);
expect(service.fromFiat(1503.3, 'USD', 'bch')).toEqual(1*1e+8);
expect(service.fromFiat(751.65, 'USD', 'bch')).toEqual(0.5*1e+8);
expect(service.fromFiat(375.825, 'USD', 'bch')).toEqual(0.25*1e+8);
});
httpMock.match(btcUrl)[0].flush(btcResponse);
httpMock.match(bchUrl)[1].flush(bchResponse);
httpMock.verify();
});
it('should covert BTC satoshis to fiat', () => {
// before we have rates
expect(service.toFiat(0.25*1e+8, 'USD', 'btc')).toBeNull();
// after we have rates
service.updateRatesBtc().then(response => {
expect(service.isAvailable()).toBe(true);
expect(service.toFiat(1*1e+8, 'USD', 'btc')).toEqual(11535.74);
expect(service.toFiat(0.5*1e+8, 'USD', 'btc')).toEqual(5767.87);
expect(service.toFiat(0.25*1e+8, 'USD', 'btc')).toEqual(2883.935);
});
httpMock.match(btcUrl)[1].flush(btcResponse);
httpMock.match(bchUrl)[0].flush(bchResponse);
httpMock.verify();
});
it('should covert fiat to BTC satoshis', () => {
// before we have rates
expect(service.fromFiat(0.25*1e+8, 'USD', 'btc')).toBeNull();
// after we have rates
service.updateRatesBtc().then(response => {
expect(service.isAvailable()).toBe(true);
expect(service.fromFiat(11535.74, 'USD', 'btc')).toEqual(1*1e+8);
expect(service.fromFiat(5767.87, 'USD', 'btc')).toEqual(0.5*1e+8);
expect(service.fromFiat(2883.935, 'USD', 'btc')).toEqual(0.25*1e+8);
});
httpMock.match(btcUrl)[1].flush(btcResponse);
httpMock.match(bchUrl)[0].flush(bchResponse);
httpMock.verify();
});
it('should list alternatives', () => {
// before we have rates
expect(service.listAlternatives(false)).toEqual([]);
expect(service.listAlternatives(true)).toEqual([]);
// after we have rates
service.updateRatesBtc().then(response => {
expect(service.isAvailable()).toBe(true);
expect(service.listAlternatives(false)).toEqual([
{name: 'Bitcoin', isoCode: 'BTC'},
{name: 'US Dollar', isoCode: 'USD'},
{name: 'Bitcoin Cash', isoCode: 'BCH'}
]);
expect(service.listAlternatives(true)).toEqual([
{name: 'Bitcoin', isoCode: 'BTC'},
{name: 'Bitcoin Cash', isoCode: 'BCH'},
{name: 'US Dollar', isoCode: 'USD'}
]);
});
httpMock.match(btcUrl)[1].flush(btcResponse);
httpMock.match(bchUrl)[0].flush(bchResponse);
httpMock.verify();
});
it('should resolve when rates are available', () => {
// before we have rates
expect(service.isAvailable()).toBe(false);
service.whenRatesAvailable().then(response => {
// after we have rates
expect(service.isAvailable()).toBe(true);
// hit the if in whenRatesAvailable
service.whenRatesAvailable();
});
httpMock.match(btcUrl)[1].flush(btcResponse);
httpMock.match(bchUrl)[0].flush(bchResponse);
httpMock.verify();
});
});

View File

@ -32,10 +32,9 @@ export class RateProvider {
this.updateRatesBch();
}
private updateRatesBtc(): Promise<any> {
public updateRatesBtc(): Promise<any> {
return new Promise((resolve, reject) => {
this.getBTC().then((dataBTC: any) => {
_.each(dataBTC, (currency: any) => {
this.rates[currency.code] = currency.rate;
this.alternatives.push({
@ -53,7 +52,7 @@ export class RateProvider {
});
}
private updateRatesBch(): Promise<any> {
public updateRatesBch(): Promise<any> {
return new Promise((resolve, reject) => {
this.getBCH().then((dataBCH: any) => {
_.each(dataBCH, (currency: any) => {
@ -67,7 +66,7 @@ export class RateProvider {
});
}
private getBTC(): Promise<any> {
public getBTC(): Promise<any> {
return new Promise((resolve, reject) => {
this.http.get(this.rateServiceUrl).subscribe((data: any) => {
resolve(data);
@ -75,7 +74,7 @@ export class RateProvider {
});
}
private getBCH(): Promise<any> {
public getBCH(): Promise<any> {
return new Promise((resolve, reject) => {
this.http.get(this.bchRateServiceUrl).subscribe((data: any) => {
resolve(data);

View File

@ -58,11 +58,19 @@ describe('Release Provider', () => {
githubReq.flush({ tag_name: latestAppVersion });
});
it('should use appVersion when no currentVersion is supplied', () => {
let result = releaseService.checkForUpdates(latestAppVersion);
expect(result.updateAvailable).toBeNull;
expect(result.availableVersion).toBeNull;
expect(result.error).toBeNull;
});
it('should check unsuccessfully the current app version format', () => {
const result = releaseService.checkForUpdates(latestAppVersion, 'V..3.3.3');
expect(result.updateAvailable).toBeNull;
expect(result.availabeVersion).toBeNull;
expect(result.availableVersion).toBeNull;
expect(result.error).toBeDefined();
expect(result.error).toMatch('Cannot');
expect(result.error).toMatch('version tag');
@ -75,7 +83,7 @@ describe('Release Provider', () => {
);
expect(result.updateAvailable).toBeNull;
expect(result.availabeVersion).toBeNull;
expect(result.availableVersion).toBeNull;
expect(result.error).toBeDefined();
expect(result.error).toMatch('Cannot');
expect(result.error).toMatch('release tag');
@ -86,7 +94,7 @@ describe('Release Provider', () => {
expect(result.error).toBeNull;
expect(result.updateAvailable).toBeNull;
expect(result.availabeVersion).toBeNull;
expect(result.availableVersion).toBeNull;
});
it('should be a new version available', () => {
@ -97,6 +105,6 @@ describe('Release Provider', () => {
expect(result.error).toBeNull;
expect(result.updateAvailable).toBeTruthy;
expect(result.availabeVersion).toEqual(latestAppVersion);
expect(result.availableVersion).toEqual(latestAppVersion);
});
});

View File

@ -36,12 +36,16 @@ export class ReleaseProvider {
};
}
public checkForUpdates(latestVersion: string, currentVersion?: string) {
public checkForUpdates(latestVersion: string, currentVersion?: string): {
updateAvailable: boolean | null,
availableVersion: string | null,
error: string | null
} {
if (!currentVersion) currentVersion = this.appVersion;
let result = {
updateAvailable: null,
availabeVersion: null,
availableVersion: null,
error: null
};
@ -62,7 +66,7 @@ export class ReleaseProvider {
return result;
else {
result.updateAvailable = true;
result.availabeVersion = latestVersion;
result.availableVersion = latestVersion;
return result;
}
}