Skip to content

Commit

Permalink
Add Pagination to searchobjects, include total count in header and pe…
Browse files Browse the repository at this point in the history
…rform unit tests
  • Loading branch information
jatindersingh93 committed Dec 15, 2023
1 parent 687361d commit b7d2eaa
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 15 deletions.
10 changes: 8 additions & 2 deletions app/src/controllers/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -929,14 +929,20 @@ const controller = {
public: isTruthy(req.query.public),
active: isTruthy(req.query.active),
deleteMarker: isTruthy(req.query.deleteMarker),
latest: isTruthy(req.query.latest)
latest: isTruthy(req.query.latest),
page: req.query.page,
limit: req.query.limit,
sort: req.query.sort,
order: req.query.order,
permissions: isTruthy(req.query.permissions)
};
// if scoping to current user permissions on objects
if (config.has('server.privacyMask')) {
params.userId = await userService.getCurrentUserId(getCurrentIdentity(req.currentUser, SYSTEM_USER));
}
const response = await objectService.searchObjects(params);
res.status(200).json(response);
res.setHeader('X-Total-Rows', response.total);
res.status(200).json(response.data);
} catch (error) {
next(error);
}
Expand Down
6 changes: 6 additions & 0 deletions app/src/db/models/tables/objectModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,12 @@ class ObjectModel extends Timestamps(Model) {
});
});
}
},
pagination(query, page, limit){
if( page && limit) query.page(page - 1, limit);
},
sortOrder(query, column, order='asc'){
if(column) query.orderBy(column, order);
}
};
}
Expand Down
42 changes: 31 additions & 11 deletions app/src/services/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,13 @@ const service = {
*/
searchObjects: async (params, etrx = undefined) => {
let trx;
let response = [];
try {
trx = etrx ? etrx : await ObjectModel.startTransaction();

const response = await ObjectModel.query(trx)
.allowGraph('version')
response.data = await ObjectModel.query(trx)
.allowGraph('objectPermission')
.withGraphFetched('objectPermission')
.modify('filterIds', params.id)
.modify('filterBucketIds', params.bucketId)
.modify('filterName', params.name)
Expand All @@ -136,16 +138,34 @@ const service = {
tag: params.tag
})
.modify('hasPermission', params.userId, 'READ')
// format result
.modify('pagination', params.page, params.limit)
.modify('sortOrder', params.sort, params.order)
.then(result => {
// just return object table records
const res = result.map(row => {
// eslint-disable-next-line no-unused-vars
const { objectPermission, bucketPermission, version, ...object } = row;
return object;
});
// remove duplicates
return [...new Map(res.map(item => [item.id, item])).values()];
if (Object.hasOwn(result, 'results')) {
response.total = result.total;
const res = result.results.map(row => {
const { objectPermission, ...object } = row;
if (params.permissions) {
object.objectPermissions = [];
objectPermission.map(o => {
object.objectPermissions.push(o.permCode);
});
}
return object;
});
// remove duplicates
return [...new Map(res.map(item => [item.id, item])).values()];
} else {
response.total = result.length;
//just return object table records
const res = result.map(row => {
// eslint-disable-next-line no-unused-vars
const { objectPermission, bucketPermission, version, ...object } = row;
return object;
});
// remove duplicates
return [...new Map(res.map(item => [item.id, item])).values()];
}
});

if (!etrx) await trx.commit();
Expand Down
7 changes: 6 additions & 1 deletion app/src/validators/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,12 @@ const scheme = {
guid: oneOrMany(type.uuidv4),

string: oneOrMany(Joi.string().max(255)),

pagination: {
page: Joi.number().min(1),
limit: Joi.number(),
sort: Joi.string(),
order: Joi.string().valid('asc', 'desc'),
},
permCode: oneOrMany(Joi.string().valid(...Object.values(Permissions)))
};

Expand Down
4 changes: 3 additions & 1 deletion app/src/validators/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,9 @@ const schema = {
public: type.truthy,
active: type.truthy,
deleteMarker: type.truthy,
latest: type.truthy
latest: type.truthy,
permissions: type.truthy,
...scheme.pagination,
})
},

Expand Down
2 changes: 2 additions & 0 deletions app/tests/unit/services/object.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ describe('searchObjects', () => {
tag: params.tag
});
expect(ObjectModel.modify).toHaveBeenNthCalledWith(11, 'hasPermission', params.userId, 'READ');
expect(ObjectModel.modify).toHaveBeenNthCalledWith(12, 'pagination', params.page, params.limit);
expect(ObjectModel.modify).toHaveBeenNthCalledWith(13, 'sortOrder', params.sort, params.order);
expect(ObjectModel.then).toHaveBeenCalledTimes(1);
expect(objectModelTrx.commit).toHaveBeenCalledTimes(1);
});
Expand Down
41 changes: 41 additions & 0 deletions app/tests/unit/validators/object.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,47 @@ describe('searchObjects', () => {
expect(active).toEqual(type.truthy.describe());
});
});

describe('page', () => {
const page = query.keys.page;

it('is a number', () => {
expect(page.type).toEqual('number');
});
});

describe('limit', () => {
const limit = query.keys.limit;

it('is a number', () => {
expect(limit.type).toEqual('number');
});
});

describe('sort', () => {
const sort = query.keys.sort;

it('is a string', () => {
expect(sort.type).toEqual('string');
});
});

describe('order', () => {
const order = query.keys.order;

it('is a string', () => {
expect(order.type).toEqual('string');
});
});

describe('permissions', () => {
const permissions = query.keys.permissions;

it('is the expected schema', () => {
expect(permissions).toEqual(type.truthy.describe());
});
});

});
});

Expand Down

0 comments on commit b7d2eaa

Please sign in to comment.