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 7cccfb1
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 11 deletions.
1 change: 1 addition & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"recommendations": [
"42crunch.vscode-openapi",
"bierner.markdown-preview-github-styles",
"davidanson.vscode-markdownlint",
"dbaeumer.vscode-eslint",
Expand Down
8 changes: 5 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"editor.defaultFormatter": "vscode.html-language-features"
},
"[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features"
Expand All @@ -16,8 +16,10 @@
},
"coverage-gutters.showGutterCoverage": false,
"coverage-gutters.showLineCoverage": true,
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"editor.defaultFormatter": "vscode.typescript-language-features",
"editor.formatOnSave": true,
"eslint.format.enable": true,
"files.insertFinalNewline": true,
"[yaml]": {
"editor.defaultFormatter": "redhat.vscode-yaml"
},
}
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
60 changes: 60 additions & 0 deletions app/src/docs/v1.api-spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,11 @@ paths:
- $ref: "#/components/parameters/Query-Public"
- $ref: "#/components/parameters/Query-MimeType"
- $ref: "#/components/parameters/Query-Name"
- $ref: "#/components/parameters/Query-Permissions"
- $ref: "#/components/parameters/Query-Page"
- $ref: "#/components/parameters/Query-Limit"
- $ref: "#/components/parameters/Query-Sort"
- $ref: "#/components/parameters/Query-Order"
- $ref: "#/components/parameters/Query-TagSet"
responses:
"200":
Expand Down Expand Up @@ -1738,6 +1743,61 @@ components:
schema:
type: boolean
example: true
Query-Permissions:
in: query
name: permissions
description: >-
Boolean representing whether or not to include matching permissions
schema:
type: boolean
example: true
Query-Page:
in: query
name: page
description: >-
The index of the page to return. The index of first page is 1.
Must specify limit when defined.
schema:
type: number
example: 1
Query-Limit:
in: query
name: limit
description: >-
The page size, number of objects in a page.
Must specify page number when defined.
schema:
type: number
example: 10
Query-Sort:
in: query
name: sort
description: >-
Any possible object Column.
schema:
type: string
enum:
- id
- path
- public
- active
- createdBy
- updatedBy
- updatedAt
- bucketId
- name
example: name
Query-Order:
in: query
name: order
description: >-
Order in ascending or descending. Default to ascending order.
schema:
type: string
enum:
- asc
- desc
example: asc
Query-Path:
in: query
name: path
Expand Down
24 changes: 19 additions & 5 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,12 +138,24 @@ 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 => {
let resultObject = [];
if (Object.hasOwn(result, 'results')) {
resultObject = result.results;
response.total = result.total;
} else {
resultObject = result;
response.total = result.length;
}

const res = resultObject.map(row => {
// eslint-disable-next-line no-unused-vars
const { objectPermission, bucketPermission, version, ...object } = row;
if (params.permissions) {
object.objectPermissions = objectPermission.map(o => o.permCode);
}
return object;
});
// remove duplicates
Expand Down
7 changes: 7 additions & 0 deletions app/src/validators/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ const scheme = {

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

pagination: (sortList) => ({
page: Joi.number().min(1),
limit: Joi.number().min(0),
sort: Joi.string().valid(...sortList),
order: Joi.string().valid('asc', 'desc'),
}),

permCode: oneOrMany(Joi.string().valid(...Object.values(Permissions)))
};

Expand Down
6 changes: 5 additions & 1 deletion app/src/validators/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,11 @@ const schema = {
public: type.truthy,
active: type.truthy,
deleteMarker: type.truthy,
latest: type.truthy
latest: type.truthy,
permissions: type.truthy,
...scheme.pagination(
['id', 'path', 'public', 'active', 'createdBy', 'updatedBy', 'updatedAt', 'bucketId', 'name']
),
})
},

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 7cccfb1

Please sign in to comment.