diff --git a/common/djangoapps/student/tests.py b/common/djangoapps/student/tests.py
index 8a46b2e4584bfd32141f64be16e46680d5d5bf4e..16eec863799e4788b26ad20b5ca99110b5fb104c 100644
--- a/common/djangoapps/student/tests.py
+++ b/common/djangoapps/student/tests.py
@@ -13,7 +13,7 @@ from mock import patch, Mock
 from nose.plugins.skip import SkipTest
 
 from .models import User, UserProfile, CourseEnrollment, replicate_user, USER_FIELDS_TO_COPY
-import .views
+from .views import process_survey_link, _cert_info, unique_id_for_user
 
 COURSE_1 = 'edX/toy/2012_Fall'
 COURSE_2 = 'edx/full/6.002_Spring_2012'
@@ -204,17 +204,85 @@ class CourseEndingTest(TestCase):
 
     def test_process_survey_link(self):
         username = "fred"
-        id = sha1(username)
+        user = Mock(username=username)
+        id = unique_id_for_user(user)
         link1 = "http://www.mysurvey.com"
-        self.assertEqual(process_survey_link(link1), link1)
+        self.assertEqual(process_survey_link(link1, user), link1)
+
         link2 = "http://www.mysurvey.com?unique={UNIQUE_ID}"
         link2_expected = "http://www.mysurvey.com?unique={UNIQUE_ID}".format(UNIQUE_ID=id)
-        self.assertEqual(views.process_survey_link(link2), link2_expected)
+        self.assertEqual(process_survey_link(link2, user), link2_expected)
 
     def test_cert_info(self):
         user = Mock(username="fred")
         survey_url = "http://a_survey.com"
         course = Mock(end_of_course_survey_url=survey_url)
-        cert_status = None
 
-        self.assertEqual(views._cert_info(user, course, None), {'status': 'processing'})
+        self.assertEqual(_cert_info(user, course, None),
+                         {'status': 'processing',
+                          'show_disabled_download_button': False,
+                          'show_download_url': False,
+                          'show_survey_button': False,})
+
+        cert_status = {'status': 'unavailable'}
+        self.assertEqual(_cert_info(user, course, cert_status),
+                         {'status': 'processing',
+                          'show_disabled_download_button': False,
+                          'show_download_url': False,
+                          'show_survey_button': False})
+
+        cert_status = {'status': 'generating', 'grade': '67'}
+        self.assertEqual(_cert_info(user, course, cert_status),
+                         {'status': 'generating',
+                          'show_disabled_download_button': True,
+                          'show_download_url': False,
+                          'show_survey_button': True,
+                          'survey_url': survey_url,
+                          'grade': '67'
+                          })
+
+        cert_status = {'status': 'regenerating', 'grade': '67'}
+        self.assertEqual(_cert_info(user, course, cert_status),
+                         {'status': 'generating',
+                          'show_disabled_download_button': True,
+                          'show_download_url': False,
+                          'show_survey_button': True,
+                          'survey_url': survey_url,
+                          'grade': '67'
+                          })
+
+        download_url = 'http://s3.edx/cert'
+        cert_status = {'status': 'downloadable', 'grade': '67',
+                       'download_url': download_url}
+        self.assertEqual(_cert_info(user, course, cert_status),
+                         {'status': 'ready',
+                          'show_disabled_download_button': False,
+                          'show_download_url': True,
+                          'download_url': download_url,
+                          'show_survey_button': True,
+                          'survey_url': survey_url,
+                          'grade': '67'
+                          })
+
+        cert_status = {'status': 'notpassing', 'grade': '67',
+                       'download_url': download_url}
+        self.assertEqual(_cert_info(user, course, cert_status),
+                         {'status': 'notpassing',
+                          'show_disabled_download_button': False,
+                          'show_download_url': False,
+                          'show_survey_button': True,
+                          'survey_url': survey_url,
+                          'grade': '67'
+                          })
+
+        # Test a course that doesn't have a survey specified
+        course2 = Mock(end_of_course_survey_url=None)
+        cert_status = {'status': 'notpassing', 'grade': '67',
+                       'download_url': download_url}
+        self.assertEqual(_cert_info(user, course2, cert_status),
+                         {'status': 'notpassing',
+                          'show_disabled_download_button': False,
+                          'show_download_url': False,
+                          'show_survey_button': False,
+                          'grade': '67'
+                          })
diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py
index 2ebb98da7ac154e1fcd0c98c8ccbe6c4ad7b69c0..250eddff577275f255b24af179af0dd58d1ddc21 100644
--- a/common/djangoapps/student/views.py
+++ b/common/djangoapps/student/views.py
@@ -129,6 +129,9 @@ def press(request):
     return render_to_response('static_templates/press.html', {'articles': articles})
 
 
