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

Send URIs to unindex or remove via form data if more than one was provided #29

Merged
merged 5 commits into from
Sep 30, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"strict": 1,
"new-cap": 0,
"camelcase": 0,
"comma-dangle": 1,
"comma-dangle": 0,
"no-unused-vars": 1,
"comma-spacing": 1,
"space-infix-ops": 1,
Expand Down
36 changes: 27 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -520,11 +520,22 @@ class DicoogleAccess {
callback = provider;
provider = undefined;
}
return andCallVoid(this.request('POST', Endpoints.UNINDEX)
.query({
uri,
provider
}), callback);

if (Array.isArray(uri) && uri.length > 1) {
// send URIs as form data to prevent URI from being too long
let body = uri.map(uri => 'uri=' + encodeURIComponent(uri)).join('&');

return andCallVoid(this.request('POST', Endpoints.UNINDEX)
.type('form')
.query({provider})
.send(body), callback);
} else {
return andCallVoid(this.request('POST', Endpoints.UNINDEX)
.query({
uri,
provider
}), callback);
}
};

/** Request that the file at the given URI is permanently removed. The operation, unlike index(), is not recursive.
Expand All @@ -533,10 +544,17 @@ class DicoogleAccess {
* @param callback the function to call on completion
*/
remove(uri: string | string[], callback?: (error: any) => void): Promise<void> {
return andCallVoid(this.request('POST', Endpoints.REMOVE)
.query({
uri
}), callback);
if (Array.isArray(uri) && uri.length > 1) {
// send URIs as form data to prevent URI from being too long
return andCallVoid(this.request('POST', Endpoints.REMOVE)
.type('form')
.send(uri.map(uri => 'uri=' + encodeURIComponent(uri)).join('&')), callback);
} else {
return andCallVoid(this.request('POST', Endpoints.REMOVE)
.query({
uri
}), callback);
}
};

/** Retrieve the running Dicoogle version.
Expand Down
4 changes: 2 additions & 2 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export function isDicomUUID(uid: string): boolean {
return uid.length <= 64 && uid.match(/^\d+(\.\d+)*$/) !== null;
}

export function andCall<T>(promise: Promise<T>, callback?: (error: any, outcome?: T) => void): Promise<T> {
export function andCall<T>(promise: Promise<T>, callback: (error: any, outcome?: T) => void | undefined): Promise<T> {
if (callback) {
promise.then(
(value) => callback(null, value),
Expand All @@ -34,7 +34,7 @@ export function andCall<T>(promise: Promise<T>, callback?: (error: any, outcome?
return promise;
}

export function andCallVoid(promise: Promise<any>, callback?: (error: any) => void): Promise<void> {
export function andCallVoid(promise: Promise<any>, callback: (error: any) => void | undefined): Promise<void> {
if (callback) {
promise.then(
() => callback(null),
Expand Down
2 changes: 1 addition & 1 deletion test/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"global-strict": 0,
"new-cap": 0,
"camelcase": 0,
"comma-dangle": 1,
"comma-dangle": 0,
"no-unused-vars": 1,
"comma-spacing": 1,
"space-infix-ops": 1,
Expand Down
54 changes: 42 additions & 12 deletions test/mock/service-mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ const nock = require('nock');
const URL = require('url');
const qs = require('querystring');

function validateURI(uri) {
if (typeof uri !== 'string') {
return false;
}
return /^(file:)?[\.-\w\/\%\?\&\=]+$/.test(uri);
}

/** Use nock to intercept Dicoogle client requests.
* @param {number} [port] the TCP port to listen to
* @returns {object} a Dicoogle access object Dicoogle access object connected to a mock Dicoogle server.
Expand All @@ -34,7 +41,7 @@ module.exports = function createDicoogleMock(port = 8080) {

const SEARCH_RESULTS = [
{
uri: '/opt/dataset/file1',
uri: 'file:/opt/dataset/file1',
fields: {
"Modality": "MR",
"StudyInstanceUID": "1.2.3.4.5.6.7777777",
Expand All @@ -48,7 +55,7 @@ module.exports = function createDicoogleMock(port = 8080) {
}
},
{
uri: '/opt/dataset/file2',
uri: 'file:/opt/dataset/file2',
fields: {
"Modality": "MR",
"StudyInstanceUID": "1.2.3.4.5.6.7777777",
Expand Down Expand Up @@ -79,10 +86,10 @@ module.exports = function createDicoogleMock(port = 8080) {
serieDescription: "",
serieModality: "CR",
images: [{
uri: '/opt/dataset/file1',
uri: 'file:/opt/dataset/file1',
"sopInstanceUID": "1.2.3.4.5.6.7777777.4444.1"
}, {
uri: '/opt/dataset/file2',
uri: 'file:/opt/dataset/file2',
"sopInstanceUID": "1.2.3.4.5.6.7777777.4444.2"
}]
}]
Expand Down Expand Up @@ -299,27 +306,50 @@ module.exports = function createDicoogleMock(port = 8080) {

// mock index on specific provider
.post('/management/tasks/index')
.query({ uri: /[a-z0-9\-/]+/, plugin: /.*/ })
.query(({ uri, plugin }) => {
return validateURI(uri) && /\w+/.test(plugin);
})
.reply(200)

// mock index on all providers
.post('/management/tasks/index')
.query({ uri: /[a-z0-9\-/]+/ })
.query(({ uri }) => validateURI(uri))
.reply(200)

