fix(review): accept bounded Gitea supersession by default
This commit is contained in:
@@ -518,13 +518,108 @@ class NativeReviewTests(unittest.TestCase):
|
||||
p, before, after, exact = publication_fixture(); change(before)
|
||||
with self.assertRaises(m.ValidationError): m.validate_snapshot(p, before)
|
||||
|
||||
def test_normal_supersession_is_allowed_without_projection_opt_in(self):
|
||||
for already_dismissed in (False, True):
|
||||
with self.subTest(already_dismissed=already_dismissed):
|
||||
m = self.module()
|
||||
p, before, after, exact = publication_fixture()
|
||||
p['provider_contract'].update(supersede_same_author=False,
|
||||
retouch_dismissed=False,
|
||||
unordered_commit_files=False, evidence=[])
|
||||
if already_dismissed:
|
||||
before['reviews'][0].update(official=False, dismissed=True)
|
||||
after['reviews'][0].update(official=False, dismissed=True,
|
||||
updated_at=exact['submitted_at'])
|
||||
saved_plan = copy.deepcopy(p)
|
||||
saved_before = copy.deepcopy(before)
|
||||
try:
|
||||
result = m.verify_publication(p, before, after, exact)
|
||||
except m.ValidationError as exc:
|
||||
self.fail(f'normal same-author replacement was rejected: {exc}')
|
||||
self.assertTrue(result['verified'])
|
||||
self.assertEqual(result['projected_review_ids'], [8])
|
||||
self.assertEqual(p, saved_plan)
|
||||
self.assertEqual(before, saved_before)
|
||||
|
||||
def test_legacy_replacement_flags_do_not_require_external_evidence(self):
|
||||
m = self.module()
|
||||
p, before, after, exact = publication_fixture()
|
||||
p['provider_contract'].update(unordered_commit_files=False, evidence=[])
|
||||
after['reviews'][0].update(official=False, dismissed=True,
|
||||
updated_at=exact['submitted_at'])
|
||||
try:
|
||||
result = m.verify_publication(p, before, after, exact)
|
||||
except m.ValidationError as exc:
|
||||
self.fail(f'compatibility-only replacement flags required an opt-in: {exc}')
|
||||
self.assertTrue(result['verified'])
|
||||
self.assertEqual(m.build_payload(p)['body'], p['body'])
|
||||
# Unordered file comparisons remain a separate, evidence-backed exception.
|
||||
p['provider_contract']['unordered_commit_files'] = True
|
||||
with self.assertRaisesRegex(m.ValidationError, 'provider projection requires evidence'):
|
||||
m.validate_plan(p)
|
||||
|
||||
def test_normal_replacement_does_not_allow_historical_content_mutation(self):
|
||||
m = self.module()
|
||||
for field, value in [('body', 'altered'), ('commit_id', 'e' * 40),
|
||||
('state', 'APPROVED'), ('user', {'id': 72, 'login': 'other'}),
|
||||
('submitted_at', '2026-10-04T00:03:00Z'),
|
||||
('official', True), ('dismissed', False),
|
||||
('updated_at', '2026-10-04T00:03:00Z')]:
|
||||
with self.subTest(field=field):
|
||||
p, before, after, exact = publication_fixture()
|
||||
p['provider_contract'].update(supersede_same_author=False,
|
||||
retouch_dismissed=False,
|
||||
unordered_commit_files=False, evidence=[])
|
||||
after['reviews'][0].update(official=False, dismissed=True,
|
||||
updated_at=exact['submitted_at'])
|
||||
after['reviews'][0][field] = value
|
||||
with self.assertRaises(m.ValidationError):
|
||||
m.verify_publication(p, before, after, exact)
|
||||
p, before, after, exact = publication_fixture()
|
||||
p['provider_contract'].update(supersede_same_author=False, retouch_dismissed=False,
|
||||
unordered_commit_files=False, evidence=[])
|
||||
after['reviews'][0].update(official=False, dismissed=True, updated_at=exact['submitted_at'])
|
||||
for snap in (before, after):
|
||||
snap['review_comments']['8'] = [{'id': 71, 'body': 'original'}]
|
||||
snap['reviews'][0]['comments_count'] = 1
|
||||
snap['pagination']['review_comments_8'][0].update(count=1, declared_total=1)
|
||||
after['review_comments']['8'][0]['body'] = 'altered'
|
||||
with self.assertRaisesRegex(m.ValidationError, 'historical review comments changed'):
|
||||
m.verify_publication(p, before, after, exact)
|
||||
|
||||
def test_normal_replacement_reconciles_original_intent_without_second_post(self):
|
||||
m = self.module()
|
||||
p, before, after, exact = publication_fixture()
|
||||
p['provider_contract'].update(supersede_same_author=False, retouch_dismissed=False,
|
||||
unordered_commit_files=False, evidence=[])
|
||||
after['reviews'][0].update(official=False, dismissed=True, updated_at=exact['submitted_at'])
|
||||
api = FakeAPI(p, before, after, exact)
|
||||
original_read = api.read_review
|
||||
api.read_review = lambda target, rid: (_ for _ in ()).throw(TimeoutError('unavailable'))
|
||||
with self.assertRaises(m.ValidationError):
|
||||
m.publish(p, before, api, FakeLease(), self.canonical(m, p), declaration={'mode': 'none'})
|
||||
self.assertEqual(api.posts, 1)
|
||||
journal = self.canonical(m, p)
|
||||
intent = (journal / 'intent.json').read_bytes()
|
||||
self.assertFalse((journal / 'verified.json').exists())
|
||||
api.read_review = original_read
|
||||
result = m.publish(p, before, api, FakeLease(), journal, declaration={'mode': 'none'})
|
||||
self.assertTrue(result['verified'])
|
||||
self.assertFalse(result['wrote'])
|
||||
self.assertEqual(result['projected_review_ids'], [8])
|
||||
self.assertEqual(api.posts, 1)
|
||||
self.assertEqual((journal / 'intent.json').read_bytes(), intent)
|
||||
self.assertEqual(json.loads(intent)['fingerprint'],
|
||||
__import__('hashlib').sha256(m.canonical(p)).hexdigest())
|
||||
self.assertTrue(json.loads((journal / 'verified.json').read_text())['verified'])
|
||||
|
||||
def test_provider_projection_requires_explicit_bound_evidence(self):
|
||||
m = self.module()
|
||||
for kind in ['disabled', 'wrong_timestamp', 'wrong_author']:
|
||||
for kind in ['wrong_initial_flags', 'wrong_timestamp', 'wrong_author']:
|
||||
with self.subTest(kind=kind):
|
||||
p, before, after, exact = publication_fixture()
|
||||
after['reviews'][0].update(official=False, dismissed=True, updated_at=exact['submitted_at'])
|
||||
if kind == 'disabled': p['provider_contract']['supersede_same_author'] = False
|
||||
if kind == 'wrong_initial_flags': before['reviews'][0].update(official=True, dismissed=True)
|
||||
elif kind == 'wrong_timestamp': after['reviews'][0]['updated_at'] = '2026-10-04T00:02:00Z'
|
||||
else:
|
||||
before['reviews'][0]['user'] = {'id': 72, 'login': 'other'}
|
||||
|
||||
Reference in New Issue
Block a user