Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes conflict checks for sharing saved objects #168655

Merged
merged 10 commits into from
Oct 16, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -411,11 +411,12 @@ describe('collectMultiNamespaceReferences', () => {
expect(mockFindSharedOriginObjects).toHaveBeenCalledWith(
expect.anything(),
[
{ type: obj1.type, origin: obj1.id },
{ type: obj2.type, origin: obj2.originId }, // If the found object has an `originId`, that is used instead of the object's `id`.
{ type: obj3.type, origin: obj3.id },
{ type: obj1.type, id: obj1.id },
{ type: obj2.type, id: obj2.id, origin: obj2.originId },
{ type: obj3.type, id: obj3.id },
],
ALIAS_OR_SHARED_ORIGIN_SEARCH_PER_PAGE
ALIAS_OR_SHARED_ORIGIN_SEARCH_PER_PAGE,
undefined
);
expect(result.objects).toEqual([
// Note: in a realistic scenario, `spacesWithMatchingOrigins` would be a superset of `spaces`. But for the purposes of this unit
Expand All @@ -441,8 +442,9 @@ describe('collectMultiNamespaceReferences', () => {
expect(mockFindSharedOriginObjects).toHaveBeenCalledTimes(1);
expect(mockFindSharedOriginObjects).toHaveBeenCalledWith(
expect.anything(),
[{ type: obj1.type, origin: obj1.id }],
ALIAS_OR_SHARED_ORIGIN_SEARCH_PER_PAGE
[{ type: obj1.type, id: obj1.id }],
ALIAS_OR_SHARED_ORIGIN_SEARCH_PER_PAGE,
undefined
);
});

Expand All @@ -458,6 +460,25 @@ describe('collectMultiNamespaceReferences', () => {
'Failed to retrieve shared origin objects: Oh no!'
);
});

it('passes options to findSharedOriginObjects', async () => {
const obj1 = { type: MULTI_NAMESPACE_OBJ_TYPE_1, id: 'id-1' };
const obj2 = { type: MULTI_NAMESPACE_OBJ_TYPE_1, id: 'id-2' };
const params = setup([obj1, obj2]);
mockMgetResults({ found: true }, { found: false }); // results for obj1 and obj2

await collectMultiNamespaceReferences({
...params,
options: { purpose: 'updateObjectsSpaces' },
});
expect(mockFindSharedOriginObjects).toHaveBeenCalledTimes(1);
expect(mockFindSharedOriginObjects).toHaveBeenCalledWith(
expect.anything(),
[{ type: obj1.type, id: obj1.id }],
ALIAS_OR_SHARED_ORIGIN_SEARCH_PER_PAGE,
'updateObjectsSpaces'
);
});
});

describe('with security enabled', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,14 @@ export async function collectMultiNamespaceReferences(
);
const objectOriginsToSearchFor = foundObjects.map(({ type, id, originId }) => ({
type,
origin: originId || id,
id,
origin: originId,
}));
const originsMap = await findSharedOriginObjects(
createPointInTimeFinder,
objectOriginsToSearchFor,
ALIAS_OR_SHARED_ORIGIN_SEARCH_PER_PAGE
ALIAS_OR_SHARED_ORIGIN_SEARCH_PER_PAGE,
options?.purpose
);
const results = objectsWithContext.map((obj) => {
const aliasesVal = aliasesMap.get(getObjectKey(obj));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ describe('findSharedOriginObjects', () => {
});
}

const obj1 = { type: 'type-1', origin: 'id-1' };
const obj2 = { type: 'type-2', origin: 'id-2' };
const obj3 = { type: 'type-3', origin: 'id-3' };
const obj4 = { type: 'type-4', origin: 'id-4' };
const obj1 = { type: 'type-1', id: 'id-1', origin: 'origin-1' };
const obj2 = { type: 'type-2', id: 'id-2', origin: 'origin-2' };
const obj3 = { type: 'type-3', id: 'id-3', origin: 'origin-3' };
const obj4 = { type: 'type-4', id: 'id-4', origin: 'origin-4' };

it('uses the PointInTimeFinder to search for legacy URL aliases', async () => {
mockFindResults(
Expand Down Expand Up @@ -156,4 +156,220 @@ describe('findSharedOriginObjects', () => {
expect(pointInTimeFinder.find).toHaveBeenCalledTimes(1);
expect(pointInTimeFinder.close).toHaveBeenCalledTimes(2);
});

describe(`when options.purpose is 'updateObjectsSpaces'`, () => {
it('calls createPointInTimeFinder with filter to ignore direct ID matches', async () => {
const objects = [obj1, obj2, obj3];
await findSharedOriginObjects(createPointInTimeFinder, objects, 999, 'updateObjectsSpaces');
expect(createPointInTimeFinder).toHaveBeenCalledTimes(1);
expect(createPointInTimeFinder).toHaveBeenCalledWith(
expect.objectContaining({
filter: expect.objectContaining({
arguments: expect.arrayContaining([
expect.objectContaining({
arguments: expect.arrayContaining([
expect.objectContaining({
arguments: [
{
arguments: [
{
isQuoted: false,
type: 'literal',
value: 'type-1.id',
},
{
isQuoted: false,
type: 'literal',
value: 'type-1:id-1',
},
],
function: 'is',
type: 'function',
},
],
function: 'not',
type: 'function',
}),
]),
}),
expect.objectContaining({
arguments: expect.arrayContaining([
expect.objectContaining({
arguments: [
{
arguments: [
{
isQuoted: false,
type: 'literal',
value: 'type-2.id',
},
{
isQuoted: false,
type: 'literal',
value: 'type-2:id-2',
},
],
function: 'is',
type: 'function',
},
],
function: 'not',
type: 'function',
}),
]),
}),
expect.objectContaining({
arguments: expect.arrayContaining([
expect.objectContaining({
arguments: [
{
arguments: [
{
isQuoted: false,
type: 'literal',
value: 'type-3.id',
},
{
isQuoted: false,
type: 'literal',
value: 'type-3:id-3',
},
],
function: 'is',
type: 'function',
},
],
function: 'not',
type: 'function',
}),
]),
}),
]),
}),
}),
undefined,
{ disableExtensions: true }
);
});

it('calls createPointInTimeFinder without redundant filter when object does not have an origin ID', async () => {
const objects = [obj1, { ...obj2, origin: undefined }, obj3];
await findSharedOriginObjects(createPointInTimeFinder, objects, 999, 'updateObjectsSpaces');
expect(createPointInTimeFinder).toHaveBeenCalledTimes(1);
expect(createPointInTimeFinder).toHaveBeenCalledWith(
expect.objectContaining({
filter: expect.objectContaining({
arguments: expect.arrayContaining([
expect.objectContaining({
arguments: expect.arrayContaining([
expect.objectContaining({
arguments: [
{
arguments: [
{
isQuoted: false,
type: 'literal',
value: 'type-1.id',
},
{
isQuoted: false,
type: 'literal',
value: 'type-1:origin-1',
},
],
function: 'is',
type: 'function',
},
{
arguments: [
{
isQuoted: false,
type: 'literal',
value: 'type-1.originId',
},
{
isQuoted: false,
type: 'literal',
value: 'origin-1',
},
],
function: 'is',
type: 'function',
},
],
function: 'or',
type: 'function',
}),
]),
}),
expect.objectContaining({
arguments: expect.arrayContaining([
expect.objectContaining({
arguments: [
{
isQuoted: false,
type: 'literal',
value: 'type-2.originId',
},
{
isQuoted: false,
type: 'literal',
value: 'id-2',
},
],
function: 'is',
type: 'function',
}),
]),
}),
expect.objectContaining({
arguments: expect.arrayContaining([
expect.objectContaining({
arguments: [
{
arguments: [
{
isQuoted: false,
type: 'literal',
value: 'type-3.id',
},
{
isQuoted: false,
type: 'literal',
value: 'type-3:origin-3',
},
],
function: 'is',
type: 'function',
},
{
arguments: [
{
isQuoted: false,
type: 'literal',
value: 'type-3.originId',
},
{
isQuoted: false,
type: 'literal',
value: 'origin-3',
},
],
function: 'is',
type: 'function',
},
],
function: 'or',
type: 'function',
}),
]),
}),
]),
}),
}),
undefined,
{ disableExtensions: true }
);
});
});
});
Loading