Skip to content
This repository was archived by the owner on Mar 4, 2025. It is now read-only.

Commit 486deb5

Browse files
author
Parth Shah
committed
Merge branch 'qa-integration'
2 parents ddb51fd + 99e8628 commit 486deb5

File tree

194 files changed

+5093
-2330
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

194 files changed

+5093
-2330
lines changed

app/account/register/register.jade

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
p.form-error(ng-message="required") Please enter an email address.
8484

8585
.validation-bar(ng-class="{ 'success-bar': (vm.registerForm.password.$valid) }")
86-
toggle-password-with-tips(ng-if="!vm.isSocialRegistration")
86+
toggle-password-with-tips(ng-if="!vm.isSocialRegistration", placeholder="Create Password")
8787

8888
.tips.password-tips(ng-show="vm.passwordFocus")
8989
.arrow

app/directives/account/toggle-password-with-tips/toggle-password-with-tips.directive.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
link: function(scope, element, attrs, formController) {
1212
var vm = scope.vm;
1313
vm.passwordField = formController.password;
14+
vm.defaultPlaceholder = attrs.placeholder || 'Create new password';
1415
vm.placeholder = vm.defaultPlaceholder;
1516
vm.password = '';
1617

@@ -40,6 +41,7 @@
4041
if (relatedTarget.attr('type') === 'checkbox' && relatedTarget.attr('id') === 'passwordCheckbox') {
4142
vm.passwordFocus = true;
4243
vm.placeholder = '';
44+
passwordInput.focus();
4345
} else {
4446
// If you are blurring from the password input and clicking anywhere but the checkbox
4547
vm.passwordFocus = false;

app/directives/account/toggle-password-with-tips/toggle-password-with-tips.jade

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
input#password-input(
22
ng-model="vm.password",
33
ng-model-options="{allowInvalid: true}",
4-
5-
focus-on="focusOnInput",
4+
65
ng-focus="vm.onFocus($event)",
76
ng-blur="vm.onBlur($event)",
87

@@ -17,4 +16,4 @@ input#password-input(
1716
has-symbol-or-number,
1817
required)
1918

20-
label(ng-show="vm.passwordFocus || vm.passwordField.$dirty") #[input(type="checkbox", id="passwordCheckbox", ng-model="focusOnInput", ng-change="vm.toggleInputType()")] Show
19+
label #[input(type="checkbox", id="passwordCheckbox", ng-model="focusOnInput", ng-change="vm.toggleInputType()")] Show

app/directives/account/toggle-password-with-tips/toggle-password-with-tips.spec.js

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,145 @@ describe('Toggle Password With Tips Directive', function() {
99
bard.appModule('topcoder');
1010
bard.inject(this, '$compile', '$rootScope');
1111
scope = $rootScope.$new();
12+
scope.vm = {};
1213
});
1314

1415
bard.verifyNoOutstandingHttpRequests();
16+
17+
describe('Toggle Password Directive', function() {
18+
var togglePassword, controller, formController, passwordFormFieldSpy;
19+
20+
beforeEach(function() {
21+
var form = angular.element('<form><toggle-password-with-tips /></form>)');
22+
element = form.find('toggle-password-with-tips');
23+
var formElement = $compile(form)(scope);
24+
scope.$digest();
25+
26+
// controller = element.controller('togglePassword');
27+
formController = form.controller('form');
28+
passwordFormFieldSpy = sinon.spy(formController.password, '$setPristine');
29+
});
30+
31+
afterEach(function() {
32+
// do nohting
33+
});
34+
35+
it('should have password default placeholder', function() {
36+
expect(scope.vm.defaultPlaceholder).to.exist.to.equal('Create new password');
37+
expect(scope.vm.placeholder).to.exist.to.equal('Create new password');
38+
});
39+
40+
it('should not have focus class', function() {
41+
expect(element.hasClass('focus')).to.be.false;
42+
});
43+
44+
it('should trigger click handler ', function() {
45+
var mockFocus = sinon.spy(element.find('input')[0], 'focus');
46+
element.trigger('click');
47+
expect(mockFocus).to.be.calledOnce;
48+
});
49+
50+
it('should trigger focus handler ', function() {
51+
var pwsIntputElement = angular.element(element.find('input')[0]);
52+
pwsIntputElement.triggerHandler('focus');
53+
expect(element.hasClass('focus')).to.be.true;
54+
});
55+
56+
it('should trigger blur handler with form field pristine ', function() {
57+
var pwsIntputElement = angular.element(element.find('input')[0]);
58+
// focus it first
59+
pwsIntputElement.triggerHandler('focus');
60+
// verifies if focus class is added
61+
expect(element.hasClass('focus')).to.be.true;
62+
// now blurs from it
63+
pwsIntputElement.triggerHandler('blur');
64+
// focus class should not be there
65+
expect(element.hasClass('focus')).to.be.false;
66+
// password field's setPristine method should be called once because currentPassword is empty
67+
expect(passwordFormFieldSpy).to.be.calledOnce;
68+
});
69+
70+
it('should trigger blur handler without form field pristine ', function() {
71+
scope.vm.password = 'some-password';
72+
scope.$digest();
73+
var pwsIntputElement = angular.element(element.find('input')[0]);
74+
// focus it first
75+
pwsIntputElement.triggerHandler('focus');
76+
// verifies if focus class is added
77+
expect(element.hasClass('focus')).to.be.true;
78+
// now blurs from it
79+
pwsIntputElement.triggerHandler('blur');
80+
// focus class should not be there
81+
expect(element.hasClass('focus')).to.be.false;
82+
// password field's setPristine method should not be called because currentPassword is non-empty
83+
expect(passwordFormFieldSpy).not.to.be.called;
84+
});
85+
86+
it('should keep focus on password field on blurring to checkbox ', function() {
87+
88+
var pwsIntputElement = angular.element(element.find('input')[0]);
89+
// focus it first
90+
pwsIntputElement.triggerHandler('focus');
91+
// verifies if focus class is added
92+
expect(element.hasClass('focus')).to.be.true;
93+
// now blurs from it
94+
95+
var e = jQuery.Event("blur");
96+
e.relatedTarget = {
97+
getAttribute: function(name) {
98+
if (name === 'type') return 'checkbox';
99+
if (name === 'id') return 'passwordCheckbox';
100+
}
101+
};
102+
//mock focus event
103+
var mockFocus = sinon.spy(element.find('input')[0], 'focus');
104+
// trigger event
105+
pwsIntputElement.trigger(e);
106+
107+
// focus should be called once
108+
expect(mockFocus).to.be.calledOnce;
109+
// password field placeholde should be empty
110+
expect(scope.vm.placeholder).to.exist.to.equal('');
111+
});
112+
113+
it('should change type of input field to be text ', function() {
114+
var pwsIntputElement = angular.element(element.find('input')[0]);
115+
var checkbox = angular.element(element.find('input')[1]);
116+
// before clicking on checkbox, it should have password type
117+
expect(pwsIntputElement.attr('type')).to.equal('password');
118+
checkbox.trigger('click');
119+
// after clicking on checkbox, it should have text type
120+
expect(pwsIntputElement.attr('type')).to.equal('text');
121+
});
122+
123+
it('should change type of input field to be password ', function() {
124+
var pwsIntputElement = angular.element(element.find('input')[0]);
125+
var checkbox = angular.element(element.find('input')[1]);
126+
// before clicking on checkbox, it should have password type
127+
expect(pwsIntputElement.attr('type')).to.equal('password');
128+
checkbox.trigger('click');
129+
// after clicking on checkbox, it should have text type
130+
expect(pwsIntputElement.attr('type')).to.equal('text');
131+
// click again to uncheck the checkbox
132+
checkbox.trigger('click');
133+
// after unchecking the checkbox, it should have password type
134+
expect(pwsIntputElement.attr('type')).to.equal('password');
135+
});
136+
137+
it('should trigger keyup handler with enter/return key ', function() {
138+
var mockBlur = sinon.spy(element.find('input')[0], 'blur');
139+
var e = jQuery.Event("keyup");
140+
e.keyCode = 13;
141+
element.trigger(e);
142+
expect(mockBlur).to.be.calledOnce;
143+
});
144+
145+
it('should NOT trigger keyup handler with non enter/return key ', function() {
146+
var mockBlur = sinon.spy(element.find('input')[0], 'blur');
147+
var e = jQuery.Event("keyup");
148+
e.keyCode = 14;
149+
element.trigger(e);
150+
expect(mockBlur).not.to.be.called;
151+
});
152+
});
15153
});

