From d9805a875e0913c1adf663a6cf9a036568c059eb Mon Sep 17 00:00:00 2001
From: pkupczyk <piotr.kupczyk@id.ethz.ch>
Date: Tue, 16 Apr 2019 19:16:19 +0200
Subject: [PATCH] SSDM-7569 NEW openBIS UI - General Template/Infrastructure
 for Forms - Visualisation/Creation/Edit - extract openbis dtos loading to a
 separate file + simplify openbis facade + have separate tabs for each open
 object (hide tabs which are not in focus rather than unmount)

---
 openbis_ng_ui/.babelrc                        |   2 +-
 openbis_ng_ui/package.json                    |   7 +-
 .../src/components/content/Content.jsx        |  12 +-
 .../content/objectType/ObjectType.jsx         |  76 +++++++++---
 openbis_ng_ui/src/services/openbis.js         | 117 +-----------------
 openbis_ng_ui/src/services/openbis/dto.js     |  54 ++++++++
 openbis_ng_ui/src/services/openbis/facade.js  |  70 +++++++++++
 openbis_ng_ui/src/store/sagas/api.js          |   4 +-
 openbis_ng_ui/src/store/sagas/app.js          |   6 +-
 .../src/store/sagas/browser/types.js          |  21 +++-
 .../src/store/sagas/browser/users.js          |  15 ++-
 .../components/browser/browser.test.js        |  12 +-
 openbis_ng_ui/srcTest/store/sagas/app.test.js |   8 +-
 .../srcTest/store/sagas/browser.test.js       |  74 ++++++++---
 14 files changed, 303 insertions(+), 175 deletions(-)
 create mode 100644 openbis_ng_ui/src/services/openbis/dto.js
 create mode 100644 openbis_ng_ui/src/services/openbis/facade.js

diff --git a/openbis_ng_ui/.babelrc b/openbis_ng_ui/.babelrc
index 99c679001f8..ec66626b190 100644
--- a/openbis_ng_ui/.babelrc
+++ b/openbis_ng_ui/.babelrc
@@ -1,4 +1,4 @@
 {
     "presets":["env", "react"],
-    "plugins": ["transform-class-properties"]
+    "plugins": ["transform-class-properties", "transform-object-rest-spread"]
 }
diff --git a/openbis_ng_ui/package.json b/openbis_ng_ui/package.json
index 1846ade5180..29665b215f3 100644
--- a/openbis_ng_ui/package.json
+++ b/openbis_ng_ui/package.json
@@ -27,9 +27,12 @@
     "babel-jest": "^23.6.0",
     "babel-loader": "7.1.4",
     "babel-plugin-transform-class-properties": "6.24.1",
+    "babel-plugin-transform-object-rest-spread": "^6.26.0",
     "babel-preset-env": "1.7.0",
     "babel-preset-react": "6.24.1",
     "css-loader": "1.0.0",
+    "enzyme": "3.9.0",
+    "enzyme-adapter-react-16": "1.12.1",
     "eslint": "4.19.1",
     "eslint-config-standard": "11.0.0",
     "eslint-plugin-import": "2.13.0",
@@ -50,9 +53,7 @@
     "url-loader": "1.1.1",
     "webpack": "4.6.0",
     "webpack-cli": "2.0.14",
