Fixed parseQueryString to handle empty values and plus signs

- now correctly parse query strings with '+' signs
- empty values are now parsed either as null or empty string
- added unit test for parseQueryString()
This commit is contained in:
Vincent Petry 2014-01-28 16:16:09 +01:00
parent d762e25cc5
commit 268206cec5
2 changed files with 92 additions and 7 deletions

View file

@ -371,6 +371,7 @@ var OC={
*/
parseQueryString:function(queryString){
var parts,
pos,
components,
result = {},
key,
@ -378,12 +379,25 @@ var OC={
if (!queryString){
return null;
}
if (queryString[0] === '?'){
queryString = queryString.substr(1);
pos = queryString.indexOf('?');
if (pos >= 0){
queryString = queryString.substr(pos + 1);
}
parts = queryString.split('&');
parts = queryString.replace(/\+/g, '%20').split('&');
for (var i = 0; i < parts.length; i++){
components = parts[i].split('=');
// split on first equal sign
var part = parts[i]
pos = part.indexOf('=');
if (pos >= 0) {
components = [
part.substr(0, pos),
part.substr(pos + 1)
]
}
else {
// key only
components = [part];
}
if (!components.length){
continue;
}
@ -391,8 +405,14 @@ var OC={
if (!key){
continue;
}
value = components[1];
result[key] = value && decodeURIComponent(value);
// if equal sign was there, return string
if (components.length > 1) {
result[key] = decodeURIComponent(components[1]);
}
// no equal sign => null value
else {
result[key] = null;
}
}
return result;
},

View file

@ -268,7 +268,72 @@ describe('Core base tests', function() {
// still nothing
expect(counter).toEqual(0);
});
});
describe('Parse query string', function() {
it('Parses query string from full URL', function() {
var query = OC.parseQueryString('http://localhost/stuff.php?q=a&b=x');
expect(query).toEqual({q: 'a', b: 'x'});
});
it('Parses query string from query part alone', function() {
var query = OC.parseQueryString('q=a&b=x');
expect(query).toEqual({q: 'a', b: 'x'});
});
it('Returns null hash when empty query', function() {
var query = OC.parseQueryString('');
expect(query).toEqual(null);
});
it('Returns empty hash when empty query with question mark', function() {
var query = OC.parseQueryString('?');
expect(query).toEqual({});
});
it('Decodes regular query strings', function() {
var query = OC.parseQueryString('a=abc&b=def');
expect(query).toEqual({
a: 'abc',
b: 'def'
});
});
it('Ignores empty parts', function() {
var query = OC.parseQueryString('&q=a&&b=x&');
expect(query).toEqual({q: 'a', b: 'x'});
});
it('Ignores lone equal signs', function() {
var query = OC.parseQueryString('&q=a&=&b=x&');
expect(query).toEqual({q: 'a', b: 'x'});
});
it('Includes extra equal signs in value', function() {
var query = OC.parseQueryString('u=a=x&q=a=b');
expect(query).toEqual({u: 'a=x', q: 'a=b'});
});
it('Decodes plus as space', function() {
var query = OC.parseQueryString('space+key=space+value');
expect(query).toEqual({'space key': 'space value'});
});
it('Decodes special characters', function() {
var query = OC.parseQueryString('unicode=%E6%B1%89%E5%AD%97');
expect(query).toEqual({unicode: '汉字'});
query = OC.parseQueryString('b=spaace%20value&space%20key=normalvalue&slash%2Fthis=amp%26ersand');
expect(query).toEqual({
b: 'spaace value',
'space key': 'normalvalue',
'slash/this': 'amp&ersand'
});
});
it('Decodes empty values', function() {
var query = OC.parseQueryString('keywithemptystring=&keywithnostring');
expect(query).toEqual({
'keywithemptystring': '',
'keywithnostring': null
});
});
it('Does not interpret data types', function() {
var query = OC.parseQueryString('booleanfalse=false&booleantrue=true&number=123');
expect(query).toEqual({
'booleanfalse': 'false',
'booleantrue': 'true',
'number': '123'
});
});
});
describe('Generate Url', function() {
it('returns absolute urls', function() {