app/directives/account/toggle-password/toggle-password.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* jshint -W117, -W030 */
2-
xdescribe('Toggle Password Directive', function() {
2+
describe('Toggle Password Directive', function() {
33
var scope;
44
var element;
55

app/directives/on-file-change.directive.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
return {
1212
restrict: 'A',
1313
link: function(scope, element, attr, ctrl) {
14-
element.bind("change", function() {
14+
element.bind('change', function() {
1515
scope.vm.onFileChange(element[0].files[0]);
1616
this.value = '';
1717
});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.progress-bar
2+
.progress-bar__bar
3+
.progress-bar__bar--completed
4+
.progress-bar__summary
5+
span(ng-bind="completed")
6+
span % {{message}}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
(function() {
2+
'use strict';
3+
4+
angular.module('tcUIComponents').directive('progressBar', progressBar);
5+
6+
progressBar.$inject = ['$timeout', '$parse'];
7+
8+
function progressBar($timeout, $parse) {
9+
return {
10+
restrict: 'E',
11+
templateUrl: 'directives/progress-bar/progress-bar.directive.html',
12+
link: function(scope, element, attr) {
13+
var model = $parse(attr.completed);
14+
var msg = attr.message;
15+
var progress = angular.element(element[0].querySelector('.progress-bar__bar--completed'));
16+
17+
scope.$watch(model, function(newValue, oldValue) {
18+
scope.completed = Math.round(newValue);
19+
// console.log("Updating progress bar with " + scope.completed);
20+
scope.message = msg;
21+
progress.css('width', scope.completed + '%')
22+
});
23+
},
24+
controller: ['$scope', function($scope) {
25+
26+
}]
27+
};
28+
}
29+
})();
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
(function() {
2+
'use strict';
3+
4+
angular.module('tcUIComponents').directive('tcFileInput', tcFileInput);
5+
6+
function tcFileInput() {
7+
return {
8+
restrict: 'E',
9+
require: '^form',
10+
templateUrl: 'directives/tc-file-input/tc-file-input.html',
11+
scope: {
12+
labelText: '@',
13+
fieldId: '@',
14+
placeholder: '@',
15+
fileType: '@',
16+
showFileType: '=',
17+
mandatory: '=',
18+
buttonText: '@',
19+
setFileReference: '&',
20+
ngModel: '='
21+
},
22+
link: function(scope, element, attrs, formController) {
23+
scope.selectFile = selectFile;
24+
var fileTypes = scope.fileType.split(',');
25+
26+
// fieldId is not set on element at this point, so grabbing with class .none
27+
// which exists on the element right away
28+
var fileInput = $(element[0]).find('.none');
29+
var fileNameInput = $(element[0]).find('input[type=text]');
30+
31+
fileInput.bind('change', function() {
32+
var file = fileInput[0].files[0];
33+
34+
// About 1 in 20 times, the file is undefined (must be race condition)
35+
// Return early in this case so no errors are thrown
36+
if (!file) {
37+
return;
38+
}
39+
40+
var fileSize = file.size;
41+
var isAllowedFileSize = fileSize < '500000000';
42+
43+
var selectedFileType = file.type.slice(file.type.lastIndexOf('/') + 1);
44+
var isAllowedFileFormat = _.some(fileTypes, _.matches(selectedFileType));
45+
46+
scope.$apply(function(){
47+
// Set the file name as the value of the disabled input
48+
fileNameInput[0].value = file.name;
49+
var clickedFileInput = formController[attrs.fieldId];
50+
51+
if (!isAllowedFileFormat) {
52+
// Manually setting is required since Angular doesn't support file inputs
53+
clickedFileInput.$setTouched();
54+
clickedFileInput.$setValidity('required', false);
55+
56+
} else {
57+
clickedFileInput.$setValidity('required', true);
58+
}
59+
60+
if (!isAllowedFileSize) {
61+
// Manually setting is required since Angular doesn't support file inputs
62+
clickedFileInput.$setTouched();
63+
clickedFileInput.$setValidity('filesize', false);
64+
65+
} else {
66+
clickedFileInput.$setValidity('filesize', true);
67+
}
68+
69+
if (isAllowedFileFormat && isAllowedFileSize) {
70+
// Pass file object up through callback into controller
71+
scope.setFileReference({file: file, fieldId: scope.fieldId});
72+
}
73+
});
74+
});
75+
76+
function selectFile() {
77+
fileInput.click();
78+
}
79+
}
80+
}
81+
}
82+
})();
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.tc-file-field__label
2+
label.tc-label {{labelText}}
3+
span.lowercase(ng-if="showFileType") {{ ' *(.' + fileType + ')'}}
4+
5+
span.tc-label__mandatory.lowercase(ng-if="mandatory") #[span *]mandatory
6+
7+
.tc-file-field__inputs
8+
input.tc-file-field__input(type="text", placeholder="{{placeholder}}", disabled)
9+
10+
button.tc-btn(ng-click="selectFile()") {{buttonText}}
11+
12+
input.none(name="{{fieldId}}", type="file", required, ng-model="ngModel")
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/* jshint -W117, -W030 */
2+
describe('Topcoder File Input Directive', function() {
3+
var scope;
4+
5+
// USE AS TEMPLATE FOR DIRECTIVES
6+
7+
beforeEach(function() {
8+
bard.appModule('tcUIComponents');
9+
bard.inject(this, '$compile', '$rootScope');
10+
});
11+
12+
bard.verifyNoOutstandingHttpRequests();
13+
14+
xdescribe('', function() {
15+
beforeEach(function() {});
16+
17+
it('', function() {});
18+
});
19+
});

0 commit comments

Comments
 (0)