Skip to content

Commit

Permalink
Add site imports and exports
Browse files Browse the repository at this point in the history
  • Loading branch information
phalestrivir committed Nov 13, 2024
1 parent 31cbb4e commit 2be8cf9
Show file tree
Hide file tree
Showing 7 changed files with 865 additions and 0 deletions.
93 changes: 93 additions & 0 deletions src/api/classic/SiteApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import util from 'util';

import { State } from '../../shared/State';
import { IdObjectSkeletonInterface, PagedResult } from '../ApiTypes';
import { generateAmApi } from '../BaseApi';

const siteURLTemplate = '%s/json/global-config/sites/%s';
const sitesURLTemplate = '%s/json/global-config/sites?_queryFilter=true';

const apiVersion = 'protocol=2.0,resource=1.0';

function getApiConfig() {
return {
apiVersion,
};
}

export type SiteSkeleton = IdObjectSkeletonInterface & {
id: string;
url: string;
secondaryURLs: string[];
servers: {
id: string;
url: string;
}[];
};

/**
* Get site
* @param {string} siteId Site id
* @returns {Promise<SiteSkeleton>} a promise that resolves to a site object
*/
export async function getSite({
siteId,
state,
}: {
siteId: string;
state: State;
}): Promise<SiteSkeleton> {
const urlString = util.format(siteURLTemplate, state.getHost(), siteId);
const { data } = await generateAmApi({ resource: getApiConfig(), state }).get(
urlString,
{
withCredentials: true,
}
);
return data;
}

/**
* Get all sites
* @returns {Promise<PagedResult<SiteSkeleton[]>>} a promise that resolves to an array of site objects
*/
export async function getSites({
state,
}: {
state: State;
}): Promise<PagedResult<SiteSkeleton>> {
const urlString = util.format(sitesURLTemplate, state.getHost());
const { data } = await generateAmApi({
resource: getApiConfig(),
state,
}).get(urlString, {
withCredentials: true,
});
return data;
}

/**
* Put site
* @param {string} siteId site id
* @param {SiteSkeleton} siteData site config object
* @returns {Promise<SiteSkeleton>} a promise that resolves to a site object
*/
export async function putSite({
siteId,
siteData,
state,
}: {
siteId: string;
siteData: SiteSkeleton;
state: State;
}): Promise<SiteSkeleton> {
const urlString = util.format(siteURLTemplate, state.getHost(), siteId);
const { data } = await generateAmApi({ resource: getApiConfig(), state }).put(
urlString,
siteData,
{
withCredentials: true,
}
);
return data;
}
3 changes: 3 additions & 0 deletions src/lib/FrodoLib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import AuthenticationSettingsOps, {
AuthenticationSettings,
} from '../ops/AuthenticationSettingsOps';
import CirclesOfTrustOps, { CirclesOfTrust } from '../ops/CirclesOfTrustOps';
import SiteOps, { Site } from '../ops/classic/SiteOps';
import AdminFederationOps, {
AdminFederation,
} from '../ops/cloud/AdminFederationOps';
Expand Down Expand Up @@ -176,6 +177,7 @@ export type Frodo = {
script: Script;
service: Service;
session: Session;
site: Site;

theme: Theme;

Expand Down Expand Up @@ -334,6 +336,7 @@ const FrodoLib = (config: StateInterface = {}): Frodo => {
script: ScriptOps(state),
service: ServiceOps(state),
session: SessionOps(state),
site: SiteOps(state),

theme: ThemeOps(state),

Expand Down
123 changes: 123 additions & 0 deletions src/ops/classic/SiteOps.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/**
* To record and update snapshots, you must perform 3 steps in order:
*
* 1. Record API responses
*
* Recording requires an available classic deployment, since sites
* can only be accessed in classic. Set FRODO_HOST and FRODO_REALM
* environment variables or alternatively FRODO_DEPLOY=classic
* in order to appropriately record requests to the classic deployment.
*
* To record API responses, you must call the test:record script and
* override all the connection state required to connect to the
* env to record from:
*
* ATTENTION: For the recording to succeed, you MUST make sure to use a
* user account, not a service account.
*
* FRODO_DEBUG=1 FRODO_HOST=frodo-dev npm run test:record SiteOps
*
* The above command assumes that you have a connection profile for
* 'frodo-dev' on your development machine.
*
* 2. Update snapshots
*
* After recording API responses, you must manually update/create snapshots
* by running:
*
* FRODO_DEBUG=1 npm run test:update SiteOps
*
* 3. Test your changes
*
* If 1 and 2 didn't produce any errors, you are ready to run the tests in
* replay mode and make sure they all succeed as well:
*
* FRODO_DEBUG=1 npm run test:only SiteOps
*
* Note: FRODO_DEBUG=1 is optional and enables debug logging for some output
* in case things don't function as expected
*/
import { autoSetupPolly, setDefaultState } from "../../utils/AutoSetupPolly";
import { filterRecording } from "../../utils/PollyUtils";
import * as SiteOps from "./SiteOps";
import { state } from "../../lib/FrodoLib";
import Constants from "../../shared/Constants";

const ctx = autoSetupPolly();

describe('SiteOps', () => {
beforeEach(async () => {
if (process.env.FRODO_POLLY_MODE === 'record') {
ctx.polly.server.any().on('beforePersist', (_req, recording) => {
filterRecording(recording);
});
}
setDefaultState(Constants.CLASSIC_DEPLOYMENT_TYPE_KEY);
});

describe('createSiteExportTemplate()', () => {
test('0: Method is implemented', async () => {
expect(SiteOps.createSiteExportTemplate).toBeDefined();
});

test('1: Create Site Export Template', async () => {
const response = SiteOps.createSiteExportTemplate({ state });
expect(response).toMatchSnapshot({
meta: expect.any(Object),
});
});
});

describe('readSite()', () => {
test('0: Method is implemented', async () => {
expect(SiteOps.readSite).toBeDefined();
});
//TODO: create tests
});

describe('readSites()', () => {
test('0: Method is implemented', async () => {
expect(SiteOps.readSites).toBeDefined();
});

test('1: Read Sites', async () => {
const response = await SiteOps.readSites({ state });
expect(response).toMatchSnapshot();
});
});

describe('exportSite()', () => {
test('0: Method is implemented', async () => {
expect(SiteOps.exportSite).toBeDefined();
});
//TODO: create tests
});

describe('exportSites()', () => {
test('0: Method is implemented', async () => {
expect(SiteOps.exportSites).toBeDefined();
});

test('1: Export Sites', async () => {
const response = await SiteOps.exportSites({ state });
expect(response).toMatchSnapshot({
meta: expect.any(Object),
});
});
});

describe('updateSite()', () => {
test('0: Method is implemented', async () => {
expect(SiteOps.updateSite).toBeDefined();
});
//TODO: create tests
});

describe('importSites()', () => {
test('0: Method is implemented', async () => {
expect(SiteOps.importSites).toBeDefined();
});
//TODO: create tests
});

});
Loading

0 comments on commit 2be8cf9

Please sign in to comment.