diff --git a/lms/djangoapps/linkedin/management/commands/linkedin_mailusers.py b/lms/djangoapps/linkedin/management/commands/linkedin_mailusers.py index 9707e343f6..e6e8571d9b 100644 --- a/lms/djangoapps/linkedin/management/commands/linkedin_mailusers.py +++ b/lms/djangoapps/linkedin/management/commands/linkedin_mailusers.py @@ -6,14 +6,18 @@ LinkedIn profiles. import json import urllib +from django.conf import settings from django.core.mail import send_mail from django.core.management.base import BaseCommand from django.template import Context from django.template.loader import get_template +from django.core.urlresolvers import reverse from optparse import make_option +from edxmako.shortcuts import render_to_string + from certificates.models import GeneratedCertificate -from courseware.courses import get_course_by_id +from courseware.courses import get_course_by_id, course_image_url from ...models import LinkedIn from . import LinkedInAPI @@ -101,15 +105,31 @@ class Command(BaseCommand): Send the 'grandfathered' email informing historical students that they may now post their certificates on their LinkedIn profiles. """ - template = get_template("linkedin_grandfather_email.html") - links = [ - {'course_name': certificate.name, - 'url': self.certificate_url(certificate, grandfather=True)} - for certificate in certificates] - context = Context({ - 'student_name': user.profile.name, - 'certificates': links}) - body = template.render(context) + courses_list = [] + for cert in certificates: + course = get_course_by_id(cert.course_id) + course_url = 'https://{}{}'.format( + settings.SITE_NAME, + reverse('course_root', kwargs={'course_id': cert.course_id}) + ) + + course_title = course.display_name + + course_img_url = 'https://{}{}'.format(settings.SITE_NAME, course_image_url(course)) + course_end_date = course.end.strftime('%b %Y') + course_org = course.display_organization + + courses_list.append({ + 'course_url': course_url, + 'course_org': course_org, + 'course_title': course_title, + 'course_image_url': course_img_url, + 'course_end_date': course_end_date, + 'linkedin_add_url': self.certificate_url(cert), + }) + + context = {'courses_list': courses_list, 'num_courses': len(courses_list)} + body = render_to_string('linkedin/linkedin_email.html', context) subject = 'Congratulations! Put your certificates on LinkedIn' self.send_email(user, subject, body) diff --git a/lms/djangoapps/linkedin/management/commands/tests/test_mailusers.py b/lms/djangoapps/linkedin/management/commands/tests/test_mailusers.py index d806272757..f766162f0a 100644 --- a/lms/djangoapps/linkedin/management/commands/tests/test_mailusers.py +++ b/lms/djangoapps/linkedin/management/commands/tests/test_mailusers.py @@ -7,36 +7,39 @@ import mock from certificates.models import GeneratedCertificate from django.contrib.auth.models import User +from django.conf import settings +from django.test.utils import override_settings from django.core import mail from django.utils.timezone import utc from django.test import TestCase +from xmodule.modulestore.tests.factories import CourseFactory from student.models import UserProfile from linkedin.models import LinkedIn +from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, mixed_store_config from linkedin.management.commands import linkedin_mailusers as mailusers MODULE = 'linkedin.management.commands.linkedin_mailusers.' +TEST_DATA_MIXED_MODULESTORE = mixed_store_config(settings.COMMON_TEST_DATA_ROOT, {}) + +@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) class MailusersTests(TestCase): """ Test mail users command. """ def setUp(self): - courses = { - 'TEST1': mock.Mock( - org='TestX', number='1', - start=datetime.datetime(2010, 5, 12, 2, 42, tzinfo=utc)), - 'TEST2': mock.Mock(org='TestX', number='2'), - 'TEST3': mock.Mock(org='TestX', number='3'), - } - - def get_course_by_id(id): - return courses.get(id) - patcher = mock.patch(MODULE + 'get_course_by_id', get_course_by_id) - patcher.start() - self.addCleanup(patcher.stop) + CourseFactory.create(org='TESTX', number='1', display_name='TEST1', + start=datetime.datetime(2010, 5, 12, 2, 42, tzinfo=utc), + end=datetime.datetime(2011, 5, 12, 2, 42, tzinfo=utc)) + CourseFactory.create(org='TESTX', number='2', display_name='TEST2', + start=datetime.datetime(2010, 5, 12, 2, 42, tzinfo=utc), + end=datetime.datetime(2011, 5, 12, 2, 42, tzinfo=utc)) + CourseFactory.create(org='TESTX', number='3', display_name='TEST3', + start=datetime.datetime(2010, 5, 12, 2, 42, tzinfo=utc), + end=datetime.datetime(2011, 5, 12, 2, 42, tzinfo=utc)) self.fred = fred = User(username='fred', email='fred@bedrock.gov') fred.save() @@ -51,19 +54,19 @@ class MailusersTests(TestCase): self.cert1 = cert1 = GeneratedCertificate( status='downloadable', user=fred, - course_id='TEST1', + course_id='TESTX/1/TEST1', name='TestX/Intro101', download_url='http://test.foo/test') cert1.save() cert2 = GeneratedCertificate( status='downloadable', user=fred, - course_id='TEST2') + course_id='TESTX/2/TEST2') cert2.save() cert3 = GeneratedCertificate( status='downloadable', user=barney, - course_id='TEST3') + course_id='TESTX/3/TEST3') cert3.save() def test_mail_users(self): @@ -73,9 +76,9 @@ class MailusersTests(TestCase): fut = mailusers.Command().handle fut() self.assertEqual( - json.loads(self.fred.linkedin.emailed_courses), ['TEST1', 'TEST2']) + json.loads(self.fred.linkedin.emailed_courses), ['TESTX/1/TEST1', 'TESTX/2/TEST2']) self.assertEqual( - json.loads(self.barney.linkedin.emailed_courses), ['TEST3']) + json.loads(self.barney.linkedin.emailed_courses), ['TESTX/3/TEST3']) self.assertEqual(len(mail.outbox), 3) self.assertEqual(mail.outbox[0].from_email, 'The Team ') self.assertEqual( @@ -94,7 +97,7 @@ class MailusersTests(TestCase): fut = mailusers.Command().handle fut() self.assertEqual( - json.loads(self.barney.linkedin.emailed_courses), ['TEST3']) + json.loads(self.barney.linkedin.emailed_courses), ['TESTX/3/TEST3']) self.assertEqual(len(mail.outbox), 1) self.assertEqual( mail.outbox[0].to, ['Barney Rubble ']) @@ -106,9 +109,9 @@ class MailusersTests(TestCase): fut = mailusers.Command().handle fut(grandfather=True) self.assertEqual( - json.loads(self.fred.linkedin.emailed_courses), ['TEST1', 'TEST2']) + json.loads(self.fred.linkedin.emailed_courses), ['TESTX/1/TEST1', 'TESTX/2/TEST2']) self.assertEqual( - json.loads(self.barney.linkedin.emailed_courses), ['TEST3']) + json.loads(self.barney.linkedin.emailed_courses), ['TESTX/3/TEST3']) self.assertEqual(len(mail.outbox), 2) self.assertEqual( mail.outbox[0].to, ['Fred Flintstone ']) @@ -120,15 +123,15 @@ class MailusersTests(TestCase): Test emailing users, making sure they are only emailed about new certificates. """ - self.fred.linkedin.emailed_courses = json.dumps(['TEST1']) + self.fred.linkedin.emailed_courses = json.dumps(['TESTX/1/TEST1']) self.fred.linkedin.save() fut = mailusers.Command().handle fut() fred = User.objects.get(username='fred') self.assertEqual( - json.loads(fred.linkedin.emailed_courses), ['TEST1', 'TEST2']) + json.loads(fred.linkedin.emailed_courses), ['TESTX/1/TEST1', 'TESTX/2/TEST2']) self.assertEqual( - json.loads(self.barney.linkedin.emailed_courses), ['TEST3']) + json.loads(self.barney.linkedin.emailed_courses), ['TESTX/3/TEST3']) self.assertEqual(len(mail.outbox), 2) self.assertEqual( mail.outbox[0].to, ['Fred Flintstone ']) @@ -140,15 +143,15 @@ class MailusersTests(TestCase): Test emailing users, making sure they are only emailed about new certificates. """ - self.barney.linkedin.emailed_courses = json.dumps(['TEST3']) + self.barney.linkedin.emailed_courses = json.dumps(['TESTX/3/TEST3']) self.barney.linkedin.save() fut = mailusers.Command().handle fut() fred = User.objects.get(username='fred') self.assertEqual( - json.loads(fred.linkedin.emailed_courses), ['TEST1', 'TEST2']) + json.loads(fred.linkedin.emailed_courses), ['TESTX/1/TEST1', 'TESTX/2/TEST2']) self.assertEqual( - json.loads(self.barney.linkedin.emailed_courses), ['TEST3']) + json.loads(self.barney.linkedin.emailed_courses), ['TESTX/3/TEST3']) self.assertEqual(len(mail.outbox), 2) self.assertEqual( mail.outbox[0].to, ['Fred Flintstone ']) @@ -165,6 +168,6 @@ class MailusersTests(TestCase): 'http://www.linkedin.com/profile/guided?' 'pfCertificationName=TestX%2FIntro101&pfAuthorityName=edX&' 'pfAuthorityId=0000000&' - 'pfCertificationUrl=http%3A%2F%2Ftest.foo%2Ftest&pfLicenseNo=TEST1&' + 'pfCertificationUrl=http%3A%2F%2Ftest.foo%2Ftest&pfLicenseNo=TESTX%2F1%2FTEST1&' 'pfCertStartDate=201005&_mSplash=1&' - 'trk=eml-prof-TestX-1-T&startTask=CERTIFICATION_NAME&force=true') + 'trk=eml-prof-TESTX-1-T&startTask=CERTIFICATION_NAME&force=true') diff --git a/lms/djangoapps/linkedin/templates/linkedin_grandfather_email.html b/lms/djangoapps/linkedin/templates/linkedin_grandfather_email.html deleted file mode 100644 index cc373a3d8e..0000000000 --- a/lms/djangoapps/linkedin/templates/linkedin_grandfather_email.html +++ /dev/null @@ -1,28 +0,0 @@ -{% load i18n %} - - - - - - - -

{% blocktrans with name=student_name %} - Dear {{student_name}}, - {% endblocktrans %}

- -

{% blocktrans with name=course_name %} - We've partnered with LinkedIn and now you can put your certificates on - your LinkedIn profile. Just use the links below. - {% endblocktrans %}

- - {% for cert in certificates %} -

- {{cert.course_name}}: - - in - {% blocktrans %}Add to profile{% endblocktrans %} - -

- {% endfor %} - - diff --git a/lms/templates/linkedin/linkedin_email.html b/lms/templates/linkedin/linkedin_email.html new file mode 100644 index 0000000000..22b0f799e9 --- /dev/null +++ b/lms/templates/linkedin/linkedin_email.html @@ -0,0 +1,836 @@ + + + + + +## NAME: 1 COLUMN + + + Share Your edX Success on LinkedIn + + + + + + +
+ + +
+ ## BEGIN TEMPLATE // + + + + + + + + + + +
+ ## BEGIN PREHEADER // + + + + +
+ + + + + +
+ + + + + + +
+ +
 Connect with us on:            
+ +
+ +
+ ## // END PREHEADER +
+ ## BEGIN HEADER // + + + + +
+ + + + + +
+ + + + +
+ + + edX - Connect To A Better Future + + +
+
+ + + + + +
+ + + + + + +
+ + Share Your edX Success on LinkedIn +
+ +
+ ## // END HEADER +
+ ## BEGIN BODY // + + + + + + + +
+ + + + + +
+ + + + + + +
+ +%if num_courses==1: + Through a partnership with LinkedIn, the world's largest professional network, we've now made it even easier for you to showcase your success. We encourage you to share your edX certificate on your LinkedIn profile. Simply click the "Add to profile" button below. +%else: + Through a partnership with LinkedIn, the world's largest professional network, we've now made it even easier for you to showcase your success. We encourage you to share your edX certificates on your LinkedIn profile. Simply click the "Add to profile" buttons below. +%endif +
+ +
+ + +%for course_dict in courses_list: + +<% + + course_url = course_dict['course_url'] + course_title = course_dict['course_title'] + course_image_url = course_dict['course_image_url'] + course_org = course_dict['course_org'] + course_end_date = course_dict['course_end_date'] + linkedin_add_url = course_dict['linkedin_add_url'] + +%> + +## Begin table for single class + + + + + + +
+ + + + +
+ + + + + +
+ + + + + + ${course_title} + + + +
+ + + + +
+ ${course_title}
+${course_org}
+Completed ${course_end_date}
+
+ +## TODO put path/to/real/source/file here +
+
+
+
+ +## End table for single class cell +%endfor + +## a really complicated hr + + + + + + +
+ + + + +
+ +
+
+ +## text for congrats on your accomplishment + + + + +
+ + + + + +
+ + + + + + +
+ + Congratulations on your accomplishment! Adding this to your profile will help get the word out about your impressive edX achievement. -The edX Team- +
+ +
+ + + + + + + +
+ + + + + + +
+ + +
+ +
+ + + + + +
+ + + + +
+ +
+
+ + + + + +
+ + + + + + +
+ +
+ Stay connected on LinkedIn, +Facebook, Twitter, Google+ and more for news and updates.
+ +
+ +
+ + + + + +
+ + + + +
+ +
+
+ + + + + +
+ + + + + + +
+ +
+           
+ +
+ +
+ ## // END BODY +
+ ## BEGIN FOOTER // + + + + +
+ + + + + +
+ + + + + + +
+
+ Copyright © 2014 edX, All rights reserved.
+
+ Our mailing address is:
+ edX
+ 11 Cambridge Center, Suite 101
+ Cambridge, MA, USA 02142
+
+
+ +
+ ## // END FOOTER +
+ ## // END TEMPLATE +
+ + +