Skip to content

Commit db5266d

Browse files
authored
Merge pull request #56 from elastic/fix-uri-decode
Ensure router will correctly match paths with URL-encoded characters
2 parents ee7147e + 3d70f20 commit db5266d

File tree

4 files changed

+105
-1
lines changed

4 files changed

+105
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,4 @@ dist
104104
.tern-port
105105

106106
.DS_Store
107+
package-lock.json

index.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ class Mocker {
5555
if (typeof pattern.path !== 'string') throw new ConfigurationError('The path is not defined')
5656
if (typeof fn !== 'function') throw new ConfigurationError('The resolver function is not defined')
5757

58+
// workaround since find-my-way no longer decodes URI escaped chars
59+
// https://github.com/delvedor/find-my-way/pull/282
60+
// https://github.com/delvedor/find-my-way/pull/286
61+
if (pattern.path.indexOf('%') > -1) pattern.path = decodeURIComponent(pattern.path)
62+
5863
const handler = this[kRouter].find(pattern.method, pattern.path)
5964
if (handler) {
6065
handler.store.push({ ...pattern, fn })
@@ -64,10 +69,19 @@ class Mocker {
6469
} else {
6570
this[kRouter].on(pattern.method, pattern.path, noop, [{ ...pattern, fn }])
6671
}
72+
6773
return this
6874
}
6975

7076
get (params) {
77+
if (typeof params.method !== 'string') throw new ConfigurationError('The method is not defined')
78+
if (typeof params.path !== 'string') throw new ConfigurationError('The path is not defined')
79+
80+
// workaround since find-my-way no longer decodes URI escaped chars
81+
// https://github.com/delvedor/find-my-way/pull/282
82+
// https://github.com/delvedor/find-my-way/pull/286
83+
if (params.path.indexOf('%') > -1) params.path = decodeURIComponent(params.path)
84+
7185
const handler = this[kRouter].find(params.method, params.path)
7286
if (!handler) return null
7387
for (const { body, querystring, fn } of handler.store) {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
},
3535
"homepage": "https://github.com/elastic/elasticsearch-js-mock#readme",
3636
"devDependencies": {
37-
"@elastic/elasticsearch": "8.17.1",
37+
"@elastic/elasticsearch": "9.0.0",
3838
"ava": "6.2.0",
3939
"node-abort-controller": "3.1.1",
4040
"nyc": "17.1.0",

test.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -880,3 +880,92 @@ test('Should clear all mocks', async t => {
880880
t.is(err.statusCode, 404)
881881
}
882882
})
883+
884+
test('Path should match URL-encoded characters for e.g. comma in multi-index operations', async t => {
885+
t.plan(1)
886+
887+
const mock = new Mock()
888+
const client = new Client({
889+
node: 'http://localhost:9200',
890+
Connection: mock.getConnection()
891+
})
892+
893+
const spy = (_req, _res, _params, _store, _searchParams) => {
894+
t.pass('Callback function was called')
895+
return {}
896+
}
897+
898+
mock.add(
899+
{
900+
method: 'DELETE',
901+
path: '/some-type-index-123tobedeleted%2Csome-type-index-456tobedeleted'
902+
},
903+
spy
904+
)
905+
906+
await client.indices.delete({
907+
index: [
908+
'some-type-index-123tobedeleted',
909+
'some-type-index-456tobedeleted'
910+
]
911+
})
912+
})
913+
914+
test('Path should match unencoded comma in path', async t => {
915+
t.plan(1)
916+
917+
const mock = new Mock()
918+
const client = new Client({
919+
node: 'http://localhost:9200',
920+
Connection: mock.getConnection()
921+
})
922+
923+
const spy = (_req, _res, _params, _store, _searchParams) => {
924+
t.pass('Callback function was called')
925+
return {}
926+
}
927+
928+
mock.add(
929+
{
930+
method: 'DELETE',
931+
path: '/some-type-index-123tobedeleted,some-type-index-456tobedeleted'
932+
},
933+
spy
934+
)
935+
936+
await client.indices.delete({
937+
index: [
938+
'some-type-index-123tobedeleted',
939+
'some-type-index-456tobedeleted'
940+
]
941+
})
942+
})
943+
944+
test('Validate types on get()', t => {
945+
t.plan(4)
946+
947+
const mock = new Mock()
948+
mock.add(
949+
{
950+
method: 'GET',
951+
path: '/foo'
952+
},
953+
() => {}
954+
)
955+
956+
try {
957+
mock.get({ method: 'GET', path: null })
958+
t.fail('should throw')
959+
} catch (err) {
960+
t.true(err instanceof errors.ConfigurationError)
961+
t.is(err.message, 'The path is not defined')
962+
}
963+
964+
try {
965+
mock.get({ method: null, path: '/foo' })
966+
t.fail('should throw')
967+
} catch (err) {
968+
t.true(err instanceof errors.ConfigurationError)
969+
t.is(err.message, 'The method is not defined')
970+
}
971+
})

0 commit comments

Comments
 (0)