// mock unindex on all providers
// mock unindex on all providers (via query string)
.post('/management/tasks/unindex')
.query({ uri: /[a-z0-9\-/]+/ })
.query(({ uri }) => validateURI(uri))
.reply(200)

// mock unindex on all providers (via form data)
.post('/management/tasks/unindex', ({ uri: uris }) => {
return uris.length > 0 && uris.every(validateURI);
})
.reply(200)

// mock unindex on specific provider
// mock unindex on specific provider (via query string)
.post('/management/tasks/unindex')
.query({ uri: /[a-z0-9\-/]+/, provider: /.*/ })
.query(({ uri, plugin }) => {
return validateURI(uri) && /\w+/.test(plugin);
})
.reply(200)

// mock remove
// mock unindex on specific provider (via form data)
.post('/management/tasks/unindex', ({ uri: uris }) => {
return uris.length > 0 && uris.every(validateURI);
})
.query({ provider: /\w+/ })
.reply(200)

// mock remove (via query string)
.post('/management/tasks/remove')
.query({ uri: /[a-z0-9\-/]+/ })
.query(({ uri }) => validateURI(uri))
.reply(200)

// mock remove (via form data)
.post('/management/tasks/remove', ({ uri: uris }) => {
return uris.length > 0 && uris.every(validateURI);
})
.reply(200)

// mock dump
Expand Down
32 changes: 26 additions & 6 deletions test/test-base-promise.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,28 +204,48 @@ describe('Dicoogle Client, Promise API (under Node.js)', function() {

describe('#index() on all providers', function() {
it("should say ok with no error", async function() {
await dicoogle.index('/opt/another-dataset');
await dicoogle.index('file:/opt/another-dataset');
});
});
});

describe('Unindex', function() {
describe('#unindex() on one provider', function() {
it("should say ok with no error", async function() {
await dicoogle.unindex('/opt/another-dataset/1_1.dcm', 'lucene');
await dicoogle.unindex('file:/opt/another-dataset/1_1.dcm', 'lucene');
});
});

describe('#unindex() on all providers', function() {
it("should say ok with no error", async function() {
await dicoogle.unindex('/opt/another-dataset/1_1.dcm');
await dicoogle.unindex('file:/opt/another-dataset/1_1.dcm');
});
});

describe('#unindex() multiple URIs', function() {
it("should say ok with no error", async function() {
await dicoogle.unindex([
'file:/opt/another-dataset/1_1.dcm',
'file:/opt/another-dataset/1_2.dcm',
]);
});
});
});

describe('#remove() a file', function() {
it("should say ok with no error", async function() {
await dicoogle.remove('/opt/another-dataset/1_1.dcm');
describe("Remove", function() {
describe('#remove() a file', function() {
it("should say ok with no error", async function() {
await dicoogle.remove('file:/opt/another-dataset/1_1.dcm');
});
});
describe('#remove() multiple files', function() {
it("should say ok with no error", async function() {
await dicoogle.remove([
'file:/opt/another-dataset/1_1.dcm',
'file:/opt/another-dataset/1_2.dcm',
'file:/opt/another-dataset/1_3.dcm',
]);
});
});
});

Expand Down
44 changes: 35 additions & 9 deletions test/test-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ describe('Dicoogle Client, callback API (under Node.js)', function() {
describe('Index', function() {
describe('#index() on one provider', function() {
it("should say ok with no error", function (done) {
Dicoogle.index('/opt/another-dataset', 'lucene', function(error) {
Dicoogle.index('file:/opt/another-dataset', 'lucene', function(error) {
assert.equal(error, null);
done();
});
Expand All @@ -302,7 +302,7 @@ describe('Dicoogle Client, callback API (under Node.js)', function() {
describe('Unindex', function() {
describe('#unindex() on one provider', function() {
it("should say ok with no error", function (done) {
Dicoogle.unindex('/opt/another-dataset/1_1.dcm', 'lucene', function(error) {
Dicoogle.unindex('file:/opt/another-dataset/1_1.dcm', 'lucene', function(error) {
assert.equal(error, null);
done();
});
Expand All @@ -311,20 +311,46 @@ describe('Dicoogle Client, callback API (under Node.js)', function() {

describe('#unindex() on all providers', function() {
it("should say ok with no error", function (done) {
Dicoogle.unindex('/opt/another-dataset/1_1.dcm', function(error) {
Dicoogle.unindex('file:/opt/another-dataset/1_1.dcm', function(error) {
assert.equal(error, null);
done();
});
});
});

describe('#unindex() multiple URIs', function() {
it("should say ok with no error", function (done) {
Dicoogle.unindex([
'file:/opt/another-dataset/1_1.dcm',
'file:/opt/another-dataset/1_2.dcm',
], function(error) {
assert.equal(error, null);
done();
});
});
});
});

describe('#remove() a file', function() {
it("should say ok with no error", function (done) {
Dicoogle.remove('/opt/another-dataset/1_1.dcm', function(error) {
assert.equal(error, null);
done();
});
describe("Remove", function() {
describe('#remove() a file', function() {
it("should say ok with no error", function (done) {
Dicoogle.remove('file:/opt/another-dataset/1_1.dcm', function(error) {
assert.equal(error, null);
done();
});
});
});
describe('#remove() multiple files', function() {
it("should say ok with no error", function (done) {
Dicoogle.remove([
'file:/opt/another-dataset/1_1.dcm',
'file:/opt/another-dataset/1_2.dcm',
'file:/opt/another-dataset/1_3.dcm',
], function(error) {
assert.equal(error, null);
done();
});
});
});
});

Expand Down