Skip to content
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: Show correct information on Modify Permissions tab #1498

Merged
merged 11 commits into from
Mar 8, 2022
4 changes: 1 addition & 3 deletions src/app/middleware/telemetryMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ const telemetryMiddleware =
componentNames.FETCH_PERMISSIONS_ACTION,
state.sampleQuery,
action.response.error,
{
HasRequestUrl: action.response.hasUrl
}
{}
);
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ const mockState: IRootState = {
},
scopes: {
pending: false,
data: [],
hasUrl: false,
data: {
fullPermissions: [],
specificPermissions: []
},
error: null
},
history: [],
Expand Down
32 changes: 14 additions & 18 deletions src/app/services/actions/permissions-action-creator.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {
FETCH_SCOPES_ERROR,
FETCH_SCOPES_PENDING,
FETCH_SCOPES_SUCCESS,
QUERY_GRAPH_STATUS
} from '../redux-constants';
QUERY_GRAPH_STATUS,
FETCH_FULL_SCOPES_SUCCESS
} from '../../../app/services/redux-constants';

import {
fetchScopesSuccess, fetchScopesPending, fetchScopesError, getPermissionsScopeType, fetchScopes,
fetchFullScopesSuccess, fetchScopesPending, fetchScopesError, getPermissionsScopeType, fetchScopes,
consentToScopes
} from
'./permissions-action-creator';
Expand Down Expand Up @@ -59,8 +59,10 @@ const mockState: IRootState = {
},
scopes: {
pending: false,
data: [],
hasUrl: false,
data: {
fullPermissions: [],
specificPermissions: []
},
error: null
},
history: [],
Expand Down Expand Up @@ -133,24 +135,19 @@ describe('tests permissions action creators', () => {
it('Tests if FETCH_SCOPES_SUCCESS is dispatched when fetchScopesSuccess is called', () => {
// Arrange
const response: IPermissionsResponse = {
hasUrl: true,
scopes: [
{
value: '',
consentDescription: '',
isAdmin: false,
consented: true
}
]
scopes: {
fullPermissions: [],
specificPermissions: []
}
}

const expectedAction = {
type: FETCH_SCOPES_SUCCESS,
type: FETCH_FULL_SCOPES_SUCCESS,
response
}

// Act
const action = fetchScopesSuccess(response);
const action = fetchFullScopesSuccess(response);

// Assert
expect(action).toEqual(expectedAction);
Expand All @@ -159,7 +156,6 @@ describe('tests permissions action creators', () => {
it('Tests if FETCH_SCOPES_ERROR is dispatched when fetchScopesError is called', () => {
// Arrange
const response = {
hasUrl: true,
error: {}
}

Expand Down
31 changes: 19 additions & 12 deletions src/app/services/actions/permissions-action-creator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import { ACCOUNT_TYPE, PERMS_SCOPE } from '../graph-constants';
import {
FETCH_SCOPES_ERROR,
FETCH_SCOPES_PENDING,
FETCH_SCOPES_SUCCESS
FETCH_FULL_SCOPES_SUCCESS,
FETCH_URL_SCOPES_SUCCESS
} from '../redux-constants';
import {
getAuthTokenSuccess,
Expand All @@ -23,13 +24,20 @@ import {
import { getProfileInfo } from './profile-action-creators';
import { setQueryResponseStatus } from './query-status-action-creator';

export function fetchScopesSuccess(response: object): IAction {
export function fetchFullScopesSuccess(response: object): IAction {
return {
type: FETCH_SCOPES_SUCCESS,
type: FETCH_FULL_SCOPES_SUCCESS,
response
};
}

export function fetchUrlScopesSuccess(response: Object): IAction {
return {
type: FETCH_URL_SCOPES_SUCCESS,
response
}
}

export function fetchScopesPending(): any {
return {
type: FETCH_SCOPES_PENDING
Expand All @@ -45,7 +53,6 @@ export function fetchScopesError(response: object): IAction {

export function fetchScopes(): Function {
return async (dispatch: Function, getState: Function) => {
let hasUrl = false; // whether permissions are for a specific url
try {
const { devxApi, permissionsPanelOpen, profile, sampleQuery: query }: IRootState = getState();
let permissionsUrl = `${devxApi.baseUrl}/permissions`;
Expand All @@ -62,7 +69,6 @@ export function fetchScopes(): Function {

// eslint-disable-next-line max-len
permissionsUrl = `${permissionsUrl}?requesturl=/${requestUrl}&method=${query.selectedVerb}&scopeType=${scopeType}`;
hasUrl = true;
}

if (devxApi.parameters) {
Expand All @@ -81,18 +87,19 @@ export function fetchScopes(): Function {
const response = await fetch(permissionsUrl, options);
if (response.ok) {
const scopes = await response.json();
return dispatch(
fetchScopesSuccess({
hasUrl,
scopes
})
);

return permissionsPanelOpen ? dispatch(fetchFullScopesSuccess({
scopes: { fullPermissions: scopes }
})) :
dispatch(fetchUrlScopesSuccess({
scopes: { specificPermissions: scopes }
}));
}

throw response;
} catch (error) {
return dispatch(
fetchScopesError({
hasUrl,
error
})
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@ const mockState: IRootState = {
},
scopes: {
pending: false,
data: [],
hasUrl: false,
data: {
fullPermissions: [],
specificPermissions: []
},
error: null
},
history: [],
Expand Down
61 changes: 48 additions & 13 deletions src/app/services/reducers/permissions-reducer.spec.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,76 @@
import { scopes } from '../../../app/services/reducers/permissions-reducer';
import { FETCH_SCOPES_ERROR, FETCH_SCOPES_PENDING, FETCH_SCOPES_SUCCESS } from '../../../app/services/redux-constants';
import {
FETCH_SCOPES_ERROR, FETCH_SCOPES_PENDING,
FETCH_FULL_SCOPES_SUCCESS,
FETCH_URL_SCOPES_SUCCESS
} from '../../../app/services/redux-constants';

const initialState = {
pending: false,
data: [],
hasUrl: false,
data: {
fullPermissions: [],
specificPermissions: []
},
error: null
};

describe('Permissions reducer', () => {
it('should handle FETCH_SCOPES_SUCCESS', () => {
it('should handle FETCH_FULL_SCOPES_SUCCESS', () => {
const action = {
type: FETCH_SCOPES_SUCCESS,
type: FETCH_FULL_SCOPES_SUCCESS,
response: {
hasUrl: false,
scopes: ['profile.read', 'profile.write', 'email.read', 'email.write']
scopes: {
specificPermissions: [],
fullPermissions: ['profile.read', 'profile.write', 'email.read', 'email.write']
}
}
}

const expectedState = {
pending: false,
data: ['profile.read', 'profile.write', 'email.read', 'email.write'],
hasUrl: false,
data: {
fullPermissions: ['profile.read', 'profile.write', 'email.read', 'email.write'],
specificPermissions: []
},
error: null
}

const newState = scopes(initialState, action);
expect(newState).toEqual(expectedState);
});

it('should handle FETCH_URL_SCOPES_SUCCESS', () => {
const action = {
type: FETCH_URL_SCOPES_SUCCESS,
response: {
scopes: {
specificPermissions: ['profile.read', 'profile.write', 'email.read', 'email.write'],
fullPermissions: []
}
}
}

const expectedState = {
pending: false,
data: {
fullPermissions: [],
specificPermissions: ['profile.read', 'profile.write', 'email.read', 'email.write']
},
error: null
}

const newState = scopes(initialState, action);
expect(newState).toEqual(expectedState);
})

it('should handle FETCH_SCOPES_ERROR', () => {
const action = {
type: FETCH_SCOPES_ERROR,
response: 'error'
}
const expectedState = {
pending: false,
data: [],
hasUrl: false,
data: {},
error: 'error'
}

Expand All @@ -53,8 +86,10 @@ describe('Permissions reducer', () => {

const expectedState = {
pending: true,
data: [],
hasUrl: false,
data: {
fullPermissions: [],
specificPermissions: []
},
error: null
}

Expand Down
33 changes: 21 additions & 12 deletions src/app/services/reducers/permissions-reducer.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,46 @@
import { IAction } from '../../../types/action';
import { IPermissionsResponse, IScopes } from '../../../types/permissions';
import { FETCH_SCOPES_ERROR, FETCH_SCOPES_PENDING, FETCH_SCOPES_SUCCESS } from '../redux-constants';
import {
FETCH_SCOPES_ERROR, FETCH_SCOPES_PENDING, FETCH_FULL_SCOPES_SUCCESS,
FETCH_URL_SCOPES_SUCCESS
} from '../redux-constants';

const initialState: IScopes = {
pending: false,
data: [],
hasUrl: false,
data: {
specificPermissions: [],
fullPermissions: []
},
error: null
};

export function scopes(state: IScopes = initialState, action: IAction): any {
switch (action.type) {
case FETCH_SCOPES_SUCCESS:
const response: IPermissionsResponse = { ...action.response as IPermissionsResponse };
case FETCH_FULL_SCOPES_SUCCESS:
let response: IPermissionsResponse = { ...action.response as IPermissionsResponse };
return {
pending: false,
data: response.scopes,
hasUrl: response.hasUrl,
data: { ...state.data, fullPermissions: response.scopes.fullPermissions },
error: null
};
case FETCH_URL_SCOPES_SUCCESS:
response = { ...action.response as IPermissionsResponse };
return {
pending: false,
data: { ...state.data, specificPermissions: response.scopes.specificPermissions },
error: null
}
case FETCH_SCOPES_ERROR:
return {
pending: false,
error: action.response,
hasUrl: false,
data: []
data: {}
};
case FETCH_SCOPES_PENDING:
return {
pending: true,
data: [],
error: null,
hasUrl: false
data: state.data,
error: null
};
default:
return state;
Expand Down
3 changes: 2 additions & 1 deletion src/app/services/redux-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export const FETCH_ADAPTIVE_CARD_SUCCESS = 'FETCH_ADAPTIVE_CARD_SUCCESS';
export const FETCH_ADAPTIVE_CARD_PENDING = 'FETCH_ADAPTIVE_CARD_PENDING';
export const FETCH_ADAPTIVE_CARD_ERROR = 'FETCH_ADAPTIVE_CARD_ERROR';
export const CLEAR_TERMS_OF_USE = 'CLEAR_TERMS_OF_USE';
export const FETCH_SCOPES_SUCCESS = 'SCOPES_FETCH_SUCCESS';
export const FETCH_FULL_SCOPES_SUCCESS = 'FULL_SCOPES_FETCH_SUCCESS';
export const FETCH_URL_SCOPES_SUCCESS = 'FETCH_URL_SCOPES_SUCCESS';
export const FETCH_SCOPES_ERROR = 'SCOPES_FETCH_ERROR';
export const FETCH_SCOPES_PENDING = 'FETCH_SCOPES_PENDING';
export const GET_CONSENT_ERROR = 'GET_CONSENT_ERROR';
Expand Down
15 changes: 10 additions & 5 deletions src/app/views/query-runner/request/permissions/PanelList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,13 @@ const PanelList = ({ messages,
columns, classes, selection,
renderItemColumn, renderDetailsHeader, renderCustomCheckbox }: IPanelList) => {

const sortedPermissions = (permissionsToSort: IPermission[]) : IPermission[] => {
return permissionsToSort.sort(dynamicSort('value', SortOrder.ASC));
}

const { consentedScopes, scopes, authToken } = useSelector((state: IRootState) => state);
const [permissions, setPermissions] = useState(scopes.data.sort(dynamicSort('value', SortOrder.ASC)));
const { fullPermissions } = scopes.data;
const [permissions, setPermissions] = useState(sortedPermissions(fullPermissions));
const permissionsList: any[] = [];
const tokenPresent = !!authToken.token;

Expand All @@ -50,11 +55,11 @@ const PanelList = ({ messages,
});

const searchValueChanged = (event: any, value?: string): void => {
let filteredPermissions = scopes.data;
let filteredPermissions = scopes.data.fullPermissions;
if (value) {
const keyword = value.toLowerCase();

filteredPermissions = scopes.data.filter((permission: IPermission) => {
filteredPermissions = fullPermissions.filter((permission: IPermission) => {
const name = permission.value.toLowerCase();
return name.includes(keyword);
});
Expand All @@ -65,7 +70,7 @@ const PanelList = ({ messages,
const groups = generateGroupsFromList(permissionsList, 'groupName');


const _onRenderGroupHeader = (props: any): any => {
const onRenderGroupHeader = (props: any): any => {
if (props) {
return (
<GroupHeader {...props} onRenderGroupHeaderCheckbox={renderCustomCheckbox} />
Expand Down Expand Up @@ -101,7 +106,7 @@ const PanelList = ({ messages,
compact={true}
groupProps={{
showEmptyGroups: false,
onRenderHeader: _onRenderGroupHeader
onRenderHeader: onRenderGroupHeader
}}
ariaLabelForSelectionColumn={messages['Toggle selection'] || 'Toggle selection'}
ariaLabelForSelectAllCheckbox={messages['Toggle selection for all items'] || 'Toggle selection for all items'}
Expand Down
Loading