gaf-mobile
Version:
GAF mobile Web site
801 lines (673 loc) • 23.8 kB
JavaScript
'use strict';
/* global UserMock */
/* global ProjectMock */
describe('DepositCtrl', function() {
var $q, $route, $rootScope, $scope, $httpBackend;
var UsersMock, CurrenciesMock, DepositsMock, DepositFeeConfigsMock,
ThreatmetrixMock, FlInterFrameServiceMock;
var $locationMock, $windowMock;
var user, project, feeConfigs, currenciesList, deposit;
var currency, createCtrl, ccResource, paypalResource;
var urlMock;
beforeEach(module('gafMobileApp'));
beforeEach(inject(function($controller, _$q_, _$route_, _$rootScope_,
_$httpBackend_) {
$controller = $controller;
$q = _$q_;
$rootScope = _$rootScope_;
$route = _$route_;
$httpBackend = _$httpBackend_;
$scope = $rootScope.$new();
$route.current = {
params: {}
};
$windowMock = {
location: {
reload: jasmine.createSpy()
},
addEventListener: jasmine.createSpy()
};
user = UserMock();
project = ProjectMock();
currency = {
code: 'USD',
id: 1,
sign: '$'
};
user.getBalanceForCurrency = function() {
return {
amount: 100,
currency: currency
};
};
user.getPrimaryCurrency = function() {
return {
get: function() {
return 1; // currency id
}
};
};
user.get = function() {
return {
id: 1
};
};
feeConfigs = {
get: function(currencyId, depositType) {
if (currencyId === '-1' && depositType === '-1') {
return undefined;
}
return {
get: function() {
return {};
}
};
}
};
currenciesList = {
getList: function() {
return [{ id: 1 }];
},
getById: function() {
return {
get: function() {
return currency;
}
};
}
};
deposit = {
amount: 1,
fee: 0.23,
currency: {
id: currency.id,
exchange_rate: 1.25
},
type: 'fln_billing'
};
ccResource = {
credit_card: {
card_type: 'mastercard',
credit_card_number: '12831*****2323',
gateway: 'gc'
},
currency_id: 18,
currency: {
code: 'PHP',
exchange_rate: 0.25
},
deposit_method: 'fln_billing',
token: '8928132'
};
paypalResource = {
credit_card: null,
currency_id: 1,
deposit_method: 'paypal_reference',
token: 'C-28SDSD9908D'
};
urlMock = {
host: 'm.freelancer.com',
protocol: 'https'
};
createCtrl = function() {
return $controller('DepositCtrl', {
$location: $locationMock,
$q: $q,
$rootScope: $rootScope,
$route: $route,
$scope: $scope,
$window: $windowMock,
Currencies: CurrenciesMock,
DepositFeeConfigs: DepositFeeConfigsMock,
Deposits: DepositsMock,
Users: UsersMock,
Threatmetrix: ThreatmetrixMock,
FlInterFrameService: FlInterFrameServiceMock
});
};
}));
beforeEach(function() {
CurrenciesMock = jasmine.createSpyObj('Currencies', ['get']);
DepositFeeConfigsMock = jasmine.createSpyObj('DepositFeeConfigs', ['get']);
DepositsMock = jasmine.createSpyObj('Deposits',
['setupDeposit', 'getVerifiedPaymentSources', 'authorizationCharge']);
UsersMock = jasmine.createSpyObj('Users', ['getLoggedInUser']);
ThreatmetrixMock = jasmine.createSpyObj('Threatmetrix', ['getSession']);
FlInterFrameServiceMock = jasmine.createSpyObj('FlInterFrameService',
['interFrameSubmit']);
$locationMock = jasmine.createSpyObj('$location', ['url', 'path',
'protocol', 'search', 'host', 'port'
]);
CurrenciesMock.get.and.returnValue($q.when(currenciesList));
DepositFeeConfigsMock.get.and.returnValue($q.when(feeConfigs));
DepositsMock.setupDeposit.and.returnValue($q.when({
get: function() {
return { url: 'newHref' }; }
}));
DepositsMock.getVerifiedPaymentSources.and.returnValue(
$q.when({
payment_source: [
ccResource,
paypalResource
]
})
);
DepositsMock.authorizationCharge.and.returnValue($q.when());
UsersMock.getLoggedInUser.and.returnValue($q.when(user));
ThreatmetrixMock.getSession.and.returnValue('tm123');
$route.current.params.depositMethod = 'skrill';
$locationMock.url.and.returnValue('/deposit');
$locationMock.search.and.returnValue({ status: 'success' });
$locationMock.protocol.and.returnValue(urlMock.protocol);
$locationMock.host.and.returnValue(urlMock.host);
$locationMock.path.and.returnValue('deposit');
$httpBackend.expectGET('/views/main.html').respond(200);
});
describe('Setting up parameters upon initialization', function() {
it('should use paypal reference for paypal deposit method', function() {
$locationMock.search.and.returnValue({});
$route.current.params.depositMethod = 'paypal';
var ctrl = createCtrl();
expect(ctrl.deposit.type).toBe('paypal_reference');
});
it('should use fln billing for cc deposit method', function() {
$locationMock.search.and.returnValue({});
$route.current.params.depositMethod = 'cc';
var ctrl = createCtrl();
expect(ctrl.deposit.type).toBe('fln_billing');
});
it('should default to paypal if on webview route', function() {
$locationMock.path.and.returnValue('webview/deposit');
var ctrl = createCtrl();
expect(ctrl.deposit.type).toBe('paypal_reference');
});
it('should default to cc deposit method', function() {
$route.current.params.depositMethod = 'someOtherMethod';
createCtrl();
expect($locationMock.path).toHaveBeenCalledWith('/deposit/cc');
});
it('should set errors object to be empty', function() {
var ctrl = createCtrl();
expect(ctrl.errors).toEqual({});
});
it('should set loading to true if init promises are unresolved',
function() {
var ctrl = createCtrl();
expect(ctrl.loading).toBeTruthy();
});
});
describe('Post deposit initialization', function() {
it('should prefill and round deposit amount if available', function() {
$locationMock.search.and.returnValue({
status: 'success',
amount: deposit.amount,
currency: deposit.currency.id,
fee: deposit.fee
});
$route.current.params.depositMethod = 'paypal';
var ctrl = createCtrl();
$scope.$digest();
expect(ctrl.userBalance.amount).toBe(100);
expect(ctrl.success).toBeTruthy();
expect(ctrl.loading).toBeFalsy();
expect(ctrl.deposit.fee).toBe(deposit.fee);
expect(ctrl.deposit.amount).toBe(deposit.amount);
expect(ctrl.deposit.currency).toBe(currency);
});
it('should stop loading if error occurred in getting user', function() {
$locationMock.search.and.returnValue({
status: 'fail',
});
$route.current.params.depositMethod = 'paypal';
var ctrl = createCtrl();
ctrl.getToken = jasmine.createSpy('getToken');
ctrl.getToken.and.returnValue('new');
$scope.$digest();
expect(ctrl.confirmError).toBeTruthy();
});
});
describe('Attaching message event to handlers', function() {
it('should call addEventListener function if addEventListener exists',
function() {
createCtrl();
expect($windowMock.addEventListener).toHaveBeenCalled();
});
it('should call attachEvent function if addEventListener does not exist',
function() {
$windowMock.addEventListener = undefined;
$windowMock.attachEvent = jasmine.createSpy();
createCtrl();
expect($windowMock.attachEvent).toHaveBeenCalled();
});
});
describe('Method: setUpUrls()', function() {
it('should set return url to upgrade accdg to params', function() {
$locationMock.search.and.returnValue({
action: 'upgrade',
project: 1
});
var ctrl = createCtrl();
ctrl.setUpUrls();
expect(ctrl.urls.return).toBe('/upgrade-project/1');
expect(ctrl.urls.confirm).toBe('&action=upgrade&project=1');
});
it('should set return url to milestones accdg to params ' +
'when creating requested milestones', function() {
$locationMock.search.and.returnValue({
action: 'create_milestone',
project: 1,
milestones: '1,2',
bidder: 1
});
var ctrl = createCtrl();
ctrl.setUpUrls();
expect(ctrl.urls.return).toBe('/projects/project-1' +
'?action=create_milestone' +
'&milestones=1,2&bidder=1#management');
expect(ctrl.urls.confirm).toBe('&action=create_milestone&project=1' +
'&milestones=1,2&bidder=1');
});
it('should set return url to milestones accdg to params ' +
'when creating new milestones', function() {
$locationMock.search.and.returnValue({
action: 'create_milestone',
project: 2,
amount: 10,
milestone_amount: 5,
milestones: '0',
descr: 'test milestone',
reason: 3,
bidder: 1
});
var ctrl = createCtrl();
ctrl.setUpUrls();
expect(ctrl.urls.return).toBe('/projects/project-2' +
'?action=create_milestone' +
'&milestones=0&bidder=1&milestone_amount=5&descr=test%20milestone' +
'&reason=3#management');
expect(ctrl.urls.confirm).toBe('&action=create_milestone&project=2' +
'&milestones=0&bidder=1&milestone_amount=5' +
'&descr=test%20milestone&reason=3');
});
it('should keep the return and/or confirm params if present only if not ' +
'creating milestones nor upgrading a project', function() {
var returnParam = '/return/here/after/deposit?success=true';
var confirmParam = '/confirm/here/after/deposit?success';
$locationMock.search.and.returnValue({
return: returnParam,
confirm: confirmParam
});
var ctrl = createCtrl();
ctrl.setUpUrls();
expect(ctrl.urls.return).toBe(returnParam);
expect(ctrl.urls.confirm).toBe(confirmParam);
});
});
describe('Method: updateFee()', function() {
it('should set deposit fee if config for currency is defined', function() {
user.getBalanceForCurrency = function() {
return {
amount: 200
};
};
var ctrl = createCtrl();
ctrl.userInfo = user;
ctrl.deposit = {};
ctrl.params = { project: project.id };
ctrl.updateFee(deposit, feeConfigs);
expect(ctrl.errors.currencyNotSupported).toBeFalsy();
expect(ctrl.feeConfig).toBeDefined();
expect(ctrl.deposit.fee).toBeDefined();
expect(ctrl.userBalance.amount).toEqual(200);
});
it('should show error if config for currency is not defined', function() {
var ctrl = createCtrl();
ctrl.userInfo = user;
ctrl.deposit = {};
ctrl.params = { project: project.id };
ctrl.updateFee(deposit, { get: function() {} });
expect(ctrl.feeConfig).not.toBeDefined();
expect(ctrl.deposit.fee).not.toBeDefined();
expect(ctrl.errors.currencyNotSupported).toBeTruthy();
});
});
describe('Method: setUpGateWay()', function() {
var depositParams;
beforeEach(function() {
depositParams = {
amount: deposit.amount,
currency_id: deposit.currency.id,
tracking_token: 'API|||gaf-mobile',
threatmetrix_session: 'tm123'
};
});
it('should call setup deposit with fln_billing params', function() {
angular.extend(depositParams, {
deposit_method: 'fln_billing',
action: 'getPostForm',
credit_card_gateway: 'gc'
});
var ctrl = createCtrl();
ctrl.setUpGateWay(deposit);
expect(DepositsMock.setupDeposit).toHaveBeenCalledWith(depositParams);
});
describe('call setup deposit with paypal params', function() {
var urlHost, urlParams;
beforeEach(function() {
urlHost = urlMock.protocol + '://' + urlMock.host;
urlParams = '?amount=' + depositParams.amount + '¤cy=' +
depositParams.currency_id + '&fee=' + deposit.fee;
deposit.type = 'paypal_reference';
angular.extend(depositParams, {
deposit_method: 'paypal_reference',
action: 'setExpressCheckoutRef'
});
});
it('should call with webview params',
function() {
$locationMock.path.and.returnValue('webview/deposit');
angular.extend(depositParams, {
cancel_url: urlHost + '/webview/deposit/',
confirm_url: urlHost + '/webview/deposit/' + urlParams
});
var ctrl = createCtrl();
ctrl.setUpGateWay(deposit);
expect(DepositsMock.setupDeposit).toHaveBeenCalledWith(depositParams);
});
it('should call w/o webview params',
function() {
$locationMock.path.and.returnValue('deposit');
angular.extend(depositParams, {
cancel_url: urlHost + '/deposit/paypal',
confirm_url: urlHost + '/deposit/paypal' + urlParams
});
var ctrl = createCtrl();
ctrl.setUpGateWay(deposit);
expect(DepositsMock.setupDeposit).toHaveBeenCalledWith(depositParams);
});
});
it('should set deposit api fail code on setup deposit if query failed',
function() {
DepositsMock.setupDeposit.and.returnValue($q.reject({
code: 'DEPOSIT_API_FAIL'
}));
var ctrl = createCtrl();
ctrl.setUpGateWay(deposit);
$scope.$digest();
expect(ctrl.errors.depositSetupFailure).toBeTruthy();
});
it('should set unknown error on setup deposit if query failed',
function() {
DepositsMock.setupDeposit.and.returnValue($q.reject({
code: 'UNKNOWN_ERROR',
data: {
message: 'unknown error'
}
}));
var ctrl = createCtrl();
ctrl.setUpGateWay(deposit);
$scope.$digest();
expect(ctrl.errors.unknownError).toBe('unknown error');
});
});
xdescribe('Method: changeDepositMethod()', function() {
it('should set iframe to response url if deposit is cc', function() {
var ctrl = createCtrl();
ctrl.changeDepositMethod(deposit);
$scope.$digest();
expect(ctrl.iframe).toBeDefined();
});
});
describe('Method: changeTab()', function() {
var randomTab;
beforeEach(function() {
randomTab = 'randomTabName';
});
it('should not change tab name if same as previous',
function() {
var ctrl = createCtrl();
$scope.tab = {
name: randomTab
};
ctrl.changeTab(randomTab);
expect($scope.tab.name).toBe(randomTab);
});
it('should change tab name according to type',
function() {
var ctrl = createCtrl();
ctrl.changeTab(randomTab);
expect($scope.tab.name).toBe(randomTab);
});
});
describe('Method: processDeposit()', function() {
it('should update the window location if deposit is paypal', function() {
deposit.type = 'paypal_reference';
deposit.token = 'new';
var ctrl = createCtrl();
ctrl.processDeposit(deposit);
$scope.$digest();
expect($windowMock.location.href).toBeDefined();
});
it('should call interframe service if deposit is cc', function() {
var ctrl = createCtrl();
deposit.token = 'new';
ctrl.processDeposit(deposit);
$scope.$digest();
expect(FlInterFrameServiceMock.interFrameSubmit).toHaveBeenCalledWith(
'iframe-payment-method-cc', deposit.amount, deposit.currency.code);
});
it('should call authorizationCharge when token is not "new"',
function() {
deposit.token = '8928132';
var ctrl = createCtrl();
ctrl.processDeposit(deposit);
$scope.$digest();
expect(DepositsMock.authorizationCharge).toHaveBeenCalled();
});
});
describe('Method: getToken()', function() {
it('Should return "new" if resources array passed ' +
'is empty', function() {
var ctrl = createCtrl();
var res = ctrl.getToken([], deposit);
expect(res).toEqual('new');
});
it('Should return "new" if no resources match ' +
'the currency and type of the deposit object ' +
'passed', function() {
deposit.currency.id = ccResource.currency_id;
deposit.type = ccResource.deposit_method;
var resources = [paypalResource];
var ctrl = createCtrl();
var res = ctrl.getToken(resources, deposit);
expect(res).toEqual('new');
});
it('should return the token resource if it matches ' +
'currency and type of the deposit object passed', function() {
deposit.currency.id = ccResource.currency_id;
deposit.type = ccResource.deposit_method;
var paymentMethods = [ccResource, paypalResource];
var ctrl = createCtrl();
var res = ctrl.getToken(paymentMethods, deposit);
expect(res).toEqual(ccResource.token);
});
});
describe('Method: hasSavedAccounts()', function() {
it('Should return true if the user has saved accounts for ' +
'the given type', function() {
var ctrl = createCtrl();
var type = paypalResource.deposit_method;
ctrl.availablePaymentMethods = [paypalResource];
ctrl.hasSavedAccounts(type);
expect(ctrl.hasSavedAccounts(type)).toBeTruthy();
});
it('Should return false if the user has no saved accounts ' +
'for the given type', function() {
var ctrl = createCtrl();
var type = ccResource.deposit_method;
ctrl.availablePaymentMethods = [paypalResource];
ctrl.hasSavedAccounts(type);
expect(ctrl.hasSavedAccounts(type)).toBeFalsy();
});
it('Should return false if the user has no saved accounts', function() {
var ctrl = createCtrl();
var type = ccResource.deposit_method;
ctrl.availablePaymentMethods = [];
ctrl.hasSavedAccounts(type);
expect(ctrl.hasSavedAccounts(type)).toBeFalsy();
});
});
describe('Method: onPaymentMethodClick()', function() {
it('Should store cc gateway if it is of type ' +
'fln_billing', function() {
var ctrl = createCtrl();
spyOn(ctrl, 'updateFee');
ctrl.onPaymentMethodClick(ccResource, deposit);
expect(ctrl.updateFee).toHaveBeenCalled();
expect(ctrl.deposit.gateway).toEqual(ccResource.credit_card.gateway);
});
it('Should not store cc gateway if resource passed ' +
'is not of type fln_billing', function() {
var ctrl = createCtrl();
spyOn(ctrl, 'updateFee');
ctrl.onPaymentMethodClick(paypalResource, deposit);
expect(ctrl.updateFee).toHaveBeenCalled();
expect(ctrl.deposit.gateway).toBeUndefined();
});
it('Should set the currency to the currency of the selected ' +
'payment method on "currencyNotSupoprted" error', function() {
var ctrl = createCtrl();
paypalResource.currency = currency;
ctrl.errors = {
currencyNotSupported: true
};
spyOn(ctrl, 'updateFee');
ctrl.onPaymentMethodClick(paypalResource, deposit);
expect(ctrl.updateFee).toHaveBeenCalled();
expect(ctrl.deposit.currency).toEqual(currency);
expect(ctrl.errors.currencyNotSupported).toBeFalsy();
});
it('Should call setExchangeRate with the resource and ' +
'deposit object passed', function() {
var ctrl = createCtrl();
spyOn(ctrl, 'setExchangeRate');
spyOn(ctrl, 'updateFee');
ctrl.onPaymentMethodClick(paypalResource, deposit);
expect(ctrl.updateFee).toHaveBeenCalled();
expect(ctrl.setExchangeRate)
.toHaveBeenCalledWith(paypalResource, deposit);
});
});
describe('Method: setExchangeRate()', function() {
it('should not calculate exchange rate when payment method' +
' selected is the same as the currency to deposit', function() {
var ctrl = createCtrl();
ccResource.currency_id = deposit.currency.id;
ctrl.setExchangeRate(ccResource, deposit);
expect(ctrl.exchangeRate).toEqual(1);
expect(ctrl.paymentMethodCode).toBeUndefined();
});
it('should calculate exchange rate when payment method' +
' selected is not the same as the currency to deposit', function() {
var fxCut = 0.03;
var conv = deposit.currency.exchange_rate /
ccResource.currency.exchange_rate;
conv = conv * (1 / (1 - fxCut));
var ctrl = createCtrl();
ctrl.setExchangeRate(ccResource, deposit);
expect(ctrl.exchangeRate).toEqual(conv);
expect(ctrl.paymentMethodCode).toEqual(ccResource.currency.code);
});
});
xdescribe('Method: receiveMessage()', function() {
it('should not set status to success if origin is NE to event origin',
function() {
var ctrl = createCtrl();
ctrl.receiveMessage({
origin: 'https://www.freelancer.com',
data: {
type: 'success'
}
});
$scope.$digest();
expect(ctrl.success).toBeTruthy();
});
it('should set error to true if failed',
function() {
var ctrl = createCtrl();
ctrl.receiveMessage({
origin: 'notoriginal',
data: {
type: 'failed'
}
});
expect(ctrl.success).toBeFalsy();
});
it('should set error to true if failed',
function() {
$windowMock.location.origin = 'original';
var ctrl = createCtrl();
ctrl.receiveMessage({
origin: 'https://www.freelancer.com',
data: {
type: 'failed'
}
});
expect(ctrl.confirmError).toBeTruthy();
});
});
xdescribe('Method: startDeposit();', function() {
it('should prefill and round deposit amount if available', function() {
$locationMock.search.and.returnValue({ amount: 100 });
var ctrl = createCtrl();
$scope.$digest();
expect(ctrl.deposit.amount).toBe(100);
});
it('should send user to error page if error with deposit fee', function() {
$locationMock.search.and.returnValue({});
DepositFeeConfigsMock.get.and.returnValue($q.reject({}));
createCtrl();
$scope.$digest();
expect($locationMock.path).toHaveBeenCalledWith('/error');
});
it('should prefill deposit currency if defined in url params', function() {
$locationMock.search.and.returnValue({ currency: 1 });
currenciesList = {
getById: function() {
return {
get: function() {
return { id: 1 };
}
};
},
getList: function() {
return [{ id: '-1' }];
}
};
CurrenciesMock.get.and.returnValue($q.when(currenciesList));
var ctrl = createCtrl();
$scope.$digest();
expect(ctrl.deposit.currency.id).toBe(1);
});
it('should not add a currency if it is undefined', function() {
currenciesList = {
getList: function() {
return [{ id: '-1' }];
}
};
CurrenciesMock.get.and.returnValue($q.when(currenciesList));
$locationMock.search.and.returnValue({});
DepositsMock.setupDeposit.and.returnValue($q.when({}));
var ctrl = createCtrl();
ctrl.deposit.type = '-1';
$scope.$digest();
expect(ctrl.currencies.length).toBe(0);
});
it('should set iframe to response url if deposit is cc', function() {
$route.current.params.depositMethod = 'cc';
var ctrl = createCtrl();
$scope.$digest();
expect(ctrl.iframe).toBeDefined();
});
});
});