mirror of https://github.com/BTCPrivate/copay.git
commit
128cb726d2
|
@ -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 {
|
||||
|
|
|
@ -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');
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
]
|
||||
});
|
||||
|
||||
});
|
||||
});
|
|
@ -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"}');
|
||||
}));
|
||||
});
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
});
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
});
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
}));
|
||||
});
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
});
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue