From 046514ea155d7468586370b2acf4bd2b09fedf71 Mon Sep 17 00:00:00 2001
From: Jean-Paul Calderone <exarkun@twistedmatrix.com>
Date: Fri, 23 Jul 2021 13:30:08 -0400
Subject: [PATCH] Add "spendable" value to the unblinded-token endpoints reply

---
 docs/source/interface.rst                         | 2 ++
 src/_zkapauthorizer/resource.py                   | 1 +
 src/_zkapauthorizer/tests/test_client_resource.py | 8 ++++++--
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/docs/source/interface.rst b/docs/source/interface.rst
index 81435b1..d3223d6 100644
--- a/docs/source/interface.rst
+++ b/docs/source/interface.rst
@@ -154,12 +154,14 @@ This endpoint accepts no request body.
 The response is **OK** with ``application/json`` content-type response body like::
 
   { "total": <integer>
+  , "spendable": <integer>
   , "unblinded-tokens": [<unblinded token string>, ...]
   , "lease-maintenance-spending": <spending object>
   }
 
 The value associated with ``total`` gives the total number of unblinded tokens in the node's database
 (independent of any limit placed on this query).
+The value associated with ``spendable`` gives the number of unblinded tokens in the node's database which can actually be spent.
 The value associated with ``unblinded-tokens`` gives the requested list of unblinded tokens.
 
 The ``<spending object>`` may be ``null`` if the lease maintenance process has never run.
diff --git a/src/_zkapauthorizer/resource.py b/src/_zkapauthorizer/resource.py
index e675ed2..1663b0c 100644
--- a/src/_zkapauthorizer/resource.py
+++ b/src/_zkapauthorizer/resource.py
@@ -370,6 +370,7 @@ class _UnblindedTokenCollection(Resource):
 
         return dumps({
             u"total": len(unblinded_tokens),
+            u"spendable": self._store.count_unblinded_tokens(),
             u"unblinded-tokens": list(islice((
                 token
                 for token
diff --git a/src/_zkapauthorizer/tests/test_client_resource.py b/src/_zkapauthorizer/tests/test_client_resource.py
index 5bee598..09e1bf0 100644
--- a/src/_zkapauthorizer/tests/test_client_resource.py
+++ b/src/_zkapauthorizer/tests/test_client_resource.py
@@ -762,6 +762,7 @@ class UnblindedTokenTests(TestCase):
             requesting,
             succeeded_with_unblinded_tokens_with_matcher(
                 num_tokens,
+                Equals(num_tokens),
                 AllMatch(
                     MatchesAll(
                         GreaterThan(position),
@@ -896,6 +897,7 @@ class UnblindedTokenTests(TestCase):
 
 def succeeded_with_unblinded_tokens_with_matcher(
         all_token_count,
+        match_spendable_token_count,
         match_unblinded_tokens,
         match_lease_maint_spending,
 ):
@@ -920,6 +922,7 @@ def succeeded_with_unblinded_tokens_with_matcher(
                 succeeded(
                     ContainsDict({
                         u"total": Equals(all_token_count),
+                        u"spendable": match_spendable_token_count,
                         u"unblinded-tokens": match_unblinded_tokens,
                         u"lease-maintenance-spending": match_lease_maint_spending,
                     }),
@@ -941,11 +944,12 @@ def succeeded_with_unblinded_tokens(all_token_count, returned_token_count):
     """
     return succeeded_with_unblinded_tokens_with_matcher(
         all_token_count,
-        MatchesAll(
+        match_spendable_token_count=Equals(all_token_count),
+        match_unblinded_tokens=MatchesAll(
             HasLength(returned_token_count),
             AllMatch(IsInstance(unicode)),
         ),
-        matches_lease_maintenance_spending(),
+        match_lease_maint_spending=matches_lease_maintenance_spending(),
     )
 
 def matches_lease_maintenance_spending():
-- 
GitLab