diff --git a/tests/test_abuse_prevention.py b/tests/test_abuse_prevention.py index 8cd8ae9..5197627 100644 --- a/tests/test_abuse_prevention.py +++ b/tests/test_abuse_prevention.py @@ -226,6 +226,108 @@ class TestWindowReset: assert count == 1 # Counter reset +class TestMinimumSizeEnforcement: + """Test minimum paste size requirement.""" + + @pytest.fixture + def minsize_app(self): + """Create app with minimum size requirement enabled.""" + app = create_app("testing") + app.config["MIN_PASTE_SIZE"] = 64 # Require 64 bytes minimum + return app + + @pytest.fixture + def minsize_client(self, minsize_app): + """Create test client with minimum size requirement.""" + return minsize_app.test_client() + + def test_small_content_rejected(self, minsize_client): + """Content below minimum size should be rejected.""" + response = minsize_client.post("/", data=b"too small") + assert response.status_code == 400 + + data = response.get_json() + assert data["error"] == "Paste too small" + assert data["size"] == 9 + assert data["min_size"] == 64 + assert "hint" in data + + def test_content_at_minimum_accepted(self, minsize_client): + """Content at minimum size should be accepted.""" + content = b"x" * 64 + response = minsize_client.post("/", data=content) + assert response.status_code == 201 + + def test_content_above_minimum_accepted(self, minsize_client): + """Content above minimum size should be accepted.""" + content = b"x" * 128 + response = minsize_client.post("/", data=content) + assert response.status_code == 201 + + def test_minsize_disabled_by_default(self, client): + """Minimum size check should be disabled by default (MIN_PASTE_SIZE=0).""" + response = client.post("/", data=b"x") + assert response.status_code == 201 + + +class TestBinaryRequirement: + """Test binary content requirement (MIME-based encryption enforcement).""" + + @pytest.fixture + def binary_app(self): + """Create app with binary requirement enabled.""" + app = create_app("testing") + app.config["REQUIRE_BINARY"] = True + return app + + @pytest.fixture + def binary_client(self, binary_app): + """Create test client with binary requirement.""" + return binary_app.test_client() + + def test_plaintext_rejected(self, binary_client): + """UTF-8 text should be rejected when binary required.""" + response = binary_client.post("/", data=b"Hello, this is plaintext") + assert response.status_code == 400 + + data = response.get_json() + assert data["error"] == "Recognizable format not allowed" + assert data["detected"] == "text/plain" + assert "hint" in data + + def test_png_rejected(self, binary_client): + """PNG magic bytes should be rejected.""" + # PNG signature: 89 50 4E 47 0D 0A 1A 0A + png_content = b"\x89PNG\r\n\x1a\n" + b"\x00" * 100 + response = binary_client.post("/", data=png_content) + assert response.status_code == 400 + + data = response.get_json() + assert data["detected"] == "image/png" + + def test_jpeg_rejected(self, binary_client): + """JPEG magic bytes should be rejected.""" + jpeg_content = b"\xff\xd8\xff" + b"\x00" * 100 + response = binary_client.post("/", data=jpeg_content) + assert response.status_code == 400 + + data = response.get_json() + assert data["detected"] == "image/jpeg" + + def test_random_binary_accepted(self, binary_client): + """Random binary data (encrypted) should be accepted.""" + import os + + random_data = os.urandom(256) # High entropy, no magic bytes + response = binary_client.post("/", data=random_data) + assert response.status_code == 201 + + def test_binary_disabled_by_default(self, client): + """Binary requirement should be disabled by default.""" + response = client.post("/", data=b"plaintext is fine by default") + assert response.status_code == 201 + + class TestEntropyEnforcement: """Test minimum entropy requirement."""