Merge lp:~mhall119/awstrial/marketing-user-export into lp:awstrial

Proposed by Michael Hall
Status: Merged
Approved by: Michael Hall
Approved revision: 276
Merged at revision: 276
Proposed branch: lp:~mhall119/awstrial/marketing-user-export
Merge into: lp:awstrial
Diff against target: 189 lines (+131/-10)
4 files modified
awstrial/templates/contacts.html (+1/-1)
awstrial/trial/export.py (+34/-0)
awstrial/trial/tests.py (+88/-1)
awstrial/trial/views.py (+8/-8)
To merge this branch: bzr merge lp:~mhall119/awstrial/marketing-user-export
Reviewer Review Type Date Requested Status
Matthew Nuzum (community) Approve
Review via email: mp+86167@code.launchpad.net

Commit message

Adds an export function for passing user marketing data to other systems. This will be used first by the marketo_exporter, but is sufficiently independent that it could be used by any other system.

Description of the change

Adds an export function for passing user marketing data to other systems. This will be used first by the marketo_exporter, but is sufficiently independent that it could be used by any other system.

One related change, at some point in the past we had merged the marketing opt-in and usage agreement checkboxes into one, but on the back end we had stopped recording the opt-in against the UserProfile for the user. I have fixed this so that we will once again record the user's opt-in status.

To post a comment you must log in.
Revision history for this message
Matthew Nuzum (newz) wrote :

