From 28d03c6d9ec400f168a27f6c88b0f15efc2fb3e3 Mon Sep 17 00:00:00 2001 From: Khac Vy Date: Fri, 26 Jun 2020 17:44:16 +0700 Subject: [PATCH] feat: #1848 filter app lists when using the marketplace in Developer Edition (#1851) * feat: #1848 filter app lists when using the marketplace in Developer Edition --- .../src/__mocks__/cognito-session.ts | 1 + packages/cognito-auth/src/core/types.ts | 1 + .../cognito-auth/src/utils/cognito.test.ts | 2 + packages/cognito-auth/src/utils/cognito.ts | 1 + .../src/context/__mocks__/mock-context.tsx | 1 + .../developer-app-revision-modal.test.tsx | 1 + packages/marketplace/src/constants/api.ts | 2 + .../marketplace/src/core/__mocks__/store.ts | 2 + .../src/reducers/__stubs__/app-state.ts | 2 + .../marketplace/src/sagas/__tests__/client.ts | 8 +++- .../src/sagas/__tests__/installed-apps.ts | 7 +++- .../src/sagas/__tests__/my-apps.ts | 14 +++++-- packages/marketplace/src/sagas/client.ts | 4 +- .../marketplace/src/sagas/installed-apps.ts | 5 ++- packages/marketplace/src/sagas/my-apps.ts | 5 ++- .../src/selector/__tests__/client.ts | 37 +++++++++++++++++++ packages/marketplace/src/selector/client.ts | 15 ++++++++ .../src/context/__mocks__/mock-context.tsx | 1 + .../src/context/__mocks__/mock-context.tsx | 1 + .../src/context/__mocks__/mock-context.ts | 1 + 20 files changed, 99 insertions(+), 12 deletions(-) diff --git a/packages/cognito-auth/src/__mocks__/cognito-session.ts b/packages/cognito-auth/src/__mocks__/cognito-session.ts index 275311d369..f97fd83612 100644 --- a/packages/cognito-auth/src/__mocks__/cognito-session.ts +++ b/packages/cognito-auth/src/__mocks__/cognito-session.ts @@ -38,6 +38,7 @@ export const mockLoginSession: LoginSession = { userCode: 'SOME_USER_CODE', isAdmin: false, userTel: '123', + groups: [], }, } diff --git a/packages/cognito-auth/src/core/types.ts b/packages/cognito-auth/src/core/types.ts index 203c3862df..3696992c85 100644 --- a/packages/cognito-auth/src/core/types.ts +++ b/packages/cognito-auth/src/core/types.ts @@ -52,6 +52,7 @@ export interface LoginIdentity { userCode: string | null isAdmin?: boolean userTel: string + groups: string[] } export interface LoginSession { diff --git a/packages/cognito-auth/src/utils/cognito.test.ts b/packages/cognito-auth/src/utils/cognito.test.ts index 64d316f609..62c7ac5e85 100644 --- a/packages/cognito-auth/src/utils/cognito.test.ts +++ b/packages/cognito-auth/src/utils/cognito.test.ts @@ -180,6 +180,7 @@ describe('Session utils', () => { name: 'SOME_NAME', userCode: 'SOME_USER_CODE', isAdmin: true, + groups: ['CustomerAdministrators'], }) }) @@ -192,6 +193,7 @@ describe('Session utils', () => { name: undefined, userCode: null, isAdmin: false, + groups: [], }) }) }) diff --git a/packages/cognito-auth/src/utils/cognito.ts b/packages/cognito-auth/src/utils/cognito.ts index 6dcd50216f..e455e2f597 100644 --- a/packages/cognito-auth/src/utils/cognito.ts +++ b/packages/cognito-auth/src/utils/cognito.ts @@ -116,6 +116,7 @@ export const deserializeIdToken = (loginSession: Partial | undefin userCode: decoded['custom:reapit:userCode'] || null, isAdmin: Boolean(decoded['cognito:groups']?.includes('CustomerAdministrators')), userTel: decoded['phone_number'], + groups: decoded['cognito:groups'] || [], } } diff --git a/packages/geo-diary-v2/src/context/__mocks__/mock-context.tsx b/packages/geo-diary-v2/src/context/__mocks__/mock-context.tsx index 045fdf668d..8e1a2ba2db 100644 --- a/packages/geo-diary-v2/src/context/__mocks__/mock-context.tsx +++ b/packages/geo-diary-v2/src/context/__mocks__/mock-context.tsx @@ -16,6 +16,7 @@ export const mockContext = { adminId: 'mockAdminID', userCode: 'mockUserCode', userTel: 'mockTel', + groups: [], }, loginType: 'CLIENT', cognitoClientId: '123', diff --git a/packages/marketplace/src/components/ui/developer-app-revision-modal/__test__/developer-app-revision-modal.test.tsx b/packages/marketplace/src/components/ui/developer-app-revision-modal/__test__/developer-app-revision-modal.test.tsx index 6e6de0917e..b05d294a8d 100644 --- a/packages/marketplace/src/components/ui/developer-app-revision-modal/__test__/developer-app-revision-modal.test.tsx +++ b/packages/marketplace/src/components/ui/developer-app-revision-modal/__test__/developer-app-revision-modal.test.tsx @@ -101,6 +101,7 @@ describe('DeveloperAppRevisionModal', () => { userCode: 'mockUserCode', isAdmin: false, userTel: '123', + groups: [], } const fn = handleCancelPendingRevisionsButtonClick(spyDispatch, appId, appRevisionId, loginIdentity) fn() diff --git a/packages/marketplace/src/constants/api.ts b/packages/marketplace/src/constants/api.ts index 7fa410089e..2b427d6e66 100644 --- a/packages/marketplace/src/constants/api.ts +++ b/packages/marketplace/src/constants/api.ts @@ -8,3 +8,5 @@ export const COGNITO_HEADERS = { } as StringMap export const SANDBOX_CLIENT_ID = 'SBOX' + +export const COGNITO_GROUP_DEVELOPER_EDITION = 'AgencyCloudDeveloperEdition' diff --git a/packages/marketplace/src/core/__mocks__/store.ts b/packages/marketplace/src/core/__mocks__/store.ts index 6e2444f75a..4b7321769b 100644 --- a/packages/marketplace/src/core/__mocks__/store.ts +++ b/packages/marketplace/src/core/__mocks__/store.ts @@ -1,4 +1,5 @@ import { RefreshParams, LoginSession } from '@reapit/cognito-auth' +import { COGNITO_GROUP_DEVELOPER_EDITION } from '@/constants/api' export const mockLoginSession: LoginSession = { userName: 'bob@acme.com', @@ -19,6 +20,7 @@ export const mockLoginSession: LoginSession = { userCode: 'SOME_USER_CODE', isAdmin: false, userTel: '123', + groups: [COGNITO_GROUP_DEVELOPER_EDITION], }, } diff --git a/packages/marketplace/src/reducers/__stubs__/app-state.ts b/packages/marketplace/src/reducers/__stubs__/app-state.ts index 4f201eaaa5..e7db7836a8 100644 --- a/packages/marketplace/src/reducers/__stubs__/app-state.ts +++ b/packages/marketplace/src/reducers/__stubs__/app-state.ts @@ -1,4 +1,5 @@ import { ReduxState } from '@/types/core' +import { COGNITO_GROUP_DEVELOPER_EDITION } from '@/constants/api' const appState: ReduxState = { client: { @@ -66,6 +67,7 @@ const appState: ReduxState = { adminId: null, userCode: 'testUserCode', userTel: '123', + groups: [COGNITO_GROUP_DEVELOPER_EDITION], }, }, isTermAccepted: false, diff --git a/packages/marketplace/src/sagas/__tests__/client.ts b/packages/marketplace/src/sagas/__tests__/client.ts index ae114ad55a..c90eab3b62 100644 --- a/packages/marketplace/src/sagas/__tests__/client.ts +++ b/packages/marketplace/src/sagas/__tests__/client.ts @@ -9,7 +9,7 @@ import { APPS_PER_PAGE } from '@/constants/paginator' import { Action } from '@/types/core' import { errorThrownServer } from '@/actions/error' import errorMessages from '@/constants/error-messages' -import { selectClientId, selectFeaturedApps } from '@/selector/client' +import { selectClientId, selectFeaturedApps, selectDeveloperEditionId } from '@/selector/client' import { selectCategories } from '@/selector/app-categories' import { PagedResultCategoryModel_, @@ -25,6 +25,7 @@ jest.mock('@reapit/elements') const params = { data: { page: 1, search: 'app1', category: 'category1', searchBy: 'appName' } } const clientId = 'DXX' +const developerId = '1234' describe('clientDataFetch', () => { const gen = cloneableGenerator(clientDataFetch as any)(params) @@ -34,11 +35,14 @@ describe('clientDataFetch', () => { expect(clone.next().value).toEqual(select(selectClientId)) expect(clone.next(clientId).value).toEqual(select(selectCategories)) expect(clone.next(appCategorieStub.data).value).toEqual(select(selectFeaturedApps)) + expect(clone.next(featuredAppsDataStub.data).value).toEqual(select(selectDeveloperEditionId)) + const response = [appsDataStub.data, featuredAppsDataStub.data, appCategorieStub] - expect(clone.next(featuredAppsDataStub.data).value).toEqual( + expect(clone.next(developerId).value).toEqual( all([ call(fetchAppsList, { clientId, + developerId: [developerId], category: params.data.category as any, appName: params.data.search, pageNumber: params.data.page, diff --git a/packages/marketplace/src/sagas/__tests__/installed-apps.ts b/packages/marketplace/src/sagas/__tests__/installed-apps.ts index d22bce2797..fb22d4454f 100644 --- a/packages/marketplace/src/sagas/__tests__/installed-apps.ts +++ b/packages/marketplace/src/sagas/__tests__/installed-apps.ts @@ -11,7 +11,7 @@ import { Action } from '@/types/core' import { cloneableGenerator } from '@redux-saga/testing-utils' import { errorThrownServer } from '@/actions/error' import errorMessages from '@/constants/error-messages' -import { selectClientId } from '@/selector/client' +import { selectClientId, selectDeveloperEditionId } from '@/selector/client' import { fetchAppsList } from '@/services/apps' import { INSTALLED_APPS_PERPAGE } from '@/constants/paginator' @@ -23,12 +23,15 @@ const params = { data: 1 } describe('installed-apps fetch data', () => { const gen = cloneableGenerator(installedAppsDataFetch)(params) const clientId = 'DAC' + const developerId = '1234' expect(gen.next().value).toEqual(put(installedAppsLoading(true))) expect(gen.next().value).toEqual(select(selectClientId)) - expect(gen.next(clientId).value).toEqual( + expect(gen.next(clientId).value).toEqual(select(selectDeveloperEditionId)) + expect(gen.next(developerId).value).toEqual( call(fetchAppsList, { clientId, + developerId: [developerId], pageNumber: params.data, pageSize: INSTALLED_APPS_PERPAGE, onlyInstalled: true, diff --git a/packages/marketplace/src/sagas/__tests__/my-apps.ts b/packages/marketplace/src/sagas/__tests__/my-apps.ts index 797a60ac39..ccf73b8c5f 100644 --- a/packages/marketplace/src/sagas/__tests__/my-apps.ts +++ b/packages/marketplace/src/sagas/__tests__/my-apps.ts @@ -7,7 +7,7 @@ import { Action } from '@/types/core' import { cloneableGenerator } from '@redux-saga/testing-utils' import { APPS_PER_PAGE } from '@/constants/paginator' import errorMessages from '@/constants/error-messages' -import { selectClientId } from '@/selector/client' +import { selectClientId, selectDeveloperEditionId } from '@/selector/client' import { errorThrownServer } from '@/actions/error' import { fetchAppsList } from '@/services/apps' @@ -18,11 +18,19 @@ const params = { data: 1 } describe('my-apps fetch data', () => { const gen = cloneableGenerator(myAppsDataFetch)(params) const clientId = 'DAC' + const developerId = '1234' expect(gen.next().value).toEqual(put(myAppsLoading(true))) expect(gen.next().value).toEqual(select(selectClientId)) - expect(gen.next(clientId).value).toEqual( - call(fetchAppsList, { clientId, onlyInstalled: true, pageNumber: params.data, pageSize: APPS_PER_PAGE }), + expect(gen.next(clientId).value).toEqual(select(selectDeveloperEditionId)) + expect(gen.next(developerId).value).toEqual( + call(fetchAppsList, { + clientId, + developerId: [developerId], + onlyInstalled: true, + pageNumber: params.data, + pageSize: APPS_PER_PAGE, + }), ) test('api call success', () => { diff --git a/packages/marketplace/src/sagas/client.ts b/packages/marketplace/src/sagas/client.ts index 1d2c330536..997122d421 100644 --- a/packages/marketplace/src/sagas/client.ts +++ b/packages/marketplace/src/sagas/client.ts @@ -6,7 +6,7 @@ import { errorThrownServer } from '../actions/error' import errorMessages from '../constants/error-messages' import { APPS_PER_PAGE, FEATURED_APPS } from '@/constants/paginator' import { Action } from '@/types/core' -import { selectClientId, selectFeaturedApps } from '@/selector/client' +import { selectClientId, selectFeaturedApps, selectDeveloperEditionId } from '@/selector/client' import { selectCategories } from '@/selector/app-categories' import { ClientAppSummary, ClientAppSummaryParams } from '@/reducers/client/app-summary' import { logger } from '@reapit/utils' @@ -24,6 +24,7 @@ export const clientDataFetch = function*({ data }) { } const currentCategories = yield select(selectCategories) const currentFeaturedApps = yield select(selectFeaturedApps) + const developerId = yield select(selectDeveloperEditionId) // because the https://dev.platformmarketplace.reapit.net/categories endpoint does not return a filter for Direct API so // we will have to manually check it here @@ -33,6 +34,7 @@ export const clientDataFetch = function*({ data }) { const [apps, featuredApps, categories] = yield all([ call(fetchAppsList, { clientId, + developerId: developerId ? [developerId] : [], category: isFilteringForDirectApiApps ? undefined : category, [searchBy]: search, pageNumber: page, diff --git a/packages/marketplace/src/sagas/installed-apps.ts b/packages/marketplace/src/sagas/installed-apps.ts index 73468a18be..4e51bec42e 100644 --- a/packages/marketplace/src/sagas/installed-apps.ts +++ b/packages/marketplace/src/sagas/installed-apps.ts @@ -9,7 +9,7 @@ import { errorThrownServer } from '../actions/error' import errorMessages from '../constants/error-messages' import { Action } from '@/types/core' import { INSTALLED_APPS_PERPAGE } from '@/constants/paginator' -import { selectClientId } from '@/selector/client' +import { selectClientId, selectDeveloperEditionId } from '@/selector/client' import { logger } from '@reapit/utils' import { fetchAppsList } from '@/services/apps' @@ -21,9 +21,10 @@ export const installedAppsDataFetch = function*({ data: page }) { if (!clientId) { return } - + const developerId = yield select(selectDeveloperEditionId) const response = yield call(fetchAppsList, { clientId, + developerId: developerId ? [developerId] : [], pageNumber: page, pageSize: INSTALLED_APPS_PERPAGE, onlyInstalled: true, diff --git a/packages/marketplace/src/sagas/my-apps.ts b/packages/marketplace/src/sagas/my-apps.ts index 4693ac8b23..d85ff0c781 100644 --- a/packages/marketplace/src/sagas/my-apps.ts +++ b/packages/marketplace/src/sagas/my-apps.ts @@ -5,7 +5,7 @@ import { errorThrownServer } from '../actions/error' import errorMessages from '../constants/error-messages' import { Action } from '@/types/core' import { APPS_PER_PAGE } from '@/constants/paginator' -import { selectClientId } from '@/selector/client' +import { selectClientId, selectDeveloperEditionId } from '@/selector/client' import { logger } from '@reapit/utils' import { fetchAppsList } from '@/services/apps' @@ -17,9 +17,10 @@ export const myAppsDataFetch = function*({ data: page }) { if (!clientId) { return } - + const developerId = yield select(selectDeveloperEditionId) const response = yield call(fetchAppsList, { clientId, + developerId: developerId ? [developerId] : [], onlyInstalled: true, pageNumber: page, pageSize: APPS_PER_PAGE, diff --git a/packages/marketplace/src/selector/__tests__/client.ts b/packages/marketplace/src/selector/__tests__/client.ts index b73ce36ceb..a5b83fb564 100644 --- a/packages/marketplace/src/selector/__tests__/client.ts +++ b/packages/marketplace/src/selector/__tests__/client.ts @@ -1,6 +1,7 @@ import { ReduxState } from '@/types/core' import { selectClientId, + selectDeveloperEditionId, selectLoggedUserEmail, selectFeaturedApps, selectWebComponentOpen, @@ -37,6 +38,42 @@ describe('selectClientId', () => { }) }) +describe('selectDeveloperEditionId', () => { + it('should run correctly when user in AgencyCloudDeveloperEdition group', () => { + const input = { + auth: { + loginSession: { + loginIdentity: { + clientId: '123', + email: 'abc@gmail.com', + developerId: '1234', + groups: ['AgencyCloudDeveloperEdition'], + }, + }, + }, + } as ReduxState + const result = selectDeveloperEditionId(input) + expect(result).toEqual('1234') + }) + + it('should run correctly when user NOT in AgencyCloudDeveloperEdition group', () => { + const input = { + auth: { + loginSession: { + loginIdentity: { + clientId: '123', + email: 'abc@gmail.com', + developerId: '1234', + groups: [''], + }, + }, + }, + } as ReduxState + const result = selectDeveloperEditionId(input) + expect(result).toEqual(null) + }) +}) + describe('selectLoggedUserEmail', () => { it('should run correctly', () => { const input = { diff --git a/packages/marketplace/src/selector/client.ts b/packages/marketplace/src/selector/client.ts index c00a056568..7c274f7f80 100644 --- a/packages/marketplace/src/selector/client.ts +++ b/packages/marketplace/src/selector/client.ts @@ -6,11 +6,26 @@ import { WebComponentConfigResult } from '@/services/web-component' import { InstalledAppsState } from '@/reducers/installed-apps' import { AppSummaryModel } from '@reapit/foundations-ts-definitions' import { ClientAppSummaryState } from '@/reducers/client/app-summary' +import { selectLoginIdentity } from '@/selector/auth' +import { COGNITO_GROUP_DEVELOPER_EDITION } from '@/constants/api' export const selectClientId = (state: ReduxState) => { return state?.auth?.loginSession?.loginIdentity?.clientId || '' } +/** + * Need get developer id to filter apps list if this user belong to + * AgencyCloudDeveloperEdition group, if not just return null + * refer to this ticket https://github.com/reapit/foundations/issues/1848 + */ +export const selectDeveloperEditionId = (state: ReduxState) => { + const loginIdentity = selectLoginIdentity(state) + if (loginIdentity?.groups.includes(COGNITO_GROUP_DEVELOPER_EDITION)) { + return state?.auth?.loginSession?.loginIdentity?.developerId || '' + } + return null +} + export const selectLoggedUserEmail = (state: ReduxState): string => { return state?.auth?.loginSession?.loginIdentity?.email || '' } diff --git a/packages/react-app-scaffolder/app/templates/apollo/src/context/__mocks__/mock-context.tsx b/packages/react-app-scaffolder/app/templates/apollo/src/context/__mocks__/mock-context.tsx index 81d6808802..2d737f68d2 100644 --- a/packages/react-app-scaffolder/app/templates/apollo/src/context/__mocks__/mock-context.tsx +++ b/packages/react-app-scaffolder/app/templates/apollo/src/context/__mocks__/mock-context.tsx @@ -16,6 +16,7 @@ export const mockContext = { adminId: 'mockAdminID', userCode: 'mockUserCode', userTel: 'mockUserTel', + groups: [], }, loginType: 'CLIENT', cognitoClientId: 'mockCognitoClientId', diff --git a/packages/site-builder/src/context/__mocks__/mock-context.tsx b/packages/site-builder/src/context/__mocks__/mock-context.tsx index 648e9ae6c3..1b574da466 100644 --- a/packages/site-builder/src/context/__mocks__/mock-context.tsx +++ b/packages/site-builder/src/context/__mocks__/mock-context.tsx @@ -16,6 +16,7 @@ export const mockContext = { adminId: 'mockAdminID', userCode: 'mockUserCode', userTel: '0799999999', + groups: [], }, loginType: 'CLIENT', cognitoClientId: '123', diff --git a/packages/smb-onboarder/src/context/__mocks__/mock-context.ts b/packages/smb-onboarder/src/context/__mocks__/mock-context.ts index 7a735a239c..d1f93c4594 100644 --- a/packages/smb-onboarder/src/context/__mocks__/mock-context.ts +++ b/packages/smb-onboarder/src/context/__mocks__/mock-context.ts @@ -16,6 +16,7 @@ export const mockContext = { adminId: 'mockAdminID', userCode: 'mockUserCode', userTel: 'mockTel', + groups: [], }, loginType: 'CLIENT', cognitoClientId: 'mockCognitoClientId',