diff --git a/app/Services/ClusterCompetitiveness.php b/app/Services/ClusterCompetitiveness.php index 521e80ba..44ac5916 100644 --- a/app/Services/ClusterCompetitiveness.php +++ b/app/Services/ClusterCompetitiveness.php @@ -57,6 +57,7 @@ final class ClusterCompetitiveness } } $clean = Validator::make($draft, $rules)->validate(); + $clean['version'] = 1; $clean['sector'] = trim($clean['sector'] ?? ''); $clean['region'] = trim($clean['region'] ?? ''); foreach (self::FORCES as $force) { diff --git a/tests/Feature/ClusterCompetitivenessTest.php b/tests/Feature/ClusterCompetitivenessTest.php index 76e548d6..e7b30483 100644 --- a/tests/Feature/ClusterCompetitivenessTest.php +++ b/tests/Feature/ClusterCompetitivenessTest.php @@ -121,6 +121,19 @@ class ClusterCompetitivenessTest extends TestCase $this->getJson($this->url($cluster))->assertJsonPath('version', 1)->assertJsonPath('draft.forces.buyers.source', ''); } + public function test_saved_data_keeps_the_portable_file_contract_and_rejects_missing_forces(): void + { + $this->manager(); + $cluster = $this->cluster(); + $draft = $this->draft($cluster); + $draft['version'] = '1'; + $this->postJson($this->url($cluster).'/saved', ['expected_version' => 0, 'draft' => $draft]) + ->assertOk()->assertJsonPath('draft.version', 1); + unset($draft['forces']['suppliers']); + $this->postJson($this->url($cluster).'/saved', ['expected_version' => 1, 'draft' => $draft])->assertUnprocessable(); + $this->getJson($this->url($cluster))->assertJsonPath('version', 1); + } + public function test_anonymous_and_unauthorised_users_cannot_read_history_or_mutate(): void { $cluster = $this->cluster();