UNPKG

gaf-mobile

Version:

GAF mobile Web site

535 lines (423 loc) 17.5 kB
'use strict'; /* global BudgetListMock */ /* global ProjectMock */ /* global TemplateMock */ /* global UserMock */ describe('Controller: FindPageCtrl', function() { var ProjectTemplatesMock, CurrenciesMock, BudgetsMock, CookieStoreMock, TranslationsMock, ProjectsMock, questionsTranslationsDomain, answersTranslationsDomain; var createCtrl, loggedInUserMock, jobMock, templateMock, projectMock, budgetFactoryMock, currencyFactoryMock; var $scope, $q, $location; beforeEach(function() { module('gafMobileApp'); inject(function($rootScope, $controller, _$q_, _$location_) { $scope = $rootScope.$new(); $q = _$q_; $location = _$location_; loggedInUserMock = { get: function() { return UserMock(); } }; jobMock = { 'category': { 'id': 1, }, 'id': 3, 'name': 'PHP', 'seo_url': 'php', 'seo_info': { 'phrase_worker': 'PHP Developer', 'plural_phrase_worker': 'PHP Developers', } }; templateMock = TemplateMock(); templateMock.dynamic_questions[0].answers = []; projectMock = jasmine.createSpyObj('currentProject', ['get', 'isReady', 'markAsReady']); projectMock.get.and.returnValue(ProjectMock()); ProjectsMock = jasmine.createSpyObj('Projects', ['post', 'getCurrent', 'setCurrent', 'projectFactory']); ProjectsMock.post.and.returnValue($q.when()); ProjectsMock.getCurrent.and.returnValue(projectMock); TranslationsMock = jasmine.createSpyObj('Translations', [ 'getTranslationFromString']); TranslationsMock.getTranslationFromString.and.returnValue($q.when()); ProjectTemplatesMock = jasmine.createSpyObj('ProjectTemplates', [ 'getNextQuestion', 'createDescription']); CookieStoreMock = jasmine.createSpyObj('CookieStore', ['get']); currencyFactoryMock = jasmine.createSpyObj('currencyFactoryMock', ['getList', 'getById']); budgetFactoryMock = jasmine.createSpyObj('budgetFactory', ['getList']); budgetFactoryMock.getList.and.returnValue(BudgetListMock().budgets); BudgetsMock = jasmine.createSpyObj('Budgets', ['getWithCurrencies']); BudgetsMock.getWithCurrencies.and.returnValue($q.when({ budgets: budgetFactoryMock, currencies: currencyFactoryMock })); questionsTranslationsDomain = 'questions/trans/domain'; answersTranslationsDomain = 'answers/trans/domain'; createCtrl = function() { return $controller('FindPageCtrl', { loggedInUser: loggedInUserMock, job: jobMock, template: templateMock, ProjectTemplates: ProjectTemplatesMock, Currencies: CurrenciesMock, Budgets: BudgetsMock, CookieStore: CookieStoreMock, Translations: TranslationsMock, Projects: ProjectsMock, $q: $q, $location: $location, TEMPLATEQS_TRANSLATION_DOMAIN: questionsTranslationsDomain, TEMPLATEANS_TRANSLATION_DOMAIN: answersTranslationsDomain }); }; }); }); describe('Initialization', function() { describe('when there is a current saved project', function() { var current; beforeEach(function() { current = { title: 'My Title', currency: { id: 3 } }; projectMock.get.and.returnValue(current); }); it('should set the project to be the current saved project', function() { ProjectsMock.getCurrent.and.returnValue(projectMock); var ctrl = createCtrl(); expect(ctrl.project).toEqual(current); }); it('should post the current saved project if it is ready', function() { projectMock.isReady.and.returnValue(true); ProjectsMock.getCurrent.and.returnValue(projectMock); ProjectsMock.projectFactory.and.returnValue(projectMock); createCtrl(); expect(ProjectsMock.post).toHaveBeenCalledWith(projectMock); }); }); describe('when there is no current saved project', function() { it('should set the project title to the template default', function() { projectMock.get.and.returnValue({}); ProjectsMock.getCurrent.and.returnValue(projectMock); var ctrl = createCtrl(); $scope.$digest(); expect(ctrl.project.title).toEqual(templateMock.project_title); }); }); it('should get the current language set using the cookie', function() { var language = 'en'; CookieStoreMock.get.and.returnValue(language); var ctrl = createCtrl(); expect(ctrl.lang).toEqual(language); }); it('should translate the first dynamic question', function() { var lang = 'es'; CookieStoreMock.get.and.returnValue(lang); templateMock.dynamic_questions[0].answers = []; var questionText = templateMock.dynamic_questions[0] .project_template_question_text.question_text; createCtrl(); $scope.$digest(); expect(TranslationsMock.getTranslationFromString) .toHaveBeenCalledWith(questionText, questionsTranslationsDomain, lang); }); }); describe('Method: workInstead', function() { it('should redirect to the signup page if user is logged out', function() { loggedInUserMock = undefined; var ctrl = createCtrl(); ctrl.workInstead(); expect($location.url()).toEqual('/signup?role=freelancer'); }); it('should redirect to the jobs page if user is logged in', function() { loggedInUserMock = UserMock(); var ctrl = createCtrl(); ctrl.workInstead(); expect($location.url()).toEqual('/jobs'); }); }); describe('Method: getAnswerTranslation', function() { var ctrl; beforeEach(function() { ctrl = createCtrl(); // Since this is called upon init of the controller for the translation // of the first question, let's reset the calls for this spy to correctly // test the cases below TranslationsMock.getTranslationFromString.calls.reset(); }); it('should resolve immediately if language is English', function() { var lang = 'en'; var answer = templateMock.answers[0]; ctrl.getAnswerTranslation(answer, answersTranslationsDomain, lang); expect(TranslationsMock.getTranslationFromString).not.toHaveBeenCalled(); }); it('should call the Translations service for the translation of the answer', function() { var lang = 'fil'; var answer = templateMock.answers[0]; var answerText = answer.answer; ctrl.getAnswerTranslation(answer, answersTranslationsDomain, lang); $scope.$digest(); expect(TranslationsMock.getTranslationFromString).toHaveBeenCalledWith( answerText, answersTranslationsDomain, lang); }); it('should return the untranslated question if API fails', function() { var lang = 'fil'; var answer = templateMock.answers[0]; TranslationsMock.getTranslationFromString.and.returnValue($q.reject()); var translated; ctrl.getAnswerTranslation(answer, answersTranslationsDomain, lang) .then(function(response) { translated = response; }); $scope.$digest(); expect(translated).toEqual(answer); }); }); describe('Method: getQuestionTranslation', function() { var ctrl; beforeEach(function() { ctrl = createCtrl(); // Since this is called upon init of the controller for the translation // of the first question, let's reset the calls for this spy to correctly // test the cases below TranslationsMock.getTranslationFromString.calls.reset(); }); it('should resolve immediately if language is English', function() { var lang = 'en'; var question = templateMock.questions['1']; ctrl.getQuestionTranslation(question, questionsTranslationsDomain, lang); expect(TranslationsMock.getTranslationFromString).not.toHaveBeenCalled(); }); it('should call the Translations service for the translation of question', function() { var lang = 'fil'; var question = templateMock.questions['1']; var questionText = question.project_template_question_text.question_text; question.answers = []; ctrl.getQuestionTranslation(question, questionsTranslationsDomain, lang); $scope.$digest(); expect(TranslationsMock.getTranslationFromString).toHaveBeenCalledWith( questionText, questionsTranslationsDomain, lang); }); it('should get the translation of each of its answers as well', function() { var lang = 'fil'; var question = templateMock.questions['1']; var questionText = question.project_template_question_text.question_text; var answer = templateMock.answers[0]; var answerText = answer.answer; question.answers = [answer]; ctrl.getQuestionTranslation(question, questionsTranslationsDomain, lang); $scope.$digest(); expect(TranslationsMock.getTranslationFromString.calls.argsFor(0)) .toEqual([questionText, questionsTranslationsDomain, lang]); expect(TranslationsMock.getTranslationFromString.calls.argsFor(1)) .toEqual([answerText, answersTranslationsDomain, lang]); }); it('should return the untranslated question if API fails', function() { var lang = 'fil'; var question = templateMock.questions['1']; TranslationsMock.getTranslationFromString.and.returnValue($q.reject()); var translated; ctrl.getQuestionTranslation(question, questionsTranslationsDomain, lang) .then(function(response) { translated = response; }); $scope.$digest(); expect(translated).toEqual(question); }); }); describe('Method: electAnswer', function() { it('should only keep the questions and answers whose question ID is ' + 'less than the current answer\'s question ID', function() { ProjectTemplatesMock.getNextQuestion.and.returnValue(null); var ctrl = createCtrl(); // given user has answered 2 questions already ctrl.questions = [ templateMock.questions['1'], templateMock.questions['2'] ]; ctrl.answers = [ templateMock.answers[0], templateMock.answers[1] ]; // re-answer first question ctrl.electAnswer(templateMock.questions['1'], templateMock.answers[0]); expect(ctrl.questions).toEqual([templateMock.questions['1']]); expect(ctrl.answers).toEqual([templateMock.answers[0]]); }); it('should fetch the next translated question', function() { ProjectTemplatesMock.createDescription.and.returnValue(''); ProjectTemplatesMock.getNextQuestion.and.returnValue( templateMock.questions['2']); var question = templateMock.questions['1']; var answer = templateMock.answers[0]; var ctrl = createCtrl(); spyOn(ctrl, 'getQuestionTranslation').and.returnValue($q.when()); ctrl.electAnswer(question, answer); $scope.$digest(); expect(ProjectTemplatesMock.getNextQuestion).toHaveBeenCalledWith( templateMock, question, ctrl.answers); expect(ctrl.getQuestionTranslation).toHaveBeenCalled(); }); it('should set at most 5 project jobs based on the answer', function() { var question = templateMock.questions['1']; var answer = templateMock.answers[0]; var ctrl = createCtrl(); ctrl.electAnswer(question, answer); expect(ctrl.project.jobs).toEqual(answer.jobs.slice(0, 5)); }); it('should update the project description', function() { var question = templateMock.questions['1']; var answer = templateMock.answers[0]; var ctrl = createCtrl(); ctrl.electAnswer(question, answer); expect(ProjectTemplatesMock.createDescription).toHaveBeenCalledWith( templateMock, ctrl.answers); }); }); describe('Method: electFreeformAnswer', function() { it('should set a formatted freeform answer to the list of answers', function() { var question = templateMock.questions['1']; var freeformAnswer = 'my freeform answer'; var formattedAnswer = { question_id: question.id, answer_text: freeformAnswer }; var ctrl = createCtrl(); spyOn(ctrl, 'electAnswer'); ctrl.electFreeformAnswer(question, freeformAnswer, 0); expect(ctrl.answers).toEqual([formattedAnswer]); expect(ctrl.electAnswer).toHaveBeenCalledWith(question, formattedAnswer); }); it('should accept a blank freeform answer', function() { var question = templateMock.questions['1']; var freeformAnswer; var formattedAnswer = { question_id: question.id, answer_text: '' }; var ctrl = createCtrl(); spyOn(ctrl, 'electAnswer'); ctrl.electFreeformAnswer(question, freeformAnswer, 0); expect(ctrl.answers).toEqual([formattedAnswer]); expect(ctrl.electAnswer).toHaveBeenCalledWith(question, formattedAnswer); }); }); describe('Method: setBudgetsForCurrency', function() { it('should filter the budgets list depending on currency', function() { var currencyId = 1; var budgetList = [ { currency_id: 1, name: 'budget 1' }, { currency_id: 1, name: 'budget 2' }, { currency_id: 2, name: 'budget 3' } ]; budgetFactoryMock.getList.and.returnValue(budgetList); var ctrl = createCtrl(); $scope.$digest(); ctrl.setBudgetsForCurrency(currencyId); expect(ctrl.budgetsForCurrency).toEqual([budgetList[0], budgetList[1]]); }); }); describe('Method: formatBudget', function() { it('should return the budget range in string form', function() { var currency = { id: 1, sign: '$' }; var budget = { minimum: 10, maximum: 30 }; var ctrl = createCtrl(); var formattedBudget = ctrl.formatBudget(budget, currency); expect(formattedBudget).toEqual('$10 - $30'); }); it('should return the budget range in string form even if there is no ' + 'maximum budget defined', function() { var currency = { id: 1, sign: '$' }; var budget = { minimum: 50 }; var ctrl = createCtrl(); var formattedBudget = ctrl.formatBudget(budget, currency); expect(formattedBudget).toEqual('$50+'); }); }); describe('Method: postProject', function() { describe('when the user is logged in', function() { var project; beforeEach(function() { loggedInUserMock = UserMock(); project = ProjectMock(); projectMock.get.and.returnValue(project); ProjectsMock.projectFactory.and.returnValue(projectMock); }); it('redirect to the PVP of the new project if successful', function() { var newProject = angular.extend(project, { id: 1234567 }); ProjectsMock.post.and.returnValue($q.when({ get: function() { return newProject; }, set: jasmine.createSpy() })); var ctrl = createCtrl(); ctrl.postProject(project); $scope.$digest(); expect($location.url()).toEqual('/projects/project-1234567#bids'); }); it('should redirect to the payment verification page if API returned ' + 'that error', function() { var currentUrl = '/find/skill'; $location.url(currentUrl); var error = { code: 'UNVERIFIED_PAYMENT' }; ProjectsMock.post.and.returnValue($q.reject(error)); var ctrl = createCtrl(); ctrl.postProject(project); $scope.$digest(); expect($location.url()).toEqual('/payments/verify' + '?postProject=true&return=' + encodeURIComponent(currentUrl)); }); it('should set the error variable to be negative balance', function() { var error = { code: 'NEGATIVE_BALANCE' }; ProjectsMock.post.and.returnValue($q.reject(error)); var ctrl = createCtrl(); ctrl.postProject(project); $scope.$digest(); expect(ctrl.error.negativeBalance).toBeTruthy(); }); it('should set the error variable to internal error for others', function() { var error = { code: 'SOME_OTHER_ERROR' }; ProjectsMock.post.and.returnValue($q.reject(error)); var ctrl = createCtrl(); ctrl.postProject(project); $scope.$digest(); expect(ctrl.error.internalError).toBeTruthy(); }); }); describe('when the user is logged out', function() { var project, currentUrl; beforeEach(function() { loggedInUserMock = undefined; project = ProjectMock(); projectMock.get.and.returnValue(project); ProjectsMock.projectFactory.and.returnValue(projectMock); currentUrl = '/find/skill'; $location.url(currentUrl); var ctrl = createCtrl(); ctrl.postProject(project); }); it('should save the project as the current', function() { expect(ProjectsMock.setCurrent).toHaveBeenCalledWith(projectMock); }); it('should mark the project as ready', function() { expect(projectMock.markAsReady).toHaveBeenCalledWith(true); }); it('should redirect to the signup page', function() { expect($location.url()).toEqual('/signup?role=employer&return=' + encodeURIComponent(currentUrl)); }); }); }); });