Skip to content
This repository has been archived by the owner on Feb 8, 2018. It is now read-only.

Implement option to hide total receiving from others (issue #1683) #1721

Closed
wants to merge 10 commits into from
8 changes: 8 additions & 0 deletions branch.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-------------------------------------------------------------------------------
-- https://github.com/gittip/www.gittip.com/issues/1683

BEGIN;
ALTER TABLE participants RENAME COLUMN anonymous TO anonymous_giving;
ALTER TABLE participants ADD COLUMN anonymous_receiving bool NOT NULL DEFAULT FALSE;
ALTER TABLE homepage_top_receivers ADD COLUMN anonymous boolean;
END;
4 changes: 2 additions & 2 deletions gittip/models/participant.py
Original file line number Diff line number Diff line change
Expand Up @@ -662,9 +662,9 @@ def get_og_title(self):
out = self.username
receiving = self.get_dollars_receiving()
giving = self.get_dollars_giving()
if (giving > receiving) and not self.anonymous:
if (giving > receiving) and not self.anonymous_giving:
out += " gives $%.2f/wk" % giving
elif receiving > 0:
elif receiving > 0 and not self.anonymous_receiving:
out += " receives $%.2f/wk" % receiving
else:
out += " is"
Expand Down
3 changes: 2 additions & 1 deletion gittip/testing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ def show_table(self, table):
def make_participant(self, username, **kw):
participant = Participant.with_random_username()
participant.change_username(username)
return self.update_participant(participant, **kw)

def update_participant(self, participant, **kw):
# brute force update for use in testing
for k,v in kw.items():
if k == 'claimed_time':
Expand All @@ -120,7 +122,6 @@ def make_participant(self, username, **kw):
self.db.run("UPDATE participants SET {}=%s WHERE username=%s" \
.format(k), (v, participant.username))
participant.set_attributes(**kw)

return participant

def make_payday(self, *transfers):
Expand Down
12 changes: 6 additions & 6 deletions gittip/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,8 @@ def update_homepage_queries_once(db):
cursor.execute("DELETE FROM homepage_top_givers")
cursor.execute("""

INSERT INTO homepage_top_givers
SELECT tipper AS username, anonymous, sum(amount) AS amount
INSERT INTO homepage_top_givers (username, anonymous, amount)
SELECT tipper, anonymous_giving, sum(amount) AS amount
FROM ( SELECT DISTINCT ON (tipper, tippee)
amount
, tipper
Expand All @@ -375,7 +375,7 @@ def update_homepage_queries_once(db):
) AS foo
JOIN participants p ON p.username = tipper
WHERE is_suspicious IS NOT true
GROUP BY tipper, anonymous
GROUP BY tipper, anonymous_giving
ORDER BY amount DESC;

""".strip())
Expand All @@ -401,8 +401,8 @@ def update_homepage_queries_once(db):
cursor.execute("DELETE FROM homepage_top_receivers")
cursor.execute("""

INSERT INTO homepage_top_receivers
SELECT tippee AS username, claimed_time, sum(amount) AS amount
INSERT INTO homepage_top_receivers (username, anonymous, amount, claimed_time)
SELECT tippee, anonymous_receiving, sum(amount) AS amount, claimed_time
FROM ( SELECT DISTINCT ON (tipper, tippee)
amount
, tippee
Expand All @@ -417,7 +417,7 @@ def update_homepage_queries_once(db):
) AS foo
JOIN participants p ON p.username = tippee
WHERE is_suspicious IS NOT true
GROUP BY tippee, claimed_time
GROUP BY tippee, anonymous_receiving, claimed_time
ORDER BY amount DESC;

""".strip())
Expand Down
5 changes: 3 additions & 2 deletions gittip/utils/fake_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def fake_sentence(start=1, stop=100):
return faker.sentence(random.randrange(start,stop))


def fake_participant(db, number="singular", is_admin=False, anonymous=False):
def fake_participant(db, number="singular", is_admin=False):
"""Create a fake User.
"""
username = faker.firstName() + fake_text_id(3)
Expand All @@ -70,7 +70,8 @@ def fake_participant(db, number="singular", is_admin=False, anonymous=False):
, ctime=faker.dateTimeThisYear()
, is_admin=is_admin
, balance=fake_balance()
, anonymous=anonymous
, anonymous_giving=(random.randrange(5) == 0)
, anonymous_receiving=(random.randrange(5) == 0)
, goal=fake_balance()
, balanced_account_uri=faker.uri()
, last_ach_result=''
Expand Down
25 changes: 23 additions & 2 deletions js/gittip/profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,13 +215,34 @@ Gittip.profile.init = function() {
// Wire up aggregate giving knob.
// ==============================

$('.anonymous input').click(function() {
$('.anonymous-giving input').click(function() {
jQuery.ajax(
{ url: 'anonymous.json'
, type: 'POST'
, data: {toggle: 'giving'}
, dataType: 'json'
, success: function(data) {
$('.anonymous input').attr('checked', data.anonymous);
$('.anonymous-giving input').attr('checked', data.giving);
}
, error: function() {
alert("Failed to change your anonymity preference. Please try again.");
}
}
);
});


// Wire up aggregate receiving knob.
// ==============================

$('.anonymous-receiving input').click(function() {
jQuery.ajax(
{ url: 'anonymous.json'
, type: 'POST'
, data: {toggle: 'receiving'}
, dataType: 'json'
, success: function(data) {
$('.anonymous-receiving input').attr('checked', data.receiving);
}
, error: function() {
alert("Failed to change your anonymity preference. Please try again.");
Expand Down
4 changes: 2 additions & 2 deletions js/gittip/tips.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ Gittip.tips.init = function() {
$myTip.data('old-amount', amount).change();

// update display
$('.total-giving').text(data.total_giving);
$('.my-total-giving').text('$'+data.total_giving);
$('.total-receiving').text(
// check and see if we are on our giving page or not
new RegExp('/' + tippee + '/').test(window.location.href) ?
data.total_receiving_tippee : data.total_receiving);
'$'+data.total_receiving_tippee : '$'+data.total_receiving);

// update quick stats
$('.quick-stats a').text('$' + data.total_giving + '/wk');
Expand Down
5 changes: 4 additions & 1 deletion templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ <h1>
<a href="/{{ user.participant.username }}/">{{ user.participant.username }}</a> &ndash;
<a id="sign-out" href="/sign-out.html">sign out</a>
<div class="quick-stats">
Giving: <a href="/{{ user.participant.username }}/giving/">${{ user.participant.get_dollars_giving() }}/wk</a><br />
Giving: <a href="/{{ user.participant.username }}/giving/">
<span class="my-total-giving">${{ user.participant.get_dollars_giving() }}<span>/wk
</a>
<br />
Receiving: <b>${{ user.participant.get_dollars_receiving() }}/wk</b>
</div>
</div>
Expand Down
48 changes: 23 additions & 25 deletions templates/participant.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,45 @@

{% block box %}

{% set prefix = user.participant == participant and "my-" or "" %}
{% set anon_giving = participant.anonymous_giving %}
{% set g = participant.get_dollars_giving() %}
{% set giving = anon_giving and "anonymously" or "$"+str(g) %}
{% set anon_receiving = participant.anonymous_receiving %}
{% set r = participant.get_dollars_receiving() %}
{% set receiving = anon_receiving and "anonymously" or "$"+str(r) %}

<table class="on-profile{% if participant.is_suspicious %} is-suspicious{% end %}">
<tr>
<td class="picture">
<a href="/{{ participant.username }}/"><img src="{{ participant.get_img_src(128) }}" /></a>
</td>
<td class="giving-receiving">
{% set g = giving = participant.get_dollars_giving() %}
{% set r = receiving = participant.get_dollars_receiving() %}

{% if g > r and not participant.anonymous %}
{% if anon_giving and anon_receiving %}
<h2 class="pad-sign">{{ participant.username }}</h2>
<div class="unit pad-sign">gives and receives anonymously</div>
{% elif not anon_giving and g > 0 and (g > r or anon_receiving) %}
<h2 class="pad-sign">{{ participant.username }} gives</h2>
<div class="number">
{% if user.participant == participant %}
$<span class="total-giving">{{ giving }}</span>
{% else %}
${{ giving }}
{% end %}
<span class="{{prefix}}total-giving">{{ giving }}</span>
</div>
<div class="unit pad-sign">per
week{% if r > 0 %}, and receives $<span class="total-receiving">{{ receiving }}</span>{% end %}
<div class="unit pad-sign">
per week{% if r > 0 %}, and receives {{ receiving }}{% end %}
</div>
{% elif r > 0 %}
{% elif not anon_receiving and r > 0 and (r >= g or anon_giving) %}
<h2 class="pad-sign">{{ participant.username }} receives</h2>
<div class="number">$<span class="total-receiving">{{ receiving }}</span></div>
<div class="unit pad-sign">per
week{% if g > 0 %}, and gives
{% if participant.anonymous %}
anonymously
{% elif user.participant == participant %}
$<span class="total-giving">{{ giving }}</span>
{% else %}
${{ giving }}
{% end %}
<div class="number">
<span class="total-receiving">{{ receiving }}</span>
</div>
<div class="unit pad-sign">
per week{% if g > 0 %}, and gives
<span class="{{prefix}}total-giving">{{ giving }}</span>
{% end %}
</div>
{% else %}
{% set age = participant.get_age_in_seconds() %}
<h2>{{ participant.username }}
{% if g > 0 %}
gives anonymously
{% elif age < 60 %}
{% if age < 60 %}
just joined Gittip! :D
{% elif age < (60 * 60 * 24 * 7) %}
joined recently
Expand Down
10 changes: 8 additions & 2 deletions templates/profile-edit.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,17 @@ <h2 class="warning">Have you linked to your Gittip profile from other

</form>
<p>
<label tabindex="104" class="anonymous">
<label tabindex="104" class="anonymous-giving">
<input type="checkbox"
{% if participant.anonymous %}checked="true"{% end %} />
{% if participant.anonymous_giving %}checked="true"{% end %} />
Hide total giving from others.
</label>
<br />
<label tabindex="105" class="anonymous-receiving">
<input type="checkbox"
{% if participant.anonymous_receiving %}checked="true"{% end %} />
Hide total receiving from others.
</label>
</p>


Expand Down
37 changes: 24 additions & 13 deletions tests/test_anonymous_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class Tests(Harness):

def hit_anonymous(self, method='GET', expected_code=200):
def hit_anonymous(self, method='GET', data={}, expected_code=200):
user, ignored = TwitterAccount(self.db, 'alice', {}).opt_in('alice')

client = TestClient()
Expand All @@ -23,26 +23,37 @@ def hit_anonymous(self, method='GET', expected_code=200):
else:
assert method == 'POST'
response = client.post( "/alice/anonymous.json"
, {'csrf_token': csrf_token}
, dict(data, csrf_token=csrf_token)
, user='alice'
)
if response.code != expected_code:
print(response.body)
return response


def test_participant_can_get_their_anonymity_setting(self):
def test_participant_can_get_their_anonymity_settings(self):
response = self.hit_anonymous('GET')
actual = json.loads(response.body)['anonymous']
actual = json.loads(response.body)
assert actual == {'giving': False, 'receiving': False}

def test_participant_can_toggle_anonymous_giving(self):
response = self.hit_anonymous('POST', data={'toggle': 'giving'})
actual = json.loads(response.body)
assert actual['giving'] is True

def test_participant_can_toggle_anonymous_receiving(self):
response = self.hit_anonymous('POST', data={'toggle': 'receiving'})
actual = json.loads(response.body)
assert actual['receiving'] is True

def test_participant_can_toggle_anonymous_giving_back(self):
response = self.hit_anonymous('POST', data={'toggle': 'giving'})
response = self.hit_anonymous('POST', data={'toggle': 'giving'})
actual = json.loads(response.body)['giving']
assert actual is False

def test_participant_can_toggle_their_anonymity_setting(self):
response = self.hit_anonymous('POST')
actual = json.loads(response.body)['anonymous']
assert actual is True

def test_participant_can_toggle_their_anonymity_setting_back(self):
response = self.hit_anonymous('POST')
response = self.hit_anonymous('POST')
actual = json.loads(response.body)['anonymous']
def test_participant_can_toggle_anonymous_receiving_back(self):
response = self.hit_anonymous('POST', data={'toggle': 'receiving'})
response = self.hit_anonymous('POST', data={'toggle': 'receiving'})
actual = json.loads(response.body)['receiving']
assert actual is False
13 changes: 12 additions & 1 deletion tests/test_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,18 @@ def test_homepage(self):

def test_homepage_with_anonymous_giver(self):
TwitterAccount(self.db, "bob", {}).opt_in("bob")
alice = self.make_participant('alice', anonymous=True, last_bill_result='')
alice = self.make_participant('alice', anonymous_giving=True, last_bill_result='')
alice.set_tip_to('bob', 1)
update_homepage_queries_once(self.db)

actual = self.client.get('/').body
expected = "Anonymous"
assert expected in actual

def test_homepage_with_anonymous_receiver(self):
bob, _ = TwitterAccount(self.db, "bob", {}).opt_in("bob")
self.update_participant(bob.participant, anonymous_receiving=True, last_bill_result='')
alice = self.make_participant('alice', last_bill_result='', claimed_time='now')
alice.set_tip_to('bob', 1)
update_homepage_queries_once(self.db)

Expand Down
15 changes: 13 additions & 2 deletions tests/test_public_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,25 @@ def test_anonymous_gets_giving(self):
def test_anonymous_gets_null_giving_if_user_anonymous(self):
alice = self.make_participant( 'alice'
, last_bill_result=''
, anonymous=True
)
, anonymous_giving=True
)
self.make_participant('bob')
alice.set_tip_to('bob', '1.00')
data = json.loads(TestClient().get('/alice/public.json').body)

assert data['giving'] == None

def test_anonymous_gets_null_receiving_if_user_anonymous(self):
alice = self.make_participant( 'alice'
, last_bill_result=''
, anonymous_receiving=True
)
self.make_participant('bob')
alice.set_tip_to('bob', '1.00')
data = json.loads(TestClient().get('/alice/public.json').body)

assert data['receiving'] == None

def test_anonymous_does_not_get_goal_if_user_regifts(self):
self.make_participant('alice', last_bill_result='', goal=0)
data = json.loads(TestClient().get('/alice/public.json').body)
Expand Down
20 changes: 13 additions & 7 deletions www/%username/anonymous.json.spt
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,25 @@ if user.ANON:
raise Response(404)
request.allow("GET", "POST")
if POST:
field = body.get("toggle", "giving")
if field not in ["giving", "receiving"]:
raise Response(400)
rec = website.db.one("""

UPDATE participants
SET anonymous=not anonymous
SET anonymous_{0}=not anonymous_{0}
WHERE username=%s
RETURNING anonymous
RETURNING anonymous_{0}

""", (user.participant.username,))
""".format(field), (user.participant.username,))
assert rec is not None
response.body = {field: rec}
else:
rec = website.db.one("""

SELECT anonymous FROM participants WHERE username=%s
SELECT anonymous_giving AS giving, anonymous_receiving AS receiving
FROM participants WHERE username=%s

""", (user.participant.username,))
assert rec is not None
response.body = {"anonymous": rec}
""", (user.participant.username,), back_as=dict)
assert rec is not None
response.body = rec
Loading