From d592aef51547ff7cf560709198f375978ba376f4 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone <exarkun@twistedmatrix.com> Date: Tue, 26 May 2020 11:41:14 -0400 Subject: [PATCH] expand direct testing of `PassGroup` --- .../tests/test_storage_client.py | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/src/_zkapauthorizer/tests/test_storage_client.py b/src/_zkapauthorizer/tests/test_storage_client.py index 39f0e6c..6716ad7 100644 --- a/src/_zkapauthorizer/tests/test_storage_client.py +++ b/src/_zkapauthorizer/tests/test_storage_client.py @@ -46,6 +46,9 @@ from testtools.twistedsupport import ( from hypothesis import ( given, ) +from hypothesis.strategies import ( + sampled_from, +) from twisted.internet.defer import ( succeed, @@ -55,6 +58,7 @@ from twisted.internet.defer import ( from .matchers import ( even, odd, + raises, ) from .strategies import ( @@ -342,3 +346,86 @@ class CallWithPassesTests(TestCase): issued=Equals(set(accepted + rejected)), ), ) + +def reset(group): + group.reset() + +def spend(group): + group.mark_spent() + +def invalidate(group): + group.mark_invalid(u"reason") + + +class PassFactoryTests(TestCase): + """ + Tests for ``pass_factory``. + + It is unfortunate that this isn't the same test suite as + ``test_spending.PassGroupTests``. + """ + @given(pass_counts(), pass_counts()) + def test_returned_passes_reused(self, num_passes_a, num_passes_b): + """ + ``IPassGroup.reset`` makes passes available to be returned by + ``IPassGroup.get`` again. + """ + message = u"message" + min_passes = min(num_passes_a, num_passes_b) + max_passes = max(num_passes_a, num_passes_b) + + factory = pass_factory(integer_passes(max_passes)) + group_a = factory.get(message, num_passes_a) + group_a.reset() + + group_b = factory.get(message, num_passes_b) + self.assertThat( + group_a.passes[:min_passes], + Equals(group_b.passes[:min_passes]), + ) + + def _test_disallowed_transition(self, num_passes, setup_op, invalid_op): + message = u"message" + factory = pass_factory(integer_passes(num_passes)) + group = factory.get(message, num_passes) + setup_op(group) + self.assertThat( + lambda: invalid_op(group), + raises(ValueError), + ) + + @given(pass_counts(), sampled_from([reset, spend, invalidate])) + def test_not_spendable(self, num_passes, setup_op): + """ + ``PassGroup.mark_spent`` raises ``ValueError`` if any passes in the group + are in a state other than in-use. + """ + self._test_disallowed_transition( + num_passes, + setup_op, + spend, + ) + + @given(pass_counts(), sampled_from([reset, spend, invalidate])) + def test_not_resetable(self, num_passes, setup_op): + """ + ``PassGroup.reset`` raises ``ValueError`` if any passes in the group are + in a state other than in-use. + """ + self._test_disallowed_transition( + num_passes, + setup_op, + reset, + ) + + @given(pass_counts(), sampled_from([reset, spend, invalidate])) + def test_not_invalidateable(self, num_passes, setup_op): + """ + ``PassGroup.mark_invalid`` raises ``ValueError`` if any passes in the + group are in a state other than in-use. + """ + self._test_disallowed_transition( + num_passes, + setup_op, + invalidate, + ) -- GitLab