Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit64c1c70

Browse files
committed
extract UserDropdownContent into a single component
1 parent6b2b57a commit64c1c70

File tree

7 files changed

+220
-212
lines changed

7 files changed

+220
-212
lines changed

‎site/src/components/UserDropdown/UserDropdown.stories.tsx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,8 @@ const Template: Story<UserDropdownProps> = (args: UserDropdownProps) => (
1717
</Box>
1818
)
1919

20-
exportconstClosed=Template.bind({})
21-
Closed.args={
22-
user:MockUser,
23-
onSignOut:()=>{
24-
returnPromise.resolve()
25-
},
26-
}
27-
28-
exportconstOpen=Template.bind({})
29-
Open.args={
30-
isOpen:true,
20+
exportconstExample=Template.bind({})
21+
Example.args={
3122
user:MockUser,
3223
onSignOut:()=>{
3324
returnPromise.resolve()
Lines changed: 3 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import{screen}from"@testing-library/react"
2-
import{MockAdminRole,MockMemberRole,MockUser}from"../../testHelpers/entities"
2+
import{MockUser}from"../../testHelpers/entities"
33
import{render}from"../../testHelpers/renderHelpers"
4-
import{Language,UserDropdown,UserDropdownProps}from"./UsersDropdown"
4+
import{Language}from"../UserDropdownContent/UserDropdownContent"
5+
import{UserDropdown,UserDropdownProps}from"./UsersDropdown"
56

67
constrenderAndClick=async(props:Partial<UserDropdownProps>={})=>{
78
render(<UserDropdownuser={props.user??MockUser}onSignOut={props.onSignOut??jest.fn()}/>)
@@ -10,18 +11,6 @@ const renderAndClick = async (props: Partial<UserDropdownProps> = {}) => {
1011
}
1112

1213
describe("UserDropdown",()=>{
13-
constenv=process.env
14-
15-
// REMARK: copying process.env so we don't mutate that object or encounter conflicts between tests
16-
beforeEach(()=>{
17-
process.env={ ...env}
18-
})
19-
20-
// REMARK: restoring process.env
21-
afterEach(()=>{
22-
process.env=env
23-
})
24-
2514
describe("when the trigger is clicked",()=>{
2615
it("opens the menu",async()=>{
2716
awaitrenderAndClick()
@@ -30,45 +19,4 @@ describe("UserDropdown", () => {
3019
expect(screen.getByText(Language.signOutLabel)).toBeDefined()
3120
})
3221
})
33-
34-
describe("when the menu is open",()=>{
35-
it("displays the user's roles",async()=>{
36-
awaitrenderAndClick()
37-
38-
expect(screen.getByText(MockAdminRole.display_name)).toBeDefined()
39-
expect(screen.getByText(MockMemberRole.display_name)).toBeDefined()
40-
})
41-
42-
it("has the correct link for the documentation item",async()=>{
43-
process.env.CODER_VERSION="v0.5.4"
44-
awaitrenderAndClick()
45-
46-
constlink=screen.getByText(Language.docsLabel).closest("a")
47-
if(!link){
48-
thrownewError("Anchor tag not found for the documentation menu item")
49-
}
50-
51-
expect(link.getAttribute("href")).toBe(`https://github.com/coder/coder/tree/${process.env.CODER_VERSION}/docs`)
52-
})
53-
54-
it("has the correct link for the account item",async()=>{
55-
awaitrenderAndClick()
56-
57-
constlink=screen.getByText(Language.accountLabel).closest("a")
58-
if(!link){
59-
thrownewError("Anchor tag not found for the account menu item")
60-
}
61-
62-
expect(link.getAttribute("href")).toBe("/settings/account")
63-
})
64-
65-
describe("and sign out is clicked",()=>{
66-
it("calls the onSignOut function",async()=>{
67-
constonSignOut=jest.fn()
68-
awaitrenderAndClick({ onSignOut})
69-
screen.getByText(Language.signOutLabel).click()
70-
expect(onSignOut).toBeCalledTimes(1)
71-
})
72-
})
73-
})
7422
})
Lines changed: 2 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,14 @@
11
importBadgefrom"@material-ui/core/Badge"
2-
importDividerfrom"@material-ui/core/Divider"
3-
importListItemIconfrom"@material-ui/core/ListItemIcon"
4-
importListItemTextfrom"@material-ui/core/ListItemText"
52
importMenuItemfrom"@material-ui/core/MenuItem"
63
import{fade,makeStyles}from"@material-ui/core/styles"
7-
importAccountIconfrom"@material-ui/icons/AccountCircleOutlined"
84
importReact,{useState}from"react"
9-
import{Link}from"react-router-dom"
105
import*asTypesGenfrom"../../api/typesGenerated"
116
import{navHeight}from"../../theme/constants"
127
import{BorderedMenu}from"../BorderedMenu/BorderedMenu"
138
import{CloseDropdown,OpenDropdown}from"../DropdownArrows/DropdownArrows"
14-
import{DocsIcon}from"../Icons/DocsIcon"
15-
import{LogoutIcon}from"../Icons/LogoutIcon"
169
import{UserAvatar}from"../UserAvatar/UserAvatar"
17-
import{UserProfileCard}from"../UserProfileCard/UserProfileCard"
10+
import{UserDropdownContent}from"../UserDropdownContent/UserDropdownContent"
1811

19-
exportconstLanguage={
20-
accountLabel:"Account",
21-
docsLabel:"Documentation",
22-
signOutLabel:"Sign Out",
23-
}
2412
exportinterfaceUserDropdownProps{
2513
user:TypesGen.User
2614
/**
@@ -68,43 +56,7 @@ export const UserDropdown: React.FC<UserDropdownProps> = ({ isOpen = false, user
6856
variant="user-dropdown"
6957
onClose={onPopoverClose}
7058
>
71-
<divclassName={styles.userInfo}>
72-
<UserProfileCarduser={user}/>
73-
74-
<Divider/>
75-
76-
<Linkto="/settings/account"className={styles.link}>
77-
<MenuItemclassName={styles.menuItem}onClick={onPopoverClose}>
78-
<ListItemIconclassName={styles.icon}>
79-
<AccountIcon/>
80-
</ListItemIcon>
81-
<ListItemTextprimary={Language.accountLabel}/>
82-
</MenuItem>
83-
</Link>
84-
85-
<Divider/>
86-
87-
<a
88-
href={`https://github.com/coder/coder/tree/${process.env.CODER_VERSION}/docs`}
89-
target="_blank"
90-
rel="noreferrer"
91-
className={styles.link}
92-
>
93-
<MenuItemclassName={styles.menuItem}onClick={onPopoverClose}>
94-
<ListItemIconclassName={styles.icon}>
95-
<DocsIcon/>
96-
</ListItemIcon>
97-
<ListItemTextprimary={Language.docsLabel}/>
98-
</MenuItem>
99-
</a>
100-
101-
<MenuItemclassName={styles.menuItem}onClick={onSignOut}>
102-
<ListItemIconclassName={styles.icon}>
103-
<LogoutIcon/>
104-
</ListItemIcon>
105-
<ListItemTextprimary={Language.signOutLabel}/>
106-
</MenuItem>
107-
</div>
59+
<UserDropdownContentuser={user}onPopoverClose={onPopoverClose}onSignOut={onSignOut}/>
10860
</BorderedMenu>
10961
</>
11062
)
@@ -123,10 +75,6 @@ export const useStyles = makeStyles((theme) => ({
12375
maxWidth:300,
12476
},
12577

126-
userInfo:{
127-
marginBottom:theme.spacing(1),
128-
},
129-
13078
menuItem:{
13179
height:navHeight,
13280
padding:`${theme.spacing(1.5)}px${theme.spacing(2.75)}px`,
@@ -136,13 +84,4 @@ export const useStyles = makeStyles((theme) => ({
13684
transition:"background-color 0.3s ease",
13785
},
13886
},
139-
140-
link:{
141-
textDecoration:"none",
142-
color:"inherit",
143-
},
144-
145-
icon:{
146-
color:theme.palette.text.secondary,
147-
},
14887
}))

‎site/src/components/UserProfileCard/UserProfileCard.stories.tsxrenamed to‎site/src/components/UserDropdownContent/UserDropdownContent.stories.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import{Story}from"@storybook/react"
22
importReactfrom"react"
33
import{MockUser}from"../../testHelpers/entities"
4-
import{UserProfileCard,UserProfileCardProps}from"./UserProfileCard"
4+
import{UserDropdownContent,UserDropdownContentProps}from"./UserDropdownContent"
55

66
exportdefault{
7-
title:"components/UserProfileCard",
8-
component:UserProfileCard,
7+
title:"components/UserDropdownContent",
8+
component:UserDropdownContent,
99
argTypes:{},
1010
}
1111

12-
constTemplate:Story<UserProfileCardProps>=(args:UserProfileCardProps)=><UserProfileCard{...args}/>
12+
constTemplate:Story<UserDropdownContentProps>=(args:UserDropdownContentProps)=><UserDropdownContent{...args}/>
1313

1414
exportconstExampleNoRoles=Template.bind({})
1515
ExampleNoRoles.args={
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import{screen}from"@testing-library/react"
2+
import{MockAdminRole,MockMemberRole,MockUser}from"../../testHelpers/entities"
3+
import{render}from"../../testHelpers/renderHelpers"
4+
import{Language,UserDropdownContent}from"./UserDropdownContent"
5+
6+
describe("UserProfileCard",()=>{
7+
constenv=process.env
8+
9+
// REMARK: copying process.env so we don't mutate that object or encounter conflicts between tests
10+
beforeEach(()=>{
11+
process.env={ ...env}
12+
})
13+
14+
// REMARK: restoring process.env
15+
afterEach(()=>{
16+
process.env=env
17+
})
18+
19+
it("displays the menu items",()=>{
20+
render(<UserDropdownContentuser={MockUser}onSignOut={jest.fn()}onPopoverClose={jest.fn()}/>)
21+
expect(screen.getByText(Language.accountLabel)).toBeDefined()
22+
expect(screen.getByText(Language.docsLabel)).toBeDefined()
23+
expect(screen.getByText(Language.signOutLabel)).toBeDefined()
24+
})
25+
26+
it("displays the user's roles",async()=>{
27+
render(<UserDropdownContentuser={MockUser}onSignOut={jest.fn()}onPopoverClose={jest.fn()}/>)
28+
expect(screen.getByText(MockAdminRole.display_name)).toBeDefined()
29+
expect(screen.getByText(MockMemberRole.display_name)).toBeDefined()
30+
})
31+
32+
it("has the correct link for the documentation item",async()=>{
33+
process.env.CODER_VERSION="v0.5.4"
34+
render(<UserDropdownContentuser={MockUser}onSignOut={jest.fn()}onPopoverClose={jest.fn()}/>)
35+
constlink=screen.getByText(Language.docsLabel).closest("a")
36+
if(!link){
37+
thrownewError("Anchor tag not found for the documentation menu item")
38+
}
39+
40+
expect(link.getAttribute("href")).toBe(`https://github.com/coder/coder/tree/${process.env.CODER_VERSION}/docs`)
41+
})
42+
43+
it("has the correct link for the account item",async()=>{
44+
render(<UserDropdownContentuser={MockUser}onSignOut={jest.fn()}onPopoverClose={jest.fn()}/>)
45+
constlink=screen.getByText(Language.accountLabel).closest("a")
46+
if(!link){
47+
thrownewError("Anchor tag not found for the account menu item")
48+
}
49+
50+
expect(link.getAttribute("href")).toBe("/settings/account")
51+
})
52+
53+
it("calls the onSignOut function",async()=>{
54+
constonSignOut=jest.fn()
55+
render(<UserDropdownContentuser={MockUser}onSignOut={onSignOut}onPopoverClose={jest.fn()}/>)
56+
screen.getByText(Language.signOutLabel).click()
57+
expect(onSignOut).toBeCalledTimes(1)
58+
})
59+
})

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp