Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 10 additions & 37 deletions apps/deep-clone/src/utils/useInstallationParameters.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,16 @@
import { useEffect, useState } from 'react';
import { BaseAppSDK } from '@contentful/app-sdk';
import { AppInstallationProps, KeyValueMap } from 'contentful-management';
import { KeyValueMap } from 'contentful-management';

export const useInstallationParameters = (sdk: BaseAppSDK) => {
const [parameters, setParameters] = useState<KeyValueMap>(sdk.parameters.installation);

useEffect(() => {
const fetch = async () => {
const newParameters = await fetchParameters(sdk);
setParameters(newParameters);
};
fetch();
}, [sdk]);

return parameters;
const DEFAULTS: KeyValueMap = {
cloneText: 'Copy',
cloneTextBefore: true,
automaticRedirect: true,
};

const fetchParameters = async (sdk: BaseAppSDK): Promise<KeyValueMap> => {
try {
if (!sdk.ids.organization || !sdk.ids.app || !sdk.ids.space) {
throw new Error('Required SDK IDs not available');
}

const appInstallation = await sdk.cma.appInstallation.getForOrganization({
appDefinitionId: sdk.ids.app,
organizationId: sdk.ids.organization,
});

const currentInstallation = appInstallation.items.find(
(installation: AppInstallationProps) => installation.sys.space.sys.id === sdk.ids.space
);

if (currentInstallation?.parameters) {
return currentInstallation.parameters as KeyValueMap;
}
return sdk.parameters.installation;
} catch (error) {
console.warn('Failed to fetch fresh parameters from CMA:', error);
export const useInstallationParameters = (sdk: BaseAppSDK): KeyValueMap => {
const params = sdk.parameters.installation;
if (!params || Object.keys(params).length === 0) {
return DEFAULTS;
}

return sdk.parameters.installation;
return params;
};
9 changes: 0 additions & 9 deletions apps/deep-clone/test/mocks/mockCma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,6 @@ const mockCma = {
create: vi.fn(),
update: vi.fn(),
},
appInstallation: {
getForOrganization: vi.fn().mockReturnValue({
items: [
{
sys: { space: { sys: { id: 'test-space' } } },
},
],
}),
},
};

export { mockCma };
60 changes: 3 additions & 57 deletions apps/deep-clone/test/utils/useInstallationParameters.spec.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,11 @@
import { renderHook, waitFor } from '@testing-library/react';
import { vi, describe, it, expect, beforeEach } from 'vitest';
import { renderHook } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { useInstallationParameters } from '../../src/utils/useInstallationParameters';
import { mockSdk } from '../mocks/mockSdk';
import { mockCma } from '../mocks/mockCma';
import { BaseAppSDK } from '@contentful/app-sdk';

describe('useInstallationParameters', () => {
beforeEach(() => {
vi.clearAllMocks();
});

it('should return parameters from appInstallation.getForOrganization when successful', async () => {
const mockAppInstallationResponse = {
items: [
{
sys: { space: { sys: { id: 'test-space' } } },
parameters: {
cloneText: 'Custom Copy',
cloneTextBefore: false,
automaticRedirect: false,
},
},
],
};

mockCma.appInstallation.getForOrganization.mockResolvedValue(mockAppInstallationResponse);

it('should return sdk.parameters.installation directly', () => {
const { result } = renderHook(() =>
useInstallationParameters(mockSdk as unknown as BaseAppSDK)
);
Expand All @@ -35,39 +15,5 @@ describe('useInstallationParameters', () => {
cloneTextBefore: true,
automaticRedirect: true,
});

await waitFor(() => {
expect(result.current).toEqual({
cloneText: 'Custom Copy',
cloneTextBefore: false,
automaticRedirect: false,
});
});

expect(mockCma.appInstallation.getForOrganization).toHaveBeenCalledWith({
appDefinitionId: 'test-app',
organizationId: 'test-organization',
});
});

it('should return sdk.parameters.installation when appInstallation.getForOrganization throws an error', async () => {
mockCma.appInstallation.getForOrganization.mockRejectedValue(new Error('Network error'));

const { result } = renderHook(() =>
useInstallationParameters(mockSdk as unknown as BaseAppSDK)
);

await waitFor(() => {
expect(result.current).toEqual({
cloneText: 'Copy',
cloneTextBefore: true,
automaticRedirect: true,
});
});

expect(mockCma.appInstallation.getForOrganization).toHaveBeenCalledWith({
appDefinitionId: 'test-app',
organizationId: 'test-organization',
});
});
});
Loading