This is an automated email from the ASF dual-hosted git repository.

elizabeth pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 5866d5e  fix: Revert "fix: RBAC hide right menu (#16902)" (#16968)
5866d5e is described below

commit 5866d5ebb064648b6ac23c498cc252207f62dfd1
Author: Elizabeth Thompson <[email protected]>
AuthorDate: Mon Oct 4 19:18:12 2021 -0700

    fix: Revert "fix: RBAC hide right menu (#16902)" (#16968)
    
    * Revert "fix: RBAC hide right menu (#16902)"
    
    This reverts commit 87baac7650bdb6a8f8f82cf4992567a2c5c73cba.
    
    * fix failing test
---
 .../dashboard/components/menu/HoverMenu_spec.tsx   |   9 +-
 .../src/components/Menu/Menu.test.tsx              |  52 ----
 .../src/components/Menu/MenuRight.tsx              | 269 ++++++++++-----------
 superset-frontend/src/views/menu.tsx               |   7 +-
 4 files changed, 129 insertions(+), 208 deletions(-)

diff --git 
a/superset-frontend/spec/javascripts/dashboard/components/menu/HoverMenu_spec.tsx
 
b/superset-frontend/spec/javascripts/dashboard/components/menu/HoverMenu_spec.tsx
index 220952b..24106f1 100644
--- 
a/superset-frontend/spec/javascripts/dashboard/components/menu/HoverMenu_spec.tsx
+++ 
b/superset-frontend/spec/javascripts/dashboard/components/menu/HoverMenu_spec.tsx
@@ -17,14 +17,13 @@
  * under the License.
  */
 import React from 'react';
-import { render } from 'spec/helpers/testing-library';
+import { shallow } from 'enzyme';
 
 import HoverMenu from 'src/dashboard/components/menu/HoverMenu';
 
 describe('HoverMenu', () => {
-  it('should render a hover menu', () => {
-    const rendered = render(<HoverMenu />);
-    const hoverMenu = rendered.container.querySelector('.hover-menu');
-    expect(hoverMenu).toBeVisible();
+  it('should render a div.hover-menu', () => {
+    const wrapper = shallow(<HoverMenu />);
+    expect(wrapper.find('.hover-menu')).toExist();
   });
 });
diff --git a/superset-frontend/src/components/Menu/Menu.test.tsx 
b/superset-frontend/src/components/Menu/Menu.test.tsx
index 8dd8f56..f3a2fd1 100644
--- a/superset-frontend/src/components/Menu/Menu.test.tsx
+++ b/superset-frontend/src/components/Menu/Menu.test.tsx
@@ -17,32 +17,12 @@
  * under the License.
  */
 import React from 'react';
-import * as reactRedux from 'react-redux';
 import { render, screen } from 'spec/helpers/testing-library';
 import userEvent from '@testing-library/user-event';
 import { Menu } from './Menu';
 import { dropdownItems } from './MenuRight';
 
-const user = {
-  createdOn: '2021-04-27T18:12:38.952304',
-  email: 'admin',
-  firstName: 'admin',
-  isActive: true,
-  lastName: 'admin',
-  permissions: {},
-  roles: {
-    Admin: [
-      ['can_sqllab', 'Superset'],
-      ['can_write', 'Dashboard'],
-      ['can_write', 'Chart'],
-    ],
-  },
-  userId: 1,
-  username: 'admin',
-};
-
 const mockedProps = {
-  user,
   data: {
     menu: [
       {
@@ -156,27 +136,17 @@ const notanonProps = {
   },
 };
 
-const useSelectorMock = jest.spyOn(reactRedux, 'useSelector');
-
-beforeEach(() => {
-  // setup a DOM element as a render target
-  useSelectorMock.mockClear();
-});
-
 test('should render', () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   const { container } = render(<Menu {...mockedProps} />);
   expect(container).toBeInTheDocument();
 });
 
 test('should render the navigation', () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   render(<Menu {...mockedProps} />);
   expect(screen.getByRole('navigation')).toBeInTheDocument();
 });
 
 test('should render the brand', () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   const {
     data: {
       brand: { alt, icon },
@@ -188,7 +158,6 @@ test('should render the brand', () => {
 });
 
 test('should render all the top navbar menu items', () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   const {
     data: { menu },
   } = mockedProps;
@@ -199,7 +168,6 @@ test('should render all the top navbar menu items', () => {
 });
 
 test('should render the top navbar child menu items', async () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   const {
     data: { menu },
   } = mockedProps;
@@ -216,7 +184,6 @@ test('should render the top navbar child menu items', async 
() => {
 });
 
 test('should render the dropdown items', async () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   render(<Menu {...notanonProps} />);
   const dropdown = screen.getByTestId('new-dropdown-icon');
   userEvent.hover(dropdown);
@@ -244,14 +211,12 @@ test('should render the dropdown items', async () => {
 });
 
 test('should render the Settings', async () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   render(<Menu {...mockedProps} />);
   const settings = await screen.findByText('Settings');
   expect(settings).toBeInTheDocument();
 });
 
 test('should render the Settings menu item', async () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   render(<Menu {...mockedProps} />);
   userEvent.hover(screen.getByText('Settings'));
   const label = await screen.findByText('Security');
@@ -259,7 +224,6 @@ test('should render the Settings menu item', async () => {
 });
 
 test('should render the Settings dropdown child menu items', async () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   const {
     data: { settings },
   } = mockedProps;
@@ -270,19 +234,16 @@ test('should render the Settings dropdown child menu 
items', async () => {
 });
 
 test('should render the plus menu (+) when user is not anonymous', () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   render(<Menu {...notanonProps} />);
   expect(screen.getByTestId('new-dropdown')).toBeInTheDocument();
 });
 
 test('should NOT render the plus menu (+) when user is anonymous', () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   render(<Menu {...mockedProps} />);
   expect(screen.queryByTestId('new-dropdown')).not.toBeInTheDocument();
 });
 
 test('should render the user actions when user is not anonymous', async () => {
-  useSelectorMock.mockReturnValue({ roles: mockedProps.user.roles });
   const {
     data: {
       navbar_right: { user_info_url, user_logout_url },
@@ -302,13 +263,11 @@ test('should render the user actions when user is not 
anonymous', async () => {
 });
 
 test('should NOT render the user actions when user is anonymous', () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   render(<Menu {...mockedProps} />);
   expect(screen.queryByText('User')).not.toBeInTheDocument();
 });
 
 test('should render the Profile link when available', async () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   const {
     data: {
       navbar_right: { user_profile_url },
@@ -323,7 +282,6 @@ test('should render the Profile link when available', async 
() => {
 });
 
 test('should render the About section and version_string, sha or build_number 
when available', async () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   const {
     data: {
       navbar_right: { version_sha, version_string, build_number },
@@ -343,7 +301,6 @@ test('should render the About section and version_string, 
sha or build_number wh
 });
 
 test('should render the Documentation link when available', async () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   const {
     data: {
       navbar_right: { documentation_url },
@@ -356,7 +313,6 @@ test('should render the Documentation link when available', 
async () => {
 });
 
 test('should render the Bug Report link when available', async () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   const {
     data: {
       navbar_right: { bug_report_url },
@@ -369,7 +325,6 @@ test('should render the Bug Report link when available', 
async () => {
 });
 
 test('should render the Login link when user is anonymous', () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   const {
     data: {
       navbar_right: { user_login_url },
@@ -382,13 +337,6 @@ test('should render the Login link when user is 
anonymous', () => {
 });
 
 test('should render the Language Picker', () => {
-  useSelectorMock.mockReturnValue({ roles: user.roles });
   render(<Menu {...mockedProps} />);
   expect(screen.getByLabelText('Languages')).toBeInTheDocument();
 });
-
-test('should hide create button without proper roles', () => {
-  useSelectorMock.mockReturnValue({ roles: [] });
-  render(<Menu {...notanonProps} />);
-  expect(screen.queryByTestId('new-dropdown')).not.toBeInTheDocument();
-});
diff --git a/superset-frontend/src/components/Menu/MenuRight.tsx 
b/superset-frontend/src/components/Menu/MenuRight.tsx
index 348bc46..1626713 100644
--- a/superset-frontend/src/components/Menu/MenuRight.tsx
+++ b/superset-frontend/src/components/Menu/MenuRight.tsx
@@ -21,9 +21,6 @@ import { MainNav as Menu } from 'src/common/components';
 import { t, styled, css, SupersetTheme } from '@superset-ui/core';
 import { Link } from 'react-router-dom';
 import Icons from 'src/components/Icons';
-import findPermission from 'src/dashboard/util/findPermission';
-import { useSelector } from 'react-redux';
-import { UserWithPermissionsAndRoles } from 'src/types/bootstrapTypes';
 import LanguagePicker from './LanguagePicker';
 import { NavBarProps, MenuObjectProps } from './Menu';
 
@@ -32,22 +29,16 @@ export const dropdownItems = [
     label: t('SQL query'),
     url: '/superset/sqllab?new=true',
     icon: 'fa-fw fa-search',
-    perm: 'can_sqllab',
-    view: 'Superset',
   },
   {
     label: t('Chart'),
     url: '/chart/add',
     icon: 'fa-fw fa-bar-chart',
-    perm: 'can_write',
-    view: 'Dashboard',
   },
   {
     label: t('Dashboard'),
     url: '/dashboard/new',
     icon: 'fa-fw fa-dashboard',
-    perm: 'can_write',
-    view: 'Chart',
   },
 ];
 
@@ -92,146 +83,134 @@ const RightMenu = ({
   settings,
   navbarRight,
   isFrontendRoute,
-}: RightMenuProps) => {
-  const { roles } = useSelector<any, UserWithPermissionsAndRoles>(
-    state => state.user,
-  );
-
-  // if user has any of these roles the dropdown will appear
-  const canSql = findPermission('can_sqllab', 'Superset', roles);
-  const canDashboard = findPermission('can_write', 'Dashboard', roles);
-  const canChart = findPermission('can_write', 'Chart', roles);
-  const showActionDropdown = canSql || canChart || canDashboard;
-  return (
-    <StyledDiv align={align}>
-      <Menu mode="horizontal">
-        {!navbarRight.user_is_anonymous && showActionDropdown && (
-          <SubMenu
-            data-test="new-dropdown"
-            title={
-              <StyledI data-test="new-dropdown-icon" className="fa fa-plus" />
-            }
-            icon={<Icons.TriangleDown />}
-          >
-            {dropdownItems.map(
-              menu =>
-                findPermission(menu.perm, menu.view, roles) && (
-                  <Menu.Item key={menu.label}>
-                    <a href={menu.url}>
-                      <i
-                        data-test={`menu-item-${menu.label}`}
-                        className={`fa ${menu.icon}`}
-                      />{' '}
-                      {menu.label}
-                    </a>
+}: RightMenuProps) => (
+  <StyledDiv align={align}>
+    <Menu mode="horizontal">
+      {!navbarRight.user_is_anonymous && (
+        <SubMenu
+          data-test="new-dropdown"
+          title={
+            <StyledI data-test="new-dropdown-icon" className="fa fa-plus" />
+          }
+          icon={<Icons.TriangleDown />}
+        >
+          {dropdownItems.map(menu => (
+            <Menu.Item key={menu.label}>
+              <a href={menu.url}>
+                <i
+                  data-test={`menu-item-${menu.label}`}
+                  className={`fa ${menu.icon}`}
+                />{' '}
+                {menu.label}
+              </a>
+            </Menu.Item>
+          ))}
+        </SubMenu>
+      )}
+      <SubMenu title="Settings" icon={<Icons.TriangleDown iconSize="xl" />}>
+        {settings.map((section, index) => [
+          <Menu.ItemGroup key={`${section.label}`} title={section.label}>
+            {section.childs?.map(child => {
+              if (typeof child !== 'string') {
+                return (
+                  <Menu.Item key={`${child.label}`}>
+                    {isFrontendRoute(child.url) ? (
+                      <Link to={child.url || ''}>{child.label}</Link>
+                    ) : (
+                      <a href={child.url}>{child.label}</a>
+                    )}
                   </Menu.Item>
-                ),
-            )}
-          </SubMenu>
-        )}
-        <SubMenu title="Settings" icon={<Icons.TriangleDown iconSize="xl" />}>
-          {settings.map((section, index) => [
-            <Menu.ItemGroup key={`${section.label}`} title={section.label}>
-              {section.childs?.map(child => {
-                if (typeof child !== 'string') {
-                  return (
-                    <Menu.Item key={`${child.label}`}>
-                      {isFrontendRoute(child.url) ? (
-                        <Link to={child.url || ''}>{child.label}</Link>
-                      ) : (
-                        <a href={child.url}>{child.label}</a>
-                      )}
-                    </Menu.Item>
-                  );
-                }
-                return null;
-              })}
-            </Menu.ItemGroup>,
-            index < settings.length - 1 && <Menu.Divider />,
-          ])}
+                );
+              }
+              return null;
+            })}
+          </Menu.ItemGroup>,
+          index < settings.length - 1 && <Menu.Divider />,
+        ])}
 
-          {!navbarRight.user_is_anonymous && [
-            <Menu.Divider key="user-divider" />,
-            <Menu.ItemGroup key="user-section" title={t('User')}>
-              {navbarRight.user_profile_url && (
-                <Menu.Item key="profile">
-                  <a href={navbarRight.user_profile_url}>{t('Profile')}</a>
-                </Menu.Item>
+        {!navbarRight.user_is_anonymous && [
+          <Menu.Divider key="user-divider" />,
+          <Menu.ItemGroup key="user-section" title={t('User')}>
+            {navbarRight.user_profile_url && (
+              <Menu.Item key="profile">
+                <a href={navbarRight.user_profile_url}>{t('Profile')}</a>
+              </Menu.Item>
+            )}
+            {navbarRight.user_info_url && (
+              <Menu.Item key="info">
+                <a href={navbarRight.user_info_url}>{t('Info')}</a>
+              </Menu.Item>
+            )}
+            <Menu.Item key="logout">
+              <a href={navbarRight.user_logout_url}>{t('Logout')}</a>
+            </Menu.Item>
+          </Menu.ItemGroup>,
+        ]}
+        {(navbarRight.version_string ||
+          navbarRight.version_sha ||
+          navbarRight.build_number) && [
+          <Menu.Divider key="version-info-divider" />,
+          <Menu.ItemGroup key="about-section" title={t('About')}>
+            <div className="about-section">
+              {navbarRight.show_watermark && (
+                <div css={versionInfoStyles}>
+                  {t('Powered by Apache Superset')}
+                </div>
               )}
-              {navbarRight.user_info_url && (
-                <Menu.Item key="info">
-                  <a href={navbarRight.user_info_url}>{t('Info')}</a>
-                </Menu.Item>
+              {navbarRight.version_string && (
+                <div css={versionInfoStyles}>
+                  Version: {navbarRight.version_string}
+                </div>
               )}
-              <Menu.Item key="logout">
-                <a href={navbarRight.user_logout_url}>{t('Logout')}</a>
-              </Menu.Item>
-            </Menu.ItemGroup>,
-          ]}
-          {(navbarRight.version_string || navbarRight.version_sha) && [
-            <Menu.Divider key="version-info-divider" />,
-            <Menu.ItemGroup key="about-section" title={t('About')}>
-              <div className="about-section">
-                {navbarRight.show_watermark && (
-                  <div css={versionInfoStyles}>
-                    {t('Powered by Apache Superset')}
-                  </div>
-                )}
-                {navbarRight.version_string && (
-                  <div css={versionInfoStyles}>
-                    Version: {navbarRight.version_string}
-                  </div>
-                )}
-                {navbarRight.version_sha && (
-                  <div css={versionInfoStyles}>
-                    SHA: {navbarRight.version_sha}
-                  </div>
-                )}
-                {navbarRight.build_number && (
-                  <div css={versionInfoStyles}>
-                    Build: {navbarRight.build_number}
-                  </div>
-                )}
-              </div>
-            </Menu.ItemGroup>,
-          ]}
-        </SubMenu>
-        {navbarRight.show_language_picker && (
-          <LanguagePicker
-            locale={navbarRight.locale}
-            languages={navbarRight.languages}
-          />
-        )}
-      </Menu>
-      {navbarRight.documentation_url && (
-        <StyledAnchor
-          href={navbarRight.documentation_url}
-          target="_blank"
-          rel="noreferrer"
-          title={t('Documentation')}
-        >
-          <i className="fa fa-question" />
-          &nbsp;
-        </StyledAnchor>
-      )}
-      {navbarRight.bug_report_url && (
-        <StyledAnchor
-          href={navbarRight.bug_report_url}
-          target="_blank"
-          rel="noreferrer"
-          title={t('Report a bug')}
-        >
-          <i className="fa fa-bug" />
-        </StyledAnchor>
-      )}
-      {navbarRight.user_is_anonymous && (
-        <StyledAnchor href={navbarRight.user_login_url}>
-          <i className="fa fa-fw fa-sign-in" />
-          {t('Login')}
-        </StyledAnchor>
+              {navbarRight.version_sha && (
+                <div css={versionInfoStyles}>
+                  SHA: {navbarRight.version_sha}
+                </div>
+              )}
+              {navbarRight.build_number && (
+                <div css={versionInfoStyles}>
+                  Build: {navbarRight.build_number}
+                </div>
+              )}
+            </div>
+          </Menu.ItemGroup>,
+        ]}
+      </SubMenu>
+      {navbarRight.show_language_picker && (
+        <LanguagePicker
+          locale={navbarRight.locale}
+          languages={navbarRight.languages}
+        />
       )}
-    </StyledDiv>
-  );
-};
+    </Menu>
+    {navbarRight.documentation_url && (
+      <StyledAnchor
+        href={navbarRight.documentation_url}
+        target="_blank"
+        rel="noreferrer"
+        title={t('Documentation')}
+      >
+        <i className="fa fa-question" />
+        &nbsp;
+      </StyledAnchor>
+    )}
+    {navbarRight.bug_report_url && (
+      <StyledAnchor
+        href={navbarRight.bug_report_url}
+        target="_blank"
+        rel="noreferrer"
+        title={t('Report a bug')}
+      >
+        <i className="fa fa-bug" />
+      </StyledAnchor>
+    )}
+    {navbarRight.user_is_anonymous && (
+      <StyledAnchor href={navbarRight.user_login_url}>
+        <i className="fa fa-fw fa-sign-in" />
+        {t('Login')}
+      </StyledAnchor>
+    )}
+  </StyledDiv>
+);
 
 export default RightMenu;
diff --git a/superset-frontend/src/views/menu.tsx 
b/superset-frontend/src/views/menu.tsx
index 68b72d7..35f6252 100644
--- a/superset-frontend/src/views/menu.tsx
+++ b/superset-frontend/src/views/menu.tsx
@@ -27,9 +27,6 @@ import { ThemeProvider } from '@superset-ui/core';
 import Menu from 'src/components/Menu/Menu';
 import { theme } from 'src/preamble';
 
-import { Provider } from 'react-redux';
-import { store } from './store';
-
 const container = document.getElementById('app');
 const bootstrapJson = container?.getAttribute('data-bootstrap') ?? '{}';
 const bootstrap = JSON.parse(bootstrapJson);
@@ -43,9 +40,7 @@ const app = (
   // @ts-ignore: emotion types defs are incompatible between core and cache
   <CacheProvider value={emotionCache}>
     <ThemeProvider theme={theme}>
-      <Provider store={store}>
-        <Menu data={menu} />
-      </Provider>
+      <Menu data={menu} />
     </ThemeProvider>
   </CacheProvider>
 );

Reply via email to