|
7 | 7 | from django.core.exceptions import ValidationError |
8 | 8 | from django.test import TestCase |
9 | 9 |
|
10 | | -from content.models import ContentDocument, ContentRelease, expected_storage_prefix |
| 10 | +from content.models import ( |
| 11 | + LEGACY_PUBLIC_CONTRACT_DIGEST, |
| 12 | + PUBLIC_CONTRACT_DIGEST, |
| 13 | + ContentDocument, |
| 14 | + ContentRelease, |
| 15 | + expected_storage_prefix, |
| 16 | +) |
11 | 17 | from content.queries import ( |
12 | 18 | ResolvePublicAsset, |
13 | 19 | ResolvePublicDocument, |
@@ -64,6 +70,77 @@ def _create_queued(self, source, character: str = "d") -> ContentRelease: |
64 | 70 | context=CONTEXT, |
65 | 71 | ) |
66 | 72 |
|
| 73 | + def test_new_release_digest_is_current_and_legacy_release_can_be_rolled_back(self) -> None: |
| 74 | + source = make_source() |
| 75 | + source.refresh_from_db() |
| 76 | + with self.assertRaisesRegex( |
| 77 | + ContentReadinessError, |
| 78 | + "checked public contract artifact", |
| 79 | + ): |
| 80 | + create_content_release( |
| 81 | + CreateContentRelease( |
| 82 | + source_id=source.id, |
| 83 | + expected_source_revision=source.revision, |
| 84 | + commit_sha="a" * 40, |
| 85 | + parser_version="parser-v1", |
| 86 | + rendering_version="renderer-v1", |
| 87 | + request_provenance={"mode": "legacy-digest-rejection"}, |
| 88 | + public_contracts_sha256=LEGACY_PUBLIC_CONTRACT_DIGEST, |
| 89 | + ), |
| 90 | + context=CONTEXT, |
| 91 | + ) |
| 92 | + self.assertEqual(ContentRelease.objects.count(), 0) |
| 93 | + |
| 94 | + first = activate(source, make_ready_release(source, commit_character="b")) |
| 95 | + self.assertEqual(first.public_contracts_sha256, PUBLIC_CONTRACT_DIGEST) |
| 96 | + second = make_ready_release(source, commit_character="c") |
| 97 | + first.refresh_from_db() |
| 98 | + source.refresh_from_db() |
| 99 | + ContentRelease.objects.filter(pk=second.id).update( |
| 100 | + public_contracts_sha256=LEGACY_PUBLIC_CONTRACT_DIGEST, |
| 101 | + ) |
| 102 | + second.refresh_from_db() |
| 103 | + with self.assertRaises(ContentReadinessError): |
| 104 | + activate_content_release( |
| 105 | + ActivateContentRelease( |
| 106 | + source.id, |
| 107 | + second.id, |
| 108 | + source.revision, |
| 109 | + second.revision, |
| 110 | + "legacy digest cannot activate as a new candidate", |
| 111 | + ), |
| 112 | + context=CONTEXT, |
| 113 | + ) |
| 114 | + source.refresh_from_db() |
| 115 | + self.assertEqual(source.active_release_id, first.id) |
| 116 | + |
| 117 | + ContentRelease.objects.filter(pk=second.id).update( |
| 118 | + public_contracts_sha256=PUBLIC_CONTRACT_DIGEST, |
| 119 | + ) |
| 120 | + second.refresh_from_db() |
| 121 | + source.refresh_from_db() |
| 122 | + activate(source, second) |
| 123 | + |
| 124 | + ContentRelease.objects.filter(pk=first.id).update( |
| 125 | + public_contracts_sha256=LEGACY_PUBLIC_CONTRACT_DIGEST, |
| 126 | + ) |
| 127 | + first.refresh_from_db() |
| 128 | + source.refresh_from_db() |
| 129 | + rollback_content_release( |
| 130 | + RollbackContentRelease( |
| 131 | + source.id, |
| 132 | + first.id, |
| 133 | + source.revision, |
| 134 | + first.revision, |
| 135 | + "retain legacy release", |
| 136 | + ), |
| 137 | + context=CONTEXT, |
| 138 | + ) |
| 139 | + source.refresh_from_db() |
| 140 | + first.refresh_from_db() |
| 141 | + self.assertEqual(source.active_release_id, first.id) |
| 142 | + self.assertEqual(first.public_contracts_sha256, LEGACY_PUBLIC_CONTRACT_DIGEST) |
| 143 | + |
67 | 144 | def test_allowed_terminal_edges_and_omitted_transitions_fail_closed(self) -> None: |
68 | 145 | source = make_source() |
69 | 146 | queued = self._create_queued(source, "d") |
|
0 commit comments