From 6eacfec4ecba00fa0db0342849c6a994db562b81 Mon Sep 17 00:00:00 2001
From: Matt Westcott <matt@west.co.tt>
Date: Fri, 7 Jun 2024 19:22:06 +0100
Subject: [PATCH] Add tests for showing / hiding errors on per-block-type
 min_num

---
 .../StreamField/blocks/StreamBlock.test.js    | 127 ++++++++++++++++++
 1 file changed, 127 insertions(+)

diff --git a/client/src/components/StreamField/blocks/StreamBlock.test.js b/client/src/components/StreamField/blocks/StreamBlock.test.js
index 062f2a751e..eb7bfdc33d 100644
--- a/client/src/components/StreamField/blocks/StreamBlock.test.js
+++ b/client/src/components/StreamField/blocks/StreamBlock.test.js
@@ -1105,6 +1105,133 @@ describe('telepath: wagtail.blocks.StreamBlock with blockCounts.max_num set', ()
   });
 });
 
+describe('telepath: wagtail.blocks.StreamBlock with blockCounts.min_num set', () => {
+  // Define a test block
+  const blockDef = new StreamBlockDefinition(
+    '',
+    [
+      [
+        '',
+        [
+          new FieldBlockDefinition(
+            'test_block_a',
+            new DummyWidgetDefinition('Block A widget'),
+            {
+              label: 'Test Block <A>',
+              required: true,
+              icon: 'placeholder',
+              classname: 'w-field w-field--char_field w-field--text_input',
+            },
+          ),
+          new FieldBlockDefinition(
+            'test_block_b',
+            new DummyWidgetDefinition('Block B widget'),
+            {
+              label: 'Test Block <B>',
+              required: true,
+              icon: 'pilcrow',
+              classname:
+                'w-field w-field--char_field w-field--admin_auto_height_text_input',
+            },
+          ),
+        ],
+      ],
+    ],
+    {
+      test_block_a: 'Block A options',
+      test_block_b: 'Block B options',
+    },
+    {
+      label: '',
+      required: true,
+      icon: 'placeholder',
+      classname: null,
+      helpText: 'use <strong>plenty</strong> of these',
+      helpIcon: '<svg></svg>',
+      maxNum: null,
+      minNum: null,
+      blockCounts: {
+        test_block_a: {
+          min_num: 2,
+        },
+      },
+      strings: {
+        MOVE_UP: 'Move up',
+        MOVE_DOWN: 'Move down',
+        DELETE: 'Delete & kill with fire',
+        DUPLICATE: 'Duplicate',
+        ADD: 'Add',
+      },
+    },
+  );
+
+  const assertShowingErrorMessage = () => {
+    expect(document.querySelector('p.help-block.help-critical').innerHTML).toBe(
+      'Test Block &lt;A&gt;: The minimum number of items is 2',
+    );
+  };
+
+  const assertNotShowingErrorMessage = () => {
+    expect(document.querySelector('p.help-block.help-critical')).toBe(null);
+  };
+
+  test('inserting block to get count above min_num removes error mesage', () => {
+    document.body.innerHTML = '<div id="placeholder"></div>';
+    const boundBlock = blockDef.render($('#placeholder'), 'the-prefix', [
+      {
+        id: '1',
+        type: 'test_block_a',
+        value: 'First value',
+      },
+      {
+        id: '2',
+        type: 'test_block_b',
+        value: 'Second value',
+      },
+    ]);
+
+    assertShowingErrorMessage();
+
+    boundBlock.insert(
+      {
+        id: '3',
+        type: 'test_block_a',
+        value: 'Third value',
+      },
+      2,
+    );
+
+    assertNotShowingErrorMessage();
+  });
+
+  test('deleting block to get count below min_num shows error message', () => {
+    document.body.innerHTML = '<div id="placeholder"></div>';
+    const boundBlock = blockDef.render($('#placeholder'), 'the-prefix', [
+      {
+        id: '1',
+        type: 'test_block_a',
+        value: 'First value',
+      },
+      {
+        id: '2',
+        type: 'test_block_b',
+        value: 'Second value',
+      },
+      {
+        id: '3',
+        type: 'test_block_a',
+        value: 'Third value',
+      },
+    ]);
+
+    assertNotShowingErrorMessage();
+
+    boundBlock.deleteBlock(2);
+
+    assertShowingErrorMessage();
+  });
+});
+
 describe('telepath: wagtail.blocks.StreamBlock with unique block type', () => {
   let boundBlock;