|
@@ -95,7 +95,8 @@ final class MaintenanceControllerTest extends AppTestCase
|
|
|
$first = $this->request(
|
|
$first = $this->request(
|
|
|
'POST',
|
|
'POST',
|
|
|
'/api/v1/admin/maintenance/seed-demo',
|
|
'/api/v1/admin/maintenance/seed-demo',
|
|
|
- ['Authorization' => 'Bearer ' . $token],
|
|
|
|
|
|
|
+ ['Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json'],
|
|
|
|
|
+ '{"confirm": "SEED"}',
|
|
|
);
|
|
);
|
|
|
self::assertSame(200, $first->getStatusCode());
|
|
self::assertSame(200, $first->getStatusCode());
|
|
|
$body = $this->decode($first);
|
|
$body = $this->decode($first);
|
|
@@ -112,7 +113,8 @@ final class MaintenanceControllerTest extends AppTestCase
|
|
|
$second = $this->request(
|
|
$second = $this->request(
|
|
|
'POST',
|
|
'POST',
|
|
|
'/api/v1/admin/maintenance/seed-demo',
|
|
'/api/v1/admin/maintenance/seed-demo',
|
|
|
- ['Authorization' => 'Bearer ' . $token],
|
|
|
|
|
|
|
+ ['Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json'],
|
|
|
|
|
+ '{"confirm": "SEED"}',
|
|
|
);
|
|
);
|
|
|
self::assertSame(409, $second->getStatusCode());
|
|
self::assertSame(409, $second->getStatusCode());
|
|
|
self::assertSame('already_seeded', $this->decode($second)['error']);
|
|
self::assertSame('already_seeded', $this->decode($second)['error']);
|
|
@@ -124,8 +126,42 @@ final class MaintenanceControllerTest extends AppTestCase
|
|
|
$resp = $this->request(
|
|
$resp = $this->request(
|
|
|
'POST',
|
|
'POST',
|
|
|
'/api/v1/admin/maintenance/seed-demo',
|
|
'/api/v1/admin/maintenance/seed-demo',
|
|
|
- ['Authorization' => 'Bearer ' . $token],
|
|
|
|
|
|
|
+ ['Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json'],
|
|
|
|
|
+ '{"confirm": "SEED"}',
|
|
|
);
|
|
);
|
|
|
self::assertSame(403, $resp->getStatusCode());
|
|
self::assertSame(403, $resp->getStatusCode());
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * SEC_REVIEW F15: a single drive-by POST with no body must not load the
|
|
|
|
|
+ * demo dataset. The API requires `confirm: "SEED"` symmetric with
|
|
|
|
|
+ * `purge`'s `"PURGE"` gate.
|
|
|
|
|
+ */
|
|
|
|
|
+ public function testSeedDemoRequiresLiteralConfirmString(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $token = $this->createToken(TokenKind::Admin, Role::Admin);
|
|
|
|
|
+
|
|
|
|
|
+ // No body at all.
|
|
|
|
|
+ $bare = $this->request(
|
|
|
|
|
+ 'POST',
|
|
|
|
|
+ '/api/v1/admin/maintenance/seed-demo',
|
|
|
|
|
+ ['Authorization' => 'Bearer ' . $token],
|
|
|
|
|
+ );
|
|
|
|
|
+ self::assertSame(400, $bare->getStatusCode());
|
|
|
|
|
+ self::assertSame('validation_failed', $this->decode($bare)['error']);
|
|
|
|
|
+
|
|
|
|
|
+ // Wrong literal.
|
|
|
|
|
+ $wrong = $this->request(
|
|
|
|
|
+ 'POST',
|
|
|
|
|
+ '/api/v1/admin/maintenance/seed-demo',
|
|
|
|
|
+ ['Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json'],
|
|
|
|
|
+ '{"confirm": "yes"}',
|
|
|
|
|
+ );
|
|
|
|
|
+ self::assertSame(400, $wrong->getStatusCode());
|
|
|
|
|
+ self::assertSame('validation_failed', $this->decode($wrong)['error']);
|
|
|
|
|
+
|
|
|
|
|
+ // Nothing landed.
|
|
|
|
|
+ self::assertSame(0, (int) $this->db->fetchOne('SELECT COUNT(*) FROM reporters'));
|
|
|
|
|
+ self::assertSame(0, (int) $this->db->fetchOne('SELECT COUNT(*) FROM reports'));
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|