+def unique_id_for_user(user):
+    return sha1(user.username).hexdigest()
+
 def process_survey_link(survey_link, user):
     """
     If {UNIQUE_ID} appears in the link, replace it with a unique id for the user.
@@ -136,8 +139,7 @@ def process_survey_link(survey_link, user):
     """
     to_replace = '{UNIQUE_ID}'
     if to_replace in survey_link:
-        unique_id = sha1(user.username)
-        return survey_link.replace(to_replace, unique_id)
+        return survey_link.replace(to_replace, unique_id_for_user(user))
 
     return survey_link
 
@@ -150,6 +152,7 @@ def cert_info(user, course):
     'status': one of 'generating', 'ready', 'notpassing', 'processing'
     'show_download_url': bool
     'download_url': url, only present if show_download_url is True
+    'show_disabled_download_button': bool -- true if state is 'generating'
     'show_survey_button': bool
     'survey_url': url, only if show_survey_button is True
     'grade': if status is not 'processing'
@@ -165,7 +168,10 @@ def _cert_info(user, course, cert_status):
     """
     default_status = 'processing'
     if cert_status is None:
-        return {'status': default_status}
+        return {'status': default_status,
+                'show_disabled_download_button': False,
+                'show_download_url': False,
+                'show_survey_button': False}
 
     # simplify the status for the template using this lookup table
     template_state = {
@@ -178,9 +184,10 @@ def _cert_info(user, course, cert_status):
     status = template_state.get(cert_status['status'], default_status)
 
     d = {'status': status,
-         'show_download_url': status in ('generating', 'ready'),}
+         'show_download_url': status == 'ready',
+         'show_disabled_download_button': status == 'generating',}
 
-    if (status in ('generating', 'ready', 'not-available') and
+    if (status in ('generating', 'ready', 'notpassing') and
         course.end_of_course_survey_url is not None):
         d.update({
          'show_survey_button': True,
@@ -188,10 +195,10 @@ def _cert_info(user, course, cert_status):
     else:
         d['show_survey_button'] = False
 
-    if template_state == 'ready':
+    if status == 'ready':
         d['download_url'] = cert_status['download_url']
 
-    if template_state in 'generating', 'ready', 'notpassing':
+    if status in ('generating', 'ready', 'notpassing'):
         d['grade'] = cert_status['grade']
 
     return d
diff --git a/lms/djangoapps/certificates/models.py b/lms/djangoapps/certificates/models.py
index 2d6f384443a4eb28c893caaf12377a8376526d68..b9bd55b9afaeab665075b86f40ca025e348b6f6e 100644
--- a/lms/djangoapps/certificates/models.py
+++ b/lms/djangoapps/certificates/models.py
@@ -75,7 +75,9 @@ def certificate_status_for_student(student, course_id):
     This returns a dictionary with a key for status, and other information.
     The status is one of the following:
 
-    unavailable  - A student is not eligible for a certificate.
+    unavailable  - No entry for this student--if they are actually in
+                   the course, they probably have not been graded for
+                   certificate generation yet.
     generating   - A request has been made to generate a certificate,
                    but it has not been generated yet.
     regenerating - A request has been made to regenerate a certificate,
@@ -90,7 +92,7 @@ def certificate_status_for_student(student, course_id):
     "download_url".
 
     If the student has been graded, the dictionary also contains their
-    grade for the course.
+    grade for the course with the key "grade".
     '''
 
     try: