tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_MemoryStore.js (6580B)


      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
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 const { MemoryStore } = ChromeUtils.importESModule(
      8  "moz-src:///browser/components/aiwindow/services/MemoryStore.sys.mjs"
      9 );
     10 
     11 add_task(async function test_init_empty_state() {
     12  // First init should succeed and not throw.
     13  await MemoryStore.ensureInitialized();
     14 
     15  let memories = await MemoryStore.getMemories();
     16  equal(memories.length, 0, "New store should start with no memories");
     17 
     18  const meta = await MemoryStore.getMeta();
     19  equal(
     20    meta.last_history_memory_ts,
     21    0,
     22    "Default last_history_memory_ts should be 0"
     23  );
     24  equal(meta.last_chat_memory_ts, 0, "Default last_chat_memory_ts should be 0");
     25 });
     26 
     27 add_task(async function test_addMemory() {
     28  await MemoryStore.ensureInitialized();
     29 
     30  const memory1 = await MemoryStore.addMemory({
     31    memory_summary: "i love driking coffee",
     32    category: "Food & Drink",
     33    intent: "Plan / Organize",
     34    score: 3,
     35  });
     36 
     37  equal(
     38    memory1.memory_summary,
     39    "i love driking coffee",
     40    "memory summary should match input"
     41  );
     42  equal(memory1.category, "Food & Drink", "Category should match input");
     43  equal(memory1.intent, "Plan / Organize", "Intent should match with input");
     44  equal(memory1.score, 3, "Score should match input");
     45  await MemoryStore.hardDeleteMemory(memory1.id);
     46 });
     47 
     48 add_task(async function test_addMemory_and_upsert_by_content() {
     49  await MemoryStore.ensureInitialized();
     50 
     51  const memory1 = await MemoryStore.addMemory({
     52    memory_summary: "trip plans to Italy",
     53    category: "Travel & Transportation",
     54    intent: "Plan / Organize",
     55    score: 3,
     56  });
     57 
     58  ok(memory1.id, "Memory should have an id");
     59  equal(
     60    memory1.memory_summary,
     61    "trip plans to Italy",
     62    "Memory summary should be stored"
     63  );
     64 
     65  // Add another memory with same (summary, category, intent) – should upsert, not duplicate.
     66  const memory2 = await MemoryStore.addMemory({
     67    memory_summary: "trip plans to Italy",
     68    category: "Travel & Transportation",
     69    intent: "Plan / Organize",
     70    score: 5,
     71  });
     72 
     73  equal(
     74    memory1.id,
     75    memory2.id,
     76    "Same (summary, category, intent) should produce same deterministic id"
     77  );
     78  equal(
     79    memory2.score,
     80    5,
     81    "Second addMemory call for same id should update score"
     82  );
     83 
     84  const memories = await MemoryStore.getMemories();
     85  equal(memories.length, 1, "Store should still have only one memory");
     86  await MemoryStore.hardDeleteMemory(memory1.id);
     87 });
     88 
     89 add_task(async function test_addMemory_different_intent_produces_new_id() {
     90  await MemoryStore.ensureInitialized();
     91 
     92  const a = await MemoryStore.addMemory({
     93    memory_summary: "trip plans to Italy",
     94    category: "Travel & Transportation",
     95    intent: "trip_planning",
     96    score: 3,
     97  });
     98 
     99  const b = await MemoryStore.addMemory({
    100    memory_summary: "trip plans to Italy",
    101    category: "Travel & Transportation",
    102    intent: "travel_budgeting",
    103    score: 4,
    104  });
    105 
    106  notEqual(a.id, b.id, "Different intent should yield different ids");
    107 
    108  const memories = await MemoryStore.getMemories();
    109  equal(
    110    memories.length == 2,
    111    true,
    112    "Store should contain at least two memories now"
    113  );
    114 });
    115 
    116 add_task(async function test_updateMemory_and_soft_delete() {
    117  await MemoryStore.ensureInitialized();
    118 
    119  const memory = await MemoryStore.addMemory({
    120    memory_summary: "debug memory",
    121    category: "debug",
    122    intent: "Monitor / Track",
    123    score: 1,
    124  });
    125 
    126  const updated = await MemoryStore.updateMemory(memory.id, {
    127    score: 4,
    128  });
    129  equal(updated.score, 4, "updateMemory should update fields");
    130 
    131  const deleted = await MemoryStore.softDeleteMemory(memory.id);
    132 
    133  ok(deleted, "softDeleteMemory should return the updated memory");
    134  equal(
    135    deleted.is_deleted,
    136    true,
    137    "Soft-deleted memory should have is_deleted = true"
    138  );
    139 
    140  const nonDeleted = await MemoryStore.getMemories();
    141  const notFound = nonDeleted.find(i => i.id === memory.id);
    142  equal(
    143    notFound,
    144    undefined,
    145    "Soft-deleted memory should be filtered out by getMemories()"
    146  );
    147 });
    148 
    149 add_task(async function test_hard_delete() {
    150  await MemoryStore.ensureInitialized();
    151 
    152  const memory = await MemoryStore.addMemory({
    153    memory_summary: "to be hard deleted",
    154    category: "debug",
    155    intent: "Monitor / Track",
    156    score: 2,
    157  });
    158 
    159  let memories = await MemoryStore.getMemories();
    160  const beforeCount = memories.length;
    161 
    162  const removed = await MemoryStore.hardDeleteMemory(memory.id);
    163  equal(
    164    removed,
    165    true,
    166    "hardDeleteMemory should return true when removing existing memory"
    167  );
    168 
    169  memories = await MemoryStore.getMemories();
    170  const afterCount = memories.length;
    171 
    172  equal(
    173    beforeCount - 1,
    174    afterCount,
    175    "hardDeleteMemory should physically remove entry from array"
    176  );
    177 });
    178 
    179 add_task(async function test_updateMeta_and_persistence_roundtrip() {
    180  await MemoryStore.ensureInitialized();
    181 
    182  const now = Date.now();
    183 
    184  await MemoryStore.updateMeta({
    185    last_history_memory_ts: now,
    186  });
    187 
    188  let meta = await MemoryStore.getMeta();
    189  equal(
    190    meta.last_history_memory_ts,
    191    now,
    192    "updateMeta should update last_history_memory_ts"
    193  );
    194  equal(
    195    meta.last_chat_memory_ts,
    196    0,
    197    "updateMeta should not touch last_chat_memory_ts when not provided"
    198  );
    199 
    200  const chatTime = now + 1000;
    201  await MemoryStore.updateMeta({
    202    last_chat_memory_ts: chatTime,
    203  });
    204 
    205  meta = await MemoryStore.getMeta();
    206  equal(
    207    meta.last_history_memory_ts,
    208    now,
    209    "last_history_memory_ts should remain unchanged when only chat ts updated"
    210  );
    211  equal(
    212    meta.last_chat_memory_ts,
    213    chatTime,
    214    "last_chat_memory_ts should be updated"
    215  );
    216 
    217  // Force a write to disk.
    218  await MemoryStore.testOnlyFlush();
    219 
    220  // Simulate a fresh import by reloading module.
    221  // This uses the xpcshell helper to bypass module caching.
    222  const { MemoryStore: FreshStore } = ChromeUtils.importESModule(
    223    "moz-src:///browser/components/aiwindow/services/MemoryStore.sys.mjs",
    224    { ignoreCache: true }
    225  );
    226 
    227  await FreshStore.ensureInitialized();
    228 
    229  const meta2 = await FreshStore.getMeta();
    230  equal(
    231    meta2.last_history_memory_ts,
    232    now,
    233    "last_history_memory_ts should survive roundtrip to disk"
    234  );
    235  equal(
    236    meta2.last_chat_memory_ts,
    237    chatTime,
    238    "last_chat_memory_ts should survive roundtrip to disk"
    239  );
    240 
    241  const memories = await FreshStore.getMemories();
    242  ok(Array.isArray(memories), "Memories should be an array after reload");
    243 });