-    "webpack-dev-server": "^3.1.14",
-    "enzyme": "3.9.0",
-    "enzyme-adapter-react-16": "1.12.1"
+    "webpack-dev-server": "^3.1.14"
   },
   "scripts": {
     "dev": "webpack-dev-server --hot --config webpack.config.dev.js",
diff --git a/openbis_ng_ui/src/components/content/Content.jsx b/openbis_ng_ui/src/components/content/Content.jsx
index c4c6979d6df..545c24445c8 100644
--- a/openbis_ng_ui/src/components/content/Content.jsx
+++ b/openbis_ng_ui/src/components/content/Content.jsx
@@ -1,3 +1,4 @@
+import _ from 'lodash'
 import React from 'react'
 import ContentTabs from './ContentTabs.jsx'
 import {connect} from 'react-redux'
@@ -50,8 +51,6 @@ class Content extends React.Component {
   render() {
     logger.log(logger.DEBUG, 'Content.render')
 
-    let ObjectContent = this.props.selectedObject ? objectTypeToComponent[this.props.selectedObject.type] : null
-
     return (
       <div>
         <ContentTabs
@@ -59,8 +58,13 @@ class Content extends React.Component {
           selectedObject={this.props.selectedObject}
           objectSelect={this.objectSelect}
           objectClose={this.objectClose} />
-        {ObjectContent &&
-          <ObjectContent objectId={this.props.selectedObject.id} />
+        {
+          this.props.openObjects.map(object => {
+            let ObjectContent = objectTypeToComponent[object.type]
+            return (
+              <ObjectContent key={object.id} objectId={object.id} visible={_.isEqual(object, this.props.selectedObject)} />
+            )
+          })
         }
       </div>
     )
diff --git a/openbis_ng_ui/src/components/content/objectType/ObjectType.jsx b/openbis_ng_ui/src/components/content/objectType/ObjectType.jsx
index 24c2f85bd44..63bf28a4c98 100644
--- a/openbis_ng_ui/src/components/content/objectType/ObjectType.jsx
+++ b/openbis_ng_ui/src/components/content/objectType/ObjectType.jsx
@@ -3,54 +3,90 @@ import React from 'react'
 import TextField from '@material-ui/core/TextField'
 import Checkbox from '@material-ui/core/Checkbox'
 import Button from '@material-ui/core/Button'
+import {withStyles} from '@material-ui/core/styles'
 import logger from '../../../common/logger.js'
-import openbis from '../../../services/openbis.js'
+import {facade, dto} from '../../../services/openbis.js'
 
+const styles = () => ({
+  visible: {
+    display: 'flex'
+  },
+  hidden: {
+    display: 'none'
+  }
+})
 
 class ObjectType extends React.Component {
 
   constructor(props){
     super(props)
     this.state = {
-      description: '',
-      listable: false
+      loaded: false,
     }
+    this.handleSave = this.handleSave.bind(this)
   }
 
   componentDidMount(){
+    facade.getSampleTypes([new dto.EntityTypePermId(this.props.objectId)], new dto.SampleTypeFetchOptions()).then(map => {
+      let objectType = map[this.props.objectId]
+      if(objectType){
+        this.setState(() => {
+          return {
+            loaded: true,
+            fields: {
+              description: objectType.description,
+              listable: objectType.listable
+            }
+          }
+        })
+      }
+    })
   }
 
   handleChange(name){
     return event => {
       let value = _.has(event.target, 'checked') ? event.target.checked : event.target.value
-      this.setState({ [name]: value })
+      this.setState((prevState) => ({
+        ...prevState,
+        fields: {
+          ...prevState.fields,
+          [name]: value
+        }
+      }))
     }
   }
 
+  handleSave(){
+    let {description, listable} = this.state.fields
+    let update = new dto.SampleTypeUpdate()
+    update.setTypeId(new dto.EntityTypePermId(this.props.objectId))
+    update.setDescription(description)
+    update.setListable(listable)
+    facade.updateSampleTypes([update])
+  }
+
   render() {
     logger.log(logger.DEBUG, 'ObjectType.render')
+
+    if(!this.state.loaded){
+      return <div></div>
+    }
+
+    let classes = this.props.classes
+    let { description, listable } = this.state.fields
+
     return (
-      <div>
+      <div className={this.props.visible ? classes.visible : classes.hidden}>
         {this.props.objectId}
         <form>
           <div>
-            <TextField
-              label='Description'
-              value={this.state.description}
-              onChange={this.handleChange('description')}
-            />
+            <TextField label='Description' value={description} onChange={this.handleChange('description')} />
           </div>
           <div>
-            <Checkbox
-              checked={this.state.listable}
-              value='listable'
-              onChange={this.handleChange('listable')}
-            />
+            <Checkbox checked={listable} value='listable' onChange={this.handleChange('listable')} />
           </div>
           <div>
-            <Button variant='contained' color='primary'>
-            Save
-            </Button>
+            <Button variant='contained' color='primary' onClick={this.handleSave}>Save</Button>
           </div>
         </form>
       </div>
@@ -59,4 +95,6 @@ class ObjectType extends React.Component {
 
 }
 
-export default ObjectType
+export default _.flow(
+  withStyles(styles)
+)(ObjectType)
diff --git a/openbis_ng_ui/src/services/openbis.js b/openbis_ng_ui/src/services/openbis.js
index 45d50acee5c..8d1b94b9610 100644
--- a/openbis_ng_ui/src/services/openbis.js
+++ b/openbis_ng_ui/src/services/openbis.js
@@ -1,115 +1,2 @@
-const autoBind = require('auto-bind')
-
-export class Openbis {
-
-  constructor() {
-    autoBind(this)
-  }
-
-  init(){
-    let _this = this
-    return new Promise((resolve, reject) => {
-      /* eslint-disable-next-line no-undef */
-      requirejs(['openbis'], openbis => {
-        _this.v3 = new openbis()
-        resolve()
-      }, error => {
-        reject(error)
-      })
-    })
-  }
-
-  login(user, password) {
-    let v3 = this.v3
-    return new Promise((resolve, reject) => {
-      v3.login(user, password).done(resolve).fail(() => {
-        reject({message: 'Login failed'})
-      })
-    })
-  }
-
-  logout() {
-    let v3 = this.v3
-    return new Promise((resolve, reject) => {
-      v3.logout().done(resolve).fail(reject)
-    })
-  }
-
-  getUsers() {
-    let v3 = this.v3
-    return new Promise((resolve, reject) => {
-      /* eslint-disable-next-line no-undef */
-      requirejs(
-        ['as/dto/person/search/PersonSearchCriteria', 'as/dto/person/fetchoptions/PersonFetchOptions'],
-        (PersonSearchCriteria, PersonFetchOptions) => {
-          v3.searchPersons(new PersonSearchCriteria(), new PersonFetchOptions()).done(resolve).fail(reject)
-        })
-    })
-  }
-
-  getGroups() {
-    let v3 = this.v3
-    return new Promise((resolve, reject) => {
-      /* eslint-disable-next-line no-undef */
-      requirejs(
-        ['as/dto/authorizationgroup/search/AuthorizationGroupSearchCriteria', 'as/dto/authorizationgroup/fetchoptions/AuthorizationGroupFetchOptions'],
-        (AuthorizationGroupSearchCriteria, AuthorizationGroupFetchOptions) => {
-          let fo = new AuthorizationGroupFetchOptions()
-          fo.withUsers()
-          v3.searchAuthorizationGroups(new AuthorizationGroupSearchCriteria(), fo).done(resolve).fail(reject)
-        })
-    })
-  }
-
-  getObjectTypes() {
-    let v3 = this.v3
-    return new Promise((resolve, reject) => {
-      /* eslint-disable-next-line no-undef */
-      requirejs(
-        ['as/dto/sample/search/SampleTypeSearchCriteria', 'as/dto/sample/fetchoptions/SampleTypeFetchOptions'],
-        (SampleTypeSearchCriteria, SampleTypeFetchOptions) => {
-          v3.searchSampleTypes(new SampleTypeSearchCriteria(), new SampleTypeFetchOptions()).done(resolve).fail(reject)
-        })
-    })
-  }
-
-  getCollectionTypes() {
-    let v3 = this.v3
-    return new Promise((resolve, reject) => {
-      /* eslint-disable-next-line no-undef */
-      requirejs(
-        ['as/dto/experiment/search/ExperimentTypeSearchCriteria', 'as/dto/experiment/fetchoptions/ExperimentTypeFetchOptions'],
-        (ExperimentTypeSearchCriteria, ExperimentTypeFetchOptions) => {
-          v3.searchExperimentTypes(new ExperimentTypeSearchCriteria(), new ExperimentTypeFetchOptions()).done(resolve).fail(reject)
-        })
-    })
-  }
-
-  getDataSetTypes() {
-    let v3 = this.v3
-    /* eslint-disable-next-line no-undef */
-    return new Promise((resolve, reject) => {
-      /* eslint-disable-next-line no-undef */
-      requirejs(
-        ['as/dto/dataset/search/DataSetTypeSearchCriteria', 'as/dto/dataset/fetchoptions/DataSetTypeFetchOptions'],
-        (DataSetTypeSearchCriteria, DataSetTypeFetchOptions) => {
-          v3.searchDataSetTypes(new DataSetTypeSearchCriteria(), new DataSetTypeFetchOptions()).done(resolve).fail(reject)
-        })
-    })
-  }
-
-  getMaterialTypes() {
-    let v3 = this.v3
-    return new Promise((resolve, reject) => {
-      /* eslint-disable-next-line no-undef */
-      requirejs(
-        ['as/dto/material/search/MaterialTypeSearchCriteria', 'as/dto/material/fetchoptions/MaterialTypeFetchOptions'],
-        (MaterialTypeSearchCriteria, MaterialTypeFetchOptions) => {
-          v3.searchMaterialTypes(new MaterialTypeSearchCriteria(), new MaterialTypeFetchOptions()).done(resolve).fail(reject)
-        })
-    })
-  }
-
-}
-
-export default new Openbis()
+export * from './openbis/dto.js'
+export * from './openbis/facade.js'
diff --git a/openbis_ng_ui/src/services/openbis/dto.js b/openbis_ng_ui/src/services/openbis/dto.js
new file mode 100644
index 00000000000..5ee496bf9a2
--- /dev/null
+++ b/openbis_ng_ui/src/services/openbis/dto.js
@@ -0,0 +1,54 @@
+const CLASS_FULL_NAMES = [
+  'as/dto/person/search/PersonSearchCriteria',
+  'as/dto/person/fetchoptions/PersonFetchOptions',
+  'as/dto/authorizationgroup/search/AuthorizationGroupSearchCriteria',
+  'as/dto/authorizationgroup/fetchoptions/AuthorizationGroupFetchOptions',
+  'as/dto/entitytype/id/EntityTypePermId',
+  'as/dto/sample/fetchoptions/SampleTypeFetchOptions',
+  'as/dto/sample/update/SampleTypeUpdate',
+  'as/dto/sample/search/SampleTypeSearchCriteria',
+  'as/dto/sample/fetchoptions/SampleTypeFetchOptions',
+  'as/dto/experiment/search/ExperimentTypeSearchCriteria',
+  'as/dto/experiment/fetchoptions/ExperimentTypeFetchOptions',
+  'as/dto/dataset/search/DataSetTypeSearchCriteria',
+  'as/dto/dataset/fetchoptions/DataSetTypeFetchOptions',
+  'as/dto/material/search/MaterialTypeSearchCriteria',
+  'as/dto/material/fetchoptions/MaterialTypeFetchOptions'
+]
+
+class Dto {
+
+  init(){
+    let _this = this
+
+    let load = function(index){
+      return new Promise((resolve, reject) => {
+        if(index < CLASS_FULL_NAMES.length){
+          let classFullName = CLASS_FULL_NAMES[index]
+          let className = classFullName.substring(classFullName.lastIndexOf('/') + 1)
+          /* eslint-disable-next-line no-undef */
+          requirejs([classFullName], clazz => {
+            _this[className] = clazz
+            return load(index + 1).then(resolve, reject)
+          }, error => {
+            reject(error)
+          })
+        }else{
+          resolve()
+        }
+      })
+    }
+
+    return load(0)
+  }
+
+}
+
+const dto = new Dto()
+
+CLASS_FULL_NAMES.forEach(classFullName => {
+  let className = classFullName.substring(classFullName.lastIndexOf('/') + 1)
+  dto[className] = function(){}
+})
+
+export { dto }
diff --git a/openbis_ng_ui/src/services/openbis/facade.js b/openbis_ng_ui/src/services/openbis/facade.js
new file mode 100644
index 00000000000..b9b6dea6b78
--- /dev/null
+++ b/openbis_ng_ui/src/services/openbis/facade.js
@@ -0,0 +1,70 @@
+const autoBind = require('auto-bind')
+
+export class Facade {
+
+  constructor() {
+    autoBind(this)
+  }
+
+  init(){
+    let _this = this
+    return new Promise((resolve, reject) => {
+      /* eslint-disable-next-line no-undef */
+      requirejs(['openbis'], openbis => {
+        _this.v3 = new openbis()
+        resolve()
+      }, error => {
+        reject(error)
+      })
+    })
+  }
+
+  login(user, password) {
+    let v3 = this.v3
+    return new Promise((resolve, reject) => {
+      v3.login(user, password).done(resolve).fail(() => {
+        reject({message: 'Login failed'})
+      })
+    })
+  }
+
+  logout() {
+    return this.v3.logout()
+  }
+
+  searchPersons(criteria, fo) {
+    return this.v3.searchPersons(criteria, fo)
+  }
+
+  searchAuthorizationGroups(criteria, fo) {
+    return this.v3.searchAuthorizationGroups(criteria, fo)
+  }
+
+  getSampleTypes(ids, fo){
+    return this.v3.getSampleTypes(ids, fo)
+  }
+
+  searchSampleTypes(criteria, fo) {
+    return this.v3.searchSampleTypes(criteria, fo)
+  }
+
+  updateSampleTypes(updates){
+    return this.v3.updateSampleTypes(updates)
+  }
+
+  searchExperimentTypes(criteria, fo) {
+    return this.v3.searchExperimentTypes(criteria, fo)
+  }
+
+  searchDataSetTypes(criteria, fo) {
+    return this.v3.searchDataSetTypes(criteria, fo)
+  }
+
+  searchMaterialTypes(criteria, fo) {
+    return this.v3.searchMaterialTypes(criteria, fo)
+  }
+
+}
+
+const facade = new Facade()
+export { facade }
diff --git a/openbis_ng_ui/src/store/sagas/api.js b/openbis_ng_ui/src/store/sagas/api.js
index 4da74cca47b..740f0eafa6d 100644
--- a/openbis_ng_ui/src/store/sagas/api.js
+++ b/openbis_ng_ui/src/store/sagas/api.js
@@ -1,5 +1,5 @@
 import {put, takeEvery, apply} from 'redux-saga/effects'
-import openbis from '../../services/openbis.js'
+import {facade} from '../../services/openbis.js'
 import * as actions from '../actions/actions.js'
 
 export default function* api() {
@@ -10,7 +10,7 @@ function* apiRequest(action){
   const { method, params } = action.payload
 
   try{
-    let result = yield apply(openbis, openbis[method], params || [])
+    let result = yield apply(facade, facade[method], params || [])
     yield put(actions.apiSuccess({result, meta: Object.assign({}, action.meta, {method, params})}))
   }catch(error){
     yield put(actions.apiError({error, meta: Object.assign({}, action.meta, {method, params})}))
diff --git a/openbis_ng_ui/src/store/sagas/app.js b/openbis_ng_ui/src/store/sagas/app.js
index b49bc955067..2a2fd8d6a28 100644
--- a/openbis_ng_ui/src/store/sagas/app.js
+++ b/openbis_ng_ui/src/store/sagas/app.js
@@ -1,4 +1,5 @@
-import {put, putAndWait, takeEvery} from './effects.js'
+import {call, put, putAndWait, takeEvery} from './effects.js'
+import {facade, dto} from '../../services/openbis.js'
 import * as actions from '../actions/actions.js'
 import * as pages from '../consts/pages.js'
 
@@ -13,7 +14,8 @@ export default function* app() {
 function* init() {
   try{
     yield put(actions.setLoading(true))
-    yield putAndWait(actions.apiRequest({method: 'init'}))
+    yield call([dto, dto.init])
+    yield call([facade, facade.init])
   }catch(e){
     yield put(actions.setError(e))
   }finally{
diff --git a/openbis_ng_ui/src/store/sagas/browser/types.js b/openbis_ng_ui/src/store/sagas/browser/types.js
index 7d4268173ec..10a2e1da8a2 100644
--- a/openbis_ng_ui/src/store/sagas/browser/types.js
+++ b/openbis_ng_ui/src/store/sagas/browser/types.js
@@ -1,5 +1,6 @@
 import _ from 'lodash'
 import {putAndWait} from './../effects.js'
+import {dto} from '../../../services/openbis.js'
 import * as objectType from '../../consts/objectType.js'
 import * as actions from '../../actions/actions.js'
 import * as common from '../../common/browser.js'
@@ -50,10 +51,22 @@ export function* createNodes() {
 
 function* getTypes(){
   let responses = yield putAndWait({
-    objectTypes: actions.apiRequest({method: 'getObjectTypes'}),
-    collectionTypes: actions.apiRequest({method: 'getCollectionTypes'}),
-    dataSetTypes: actions.apiRequest({method: 'getDataSetTypes'}),
-    materialTypes: actions.apiRequest({method: 'getMaterialTypes'})
+    objectTypes: actions.apiRequest({
+      method: 'searchSampleTypes',
+      params: [new dto.SampleTypeSearchCriteria(), new dto.SampleTypeFetchOptions()]
+    }),
+    collectionTypes: actions.apiRequest({
+      method: 'searchExperimentTypes',
+      params: [new dto.ExperimentTypeSearchCriteria(), new dto.ExperimentTypeFetchOptions()]
+    }),
+    dataSetTypes: actions.apiRequest({
+      method: 'searchDataSetTypes',
+      params: [new dto.DataSetTypeSearchCriteria(), new dto.DataSetTypeFetchOptions()]
+    }),
+    materialTypes: actions.apiRequest({
+      method: 'searchMaterialTypes',
+      params: [new dto.MaterialTypeSearchCriteria(), new dto.MaterialTypeFetchOptions()]
+    })
   })
 
   let convert = function(response){
diff --git a/openbis_ng_ui/src/store/sagas/browser/users.js b/openbis_ng_ui/src/store/sagas/browser/users.js
index edb4d1fc629..d4bf9c6a77c 100644
--- a/openbis_ng_ui/src/store/sagas/browser/users.js
+++ b/openbis_ng_ui/src/store/sagas/browser/users.js
@@ -1,5 +1,6 @@
 import _ from 'lodash'
 import {putAndWait} from './../effects.js'
+import {dto} from '../../../services/openbis.js'
 import * as objectType from '../../consts/objectType.js'
 import * as actions from '../../actions/actions.js'
 import * as common from '../../common/browser.js'
@@ -57,8 +58,18 @@ export function* createNodes() {
 }
 
 function* getUsersAndGroups(){
-  let getUsersReponse = yield putAndWait(actions.apiRequest({method: 'getUsers'}))
-  let getGroupsReponse = yield putAndWait(actions.apiRequest({method: 'getGroups'}))
+  let getUsersReponse = yield putAndWait(actions.apiRequest({
+    method: 'searchPersons',
+    params: [new dto.PersonSearchCriteria(), new dto.PersonFetchOptions()]
+  }))
+
+  let groupFetchOptions = new dto.AuthorizationGroupFetchOptions()
+  groupFetchOptions.withUsers()
+
+  let getGroupsReponse = yield putAndWait(actions.apiRequest({
+    method: 'searchAuthorizationGroups',
+    params: [new dto.AuthorizationGroupSearchCriteria(), groupFetchOptions]
+  }))
 
   let users = {}
   let groups = {}
diff --git a/openbis_ng_ui/srcTest/components/browser/browser.test.js b/openbis_ng_ui/srcTest/components/browser/browser.test.js
index 25da2f03b62..c53e2dc848a 100644
--- a/openbis_ng_ui/srcTest/components/browser/browser.test.js
+++ b/openbis_ng_ui/srcTest/components/browser/browser.test.js
@@ -1,7 +1,7 @@
 import React from 'react'
 import { mount } from 'enzyme'
 import Browser from '../../../src/components/browser/Browser.jsx'
-import openbis from '../../../src/services/openbis.js'
+import { facade, dto } from '../../../src/services/openbis.js'
 import * as actions from '../../../src/store/actions/actions.js'
 import * as pages from '../../../src/store/consts/pages.js'
 import { createStore } from '../../../src/store/store.js'
@@ -19,14 +19,20 @@ beforeEach(() => {
 describe('browser', () => {
 
   test('test', () => {
-    openbis.getUsers.mockReturnValue({
+    facade.searchPersons.mockReturnValue({
       objects: [ fixture.TEST_USER_DTO, fixture.ANOTHER_USER_DTO ]
     })
 
-    openbis.getGroups.mockReturnValue({
+    facade.searchAuthorizationGroups.mockReturnValue({
       objects: [ fixture.TEST_GROUP_DTO, fixture.ANOTHER_GROUP_DTO, fixture.ALL_USERS_GROUP_DTO ]
     })
 
+    dto.AuthorizationGroupFetchOptions.mockImplementation(() => {
+      return {
+        withUsers: function(){}
+      }
+    })
+
     store.dispatch(actions.currentPageChange(pages.USERS))
     store.dispatch(actions.browserInit(pages.USERS))
 
diff --git a/openbis_ng_ui/srcTest/store/sagas/app.test.js b/openbis_ng_ui/srcTest/store/sagas/app.test.js
index 331ffcf0790..3a9f4b98595 100644
--- a/openbis_ng_ui/srcTest/store/sagas/app.test.js
+++ b/openbis_ng_ui/srcTest/store/sagas/app.test.js
@@ -1,4 +1,4 @@
-import openbis from '../../../src/services/openbis.js'
+import { facade } from '../../../src/services/openbis.js'
 import * as actions from '../../../src/store/actions/actions.js'
 import * as selectors from '../../../src/store/selectors/selectors.js'
 import * as pages from '../../../src/store/consts/pages.js'
@@ -16,7 +16,7 @@ beforeEach(() => {
 
 describe('app', () => {
   test('login successful', () => {
-    openbis.login.mockReturnValue(fixture.TEST_SESSION_TOKEN)
+    facade.login.mockReturnValue(fixture.TEST_SESSION_TOKEN)
 
     store.dispatch(actions.login(fixture.TEST_USER, fixture.TEST_PASSWORD))
 
@@ -26,7 +26,7 @@ describe('app', () => {
   })
 
   test('login failed', () => {
-    openbis.login.mockReturnValue(null)
+    facade.login.mockReturnValue(null)
 
     store.dispatch(actions.login(fixture.TEST_USER, fixture.TEST_PASSWORD))
 
@@ -36,7 +36,7 @@ describe('app', () => {
   })
 
   test('logout', () => {
-    openbis.login.mockReturnValue(fixture.TEST_SESSION_TOKEN)
+    facade.login.mockReturnValue(fixture.TEST_SESSION_TOKEN)
 
     store.dispatch(actions.login(fixture.TEST_USER, fixture.TEST_PASSWORD))
     store.dispatch(actions.logout())
diff --git a/openbis_ng_ui/srcTest/store/sagas/browser.test.js b/openbis_ng_ui/srcTest/store/sagas/browser.test.js
index 6af2867a30f..1c518e6d9dc 100644
--- a/openbis_ng_ui/srcTest/store/sagas/browser.test.js
+++ b/openbis_ng_ui/srcTest/store/sagas/browser.test.js
@@ -1,5 +1,5 @@
 import _ from 'lodash'
-import openbis from '../../../src/services/openbis.js'
+import { facade, dto } from '../../../src/services/openbis.js'
 import * as actions from '../../../src/store/actions/actions.js'
 import * as selectors from '../../../src/store/selectors/selectors.js'
 import * as pages from '../../../src/store/consts/pages.js'
@@ -15,7 +15,7 @@ let store = null
 beforeEach(() => {
   jest.resetAllMocks()
 
-  openbis.login.mockReturnValue(fixture.TEST_SESSION_TOKEN)
+  facade.login.mockReturnValue(fixture.TEST_SESSION_TOKEN)
 
   store = createStore()
   store.dispatch(actions.login(fixture.TEST_USER, fixture.TEST_PASSWORD))
@@ -24,14 +24,20 @@ beforeEach(() => {
 describe('browser', () => {
 
   test('init', () => {
-    openbis.getUsers.mockReturnValue({
+    facade.searchPersons.mockReturnValue({
       objects: [ fixture.TEST_USER_DTO, fixture.ANOTHER_USER_DTO ]
     })
 
-    openbis.getGroups.mockReturnValue({
+    facade.searchAuthorizationGroups.mockReturnValue({
       objects: [ fixture.TEST_GROUP_DTO, fixture.ANOTHER_GROUP_DTO, fixture.ALL_USERS_GROUP_DTO ]
     })
 
+    dto.AuthorizationGroupFetchOptions.mockImplementation(() => {
+      return {
+        withUsers: function(){}
+      }
+    })
+
     store.dispatch(actions.browserInit(pages.USERS))
 
     const state = store.getState()
@@ -65,14 +71,20 @@ describe('browser', () => {
   })
 
   test('filter', () => {
-    openbis.getUsers.mockReturnValue({
+    facade.searchPersons.mockReturnValue({
       objects: [ fixture.TEST_USER_DTO, fixture.ANOTHER_USER_DTO ]
     })
 
-    openbis.getGroups.mockReturnValue({
+    facade.searchAuthorizationGroups.mockReturnValue({
       objects: [ fixture.TEST_GROUP_DTO, fixture.ANOTHER_GROUP_DTO, fixture.ALL_USERS_GROUP_DTO ]
     })
 
+    dto.AuthorizationGroupFetchOptions.mockImplementation(() => {
+      return {
+        withUsers: function(){}
+      }
+    })
+
     store.dispatch(actions.browserInit(pages.USERS))
     store.dispatch(actions.browserFilterChange(pages.USERS, fixture.ANOTHER_GROUP_DTO.code.toUpperCase()))
 
@@ -93,14 +105,20 @@ describe('browser', () => {
   })
 
   test('select node', () => {
-    openbis.getUsers.mockReturnValue({
+    facade.searchPersons.mockReturnValue({
       objects: [ fixture.TEST_USER_DTO, fixture.ANOTHER_USER_DTO ]
     })
 
-    openbis.getGroups.mockReturnValue({
+    facade.searchAuthorizationGroups.mockReturnValue({
       objects: []
     })
 
+    dto.AuthorizationGroupFetchOptions.mockImplementation(() => {
+      return {
+        withUsers: function(){}
+      }
+    })
+
     let testUserObject = fixture.object(objectType.USER, fixture.TEST_USER_DTO.userId)
 
     store.dispatch(actions.browserInit(pages.USERS))
@@ -120,14 +138,20 @@ describe('browser', () => {
   })
 
   test('select another node', () => {
-    openbis.getUsers.mockReturnValue({
+    facade.searchPersons.mockReturnValue({
       objects: [ fixture.TEST_USER_DTO, fixture.ANOTHER_USER_DTO ]
     })
 
-    openbis.getGroups.mockReturnValue({
+    facade.searchAuthorizationGroups.mockReturnValue({
       objects: []
     })
 
+    dto.AuthorizationGroupFetchOptions.mockImplementation(() => {
+      return {
+        withUsers: function(){}
+      }
+    })
+
     let testUserObject = fixture.object(objectType.USER, fixture.TEST_USER_DTO.userId)
     let anotherUserObject = fixture.object(objectType.USER, fixture.ANOTHER_USER_DTO.userId)
 
@@ -149,14 +173,20 @@ describe('browser', () => {
   })
 
   test('select virtual node', () => {
-    openbis.getUsers.mockReturnValue({
+    facade.searchPersons.mockReturnValue({
       objects: [ fixture.TEST_USER_DTO, fixture.ANOTHER_USER_DTO ]
     })
 
-    openbis.getGroups.mockReturnValue({
+    facade.searchAuthorizationGroups.mockReturnValue({
       objects: []
     })
 
+    dto.AuthorizationGroupFetchOptions.mockImplementation(() => {
+      return {
+        withUsers: function(){}
+      }
+    })
+
     store.dispatch(actions.browserInit(pages.USERS))
     store.dispatch(actions.browserNodeSelect(pages.USERS, nodeId(['users'])))
 
@@ -174,14 +204,20 @@ describe('browser', () => {
   })
 
   test('select two nodes that represent the same object', () => {
-    openbis.getUsers.mockReturnValue({
+    facade.searchPersons.mockReturnValue({
       objects: [ fixture.TEST_USER_DTO ]
     })
 
-    openbis.getGroups.mockReturnValue({
+    facade.searchAuthorizationGroups.mockReturnValue({
       objects: [ fixture.TEST_GROUP_DTO ]
     })
 
+    dto.AuthorizationGroupFetchOptions.mockImplementation(() => {
+      return {
+        withUsers: function(){}
+      }
+    })
+
     let testUserObject = fixture.object(objectType.USER, fixture.TEST_USER_DTO.userId)
 
     store.dispatch(actions.browserInit(pages.USERS))
@@ -225,14 +261,20 @@ describe('browser', () => {
   })
 
   test('expand and collapse node', () => {
-    openbis.getUsers.mockReturnValue({
+    facade.searchPersons.mockReturnValue({
       objects: []
     })
 
-    openbis.getGroups.mockReturnValue({
+    facade.searchAuthorizationGroups.mockReturnValue({
       objects: [ fixture.TEST_GROUP_DTO ]
     })
 
+    dto.AuthorizationGroupFetchOptions.mockImplementation(() => {
+      return {
+        withUsers: function(){}
+      }
+    })
+
     store.dispatch(actions.browserInit(pages.USERS))
     store.dispatch(actions.browserNodeExpand(pages.USERS, nodeId(['groups'])))
 
-- 
GitLab