Commit 29c0aa11 authored by Markus Scheidgen's avatar Markus Scheidgen
Browse files

Merge branch 'MetadataEditor' into 'v1.0.3'

Metadata editor (#730)

See merge request !553
parents 0d2cd79c 7942d25c
Pipeline #123446 passed with stages
in 49 minutes and 40 seconds
......@@ -78,6 +78,7 @@
"eject": "react-scripts eject"
},
"devDependencies": {
"@apidevtools/swagger-express-middleware": "^4.0.2",
"@material-ui/codemod": "^4.5.0",
"@welldone-software/why-did-you-render": "^6.2.1",
"babel-eslint": "^10.1.0",
......@@ -90,9 +91,11 @@
"eslint-plugin-react": "^7.20.5",
"eslint-plugin-standard": "^3.1.0",
"eslint-plugin-testing-library": "^3.10.1",
"express": "^4.17.2",
"jest-environment-jsdom-sixteen": "^1.0.3",
"react-docgen": "^5.3.0",
"serve": "^10.0.0"
"serve": "^10.0.0",
"supertest": "^6.2.2"
},
"eslintConfig": {
"extends": "react-app"
......
......@@ -122,6 +122,7 @@ export const DatatablePagePagination = React.memo(function DatatablePagePaginati
page={pagination.page - 1}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
role='table-pagination'
/>
})
DatatablePagePagination.propTypes = {
......@@ -454,7 +455,7 @@ export const DatatableTable = React.memo(function DatatableTable({children, acti
const table = <Table size="medium" stickyHeader={isScrolling}>
{!noHeader && <DatatableHeader actions={actions}/>}
<TableBody>
<TableBody role='datatable-body'>
{dataToShow.map((row, index) => (
<DatatableRow
actions={actions}
......
......@@ -68,8 +68,10 @@ const InviteUserDialog = React.memo(function InviteUserDialog(props) {
})
const {api} = useApi()
const handleClose = useCallback(() => {
setOpen(false)
const handleClose = useCallback((event, reason) => {
if (reason !== 'backdropClick') {
setOpen(false)
}
}, [setOpen])
const handleSubmit = useCallback(() => {
......@@ -117,7 +119,7 @@ const InviteUserDialog = React.memo(function InviteUserDialog(props) {
<Dialog
classes={{paper: classes.dialog}}
open={open}
onClose={handleClose} disableBackdropClick disableEscapeKeyDown>
onClose={handleClose} disableEscapeKeyDown>
<DialogTitle>Invite a new user to NOMAD</DialogTitle>
<DialogContent>
<DialogContentText>
......@@ -279,7 +281,7 @@ function AddMember({...props}) {
The selected user is already in the members list
</Typography>
</Box>
<FormControl variant="filled" fullWidth>
<FormControl variant="filled" size='small' fullWidth>
<InputLabel htmlFor="role">Select the member&apos;s role</InputLabel>
<Select
native
......
......@@ -41,7 +41,7 @@ export default function NewUploadButton({...props}) {
})
}
return <Button variant="contained" onClick={handleClick} disabled={clicked} {...props}>
return <Button variant="contained" onClick={handleClick} disabled={clicked} role='new-upload-button' {...props}>
Create a new upload
</Button>
}
......
......@@ -141,11 +141,11 @@ addColumnDefaults(columns, {align: 'left'})
const Published = React.memo(function Published({upload}) {
if (upload.published) {
return <Tooltip title="published upload">
<PublicIcon color="primary" />
<PublicIcon color="primary" role='published-upload-icon'/>
</Tooltip>
} else {
return <Tooltip title="this upload is not yet published">
<UploaderIcon color="error"/>
<UploaderIcon color="error" role='unpublished-upload-icon'/>
</Tooltip>
}
})
......@@ -173,7 +173,7 @@ function UploadCommands({uploadCommands}) {
const classes = useUploadCommandStyles()
return <div className={classes.root}>
<div className={classes.commandContainer}>
<div className={classes.commandContainer} role='upload-commands'>
<div className={classes.commandMarkup}>
<Markdown>{`
\`\`\`
......@@ -242,7 +242,7 @@ UploadCommands.propTypes = {
uploadCommands: PropTypes.object.isRequired
}
function UploadsPage() {
export function UploadsPage() {
const {api} = useApi()
const errors = useErrors()
const [apiData, setApiData] = useState(null)
......@@ -275,7 +275,7 @@ function UploadsPage() {
fetchData()
}, [fetchData])
const isDisabled = unpublished ? (unpublished.pagination ? unpublished.pagination.total >= servicesUploadLimit : true) : true
const isDisabled = unpublished ? (unpublished.pagination ? unpublished.pagination.total >= servicesUploadLimit : false) : false
useEffect(() => {
api.get('/uploads/command-examples')
......@@ -293,7 +293,7 @@ function UploadsPage() {
<Box>
<NewUploadButton color="primary" disabled={isDisabled}/>
<Box display="inline-block" marginLeft={2}>
{isDisabled && <Typography color="error">
{isDisabled && <Typography color="error" role='error-maximum-number-of-unpublished'>
You have reached maximum number of unpublished uploads!
</Typography>}
</Box>
......
/*
* Copyright The NOMAD Authors.
*
* This file is part of NOMAD. See https://nomad-lab.eu for further info.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react'
import 'regenerator-runtime/runtime'
import {render, screen, archives, wait, within} from '../../testSetup'
import { waitFor } from '@testing-library/dom'
import { getIndex } from '../../../tests/DFTBulk'
import { useApi } from '../api'
import { UploadsPage } from './UploadsPage'
import supertest from 'supertest'
const express = require('express')
const createMiddleware = require('@apidevtools/swagger-express-middleware')
let app = express()
// eslint-disable-next-line handle-callback-err
createMiddleware('openapi.json', app, (err, middleware) => {
app.use(
middleware.metadata(),
middleware.parseRequest(),
middleware.validateRequest(),
middleware.mock()
)
supertest(app)
.get('/info')
.then(response => {
if (response) {}
// console.log(response.body)
})
// .end(function(err, res) {
// if (err) console.log(err)
// })
})
jest.mock('../api')
const index = getIndex()
beforeAll(() => {
// API mock init
useApi.mockReturnValue({
api: {
post: () => wait({response: {data: {archive: archives.get(index.entry_id)}}}), // results
get: (url) => {
switch (url) {
case '/uploads?page_size=10&page=1&order_by=upload_create_time&order=desc':
return wait({response: { // response when page_size != 0
query: {},
data: [index],
pagination: {
'page_size': 10,
'order_by': 'upload_create_time',
'order': 'desc',
'page': 1,
'total': 1
}
}})
case '/uploads?is_published=false&page_size=0&order_by=upload_create_time&order=desc':
return wait(
{ // response when page_size=0
query: {
'is_published': false
},
data: [],
pagination: {
'page_size': 0,
'order_by': 'upload_create_time',
'order': 'desc',
'page': 1,
'total': 0
}
})
default:
return wait({response: { // response any other url
}})
}
}}})
})
afterAll(() => {
// API mock cleanup
jest.unmock('../api')
})
test('correctly renders uploads page', async () => {
render(<UploadsPage/>)
// Wait to load the UploadsPage
await waitFor(() => {
expect(screen.queryByRole('new-upload-button')).toBeInTheDocument()
})
expect(screen.queryByRole('upload-commands')).toBeInTheDocument()
expect(screen.queryByRole('error-maximum-number-of-unpublished')).toBeNull()
// Test if the table header is rendered correctly
expect(screen.queryByText('Your existing uploads')).toBeInTheDocument()
expect(screen.queryByRole('table-pagination')).toBeInTheDocument()
expect(screen.queryByRole('datatable-body')).toBeInTheDocument()
let datatableBody = screen.getByRole('datatable-body')
// Test if the times are printed correctly
expect(within(datatableBody).queryByText('2021-03-17T13:47:32.899000')).toBeNull()
expect(within(datatableBody).queryByText(new Date('2021-03-17T13:47:32.899000').toLocaleString())).toBeInTheDocument()
// Test if the published icon is printed not unpublished icon
expect(within(datatableBody).queryByTitle('published upload')).toBeInTheDocument()
expect(within(datatableBody).queryByTitle('this upload is not yet published')).toBeNull()
// TODO: test if the data is sorted by upload_create_time. It needs more test data in DFTBulk.js.
})
......@@ -39,7 +39,22 @@ const common = {
authors: [{name: 'Lauri Himanen'}],
datasets: [{dataset_id: 'Mock dataset', dataset_name: 'Mock dataset'}],
mainfile: 'vasp.xml',
formula: 'Si2'
formula: 'Si2',
upload_name: 'a mock upload',
entries: 1,
main_author: 'Lauri_Himanen_ID',
coauthors: [],
reviewers: [],
process_status: 'SUCCESS',
last_status_message: 'Process edit_upload_metadata completed successfully',
viewers: ['Lauri_Himanen_ID'],
writers: ['Lauri_Himanen_ID'],
published: true,
publish_time: '2022-02-02T09:53:39.056000',
with_embargo: false,
embargo_length: 0,
license: 'CC BY 4.0',
process_running: false
}
const vdwMethod = 'G06'
......
This diff is collapsed.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment