Repository: gratipay/gratipay.com

Issue:
log spam during test
What's this `TypeError` about? Seems spurious ...

```
pid-13897 thread-4384100352 (Thread-1) Traceback (most recent call last):
pid-13897 thread-4384100352 (Thread-1)   File "/Users/whit537/personal/gratipay/gratipay.com/gratipay/cron.py", line 26, in f
pid-13897 thread-4384100352 (Thread-1)     func()
pid-13897 thread-4384100352 (Thread-1)   File "/Users/whit537/personal/gratipay/gratipay.com/gratipay/main.py", line 82, in <lambda>
pid-13897 thread-4384100352 (Thread-1)     cron(env.update_cta_every, lambda: utils.update_cta(website))
pid-13897 thread-4384100352 (Thread-1)   File "/Users/whit537/personal/gratipay/gratipay.com/gratipay/utils/__init__.py", line 145, in update_cta
pid-13897 thread-4384100352 (Thread-1)     website.support_current = cur = int(round(nreceiving_from / nusers * 100)) if nusers else 0
pid-13897 thread-4384100352 (Thread-1) TypeError: unsupported operand type(s) for /: 'int' and 'tuple'
```



Discussion:
+1 from @yifeiwu at https://github.com/gratipay/inside.gratipay.com/issues/336#issuecomment-140037659.

Working on this because it's actually blocking the tests I'm trying to write for #3788: certain test cases expect `website.support_current` to be available (and it's curious that the test suite isn't failing because of this, I guess that means we don't exercise `support_current` otherwise?).

This is a weird line:

https://github.com/gratipay/gratipay.com/blob/1915/gratipay/utils/__init__.py#L139

Why is the default for `nusers` a tuple?

Blame: https://github.com/gratipay/gratipay.com/blame/1915/gratipay/utils/__init__.py#L139

Borked at https://github.com/gratipay/gratipay.com/commit/26611acda5706fe8708becbae696f3c7829c0627#diff-29dde85b4bbb7c47ef404ed0ab9f054eL135.


Resolving patch:
diff --git a/gratipay/utils/__init__.py b/gratipay/utils/__init__.py
--- a/gratipay/utils/__init__.py
+++ b/gratipay/utils/__init__.py
@@ -136,7 +136,7 @@ def update_cta(website):
     nusers = website.db.one("""
         SELECT nusers FROM paydays
         ORDER BY ts_end DESC LIMIT 1
-    """, default=(0.0, 0))
+    """, default=0)
     nreceiving_from = website.db.one("""
         SELECT nreceiving_from
           FROM teams


Test patch:
diff --git a/tests/py/test_privacy_json.py b/tests/py/test_privacy_json.py
--- a/tests/py/test_privacy_json.py
+++ b/tests/py/test_privacy_json.py
@@ -58,3 +58,57 @@ def test_participant_does_show_up_on_search(self):
     def test_participant_doesnt_show_up_on_search(self):
         self.hit_privacy('POST', data={'toggle': 'is_searchable'})
         assert 'alice' not in self.client.GET("/search.json?q=alice").body
+
+    # Related to anonymous_giving
+
+    def test_anon_can_see_giving_for_non_anonymous_giving(self):
+        self.make_participant('bob', claimed_time='now',
+                              giving=10.79, ngiving_to=342, anonymous_giving=False)
+        assert '10.79' in self.client.GET('/~bob/').body
+        assert '342' in self.client.GET('/~bob/').body
+
+    def test_auth_can_see_giving_for_non_anonymous_giving(self):
+        self.make_participant('bob', claimed_time='now',
+                              giving=10.79, ngiving_to=342, anonymous_giving=False)
+        assert '10.79' in self.client.GET('/~bob/', auth_as='alice').body
+        assert '342' in self.client.GET('/~bob/', auth_as='alice').body
+
+    def test_admin_can_see_giving_for_non_anonymous_giving(self):
+        self.make_participant('bob', claimed_time='now',
+                              giving=10.79, ngiving_to=342, anonymous_giving=False)
+        self.make_participant('admin', is_admin=True)
+        assert '10.79' in self.client.GET('/~bob/', auth_as='admin').body
+        assert '342' in self.client.GET('/~bob/', auth_as='admin').body
+        assert '[342]' not in self.client.GET('/~bob/', auth_as='admin').body
+
+    def test_self_can_see_giving_for_non_anonymous_giving(self):
+        self.make_participant('bob', claimed_time='now',
+                              giving=10.79, ngiving_to=342, anonymous_giving=False)
+        assert '10.79' in self.client.GET('/~bob/', auth_as='bob').body.decode('utf8')
+        assert '342' in self.client.GET('/~bob/', auth_as='bob').body.decode('utf8')
+        assert '[342]' not in self.client.GET('/~bob/', auth_as='bob').body.decode('utf8')
+
+    def test_anon_cannot_see_giving_for_anonymous_giving(self):
+        self.make_participant('bob', claimed_time='now',
+                              giving=10.79, ngiving_to=342, anonymous_giving=True)
+        assert '10.79' not in self.client.GET('/~bob/').body
+        assert '342' not in self.client.GET('/~bob/').body
+
+    def test_auth_cannot_see_giving_for_anonymous_giving(self):
+        self.make_participant('bob', claimed_time='now',
+                              giving=10.79, ngiving_to=342, anonymous_giving=True)
+        assert '10.79' not in self.client.GET('/~bob/', auth_as='alice').body
+        assert '342' not in self.client.GET('/~bob/', auth_as='alice').body
+
+    def test_admin_can_see_giving_for_anonymous_giving(self):
+        self.make_participant('bob', claimed_time='now',
+                              giving=10.79, ngiving_to=342, anonymous_giving=True)
+        self.make_participant('admin', is_admin=True)
+        assert '10.79' in self.client.GET('/~bob/', auth_as='admin').body
+        assert '[342]' in self.client.GET('/~bob/', auth_as='admin').body
+
+    def test_self_can_see_giving_for_anonymous_giving(self):
+        self.make_participant('bob', claimed_time='now',
+                              giving=10.79, ngiving_to=342, anonymous_giving=True)
+        assert '10.79' in self.client.GET('/~bob/', auth_as='bob').body.decode('utf8')
+        assert '[342]' in self.client.GET('/~bob/', auth_as='bob').body.decode('utf8')