gaf-mobile
Version:
GAF mobile Web site
1,062 lines (864 loc) • 33.5 kB
JavaScript
/* global LocationMock */
/* global ProjectMock */
/* global BudgetMock */
/* global BudgetListMock */
/* global TemplateMock */
/* global UserMock */
describe('Controller: PostProjectCtrl', function() {
var $scope, $q, $location, $route, $httpBackend;
var ProjectsMock, JobBundlesMock, AuthMock, ProjectLocationMock, BudgetsMock,
DepositsMock;
var CategoriesMock, UsersMock, currencyFilterMock,
ProjectTemplatesMock, TranslationsMock, CookieStoreMock;
var createCtrl;
var project, defaultCurrency, projectFactoryMock, jobBundlesFactoryMock,
categoriesFactoryMock, currencyFactoryMock, budgetsFactoryMock;
// Clean up once SetTitleFromAnswer A/B test is done
var ExperimentsMock;
beforeEach(module('gafMobileApp'));
beforeEach(inject(function($controller, _$rootScope_, _$q_, _$location_,
_$httpBackend_, _$route_) {
$scope = _$rootScope_.$new();
$q = _$q_;
$location = _$location_;
$httpBackend = _$httpBackend_;
$route = _$route_;
project = ProjectMock();
createCtrl = function() {
return $controller('PostProjectCtrl', {
$scope: $scope,
$q: $q,
$route: $route,
$location: $location,
Projects: ProjectsMock,
Auth: AuthMock,
JobBundles: JobBundlesMock,
ProjectLocation: ProjectLocationMock,
Budgets: BudgetsMock,
Categories: CategoriesMock,
Users: UsersMock,
currencyFilter: currencyFilterMock,
ProjectTemplates: ProjectTemplatesMock,
Translations: TranslationsMock,
CookieStore: CookieStoreMock,
Deposits: DepositsMock,
// Clean up once SetTitleFromAnswer A/B test is done
Experiments: ExperimentsMock
});
};
}));
beforeEach(function() {
AuthMock = jasmine.createSpyObj('Auth', ['isAuthenticated', 'getUserId']);
UsersMock = jasmine.createSpyObj('Users', ['getLoggedInUser']);
JobBundlesMock = jasmine.createSpyObj('JobBundles',
['getCategoriesWithBundles']);
BudgetsMock = jasmine.createSpyObj('Budgets', ['getWithCurrencies']);
ProjectLocationMock = jasmine.createSpyObj('ProjectLocation',
['isValidPlace', 'getLocation', 'denormaliseLatLng']);
ProjectsMock = jasmine.createSpyObj('Projects', ['post', 'getCurrent',
'setCurrent']);
ProjectTemplatesMock = jasmine.createSpyObj('ProjectTemplates',
['getNextQuestion', 'createDescription']);
CategoriesMock = jasmine.createSpyObj('Categories', ['getListWithJobs']);
currencyFilterMock = jasmine.createSpy('currencyFilter');
TranslationsMock = jasmine.createSpyObj('Translations',
['getTranslationFromString']);
DepositsMock = jasmine.createSpyObj('Deposits',
['getVerifiedPaymentSources']);
CookieStoreMock = {
get: function() { return 'en'; }
};
TranslationsMock.getTranslationFromString.and.returnValue($q.when({}));
ProjectLocationMock.getLocation.and.returnValue($q.when({}));
projectFactoryMock = jasmine.createSpyObj('projectFactory', ['get',
'isReady', 'markAsReady', 'set', 'reset', 'setTitle', 'setJobs']);
projectFactoryMock.get.and.returnValue(project);
ProjectsMock.getCurrent.and.returnValue(projectFactoryMock);
jobBundlesFactoryMock = jasmine.createSpyObj('jobBundlesFactory',
['getList', 'remove', 'getById', 'getBundlesForCategory']);
jobBundlesFactoryMock.getList.and.returnValue([]);
jobBundlesFactoryMock.getById.and.returnValue({
get: function() { return {id: 1}; }
});
JobBundlesMock.getCategoriesWithBundles.and.returnValue(
$q.when(jobBundlesFactoryMock));
categoriesFactoryMock = jasmine.createSpyObj('categoriesFactory',
['getJobs']);
categoriesFactoryMock.getJobs.and.returnValue(jobBundlesFactoryMock);
CategoriesMock.getListWithJobs.and.returnValue(
$q.when(categoriesFactoryMock));
defaultCurrency = {
get: function() {
var user = UserMock();
return user.primary_currency;
}
};
currencyFactoryMock = jasmine.createSpyObj('currencyFactory',
['get', 'getList']);
currencyFactoryMock.get.and.returnValue(defaultCurrency);
budgetsFactoryMock = jasmine.createSpyObj('budgetsFactory',
['getByMaximum', 'getList', 'getByIndex']);
BudgetsMock.getWithCurrencies.and.returnValue($q.when({
currencies: currencyFactoryMock,
budgets: budgetsFactoryMock
}));
$route.current = {
locals: {
template: {
get: function() {
return TemplateMock();
}
},
user: jasmine.createSpyObj('user', ['get', 'getBalanceForCurrency']),
},
loadedTemplateUrl: []
};
$route.current.locals.user.get.and.returnValue(UserMock());
// Clean up once SetTitleFromAnswer A/B test is done
ExperimentsMock = jasmine.createSpyObj('Experiments', ['activateTest',
'isInSplit']);
});
it('should set current project if it exists', function() {
var ctrl = createCtrl();
expect(ProjectsMock.getCurrent).toHaveBeenCalled();
expect(ctrl.project.id).toEqual(project.id);
});
it('should set current jobs from search params if undefined', function() {
var newProject = ProjectMock();
delete newProject.jobs;
projectFactoryMock.get.and.returnValue(newProject);
$location.url('/post-project?jobs=1,2');
var ctrl = createCtrl();
expect(ctrl.currentProject.setJobs).toHaveBeenCalledWith(['1', '2']);
});
it('should set start state if no ready proj', function() {
projectFactoryMock.isReady.and.returnValue(false);
ProjectsMock.post.and.returnValue($q.reject());
var ctrl = createCtrl();
expect(ctrl.state).toBe('start');
});
it('should automatically post project when ready with auth user', function() {
AuthMock.isAuthenticated.and.returnValue(true);
projectFactoryMock.isReady.and.returnValue(true);
ProjectsMock.post.and.returnValue($q.reject());
var ctrl = createCtrl();
expect(ctrl.state).toBe('loading');
expect(ProjectsMock.post).toHaveBeenCalled();
});
// Clean up when RequireProjectDescription A/B test is done
describe('Set isFromNonFiveEye if user is from non5eye', function() {
it('should set isFromNonFiveEye if logged in and location is non5eye',
function() {
var user = UserMock();
user.location.country.name = 'India';
ExperimentsMock.activateTest.and.returnValue(true);
$route.current.locals.user.get.and.returnValue(user);
var ctrl = createCtrl();
expect(ctrl.isFromNonFiveEye).toBeTruthy();
});
it('should set isFromNonFiveEye if logged out and location is non5eye',
function() {
ExperimentsMock.activateTest.and.returnValue(true);
$route.current.locals.user.get.and.returnValue(false);
ProjectLocationMock.getLocation.and.returnValue($q.when());
ProjectLocationMock.denormaliseLatLng.and.returnValue({
country: 'India'
});
var ctrl = createCtrl();
$scope.$digest();
expect(ctrl.isFromNonFiveEye).toBeTruthy();
});
});
describe('Property: project.title', function() {
var newProject;
beforeEach(function() {
newProject = ProjectMock();
delete newProject.title;
});
it('should set default title according to search params if undefined',
function() {
$location.url('/post-project?title=Project');
projectFactoryMock.get.and.returnValue(newProject);
var ctrl = createCtrl();
expect(ctrl.currentProject.setTitle).toHaveBeenCalledWith('Project');
});
it('should set default title according to search params if undefined',
function() {
$location.url('/post-project?project_title=Project');
projectFactoryMock.get.and.returnValue(newProject);
var ctrl = createCtrl();
expect(ctrl.currentProject.setTitle).toHaveBeenCalledWith('Project');
});
});
describe('Property: isRepost', function() {
it('should set repost to true if current jobs and categories exist',
function() {
var ctrl = createCtrl();
expect(ctrl.isRepost).toBeTruthy();
});
it('should set repost to false if current jobs does not exist',
function() {
var newProject = ProjectMock();
delete newProject.jobs;
projectFactoryMock.get.and.returnValue(newProject);
var ctrl = createCtrl();
expect(ctrl.isRepost).toBeFalsy();
});
it('should set repost to false if current category is set',
function() {
var newProject = ProjectMock();
newProject.category = {};
projectFactoryMock.get.and.returnValue(newProject);
var ctrl = createCtrl();
expect(ctrl.isRepost).toBeFalsy();
});
});
it('should set fetching location if it is', function() {
ProjectLocationMock.isFetchingLocation = true;
var ctrl = createCtrl();
expect(ctrl.isFetchingLocation).toBeTruthy();
});
describe('Method: locationValid()', function() {
it('should check if input location is valid', function() {
project.place = LocationMock();
var ctrl = createCtrl();
ctrl.locationValid();
expect(ProjectLocationMock.isValidPlace)
.toHaveBeenCalledWith(LocationMock());
});
});
describe('Method: getLocation()', function() {
it('should be able to fill input location from ProjectLocation',
function() {
ProjectLocationMock.getLocation.and.returnValue($q.when({
city: 'Manila'
}));
var ctrl = createCtrl();
ctrl.getLocation();
$scope.$digest();
expect(ctrl.project.place.city).toBe('Manila');
});
it('should display location error when it hasnt been set previously',
function() {
ProjectLocationMock.getLocation.and.returnValue($q.reject({
code: 'PERMISSION_DENIED'
}));
var ctrl = createCtrl();
ctrl.getLocation();
$scope.$digest();
expect(ctrl.error.locationError).toBeTruthy();
});
it('should display location error',
function() {
ProjectLocationMock.getLocation.and.returnValue($q.reject({
code: 'PERMISSION_DENIED'
}));
var ctrl = createCtrl();
ctrl.error = {};
ctrl.getLocation();
$scope.$digest();
expect(ctrl.error.locationError).toBeTruthy();
});
});
describe('Method: create()', function() {
describe('Creating a project', function() {
var newProject;
beforeEach(function() {
newProject = ProjectMock();
});
it('should assign location to new project if local', function() {
ProjectLocationMock.denormaliseLatLng.and.returnValue({
country: 'PH'
});
newProject.local = true;
var ctrl = createCtrl();
ctrl.project.place = LocationMock();
ctrl.create(newProject);
expect(ProjectLocationMock.denormaliseLatLng)
.toHaveBeenCalledWith(LocationMock());
expect(newProject.location.country.name).toBe('PH');
});
it('should delete location prop of new project if not local', function() {
newProject.local = false;
var ctrl = createCtrl();
ctrl.project.place = null;
ctrl.create(newProject);
expect(newProject.location).not.toBeDefined();
});
it('should set hourly project info if hourly', function() {
newProject.type = 'hourly';
var ctrl = createCtrl();
ctrl.create(newProject);
// Test default values
expect(newProject.hourly_project_info).toEqual({
duration_enum: 'one_to_four_weeks',
commitment: {
hours: 10,
interval: 'week'
}
});
});
it('should save the project and mark it as ready', function() {
var ctrl = createCtrl();
ctrl.create(newProject);
expect(ProjectsMock.setCurrent).toHaveBeenCalled();
});
it('should redirect to sign up page if unauthenticated', function() {
AuthMock.isAuthenticated.and.returnValue(false);
$location.url('/post-project');
var ctrl = createCtrl();
ctrl.create(newProject);
$scope.$digest();
expect($location.url()).toBe('/signup?role=employer&return=' +
encodeURIComponent('/post-project'));
});
it('should redirect user to PVP bids tab when project is posted',
function() {
AuthMock.isAuthenticated.and.returnValue(true);
ProjectsMock.post.and.returnValue($q.when({
get: function() {
return newProject;
},
}));
var ctrl = createCtrl();
ctrl.create(newProject);
$scope.$digest();
expect(ctrl.project).toBe(newProject);
expect($location.url()).toBe('/projects/project-' + newProject.id +
'#bids');
});
it('should catch unverified payment error when posting project',
function() {
AuthMock.isAuthenticated.and.returnValue(true);
ProjectsMock.post.and.returnValue($q.reject({
code: 'UNVERIFIED_PAYMENT'
}));
var currentLocation = encodeURIComponent($location.url());
var ctrl = createCtrl();
ctrl.create(newProject);
$scope.$digest();
expect($location.url()).toBe('/payments/verify?postProject=true' +
'&return=' + currentLocation);
});
it('should catch negative balance error when posting project',
function() {
AuthMock.isAuthenticated.and.returnValue(true);
ProjectsMock.post.and.returnValue($q.reject({
code: 'NEGATIVE_BALANCE'
}));
var ctrl = createCtrl();
ctrl.create(newProject);
$scope.$digest();
expect(ctrl.state).toBe('start');
expect(ctrl.error.negativeBalance).toBeTruthy();
});
it('should catch unknown error when posting project',
function() {
AuthMock.isAuthenticated.and.returnValue(true);
ProjectsMock.post.and.returnValue($q.reject({
code: 'UNKNOWN_ERROR'
}));
var ctrl = createCtrl();
ctrl.create(newProject);
$scope.$digest();
expect(ctrl.state).toBe('start');
expect(ctrl.error.internalError).toBe('UNKNOWN_ERROR');
});
});
describe('Creating a contest', function() {
var newContest;
beforeEach(function() {
// Contests created from our PPP essentially has the same structure as
// a project, but with the `type` property as `contest`
newContest = ProjectMock();
newContest.type = 'contest';
newContest.customBudget = 10;
});
it('should redirect to sign up page if unauthenticated', function() {
AuthMock.isAuthenticated.and.returnValue(false);
$location.url('/post-project');
var ctrl = createCtrl();
ctrl.create(newContest);
expect($location.url()).toBe('/signup?role=employer&return=' +
encodeURIComponent('/post-project'));
});
it('should show the payment release modal if authenticated and has ' +
'an existing billing agreement', function() {
AuthMock.isAuthenticated.and.returnValue(true);
DepositsMock.getVerifiedPaymentSources.and.returnValue($q.when({
payment_source: [1, 2]
}));
var ctrl = createCtrl();
ctrl.create(newContest);
$scope.$digest();
expect(ctrl.showPaymentReleaseModal).toBeTruthy();
});
it('should show the payment release modal if authenticated and has ' +
'enough funds for currency to cover contest prize', function() {
AuthMock.isAuthenticated.and.returnValue(true);
$route.current.locals.user.getBalanceForCurrency
.and.returnValue(newContest.customBudget);
DepositsMock.getVerifiedPaymentSources.and.returnValue($q.when({
payment_source: []
}));
var ctrl = createCtrl();
ctrl.create(newContest);
$scope.$digest();
expect(ctrl.showPaymentReleaseModal).toBeTruthy();
});
it('should redirect to deposits page if authenticated and cannot ' +
'cover contest prize', function() {
AuthMock.isAuthenticated.and.returnValue(true);
$route.current.locals.user.getBalanceForCurrency.and.returnValue(0);
DepositsMock.getVerifiedPaymentSources.and.returnValue($q.when({
payment_source: []
}));
var currentUrl = '/post-project';
$location.url(currentUrl);
var ctrl = createCtrl();
ctrl.create(newContest);
$scope.$digest();
expect($location.url()).toBe('/deposit' +
'?postContest' +
'&amount=' + newContest.budget +
'¤cy=' + newContest.currency.id +
'&return=' + encodeURIComponent(currentUrl) +
'&confirm=' +
encodeURIComponent('&return=' + encodeURIComponent(currentUrl)));
});
});
});
describe('Method: reset()', function() {
it('should reload the route', function() {
$location.path('/post-project');
var ctrl = createCtrl();
ctrl.reset();
$scope.$digest();
expect($location.path()).toBe('/post-project');
});
});
describe('Method: checkBids()', function() {
it('should load project page', function() {
$location.path('/post-project');
var ctrl = createCtrl();
ctrl.checkBids(project.id);
$scope.$digest();
expect($location.path()).toBe('/project/' + project.id);
});
});
describe('Condition: existing project template', function() {
var template, newProject;
beforeEach(function() {
template = TemplateMock();
newProject = ProjectMock();
});
describe('set project title if nonexisting yet', function() {
var newProject;
beforeEach(function() {
newProject = ProjectMock();
delete newProject.title;
projectFactoryMock.get.and.returnValue(newProject);
});
it('updates title with url params title', function() {
var title = 'projectTitle';
$location.url('/post-project?title=' + title);
var ctrl = createCtrl();
expect(ctrl.currentProject.setTitle).toHaveBeenCalledWith(title);
});
it('updates title with template title if no url params', function() {
var ctrl = createCtrl();
expect(ctrl.currentProject.setTitle)
.toHaveBeenCalledWith(template.project_title);
});
});
it('exposes current template to the scope', function() {
var ctrl = createCtrl();
expect(ctrl.template).toEqual(jasmine.objectContaining(TemplateMock()));
});
it('sets questions to empty array if undefined', function() {
var newTemplate = TemplateMock();
delete newTemplate.questions;
$route.current.locals.template.get = function() {
return newTemplate;
};
var ctrl = createCtrl();
expect(ctrl.template.questions.length)
.toBe(0);
});
it('sets project answers to empty array if undefined', function() {
var ctrl = createCtrl();
expect(ctrl.project.answers.length).toBe(0);
expect(ctrl.project.freeform_answers.length).toBe(0);
});
describe('Method: getQuestionTemplateTranslation()', function() {
beforeEach(function() {
CookieStoreMock = {
get: function() { return 'pl'; }
};
});
it('should call Translations.getTranslationFromString if lang is not en',
function() {
createCtrl();
$scope.$digest();
expect(TranslationsMock.getTranslationFromString).toHaveBeenCalled();
});
it('should call Translations.getTranslationFromString for answer texts',
function() {
template.questions[1].answers = template.answers;
ProjectTemplatesMock.getNextQuestion.and
.returnValue(template.questions[1]);
var ctrl = createCtrl();
ctrl.electAnswer(template.questions[1], template.answers);
$scope.$digest();
expect(TranslationsMock.getTranslationFromString).toHaveBeenCalled();
});
});
describe('Method: electAnswer()', function() {
var question, answers;
beforeEach(function() {
question = template.questions[1];
answers = template.answers;
var newProject = ProjectMock();
newProject.answers = answers;
projectFactoryMock.get.and.returnValue(newProject);
});
// Clean up when SetTitleFromAnswer A/B test is done
it('should set title according to first answer', function() {
AuthMock.isAuthenticated.and.returnValue(true);
ExperimentsMock.isInSplit.and.returnValue(true);
var firstAnswer = answers[0];
var ctrl = createCtrl();
ctrl.electAnswer(question, [firstAnswer]);
expect(ctrl.currentProject.setTitle)
.toHaveBeenCalledWith(firstAnswer.answer);
});
// Clean up when SetTitleFromAnswer A/B test is done
it('should set title according to template if answer is other/not sure',
function() {
AuthMock.isAuthenticated.and.returnValue(true);
ExperimentsMock.isInSplit.and.returnValue(true);
var firstAnswer = answers[0];
firstAnswer.answer_text = '';
var ctrl = createCtrl();
ctrl.electAnswer(question, [firstAnswer]);
expect(ctrl.currentProject.setTitle)
.toHaveBeenCalledWith(template.project_title);
});
it('should remove unnecessary q&a if earlier q is reanswered',
function() {
var ctrl = createCtrl();
ctrl.electAnswer(question, answers);
expect(ctrl.project.answers[1]).toBeUndefined();
});
it('should remove unnecessary dynamic qs', function() {
var ctrl = createCtrl();
ctrl.electAnswer(question, answers);
expect(ctrl.template.dynamic_questions[1]).toBeUndefined();
});
it('should get next question', function() {
ProjectTemplatesMock.getNextQuestion.and.returnValue(question);
var ctrl = createCtrl();
ctrl.electAnswer(question, answers);
expect(ProjectTemplatesMock.getNextQuestion).toHaveBeenCalled();
expect(ctrl.template.dynamic_questions[
ctrl.template.dynamic_questions.length - 1])
.toEqual(jasmine.objectContaining(question));
});
it('should set current jobs based on answers', function() {
var ctrl = createCtrl();
ctrl.electAnswer(question, answers);
expect(ctrl.currentProject.setJobs).toHaveBeenCalledWith([1, 2]);
});
it('should limit setting of current jobs to 5', function() {
var ctrl = createCtrl();
var mockAnswer = [{
jobs: [{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}],
question_id: 1
}];
ctrl.electAnswer(question, mockAnswer);
expect(ctrl.currentProject.setJobs).toHaveBeenCalledWith([1, 2, 3, 4]);
});
});
describe('Method: electFreeFormAnswer()', function() {
it('should format freeform a and add to answers', function() {
var template = TemplateMock();
var ctrl = createCtrl();
ctrl.electAnswer = jasmine.createSpy('electAnswer');
ctrl.electFreeFormAnswer(template.questions[1], 5, 'FreeformAnswer');
expect(ctrl.project.answers[5]).toEqual(jasmine.objectContaining({
question_id: 1,
answer_text: 'FreeformAnswer'
}));
expect(ctrl.electAnswer).toHaveBeenCalled();
});
it('should format freeform a and add to answers even when blank',
function() {
var template = TemplateMock();
var ctrl = createCtrl();
ctrl.electAnswer = jasmine.createSpy('electAnswer');
ctrl.electFreeFormAnswer(template.questions[1], 5, '');
expect(ctrl.project.answers[5]).toEqual(jasmine.objectContaining({
question_id: 1,
answer_text: ''
}));
expect(ctrl.electAnswer).toHaveBeenCalled();
});
});
describe('Method: optOutTemplate()', function() {
it('sets project answers to empty array if undefined', function() {
$location.url('/post-project/Web-development');
var ctrl = createCtrl();
ctrl.optOutTemplate();
$scope.$digest();
expect($location.path()).toBe('/post-project/custom');
expect($location.search().title).toBe(project.title);
});
});
});
describe('Condition: no existing project template', function() {
beforeEach(function() {
$route.current.locals = {};
});
it('should set project answers and template', function() {
var ctrl = createCtrl();
expect(ctrl.project.answers.length).toEqual(0);
expect(ctrl.template).toEqual(jasmine.objectContaining({
dynamic_questions: [],
questions: []
}));
});
});
describe('Loading job bundles and categories', function() {
it('should store fallbackCategory to preselect right category', function() {
$location.url('/post-project/Web-development?fallback-cat=1');
var ctrl = createCtrl();
$scope.$digest();
expect(ctrl.categoriesWithBundles.getById).toHaveBeenCalledWith(1);
});
it('should set the job name as the default title if no title is given',
function() {
var newProject = ProjectMock();
delete newProject.title;
newProject.bundle = {
name: 'Website Development'
};
projectFactoryMock.get.and.returnValue(newProject);
var ctrl = createCtrl();
$scope.$digest();
expect(ctrl.project.title)
.toBe('Website Development');
});
});
describe('Loading job bundles', function() {
var bundle;
beforeEach(function() {
bundle = {
id: 'Website',
name: 'Website Development',
jobs: [1]
};
});
it('should store fallbackCategory to preselect right category', function() {
$location.url('/post-project/Web-development?fallback-cat=1');
var ctrl = createCtrl();
$scope.$digest();
expect(ctrl.categoriesWithBundles.getById).toHaveBeenCalledWith(1);
});
it('should set the job name as the default title if no title is given',
function() {
var newProject = ProjectMock();
delete newProject.title;
newProject.bundle = bundle;
projectFactoryMock.get.and.returnValue(newProject);
var ctrl = createCtrl();
$scope.$digest();
expect(ctrl.project.title)
.toBe('Website Development');
});
describe('Method: setBundle()', function() {
beforeEach(function() {
var newProject = ProjectMock();
delete newProject.title;
projectFactoryMock.get.and.returnValue(newProject);
});
it('should set title when a job bundle is selected and no title given',
function() {
var ctrl = createCtrl();
ctrl.setBundle(jobBundlesFactoryMock, bundle);
expect(ctrl.project.title).toBe('Website Development');
});
it('should set blank title when a job bundle is selected and ' +
'no title given', function() {
bundle.id = 'OTHER';
var ctrl = createCtrl();
ctrl.setBundle(jobBundlesFactoryMock, bundle);
expect(ctrl.project.title).toBe('');
});
it('should pre-fill the skill selector with the matching jobs',
function() {
var ctrl = createCtrl();
ctrl.setBundle(jobBundlesFactoryMock, bundle);
expect(ctrl.project.jobs.length).toBeDefined();
});
});
});
describe('Loading categories', function() {
it('should set the job name as the default title if no title is given',
function() {
var bundle = {};
var newProject = ProjectMock();
delete newProject.jobs;
newProject.bundle = bundle;
projectFactoryMock.get.and.returnValue(newProject);
var ctrl = createCtrl();
ctrl.setBundle = jasmine.createSpy('setBundle');
$scope.$digest();
expect(ctrl.setBundle).toHaveBeenCalled();
});
it('should export the job list & the jobs used by skill selector',
function() {
var ctrl = createCtrl();
$scope.$digest();
expect(ctrl.jobList).toEqual(jasmine
.objectContaining(jobBundlesFactoryMock));
expect(ctrl.jobList.getList).toHaveBeenCalled();
});
it('should prefill project category if params provided', function() {
jobBundlesFactoryMock.getList.and.returnValue([{
id: 9,
job_bundles: []
}]);
$location.url('/post-project?skill_category=9');
var ctrl = createCtrl();
$scope.$digest();
expect(ctrl.project.category.id).toBe(9);
});
it('should prefill project subcategory if params provided', function() {
jobBundlesFactoryMock.getList.and.returnValue([{
id: 9,
job_bundles: []
}]);
jobBundlesFactoryMock.getBundlesForCategory.and.returnValue({
getById: function() {
return { get: function() { return 'bundle'; } };
}
});
$location.url('/post-project?skill_category=9&skill_subcategory=89');
var ctrl = createCtrl();
$scope.$digest();
expect(ctrl.project.bundle).toBe('bundle');
});
it('should not prefill project sub/category if incomplete params provided',
function() {
jobBundlesFactoryMock.getList.and.returnValue([{
id: 9,
job_bundles: []
}]);
$location.url('/post-project?skill_subcategory=89');
var ctrl = createCtrl();
$scope.$digest();
expect(ctrl.project.category).toBeUndefined();
});
it('should set project type to local if category is local jobs',
function() {
$route.current.loadedTemplateUrl = 'template';
jobBundlesFactoryMock.getList.and.returnValue([{
id: 9,
job_bundles: []
}]);
$location.url('/post-project?skill_category=9');
var ctrl = createCtrl();
$scope.$digest();
expect(ctrl.project.local).toBeTruthy();
});
describe('Method: setLocalOption()', function() {
beforeEach(function() {
$route.current.locals.user.get.and.returnValue(UserMock());
});
it('should set local prop to true if category selected is local jobs',
function() {
var category = {
id: 9,
name: 'General Labor, Cleaning, Photography...'
};
var ctrl = createCtrl();
ctrl.setLocalOption(category);
expect(ctrl.project.local).toBeTruthy();
expect(ProjectLocationMock.getLocation).toHaveBeenCalled();
});
it('should set local prop to false if category selected is not local',
function() {
var category = {
id: 1
};
var ctrl = createCtrl();
ctrl.setLocalOption(category);
expect(ctrl.project.local).toBeFalsy();
expect(ProjectLocationMock.getLocation).not.toHaveBeenCalled();
});
});
});
describe('Loading budgets and currencies', function() {
it('should default to USD currency if no currency selected yet ' +
'and no default', function() {
var newProject = ProjectMock();
delete newProject.currency;
projectFactoryMock.get.and.returnValue(newProject);
var ctrl = createCtrl();
$scope.$digest();
expect(ctrl.project.currency).toEqual(jasmine
.objectContaining(defaultCurrency.get()));
});
describe('Method: formatBudget()', function() {
it('should format the budget selector labels',
function() {
var ctrl = createCtrl();
ctrl.formatBudget({
maximum: true
}, { sign: '$' });
expect(currencyFilterMock).toHaveBeenCalled();
});
});
describe('Method: setBudgetLists()', function() {
it('should set the budget list for different project types',
function() {
var budgets = BudgetListMock().budgets;
var ctrl = createCtrl();
ctrl.setBudgetLists(budgets);
expect(ctrl.budgets.fixed[0]).toBe(budgets[2]);
});
});
describe('Method: getDefaultBudget()', function() {
it('should get default budget from index and project type',
function() {
var ctrl = createCtrl();
ctrl.budgets = {
fixed: [BudgetMock()]
};
ctrl.project = { currency: { id: 1 } };
ctrl.defaultProjectConfig.budgetIndex = 0;
var defaultBudget = ctrl.getDefaultBudget('fixed');
expect(defaultBudget).toEqual(jasmine.objectContaining(BudgetMock()));
});
});
describe('Method: getMaxBudgetByProjType()', function() {
var budgetListMock, ctrl;
beforeEach(function() {
budgetListMock = BudgetListMock().budgets;
budgetsFactoryMock.getList.and.returnValue(budgetListMock);
ctrl = createCtrl();
ctrl.budgetList = budgetsFactoryMock;
ctrl.project = { currency: { id: 1 } };
});
it('should get the maximum according to hourly proj type', function() {
var maxBudget = ctrl.getMaxBudgetByProjType(15, 'hourly');
expect(maxBudget).toEqual(jasmine.objectContaining(budgetListMock[1]));
});
it('should get the maximum according to default proj type', function() {
var maxBudget = ctrl.getMaxBudgetByProjType(29);
expect(maxBudget).toEqual(jasmine.objectContaining(budgetListMock[2]));
});
});
});
});
;