test_hashes.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. """
  2. Tests for the hashes plugin.
  3. Tests the real merkle tree generation with actual files.
  4. """
  5. import json
  6. import os
  7. import subprocess
  8. import sys
  9. import tempfile
  10. from pathlib import Path
  11. import pytest
  12. from django.test import TestCase
  13. # Get the path to the hashes hook
  14. PLUGIN_DIR = Path(__file__).parent.parent
  15. HASHES_HOOK = PLUGIN_DIR / 'on_Snapshot__93_hashes.py'
  16. class TestHashesPlugin(TestCase):
  17. """Test the hashes plugin."""
  18. def test_hashes_hook_exists(self):
  19. """Hashes hook script should exist."""
  20. self.assertTrue(HASHES_HOOK.exists(), f"Hook not found: {HASHES_HOOK}")
  21. def test_hashes_generates_tree_for_files(self):
  22. """Hashes hook should generate merkle tree for files in snapshot directory."""
  23. with tempfile.TemporaryDirectory() as temp_dir:
  24. # Create a mock snapshot directory structure
  25. snapshot_dir = Path(temp_dir) / 'snapshot'
  26. snapshot_dir.mkdir()
  27. # Create output directory for hashes
  28. output_dir = snapshot_dir / 'hashes'
  29. output_dir.mkdir()
  30. # Create some test files
  31. (snapshot_dir / 'index.html').write_text('<html><body>Test</body></html>')
  32. (snapshot_dir / 'screenshot.png').write_bytes(b'\x89PNG\r\n\x1a\n' + b'\x00' * 100)
  33. subdir = snapshot_dir / 'media'
  34. subdir.mkdir()
  35. (subdir / 'video.mp4').write_bytes(b'\x00\x00\x00\x18ftypmp42')
  36. # Run the hook from the output directory
  37. env = os.environ.copy()
  38. env['HASHES_ENABLED'] = 'true'
  39. result = subprocess.run(
  40. [
  41. sys.executable, str(HASHES_HOOK),
  42. '--url=https://example.com',
  43. '--snapshot-id=test-snapshot',
  44. ],
  45. capture_output=True,
  46. text=True,
  47. cwd=str(output_dir), # Hook expects to run from output dir
  48. env=env,
  49. timeout=30
  50. )
  51. # Should succeed
  52. self.assertEqual(result.returncode, 0, f"Hook failed: {result.stderr}")
  53. # Check output file exists
  54. output_file = output_dir / 'hashes.json'
  55. self.assertTrue(output_file.exists(), "hashes.json not created")
  56. # Parse and verify output
  57. with open(output_file) as f:
  58. data = json.load(f)
  59. self.assertIn('root_hash', data)
  60. self.assertIn('files', data)
  61. self.assertIn('metadata', data)
  62. # Should have indexed our test files
  63. file_paths = [f['path'] for f in data['files']]
  64. self.assertIn('index.html', file_paths)
  65. self.assertIn('screenshot.png', file_paths)
  66. # Verify metadata
  67. self.assertGreater(data['metadata']['file_count'], 0)
  68. self.assertGreater(data['metadata']['total_size'], 0)
  69. def test_hashes_skips_when_disabled(self):
  70. """Hashes hook should skip when HASHES_ENABLED=false."""
  71. with tempfile.TemporaryDirectory() as temp_dir:
  72. snapshot_dir = Path(temp_dir) / 'snapshot'
  73. snapshot_dir.mkdir()
  74. output_dir = snapshot_dir / 'hashes'
  75. output_dir.mkdir()
  76. env = os.environ.copy()
  77. env['HASHES_ENABLED'] = 'false'
  78. result = subprocess.run(
  79. [
  80. sys.executable, str(HASHES_HOOK),
  81. '--url=https://example.com',
  82. '--snapshot-id=test-snapshot',
  83. ],
  84. capture_output=True,
  85. text=True,
  86. cwd=str(output_dir),
  87. env=env,
  88. timeout=30
  89. )
  90. # Should succeed (exit 0) but skip
  91. self.assertEqual(result.returncode, 0)
  92. self.assertIn('skipped', result.stdout)
  93. def test_hashes_handles_empty_directory(self):
  94. """Hashes hook should handle empty snapshot directory."""
  95. with tempfile.TemporaryDirectory() as temp_dir:
  96. snapshot_dir = Path(temp_dir) / 'snapshot'
  97. snapshot_dir.mkdir()
  98. output_dir = snapshot_dir / 'hashes'
  99. output_dir.mkdir()
  100. env = os.environ.copy()
  101. env['HASHES_ENABLED'] = 'true'
  102. result = subprocess.run(
  103. [
  104. sys.executable, str(HASHES_HOOK),
  105. '--url=https://example.com',
  106. '--snapshot-id=test-snapshot',
  107. ],
  108. capture_output=True,
  109. text=True,
  110. cwd=str(output_dir),
  111. env=env,
  112. timeout=30
  113. )
  114. # Should succeed even with empty directory
  115. self.assertEqual(result.returncode, 0, f"Hook failed: {result.stderr}")
  116. # Check output file exists
  117. output_file = output_dir / 'hashes.json'
  118. self.assertTrue(output_file.exists())
  119. with open(output_file) as f:
  120. data = json.load(f)
  121. # Should have empty file list
  122. self.assertEqual(data['metadata']['file_count'], 0)
  123. if __name__ == '__main__':
  124. pytest.main([__file__, '-v'])