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

Commit d0b04c1

Browse files
committed
Merge pull request #766 from appirio-tech/qa-integration
QA -> Prod
2 parents 6f0fcb4 + 99de640 commit d0b04c1

File tree

8 files changed

+162
-41
lines changed

8 files changed

+162
-41
lines changed

app/directives/tc-file-input/tc-file-input.directive.js

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import _ from 'lodash'
44
(function() {
55
'use strict'
66

7-
angular.module('tcUIComponents').directive('tcFileInput', ['$timeout', tcFileInput])
7+
angular.module('tcUIComponents').directive('tcFileInput', ['$timeout', 'Helpers', 'logger', tcFileInput])
88

9-
function tcFileInput($timeout) {
9+
function tcFileInput($timeout, Helpers, logger) {
1010
return {
1111
restrict: 'E',
1212
require: '^form',
@@ -26,14 +26,6 @@ import _ from 'lodash'
2626
scope.selectFile = selectFile
2727
var fileTypes = scope.fileType.split(',')
2828

29-
// Add extra checks for Windows zip file types
30-
var hasZip = _.some(fileTypes, _.matches('zip'))
31-
32-
if (hasZip) {
33-
fileTypes = angular.copy(fileTypes)
34-
fileTypes.push('x-zip', 'x-zip-compressed')
35-
}
36-
3729
// fieldId is not set on element at this point, so grabbing with class .none
3830
// which exists on the element right away
3931
var fileInput = $(element[0]).find('.none')
@@ -49,10 +41,16 @@ import _ from 'lodash'
4941
}
5042

5143
var fileSize = file.size
52-
var isAllowedFileSize = fileSize < '524288000'
44+
var fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
5345

54-
var selectedFileType = file.type.slice(file.type.lastIndexOf('/') + 1)
55-
var isAllowedFileFormat = _.some(fileTypes, _.matches(selectedFileType))
46+
var isAllowedFileSize = fileSize < '524288000'
47+
var isAllowedFileExt = _.some(fileTypes, _.matches(fileExtension))
48+
var isAllowedMIMEType = Helpers.isValidMIMEType(file.type, fileExtension)
49+
var isAllowedFileFormat = isAllowedFileExt && isAllowedMIMEType
50+
51+
if (file && !isAllowedFileFormat) {
52+
logger.error(`Invalid file. Allowed extensions: ${scope.fileType}. Recieved file extension ${fileExtension} with MIME type ${file.type} and file size ${fileSize}`)
53+
}
5654

5755
// Timeout needed for fixing IE bug ($apply already in progress)
5856
$timeout(function() {

app/directives/tc-file-input/tc-file-input.spec.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,28 @@ describe('Topcoder File Input Directive', function() {
161161
})
162162
})
163163

164+
describe('with a file extension that is not in the list of fileTypes given to the directive', function() {
165+
beforeEach(function() {
166+
fileList[0].name = 'submission.zip.jpg'
167+
168+
$(fileInput).triggerHandler({
169+
type: 'change',
170+
target: { files: fileList }
171+
})
172+
173+
$timeout.flush()
174+
})
175+
176+
it('does not call setFileReference', function() {
177+
expect(mockSetFileReference).not.calledOnce
178+
})
179+
180+
it('has ng-touched and ng-invalid-required classes', function() {
181+
expect($(fileInput).hasClass('ng-invalid-required')).to.be.true
182+
expect($(fileInput).hasClass('ng-touched')).to.be.true
183+
})
184+
})
185+
164186
describe('with a file that\'s greater than 500MB', function() {
165187
beforeEach(function() {
166188
fileList[0].size = 524288001

app/layout/header/header.controller.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import _ from 'lodash'
2525
// window.location.replace(vm.constants.MAIN_URL + '/search?s=' + vm.searchTerm + '&scope=member')
2626

2727
// Replace with new member search url
28-
window.location.replace('/search/members/?q=' + vm.searchTerm)
28+
window.location.replace('/search/members/?q=' + window.encodeURIComponent(vm.searchTerm))
2929
}
3030
}
3131

app/my-dashboard/my-dashboard.jade

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
.challenges(id="challenges", ui-view="my-challenges")
77

8-
.ttl
9-
tc-banner(theme="black", banner-name="ttl")
8+
//- .ttl
9+
//- tc-banner(theme="black", banner-name="ttl")
1010
1111
.tco
1212
tc-banner(theme="black", banner-name="tco16")

app/services/bannerDataService.js

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,20 @@ import angular from 'angular'
3535
url: 'http://tco16.topcoder.com/latest/overview/',
3636
cssClass: 'tc-btn tc-btn-s tco-cta'
3737
}]
38-
},
39-
'ttl': {
40-
title: 'Episode #3 | Featuring Jessie D’Amato Ford',
41-
img: require('../../assets/images/team-live-logo.png'),
42-
description: 'APR 15 / 10:30am EST / Live on <a href="https://plus.google.com/events/c86vvsum04lmq3bnd0bqp719img"> #GoogleHangoutOnAir</a>',
43-
ctas: [{
44-
title: 'Tune In',
45-
url: 'https://plus.google.com/events/c86vvsum04lmq3bnd0bqp719img',
46-
cssClass: 'tc-btn tc-btn-s'
47-
}]
4838
}
39+
// Commenting out instead of deleting in case there is
40+
// another one with a similar format soon
41+
42+
// 'ttl': {
43+
// title: 'Episode #3 | Featuring Jessie D’Amato Ford',
44+
// img: require('../../assets/images/team-live-logo.png'),
45+
// description: 'APR 15 / 10:30am EST / Live on <a href="https://plus.google.com/events/c86vvsum04lmq3bnd0bqp719img"> #GoogleHangoutOnAir</a>',
46+
// ctas: [{
47+
// title: 'Tune In',
48+
// url: 'https://plus.google.com/events/c86vvsum04lmq3bnd0bqp719img',
49+
// cssClass: 'tc-btn tc-btn-s'
50+
// }]
51+
// }
4952
}
5053
}
5154
}

