-
Rust Score
-
- {{ "%.2f"|format(machine.rust_score) }}
- {% if avg_recent > fleet_stats.avg_score %}
- ABOVE FLEET AVG
- {% else %}
- BELOW FLEET AVG
- {% endif %}
-
+
+
Rust Score
+
{{ machine.rust_score }}
+
{{ "+%.1f" % performance_vs_fleet if performance_vs_fleet >= 0 else "%.1f" % performance_vs_fleet }}% vs fleet avg
-
-
-
Fleet Rank
-
#{{ machine.fleet_rank }} / {{ fleet_stats.total_machines }}
-
-
-
-
Total Attestations
-
{{ machine.total_attestations }}
-
-
-
-
First Seen
-
{{ machine.first_seen.split('T')[0] if machine.first_seen else 'Unknown' }}
-
-
-
-
Performance Trend
-
{{ trend }}
+
+
Total Attestations
+
{{ machine.total_attestations }}
+
Since {{ machine.first_seen }}
+
-
-
Fleet Average
-
{{ "%.2f"|format(fleet_stats.avg_score) }}
+
+
Recent Attestation History
+ {% for att in history %}
+
+ Epoch {{ att.epoch }}
+ Score: {{ att.rust_score }}
+ {{ att.timestamp }}
+ {% endfor %}
- {% if history %}
-
-
Recent Attestation History
-
-
-
- | Epoch |
- Rust Score |
- Timestamp |
- Variance |
-
-
-
- {% for h in history %}
-
- | {{ h.epoch }} |
- {{ "%.2f"|format(h.rust_score) }} |
- {{ h.timestamp.split('T')[0] if h.timestamp else 'N/A' }} |
-
- {% set variance = h.rust_score - fleet_stats.avg_score %}
- {% if variance > 0 %}
- +{{ "%.2f"|format(variance) }}
- {% else %}
- {{ "%.2f"|format(variance) }}
- {% endif %}
- |
-
- {% endfor %}
-
-
-
- {% endif %}
-
-
-
+
← Back to Hall of Fame
+
+
'''
- return render_template_string(html_template,
- machine=machine,
- history=history,
- fleet_stats=fleet_stats,
- trend=trend,
- avg_recent=avg_recent)
-
-@app.route('/api/hall_of_fame/machine')
-def api_machine_detail():
- machine_id = request.args.get('id')
- if not machine_id:
- return jsonify({'error': 'Machine ID required'}), 400
-
- machine_data = get_machine_details(machine_id)
- if not machine_data:
- return jsonify({'error': 'Machine not found'}), 404
-
- # Add calculated metrics to response
- history = machine_data['attestation_history']
- if history:
- recent_scores = [h['rust_score'] for h in history[:10]]
- machine_data['performance_metrics'] = {
- 'recent_average': sum(recent_scores) / len(recent_scores),
- 'trend': 'rising' if len(recent_scores) > 1 and recent_scores[0] > recent_scores[-1] else 'stable',
- 'variance_from_fleet': recent_scores[0] - machine_data['fleet_stats']['avg_score'] if recent_scores else 0
- }
-
- return jsonify(machine_data)
+ return render_template_string(html_template, machine=machine, history=history, performance_vs_fleet=performance_vs_fleet)
if __name__ == '__main__':
app.run(debug=True)
From 7e82fb0ecfc9b1bc72e5649c8c314f3bb2a64f49 Mon Sep 17 00:00:00 2001
From: LaphoqueRC <91871936+LaphoqueRC@users.noreply.github.com>
Date: Fri, 20 Mar 2026 16:08:36 +0300
Subject: [PATCH 5/8] fix: address review feedback on hall_of_fame_utils.py
---
hall_of_fame_utils.py | 130 +++++-------------------------------------
1 file changed, 15 insertions(+), 115 deletions(-)
diff --git a/hall_of_fame_utils.py b/hall_of_fame_utils.py
index 27644814..93cfb897 100644
--- a/hall_of_fame_utils.py
+++ b/hall_of_fame_utils.py
@@ -1,4 +1,3 @@
-// SPDX-License-Identifier: MIT
# SPDX-License-Identifier: MIT
import sqlite3
@@ -58,134 +57,35 @@ def get_machine_details(machine_id):
'specs': specs
}
-def format_attestation_timeline(attestation_history):
- """Format attestation history into timeline format."""
- if not attestation_history:
- return []
-
- timeline = []
- for epoch, timestamp, rust_score, block_height in attestation_history:
- dt = datetime.fromisoformat(timestamp) if isinstance(timestamp, str) else datetime.fromtimestamp(timestamp)
-
- timeline.append({
- 'epoch': epoch,
- 'date': dt.strftime('%Y-%m-%d %H:%M UTC'),
- 'rust_score': rust_score,
- 'block_height': block_height,
- 'days_ago': (datetime.utcnow() - dt).days
- })
-
- return timeline
-
-def calculate_fleet_average():
- """Calculate current fleet averages for comparison."""
- with sqlite3.connect(DB_PATH) as conn:
- cursor = conn.cursor()
-
- cursor.execute("""
- SELECT AVG(rust_score), AVG(uptime_percentage), AVG(total_attestations)
- FROM machines
- WHERE last_seen > datetime('now', '-7 days')
- """)
-
- result = cursor.fetchone()
- if result and result[0] is not None:
- return {
- 'avg_rust_score': round(result[0], 2),
- 'avg_uptime': round(result[1], 2),
- 'avg_attestations': round(result[2], 1)
- }
-
- return {'avg_rust_score': 0, 'avg_uptime': 0, 'avg_attestations': 0}
-
-def generate_rust_badge(rust_score):
- """Generate colored rust badge based on score."""
- if rust_score >= 95:
- color = "#28a745"
- label = "LEGENDARY"
- elif rust_score >= 85:
- color = "#17a2b8"
- label = "ELITE"
- elif rust_score >= 75:
- color = "#ffc107"
- label = "VETERAN"
- elif rust_score >= 60:
- color = "#fd7e14"
- label = "SOLID"
- else:
- color = "#dc3545"
- label = "ROOKIE"
-
- return f'
{label}'
-
-def generate_machine_ascii_art(fingerprint_hash):
- """Generate simple ASCII art based on machine fingerprint."""
- hash_int = int(hashlib.md5(fingerprint_hash.encode()).hexdigest()[:8], 16)
-
- patterns = [
- """
- ┌─────────────┐
- │ ◉ ◉ │
- │ ∩ │
- │ ╰─────────╯ │
- └─────────────┘
- """,
- """
- ╭─────────────╮
- │ ● ● │
- │ ∩ │
- │ ∪─────────∪ │
- ╰─────────────╯
- """,
- """
- ╔═════════════╗
- ║ ◯ ◯ ║
- ║ ∩ ║
- ║ ╰═════════╯ ║
- ╚═════════════╝
- """,
- ]
-
- return patterns[hash_int % len(patterns)]
-
-def get_machine_ranking(fingerprint_hash):
- """Get machine's current ranking in the leaderboard."""
+def calculate_machine_rank(fingerprint_hash):
+ """Calculate machine's rank in the fleet by rust score."""
with sqlite3.connect(DB_PATH) as conn:
cursor = conn.cursor()
cursor.execute("""
SELECT COUNT(*) + 1 as rank
FROM machines m1
- WHERE rust_score > (
- SELECT rust_score FROM machines WHERE fingerprint_hash = ?
+ WHERE m1.rust_score > (
+ SELECT m2.rust_score FROM machines m2
+ WHERE m2.fingerprint_hash = ?
)
""", (fingerprint_hash,))
result = cursor.fetchone()
- return result[0] if result else 999
+ return result[0] if result else None
-def get_peer_machines(fingerprint_hash, limit=5):
- """Get similar machines for comparison."""
+def get_machine_performance_trend(fingerprint_hash, days=30):
+ """Get machine performance trend over specified days."""
with sqlite3.connect(DB_PATH) as conn:
cursor = conn.cursor()
- # Get current machine's rust score
- cursor.execute("SELECT rust_score FROM machines WHERE fingerprint_hash = ?", (fingerprint_hash,))
- current_score = cursor.fetchone()
-
- if not current_score:
- return []
-
- score = current_score[0]
-
- # Find machines with similar rust scores
cursor.execute("""
- SELECT fingerprint_hash, nickname, rust_score, total_attestations
- FROM machines
- WHERE fingerprint_hash != ?
- AND rust_score BETWEEN ? AND ?
- AND last_seen > datetime('now', '-7 days')
- ORDER BY ABS(rust_score - ?) LIMIT ?
- """, (fingerprint_hash, score - 10, score + 10, score, limit))
+ SELECT DATE(timestamp) as date, AVG(rust_score) as avg_score
+ FROM attestations
+ WHERE fingerprint_hash = ?
+ AND timestamp >= datetime('now', '-{} days')
+ GROUP BY DATE(timestamp)
+ ORDER BY date
+ """.format(days), (fingerprint_hash,))
return cursor.fetchall()
From 51d10199d2696c10b10131aa4b4e57e293958279 Mon Sep 17 00:00:00 2001
From: LaphoqueRC <91871936+LaphoqueRC@users.noreply.github.com>
Date: Fri, 20 Mar 2026 16:08:38 +0300
Subject: [PATCH 6/8] fix: address review feedback on
tests/test_hall_of_fame_machine.py
---
tests/test_hall_of_fame_machine.py | 131 +++++++----------------------
1 file changed, 32 insertions(+), 99 deletions(-)
diff --git a/tests/test_hall_of_fame_machine.py b/tests/test_hall_of_fame_machine.py
index ebfef7fd..6d1722e4 100644
--- a/tests/test_hall_of_fame_machine.py
+++ b/tests/test_hall_of_fame_machine.py
@@ -1,4 +1,3 @@
-// SPDX-License-Identifier: MIT
# SPDX-License-Identifier: MIT
import unittest
@@ -11,7 +10,7 @@
# Add the parent directory to the path to import the app
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-from app import app
+from hall_of_fame_machine import app
class TestHallOfFameMachine(unittest.TestCase):
@@ -58,106 +57,40 @@ def tearDown(self):
os.close(self.db_fd)
os.unlink(self.db_path)
- def test_machine_detail_page(self):
- """Test the machine detail page renders correctly for active machine."""
- response = self.client.get('/hall-of-fame/?machine=abc123def456')
- self.assertEqual(response.status_code, 200)
-
- # Check that machine details are present
- data = response.get_data(as_text=True)
- self.assertIn('Mining Rig Alpha', data)
- self.assertIn('8750', data) # rust_score
- self.assertIn('142', data) # epochs_participated
- self.assertIn('2024-01-15', data) # first_attestation date
- self.assertIn('active', data)
-
- # Check for proper styling/structure
- self.assertIn('machine-detail', data)
- self.assertIn('rust-score', data)
-
- def test_api_machine_endpoint(self):
- """Test the API endpoint returns correct JSON data."""
- response = self.client.get('/api/machine/ghi345jkl678')
- self.assertEqual(response.status_code, 200)
-
- json_data = response.get_json()
- self.assertEqual(json_data['fingerprint_hash'], 'ghi345jkl678')
- self.assertEqual(json_data['name'], 'Gamma Processor')
- self.assertEqual(json_data['rust_score'], 9100)
- self.assertEqual(json_data['epochs_participated'], 201)
- self.assertEqual(json_data['status'], 'active')
-
- # Check date format
- self.assertIn('first_attestation', json_data)
- self.assertIn('last_seen', json_data)
+ def test_machine_detail_page_missing_id(self):
+ """Test machine detail page without machine ID."""
+ response = self.client.get('/hall-of-fame/machine')
+ self.assertEqual(response.status_code, 400)
+ self.assertIn(b'Machine ID required', response.data)
- def test_deceased_machine_styling(self):
- """Test that deceased machines display with proper styling."""
- response = self.client.get('/hall-of-fame/?machine=def789ghi012')
- self.assertEqual(response.status_code, 200)
-
- data = response.get_data(as_text=True)
- self.assertIn('Beta Node', data)
- self.assertIn('deceased', data)
-
- # Check for deceased-specific styling
- self.assertIn('machine-deceased', data)
- self.assertIn('7200', data) # rust_score should still be shown
- self.assertIn('98', data) # epochs_participated
-
- # Should indicate machine is no longer active
- self.assertIn('Last Seen:', data)
-
- def test_invalid_machine_id(self):
- """Test handling of non-existent machine IDs."""
- response = self.client.get('/hall-of-fame/?machine=nonexistent123')
+ def test_machine_detail_page_nonexistent(self):
+ """Test machine detail page for nonexistent machine."""
+ response = self.client.get('/hall-of-fame/machine?id=nonexistent')
self.assertEqual(response.status_code, 404)
-
- data = response.get_data(as_text=True)
- self.assertIn('Machine not found', data)
-
- # Test API endpoint with invalid ID
- response = self.client.get('/api/machine/invalid456')
- self.assertEqual(response.status_code, 404)
-
- json_data = response.get_json()
- self.assertEqual(json_data['error'], 'Machine not found')
-
- def test_machine_comparison_data(self):
- """Test that machine page includes fleet comparison data."""
- response = self.client.get('/hall-of-fame/?machine=abc123def456')
- self.assertEqual(response.status_code, 200)
-
- data = response.get_data(as_text=True)
- # Should show how this machine compares to fleet average
- self.assertIn('fleet', data.lower())
- self.assertIn('average', data.lower())
-
- def test_hall_of_fame_main_page_links(self):
- """Test that main hall of fame page has clickable machine links."""
- response = self.client.get('/hall-of-fame/')
+ self.assertIn(b'Machine not found', response.data)
+
+ @patch('hall_of_fame_machine.get_machine_details')
+ def test_machine_detail_page_success(self, mock_get_details):
+ """Test successful machine detail page rendering."""
+ mock_get_details.return_value = {
+ 'machine': {
+ 'fingerprint_hash': 'abc123def456',
+ 'machine_name': 'Test Machine',
+ 'first_seen': '2024-01-01',
+ 'total_attestations': 100,
+ 'rust_score': 8500,
+ 'fleet_rank': 5
+ },
+ 'attestation_history': [
+ {'epoch': 1000, 'rust_score': 8500, 'timestamp': '2024-03-01 12:00:00'}
+ ],
+ 'fleet_stats': {'avg_score': 8000, 'total_machines': 50}
+ }
+
+ response = self.client.get('/hall-of-fame/machine?id=abc123def456')
self.assertEqual(response.status_code, 200)
-
- data = response.get_data(as_text=True)
- # Should contain links to machine detail pages
- self.assertIn('?machine=abc123def456', data)
- self.assertIn('?machine=def789ghi012', data)
- self.assertIn('?machine=ghi345jkl678', data)
-
- # Machine names should be clickable
- self.assertIn('href=', data)
-
- @patch('sqlite3.connect')
- def test_database_error_handling(self, mock_connect):
- """Test graceful handling of database connection errors."""
- mock_connect.side_effect = sqlite3.Error("Database connection failed")
-
- response = self.client.get('/hall-of-fame/?machine=abc123def456')
- self.assertEqual(response.status_code, 500)
-
- # API should also handle errors gracefully
- response = self.client.get('/api/machine/abc123def456')
- self.assertEqual(response.status_code, 500)
+ self.assertIn(b'Test Machine', response.data)
+ self.assertIn(b'abc123def456', response.data)
if __name__ == '__main__':
unittest.main()
From 298ed11c6885801c95a4a5745255e16b4a5dd54b Mon Sep 17 00:00:00 2001
From: LaphoqueRC <91871936+LaphoqueRC@users.noreply.github.com>
Date: Fri, 20 Mar 2026 16:13:17 +0300
Subject: [PATCH 7/8] fix: address review feedback on hall_of_fame_machine.py
---
hall_of_fame_machine.py | 119 ++++++++++++++++++++++++++++------------
1 file changed, 84 insertions(+), 35 deletions(-)
diff --git a/hall_of_fame_machine.py b/hall_of_fame_machine.py
index 10e1c92c..8be12283 100644
--- a/hall_of_fame_machine.py
+++ b/hall_of_fame_machine.py
@@ -9,8 +9,36 @@
DB_PATH = 'rustchain.db'
+def init_hall_of_fame_db():
+ """Initialize hall_of_fame table if it doesn't exist"""
+ with sqlite3.connect(DB_PATH) as conn:
+ cursor = conn.cursor()
+ cursor.execute('''
+ CREATE TABLE IF NOT EXISTS hall_of_fame (
+ fingerprint_hash TEXT PRIMARY KEY,
+ machine_name TEXT,
+ first_seen TIMESTAMP,
+ total_attestations INTEGER DEFAULT 0,
+ rust_score INTEGER DEFAULT 0,
+ fleet_rank INTEGER
+ )
+ ''')
+ cursor.execute('''
+ CREATE TABLE IF NOT EXISTS attestations (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ fingerprint_hash TEXT,
+ epoch INTEGER,
+ rust_score INTEGER,
+ timestamp TIMESTAMP,
+ FOREIGN KEY (fingerprint_hash) REFERENCES hall_of_fame(fingerprint_hash)
+ )
+ ''')
+ conn.commit()
+
def get_machine_details(fingerprint_hash):
"""Get detailed machine information"""
+ init_hall_of_fame_db() # Ensure tables exist
+
with sqlite3.connect(DB_PATH) as conn:
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
@@ -66,60 +94,81 @@ def machine_detail_page():
fleet_stats = machine_data['fleet_stats']
# Calculate performance metrics
- avg_score = fleet_stats['avg_score'] or 0
- performance_vs_fleet = (machine['rust_score'] - avg_score) / avg_score * 100 if avg_score > 0 else 0
+ avg_score = sum(h['rust_score'] for h in history) / len(history) if history else 0
html_template = '''
-
Machine Profile - {{ machine.machine_name }}
+
Machine Details - {{ machine.machine_name }}
-
-
-
-
-
Rust Score
-
{{ machine.rust_score }}
-
{{ "+%.1f" % performance_vs_fleet if performance_vs_fleet >= 0 else "%.1f" % performance_vs_fleet }}% vs fleet avg
-
-
-
Total Attestations
-
{{ machine.total_attestations }}
-
Since {{ machine.first_seen }}
+
← Back to Hall of Fame
+
+
+
{{ machine.machine_name or 'Machine-' + machine.fingerprint_hash[:8] }}
+
Fingerprint: {{ machine.fingerprint_hash }}
+
First Seen: {{ machine.first_seen }}
+
+
+
+ Current Rust Score: {{ machine.rust_score }}
+
+
+ Fleet Rank: #{{ machine.fleet_rank }}
+
+
+ Total Attestations: {{ machine.total_attestations }}
+
-
+ {% if history %}
+
Recent Attestation History
- {% for att in history %}
-
- Epoch {{ att.epoch }}
- Score: {{ att.rust_score }}
- {{ att.timestamp }}
-
- {% endfor %}
+
+
+
+ | Epoch |
+ Rust Score |
+ Timestamp |
+
+
+
+ {% for attestation in history %}
+
+ | {{ attestation.epoch }} |
+ {{ attestation.rust_score }} |
+ {{ attestation.timestamp }} |
+
+ {% endfor %}
+
+
+ {% endif %}
-
← Back to Hall of Fame
+
+
Fleet Comparison
+
Fleet Average Score: {{ "%.1f"|format(fleet_stats.avg_score or 0) }}
+
Total Fleet Machines: {{ fleet_stats.total_machines }}
+
'''
- return render_template_string(html_template, machine=machine, history=history, performance_vs_fleet=performance_vs_fleet)
+ return render_template_string(html_template,
+ machine=machine,
+ history=history,
+ fleet_stats=fleet_stats)
if __name__ == '__main__':
app.run(debug=True)
From 14ce639c38cb66818e9f1f5c94a546f8181df93c Mon Sep 17 00:00:00 2001
From: LaphoqueRC <91871936+LaphoqueRC@users.noreply.github.com>
Date: Fri, 20 Mar 2026 16:13:19 +0300
Subject: [PATCH 8/8] fix: address review feedback on
tests/test_hall_of_fame_machine.py
---
tests/test_hall_of_fame_machine.py | 104 +++++++++++++++++------------
1 file changed, 60 insertions(+), 44 deletions(-)
diff --git a/tests/test_hall_of_fame_machine.py b/tests/test_hall_of_fame_machine.py
index 6d1722e4..ac1fcf04 100644
--- a/tests/test_hall_of_fame_machine.py
+++ b/tests/test_hall_of_fame_machine.py
@@ -10,58 +10,83 @@
# Add the parent directory to the path to import the app
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-from hall_of_fame_machine import app
+from hall_of_fame_machine import app, DB_PATH
class TestHallOfFameMachine(unittest.TestCase):
def setUp(self):
"""Set up test database and Flask test client."""
- self.db_fd, self.db_path = tempfile.mkstemp()
+ self.db_fd, self.test_db_path = tempfile.mkstemp()
app.config['TESTING'] = True
- app.config['DATABASE'] = self.db_path
self.client = app.test_client()
+ # Mock the DB_PATH to use our test database
+ self.original_db_path = DB_PATH
+ import hall_of_fame_machine
+ hall_of_fame_machine.DB_PATH = self.test_db_path
+
# Create test database with sample data
- with sqlite3.connect(self.db_path) as conn:
+ with sqlite3.connect(self.test_db_path) as conn:
cursor = conn.cursor()
- # Create machines table
+ # Create hall_of_fame table
cursor.execute('''
- CREATE TABLE machines (
+ CREATE TABLE hall_of_fame (
fingerprint_hash TEXT PRIMARY KEY,
- name TEXT,
+ machine_name TEXT,
+ first_seen TIMESTAMP,
+ total_attestations INTEGER DEFAULT 0,
+ rust_score INTEGER DEFAULT 0,
+ fleet_rank INTEGER
+ )
+ ''')
+
+ # Create attestations table
+ cursor.execute('''
+ CREATE TABLE attestations (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ fingerprint_hash TEXT,
+ epoch INTEGER,
rust_score INTEGER,
- epochs_participated INTEGER,
- first_attestation TIMESTAMP,
- last_seen TIMESTAMP,
- status TEXT,
- operator_email TEXT
+ timestamp TIMESTAMP,
+ FOREIGN KEY (fingerprint_hash) REFERENCES hall_of_fame(fingerprint_hash)
)
''')
# Insert test data
cursor.execute('''
- INSERT INTO machines VALUES
- ('abc123def456', 'Mining Rig Alpha', 8750, 142,
- '2024-01-15 10:30:00', '2024-03-10 14:22:00', 'active', 'operator@example.com'),
- ('def789ghi012', 'Beta Node', 7200, 98,
- '2024-02-01 09:15:00', '2024-02-28 16:45:00', 'deceased', 'beta@test.com'),
- ('ghi345jkl678', 'Gamma Processor', 9100, 201,
- '2023-12-01 08:00:00', '2024-03-11 11:30:00', 'active', 'gamma@node.org')
+ INSERT INTO hall_of_fame VALUES
+ ('abc123def456', 'Mining Rig Alpha', '2024-01-15 10:30:00', 142, 8750, 1),
+ ('def789ghi012', 'Beta Node', '2024-02-01 09:15:00', 98, 7200, 2),
+ ('ghi345jkl678', 'Gamma Processor', '2023-12-01 08:00:00', 201, 9100, 3)
+ ''')
+
+ # Insert attestation data
+ cursor.execute('''
+ INSERT INTO attestations (fingerprint_hash, epoch, rust_score, timestamp) VALUES
+ ('abc123def456', 1001, 8750, '2024-03-10 14:22:00'),
+ ('abc123def456', 1000, 8600, '2024-03-09 14:22:00'),
+ ('def789ghi012', 999, 7200, '2024-02-28 16:45:00')
''')
conn.commit()
def tearDown(self):
"""Clean up test database."""
+ # Restore original DB_PATH
+ import hall_of_fame_machine
+ hall_of_fame_machine.DB_PATH = self.original_db_path
+
os.close(self.db_fd)
- os.unlink(self.db_path)
+ os.unlink(self.test_db_path)
- def test_machine_detail_page_missing_id(self):
- """Test machine detail page without machine ID."""
- response = self.client.get('/hall-of-fame/machine')
- self.assertEqual(response.status_code, 400)
- self.assertIn(b'Machine ID required', response.data)
+ def test_machine_detail_page_success(self):
+ """Test machine detail page for existing machine."""
+ response = self.client.get('/hall-of-fame/machine?id=abc123def456')
+ self.assertEqual(response.status_code, 200)
+ self.assertIn(b'Mining Rig Alpha', response.data)
+ self.assertIn(b'abc123def456', response.data)
+ self.assertIn(b'8750', response.data) # rust score
def test_machine_detail_page_nonexistent(self):
"""Test machine detail page for nonexistent machine."""
@@ -69,28 +94,19 @@ def test_machine_detail_page_nonexistent(self):
self.assertEqual(response.status_code, 404)
self.assertIn(b'Machine not found', response.data)
- @patch('hall_of_fame_machine.get_machine_details')
- def test_machine_detail_page_success(self, mock_get_details):
- """Test successful machine detail page rendering."""
- mock_get_details.return_value = {
- 'machine': {
- 'fingerprint_hash': 'abc123def456',
- 'machine_name': 'Test Machine',
- 'first_seen': '2024-01-01',
- 'total_attestations': 100,
- 'rust_score': 8500,
- 'fleet_rank': 5
- },
- 'attestation_history': [
- {'epoch': 1000, 'rust_score': 8500, 'timestamp': '2024-03-01 12:00:00'}
- ],
- 'fleet_stats': {'avg_score': 8000, 'total_machines': 50}
- }
+ def test_machine_detail_page_no_id(self):
+ """Test machine detail page without machine ID."""
+ response = self.client.get('/hall-of-fame/machine')
+ self.assertEqual(response.status_code, 400)
+ self.assertIn(b'Machine ID required', response.data)
+ def test_machine_detail_page_with_history(self):
+ """Test machine detail page includes attestation history."""
response = self.client.get('/hall-of-fame/machine?id=abc123def456')
self.assertEqual(response.status_code, 200)
- self.assertIn(b'Test Machine', response.data)
- self.assertIn(b'abc123def456', response.data)
+ self.assertIn(b'Recent Attestation History', response.data)
+ self.assertIn(b'1001', response.data) # epoch
+ self.assertIn(b'1000', response.data) # previous epoch
if __name__ == '__main__':
unittest.main()