Looks good. My only concern is the dual purpose checkbox but that is a user interface issue and is not really relevant to this code change. Approving.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'awstrial/templates/contacts.html'
2--- awstrial/templates/contacts.html 2011-11-14 18:56:50 +0000
3+++ awstrial/templates/contacts.html 2011-12-18 16:01:18 +0000
4@@ -38,7 +38,7 @@
5 2. Agree to the terms of Service
6 </p>
7 <p>
8- <input class="checkbox" type="checkbox" name="a" id="a" onClick="document.getElementById('launchbtn').disabled=(document.getElementById('launchbtn').disabled)? false : true"/>
9+ <input class="checkbox" type="checkbox" name="opt_marketing" id="opt_marketing" onClick="document.getElementById('launchbtn').disabled=(document.getElementById('launchbtn').disabled)? false : true"/>
10 <label for="a">I will use this instance in accordance with the <a href=http://aws.amazon.com/agreement/>Amazon Web Services Customer Agreement</a>,
11 the <a href=http://www.ubuntu.com/community/conduct>Ubuntu Code of Conduct</a>,
12 and that Canonical may occasionally mail me information about products and services in accordance with our <a href="http://www.canonical.com/privacy">privacy policy</a>.</label><br/>
13
14=== added file 'awstrial/trial/export.py'
15--- awstrial/trial/export.py 1970-01-01 00:00:00 +0000
16+++ awstrial/trial/export.py 2011-12-18 16:01:18 +0000
17@@ -0,0 +1,34 @@
18+from trial.models import Instances
19+from django.contrib.auth.models import User
20+
21+
22+def get_marketing_opt_in_users(created_after=None):
23+ """
24+ Returns a list of user data dicts corresponding to users who have opted
25+ into receiving marketing material
26+ """
27+ user_data = []
28+ collected = []
29+ # Since the user is only presented with the option to opt-in at the point
30+ # of running a new instance, we have to check by instance
31+ if created_after:
32+ users = []
33+ instances = Instances.objects.filter(reservation_time__gte=created_after)
34+ for instance in instances:
35+ users.append(instance.owner)
36+ else:
37+ users = User.objects.all()
38+
39+ for user in users:
40+ if user.username not in collected and user.profile.opt_marketing:
41+ user_data.append({
42+ 'id': user.id,
43+ 'email': user.email,
44+ 'first_name': user.first_name,
45+ 'last_name': user.last_name,
46+ 'username': user.username,
47+ 'created': user.date_joined,
48+ })
49+ collected.append(user.username)
50+
51+ return user_data
52
53=== modified file 'awstrial/trial/tests.py'
54--- awstrial/trial/tests.py 2011-10-24 19:10:19 +0000
55+++ awstrial/trial/tests.py 2011-12-18 16:01:18 +0000
56@@ -30,10 +30,97 @@
57 from trial import ec2_helper
58 from trial.models import Campaign, Instances, EmailBlacklist
59 from trial.auth import blacklisted_email_domain, client_using_tor
60+from trial import export
61 import logging
62 import socket
63
64
65+class TestExporter(DjangoTestCase):
66+ """
67+ Tests the export APIs
68+ """
69+
70+ def setUp(self):
71+ self.create_date = datetime.datetime.now()
72+ self.user = User.objects.create(
73+ username='testuser',
74+ first_name='Test',
75+ last_name='User',
76+ email='test@example.org',
77+ date_joined=self.create_date
78+ )
79+ self.profile = self.user.profile
80+ self.profile.opt_marketing=True
81+ self.profile.save()
82+
83+ self.campaign = Campaign.objects.create(
84+ name='test-campaign',
85+ verbose_name='Test Campaign',
86+ max_instances=5,
87+ active=True,
88+ )
89+
90+ self.instance = Instances.objects.create(
91+ instance_id='i-00000001',
92+ campaign=self.campaign,
93+ owner=self.user,
94+ reservation_time=self.create_date,
95+ )
96+
97+ def test_full_export(self):
98+ users = export.get_marketing_opt_in_users()
99+ self.assertEquals(1, len(users))
100+ self.assertEquals(self.user.id, users[0]['id'])
101+ self.assertEquals(self.user.username, users[0]['username'])
102+ self.assertEquals(self.user.first_name, users[0]['first_name'])
103+ self.assertEquals(self.user.last_name, users[0]['last_name'])
104+ self.assertEquals(self.user.email, users[0]['email'])
105+ self.assertEquals(self.user.date_joined, users[0]['created'])
106+
107+ def test_partial_export_prev(self):
108+ prev_day = self.create_date - datetime.timedelta(days=1)
109+ users = export.get_marketing_opt_in_users(created_after=prev_day)
110+ self.assertEquals(1, len(users))
111+
112+ def test_partial_export_after(self):
113+ next_day = self.create_date + datetime.timedelta(days=1)
114+ users = export.get_marketing_opt_in_users(created_after=next_day)
115+ self.assertEquals(0, len(users))
116+
117+ def test_opt_out(self):
118+ self.profile.opt_marketing=False
119+ self.profile.save()
120+ users = export.get_marketing_opt_in_users()
121+ self.assertEquals(0, len(users))
122+
123+ def test_opt_in_after_user_joined(self):
124+ prev_day = self.create_date - datetime.timedelta(days=1)
125+ self.instance.reservation_time = prev_day
126+ self.instance.save()
127+
128+ users = export.get_marketing_opt_in_users(created_after=self.create_date)
129+ self.assertEquals(0, len(users))
130+
131+ next_day = self.create_date + datetime.timedelta(days=1)
132+ self.instance.reservation_time = next_day
133+ self.instance.save()
134+
135+ users = export.get_marketing_opt_in_users(created_after=prev_day)
136+ self.assertEquals(1, len(users))
137+
138+ def test_user_without_instance(self):
139+ prev_day = self.create_date - datetime.timedelta(days=1)
140+ self.instance.delete()
141+ self.profile.opt_marketing=False
142+ self.profile.save()
143+
144+ users = export.get_marketing_opt_in_users(created_after=prev_day)
145+ self.assertEquals(0, len(users))
146+
147+ users = export.get_marketing_opt_in_users()
148+ self.assertEquals(0, len(users))
149+
150+
151 class TestEc2Helper(UnitTestCase):
152 """
153 Tests the calls to functions in the ec2_helper module
154@@ -114,7 +201,7 @@
155 def call_run_instance(self, campaign):
156 post_data = {
157 'config': 'default',
158- 'a': 1,
159+ 'opt_marketing': 1,
160 'launchbtn': 'Launch',
161 }
162 return self.client.post('/%s/run/' % campaign.name, post_data)
163
164=== modified file 'awstrial/trial/views.py'
165--- awstrial/trial/views.py 2011-10-20 14:01:31 +0000
166+++ awstrial/trial/views.py 2011-12-18 16:01:18 +0000
167@@ -71,14 +71,14 @@
168 # Now Check the campaign is running and has avaliability left.
169 if current_campaign.remaining() and (current_campaign.active):
170 if request.method == "POST":
171- # opt_marketing = opt in for marketing mail, bool
172- user = request.user.profile
173- user.opt_marketing = request.POST.get('opt_marketing', '')
174- user.save()
175-
176- # a = disclaimer box
177- a = request.POST.get('a', '')
178- if a:
179+
180+ # This is both the disclaiming and marketing opt-in checkbox
181+ opt_marketing = request.POST.get('opt_marketing', '')
182+ if opt_marketing:
183+ user = request.user.profile
184+ user.opt_marketing = opt_marketing
185+ user.save()
186+
187 #try:
188 region = request.POST.get('region',None)
189 if region is not None:

Subscribers

People subscribed via source and target branches