-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(projects): Show join a team if person doesn't have a team #55499
Changes from 4 commits
8b56252
deb2711
0ef863e
efdc82a
2e4bf3b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
import {render, screen} from 'sentry-test/reactTestingLibrary'; | ||
|
||
import {Label} from 'sentry/components/editableText'; | ||
import NoProjectMessage from 'sentry/components/noProjectMessage'; | ||
import ConfigStore from 'sentry/stores/configStore'; | ||
import ProjectsStore from 'sentry/stores/projectsStore'; | ||
|
@@ -26,6 +27,41 @@ describe('NoProjectMessage', function () { | |
expect(screen.getByText('Remain Calm')).toBeInTheDocument(); | ||
}); | ||
|
||
it('shows "Join a Team" when member has no teams', function () { | ||
const organization = TestStubs.Organization({ | ||
slug: 'org-slug', | ||
access: ['org:read', 'team:read'], | ||
}); | ||
const childrenMock = jest.fn().mockReturnValue(null); | ||
ProjectsStore.loadInitialData([]); | ||
|
||
render( | ||
<NoProjectMessage organization={organization}>{childrenMock}</NoProjectMessage> | ||
); | ||
|
||
expect(childrenMock).not.toHaveBeenCalled(); | ||
expect(screen.getByRole('button', {name: 'Join a Team'})).toBeInTheDocument(); | ||
}); | ||
|
||
it('does not show up when user has at least a project and a team', function () { | ||
const organization = TestStubs.Organization({slug: 'org-slug'}); | ||
const team = TestStubs.Team({slug: 'team-slug', isMember: true}); | ||
const project = TestStubs.Project({slug: 'project1', teams: [team]}); | ||
ProjectsStore.loadInitialData([{...project, hasAccess: true}]); | ||
TeamStore.loadInitialData([{...team, access: ['team:read']}]); | ||
|
||
render( | ||
<NoProjectMessage organization={organization}> | ||
<Label data-test-id="project-row" isDisabled> | ||
Some Project | ||
</Label> | ||
</NoProjectMessage> | ||
); | ||
|
||
expect(screen.getByTestId('project-row')).toBeInTheDocument(); | ||
expect(screen.queryByText('Remain Calm')).not.toBeInTheDocument(); | ||
}); | ||
|
||
it('shows "Create Project" button when there are no projects', function () { | ||
ProjectsStore.loadInitialData([]); | ||
|
||
|
@@ -96,4 +132,22 @@ describe('NoProjectMessage', function () { | |
screen.getByText('You need at least one project to use this view') | ||
).toBeInTheDocument(); | ||
}); | ||
|
||
it('shows projects to superusers if membership is not required', function () { | ||
ProjectsStore.loadInitialData([ | ||
TestStubs.Project({hasAccess: true, isMember: false}), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we always return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No. The component I'm modifying has a prop |
||
]); | ||
|
||
ConfigStore.set('user', {...ConfigStore.get('user'), isSuperuser: true}); | ||
|
||
render( | ||
<NoProjectMessage organization={org}> | ||
<Label data-test-id="project-row" isDisabled> | ||
Some Project | ||
</Label> | ||
</NoProjectMessage> | ||
); | ||
|
||
expect(screen.getByTestId('project-row')).toBeInTheDocument(); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,7 @@ function NoProjectMessage({ | |
}: Props) { | ||
const {projects, initiallyLoaded: projectsLoaded} = useProjects(); | ||
const {teams, initiallyLoaded: teamsLoaded} = useTeams(); | ||
const isTeamMember = teams.some(team => team.isMember); | ||
|
||
const orgSlug = organization.slug; | ||
const {canCreateProject} = useProjectCreationAccess({organization, teams}); | ||
|
@@ -39,7 +40,10 @@ function NoProjectMessage({ | |
? !!projects?.some(p => p.hasAccess) | ||
: !!projects?.some(p => p.isMember && p.hasAccess); | ||
|
||
if (hasProjectAccess || !projectsLoaded || !teamsLoaded) { | ||
if ( | ||
(isTeamMember || isSuperuser) && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the only change from previous PR |
||
(hasProjectAccess || !projectsLoaded || !teamsLoaded) | ||
) { | ||
return <Fragment>{children}</Fragment>; | ||
} | ||
|
||
|
@@ -81,7 +85,7 @@ function NoProjectMessage({ | |
<Layout.Title>{t('Remain Calm')}</Layout.Title> | ||
<HelpMessage>{t('You need at least one project to use this view')}</HelpMessage> | ||
<Actions gap={1}> | ||
{!orgHasProjects ? ( | ||
{!orgHasProjects && canCreateProject ? ( | ||
createProjectAction | ||
) : ( | ||
<Fragment> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the test that would have failed on the previous PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the test 👏