/ tests / utils / image-optimizer.test.js
image-optimizer.test.js
 1  /**
 2   * Tests for src/utils/image-optimizer.js
 3   *
 4   * Tests the pure calculateSavings() function.
 5   * optimizeScreenshot/optimizeScreenshots require sharp image processing with
 6   * real image buffers — not tested here (covered by integration tests).
 7   */
 8  
 9  import { test, describe } from 'node:test';
10  import assert from 'node:assert/strict';
11  
12  import { calculateSavings } from '../../src/utils/image-optimizer.js';
13  
14  // ─── calculateSavings ─────────────────────────────────────────────────────────
15  
16  describe('calculateSavings', () => {
17    test('calculates savings when all three screenshot types are present', () => {
18      const original = {
19        desktop_above: Buffer.alloc(100 * 1024), // 100 KB
20        desktop_below: Buffer.alloc(80 * 1024), // 80 KB
21        mobile_above: Buffer.alloc(50 * 1024), // 50 KB
22      };
23      const optimized = {
24        desktop_above: Buffer.alloc(60 * 1024), // 60 KB
25        desktop_below: Buffer.alloc(50 * 1024), // 50 KB
26        mobile_above: Buffer.alloc(30 * 1024), // 30 KB
27      };
28  
29      const result = calculateSavings(original, optimized);
30      assert.equal(result.originalKB, 230); // 100+80+50 = 230 KB
31      assert.equal(result.optimizedKB, 140); // 60+50+30 = 140 KB
32      assert.equal(result.savingsKB, 90); // 230-140 = 90 KB
33      assert.ok(result.savingsPercent > 0 && result.savingsPercent <= 100);
34    });
35  
36    test('returns correct savings percentage', () => {
37      const original = { desktop_above: Buffer.alloc(200) };
38      const optimized = { desktop_above: Buffer.alloc(100) };
39  
40      const result = calculateSavings(original, optimized);
41      assert.equal(result.savingsPercent, 50); // 50% savings
42    });
43  
44    test('handles missing screenshot types gracefully', () => {
45      const original = { desktop_above: Buffer.alloc(50 * 1024) };
46      const optimized = { desktop_above: Buffer.alloc(25 * 1024) };
47  
48      // desktop_below and mobile_above are missing — should not throw
49      const result = calculateSavings(original, optimized);
50      assert.ok(result.savingsPercent >= 0);
51    });
52  
53    test('returns KB values rounded to integers', () => {
54      const original = { desktop_above: Buffer.alloc(1500) }; // ~1.46 KB
55      const optimized = { desktop_above: Buffer.alloc(1000) }; // ~0.98 KB
56  
57      const result = calculateSavings(original, optimized);
58      assert.equal(typeof result.originalKB, 'number');
59      assert.equal(typeof result.optimizedKB, 'number');
60      assert.equal(typeof result.savingsKB, 'number');
61      assert.equal(typeof result.savingsPercent, 'number');
62      // Check they are integers (Math.round)
63      assert.equal(result.originalKB, Math.round(result.originalKB));
64    });
65  
66    test('handles empty objects', () => {
67      const result = calculateSavings({}, {});
68      assert.equal(result.originalKB, 0);
69      assert.equal(result.optimizedKB, 0);
70      assert.equal(result.savingsKB, 0);
71      // NaN when original is 0 — check it's a number
72      assert.equal(typeof result.savingsPercent, 'number');
73    });
74  
75    test('calculates correct result when optimized is same size as original', () => {
76      const buf = Buffer.alloc(1024);
77      const result = calculateSavings({ desktop_above: buf }, { desktop_above: buf });
78      assert.equal(result.savingsPercent, 0);
79      assert.equal(result.savingsKB, 0);
80    });
81  });