Skip to content

Commit

Permalink
chore!: Update private apps cap on Community Edition (#33399)
Browse files Browse the repository at this point in the history
* chore!: update private apps cap on CE

---------

Co-authored-by: Tasso <tasso.evangelista@rocket.chat>
  • Loading branch information
2 people authored and ggazzo committed Oct 11, 2024
1 parent 5e73ae8 commit 874f70e
Show file tree
Hide file tree
Showing 24 changed files with 172 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ const AppStatus = ({ app, showStatus = true, isAppDetailsPage, installed, ...pro

{statuses?.map((status, index) => (
<Margins inlineEnd={index !== statuses.length - 1 ? 8 : undefined} key={index}>
<Tag variant={getStatusVariant(status)} title={status.tooltipText ? status.tooltipText : ''}>
<Tag data-qa-type='app-status-tag' variant={getStatusVariant(status)} title={status.tooltipText ? status.tooltipText : ''}>
{handleAppRequestsNumber(status)} {t(`${status.label}` as TranslationKey)}
</Tag>
</Margins>
Expand Down
1 change: 1 addition & 0 deletions apps/meteor/client/views/marketplace/AppsList/AppRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const AppRow = ({ className, ...props }: App & { className?: string }): ReactEle
return (
<div role='listitem' className={className} key={id}>
<Card
data-qa-type='app-row'
horizontal
clickable
role='link'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const AppInstallationModal = ({
<Modal>
<Modal.Header>
<Modal.HeaderText>
<Modal.Title>{getTitle()}</Modal.Title>
<Modal.Title data-qa-id='confirm-app-upload-modal-title'>{getTitle()}</Modal.Title>
</Modal.HeaderText>
<Modal.Close onClick={handleClose} />
</Modal.Header>
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/client/views/marketplace/hooks/useAppMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ export const useAppMenu = (app: App, isAppDetailsPage: boolean) => {
const doesItReachedTheLimit =
!app.migrated &&
!appCountQuery?.data?.hasUnlimitedApps &&
!!appCountQuery?.data?.enabled &&
appCountQuery?.data?.enabled !== undefined &&
appCountQuery?.data?.enabled >= appCountQuery?.data?.limit;

const installedAppOptions = [
Expand Down
2 changes: 2 additions & 0 deletions apps/meteor/tests/e2e/apps/apps-contextualbar.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import type { Page } from '@playwright/test';

import { IS_EE } from '../config/constants';
import { Users } from '../fixtures/userStates';
import { HomeChannel } from '../page-objects';
import { expect, test } from '../utils/test';

test.use({ storageState: Users.user1.state });

test.describe.serial('Apps > ContextualBar', () => {
test.skip(!IS_EE, 'Premium Only');
let poHomeChannel: HomeChannel;

let page: Page;
Expand Down
2 changes: 2 additions & 0 deletions apps/meteor/tests/e2e/apps/apps-modal.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Page } from '@playwright/test';

import { IS_EE } from '../config/constants';
import { Users } from '../fixtures/userStates';
import { HomeChannel } from '../page-objects';
import { Modal } from '../page-objects/modal';
Expand All @@ -8,6 +9,7 @@ import { expect, test } from '../utils/test';
test.use({ storageState: Users.user1.state });

test.describe.serial('Apps > Modal', () => {
test.skip(!IS_EE, 'Premium Only');
let poHomeChannel: HomeChannel;
let poModal: Modal;

Expand Down
70 changes: 70 additions & 0 deletions apps/meteor/tests/e2e/apps/private-apps-upload.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { IS_EE } from '../config/constants';
import { Users } from '../fixtures/userStates';
import { Marketplace } from '../page-objects';
import { expect, test } from '../utils/test';

test.use({ storageState: Users.admin.state });

test.describe.serial('Private apps upload', () => {
let poMarketplace: Marketplace;

test.beforeEach(async ({ page }) => {
poMarketplace = new Marketplace(page);

await page.goto('/marketplace/private');
});

test.describe('Premium', () => {
test.skip(!IS_EE, 'Premium Only');

test('expect to allow admin to upload a private app in EE, which should be enabled by default', async ({ page }) => {
const fileChooserPromise = page.waitForEvent('filechooser');

await poMarketplace.btnUploadPrivateApp.click();
await expect(poMarketplace.btnInstallPrivateApp).toBeDisabled();

await poMarketplace.btnUploadPrivateAppFile.click();
const fileChooser = await fileChooserPromise;
await fileChooser.setFiles('./tests/e2e/fixtures/files/test-app_0.0.1.zip');

await expect(poMarketplace.btnInstallPrivateApp).toBeEnabled();
await poMarketplace.btnInstallPrivateApp.click();
await page.getByRole('button', { name: 'Agree' }).click();
await expect(poMarketplace.appStatusTag).toHaveText('Enabled');
});
});

test.describe('Community Edition', () => {
test.skip(IS_EE, 'CE Only');

test('expect to allow admin to upload a private app in CE, but it should be disabled by default', async ({ page }) => {
const fileChooserPromise = page.waitForEvent('filechooser');

await poMarketplace.btnUploadPrivateApp.click();
await expect(poMarketplace.btnConfirmAppUploadModal).toBeEnabled();
await poMarketplace.btnConfirmAppUploadModal.click();

await expect(poMarketplace.btnInstallPrivateApp).toBeDisabled();
await poMarketplace.btnUploadPrivateAppFile.click();
const fileChooser = await fileChooserPromise;
await fileChooser.setFiles('./tests/e2e/fixtures/files/test-app_0.0.1.zip');

await expect(poMarketplace.btnInstallPrivateApp).toBeEnabled();
await poMarketplace.btnInstallPrivateApp.click();

await expect(poMarketplace.confirmAppUploadModalTitle).toHaveText('Private apps limit reached');
await expect(poMarketplace.btnConfirmAppUploadModal).toBeEnabled();
await poMarketplace.btnConfirmAppUploadModal.click();

await page.getByRole('button', { name: 'Agree' }).click();
await expect(poMarketplace.appStatusTag).toHaveText('Disabled');
});

test('expect not to allow enabling a recently installed private app in CE', async () => {
await poMarketplace.lastAppRow.click();
await expect(poMarketplace.appStatusTag).toHaveText('Disabled');
await poMarketplace.appMenu.click();
await expect(poMarketplace.btnEnableApp).toBeDisabled();
});
});
});
2 changes: 2 additions & 0 deletions apps/meteor/tests/e2e/channel-management.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { faker } from '@faker-js/faker';
import type { Page } from '@playwright/test';

import { IS_EE } from './config/constants';
import { Users } from './fixtures/userStates';
import { HomeChannel } from './page-objects';
import { createTargetChannel } from './utils';
Expand Down Expand Up @@ -46,6 +47,7 @@ test.describe.serial('channel-management', () => {
});

test('should be able to navigate on call popup with keyboard', async ({ page }) => {
test.skip(!IS_EE, 'Premium Only');
await poHomeChannel.sidenav.openChat(targetChannel);
await poHomeChannel.roomHeaderFavoriteBtn.focus();

Expand Down
4 changes: 3 additions & 1 deletion apps/meteor/tests/e2e/e2e-encryption.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { faker } from '@faker-js/faker';
import type { Page } from '@playwright/test';

import { BASE_API_URL } from './config/constants';
import { BASE_API_URL, IS_EE } from './config/constants';
import { createAuxContext } from './fixtures/createAuxContext';
import injectInitialData from './fixtures/inject-initial-data';
import { Users, storeState, restoreState } from './fixtures/userStates';
Expand Down Expand Up @@ -641,6 +641,7 @@ test.describe.serial('e2e-encryption', () => {
});

test('expect slash commands to be enabled in an e2ee room', async ({ page }) => {
test.skip(!IS_EE, 'Premium Only');
const channelName = faker.string.uuid();

await poHomeChannel.sidenav.createEncryptedChannel(channelName);
Expand Down Expand Up @@ -668,6 +669,7 @@ test.describe.serial('e2e-encryption', () => {
});

test.describe('un-encrypted messages not allowed in e2ee rooms', () => {
test.skip(!IS_EE, 'Premium Only');
let poHomeChannel: HomeChannel;

test.beforeEach(async ({ page }) => {
Expand Down
Binary file not shown.
1 change: 1 addition & 0 deletions apps/meteor/tests/e2e/page-objects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ export * from './omnichannel-settings';
export * from './omnichannel-business-hours';
export * from './omnichannel-tags';
export * from './utils';
export * from './marketplace';
45 changes: 45 additions & 0 deletions apps/meteor/tests/e2e/page-objects/marketplace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import type { Locator, Page } from '@playwright/test';

export class Marketplace {
private readonly page: Page;

constructor(page: Page) {
this.page = page;
}

get btnUploadPrivateApp(): Locator {
return this.page.locator('role=button[name="Upload private app"]');
}

get btnInstallPrivateApp(): Locator {
return this.page.locator('role=button[name="Install"]');
}

get btnUploadPrivateAppFile(): Locator {
return this.page.locator('role=button[name="Browse Files"]');
}

get appStatusTag(): Locator {
return this.page.locator('[data-qa-type="app-status-tag"]');
}

get confirmAppUploadModalTitle(): Locator {
return this.page.locator('[data-qa-id="confirm-app-upload-modal-title"]');
}

get btnConfirmAppUploadModal(): Locator {
return this.page.locator('role=button[name="Upload anyway"]');
}

get lastAppRow(): Locator {
return this.page.locator('[data-qa-type="app-row"]').last();
}

get appMenu(): Locator {
return this.page.getByTitle('More options');
}

get btnEnableApp(): Locator {
return this.page.getByRole('menuitem', { name: 'Enable' });
}
}
2 changes: 2 additions & 0 deletions apps/meteor/tests/e2e/video-conference.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { IS_EE } from './config/constants';
import { Users } from './fixtures/userStates';
import { HomeChannel } from './page-objects';
import { createTargetChannel, createTargetTeam, createDirectMessage } from './utils';
Expand All @@ -6,6 +7,7 @@ import { expect, test } from './utils/test';
test.use({ storageState: Users.user1.state });

test.describe('video conference', () => {
test.skip(!IS_EE, 'Premium Only');
let poHomeChannel: HomeChannel;
let targetChannel: string;
let targetReadOnlyChannel: string;
Expand Down
3 changes: 2 additions & 1 deletion apps/meteor/tests/end-to-end/apps/apps-uninstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import { after, before, describe, it } from 'mocha';
import { getCredentials, request, credentials } from '../../data/api-data';
import { apps } from '../../data/apps/apps-data';
import { installTestApp, cleanupApps } from '../../data/apps/helper';
import { IS_EE } from '../../e2e/config/constants';

describe('Apps - Uninstall', () => {
(IS_EE ? describe : describe.skip)('Apps - Uninstall', () => {
let app: App;

before((done) => getCredentials(done));
Expand Down
27 changes: 24 additions & 3 deletions apps/meteor/tests/end-to-end/apps/installation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { APP_URL, apps } from '../../data/apps/apps-data';
import { cleanupApps } from '../../data/apps/helper';
import { updatePermission } from '../../data/permissions.helper';
import { getUserByUsername } from '../../data/users.helper';
import { IS_EE } from '../../e2e/config/constants';

const APP_USERNAME = 'appsrocketchattester.bot';

Expand Down Expand Up @@ -34,7 +35,7 @@ describe('Apps - Installation', () => {
.end(done);
});
});
it('should install the app successfully from a URL', (done) => {
(IS_EE ? it : it.skip)('should succesfully install an app from a URL in EE, which should be auto-enabled', (done) => {
void updatePermission('manage-apps', ['admin']).then(() => {
void request
.post(apps())
Expand All @@ -54,14 +55,34 @@ describe('Apps - Installation', () => {
.end(done);
});
});
(!IS_EE ? it : it.skip)('should succesfully install an app from a URL in CE, which should not be enabled', (done) => {
void updatePermission('manage-apps', ['admin']).then(() => {
void request
.post(apps())
.set(credentials)
.send({
url: APP_URL,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.a.property('success', true);
expect(res.body).to.have.a.property('app');
expect(res.body.app).to.have.a.property('id');
expect(res.body.app).to.have.a.property('version');
expect(res.body.app).to.have.a.property('status').and.to.be.equal('initialized');
})
.end(done);
});
});
it('should have created the app user successfully', (done) => {
void getUserByUsername(APP_USERNAME)
.then((user) => {
expect(user.username).to.be.equal(APP_USERNAME);
})
.then(done);
});
describe('Slash commands registration', () => {
(IS_EE ? describe : describe.skip)('Slash commands registration', () => {
it('should have created the "test-simple" slash command successfully', (done) => {
void request
.get(api('commands.get'))
Expand Down Expand Up @@ -91,7 +112,7 @@ describe('Apps - Installation', () => {
.end(done);
});
});
describe('Video Conf Provider registration', () => {
(IS_EE ? describe : describe.skip)('Video Conf Provider registration', () => {
it('should have created two video conf provider successfully', (done) => {
void request
.get(api('video-conference.providers'))
Expand Down
3 changes: 2 additions & 1 deletion apps/meteor/tests/end-to-end/apps/send-messages-as-user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ import { createRoom, deleteRoom } from '../../data/rooms.helper';
import { adminUsername, password } from '../../data/user';
import type { TestUser } from '../../data/users.helper';
import { createUser, deleteUser, login } from '../../data/users.helper';
import { IS_EE } from '../../e2e/config/constants';

describe('Apps - Send Messages As User', () => {
(IS_EE ? describe : describe.skip)('Apps - Send Messages As User', () => {
let app: App;

before((done) => getCredentials(done));
Expand Down
3 changes: 2 additions & 1 deletion apps/meteor/tests/end-to-end/apps/send-messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import { apps } from '../../data/apps/apps-data';
import { cleanupApps, installTestApp } from '../../data/apps/helper';
import { getMessageById } from '../../data/chat.helper';
import { createRoom, deleteRoom } from '../../data/rooms.helper';
import { IS_EE } from '../../e2e/config/constants';

describe('Apps - Send Messages As APP User', () => {
(IS_EE ? describe : describe.skip)('Apps - Send Messages As APP User', () => {
let app: App;

before((done) => getCredentials(done));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import { after, before, describe, it } from 'mocha';

import { getCredentials, request, credentials, api } from '../../data/api-data';
import { cleanupApps, installTestApp } from '../../data/apps/helper';
import { IS_EE } from '../../e2e/config/constants';

describe('Apps - Slash Command "test-simple"', () => {
(IS_EE ? describe : describe.skip)('Apps - Slash Command "test-simple"', () => {
before((done) => getCredentials(done));
before(async () => {
await cleanupApps();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import { after, before, describe, it } from 'mocha';

import { getCredentials, request, credentials, api } from '../../data/api-data';
import { cleanupApps, installTestApp } from '../../data/apps/helper';
import { IS_EE } from '../../e2e/config/constants';

describe('Apps - Slash Command "test-with-arguments"', () => {
(IS_EE ? describe : describe.skip)('Apps - Slash Command "test-with-arguments"', () => {
before((done) => getCredentials(done));
before(async () => {
await cleanupApps();
Expand Down
3 changes: 2 additions & 1 deletion apps/meteor/tests/end-to-end/apps/video-conferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { cleanupApps, installTestApp } from '../../data/apps/helper';
import { updateSetting } from '../../data/permissions.helper';
import { createRoom, deleteRoom } from '../../data/rooms.helper';
import { adminUsername } from '../../data/user';
import { IS_EE } from '../../e2e/config/constants';

describe('Apps - Video Conferences', () => {
before((done) => getCredentials(done));
Expand Down Expand Up @@ -65,7 +66,7 @@ describe('Apps - Video Conferences', () => {
});
});

describe('[With Test App]', () => {
(IS_EE ? describe : describe.skip)('[With Test App]', () => {
before(async () => {
await cleanupApps();
await installTestApp();
Expand Down
4 changes: 2 additions & 2 deletions ee/packages/license/__tests__/DefaultRestrictions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ describe('Community Restrictions', () => {
it('should respect the default if there is no license applied', async () => {
const license = new LicenseImp();

license.setLicenseLimitCounter('privateApps', () => 1);
license.setLicenseLimitCounter('privateApps', () => 0);

await expect(await license.shouldPreventAction('privateApps')).toBe(false);
await expect(await license.shouldPreventAction('privateApps')).toBe(true);

license.setLicenseLimitCounter('privateApps', () => 10);

Expand Down
2 changes: 1 addition & 1 deletion ee/packages/license/src/getLicenseLimit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ describe('Marketplace Restrictions', () => {
const LicenseManager = new LicenseImp();

expect(getAppsConfig.call(LicenseManager)).toEqual({
maxPrivateApps: 3,
maxPrivateApps: 0,
maxMarketplaceApps: 5,
});
});
Expand Down
Loading

0 comments on commit 874f70e

Please sign in to comment.