diff --git a/static/app/components/lightWeightNoProjectMessage.tsx b/static/app/components/lightWeightNoProjectMessage.tsx
deleted file mode 100644
index 1b9211e54d202b..00000000000000
--- a/static/app/components/lightWeightNoProjectMessage.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import NoProjectMessage from 'app/components/noProjectMessage';
-import {Organization, Project} from 'app/types';
-import withProjects from 'app/utils/withProjects';
-
-type Props = {
- organization: Organization;
- projects: Project[];
- loadingProjects: boolean;
-};
-
-function LightWeightNoProjectMessage({
- organization,
- projects,
- loadingProjects,
- ...props
-}: Props) {
- return (
-
- );
-}
-
-export default withProjects(LightWeightNoProjectMessage);
diff --git a/static/app/components/noProjectMessage.tsx b/static/app/components/noProjectMessage.tsx
index 7a52c8fd26267b..1e4cf609032eae 100644
--- a/static/app/components/noProjectMessage.tsx
+++ b/static/app/components/noProjectMessage.tsx
@@ -11,15 +11,16 @@ import {t} from 'app/locale';
import ConfigStore from 'app/stores/configStore';
import space from 'app/styles/space';
import {Organization, Project} from 'app/types';
+import withProjects from 'app/utils/withProjects';
type Props = React.PropsWithChildren<{
organization: Organization;
- projects?: Project[];
- loadingProjects?: boolean;
+ projects: Project[];
+ loadingProjects: boolean;
superuserNeedsToBeProjectMember?: boolean;
}>;
-export default function NoProjectMessage({
+function NoProjectMessage({
children,
organization,
projects,
@@ -127,3 +128,5 @@ const Content = styled(Flex)`
const Actions = styled(ButtonBar)`
width: fit-content;
`;
+
+export default withProjects(NoProjectMessage);
diff --git a/static/app/views/dashboardsV2/detail.tsx b/static/app/views/dashboardsV2/detail.tsx
index f9d046fa319a2b..a4f75d8b83b622 100644
--- a/static/app/views/dashboardsV2/detail.tsx
+++ b/static/app/views/dashboardsV2/detail.tsx
@@ -13,7 +13,7 @@ import {Client} from 'app/api';
import Breadcrumbs from 'app/components/breadcrumbs';
import HookOrDefault from 'app/components/hookOrDefault';
import * as Layout from 'app/components/layouts/thirds';
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
+import NoProjectMessage from 'app/components/noProjectMessage';
import GlobalSelectionHeader from 'app/components/organizations/globalSelectionHeader';
import {t} from 'app/locale';
import {PageContent} from 'app/styles/organization';
@@ -403,7 +403,7 @@ class DashboardDetail extends Component {
}}
>
-
+
{
router={router}
location={location}
/>
-
+
);
@@ -455,7 +455,7 @@ class DashboardDetail extends Component {
},
}}
>
-
+
{
/>
-
+
);
}
diff --git a/static/app/views/dashboardsV2/manage/index.tsx b/static/app/views/dashboardsV2/manage/index.tsx
index 2617e38e176584..2bfe5637247292 100644
--- a/static/app/views/dashboardsV2/manage/index.tsx
+++ b/static/app/views/dashboardsV2/manage/index.tsx
@@ -7,7 +7,7 @@ import Feature from 'app/components/acl/feature';
import Alert from 'app/components/alert';
import Button from 'app/components/button';
import DropdownControl, {DropdownItem} from 'app/components/dropdownControl';
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
+import NoProjectMessage from 'app/components/noProjectMessage';
import SearchBar from 'app/components/searchBar';
import SentryDocumentTitle from 'app/components/sentryDocumentTitle';
import {IconAdd} from 'app/icons';
@@ -191,7 +191,7 @@ class ManageDashboards extends AsyncView {
>
-
+
{t('Dashboards')}
@@ -210,7 +210,7 @@ class ManageDashboards extends AsyncView {
{this.renderActions()}
{this.renderDashboards()}
-
+
diff --git a/static/app/views/eventsV2/eventDetails/index.tsx b/static/app/views/eventsV2/eventDetails/index.tsx
index 1b30eab0383968..8acb2cdeb36cfb 100644
--- a/static/app/views/eventsV2/eventDetails/index.tsx
+++ b/static/app/views/eventsV2/eventDetails/index.tsx
@@ -2,7 +2,7 @@ import {Component} from 'react';
import {RouteComponentProps} from 'react-router';
import styled from '@emotion/styled';
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
+import NoProjectMessage from 'app/components/noProjectMessage';
import SentryDocumentTitle from 'app/components/sentryDocumentTitle';
import {t} from 'app/locale';
import {PageContent} from 'app/styles/organization';
@@ -53,7 +53,7 @@ class EventDetails extends Component {
projectSlug={projectSlug}
>
-
+
{
router={router}
route={route}
/>
-
+
);
diff --git a/static/app/views/eventsV2/landing.tsx b/static/app/views/eventsV2/landing.tsx
index 15efa817d45e8d..44871739fda401 100644
--- a/static/app/views/eventsV2/landing.tsx
+++ b/static/app/views/eventsV2/landing.tsx
@@ -10,7 +10,7 @@ import GuideAnchor from 'app/components/assistant/guideAnchor';
import AsyncComponent from 'app/components/asyncComponent';
import Button from 'app/components/button';
import DropdownControl, {DropdownItem} from 'app/components/dropdownControl';
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
+import NoProjectMessage from 'app/components/noProjectMessage';
import SearchBar from 'app/components/searchBar';
import SentryDocumentTitle from 'app/components/sentryDocumentTitle';
import Switch from 'app/components/switchButton';
@@ -290,7 +290,7 @@ class DiscoverLanding extends AsyncComponent {
>
-
+
@@ -315,7 +315,7 @@ class DiscoverLanding extends AsyncComponent {
{this.renderActions()}
{this.renderComponent()}
-
+
diff --git a/static/app/views/eventsV2/results.tsx b/static/app/views/eventsV2/results.tsx
index 3f65e90aa577ef..552f1a5f72f65b 100644
--- a/static/app/views/eventsV2/results.tsx
+++ b/static/app/views/eventsV2/results.tsx
@@ -17,7 +17,7 @@ import Confirm from 'app/components/confirm';
import {CreateAlertFromViewButton} from 'app/components/createAlertButton';
import SearchBar from 'app/components/events/searchBar';
import * as Layout from 'app/components/layouts/thirds';
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
+import NoProjectMessage from 'app/components/noProjectMessage';
import GlobalSelectionHeader from 'app/components/organizations/globalSelectionHeader';
import {getParams} from 'app/components/organizations/globalSelectionHeader/getParams';
import SentryDocumentTitle from 'app/components/sentryDocumentTitle';
@@ -461,7 +461,7 @@ class Results extends React.Component {
return (
-
+
{
{this.setOpenFunction}
-
+
);
diff --git a/static/app/views/issueList/container.tsx b/static/app/views/issueList/container.tsx
index 3f476d227675f4..c3fb2d4e32cb7c 100644
--- a/static/app/views/issueList/container.tsx
+++ b/static/app/views/issueList/container.tsx
@@ -1,7 +1,7 @@
import {Component} from 'react';
import DocumentTitle from 'react-document-title';
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
+import NoProjectMessage from 'app/components/noProjectMessage';
import GlobalSelectionHeader from 'app/components/organizations/globalSelectionHeader';
import {Organization} from 'app/types';
import withOrganization from 'app/utils/withOrganization';
@@ -21,9 +21,7 @@ class IssueListContainer extends Component {
return (
-
- {children}
-
+ {children}
);
diff --git a/static/app/views/performance/compare/index.tsx b/static/app/views/performance/compare/index.tsx
index 3040172703c382..0366139a5c1a53 100644
--- a/static/app/views/performance/compare/index.tsx
+++ b/static/app/views/performance/compare/index.tsx
@@ -4,9 +4,9 @@ import styled from '@emotion/styled';
import * as Sentry from '@sentry/react';
import NotFound from 'app/components/errors/notFound';
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
import LoadingError from 'app/components/loadingError';
import LoadingIndicator from 'app/components/loadingIndicator';
+import NoProjectMessage from 'app/components/noProjectMessage';
import SentryDocumentTitle from 'app/components/sentryDocumentTitle';
import {t} from 'app/locale';
import {PageContent} from 'app/styles/organization';
@@ -125,9 +125,9 @@ class TransactionComparisonPage extends React.PureComponent {
>
-
+
{this.renderComparison({baselineEventSlug, regressionEventSlug})}
-
+
diff --git a/static/app/views/performance/content.tsx b/static/app/views/performance/content.tsx
index 939a47ceef1234..79be7520c0dfc5 100644
--- a/static/app/views/performance/content.tsx
+++ b/static/app/views/performance/content.tsx
@@ -9,7 +9,7 @@ import Feature from 'app/components/acl/feature';
import Alert from 'app/components/alert';
import Button from 'app/components/button';
import GlobalSdkUpdateAlert from 'app/components/globalSdkUpdateAlert';
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
+import NoProjectMessage from 'app/components/noProjectMessage';
import GlobalSelectionHeader from 'app/components/organizations/globalSelectionHeader';
import PageHeading from 'app/components/pageHeading';
import SentryDocumentTitle from 'app/components/sentryDocumentTitle';
@@ -211,7 +211,7 @@ class PerformanceContent extends Component {
return (
-
+
{t('Performance')}
{!showOnboarding && (
@@ -248,7 +248,7 @@ class PerformanceContent extends Component {
handleSearch={this.handleSearch}
/>
)}
-
+
);
}
diff --git a/static/app/views/performance/traceDetails/index.tsx b/static/app/views/performance/traceDetails/index.tsx
index cef4e9e30b578c..905ee98f979b3a 100644
--- a/static/app/views/performance/traceDetails/index.tsx
+++ b/static/app/views/performance/traceDetails/index.tsx
@@ -3,7 +3,7 @@ import {RouteComponentProps} from 'react-router';
import styled from '@emotion/styled';
import {Client} from 'app/api';
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
+import NoProjectMessage from 'app/components/noProjectMessage';
import {getParams} from 'app/components/organizations/globalSelectionHeader/getParams';
import SentryDocumentTitle from 'app/components/sentryDocumentTitle';
import {ALL_ACCESS_PROJECTS} from 'app/constants/globalSelectionHeader';
@@ -142,9 +142,9 @@ class TraceSummary extends Component {
return (
-
+
{this.renderContent()}
-
+
);
diff --git a/static/app/views/performance/transactionDetails/index.tsx b/static/app/views/performance/transactionDetails/index.tsx
index 6f5c038f985b2c..be268e3daa0761 100644
--- a/static/app/views/performance/transactionDetails/index.tsx
+++ b/static/app/views/performance/transactionDetails/index.tsx
@@ -2,7 +2,7 @@ import {Component} from 'react';
import {RouteComponentProps} from 'react-router';
import styled from '@emotion/styled';
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
+import NoProjectMessage from 'app/components/noProjectMessage';
import SentryDocumentTitle from 'app/components/sentryDocumentTitle';
import {t} from 'app/locale';
import {PageContent} from 'app/styles/organization';
@@ -36,7 +36,7 @@ class EventDetails extends Component {
projectSlug={projectSlug}
>
-
+
{({projects}) => {
if (projects.length === 0) {
@@ -58,7 +58,7 @@ class EventDetails extends Component {
router={router}
route={route}
/>
-
+
);
diff --git a/static/app/views/performance/transactionSummary/pageLayout.tsx b/static/app/views/performance/transactionSummary/pageLayout.tsx
index 1defe01c84fc06..45460e805dffa4 100644
--- a/static/app/views/performance/transactionSummary/pageLayout.tsx
+++ b/static/app/views/performance/transactionSummary/pageLayout.tsx
@@ -7,7 +7,7 @@ import Feature from 'app/components/acl/feature';
import Alert from 'app/components/alert';
import GlobalSdkUpdateAlert from 'app/components/globalSdkUpdateAlert';
import * as Layout from 'app/components/layouts/thirds';
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
+import NoProjectMessage from 'app/components/noProjectMessage';
import GlobalSelectionHeader from 'app/components/organizations/globalSelectionHeader';
import SentryDocumentTitle from 'app/components/sentryDocumentTitle';
import {IconFlag} from 'app/icons';
@@ -112,7 +112,7 @@ function PageLayout(props: Props) {
showProjectSettingsLink
>
-
+
-
+
diff --git a/static/app/views/performance/trends/index.tsx b/static/app/views/performance/trends/index.tsx
index 887777c5d793f1..3f08681fe2b976 100644
--- a/static/app/views/performance/trends/index.tsx
+++ b/static/app/views/performance/trends/index.tsx
@@ -3,7 +3,7 @@ import {RouteComponentProps} from 'react-router';
import styled from '@emotion/styled';
import {Client} from 'app/api';
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
+import NoProjectMessage from 'app/components/noProjectMessage';
import SentryDocumentTitle from 'app/components/sentryDocumentTitle';
import {t} from 'app/locale';
import {PageContent} from 'app/styles/organization';
@@ -79,9 +79,9 @@ class TrendsSummary extends React.Component {
return (
-
+
{this.renderContent()}
-
+
);
diff --git a/static/app/views/performance/vitalDetail/index.tsx b/static/app/views/performance/vitalDetail/index.tsx
index c90b3b5fa456bd..5c7c75b567cafb 100644
--- a/static/app/views/performance/vitalDetail/index.tsx
+++ b/static/app/views/performance/vitalDetail/index.tsx
@@ -5,7 +5,7 @@ import isEqual from 'lodash/isEqual';
import {loadOrganizationTags} from 'app/actionCreators/tags';
import {Client} from 'app/api';
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
+import NoProjectMessage from 'app/components/noProjectMessage';
import GlobalSelectionHeader from 'app/components/organizations/globalSelectionHeader';
import SentryDocumentTitle from 'app/components/sentryDocumentTitle';
import {t} from 'app/locale';
@@ -109,7 +109,7 @@ class VitalDetail extends Component {
-
+
{
router={router}
vitalName={vitalName || WebVital.LCP}
/>
-
+
diff --git a/static/app/views/projectDetail/projectDetail.tsx b/static/app/views/projectDetail/projectDetail.tsx
index e7a1228ab28a1b..895d6e7037ec5c 100644
--- a/static/app/views/projectDetail/projectDetail.tsx
+++ b/static/app/views/projectDetail/projectDetail.tsx
@@ -15,8 +15,8 @@ import GlobalEventProcessingAlert from 'app/components/globalEventProcessingAler
import GlobalSdkUpdateAlert from 'app/components/globalSdkUpdateAlert';
import IdBadge from 'app/components/idBadge';
import * as Layout from 'app/components/layouts/thirds';
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
import LoadingError from 'app/components/loadingError';
+import NoProjectMessage from 'app/components/noProjectMessage';
import GlobalSelectionHeader from 'app/components/organizations/globalSelectionHeader';
import MissingProjectMembership from 'app/components/projects/missingProjectMembership';
import TextOverflow from 'app/components/textOverflow';
@@ -240,7 +240,7 @@ class ProjectDetail extends AsyncView {
skipLoadLastUsed
onUpdateProjects={this.handleProjectChange}
>
-
+
@@ -370,7 +370,7 @@ class ProjectDetail extends AsyncView {
-
+
);
}
diff --git a/static/app/views/projectsDashboard/index.tsx b/static/app/views/projectsDashboard/index.tsx
index 5da791aa0aba25..050218614cd323 100644
--- a/static/app/views/projectsDashboard/index.tsx
+++ b/static/app/views/projectsDashboard/index.tsx
@@ -67,11 +67,7 @@ function Dashboard({teams, params, organization, loadingTeams, error}: Props) {
if (showEmptyMessage) {
return (
-
+
);
}
diff --git a/static/app/views/releases/detail/index.tsx b/static/app/views/releases/detail/index.tsx
index 4cc4ff1c1cd014..528aabfc05d7f5 100644
--- a/static/app/views/releases/detail/index.tsx
+++ b/static/app/views/releases/detail/index.tsx
@@ -6,8 +6,8 @@ import moment from 'moment';
import Alert from 'app/components/alert';
import AsyncComponent from 'app/components/asyncComponent';
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
import LoadingIndicator from 'app/components/loadingIndicator';
+import NoProjectMessage from 'app/components/noProjectMessage';
import GlobalSelectionHeader from 'app/components/organizations/globalSelectionHeader';
import {getParams} from 'app/components/organizations/globalSelectionHeader/getParams';
import PickProjectToContinue from 'app/components/pickProjectToContinue';
@@ -196,7 +196,7 @@ class ReleasesDetail extends AsyncView {
}
return (
-
+
{
{this.props.children}
-
+
);
}
}
diff --git a/static/app/views/releases/list/index.tsx b/static/app/views/releases/list/index.tsx
index 087844462d9882..5304f36c5d0d44 100644
--- a/static/app/views/releases/list/index.tsx
+++ b/static/app/views/releases/list/index.tsx
@@ -9,9 +9,9 @@ import Feature from 'app/components/acl/feature';
import Alert from 'app/components/alert';
import GuideAnchor from 'app/components/assistant/guideAnchor';
import EmptyStateWarning from 'app/components/emptyStateWarning';
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
import ExternalLink from 'app/components/links/externalLink';
import LoadingIndicator from 'app/components/loadingIndicator';
+import NoProjectMessage from 'app/components/noProjectMessage';
import GlobalSelectionHeader from 'app/components/organizations/globalSelectionHeader';
import {getRelativeSummary} from 'app/components/organizations/timeRangeSelector/utils';
import PageHeading from 'app/components/pageHeading';
@@ -544,7 +544,7 @@ class ReleasesList extends AsyncView {
)}
>
-
+
{t('Releases')}
@@ -608,7 +608,7 @@ class ReleasesList extends AsyncView {
{error
? super.renderError(new Error('Unable to load all required endpoints'))
: this.renderInnerBody(activeDisplay, showReleaseAdoptionStages)}
-
+
);
diff --git a/static/app/views/userFeedback/index.tsx b/static/app/views/userFeedback/index.tsx
index 8dda7de410d3b9..e12381405f8ea0 100644
--- a/static/app/views/userFeedback/index.tsx
+++ b/static/app/views/userFeedback/index.tsx
@@ -7,8 +7,8 @@ import Button from 'app/components/button';
import ButtonBar from 'app/components/buttonBar';
import EventUserFeedback from 'app/components/events/userFeedback';
import CompactIssue from 'app/components/issues/compactIssue';
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
import LoadingIndicator from 'app/components/loadingIndicator';
+import NoProjectMessage from 'app/components/noProjectMessage';
import GlobalSelectionHeader from 'app/components/organizations/globalSelectionHeader';
import PageHeading from 'app/components/pageHeading';
import Pagination from 'app/components/pagination';
@@ -119,7 +119,7 @@ class OrganizationUserFeedback extends AsyncView {
return (
-
+
{t('User Feedback')}
@@ -139,7 +139,7 @@ class OrganizationUserFeedback extends AsyncView {
{this.renderStreamBody()}
-
+
);
diff --git a/tests/js/spec/views/projectsDashboard/lightWeightNoProjectMessage.spec.jsx b/tests/js/spec/views/projectsDashboard/lightWeightNoProjectMessage.spec.jsx
deleted file mode 100644
index c02c175373a639..00000000000000
--- a/tests/js/spec/views/projectsDashboard/lightWeightNoProjectMessage.spec.jsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import {Component} from 'react';
-
-import {mountWithTheme} from 'sentry-test/enzyme';
-
-import LightWeightNoProjectMessage from 'app/components/lightWeightNoProjectMessage';
-import ProjectsStore from 'app/stores/projectsStore';
-
-describe('LightWeightNoProjectMessage', function () {
- beforeEach(function () {
- ProjectsStore.reset();
- });
-
- it('renders', async function () {
- const project1 = TestStubs.Project();
- const project2 = TestStubs.Project();
- const organization = TestStubs.Organization({slug: 'org-slug'});
- delete organization.projects;
- ProjectsStore.loadInitialData([project1, project2]);
- const wrapper = mountWithTheme(
-
- {null}
- ,
- TestStubs.routerContext()
- );
- expect(wrapper.prop('children')).toBe(null);
- expect(wrapper.find('NoProjectMessage').exists()).toBe(true);
- });
-
- it('does not remount when the projects store loads', async function () {
- const mount = jest.fn();
- const unmount = jest.fn();
- class MockComponent extends Component {
- componentWillMount() {
- mount();
- }
- componentWillUnmount() {
- unmount();
- }
- render() {
- return children
;
- }
- }
-
- const project1 = TestStubs.Project();
- const project2 = TestStubs.Project();
- const organization = TestStubs.Organization({slug: 'org-slug'});
- delete organization.projects;
- const wrapper = mountWithTheme(
-
-
- ,
- TestStubs.routerContext()
- );
-
- // verify MockComponent is mounted once
- expect(mount).toHaveBeenCalledTimes(1);
- expect(wrapper.find('NoProjectMessage')).toHaveLength(1);
- expect(wrapper.find('NoProjectMessage').prop('loadingProjects')).toEqual(true);
- ProjectsStore.loadInitialData([project1, project2]);
- // await for trigger from projects store to resolve
- await tick();
- wrapper.update();
-
- // verify MockComponent is not unmounted and is still mounted once
- expect(unmount).toHaveBeenCalledTimes(0);
- expect(mount).toHaveBeenCalledTimes(1);
- expect(wrapper.find('NoProjectMessage')).toHaveLength(1);
- expect(wrapper.find('NoProjectMessage').prop('loadingProjects')).toEqual(false);
- });
-});
diff --git a/tests/js/spec/views/projectsDashboard/noProjectMessage.spec.jsx b/tests/js/spec/views/projectsDashboard/noProjectMessage.spec.jsx
index 9ad459869a63a8..2273d2206c3cbe 100644
--- a/tests/js/spec/views/projectsDashboard/noProjectMessage.spec.jsx
+++ b/tests/js/spec/views/projectsDashboard/noProjectMessage.spec.jsx
@@ -1,11 +1,34 @@
+import {Component} from 'react';
+
import {mountWithTheme} from 'sentry-test/enzyme';
import NoProjectMessage from 'app/components/noProjectMessage';
import ConfigStore from 'app/stores/configStore';
+import ProjectsStore from 'app/stores/projectsStore';
describe('NoProjectMessage', function () {
+ beforeEach(function () {
+ ProjectsStore.reset();
+ });
+
const org = TestStubs.Organization();
+
+ it('renders', async function () {
+ const project1 = TestStubs.Project();
+ const project2 = TestStubs.Project();
+ const organization = TestStubs.Organization({slug: 'org-slug'});
+ delete organization.projects;
+ ProjectsStore.loadInitialData([project1, project2]);
+ const wrapper = mountWithTheme(
+ {null},
+ TestStubs.routerContext()
+ );
+ expect(wrapper.prop('children')).toBe(null);
+ expect(wrapper.find('NoProjectMessage').exists()).toBe(true);
+ });
+
it('shows "Create Project" button when there are no projects', function () {
+ ProjectsStore.loadInitialData([]);
const wrapper = mountWithTheme(
,
TestStubs.routerContext()
@@ -16,6 +39,7 @@ describe('NoProjectMessage', function () {
});
it('"Create Project" is disabled when no access to `project:write`', function () {
+ ProjectsStore.loadInitialData([]);
const wrapper = mountWithTheme(
,
TestStubs.routerContext()
@@ -34,22 +58,18 @@ describe('NoProjectMessage', function () {
});
it('has a "Join a Team" button when no projects but org has projects', function () {
+ ProjectsStore.loadInitialData([TestStubs.Project({hasAccess: false})]);
const wrapper = mountWithTheme(
- ,
+ ,
TestStubs.routerContext()
);
expect(wrapper.find('Button[to="/settings/org-slug/teams/"]')).toHaveLength(1);
});
it('has a disabled "Join a Team" button if no access to `team:read`', function () {
+ ProjectsStore.loadInitialData([TestStubs.Project({hasAccess: false})]);
const wrapper = mountWithTheme(
- ,
+ ,
TestStubs.routerContext()
);
expect(wrapper.find('Button[to="/settings/org-slug/teams/"]').prop('disabled')).toBe(
@@ -57,47 +77,59 @@ describe('NoProjectMessage', function () {
);
});
- it('handles projects from props', function () {
- const lightWeightOrg = TestStubs.Organization();
- delete lightWeightOrg.projects;
-
+ it('shows empty message to superusers that are not members', function () {
+ ProjectsStore.loadInitialData([
+ TestStubs.Project({hasAccess: true, isMember: false}),
+ ]);
+ ConfigStore.config.user = {isSuperuser: true};
const wrapper = mountWithTheme(
- ,
+
+ {null}
+ ,
TestStubs.routerContext()
);
- expect(
- wrapper.find('Button[to="/organizations/org-slug/projects/new/"]')
- ).toHaveLength(1);
+ expect(wrapper.find('HelpMessage')).toHaveLength(1);
});
- it('handles loading projects from props', function () {
- const lightWeightOrg = TestStubs.Organization();
- delete lightWeightOrg.projects;
-
- const child = child
;
+ it('does not remount when the projects store loads', async function () {
+ const mount = jest.fn();
+ const unmount = jest.fn();
+ class MockComponent extends Component {
+ componentWillMount() {
+ mount();
+ }
+ componentWillUnmount() {
+ unmount();
+ }
+ render() {
+ return children
;
+ }
+ }
+ const project1 = TestStubs.Project();
+ const project2 = TestStubs.Project();
+ const organization = TestStubs.Organization({slug: 'org-slug'});
+ delete organization.projects;
const wrapper = mountWithTheme(
-
- {child}
+
+
,
TestStubs.routerContext()
);
- // ensure loading projects causes children to render
- expect(wrapper.find('div')).toHaveLength(1);
- });
- it('shows empty message to superusers that are not members', function () {
- ConfigStore.config.user = {isSuperuser: true};
- const wrapper = mountWithTheme(
-
- {null}
- ,
- TestStubs.routerContext()
- );
- expect(wrapper.find('HelpMessage')).toHaveLength(1);
+ // verify MockComponent is mounted once
+ expect(mount).toHaveBeenCalledTimes(1);
+ expect(wrapper.find('NoProjectMessage')).toHaveLength(1);
+ expect(wrapper.find('NoProjectMessage').prop('loadingProjects')).toEqual(true);
+ ProjectsStore.loadInitialData([project1, project2]);
+ // await for trigger from projects store to resolve
+ await tick();
+ wrapper.update();
+
+ // verify MockComponent is not unmounted and is still mounted once
+ expect(unmount).toHaveBeenCalledTimes(0);
+ expect(mount).toHaveBeenCalledTimes(1);
+ expect(wrapper.find('NoProjectMessage')).toHaveLength(1);
+ expect(wrapper.find('NoProjectMessage').prop('loadingProjects')).toEqual(false);
});
});