mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-09 22:24:05 -08:00
fix(editor): Fix updating/uninstalling community nodes (#10138)
Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
This commit is contained in:
parent
a51e86f20b
commit
de015ff297
|
@ -6,6 +6,13 @@ import CustomNodeWithN8nCredentialFixture from '../fixtures/Custom_node_n8n_cred
|
||||||
import CustomNodeWithCustomCredentialFixture from '../fixtures/Custom_node_custom_credential.json';
|
import CustomNodeWithCustomCredentialFixture from '../fixtures/Custom_node_custom_credential.json';
|
||||||
import CustomCredential from '../fixtures/Custom_credential.json';
|
import CustomCredential from '../fixtures/Custom_credential.json';
|
||||||
import { getVisibleSelect } from '../utils';
|
import { getVisibleSelect } from '../utils';
|
||||||
|
import {
|
||||||
|
confirmCommunityNodeUninstall,
|
||||||
|
confirmCommunityNodeUpdate,
|
||||||
|
getCommunityCards,
|
||||||
|
installFirstCommunityNode,
|
||||||
|
visitCommunityNodesSettings,
|
||||||
|
} from '../pages/settings-community-nodes';
|
||||||
|
|
||||||
const credentialsModal = new CredentialsModal();
|
const credentialsModal = new CredentialsModal();
|
||||||
const nodeCreatorFeature = new NodeCreator();
|
const nodeCreatorFeature = new NodeCreator();
|
||||||
|
@ -14,7 +21,7 @@ const workflowPage = new WorkflowPage();
|
||||||
// We separate-out the custom nodes because they require injecting nodes and credentials
|
// We separate-out the custom nodes because they require injecting nodes and credentials
|
||||||
// so the /nodes and /credentials endpoints are intercepted and non-cached.
|
// so the /nodes and /credentials endpoints are intercepted and non-cached.
|
||||||
// We want to keep the other tests as fast as possible so we don't want to break the cache in those.
|
// We want to keep the other tests as fast as possible so we don't want to break the cache in those.
|
||||||
describe('Community Nodes', () => {
|
describe('Community and custom nodes in canvas', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.intercept('/types/nodes.json', { middleware: true }, (req) => {
|
cy.intercept('/types/nodes.json', { middleware: true }, (req) => {
|
||||||
req.headers['cache-control'] = 'no-cache, no-store';
|
req.headers['cache-control'] = 'no-cache, no-store';
|
||||||
|
@ -95,3 +102,89 @@ describe('Community Nodes', () => {
|
||||||
credentialsModal.getters.editCredentialModal().should('contain.text', 'Custom E2E Credential');
|
credentialsModal.getters.editCredentialModal().should('contain.text', 'Custom E2E Credential');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Community nodes', () => {
|
||||||
|
const mockPackage = {
|
||||||
|
createdAt: '2024-07-22T19:08:06.505Z',
|
||||||
|
updatedAt: '2024-07-22T19:08:06.505Z',
|
||||||
|
packageName: 'n8n-nodes-chatwork',
|
||||||
|
installedVersion: '1.0.0',
|
||||||
|
authorName: null,
|
||||||
|
authorEmail: null,
|
||||||
|
installedNodes: [
|
||||||
|
{
|
||||||
|
name: 'Chatwork',
|
||||||
|
type: 'n8n-nodes-chatwork.chatwork',
|
||||||
|
latestVersion: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
updateAvailable: '1.1.2',
|
||||||
|
};
|
||||||
|
|
||||||
|
it('can install, update and uninstall community nodes', () => {
|
||||||
|
cy.intercept(
|
||||||
|
{
|
||||||
|
hostname: 'api.npms.io',
|
||||||
|
pathname: '/v2/search',
|
||||||
|
query: { q: 'keywords:n8n-community-node-package' },
|
||||||
|
},
|
||||||
|
{ body: {} },
|
||||||
|
);
|
||||||
|
cy.intercept(
|
||||||
|
{ method: 'GET', pathname: '/rest/community-packages', times: 1 },
|
||||||
|
{
|
||||||
|
body: { data: [] },
|
||||||
|
},
|
||||||
|
).as('getEmptyPackages');
|
||||||
|
visitCommunityNodesSettings();
|
||||||
|
cy.wait('@getEmptyPackages');
|
||||||
|
|
||||||
|
// install a package
|
||||||
|
cy.intercept(
|
||||||
|
{ method: 'POST', pathname: '/rest/community-packages', times: 1 },
|
||||||
|
{
|
||||||
|
body: { data: mockPackage },
|
||||||
|
},
|
||||||
|
).as('installPackage');
|
||||||
|
cy.intercept(
|
||||||
|
{ method: 'GET', pathname: '/rest/community-packages', times: 1 },
|
||||||
|
{
|
||||||
|
body: { data: [mockPackage] },
|
||||||
|
},
|
||||||
|
).as('getPackages');
|
||||||
|
installFirstCommunityNode('n8n-nodes-chatwork@1.0.0');
|
||||||
|
cy.wait('@installPackage');
|
||||||
|
cy.wait('@getPackages');
|
||||||
|
getCommunityCards().should('have.length', 1);
|
||||||
|
getCommunityCards().eq(0).should('include.text', 'v1.0.0');
|
||||||
|
|
||||||
|
// update the package
|
||||||
|
cy.intercept(
|
||||||
|
{ method: 'PATCH', pathname: '/rest/community-packages' },
|
||||||
|
{
|
||||||
|
body: { data: { ...mockPackage, installedVersion: '1.2.0', updateAvailable: undefined } },
|
||||||
|
},
|
||||||
|
).as('updatePackage');
|
||||||
|
getCommunityCards().eq(0).find('button').click();
|
||||||
|
confirmCommunityNodeUpdate();
|
||||||
|
cy.wait('@updatePackage');
|
||||||
|
getCommunityCards().should('have.length', 1);
|
||||||
|
getCommunityCards().eq(0).should('not.include.text', 'v1.0.0');
|
||||||
|
|
||||||
|
// uninstall the package
|
||||||
|
cy.intercept(
|
||||||
|
{
|
||||||
|
method: 'DELETE',
|
||||||
|
pathname: '/rest/community-packages',
|
||||||
|
query: { name: 'n8n-nodes-chatwork' },
|
||||||
|
},
|
||||||
|
{ statusCode: 204 },
|
||||||
|
).as('uninstallPackage');
|
||||||
|
getCommunityCards().getByTestId('action-toggle').click();
|
||||||
|
cy.getByTestId('action-uninstall').click();
|
||||||
|
confirmCommunityNodeUninstall();
|
||||||
|
cy.wait('@uninstallPackage');
|
||||||
|
|
||||||
|
cy.getByTestId('action-box').should('exist');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
22
cypress/pages/settings-community-nodes.ts
Normal file
22
cypress/pages/settings-community-nodes.ts
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
export const getCommunityCards = () => {
|
||||||
|
return cy.getByTestId('community-package-card');
|
||||||
|
};
|
||||||
|
|
||||||
|
export const visitCommunityNodesSettings = () => {
|
||||||
|
cy.visit('/settings/community-nodes');
|
||||||
|
};
|
||||||
|
|
||||||
|
export const installFirstCommunityNode = (nodeName: string) => {
|
||||||
|
cy.getByTestId('action-box').find('button').click();
|
||||||
|
cy.getByTestId('communityPackageInstall-modal').find('input').eq(0).type(nodeName);
|
||||||
|
cy.getByTestId('user-agreement-checkbox').click();
|
||||||
|
cy.getByTestId('install-community-package-button').click();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const confirmCommunityNodeUpdate = () => {
|
||||||
|
cy.getByTestId('communityPackageManageConfirm-modal').find('button').eq(1).click();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const confirmCommunityNodeUninstall = () => {
|
||||||
|
cy.getByTestId('communityPackageManageConfirm-modal').find('button').eq(1).click();
|
||||||
|
};
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div :class="$style.cardContainer">
|
<div :class="$style.cardContainer" data-test-id="community-package-card">
|
||||||
<div v-if="loading" :class="$style.cardSkeleton">
|
<div v-if="loading" :class="$style.cardSkeleton">
|
||||||
<n8n-loading :class="$style.loader" variant="p" :rows="1" />
|
<n8n-loading :class="$style.loader" variant="p" :rows="1" />
|
||||||
<n8n-loading :class="$style.loader" variant="p" :rows="1" />
|
<n8n-loading :class="$style.loader" variant="p" :rows="1" />
|
||||||
|
|
|
@ -148,8 +148,6 @@ export default defineComponent({
|
||||||
this.infoTextErrorMessage = '';
|
this.infoTextErrorMessage = '';
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
await this.communityNodesStore.installPackage(this.packageName);
|
await this.communityNodesStore.installPackage(this.packageName);
|
||||||
// TODO: We need to fetch a fresh list of installed packages until proper response is implemented on the back-end
|
|
||||||
await this.communityNodesStore.fetchInstalledPackages();
|
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.modalBus.emit('close');
|
this.modalBus.emit('close');
|
||||||
this.showMessage({
|
this.showMessage({
|
||||||
|
|
|
@ -480,14 +480,14 @@ export const useUIStore = defineStore(STORES.UI, () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const openCommunityPackageUninstallConfirmModal = (packageName: string) => {
|
const openCommunityPackageUninstallConfirmModal = (packageName: string) => {
|
||||||
setMode(COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY, packageName);
|
setMode(COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY, COMMUNITY_PACKAGE_MANAGE_ACTIONS.UNINSTALL);
|
||||||
setActiveId(COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY, COMMUNITY_PACKAGE_MANAGE_ACTIONS.UNINSTALL);
|
setActiveId(COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY, packageName);
|
||||||
openModal(COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY);
|
openModal(COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY);
|
||||||
};
|
};
|
||||||
|
|
||||||
const openCommunityPackageUpdateConfirmModal = (packageName: string) => {
|
const openCommunityPackageUpdateConfirmModal = (packageName: string) => {
|
||||||
setMode(COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY, packageName);
|
setMode(COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY, COMMUNITY_PACKAGE_MANAGE_ACTIONS.UPDATE);
|
||||||
setActiveId(COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY, COMMUNITY_PACKAGE_MANAGE_ACTIONS.UPDATE);
|
setActiveId(COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY, packageName);
|
||||||
openModal(COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY);
|
openModal(COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue