From 61e34e0fb6c70518d918dbb6a0c8c79b3d94d9dc Mon Sep 17 00:00:00 2001
From: pkupczyk <piotr.kupczyk@id.ethz.ch>
Date: Mon, 17 Aug 2020 23:05:43 +0200
Subject: [PATCH] NG_UI : vocabulary form : SSDM-10060 - extend tests with
 removing a term

---
 .../components/common/grid/GridController.js  |  10 +-
 .../js/components/common/grid/GridPaging.jsx  |   4 +
 .../common/grid/wrapper/GridPagingWrapper.js  |  26 +++++
 .../form/VocabularyFormComponent.test.js      | 107 ++++++++++++++++++
 4 files changed, 145 insertions(+), 2 deletions(-)

diff --git a/openbis_ng_ui/src/js/components/common/grid/GridController.js b/openbis_ng_ui/src/js/components/common/grid/GridController.js
index 77957493c37..834cb7c654d 100644
--- a/openbis_ng_ui/src/js/components/common/grid/GridController.js
+++ b/openbis_ng_ui/src/js/components/common/grid/GridController.js
@@ -154,14 +154,20 @@ export default class GridController {
     } = this.context.getState()
 
     const filteredRows = this._filter(allRows, columns, filters)
+
+    const pageCount = Math.max(Math.ceil(filteredRows.length / pageSize), 1)
+    const newPage = Math.min(page, pageCount - 1)
+
     const sortedRows = this._sort(filteredRows, columns, sort, sortDirection)
-    const currentRows = this._page(sortedRows, page, pageSize)
+    const currentRows = this._page(sortedRows, newPage, pageSize)
 
     await this.context.setState({
       filteredRows,
       sortedRows,
-      currentRows
+      currentRows,
+      page: newPage
     })
+
     if (selectedRowId) {
       await this._recalculateSelectedRow()
     }
diff --git a/openbis_ng_ui/src/js/components/common/grid/GridPaging.jsx b/openbis_ng_ui/src/js/components/common/grid/GridPaging.jsx
index ef64775218e..ced6b40187e 100644
--- a/openbis_ng_ui/src/js/components/common/grid/GridPaging.jsx
+++ b/openbis_ng_ui/src/js/components/common/grid/GridPaging.jsx
@@ -106,6 +106,7 @@ class GridPaging extends React.PureComponent {
             onClick={this.handleFirstPageButtonClick}
             disabled={page === 0}
             aria-label='First Page'
+            data-part='firstPage'
           >
             <FirstPageIcon fontSize='small' />
           </IconButton>
@@ -113,6 +114,7 @@ class GridPaging extends React.PureComponent {
             onClick={this.handleBackButtonClick}
             disabled={page === 0}
             aria-label='Previous Page'
+            data-part='prevPage'
           >
             <KeyboardArrowLeft fontSize='small' />
           </IconButton>
@@ -120,6 +122,7 @@ class GridPaging extends React.PureComponent {
             onClick={this.handleNextButtonClick}
             disabled={page >= Math.ceil(count / pageSize) - 1}
             aria-label='Next Page'
+            data-part='nextPage'
           >
             <KeyboardArrowRight fontSize='small' />
           </IconButton>
@@ -127,6 +130,7 @@ class GridPaging extends React.PureComponent {
             onClick={this.handleLastPageButtonClick}
             disabled={page >= Math.ceil(count / pageSize) - 1}
             aria-label='Last Page'
+            data-part='lastPage'
           >
             <LastPageIcon fontSize='small' />
           </IconButton>
diff --git a/openbis_ng_ui/srcTest/js/components/common/grid/wrapper/GridPagingWrapper.js b/openbis_ng_ui/srcTest/js/components/common/grid/wrapper/GridPagingWrapper.js
index 7877a738b58..d208c05bb9d 100644
--- a/openbis_ng_ui/srcTest/js/components/common/grid/wrapper/GridPagingWrapper.js
+++ b/openbis_ng_ui/srcTest/js/components/common/grid/wrapper/GridPagingWrapper.js
@@ -1,13 +1,39 @@
 import BaseWrapper from '@srcTest/js/components/common/wrapper/BaseWrapper.js'
 import SelectField from '@src/js/components/common/form/SelectField.jsx'
 import SelectFieldWrapper from '@srcTest/js/components/common/form/wrapper/SelectFieldWrapper.js'
+import IconWrapper from '@srcTest/js/components/common/form/wrapper/IconWrapper.js'
 import Typography from '@material-ui/core/Typography'
+import IconButton from '@material-ui/core/IconButton'
 
 export default class GridPagingWrapper extends BaseWrapper {
   getPageSize() {
     return new SelectFieldWrapper(this.findComponent(SelectField))
   }
 
+  getPrevPage() {
+    return new IconWrapper(
+      this.findComponent(IconButton).filter({ 'data-part': 'prevPage' })
+    )
+  }
+
+  getNextPage() {
+    return new IconWrapper(
+      this.findComponent(IconButton).filter({ 'data-part': 'nextPage' })
+    )
+  }
+
+  getFirstPage() {
+    return new IconWrapper(
+      this.findComponent(IconButton).filter({ 'data-part': 'firstPage' })
+    )
+  }
+
+  getLastPage() {
+    return new IconWrapper(
+      this.findComponent(IconButton).filter({ 'data-part': 'lastPage' })
+    )
+  }
+
   getRange() {
     return this.getStringValue(
       this.findComponent(Typography)
diff --git a/openbis_ng_ui/srcTest/js/components/types/form/VocabularyFormComponent.test.js b/openbis_ng_ui/srcTest/js/components/types/form/VocabularyFormComponent.test.js
index 68d5c03ae0f..e7036d66f06 100644
--- a/openbis_ng_ui/srcTest/js/components/types/form/VocabularyFormComponent.test.js
+++ b/openbis_ng_ui/srcTest/js/components/types/form/VocabularyFormComponent.test.js
@@ -29,6 +29,7 @@ describe('VocabularyFormComponent', () => {
   test('load existing', testLoadExisting)
   test('select term', testSelectTerm)
   test('add term', testAddTerm)
+  test('remove term', testRemoveTerm)
 })
 
 async function testLoadNew() {
@@ -131,6 +132,7 @@ async function testLoadExisting() {
     grid: gridJSON,
     parameters: {
       vocabulary: {
+        title: 'Vocabulary',
         code: {
           label: 'Code',
           value: fixture.TEST_VOCABULARY_DTO.getCode(),
@@ -377,6 +379,111 @@ async function testAddTerm() {
   })
 }
 
+async function testRemoveTerm() {
+  const form = await mountExisting()
+
+  form.getGrid().getPaging().getPageSize().change(5)
+  form.getGrid().getPaging().getNextPage().click()
+  await form.update()
+
+  form.getGrid().getRows()[0].click()
+  await form.update()
+
+  form.expectJSON({
+    grid: {
+      rows: [fixture.TEST_TERM_6_DTO].map(term => ({
+        values: {
+          'code.value': term.getCode(),
+          'label.value': term.getLabel(),
+          'description.value': term.getDescription(),
+          'official.value': String(term.isOfficial())
+        },
+        selected: true
+      })),
+      paging: {
+        pageSize: {
+          value: 5
+        },
+        range: '6-6 of 6'
+      }
+    }
+  })
+
+  form.getButtons().getEdit().click()
+  await form.update()
+
+  form.getButtons().getRemoveTerm().click()
+  await form.update()
+
+  form.expectJSON({
+    grid: {
+      rows: [
+        fixture.TEST_TERM_1_DTO,
+        fixture.TEST_TERM_2_DTO,
+        fixture.TEST_TERM_3_DTO,
+        fixture.TEST_TERM_4_DTO,
+        fixture.TEST_TERM_5_DTO
+      ].map(term => ({
+        values: {
+          'code.value': term.getCode(),
+          'label.value': term.getLabel(),
+          'description.value': term.getDescription(),
+          'official.value': String(term.isOfficial())
+        },
+        selected: false
+      })),
+      paging: {
+        pageSize: {
+          value: 5
+        },
+        range: '1-5 of 5'
+      }
+    },
+    parameters: {
+      vocabulary: {
+        title: 'Vocabulary',
+        code: {
+          label: 'Code',
+          value: fixture.TEST_VOCABULARY_DTO.getCode(),
+          enabled: false,
+          mode: 'edit'
+        },
+        description: {
+          label: 'Description',
+          value: fixture.TEST_VOCABULARY_DTO.getDescription(),
+          enabled: true,
+          mode: 'edit'
+        },
+        urlTemplate: {
+          label: 'URL template',
+          value: fixture.TEST_VOCABULARY_DTO.getUrlTemplate(),
+          enabled: true,
+          mode: 'edit'
+        }
+      }
+    },
+    buttons: {
+      addTerm: {
+        enabled: true
+      },
+      removeTerm: {
+        enabled: false
+      },
+      save: {
+        enabled: true
+      },
+      cancel: {
+        enabled: true
+      },
+      edit: null,
+      message: {
+        text: 'You have unsaved changes.',
+        type: 'warning'
+      }
+    }
+  })
+}
+
 async function mountNew() {
   return await common.mount({
     type: objectTypes.NEW_VOCABULARY_TYPE
-- 
GitLab