diff --git a/app/directives/tc-file-input/tc-file-input.directive.js b/app/directives/tc-file-input/tc-file-input.directive.js
index a7cb39c21..bc4a18554 100644
--- a/app/directives/tc-file-input/tc-file-input.directive.js
+++ b/app/directives/tc-file-input/tc-file-input.directive.js
@@ -28,8 +28,8 @@
         var fileInput = $(element[0]).find('.none');
         var fileNameInput = $(element[0]).find('input[type=text]');
 
-        fileInput.bind('change', function() {
-          var file = fileInput[0].files[0];
+        fileInput.bind('change', function(event) {
+          var file = event.target.files[0];
 
           // About 1 in 20 times, the file is undefined (must be race condition)
           // Return early in this case so no errors are thrown
diff --git a/app/directives/tc-file-input/tc-file-input.spec.js b/app/directives/tc-file-input/tc-file-input.spec.js
index 3f2b398aa..ef1917cc8 100644
--- a/app/directives/tc-file-input/tc-file-input.spec.js
+++ b/app/directives/tc-file-input/tc-file-input.spec.js
@@ -1,19 +1,148 @@
 /* jshint -W117, -W030 */
 describe('Topcoder File Input Directive', function() {
-  var scope;
-
-  // USE AS TEMPLATE FOR DIRECTIVES
+  var scope, element, isolateScope, fileInput;
 
   beforeEach(function() {
-    bard.appModule('tcUIComponents');
+    bard.appModule('topcoder');
     bard.inject(this, '$compile', '$rootScope');
+    scope = $rootScope.$new();
+
+    var html = '' +
+      '<form>' +
+        '<tc-file-input ' +
+          'label-text="Preview Image"' +
+          'field-id="DESIGN_COVER"' +
+          'button-text="Add File"' +
+          'file-type="jpg,jpeg,png"' +
+          'placeholder="Image file as .jpg or .png"' +
+          'mandatory="true"' +
+          'set-file-reference="vm.setFileReference(file, fieldId)"' +
+          'ng-model="vm.submissionForm.submissionZip"' +
+        ' />' +
+      '</form>';
+    var form = angular.element(html);
+    element = form.find('tc-file-input');
+    var formElement = $compile(form)(scope);
+    scope.$digest();
+
+    isolateScope = element.isolateScope();
+  });
+
+  beforeEach(function() {
+    fileInput = $(element).find('.none')[0];
+  });
+
+  afterEach(function() {
+    scope.$destroy();
+    fileInput = undefined;
   });
 
   bard.verifyNoOutstandingHttpRequests();
 
-  xdescribe('', function() {
-    beforeEach(function() {});
+  describe('selectFile', function() {
+    it('triggers a click on the file input', function() {
+      var mockClick = sinon.spy(fileInput, 'click');
+
+      isolateScope.selectFile();
+      scope.$digest();
+
+      expect(mockClick).calledOnce;
+    });
+  });
+
+  describe('a change event on the file input', function() {
+    var fileNameInput, fileList, mockSetFileReference;
+
+    beforeEach(function() {
+      fileNameInput = $(element).find('input[type=text]')[0];
+      fileList = {
+        0: {
+          name: 'test.png',
+          size: 50,
+          type: 'image/png'
+        },
+        length: 1,
+        item: function (index) { return file; }
+      };
+
+      mockSetFileReference = sinon.spy(isolateScope, 'setFileReference');
+    });
+
+    afterEach(function() {
+      fileNameInput = undefined;
+      fileList = undefined;
+      mockSetFileReference = undefined;
+    });
+
+    it('sets the value of the fileNameInput with the name of the file', function() {
+      $(fileInput).triggerHandler({
+        type: 'change',
+        target: { files: fileList }
+      });
+
+      expect(fileNameInput.value).to.equal('test.png');
+    });
+
+    describe('with a valid file', function() {
+      beforeEach(function() {
+        $(fileInput).triggerHandler({
+          type: 'change',
+          target: { files: fileList }
+        });
+      });
+
+      it('calls setFileReference', function() {
+        expect(mockSetFileReference).calledOnce;
+      });
+
+      it('has ng-valid-filesize class', function() {
+        expect($(fileInput).hasClass('ng-valid-filesize')).to.be.true;
+      });
+
+      it('has ng-valid-required class', function() {
+        expect($(fileInput).hasClass('ng-valid-required')).to.be.true;
+      });
+    });
+
+    describe('with a file that\'s greater than 500MB', function() {
+      beforeEach(function() {
+        fileList[0].size = 500000001;
+
+        $(fileInput).triggerHandler({
+          type: 'change',
+          target: { files: fileList }
+        });
+      });
+
+      it('does not call setFileReference', function() {
+        expect(mockSetFileReference).not.calledOnce;
+      });
+
+      it('has ng-touched and ng-invalid-filesize classes', function() {
+        expect($(fileInput).hasClass('ng-invalid-filesize')).to.be.true;
+        expect($(fileInput).hasClass('ng-touched')).to.be.true;
+      });
+    });
+
+    describe('with a file type that\'s not in the list of fileTypes given to the directive', function() {
+      beforeEach(function() {
+        fileList[0].type = 'application/zip';
+
+        $(fileInput).triggerHandler({
+          type: 'change',
+          target: { files: fileList }
+        });
+      });
+
+      it('does not call setFileReference', function() {
+        expect(mockSetFileReference).not.calledOnce;
+      });
+
+      it('has ng-touched and ng-invalid-required classes', function() {
+        expect($(fileInput).hasClass('ng-invalid-required')).to.be.true;
+        expect($(fileInput).hasClass('ng-touched')).to.be.true;
+      });
+    });
 
-    it('', function() {});
   });
 });
diff --git a/app/directives/tc-form-fonts/tc-form-fonts.spec.js b/app/directives/tc-form-fonts/tc-form-fonts.spec.js
index 8f0c5de95..8b7019756 100644
--- a/app/directives/tc-form-fonts/tc-form-fonts.spec.js
+++ b/app/directives/tc-form-fonts/tc-form-fonts.spec.js
@@ -15,6 +15,10 @@ describe('Topcoder Form Fonts Directive', function() {
     isolateScope = element.isolateScope();
   });
 
+  afterEach(function() {
+    scope.$destroy();
+  });
+
   bard.verifyNoOutstandingHttpRequests();
 
   describe('is initialized with', function() {
diff --git a/app/directives/tc-form-stockart/tc-form-stockart.spec.js b/app/directives/tc-form-stockart/tc-form-stockart.spec.js
index ccdf6d1c6..ed4429ce4 100644
--- a/app/directives/tc-form-stockart/tc-form-stockart.spec.js
+++ b/app/directives/tc-form-stockart/tc-form-stockart.spec.js
@@ -15,6 +15,10 @@ describe('Topcoder Form Stockart Directive', function() {
     isolateScope = element.isolateScope();
   });
 
+  afterEach(function() {
+    scope.$destroy();
+  });
+
   bard.verifyNoOutstandingHttpRequests();
 
   describe('is initialized with', function() {
diff --git a/app/directives/tc-input/tc-input.spec.js b/app/directives/tc-input/tc-input.spec.js
index 56e369efe..d7e481353 100644
--- a/app/directives/tc-input/tc-input.spec.js
+++ b/app/directives/tc-input/tc-input.spec.js
@@ -11,6 +11,10 @@ describe('Topcoder Input Directive', function() {
     scope.$digest();
   });
 
+  afterEach(function() {
+    scope.$destroy();
+  });
+
   bard.verifyNoOutstandingHttpRequests();
 
   it('should set inputType to text if no inputType given', function() {
diff --git a/app/specs.html b/app/specs.html
index 1c1199ee6..eb19c8329 100644
--- a/app/specs.html
+++ b/app/specs.html
@@ -270,6 +270,7 @@ <h1><a href="specs.html">Spec Runner</a></h1>
     <script src="/app/my-dashboard/my-dashboard.spec.js"></script>
     <script src="/app/my-srms/my-srms.spec.js"></script>
     <script src="/app/profile/profile.controller.spec.js"></script>
+    <script src="/app/settings/settings.spec.js"></script>
     <script src="/app/services/authToken.service.spec.js"></script>
     <script src="/app/services/challenge.service.spec.js"></script>
     <script src="/app/services/externalAccounts.service.spec.js"></script>
@@ -280,12 +281,11 @@ <h1><a href="specs.html">Spec Runner</a></h1>
     <script src="/app/services/tcAuth.service.spec.js"></script>
     <script src="/app/services/user.service.spec.js"></script>
     <script src="/app/services/userStats.service.spec.js"></script>
-    <script src="/app/settings/settings.spec.js"></script>
     <script src="/app/skill-picker/skill-picker.spec.js"></script>
     <script src="/app/submissions/submissions.spec.js"></script>
     <script src="/app/account/login/login.spec.js"></script>
-    <script src="/app/account/register/register.spec.js"></script>
     <script src="/app/account/logout/logout.controller.spec.js"></script>
+    <script src="/app/account/register/register.spec.js"></script>
     <script src="/app/account/reset-password/reset-password.spec.js"></script>
     <script src="/app/blocks/exception/exception-handler.provider.spec.js"></script>
     <script src="/app/directives/badges/badge-tooltip.spec.js"></script>