UNPKG

gaf-mobile

Version:

GAF mobile Web site

1,062 lines (864 loc) 33.5 kB
'use strict'; /* 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 + '&currency=' + 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])); }); }); }); });