upgrade to react 18

* new root rendering api
* components are now allowed to return undefine
* testing library changes for userEvent.type
This commit is contained in:
Scott Lamb 2023-01-11 22:25:56 -08:00
parent fbb5e6b266
commit 098b54c9f9
No known key found for this signature in database
9 changed files with 606 additions and 163 deletions

620
ui/package-lock.json generated
View File

@ -16,15 +16,14 @@
"@mui/material": "^5.10.8", "@mui/material": "^5.10.8",
"@mui/x-date-pickers": "^5.0.3", "@mui/x-date-pickers": "^5.0.3",
"@react-hook/resize-observer": "^1.2.5", "@react-hook/resize-observer": "^1.2.5",
"@types/jest": "^27.4.1",
"@types/node": "^18.8.1", "@types/node": "^18.8.1",
"@types/react": "^17.0.40", "@types/react": "^18.0.26",
"@types/react-dom": "^17.0.13", "@types/react-dom": "^18.0.10",
"date-fns": "^2.28.0", "date-fns": "^2.28.0",
"date-fns-tz": "^1.3.0", "date-fns-tz": "^1.3.0",
"gzipper": "^7.0.0", "gzipper": "^7.0.0",
"react": "^17.0.1", "react": "^18.2.0",
"react-dom": "^17.0.1", "react-dom": "^18.2.0",
"react-hook-form": "^7.41.5", "react-hook-form": "^7.41.5",
"react-hook-form-mui": "^5.12.3", "react-hook-form-mui": "^5.12.3",
"react-router-dom": "^6.2.2", "react-router-dom": "^6.2.2",
@ -34,8 +33,9 @@
"devDependencies": { "devDependencies": {
"@testing-library/dom": "^8.11.3", "@testing-library/dom": "^8.11.3",
"@testing-library/jest-dom": "^5.16.2", "@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.4", "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^14.4.3",
"@types/jest": "^29.2.5",
"http-proxy-middleware": "^2.0.4", "http-proxy-middleware": "^2.0.4",
"msw": "^0.49.2", "msw": "^0.49.2",
"prettier": "^2.6.0" "prettier": "^2.6.0"
@ -2715,6 +2715,27 @@
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
} }
}, },
"node_modules/@jest/expect-utils": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.3.1.tgz",
"integrity": "sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==",
"dev": true,
"dependencies": {
"jest-get-type": "^29.2.0"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@jest/expect-utils/node_modules/jest-get-type": {
"version": "29.2.0",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
"integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
"dev": true,
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@jest/fake-timers": { "node_modules/@jest/fake-timers": {
"version": "27.5.1", "version": "27.5.1",
"resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
@ -4207,33 +4228,30 @@
} }
}, },
"node_modules/@testing-library/react": { "node_modules/@testing-library/react": {
"version": "12.1.5", "version": "13.4.0",
"resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.5.tgz", "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz",
"integrity": "sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg==", "integrity": "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@babel/runtime": "^7.12.5", "@babel/runtime": "^7.12.5",
"@testing-library/dom": "^8.0.0", "@testing-library/dom": "^8.5.0",
"@types/react-dom": "<18.0.0" "@types/react-dom": "^18.0.0"
}, },
"engines": { "engines": {
"node": ">=12" "node": ">=12"
}, },
"peerDependencies": { "peerDependencies": {
"react": "<18.0.0", "react": "^18.0.0",
"react-dom": "<18.0.0" "react-dom": "^18.0.0"
} }
}, },
"node_modules/@testing-library/user-event": { "node_modules/@testing-library/user-event": {
"version": "13.5.0", "version": "14.4.3",
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.4.3.tgz",
"integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", "integrity": "sha512-kCUc5MEwaEMakkO5x7aoD+DLi02ehmEM2QCGWvNqAS1dV/fAvORWEjnjsEIvml59M7Y5kCkWN6fCCyPOe8OL6Q==",
"dev": true, "dev": true,
"dependencies": {
"@babel/runtime": "^7.12.5"
},
"engines": { "engines": {
"node": ">=10", "node": ">=12",
"npm": ">=6" "npm": ">=6"
}, },
"peerDependencies": { "peerDependencies": {
@ -4435,12 +4453,248 @@
} }
}, },
"node_modules/@types/jest": { "node_modules/@types/jest": {
"version": "27.5.2", "version": "29.2.5",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.5.tgz",
"integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", "integrity": "sha512-H2cSxkKgVmqNHXP7TC2L/WUorrZu8ZigyRywfVzv6EyBlxj39n4C00hjXYQWsbwqgElaj/CiAeSRmk5GoaKTgw==",
"dev": true,
"dependencies": { "dependencies": {
"jest-matcher-utils": "^27.0.0", "expect": "^29.0.0",
"pretty-format": "^27.0.0" "pretty-format": "^29.0.0"
}
},
"node_modules/@types/jest/node_modules/@jest/schemas": {
"version": "29.0.0",
"resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz",
"integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==",
"dev": true,
"dependencies": {
"@sinclair/typebox": "^0.24.1"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@types/jest/node_modules/@jest/types": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz",
"integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==",
"dev": true,
"dependencies": {
"@jest/schemas": "^29.0.0",
"@types/istanbul-lib-coverage": "^2.0.0",
"@types/istanbul-reports": "^3.0.0",
"@types/node": "*",
"@types/yargs": "^17.0.8",
"chalk": "^4.0.0"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@types/jest/node_modules/@types/yargs": {
"version": "17.0.19",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.19.tgz",
"integrity": "sha512-cAx3qamwaYX9R0fzOIZAlFpo4A+1uBVCxqpKz9D26uTF4srRXaGTTsikQmaotCtNdbhzyUH7ft6p9ktz9s6UNQ==",
"dev": true,
"dependencies": {
"@types/yargs-parser": "*"
}
},
"node_modules/@types/jest/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/@types/jest/node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/@types/jest/node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/@types/jest/node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"node_modules/@types/jest/node_modules/diff-sequences": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz",
"integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==",
"dev": true,
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@types/jest/node_modules/expect": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz",
"integrity": "sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==",
"dev": true,
"dependencies": {
"@jest/expect-utils": "^29.3.1",
"jest-get-type": "^29.2.0",
"jest-matcher-utils": "^29.3.1",
"jest-message-util": "^29.3.1",
"jest-util": "^29.3.1"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@types/jest/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/@types/jest/node_modules/jest-diff": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz",
"integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==",
"dev": true,
"dependencies": {
"chalk": "^4.0.0",
"diff-sequences": "^29.3.1",
"jest-get-type": "^29.2.0",
"pretty-format": "^29.3.1"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@types/jest/node_modules/jest-get-type": {
"version": "29.2.0",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
"integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
"dev": true,
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@types/jest/node_modules/jest-matcher-utils": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz",
"integrity": "sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==",
"dev": true,
"dependencies": {
"chalk": "^4.0.0",
"jest-diff": "^29.3.1",
"jest-get-type": "^29.2.0",
"pretty-format": "^29.3.1"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@types/jest/node_modules/jest-message-util": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz",
"integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.12.13",
"@jest/types": "^29.3.1",
"@types/stack-utils": "^2.0.0",
"chalk": "^4.0.0",
"graceful-fs": "^4.2.9",
"micromatch": "^4.0.4",
"pretty-format": "^29.3.1",
"slash": "^3.0.0",
"stack-utils": "^2.0.3"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@types/jest/node_modules/jest-util": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz",
"integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==",
"dev": true,
"dependencies": {
"@jest/types": "^29.3.1",
"@types/node": "*",
"chalk": "^4.0.0",
"ci-info": "^3.2.0",
"graceful-fs": "^4.2.9",
"picomatch": "^2.2.3"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@types/jest/node_modules/pretty-format": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
"integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
"dev": true,
"dependencies": {
"@jest/schemas": "^29.0.0",
"ansi-styles": "^5.0.0",
"react-is": "^18.0.0"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@types/jest/node_modules/pretty-format/node_modules/ansi-styles": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/@types/jest/node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
} }
}, },
"node_modules/@types/js-levenshtein": { "node_modules/@types/js-levenshtein": {
@ -4506,9 +4760,9 @@
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw=="
}, },
"node_modules/@types/react": { "node_modules/@types/react": {
"version": "17.0.52", "version": "18.0.26",
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.52.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz",
"integrity": "sha512-vwk8QqVODi0VaZZpDXQCmEmiOuyjEFPY7Ttaw5vjM112LOq37yz1CDJGrRJwA1fYEq4Iitd5rnjd1yWAc/bT+A==", "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==",
"dependencies": { "dependencies": {
"@types/prop-types": "*", "@types/prop-types": "*",
"@types/scheduler": "*", "@types/scheduler": "*",
@ -4516,11 +4770,11 @@
} }
}, },
"node_modules/@types/react-dom": { "node_modules/@types/react-dom": {
"version": "17.0.18", "version": "18.0.10",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.18.tgz", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.10.tgz",
"integrity": "sha512-rLVtIfbwyur2iFKykP2w0pl/1unw26b5td16d5xMgp7/yjTHomkyxPYChFoCr/FtEX1lN9wY6lFj1qvKdS5kDw==", "integrity": "sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==",
"dependencies": { "dependencies": {
"@types/react": "^17" "@types/react": "*"
} }
}, },
"node_modules/@types/react-is": { "node_modules/@types/react-is": {
@ -15666,12 +15920,11 @@
} }
}, },
"node_modules/react": { "node_modules/react": {
"version": "17.0.2", "version": "18.2.0",
"resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
"integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
"dependencies": { "dependencies": {
"loose-envify": "^1.1.0", "loose-envify": "^1.1.0"
"object-assign": "^4.1.1"
}, },
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
@ -15800,16 +16053,15 @@
} }
}, },
"node_modules/react-dom": { "node_modules/react-dom": {
"version": "17.0.2", "version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
"integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
"dependencies": { "dependencies": {
"loose-envify": "^1.1.0", "loose-envify": "^1.1.0",
"object-assign": "^4.1.1", "scheduler": "^0.23.0"
"scheduler": "^0.20.2"
}, },
"peerDependencies": { "peerDependencies": {
"react": "17.0.2" "react": "^18.2.0"
} }
}, },
"node_modules/react-error-overlay": { "node_modules/react-error-overlay": {
@ -16577,12 +16829,11 @@
} }
}, },
"node_modules/scheduler": { "node_modules/scheduler": {
"version": "0.20.2", "version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
"integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
"dependencies": { "dependencies": {
"loose-envify": "^1.1.0", "loose-envify": "^1.1.0"
"object-assign": "^4.1.1"
} }
}, },
"node_modules/schema-utils": { "node_modules/schema-utils": {
@ -20725,6 +20976,23 @@
"jest-mock": "^27.5.1" "jest-mock": "^27.5.1"
} }
}, },
"@jest/expect-utils": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.3.1.tgz",
"integrity": "sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==",
"dev": true,
"requires": {
"jest-get-type": "^29.2.0"
},
"dependencies": {
"jest-get-type": {
"version": "29.2.0",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
"integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
"dev": true
}
}
},
"@jest/fake-timers": { "@jest/fake-timers": {
"version": "27.5.1", "version": "27.5.1",
"resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
@ -21669,24 +21937,22 @@
} }
}, },
"@testing-library/react": { "@testing-library/react": {
"version": "12.1.5", "version": "13.4.0",
"resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.5.tgz", "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz",
"integrity": "sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg==", "integrity": "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/runtime": "^7.12.5", "@babel/runtime": "^7.12.5",
"@testing-library/dom": "^8.0.0", "@testing-library/dom": "^8.5.0",
"@types/react-dom": "<18.0.0" "@types/react-dom": "^18.0.0"
} }
}, },
"@testing-library/user-event": { "@testing-library/user-event": {
"version": "13.5.0", "version": "14.4.3",
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.4.3.tgz",
"integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", "integrity": "sha512-kCUc5MEwaEMakkO5x7aoD+DLi02ehmEM2QCGWvNqAS1dV/fAvORWEjnjsEIvml59M7Y5kCkWN6fCCyPOe8OL6Q==",
"dev": true, "dev": true,
"requires": { "requires": {}
"@babel/runtime": "^7.12.5"
}
}, },
"@tootallnate/once": { "@tootallnate/once": {
"version": "1.1.2", "version": "1.1.2",
@ -21877,12 +22143,195 @@
} }
}, },
"@types/jest": { "@types/jest": {
"version": "27.5.2", "version": "29.2.5",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.5.tgz",
"integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", "integrity": "sha512-H2cSxkKgVmqNHXP7TC2L/WUorrZu8ZigyRywfVzv6EyBlxj39n4C00hjXYQWsbwqgElaj/CiAeSRmk5GoaKTgw==",
"dev": true,
"requires": { "requires": {
"jest-matcher-utils": "^27.0.0", "expect": "^29.0.0",
"pretty-format": "^27.0.0" "pretty-format": "^29.0.0"
},
"dependencies": {
"@jest/schemas": {
"version": "29.0.0",
"resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz",
"integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==",
"dev": true,
"requires": {
"@sinclair/typebox": "^0.24.1"
}
},
"@jest/types": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz",
"integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==",
"dev": true,
"requires": {
"@jest/schemas": "^29.0.0",
"@types/istanbul-lib-coverage": "^2.0.0",
"@types/istanbul-reports": "^3.0.0",
"@types/node": "*",
"@types/yargs": "^17.0.8",
"chalk": "^4.0.0"
}
},
"@types/yargs": {
"version": "17.0.19",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.19.tgz",
"integrity": "sha512-cAx3qamwaYX9R0fzOIZAlFpo4A+1uBVCxqpKz9D26uTF4srRXaGTTsikQmaotCtNdbhzyUH7ft6p9ktz9s6UNQ==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
}
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"diff-sequences": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz",
"integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==",
"dev": true
},
"expect": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz",
"integrity": "sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==",
"dev": true,
"requires": {
"@jest/expect-utils": "^29.3.1",
"jest-get-type": "^29.2.0",
"jest-matcher-utils": "^29.3.1",
"jest-message-util": "^29.3.1",
"jest-util": "^29.3.1"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"jest-diff": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz",
"integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==",
"dev": true,
"requires": {
"chalk": "^4.0.0",
"diff-sequences": "^29.3.1",
"jest-get-type": "^29.2.0",
"pretty-format": "^29.3.1"
}
},
"jest-get-type": {
"version": "29.2.0",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
"integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
"dev": true
},
"jest-matcher-utils": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz",
"integrity": "sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==",
"dev": true,
"requires": {
"chalk": "^4.0.0",
"jest-diff": "^29.3.1",
"jest-get-type": "^29.2.0",
"pretty-format": "^29.3.1"
}
},
"jest-message-util": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz",
"integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.12.13",
"@jest/types": "^29.3.1",
"@types/stack-utils": "^2.0.0",
"chalk": "^4.0.0",
"graceful-fs": "^4.2.9",
"micromatch": "^4.0.4",
"pretty-format": "^29.3.1",
"slash": "^3.0.0",
"stack-utils": "^2.0.3"
}
},
"jest-util": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz",
"integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==",
"dev": true,
"requires": {
"@jest/types": "^29.3.1",
"@types/node": "*",
"chalk": "^4.0.0",
"ci-info": "^3.2.0",
"graceful-fs": "^4.2.9",
"picomatch": "^2.2.3"
}
},
"pretty-format": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
"integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
"dev": true,
"requires": {
"@jest/schemas": "^29.0.0",
"ansi-styles": "^5.0.0",
"react-is": "^18.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"dev": true
}
}
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
}
} }
}, },
"@types/js-levenshtein": { "@types/js-levenshtein": {
@ -21948,9 +22397,9 @@
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw=="
}, },
"@types/react": { "@types/react": {
"version": "17.0.52", "version": "18.0.26",
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.52.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz",
"integrity": "sha512-vwk8QqVODi0VaZZpDXQCmEmiOuyjEFPY7Ttaw5vjM112LOq37yz1CDJGrRJwA1fYEq4Iitd5rnjd1yWAc/bT+A==", "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==",
"requires": { "requires": {
"@types/prop-types": "*", "@types/prop-types": "*",
"@types/scheduler": "*", "@types/scheduler": "*",
@ -21958,11 +22407,11 @@
} }
}, },
"@types/react-dom": { "@types/react-dom": {
"version": "17.0.18", "version": "18.0.10",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.18.tgz", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.10.tgz",
"integrity": "sha512-rLVtIfbwyur2iFKykP2w0pl/1unw26b5td16d5xMgp7/yjTHomkyxPYChFoCr/FtEX1lN9wY6lFj1qvKdS5kDw==", "integrity": "sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==",
"requires": { "requires": {
"@types/react": "^17" "@types/react": "*"
} }
}, },
"@types/react-is": { "@types/react-is": {
@ -29885,12 +30334,11 @@
} }
}, },
"react": { "react": {
"version": "17.0.2", "version": "18.2.0",
"resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
"integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
"requires": { "requires": {
"loose-envify": "^1.1.0", "loose-envify": "^1.1.0"
"object-assign": "^4.1.1"
} }
}, },
"react-app-polyfill": { "react-app-polyfill": {
@ -29988,13 +30436,12 @@
} }
}, },
"react-dom": { "react-dom": {
"version": "17.0.2", "version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
"integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
"requires": { "requires": {
"loose-envify": "^1.1.0", "loose-envify": "^1.1.0",
"object-assign": "^4.1.1", "scheduler": "^0.23.0"
"scheduler": "^0.20.2"
} }
}, },
"react-error-overlay": { "react-error-overlay": {
@ -30510,12 +30957,11 @@
} }
}, },
"scheduler": { "scheduler": {
"version": "0.20.2", "version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
"integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
"requires": { "requires": {
"loose-envify": "^1.1.0", "loose-envify": "^1.1.0"
"object-assign": "^4.1.1"
} }
}, },
"schema-utils": { "schema-utils": {

View File

@ -11,15 +11,14 @@
"@mui/material": "^5.10.8", "@mui/material": "^5.10.8",
"@mui/x-date-pickers": "^5.0.3", "@mui/x-date-pickers": "^5.0.3",
"@react-hook/resize-observer": "^1.2.5", "@react-hook/resize-observer": "^1.2.5",
"@types/jest": "^27.4.1",
"@types/node": "^18.8.1", "@types/node": "^18.8.1",
"@types/react": "^17.0.40", "@types/react": "^18.0.26",
"@types/react-dom": "^17.0.13", "@types/react-dom": "^18.0.10",
"date-fns": "^2.28.0", "date-fns": "^2.28.0",
"date-fns-tz": "^1.3.0", "date-fns-tz": "^1.3.0",
"gzipper": "^7.0.0", "gzipper": "^7.0.0",
"react": "^17.0.1", "react": "^18.2.0",
"react-dom": "^17.0.1", "react-dom": "^18.2.0",
"react-hook-form": "^7.41.5", "react-hook-form": "^7.41.5",
"react-hook-form-mui": "^5.12.3", "react-hook-form-mui": "^5.12.3",
"react-router-dom": "^6.2.2", "react-router-dom": "^6.2.2",
@ -69,8 +68,9 @@
"devDependencies": { "devDependencies": {
"@testing-library/dom": "^8.11.3", "@testing-library/dom": "^8.11.3",
"@testing-library/jest-dom": "^5.16.2", "@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.4", "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^14.4.3",
"@types/jest": "^29.2.5",
"http-proxy-middleware": "^2.0.4", "http-proxy-middleware": "^2.0.4",
"msw": "^0.49.2", "msw": "^0.49.2",
"prettier": "^2.6.0" "prettier": "^2.6.0"

View File

@ -5,26 +5,10 @@
import { render, screen } from "@testing-library/react"; import { render, screen } from "@testing-library/react";
import ErrorBoundary from "./ErrorBoundary"; import ErrorBoundary from "./ErrorBoundary";
const BuggyComponent = () => {
return [][0]; // return undefined in a way that outsmarts Typescript.
};
const ThrowsLiteralComponent = () => { const ThrowsLiteralComponent = () => {
throw "simple string error"; // eslint-disable-line no-throw-literal throw "simple string error"; // eslint-disable-line no-throw-literal
}; };
test("renders error", () => {
render(
<ErrorBoundary>
<BuggyComponent />
</ErrorBoundary>
);
const buggyComponentElement = screen.getByText(/BuggyComponent/);
expect(buggyComponentElement).toBeInTheDocument();
const sorryElement = screen.getByText(/Sorry/);
expect(sorryElement).toBeInTheDocument();
});
test("renders string error", () => { test("renders string error", () => {
render( render(
<ErrorBoundary> <ErrorBoundary>

View File

@ -100,10 +100,10 @@ const StreamMultiSelector = ({ toplevel, selected, setSelected }: Props) => {
component="table" component="table"
sx={{ sx={{
fontSize: "0.9rem", fontSize: "0.9rem",
"& td:first-child": { "& td:first-of-type": {
paddingRight: "3px", paddingRight: "3px",
}, },
"& td:not(:first-child)": { "& td:not(:first-of-type)": {
textAlign: "center", textAlign: "center",
}, },
"& .MuiCheckbox-root": { "& .MuiCheckbox-root": {

View File

@ -192,7 +192,7 @@ const Multiview = (props: MultiviewProps) => {
gridTemplateColumns: "repeat(3, calc(100% / 3))", gridTemplateColumns: "repeat(3, calc(100% / 3))",
gridTemplateRows: "repeat(3, calc(100% / 3))", gridTemplateRows: "repeat(3, calc(100% / 3))",
}, },
"&.main-plus-five > div:nth-child(1)": { "&.main-plus-five > div:nth-of-type(1)": {
gridColumn: "span 2", gridColumn: "span 2",
gridRow: "span 2", gridRow: "span 2",
}, },

View File

@ -13,6 +13,9 @@ import { renderWithCtx } from "./testutil";
const server = setupServer( const server = setupServer(
rest.post("/api/login", (req, res, ctx) => { rest.post("/api/login", (req, res, ctx) => {
const { username, password } = req.body! as Record<string, string>; const { username, password } = req.body! as Record<string, string>;
console.log(
"/api/login post username=" + username + " password=" + password
);
if (username === "slamb" && password === "hunter2") { if (username === "slamb" && password === "hunter2") {
return res(ctx.status(204)); return res(ctx.status(204));
} else if (username === "delay") { } else if (username === "delay") {
@ -39,9 +42,14 @@ afterAll(() => server.close());
// (Seems like waitFor's internal advance calls aren't wrapped in act) // (Seems like waitFor's internal advance calls aren't wrapped in act)
// * react-scripts v5, @testing-library/react v12: // * react-scripts v5, @testing-library/react v12:
// msw requests never complete // msw requests never complete
// https://github.com/mswjs/msw/issues/448#issuecomment-723438099 ?
// https://github.com/facebook/jest/issues/11103 ?
// https://github.com/facebook/jest/issues/13018 ?
// //
// Argh! // Argh!
// beforeEach(() => jest.useFakeTimers()); // beforeEach(() => jest.useFakeTimers({
// legacyFakeTimers: true,
// }));
// afterEach(() => { // afterEach(() => {
// act(() => { // act(() => {
// jest.runOnlyPendingTimers(); // jest.runOnlyPendingTimers();
@ -50,13 +58,14 @@ afterAll(() => server.close());
// }); // });
test("success", async () => { test("success", async () => {
const user = userEvent.setup();
const handleClose = jest.fn().mockName("handleClose"); const handleClose = jest.fn().mockName("handleClose");
const onSuccess = jest.fn().mockName("handleOpen"); const onSuccess = jest.fn().mockName("handleOpen");
renderWithCtx( renderWithCtx(
<Login open={true} onSuccess={onSuccess} handleClose={handleClose} /> <Login open={true} onSuccess={onSuccess} handleClose={handleClose} />
); );
userEvent.type(screen.getByLabelText(/Username/), "slamb"); await user.type(screen.getByLabelText(/Username/), "slamb");
userEvent.type(screen.getByLabelText(/Password/), "hunter2{enter}"); await user.type(screen.getByLabelText(/Password/), "hunter2{enter}");
await waitFor(() => expect(onSuccess).toHaveBeenCalledTimes(1)); await waitFor(() => expect(onSuccess).toHaveBeenCalledTimes(1));
}); });
@ -92,8 +101,8 @@ xtest("bad credentials", async () => {
renderWithCtx( renderWithCtx(
<Login open={true} onSuccess={onSuccess} handleClose={handleClose} /> <Login open={true} onSuccess={onSuccess} handleClose={handleClose} />
); );
userEvent.type(screen.getByLabelText(/Username/), "slamb"); await userEvent.type(screen.getByLabelText(/Username/), "slamb");
userEvent.type(screen.getByLabelText(/Password/), "wrong{enter}"); await userEvent.type(screen.getByLabelText(/Password/), "wrong{enter}");
await screen.findByText(/bad credentials/); await screen.findByText(/bad credentials/);
expect(onSuccess).toHaveBeenCalledTimes(0); expect(onSuccess).toHaveBeenCalledTimes(0);
}); });
@ -106,8 +115,8 @@ xtest("server error", async () => {
renderWithCtx( renderWithCtx(
<Login open={true} onSuccess={onSuccess} handleClose={handleClose} /> <Login open={true} onSuccess={onSuccess} handleClose={handleClose} />
); );
userEvent.type(screen.getByLabelText(/Username/), "server-error"); await userEvent.type(screen.getByLabelText(/Username/), "server-error");
userEvent.type(screen.getByLabelText(/Password/), "asdf{enter}"); await userEvent.type(screen.getByLabelText(/Password/), "asdf{enter}");
await screen.findByText(/server error/); await screen.findByText(/server error/);
await waitFor(() => await waitFor(() =>
expect(screen.queryByText(/server error/)).not.toBeInTheDocument() expect(screen.queryByText(/server error/)).not.toBeInTheDocument()
@ -123,8 +132,8 @@ xtest("network error", async () => {
renderWithCtx( renderWithCtx(
<Login open={true} onSuccess={onSuccess} handleClose={handleClose} /> <Login open={true} onSuccess={onSuccess} handleClose={handleClose} />
); );
userEvent.type(screen.getByLabelText(/Username/), "network-error"); await userEvent.type(screen.getByLabelText(/Username/), "network-error");
userEvent.type(screen.getByLabelText(/Password/), "asdf{enter}"); await userEvent.type(screen.getByLabelText(/Password/), "asdf{enter}");
await screen.findByText(/network error/); await screen.findByText(/network error/);
await waitFor(() => await waitFor(() =>
expect(screen.queryByText(/network error/)).not.toBeInTheDocument() expect(screen.queryByText(/network error/)).not.toBeInTheDocument()

View File

@ -6,7 +6,6 @@ import Avatar from "@mui/material/Avatar";
import Dialog from "@mui/material/Dialog"; import Dialog from "@mui/material/Dialog";
import DialogActions from "@mui/material/DialogActions"; import DialogActions from "@mui/material/DialogActions";
import DialogTitle from "@mui/material/DialogTitle"; import DialogTitle from "@mui/material/DialogTitle";
import FormControl from "@mui/material/FormControl";
import FormHelperText from "@mui/material/FormHelperText"; import FormHelperText from "@mui/material/FormHelperText";
import { useTheme } from "@mui/material/styles"; import { useTheme } from "@mui/material/styles";
import TextField from "@mui/material/TextField"; import TextField from "@mui/material/TextField";
@ -119,41 +118,41 @@ const Login = ({ open, onSuccess, handleClose }: Props) => {
</DialogTitle> </DialogTitle>
<form onSubmit={onSubmit}> <form onSubmit={onSubmit}>
<FormControl error={error != null} fullWidth> <TextField
<TextField id="username"
id="username" label="Username"
label="Username" variant="filled"
variant="filled" required
required autoComplete="username"
autoComplete="username" fullWidth
fullWidth error={error != null}
inputRef={usernameRef} inputRef={usernameRef}
/> />
<TextField <TextField
id="password" id="password"
label="Password" label="Password"
variant="filled" variant="filled"
type="password" type="password"
required required
autoComplete="current-password" autoComplete="current-password"
fullWidth fullWidth
inputRef={passwordRef} error={error != null}
/> inputRef={passwordRef}
/>
{/* reserve space for an error; show when there's something to see */} {/* reserve space for an error; show when there's something to see */}
<FormHelperText>{error == null ? " " : error}</FormHelperText> <FormHelperText>{error == null ? " " : error}</FormHelperText>
<DialogActions> <DialogActions>
<LoadingButton <LoadingButton
type="submit" type="submit"
variant="contained" variant="contained"
color="secondary" color="secondary"
loading={loading !== null} loading={loading !== null}
> >
Log in Log in
</LoadingButton> </LoadingButton>
</DialogActions> </DialogActions>
</FormControl>
</form> </form>
</Dialog> </Dialog>
); );

View File

@ -8,7 +8,7 @@ import StyledEngineProvider from "@mui/material/StyledEngineProvider";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import "@fontsource/roboto"; import "@fontsource/roboto";
import React from "react"; import React from "react";
import ReactDOM from "react-dom"; import { createRoot } from "react-dom/client";
import App from "./App"; import App from "./App";
import ErrorBoundary from "./ErrorBoundary"; import ErrorBoundary from "./ErrorBoundary";
import { SnackbarProvider } from "./snackbars"; import { SnackbarProvider } from "./snackbars";
@ -27,7 +27,9 @@ const theme = createTheme({
}, },
}); });
ReactDOM.render( const container = document.getElementById("root");
const root = createRoot(container!);
root.render(
<React.StrictMode> <React.StrictMode>
<StyledEngineProvider injectFirst> <StyledEngineProvider injectFirst>
<CssBaseline /> <CssBaseline />
@ -43,6 +45,5 @@ ReactDOM.render(
</ErrorBoundary> </ErrorBoundary>
</ThemeProvider> </ThemeProvider>
</StyledEngineProvider> </StyledEngineProvider>
</React.StrictMode>, </React.StrictMode>
document.getElementById("root")
); );

View File

@ -2,7 +2,7 @@
// Copyright (C) 2021 The Moonfire NVR Authors; see AUTHORS and LICENSE.txt. // Copyright (C) 2021 The Moonfire NVR Authors; see AUTHORS and LICENSE.txt.
// SPDX-License-Identifier: GPL-v3.0-or-later WITH GPL-3.0-linking-exception // SPDX-License-Identifier: GPL-v3.0-or-later WITH GPL-3.0-linking-exception
import { render, screen } from "@testing-library/react"; import { render, screen, waitFor } from "@testing-library/react";
import { useEffect } from "react"; import { useEffect } from "react";
import { SnackbarProvider, useSnackbars } from "./snackbars"; import { SnackbarProvider, useSnackbars } from "./snackbars";
@ -40,7 +40,9 @@ test("notifications that time out", async () => {
// ...then it should close and message B should open... // ...then it should close and message B should open...
jest.runOnlyPendingTimers(); jest.runOnlyPendingTimers();
expect(screen.queryByText(/message A/)).not.toBeInTheDocument(); await waitFor(() =>
expect(screen.queryByText(/message A/)).not.toBeInTheDocument()
);
expect(screen.getByText(/message B/)).toBeInTheDocument(); expect(screen.getByText(/message B/)).toBeInTheDocument();
// ...then message B should start to close... // ...then message B should start to close...
@ -51,7 +53,9 @@ test("notifications that time out", async () => {
// ...then message B should fully close. // ...then message B should fully close.
jest.runOnlyPendingTimers(); jest.runOnlyPendingTimers();
expect(screen.queryByText(/message A/)).not.toBeInTheDocument(); expect(screen.queryByText(/message A/)).not.toBeInTheDocument();
expect(screen.queryByText(/message B/)).not.toBeInTheDocument(); await waitFor(() =>
expect(screen.queryByText(/message B/)).not.toBeInTheDocument()
);
}); });
// TODO: test dismiss. // TODO: test dismiss.