diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml
index 38edc63d..5d00dbcc 100644
--- a/.github/workflows/run-tests.yml
+++ b/.github/workflows/run-tests.yml
@@ -46,7 +46,7 @@ jobs:
-Dsonar.projectKey=TykTechnologies_tyk-ui
-Dsonar.sources=./src
-Dsonar.coverage.exclusions=cypress/**/*.js,**/*.test.js,src/form/components/Combobox/*.js,src/form/redux-form/**/*.js
- -Dsonar.cpd.exclusions=**/*.test.js,src/form/redux-form/**/*,src/common/fonts
+ -Dsonar.cpd.exclusions=**/*.test.js,src/form/redux-form/**/*,src/common/fonts/**/*
-Dsonar.test.inclusions=**/*.test.js
-Dsonar.tests=./src
-Dsonar.javascript.lcov.reportPaths=coverage/lcov.info
diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml
index ae1c83e6..2deaf476 100644
--- a/.github/workflows/sonarcloud.yml
+++ b/.github/workflows/sonarcloud.yml
@@ -24,7 +24,7 @@ jobs:
-Dsonar.projectKey=TykTechnologies_tyk-ui
-Dsonar.sources=./src
-Dsonar.coverage.exclusions=cypress/**/*.js,**/*.test.js,src/form/components/Combobox/*.js,src/form/redux-form/**/*.js
- -Dsonar.cpd.exclusions=**/*.test.js,src/form/redux-form/**/*,src/common/fonts
+ -Dsonar.cpd.exclusions=**/*.test.js,src/form/redux-form/**/*,src/common/fonts/**/*
-Dsonar.test.inclusions=**/*.test.js
-Dsonar.tests=./src
-Dsonar.javascript.lcov.reportPaths=coverage/lcov.info
diff --git a/src/form/components/SelectableList/SelectableList.test.js b/src/form/components/SelectableList/SelectableList.test.js
index 1bb6b854..9cbacafd 100644
--- a/src/form/components/SelectableList/SelectableList.test.js
+++ b/src/form/components/SelectableList/SelectableList.test.js
@@ -1,7 +1,107 @@
+import React from 'react';
import SelectableList from './index';
+// eslint-disable-next-line react/prop-types
+function Component(props) {
+ return (
+
+ );
+}
+
+const items = [
+ { name: 'Item one', id: '1' },
+ { name: 'Item two', id: '2' },
+ { name: 'Item three', id: '3' },
+];
+
+const selectors = {
+ component: '.tyk-selectable-list',
+ message: '.tyk-message',
+ item: '.tyk-selectable-list li',
+ icon: '.tyk-icon',
+};
+
describe('SelectableList', () => {
- it('TODO', () => {
- expect(true).to.equal(true);
+ it('renders the component with the default "no items" message', () => {
+ cy.mount()
+ .get(selectors.component)
+ .should('exist')
+ .get(selectors.message)
+ .should('exist')
+ .and('have.text', 'No items in the list');
+ });
+
+ it('the "no items" message can be customized', () => {
+ const message = 'another message';
+ cy.mount()
+ .get(selectors.message)
+ .should('have.text', message);
+ });
+
+ it('renders the component with items', () => {
+ cy.mount()
+ .get(selectors.item)
+ .should('have.length', items.length);
+ });
+
+ it('you can specify what to be rendered for an item using itemTemplate', () => {
+ cy.mount( item.id} />)
+ .get(selectors.item)
+ .eq(0)
+ .should('have.text', items[0].id);
+ });
+
+ it('you can specify a value', () => {
+ cy.mount()
+ .get(selectors.item)
+ .eq(0)
+ .find('input')
+ .should('be.checked')
+ .get(selectors.item)
+ .eq(1)
+ .find('input')
+ .should('not.be.checked')
+ .get(selectors.item)
+ .eq(2)
+ .find('input')
+ .should('be.checked');
+ });
+
+ it('calls the onChange callback when the value changes', () => {
+ const onChange = cy.stub().as('onChange');
+ cy.mount()
+ .get(selectors.item)
+ .eq(1)
+ .find('input')
+ .check();
+ cy.get('@onChange')
+ .should('be.called');
+ });
+
+ it('can specify another property of the item as the identifier', () => {
+ const onChange = cy.stub().as('onChange');
+ cy.mount()
+ .get(selectors.item)
+ .eq(1)
+ .find('input')
+ .check();
+ cy.get('@onChange')
+ .should('be.calledWith', [items[1].name]);
+ });
+
+ it('can have a custom css class', () => {
+ const wrapperClassName = 'selectable-list-1';
+ cy.mount()
+ .get(selectors.component)
+ .should('have.class', wrapperClassName);
+ });
+
+ it('can display an icon instead of the checkbox', () => {
+ cy.mount()
+ .get(selectors.icon)
+ .should('exist')
+ .get(selectors.item)
+ .find('input')
+ .should('not.be.visible');
});
});
diff --git a/src/form/components/SelectableList/index.js b/src/form/components/SelectableList/index.js
index 36030cb0..b540f1f6 100644
--- a/src/form/components/SelectableList/index.js
+++ b/src/form/components/SelectableList/index.js
@@ -1,18 +1,17 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { fromJS } from 'immutable';
import Message from '../../../components/Message';
import List from '../../../components/List';
import Icon from '../../../components/Icon';
-const SelectableList = (props) => {
+function SelectableList(props) {
const {
checkboxalticon,
items,
itemTemplate,
value,
- noItemsMessage,
+ noItemsMessage = 'No items in the list',
onChange,
theme,
primaryKey,
@@ -20,9 +19,9 @@ const SelectableList = (props) => {
} = props;
const handleOnSelect = (event) => {
- const newSelectedItems = fromJS(value).toJS();
+ const newSelectedItems = structuredClone(value);
const elemPosition = newSelectedItems.findIndex(
- id => JSON.stringify(id) === JSON.stringify(
+ (id) => JSON.stringify(id) === JSON.stringify(
Array.isArray(id)
? event.target.value.split(',')
: event.target.value,
@@ -58,7 +57,7 @@ const SelectableList = (props) => {
};
const isChecked = (inputValue, itemValue) => Boolean(
- inputValue.find(tvalue => JSON.stringify(itemValue) === JSON.stringify(tvalue)),
+ inputValue.find((tvalue) => JSON.stringify(itemValue) === JSON.stringify(tvalue)),
);
return (
@@ -68,7 +67,7 @@ const SelectableList = (props) => {
? (
- {noItemsMessage || 'No items in the list'}
+ {noItemsMessage}
)
@@ -100,7 +99,7 @@ const SelectableList = (props) => {
}
);
-};
+}
SelectableList.propTypes = {
items: PropTypes.instanceOf(Array),
diff --git a/src/form/components/Textarea/Textarea.test.js b/src/form/components/Textarea/Textarea.test.js
index 580fc41d..4d719272 100644
--- a/src/form/components/Textarea/Textarea.test.js
+++ b/src/form/components/Textarea/Textarea.test.js
@@ -104,8 +104,8 @@ describe('Textarea', () => {
const onChange = cy.stub().as('onChange');
cy.mount()
.get(selectors.textarea)
- .type('something')
- .get('@onChange')
+ .type('something');
+ cy.get('@onChange')
.should('be.called');
});