mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-17 23:13:00 +00:00
Merge commit '63b7defe1a40b3abc3582a65a0402c1e82a2e230' into group_property_feature
This commit is contained in:
@@ -60,7 +60,10 @@ const AddUser = (props) => {
|
||||
placeholder="usernames separated by line"
|
||||
data-testid="user-textarea"
|
||||
onBlur={(e) => {
|
||||
let split_users = e.target.value.split("\n");
|
||||
let split_users = e.target.value
|
||||
.split("\n")
|
||||
.map((u) => u.trim())
|
||||
.filter((u) => u.length > 0);
|
||||
setUsers(split_users);
|
||||
}}
|
||||
></textarea>
|
||||
@@ -88,17 +91,7 @@ const AddUser = (props) => {
|
||||
data-testid="submit"
|
||||
className="btn btn-primary"
|
||||
onClick={() => {
|
||||
let filtered_users = users.filter(
|
||||
(e) =>
|
||||
e.length > 2 &&
|
||||
/[!@#$%^&*(),.?":{}|<>]/g.test(e) == false
|
||||
);
|
||||
if (filtered_users.length < users.length) {
|
||||
setUsers(filtered_users);
|
||||
failRegexEvent();
|
||||
}
|
||||
|
||||
addUsers(filtered_users, admin)
|
||||
addUsers(users, admin)
|
||||
.then((data) =>
|
||||
data.status < 300
|
||||
? updateUsers(0, limit)
|
||||
|
@@ -70,12 +70,12 @@ test("Removes users when they fail Regex", async () => {
|
||||
let textarea = screen.getByTestId("user-textarea");
|
||||
let submit = screen.getByTestId("submit");
|
||||
|
||||
fireEvent.blur(textarea, { target: { value: "foo\nbar\n!!*&*" } });
|
||||
fireEvent.blur(textarea, { target: { value: "foo \n bar\na@b.co\n \n\n" } });
|
||||
await act(async () => {
|
||||
fireEvent.click(submit);
|
||||
});
|
||||
|
||||
expect(callbackSpy).toHaveBeenCalledWith(["foo", "bar"], false);
|
||||
expect(callbackSpy).toHaveBeenCalledWith(["foo", "bar", "a@b.co"], false);
|
||||
});
|
||||
|
||||
test("Correctly submits admin", async () => {
|
||||
|
@@ -59,7 +59,7 @@ const CreateGroup = (props) => {
|
||||
value={groupName}
|
||||
placeholder="group name..."
|
||||
onChange={(e) => {
|
||||
setGroupName(e.target.value);
|
||||
setGroupName(e.target.value.trim());
|
||||
}}
|
||||
></input>
|
||||
</div>
|
||||
|
@@ -30,7 +30,7 @@ const AccessServerButton = ({ url }) => (
|
||||
);
|
||||
|
||||
const ServerDashboard = (props) => {
|
||||
let base_url = window.base_url;
|
||||
let base_url = window.base_url || "/";
|
||||
// sort methods
|
||||
var usernameDesc = (e) => e.sort((a, b) => (a.name > b.name ? 1 : -1)),
|
||||
usernameAsc = (e) => e.sort((a, b) => (a.name < b.name ? 1 : -1)),
|
||||
@@ -200,6 +200,25 @@ const ServerDashboard = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
const ServerRowTable = ({ data }) => {
|
||||
return (
|
||||
<ReactObjectTableViewer
|
||||
className="table-striped table-bordered"
|
||||
style={{
|
||||
padding: "3px 6px",
|
||||
margin: "auto",
|
||||
}}
|
||||
keyStyle={{
|
||||
padding: "4px",
|
||||
}}
|
||||
valueStyle={{
|
||||
padding: "4px",
|
||||
}}
|
||||
data={data}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const serverRow = (user, server) => {
|
||||
const { servers, ...userNoServers } = user;
|
||||
const serverNameDash = server.name ? `-${server.name}` : "";
|
||||
@@ -258,7 +277,7 @@ const ServerDashboard = (props) => {
|
||||
/>
|
||||
<a
|
||||
href={`${base_url}spawn/${user.name}${
|
||||
server.name && "/" + server.name
|
||||
server.name ? "/" + server.name : ""
|
||||
}`}
|
||||
>
|
||||
<button
|
||||
@@ -286,37 +305,11 @@ const ServerDashboard = (props) => {
|
||||
>
|
||||
<Card style={{ width: "100%", padding: 3, margin: "0 auto" }}>
|
||||
<Card.Title>User</Card.Title>
|
||||
<ReactObjectTableViewer
|
||||
className="table-striped table-bordered admin-table-head"
|
||||
style={{
|
||||
padding: "3px 6px",
|
||||
margin: "auto",
|
||||
}}
|
||||
keyStyle={{
|
||||
padding: "4px",
|
||||
}}
|
||||
valueStyle={{
|
||||
padding: "4px",
|
||||
}}
|
||||
data={userNoServers}
|
||||
/>
|
||||
<ServerRowTable data={userNoServers} />
|
||||
</Card>
|
||||
<Card style={{ width: "100%", padding: 3, margin: "0 auto" }}>
|
||||
<Card.Title>Server</Card.Title>
|
||||
<ReactObjectTableViewer
|
||||
className="table-striped table-bordered admin-table-head"
|
||||
style={{
|
||||
padding: "3px 6px",
|
||||
margin: "auto",
|
||||
}}
|
||||
keyStyle={{
|
||||
padding: "4px",
|
||||
}}
|
||||
valueStyle={{
|
||||
padding: "4px",
|
||||
}}
|
||||
data={server}
|
||||
/>
|
||||
<ServerRowTable data={server} />
|
||||
</Card>
|
||||
</CardGroup>
|
||||
</Collapse>
|
||||
|
@@ -98,6 +98,18 @@ test("Renders correctly the status of a single-user server", async () => {
|
||||
expect(stop).toBeVisible();
|
||||
});
|
||||
|
||||
test("Renders spawn page link", async () => {
|
||||
let callbackSpy = mockAsync();
|
||||
|
||||
await act(async () => {
|
||||
render(serverDashboardJsx(callbackSpy));
|
||||
});
|
||||
|
||||
let link = screen.getByText("Spawn Page").closest("a");
|
||||
let url = new URL(link.href);
|
||||
expect(url.pathname).toEqual("/spawn/bar");
|
||||
});
|
||||
|
||||
test("Invokes the startServer event on button click", async () => {
|
||||
let callbackSpy = mockAsync();
|
||||
|
||||
|
Reference in New Issue
Block a user