diff options
Diffstat (limited to '')
-rw-r--r-- | netwerk/test/unit/test_http_sfv.js | 597 |
1 files changed, 597 insertions, 0 deletions
diff --git a/netwerk/test/unit/test_http_sfv.js b/netwerk/test/unit/test_http_sfv.js new file mode 100644 index 0000000000..4b7ec9893c --- /dev/null +++ b/netwerk/test/unit/test_http_sfv.js @@ -0,0 +1,597 @@ +"use strict"; + +const gService = Cc["@mozilla.org/http-sfv-service;1"].getService( + Ci.nsISFVService +); + +add_task(async function test_sfv_bare_item() { + // tests bare item + let item_int = gService.newInteger(19); + Assert.equal(item_int.value, 19, "check bare item value"); + + let item_bool = gService.newBool(true); + Assert.equal(item_bool.value, true, "check bare item value"); + item_bool.value = false; + Assert.equal(item_bool.value, false, "check bare item value"); + + let item_float = gService.newDecimal(145.45); + Assert.equal(item_float.value, 145.45); + + let item_str = gService.newString("some_string"); + Assert.equal(item_str.value, "some_string", "check bare item value"); + + let item_byte_seq = gService.newByteSequence("aGVsbG8="); + Assert.equal(item_byte_seq.value, "aGVsbG8=", "check bare item value"); + + let item_token = gService.newToken("*a"); + Assert.equal(item_token.value, "*a", "check bare item value"); +}); + +add_task(async function test_sfv_params() { + // test params + let params = gService.newParameters(); + let bool_param = gService.newBool(false); + let int_param = gService.newInteger(15); + let decimal_param = gService.newDecimal(15.45); + + params.set("bool_param", bool_param); + params.set("int_param", int_param); + params.set("decimal_param", decimal_param); + + Assert.throws( + () => { + params.get("some_param"); + }, + /NS_ERROR_UNEXPECTED/, + "must throw exception as key does not exist in parameters" + ); + Assert.equal( + params.get("bool_param").QueryInterface(Ci.nsISFVBool).value, + false, + "get parameter by key and check its value" + ); + Assert.equal( + params.get("int_param").QueryInterface(Ci.nsISFVInteger).value, + 15, + "get parameter by key and check its value" + ); + Assert.equal( + params.get("decimal_param").QueryInterface(Ci.nsISFVDecimal).value, + 15.45, + "get parameter by key and check its value" + ); + Assert.deepEqual( + params.keys(), + ["bool_param", "int_param", "decimal_param"], + "check that parameters contain all the expected keys" + ); + + params.delete("int_param"); + Assert.deepEqual( + params.keys(), + ["bool_param", "decimal_param"], + "check that parameter has been deleted" + ); + + Assert.throws( + () => { + params.delete("some_param"); + }, + /NS_ERROR_UNEXPECTED/, + "must throw exception upon attempt to delete by non-existing key" + ); +}); + +add_task(async function test_sfv_inner_list() { + // create primitives for inner list + let item1_params = gService.newParameters(); + item1_params.set("param_1", gService.newToken("*smth")); + let item1 = gService.newItem(gService.newDecimal(172.145865), item1_params); + + let item2_params = gService.newParameters(); + item2_params.set("param_1", gService.newBool(true)); + item2_params.set("param_2", gService.newInteger(145454)); + let item2 = gService.newItem( + gService.newByteSequence("weather"), + item2_params + ); + + // create inner list + let inner_list_params = gService.newParameters(); + inner_list_params.set("inner_param", gService.newByteSequence("tests")); + let inner_list = gService.newInnerList([item1, item2], inner_list_params); + + // check inner list members & params + let inner_list_members = inner_list.QueryInterface(Ci.nsISFVInnerList).items; + let inner_list_parameters = inner_list + .QueryInterface(Ci.nsISFVInnerList) + .params.QueryInterface(Ci.nsISFVParams); + Assert.equal(inner_list_members.length, 2, "check inner list length"); + + let inner_item1 = inner_list_members[0].QueryInterface(Ci.nsISFVItem); + Assert.equal( + inner_item1.value.QueryInterface(Ci.nsISFVDecimal).value, + 172.145865, + "check inner list member value" + ); + + let inner_item2 = inner_list_members[1].QueryInterface(Ci.nsISFVItem); + Assert.equal( + inner_item2.value.QueryInterface(Ci.nsISFVByteSeq).value, + "weather", + "check inner list member value" + ); + + Assert.equal( + inner_list_parameters.get("inner_param").QueryInterface(Ci.nsISFVByteSeq) + .value, + "tests", + "get inner list parameter by key and check its value" + ); +}); + +add_task(async function test_sfv_item() { + // create parameters for item + let params = gService.newParameters(); + let param1 = gService.newBool(false); + let param2 = gService.newString("str_value"); + let param3 = gService.newBool(true); + params.set("param_1", param1); + params.set("param_2", param2); + params.set("param_3", param3); + + // create item field + let item = gService.newItem(gService.newToken("*abc"), params); + + Assert.equal( + item.value.QueryInterface(Ci.nsISFVToken).value, + "*abc", + "check items's value" + ); + Assert.equal( + item.params.get("param_1").QueryInterface(Ci.nsISFVBool).value, + false, + "get item parameter by key and check its value" + ); + Assert.equal( + item.params.get("param_2").QueryInterface(Ci.nsISFVString).value, + "str_value", + "get item parameter by key and check its value" + ); + Assert.equal( + item.params.get("param_3").QueryInterface(Ci.nsISFVBool).value, + true, + "get item parameter by key and check its value" + ); + + // check item field serialization + let serialized = item.serialize(); + Assert.equal( + serialized, + `*abc;param_1=?0;param_2="str_value";param_3`, + "serialized output must match expected one" + ); +}); + +add_task(async function test_sfv_list() { + // create primitives for List + let item1_params = gService.newParameters(); + item1_params.set("param_1", gService.newToken("*smth")); + let item1 = gService.newItem(gService.newDecimal(145454.14568), item1_params); + + let item2_params = gService.newParameters(); + item2_params.set("param_1", gService.newBool(true)); + let item2 = gService.newItem( + gService.newByteSequence("weather"), + item2_params + ); + + let inner_list = gService.newInnerList( + [item1, item2], + gService.newParameters() + ); + + // create list field + let list = gService.newList([item1, inner_list]); + + // check list's members + let list_members = list.members; + Assert.equal(list_members.length, 2, "check list length"); + + // check list's member of item type + let member1 = list_members[0].QueryInterface(Ci.nsISFVItem); + Assert.equal( + member1.value.QueryInterface(Ci.nsISFVDecimal).value, + 145454.14568, + "check list member's value" + ); + let member1_parameters = member1.params; + Assert.equal( + member1_parameters.get("param_1").QueryInterface(Ci.nsISFVToken).value, + "*smth", + "get list member's parameter by key and check its value" + ); + + // check list's member of inner list type + let inner_list_members = list_members[1].QueryInterface( + Ci.nsISFVInnerList + ).items; + Assert.equal(inner_list_members.length, 2, "check inner list length"); + + let inner_item1 = inner_list_members[0].QueryInterface(Ci.nsISFVItem); + Assert.equal( + inner_item1.value.QueryInterface(Ci.nsISFVDecimal).value, + 145454.14568, + "check inner list member's value" + ); + + let inner_item2 = inner_list_members[1].QueryInterface(Ci.nsISFVItem); + Assert.equal( + inner_item2.value.QueryInterface(Ci.nsISFVByteSeq).value, + "weather", + "check inner list member's value" + ); + + // check inner list member's params + list_members[1] + .QueryInterface(Ci.nsISFVInnerList) + .params.QueryInterface(Ci.nsISFVParams); + + // check serialization of list field + let expected_serialized = + "145454.146;param_1=*smth, (145454.146;param_1=*smth :d2VhdGhlcg==:;param_1)"; + let actual_serialized = list.serialize(); + Assert.equal( + actual_serialized, + expected_serialized, + "serialized output must match expected one" + ); +}); + +add_task(async function test_sfv_dictionary() { + // create primitives for dictionary field + + // dict member1 + let params1 = gService.newParameters(); + params1.set("mp_1", gService.newBool(true)); + params1.set("mp_2", gService.newDecimal(68.758602)); + let member1 = gService.newItem(gService.newString("member_1"), params1); + + // dict member2 + let params2 = gService.newParameters(); + let inner_item1 = gService.newItem( + gService.newString("inner_item_1"), + gService.newParameters() + ); + let inner_item2 = gService.newItem( + gService.newToken("tok"), + gService.newParameters() + ); + let member2 = gService.newInnerList([inner_item1, inner_item2], params2); + + // dict member3 + let params_3 = gService.newParameters(); + params_3.set("mp_1", gService.newInteger(6586)); + let member3 = gService.newItem(gService.newString("member_3"), params_3); + + // create dictionary field + let dict = gService.newDictionary(); + dict.set("key_1", member1); + dict.set("key_2", member2); + dict.set("key_3", member3); + + // check dictionary keys + let expected = ["key_1", "key_2", "key_3"]; + Assert.deepEqual( + expected, + dict.keys(), + "check dictionary contains all the expected keys" + ); + + // check dictionary members + Assert.throws( + () => { + dict.get("key_4"); + }, + /NS_ERROR_UNEXPECTED/, + "must throw exception as key does not exist in dictionary" + ); + + // let dict_member1 = dict.get("key_1").QueryInterface(Ci.nsISFVItem); + let dict_member2 = dict.get("key_2").QueryInterface(Ci.nsISFVInnerList); + let dict_member3 = dict.get("key_3").QueryInterface(Ci.nsISFVItem); + + // Assert.equal( + // dict_member1.value.QueryInterface(Ci.nsISFVString).value, + // "member_1", + // "check dictionary member's value" + // ); + // Assert.equal( + // dict_member1.params.get("mp_1").QueryInterface(Ci.nsISFVBool).value, + // true, + // "get dictionary member's parameter by key and check its value" + // ); + // Assert.equal( + // dict_member1.params.get("mp_2").QueryInterface(Ci.nsISFVDecimal).value, + // "68.758602", + // "get dictionary member's parameter by key and check its value" + // ); + + let dict_member2_items = dict_member2.QueryInterface( + Ci.nsISFVInnerList + ).items; + let dict_member2_params = dict_member2 + .QueryInterface(Ci.nsISFVInnerList) + .params.QueryInterface(Ci.nsISFVParams); + Assert.equal( + dict_member2_items[0] + .QueryInterface(Ci.nsISFVItem) + .value.QueryInterface(Ci.nsISFVString).value, + "inner_item_1", + "get dictionary member of inner list type, and check inner list member's value" + ); + Assert.equal( + dict_member2_items[1] + .QueryInterface(Ci.nsISFVItem) + .value.QueryInterface(Ci.nsISFVToken).value, + "tok", + "get dictionary member of inner list type, and check inner list member's value" + ); + Assert.throws( + () => { + dict_member2_params.get("some_param"); + }, + /NS_ERROR_UNEXPECTED/, + "must throw exception as dict member's parameters are empty" + ); + + Assert.equal( + dict_member3.value.QueryInterface(Ci.nsISFVString).value, + "member_3", + "check dictionary member's value" + ); + Assert.equal( + dict_member3.params.get("mp_1").QueryInterface(Ci.nsISFVInteger).value, + 6586, + "get dictionary member's parameter by key and check its value" + ); + + // check serialization of Dictionary field + let expected_serialized = `key_1="member_1";mp_1;mp_2=68.759, key_2=("inner_item_1" tok), key_3="member_3";mp_1=6586`; + let actual_serialized = dict.serialize(); + Assert.equal( + actual_serialized, + expected_serialized, + "serialized output must match expected one" + ); + + // check deleting dict member + dict.delete("key_2"); + Assert.deepEqual( + dict.keys(), + ["key_1", "key_3"], + "check that dictionary member has been deleted" + ); + + Assert.throws( + () => { + dict.delete("some_key"); + }, + /NS_ERROR_UNEXPECTED/, + "must throw exception upon attempt to delete by non-existing key" + ); +}); + +add_task(async function test_sfv_item_parsing() { + Assert.ok(gService.parseItem(`"str"`), "input must be parsed into Item"); + Assert.ok(gService.parseItem("12.35;a "), "input must be parsed into Item"); + Assert.ok(gService.parseItem("12.35; a "), "input must be parsed into Item"); + Assert.ok(gService.parseItem("12.35 "), "input must be parsed into Item"); + + Assert.throws( + () => { + gService.parseItem("12.35;\ta "); + }, + /NS_ERROR_FAILURE/, + "item parsing must fail: invalid parameters delimiter" + ); + + Assert.throws( + () => { + gService.parseItem("125666.3565648855455"); + }, + /NS_ERROR_FAILURE/, + "item parsing must fail: decimal too long" + ); +}); + +add_task(async function test_sfv_list_parsing() { + Assert.ok( + gService.parseList( + "(?1;param_1=*smth :d2VhdGhlcg==:;param_1;param_2=145454);inner_param=:d2VpcmR0ZXN0cw==:" + ), + "input must be parsed into List" + ); + Assert.ok("a, (b c)", "input must be parsed into List"); + + Assert.throws(() => { + gService.parseList("?tok", "list parsing must fail"); + }, /NS_ERROR_FAILURE/); + + Assert.throws(() => { + gService.parseList( + "a, (b, c)", + "list parsing must fail: invalid delimiter within inner list" + ); + }, /NS_ERROR_FAILURE/); + + Assert.throws( + () => { + gService.parseList("a, b c"); + }, + /NS_ERROR_FAILURE/, + "list parsing must fail: invalid delimiter" + ); +}); + +add_task(async function test_sfv_dict_parsing() { + Assert.ok( + gService.parseDictionary(`abc=123;a=1;b=2, def=456, ghi=789;q=9;r="+w"`), + "input must be parsed into Dictionary" + ); + Assert.ok( + gService.parseDictionary("a=1\t,\t\t\t c=*"), + "input must be parsed into Dictionary" + ); + Assert.ok( + gService.parseDictionary("a=1\t,\tc=* \t\t"), + "input must be parsed into Dictionary" + ); + + Assert.throws( + () => { + gService.parseDictionary("a=1\t,\tc=*,"); + }, + /NS_ERROR_FAILURE/, + "dictionary parsing must fail: trailing comma" + ); + + Assert.throws( + () => { + gService.parseDictionary("a=1 c=*"); + }, + /NS_ERROR_FAILURE/, + "dictionary parsing must fail: invalid delimiter" + ); + + Assert.throws( + () => { + gService.parseDictionary("INVALID_key=1, c=*"); + }, + /NS_ERROR_FAILURE/, + "dictionary parsing must fail: invalid key format, can't be in uppercase" + ); +}); + +add_task(async function test_sfv_list_parse_serialize() { + let list_field = gService.parseList("1 , 42, (42 43)"); + Assert.equal( + list_field.serialize(), + "1, 42, (42 43)", + "serialized output must match expected one" + ); + + // create new inner list with parameters + function params() { + let inner_list_params = gService.newParameters(); + inner_list_params.set("key1", gService.newString("value1")); + inner_list_params.set("key2", gService.newBool(true)); + inner_list_params.set("key3", gService.newBool(false)); + return inner_list_params; + } + + function changeMembers() { + // set one of list members to inner list and check it's serialized as expected + let members = list_field.members; + members[1] = gService.newInnerList( + [ + gService.newItem( + gService.newDecimal(-1865.75653), + gService.newParameters() + ), + gService.newItem(gService.newToken("token"), gService.newParameters()), + gService.newItem( + gService.newString(`no"yes`), + gService.newParameters() + ), + ], + params() + ); + return members; + } + + list_field.members = changeMembers(); + + Assert.equal( + list_field.serialize(), + `1, (-1865.757 token "no\\"yes");key1="value1";key2;key3=?0, (42 43)`, + "update list member and check list is serialized as expected" + ); +}); + +add_task(async function test_sfv_dict_parse_serialize() { + let dict_field = gService.parseDictionary( + "a=1, b; foo=*, \tc=3, \t \tabc=123;a=1;b=2\t" + ); + Assert.equal( + dict_field.serialize(), + "a=1, b;foo=*, c=3, abc=123;a=1;b=2", + "serialized output must match expected one" + ); + + // set new value for existing dict's key + dict_field.set( + "a", + gService.newItem(gService.newInteger(165), gService.newParameters()) + ); + + // add new member to dict + dict_field.set( + "key", + gService.newItem(gService.newDecimal(45.0), gService.newParameters()) + ); + + // check dict is serialized properly after the above changes + Assert.equal( + dict_field.serialize(), + "a=165, b;foo=*, c=3, abc=123;a=1;b=2, key=45.0", + "update dictionary members and dictionary list is serialized as expected" + ); +}); + +add_task(async function test_sfv_list_parse_more() { + // check parsing of multiline header of List type + let list_field = gService.parseList("(12 abc), 12.456\t\t "); + list_field.parseMore("11, 15, tok"); + Assert.equal( + list_field.serialize(), + "(12 abc), 12.456, 11, 15, tok", + "multi-line field value parsed and serialized successfully" + ); + + // should fail parsing one more line + Assert.throws( + () => { + list_field.parseMore("(tk\t1)"); + }, + /NS_ERROR_FAILURE/, + "line parsing must fail: invalid delimiter in inner list" + ); + Assert.equal( + list_field.serialize(), + "(12 abc), 12.456, 11, 15, tok", + "parsed value must not change if parsing one more line of header fails" + ); +}); + +add_task(async function test_sfv_dict_parse_more() { + // check parsing of multiline header of Dictionary type + let dict_field = gService.parseDictionary(""); + dict_field.parseMore("key2=?0, key3=?1, key4=itm"); + dict_field.parseMore("key1, key5=11, key4=45"); + + Assert.equal( + dict_field.serialize(), + "key2=?0, key3, key4=45, key1, key5=11", + "multi-line field value parsed and serialized successfully" + ); + + // should fail parsing one more line + Assert.throws( + () => { + dict_field.parseMore("c=12, _k=13"); + }, + /NS_ERROR_FAILURE/, + "line parsing must fail: invalid key format" + ); +}); |