test_SessionData.js (17190B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 const { ContextDescriptorType } = ChromeUtils.importESModule( 6 "chrome://remote/content/shared/messagehandler/MessageHandler.sys.mjs" 7 ); 8 const { RootMessageHandler } = ChromeUtils.importESModule( 9 "chrome://remote/content/shared/messagehandler/RootMessageHandler.sys.mjs" 10 ); 11 const { SessionData, SessionDataMethod } = ChromeUtils.importESModule( 12 "chrome://remote/content/shared/messagehandler/sessiondata/SessionData.sys.mjs" 13 ); 14 15 add_task(async function test_sessionData() { 16 const sessionData = new SessionData(new RootMessageHandler("session-id-1")); 17 equal(sessionData.getSessionData("mod", "event").length, 0); 18 19 const globalContext = { 20 type: ContextDescriptorType.All, 21 }; 22 const otherContext = { type: "other-type", id: "some-id" }; 23 24 info("Add a first event for the global context"); 25 let updatedItems = sessionData.applySessionData([ 26 createUpdate(SessionDataMethod.Add, globalContext, ["first.event"]), 27 ]); 28 equal(updatedItems.length, 1, "One item updated"); 29 equal(updatedItems[0].method, SessionDataMethod.Add, "One item added"); 30 let updatedValues = updatedItems[0].values; 31 equal(updatedValues.length, 1, "One value added"); 32 equal(updatedValues[0], "first.event", "Expected value was added"); 33 checkEvents(sessionData.getSessionData("mod", "event"), [ 34 { 35 value: "first.event", 36 contextDescriptor: globalContext, 37 }, 38 ]); 39 40 info("Add the exact same data (same module, type, context, value)"); 41 updatedItems = sessionData.applySessionData([ 42 createUpdate(SessionDataMethod.Add, globalContext, ["first.event"]), 43 ]); 44 equal(updatedItems.length, 0, "No new item updated"); 45 checkEvents(sessionData.getSessionData("mod", "event"), [ 46 { 47 value: "first.event", 48 contextDescriptor: globalContext, 49 }, 50 ]); 51 52 info("Add another context for the same event"); 53 updatedItems = sessionData.applySessionData([ 54 createUpdate(SessionDataMethod.Add, otherContext, ["first.event"]), 55 ]); 56 equal(updatedItems.length, 1, "One item updated"); 57 equal(updatedItems[0].method, SessionDataMethod.Add, "One item added"); 58 updatedValues = updatedItems[0].values; 59 equal(updatedValues.length, 1, "One value added"); 60 equal(updatedValues[0], "first.event", "Expected value was added"); 61 checkEvents(sessionData.getSessionData("mod", "event"), [ 62 { 63 value: "first.event", 64 contextDescriptor: globalContext, 65 }, 66 { 67 value: "first.event", 68 contextDescriptor: otherContext, 69 }, 70 ]); 71 72 info("Add a second event for the global context"); 73 updatedItems = sessionData.applySessionData([ 74 createUpdate(SessionDataMethod.Add, globalContext, ["second.event"]), 75 ]); 76 equal(updatedItems.length, 1, "One item updated"); 77 equal(updatedItems[0].method, SessionDataMethod.Add, "One item added"); 78 updatedValues = updatedItems[0].values; 79 equal(updatedValues.length, 1, "One value added"); 80 equal(updatedValues[0], "second.event", "Expected value was added"); 81 checkEvents(sessionData.getSessionData("mod", "event"), [ 82 { 83 value: "first.event", 84 contextDescriptor: globalContext, 85 }, 86 { 87 value: "first.event", 88 contextDescriptor: otherContext, 89 }, 90 { 91 value: "second.event", 92 contextDescriptor: globalContext, 93 }, 94 ]); 95 96 info("Add two events for the global context"); 97 updatedItems = sessionData.applySessionData([ 98 createUpdate(SessionDataMethod.Add, globalContext, [ 99 "third.event", 100 "fourth.event", 101 ]), 102 ]); 103 equal(updatedItems.length, 1, "One item updated"); 104 equal(updatedItems[0].method, SessionDataMethod.Add, "One item added"); 105 updatedValues = updatedItems[0].values; 106 equal(updatedValues.length, 2, "Two values added"); 107 equal(updatedValues[0], "third.event", "Expected value was added"); 108 equal(updatedValues[1], "fourth.event", "Expected value was added"); 109 checkEvents(sessionData.getSessionData("mod", "event"), [ 110 { 111 value: "first.event", 112 contextDescriptor: globalContext, 113 }, 114 { 115 value: "first.event", 116 contextDescriptor: otherContext, 117 }, 118 { 119 value: "second.event", 120 contextDescriptor: globalContext, 121 }, 122 { 123 value: "third.event", 124 contextDescriptor: globalContext, 125 }, 126 { 127 value: "fourth.event", 128 contextDescriptor: globalContext, 129 }, 130 ]); 131 132 info("Remove the second, third and fourth events"); 133 updatedItems = sessionData.applySessionData([ 134 createUpdate(SessionDataMethod.Remove, globalContext, [ 135 "second.event", 136 "third.event", 137 "fourth.event", 138 ]), 139 ]); 140 equal(updatedItems.length, 1, "One item updated"); 141 equal(updatedItems[0].method, SessionDataMethod.Remove, "One item removed"); 142 updatedValues = updatedItems[0].values; 143 equal(updatedValues.length, 3, "Three values removed"); 144 equal(updatedValues[0], "second.event", "Expected value was removed"); 145 equal(updatedValues[1], "third.event", "Expected value was removed"); 146 equal(updatedValues[2], "fourth.event", "Expected value was removed"); 147 checkEvents(sessionData.getSessionData("mod", "event"), [ 148 { 149 value: "first.event", 150 contextDescriptor: globalContext, 151 }, 152 { 153 value: "first.event", 154 contextDescriptor: otherContext, 155 }, 156 ]); 157 158 info("Remove the global context from the first event"); 159 updatedItems = sessionData.applySessionData([ 160 createUpdate(SessionDataMethod.Remove, globalContext, ["first.event"]), 161 ]); 162 equal(updatedItems.length, 1, "One item updated"); 163 equal(updatedItems[0].method, SessionDataMethod.Remove, "One item removed"); 164 updatedValues = updatedItems[0].values; 165 equal(updatedValues.length, 1, "One value removed"); 166 equal(updatedValues[0], "first.event", "Expected value was removed"); 167 checkEvents(sessionData.getSessionData("mod", "event"), [ 168 { 169 value: "first.event", 170 contextDescriptor: otherContext, 171 }, 172 ]); 173 174 info("Remove the other context from the first event"); 175 updatedItems = sessionData.applySessionData([ 176 createUpdate(SessionDataMethod.Remove, otherContext, ["first.event"]), 177 ]); 178 equal(updatedItems.length, 1, "One item updated"); 179 equal(updatedItems[0].method, SessionDataMethod.Remove, "One item removed"); 180 updatedValues = updatedItems[0].values; 181 equal(updatedValues.length, 1, "One value removed"); 182 equal(updatedValues[0], "first.event", "Expected value was removed"); 183 checkEvents(sessionData.getSessionData("mod", "event"), []); 184 185 info("Add two events for different contexts"); 186 updatedItems = sessionData.applySessionData([ 187 createUpdate(SessionDataMethod.Add, otherContext, ["first.event"]), 188 createUpdate(SessionDataMethod.Add, globalContext, ["second.event"]), 189 ]); 190 equal(updatedItems.length, 2, "Two items updated"); 191 equal(updatedItems[0].method, SessionDataMethod.Add, "First item added"); 192 updatedValues = updatedItems[0].values; 193 equal(updatedValues.length, 1, "One value for first item added"); 194 equal(updatedValues[0], "first.event", "Expected value first item was added"); 195 equal(updatedItems[1].method, SessionDataMethod.Add, "Second item added"); 196 updatedValues = updatedItems[1].values; 197 equal(updatedValues.length, 1, "One value for second item added"); 198 equal( 199 updatedValues[0], 200 "second.event", 201 "Expected value second item was added" 202 ); 203 checkEvents(sessionData.getSessionData("mod", "event"), [ 204 { 205 value: "first.event", 206 contextDescriptor: otherContext, 207 }, 208 { 209 value: "second.event", 210 contextDescriptor: globalContext, 211 }, 212 ]); 213 214 info("Remove two events for different contexts"); 215 updatedItems = sessionData.applySessionData([ 216 createUpdate(SessionDataMethod.Remove, otherContext, ["first.event"]), 217 createUpdate(SessionDataMethod.Remove, globalContext, ["second.event"]), 218 ]); 219 equal(updatedItems.length, 2, "Two items updated"); 220 equal(updatedItems[0].method, SessionDataMethod.Remove, "First item removed"); 221 updatedValues = updatedItems[0].values; 222 equal(updatedValues.length, 1, "One value for first item removed"); 223 equal( 224 updatedValues[0], 225 "first.event", 226 "Expected value first item was removed" 227 ); 228 equal( 229 updatedItems[1].method, 230 SessionDataMethod.Remove, 231 "Second item removed" 232 ); 233 updatedValues = updatedItems[1].values; 234 equal(updatedValues.length, 1, "One value for second item removed"); 235 equal( 236 updatedValues[0], 237 "second.event", 238 "Expected value second item was removed" 239 ); 240 checkEvents(sessionData.getSessionData("mod", "event"), []); 241 242 info("Add and remove event in different order"); 243 updatedItems = sessionData.applySessionData([ 244 createUpdate(SessionDataMethod.Remove, otherContext, ["first.event"]), 245 createUpdate(SessionDataMethod.Add, otherContext, ["first.event"]), 246 ]); 247 equal(updatedItems.length, 1, "One item updated"); 248 equal(updatedItems[0].method, SessionDataMethod.Add, "One item added"); 249 updatedValues = updatedItems[0].values; 250 equal(updatedValues.length, 1, "One value added"); 251 equal(updatedValues[0], "first.event", "Expected value was added"); 252 checkEvents(sessionData.getSessionData("mod", "event"), [ 253 { 254 value: "first.event", 255 contextDescriptor: otherContext, 256 }, 257 ]); 258 259 updatedItems = sessionData.applySessionData([ 260 createUpdate(SessionDataMethod.Add, otherContext, ["first.event"]), 261 createUpdate(SessionDataMethod.Remove, otherContext, ["first.event"]), 262 ]); 263 equal(updatedItems.length, 1, "No item update"); 264 equal(updatedItems[0].method, SessionDataMethod.Remove, "One item removed"); 265 updatedValues = updatedItems[0].values; 266 equal(updatedValues.length, 1, "One value removed"); 267 equal(updatedValues[0], "first.event", "Expected value was removed"); 268 checkEvents(sessionData.getSessionData("mod", "event"), []); 269 }); 270 271 add_task(function test_hasSessionData() { 272 const sessionData = new SessionData(new RootMessageHandler("session-id-1")); 273 274 ok( 275 !sessionData.hasSessionData("mod", "event"), 276 "Starts with no session data" 277 ); 278 279 const globalContext = { 280 type: ContextDescriptorType.All, 281 }; 282 const otherContext = { type: "other-type", id: "some-id" }; 283 284 sessionData.applySessionData([ 285 createUpdate(SessionDataMethod.Add, globalContext, ["test.event"]), 286 ]); 287 ok(sessionData.hasSessionData("mod", "event"), "Detects global context"); 288 sessionData.applySessionData([ 289 createUpdate(SessionDataMethod.Remove, globalContext, ["test.event"]), 290 ]); 291 ok( 292 !sessionData.hasSessionData("mod", "event"), 293 "Detects removal of global context data" 294 ); 295 296 sessionData.applySessionData([ 297 createUpdate(SessionDataMethod.Add, otherContext, ["other.event"]), 298 ]); 299 ok( 300 sessionData.hasSessionData("mod", "event"), 301 "Detects specific context data" 302 ); 303 304 sessionData.applySessionData([ 305 createUpdate(SessionDataMethod.Add, globalContext, ["global.event"]), 306 ]); 307 ok(sessionData.hasSessionData("mod", "event"), "Detects mixed context data"); 308 309 sessionData.applySessionData([ 310 createUpdate(SessionDataMethod.Remove, otherContext, ["other.event"]), 311 ]); 312 ok( 313 sessionData.hasSessionData("mod", "event"), 314 "Should still contain global context data" 315 ); 316 317 sessionData.applySessionData([ 318 createUpdate(SessionDataMethod.Remove, globalContext, ["global.event"]), 319 ]); 320 ok( 321 !sessionData.hasSessionData("mod", "event"), 322 "Should detect removal of all context data" 323 ); 324 325 const specificContext = { type: "specific-type", id: "some-id" }; 326 327 ok(!sessionData.hasSessionData("mod"), "Works without category"); 328 sessionData.applySessionData([ 329 createUpdate(SessionDataMethod.Add, specificContext, ["specific.event"]), 330 ]); 331 ok(sessionData.hasSessionData("mod"), "Detects without category"); 332 sessionData.applySessionData([ 333 createUpdate(SessionDataMethod.Remove, specificContext, ["specific.event"]), 334 ]); 335 336 ok( 337 !sessionData.hasSessionData("mod", "event", specificContext), 338 "No data for specific context initially" 339 ); 340 sessionData.applySessionData([ 341 createUpdate(SessionDataMethod.Add, specificContext, ["specific.event"]), 342 ]); 343 ok( 344 sessionData.hasSessionData("mod", "event", specificContext), 345 "Detects specific context data" 346 ); 347 ok( 348 !sessionData.hasSessionData("mod", "event", otherContext), 349 "Doesn't show for wrong context" 350 ); 351 sessionData.applySessionData([ 352 createUpdate(SessionDataMethod.Remove, specificContext, ["specific.event"]), 353 ]); 354 355 ok( 356 !sessionData.hasSessionData("non-existent-module"), 357 "Unknown module returns false" 358 ); 359 }); 360 361 add_task(async function test_getSessionDataForContext() { 362 const sessionData = new SessionData(new RootMessageHandler("session-id-1")); 363 364 const globalContextDescriptor = { 365 type: ContextDescriptorType.All, 366 }; 367 368 const userContextDescriptor = { 369 type: ContextDescriptorType.UserContext, 370 id: 1, 371 }; 372 373 const browsingContextDescriptor = { 374 type: ContextDescriptorType.TopBrowsingContext, 375 id: 2, 376 }; 377 378 sessionData.applySessionData([ 379 createUpdate(SessionDataMethod.Add, globalContextDescriptor, ["global"]), 380 createUpdate(SessionDataMethod.Add, userContextDescriptor, ["userContext"]), 381 createUpdate(SessionDataMethod.Add, browsingContextDescriptor, [ 382 "browsingContext", 383 ]), 384 ]); 385 386 const browsingContext1 = { 387 browserId: 2, 388 originAttributes: { 389 userContextId: 1, 390 }, 391 }; 392 393 const sessionDataForContext1 = sessionData.getSessionDataForContext( 394 "mod", 395 "event", 396 browsingContext1 397 ); 398 equal(sessionDataForContext1.length, 3, "Get 3 session data items"); 399 equal( 400 sessionDataForContext1[0].value, 401 "global", 402 "Get a session data item for the global context descriptor" 403 ); 404 equal( 405 sessionDataForContext1[1].value, 406 "userContext", 407 "Get a session data item for the user context descriptor" 408 ); 409 equal( 410 sessionDataForContext1[2].value, 411 "browsingContext", 412 "Get a session data item for the browsing context descriptor" 413 ); 414 415 const browsingContext2 = { 416 browserId: 3, 417 originAttributes: { 418 userContextId: 2, 419 }, 420 }; 421 422 const sessionDataForContext2 = sessionData.getSessionDataForContext( 423 "mod", 424 "event", 425 browsingContext2 426 ); 427 equal(sessionDataForContext2.length, 1, "Get 1 session data items"); 428 equal( 429 sessionDataForContext2[0].value, 430 "global", 431 "Get a session data item for the global context descriptor" 432 ); 433 434 const browsingContext3 = { 435 browserId: 4, 436 originAttributes: { 437 userContextId: 1, 438 }, 439 }; 440 441 const sessionDataForContext3 = sessionData.getSessionDataForContext( 442 "mod", 443 "event", 444 browsingContext3 445 ); 446 equal(sessionDataForContext3.length, 2, "Get 2 session data items"); 447 equal( 448 sessionDataForContext3[0].value, 449 "global", 450 "Get a session data item for the global context descriptor" 451 ); 452 equal( 453 sessionDataForContext3[1].value, 454 "userContext", 455 "Get a session data item for the user context descriptor" 456 ); 457 }); 458 459 add_task(async function test_generateSessionDataItemUpdate() { 460 const sessionData = new SessionData(new RootMessageHandler("session-id-1")); 461 462 const browsingContextDescriptor = { 463 type: ContextDescriptorType.TopBrowsingContext, 464 id: 2, 465 }; 466 467 sessionData.applySessionData([ 468 createUpdate(SessionDataMethod.Add, browsingContextDescriptor, [ 469 "old value", 470 ]), 471 ]); 472 473 const newValue = "new value"; 474 const sessionDataItemUpdates = sessionData.generateSessionDataItemUpdate( 475 "mod", 476 "event", 477 browsingContextDescriptor, 478 false, 479 newValue 480 ); 481 482 equal(sessionDataItemUpdates.length, 2, "Get 2 session data item updates"); 483 equal( 484 sessionDataItemUpdates[0].method, 485 SessionDataMethod.Remove, 486 "First update is to remove the old item" 487 ); 488 equal( 489 sessionDataItemUpdates[1].method, 490 SessionDataMethod.Add, 491 "Second update is to add the new item" 492 ); 493 equal(sessionDataItemUpdates[1].values[0], newValue, "The new value is set"); 494 495 const sessionDataItemUpdatesOnlyRemove = 496 sessionData.generateSessionDataItemUpdate( 497 "mod", 498 "event", 499 browsingContextDescriptor, 500 true, 501 newValue 502 ); 503 504 equal( 505 sessionDataItemUpdatesOnlyRemove.length, 506 1, 507 "Get 1 session data item update" 508 ); 509 equal( 510 sessionDataItemUpdatesOnlyRemove[0].method, 511 SessionDataMethod.Remove, 512 "Update is to remove the old item" 513 ); 514 }); 515 516 function checkEvents(events, expectedEvents) { 517 // Check the arrays have the same size. 518 equal(events.length, expectedEvents.length); 519 520 // Check all the expectedEvents can be found in the events array. 521 for (const expected of expectedEvents) { 522 ok( 523 events.some( 524 event => 525 expected.contextDescriptor.type === event.contextDescriptor.type && 526 expected.contextDescriptor.id === event.contextDescriptor.id && 527 expected.value == event.value 528 ) 529 ); 530 } 531 } 532 533 function createUpdate(method, contextDescriptor, values) { 534 return { 535 method, 536 moduleName: "mod", 537 category: "event", 538 contextDescriptor, 539 values, 540 }; 541 }