Skip to content

Commit

Permalink
Merge branch 'cell-level-upload-details' of github.com:biomage-org/ap…
Browse files Browse the repository at this point in the history
…i into cell-level-upload-details

Signed-off-by: stefanbabukov <[email protected]>
  • Loading branch information
StefanBabukov committed Nov 7, 2023
2 parents 446e847 + 653f098 commit a888309
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 3 deletions.
18 changes: 16 additions & 2 deletions src/api.v2/helpers/s3/patchCellSetsObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,28 @@ const putObject = require('./putObject');

const validateRequest = require('../../../utils/schema-validator');

function removeElementsWithTypeCLM(data) {
// Filter out cell-level metadata cell sets
return data.filter((item) => item.type !== 'CLM' && item.type !== 'CLMPerSample');
}

const containsTypeCLM = (data) => data.some((item) => {
const appendObject = item.$append;
return appendObject && (appendObject.type === 'CLM' || appendObject.type === 'CLMPerSample');
});

const patchCellSetsObject = async (experimentId, patch) => {
const currentCellSet = await getObject({
Bucket: bucketNames.CELL_SETS,
Key: experimentId,
});

const { cellSets: prePatchCellSets } = JSON.parse(currentCellSet);
let { cellSets: prePatchCellSets } = JSON.parse(currentCellSet);

// If the patch contains a cell-level metadata we need to clear them before to avoid duplications
if (containsTypeCLM(patch)) {
prePatchCellSets = removeElementsWithTypeCLM(prePatchCellSets);
}

/**
* The $remove operation will replace the element in the array with an
Expand All @@ -26,7 +41,6 @@ const patchCellSetsObject = async (experimentId, patch) => {
);

const patchedCellSets = { cellSets: patchedCellSetslist };

await validateRequest(patchedCellSets, 'cell-sets-bodies/CellSets.v2.yaml');

await putObject({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`patchCellSetsObject Patch with CLM elements replaces old CLM cell sets 1`] = `
Array [
Object {
"children": Array [],
"key": "sample2",
"name": "Sample 2",
"type": "notCLM",
},
Object {
"children": Array [],
"key": "New",
"name": "New CLM",
"type": "CLM",
},
]
`;

exports[`patchCellSetsObject Works correctly 1`] = `
Object {
"Body": "{\\"cellSets\\":[{\\"key\\":\\"louvain\\",\\"name\\":\\"louvain clusters\\",\\"rootNode\\":true,\\"type\\":\\"cellSets\\",\\"children\\":[{\\"key\\":\\"louvain-0\\",\\"name\\":\\"Cluster 0\\",\\"rootNode\\":false,\\"type\\":\\"cellSets\\",\\"color\\":\\"#77aadd\\",\\"cellIds\\":[0,1,2,3]},{\\"key\\":\\"new-cluster-1\\",\\"name\\":\\"New Cluster 1\\",\\"rootNode\\":false,\\"color\\":\\"#3957ff\\",\\"type\\":\\"cellSets\\",\\"cellIds\\":[4,5,6]}]}]}",
Expand Down
57 changes: 56 additions & 1 deletion tests/api.v2/helpers/s3/patchCellSetsObject.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,16 @@ const mockPatch = [
},
];

getObject.mockReturnValue(mockCellSets);

describe('patchCellSetsObject', () => {
beforeEach(() => {
jest.resetAllMocks(); // This resets the state of all mocks
});


it('Works correctly', async () => {
getObject.mockReturnValue(mockCellSets);

const result = await patchCellSetsObject(mockExperimentId, mockPatch);

// Put a modified object
Expand Down Expand Up @@ -102,4 +108,53 @@ describe('patchCellSetsObject', () => {

await expect(patchCellSetsObject(mockExperimentId, malformedPatch)).rejects.toThrow();
});

it('Patch with CLM elements replaces old CLM cell sets', async () => {
// Mock cellSets with CLM types
const mockCellSetsWithCLM = JSON.stringify({
cellSets: [
{
key: 'sample1',
name: 'To remove 1',
type: 'CLM',
children: [],
},
// This should stay since it's not CLM type
{
key: 'sample2',
name: 'Sample 2',
type: 'notCLM',
children: [],
},
{
key: 'sample3',
name: 'To Remove 2',
type: 'CLMPerSample',
children: [],
},
],
});

const mockPatchThatContainsCLM = [
{
$append: {
key: 'New',
name: 'New CLM',
type: 'CLM',
children: [],
},
},
];

getObject.mockReturnValueOnce(mockCellSetsWithCLM);

await patchCellSetsObject(mockExperimentId, mockPatchThatContainsCLM);

// Put a modified object without CLM types
const putParams = putObject.mock.calls[0][0];
const modifiedCellSets = JSON.parse(putParams.Body).cellSets;

// Check that the elements with CLM types have been removed
expect(modifiedCellSets).toMatchSnapshot();
});
});

0 comments on commit a888309

Please sign in to comment.