Просмотр исходного кода

test(stats): update StatsPage tests to match current widget structure

Enrich mock archives with full fields, fix failure analysis endpoint,
remove outdated Filament Types test, and add coverage for new widgets
(Records, Printer Stats sub-cards, Filament Trends sub-cards).
AneoPsy 6 месяцев назад
Родитель
Сommit
1a7bdf2b18
1 измененных файлов с 201 добавлено и 11 удалено
  1. 201 11
      frontend/src/__tests__/pages/StatsPage.test.tsx

+ 201 - 11
frontend/src/__tests__/pages/StatsPage.test.tsx

@@ -41,8 +41,70 @@ const mockPrinters = [
 ];
 
 const mockArchives = [
-  { id: 1, created_at: '2024-01-01T00:00:00Z', print_name: 'Test Print 1' },
-  { id: 2, created_at: '2024-01-02T00:00:00Z', print_name: 'Test Print 2' },
+  {
+    id: 1,
+    created_at: '2024-01-01T10:00:00Z',
+    started_at: '2024-01-01T10:00:00Z',
+    completed_at: '2024-01-01T14:30:00Z',
+    print_name: 'Benchy',
+    status: 'completed',
+    printer_id: 1,
+    filament_type: 'PLA',
+    filament_color: '#00FF00',
+    filament_used_grams: 25,
+    actual_time_seconds: 16200,
+    print_time_seconds: 15000,
+    cost: 0.75,
+    quantity: 1,
+  },
+  {
+    id: 2,
+    created_at: '2024-01-02T14:00:00Z',
+    started_at: '2024-01-02T14:00:00Z',
+    completed_at: '2024-01-02T22:00:00Z',
+    print_name: 'Large Vase',
+    status: 'completed',
+    printer_id: 1,
+    filament_type: 'PETG',
+    filament_color: '#FF0000',
+    filament_used_grams: 180,
+    actual_time_seconds: 28800,
+    print_time_seconds: 27000,
+    cost: 5.40,
+    quantity: 1,
+  },
+  {
+    id: 3,
+    created_at: '2024-01-03T08:00:00Z',
+    started_at: '2024-01-03T08:00:00Z',
+    completed_at: null,
+    print_name: 'Failed Bracket',
+    status: 'failed',
+    printer_id: 2,
+    filament_type: 'ABS',
+    filament_color: '#0000FF',
+    filament_used_grams: 10,
+    actual_time_seconds: 3600,
+    print_time_seconds: 7200,
+    cost: 0.30,
+    quantity: 1,
+  },
+  {
+    id: 4,
+    created_at: '2024-01-03T20:00:00Z',
+    started_at: '2024-01-03T20:00:00Z',
+    completed_at: '2024-01-04T02:00:00Z',
+    print_name: 'Phone Stand',
+    status: 'completed',
+    printer_id: 2,
+    filament_type: 'PLA',
+    filament_color: '#00FF00',
+    filament_used_grams: 45,
+    actual_time_seconds: 21600,
+    print_time_seconds: 20000,
+    cost: 1.35,
+    quantity: 1,
+  },
 ];
 
 const mockSettings = {
@@ -60,6 +122,16 @@ const mockFailureAnalysis = {
     'First layer adhesion': 3,
     'Filament runout': 2,
   },
+  failures_by_filament: {
+    'ABS': 3,
+    'PLA': 2,
+  },
+  failures_by_printer: {
+    '1': 2,
+    '2': 3,
+  },
+  failures_by_hour: {},
+  recent_failures: [],
   trend: [
     { week: '2024-W01', failure_rate: 6.0 },
     { week: '2024-W02', failure_rate: 5.0 },
@@ -81,7 +153,7 @@ describe('StatsPage', () => {
       http.get('/api/v1/settings/', () => {
         return HttpResponse.json(mockSettings);
       }),
-      http.get('/api/v1/stats/failure-analysis', () => {
+      http.get('/api/v1/archives/analysis/failures', () => {
         return HttpResponse.json(mockFailureAnalysis);
       })
     );
@@ -127,7 +199,7 @@ describe('StatsPage', () => {
 
       await waitFor(() => {
         expect(screen.getByText('Filament Used')).toBeInTheDocument();
-        expect(screen.getByText('5.50kg')).toBeInTheDocument();
+        expect(screen.getByText('5.5kg')).toBeInTheDocument();
       });
     });
   });
@@ -138,7 +210,7 @@ describe('StatsPage', () => {
 
       await waitFor(() => {
         expect(screen.getByText('Success Rate')).toBeInTheDocument();
-        // Success rate should be calculated: 140/150 = 93%
+        // Success rate: 140/(140+10) = 93%
         expect(screen.getByText('93%')).toBeInTheDocument();
       });
     });
@@ -163,27 +235,145 @@ describe('StatsPage', () => {
   });
 
   describe('widgets', () => {
-    it('shows filament types widget', async () => {
+    it('shows time accuracy widget', async () => {
       render(<StatsPage />);
 
       await waitFor(() => {
-        expect(screen.getByText('Filament Types')).toBeInTheDocument();
+        expect(screen.getByText('Time Accuracy')).toBeInTheDocument();
       });
     });
 
-    it('shows time accuracy widget', async () => {
+    it('shows print activity widget', async () => {
       render(<StatsPage />);
 
       await waitFor(() => {
-        expect(screen.getByText('Time Accuracy')).toBeInTheDocument();
+        expect(screen.getByText('Print Activity')).toBeInTheDocument();
       });
     });
 
-    it('shows print activity widget', async () => {
+    it('shows failure analysis widget', async () => {
       render(<StatsPage />);
 
       await waitFor(() => {
-        expect(screen.getByText('Print Activity')).toBeInTheDocument();
+        expect(screen.getByText('Failure Analysis')).toBeInTheDocument();
+      });
+    });
+
+    it('shows printer stats widget', async () => {
+      render(<StatsPage />);
+
+      await waitFor(() => {
+        expect(screen.getByText('Printer Stats')).toBeInTheDocument();
+      });
+    });
+
+    it('shows filament trends widget', async () => {
+      render(<StatsPage />);
+
+      await waitFor(() => {
+        expect(screen.getByText('Filament Trends')).toBeInTheDocument();
+      });
+    });
+
+    it('shows records widget', async () => {
+      render(<StatsPage />);
+
+      await waitFor(() => {
+        expect(screen.getByText('Records')).toBeInTheDocument();
+      });
+    });
+  });
+
+  describe('printer stats sub-cards', () => {
+    it('shows prints by printer section', async () => {
+      render(<StatsPage />);
+
+      await waitFor(() => {
+        expect(screen.getByText('Prints by Printer')).toBeInTheDocument();
+      });
+    });
+
+    it('shows print duration section', async () => {
+      render(<StatsPage />);
+
+      await waitFor(() => {
+        expect(screen.getByText('Print Duration')).toBeInTheDocument();
+      });
+    });
+
+    it('shows print habits section', async () => {
+      render(<StatsPage />);
+
+      await waitFor(() => {
+        expect(screen.getByText('Print Habits')).toBeInTheDocument();
+      });
+    });
+
+    it('shows print time of day section', async () => {
+      render(<StatsPage />);
+
+      await waitFor(() => {
+        expect(screen.getByText('Print Time of Day')).toBeInTheDocument();
+      });
+    });
+  });
+
+  describe('filament trends sub-cards', () => {
+    it('shows by material section', async () => {
+      render(<StatsPage />);
+
+      await waitFor(() => {
+        expect(screen.getByText('By Material')).toBeInTheDocument();
+      });
+    });
+
+    it('shows success by material section', async () => {
+      render(<StatsPage />);
+
+      await waitFor(() => {
+        expect(screen.getByText('Success by Material')).toBeInTheDocument();
+      });
+    });
+
+    it('shows color distribution section', async () => {
+      render(<StatsPage />);
+
+      await waitFor(() => {
+        expect(screen.getByText('Color Distribution')).toBeInTheDocument();
+      });
+    });
+  });
+
+  describe('records widget', () => {
+    it('shows longest print record', async () => {
+      render(<StatsPage />);
+
+      await waitFor(() => {
+        expect(screen.getByText('Longest Print')).toBeInTheDocument();
+      });
+    });
+
+    it('shows heaviest print record', async () => {
+      render(<StatsPage />);
+
+      await waitFor(() => {
+        expect(screen.getByText('Heaviest Print')).toBeInTheDocument();
+      });
+    });
+
+    it('shows most expensive record', async () => {
+      render(<StatsPage />);
+
+      await waitFor(() => {
+        expect(screen.getByText('Most Expensive')).toBeInTheDocument();
+      });
+    });
+
+    it('shows success streak record', async () => {
+      render(<StatsPage />);
+
+      await waitFor(() => {
+        expect(screen.getByText('Success Streak')).toBeInTheDocument();
       });
     });
   });