app/services/helpers.service.js

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import angular from 'angular'
2+
import _ from 'lodash'
23

34
(function() {
45
'use strict'
@@ -21,8 +22,8 @@ import angular from 'angular'
2122
redirectPostLogin: redirectPostLogin,
2223
getSocialUserData: getSocialUserData,
2324
setupLoginEventMetrics: setupLoginEventMetrics,
24-
npad: npad
25-
25+
npad: npad,
26+
isValidMIMEType: isValidMIMEType
2627
}
2728
return service
2829

@@ -297,5 +298,50 @@ import angular from 'angular'
297298
function npad(toPad, n) {
298299
return $filter('npad')(toPad, n)
299300
}
301+
302+
function isValidMIMEType(mimeType, fileExt) {
303+
var areStrings = _.isString(mimeType) && _.isString(fileExt)
304+
305+
if (!areStrings) {
306+
return false
307+
}
308+
309+
var mimeTypesByExtension = {
310+
zip: [
311+
'application/zip',
312+
'application/x-zip',
313+
'application/x-zip-compressed',
314+
'application/octet-stream',
315+
'application/x-compress',
316+
'application/x-compressed',
317+
'multipart/x-zip'
318+
],
319+
jpeg: [
320+
'image/jpeg',
321+
'image/jpg',
322+
'image/jpe_',
323+
'image/pjpeg',
324+
'image/vnd.swiftview-jpeg'
325+
],
326+
jpg: [
327+
'image/jpeg',
328+
'image/jpg',
329+
'image/jp_',
330+
'application/jpg',
331+
'application/x-jpg',
332+
'image/pjpeg',
333+
'image/pipeg',
334+
'image/vnd.swiftview-jpeg',
335+
'image/x-xbitmap'
336+
],
337+
png: [
338+
'image/png',
339+
'application/png',
340+
'application/x-png'
341+
]
342+
}
343+
344+
return _.some(mimeTypesByExtension[fileExt], _.matches(mimeType))
345+
}
300346
}
301347
})()

app/services/helpers.service.spec.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,4 +390,25 @@ describe('Helper Service', function() {
390390
expect($window._kmq[0][1]).to.exist.to.equal('mockuser')
391391
})
392392
})
393+
394+
describe('isValidMIMEType', function() {
395+
it('should return false for for non string arguments', function() {
396+
expect(Helpers.isValidMIMEType()).to.be.false
397+
expect(Helpers.isValidMIMEType(1, 'jpg')).to.be.false
398+
expect(Helpers.isValidMIMEType('application/zip', {})).to.be.false
399+
})
400+
401+
it('should return false for an unsupported file extension', function() {
402+
expect(Helpers.isValidMIMEType('application/zip', 'zip314')).to.be.false
403+
})
404+
405+
it('should return false for an unsupported MIME type', function() {
406+
expect(Helpers.isValidMIMEType('application/zip314', 'zip')).to.be.false
407+
})
408+
409+
it('should return true for valid MIME types and file extensions', function() {
410+
expect(Helpers.isValidMIMEType('application/zip', 'zip')).to.be.true
411+
expect(Helpers.isValidMIMEType('image/png', 'png')).to.be.true
412+
})
413+
})
393414
})

assets/images/nav/ico-tco16.svg

Lines changed: 44 additions & 13 deletions
Loading

0 commit comments

Comments
 (0)