summaryrefslogtreecommitdiffstats
path: root/comm/calendar/test/unit/test_calmgr.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /comm/calendar/test/unit/test_calmgr.js
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/calendar/test/unit/test_calmgr.js')
-rw-r--r--comm/calendar/test/unit/test_calmgr.js411
1 files changed, 411 insertions, 0 deletions
diff --git a/comm/calendar/test/unit/test_calmgr.js b/comm/calendar/test/unit/test_calmgr.js
new file mode 100644
index 0000000000..e4d09db0a3
--- /dev/null
+++ b/comm/calendar/test/unit/test_calmgr.js
@@ -0,0 +1,411 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
+var { CalReadableStreamFactory } = ChromeUtils.import(
+ "resource:///modules/CalReadableStreamFactory.jsm"
+);
+var { XPCOMUtils } = ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs");
+
+XPCOMUtils.defineLazyModuleGetters(this, {
+ CalEvent: "resource:///modules/CalEvent.jsm",
+});
+
+/**
+ * Tests the calICalendarManager interface
+ */
+function run_test() {
+ do_calendar_startup(run_next_test);
+}
+
+class CalendarManagerObserver {
+ QueryInterface = ChromeUtils.generateQI(["calICalendarManager"]);
+
+ constructor() {
+ this.reset();
+ }
+
+ reset() {
+ this.registered = [];
+ this.unregistering = [];
+ this.deleting = [];
+ }
+
+ check({ unregistering, registered, deleting }) {
+ equal(this.unregistering[0], unregistering);
+ equal(this.registered[0], registered);
+ equal(this.deleting[0], deleting);
+
+ this.reset();
+ }
+
+ onCalendarRegistered(calendar) {
+ this.registered.push(calendar.id);
+ }
+
+ onCalendarUnregistering(calendar) {
+ this.unregistering.push(calendar.id);
+ }
+
+ onCalendarDeleting(calendar) {
+ this.deleting.push(calendar.id);
+ }
+}
+
+add_test(function test_builtin_registration() {
+ function checkCalendarCount(net, rdonly, all) {
+ equal(cal.manager.networkCalendarCount, net);
+ equal(cal.manager.readOnlyCalendarCount, rdonly);
+ equal(cal.manager.calendarCount, all);
+ }
+
+ // Initially there should be no calendars.
+ checkCalendarCount(0, 0, 0);
+
+ // Create a local memory calendar, this shouldn't register any calendars.
+ let memory = cal.manager.createCalendar("memory", Services.io.newURI("moz-memory-calendar://"));
+ checkCalendarCount(0, 0, 0);
+
+ // Register an observer to test it.
+ let calmgrObserver = new CalendarManagerObserver();
+
+ let readOnly = false;
+ let calendarObserver = cal.createAdapter(Ci.calIObserver, {
+ onPropertyChanged(aCalendar, aName, aValue, aOldValue) {
+ equal(aCalendar.id, memory.id);
+ equal(aName, "readOnly");
+ readOnly = aValue;
+ },
+ });
+
+ memory.addObserver(calendarObserver);
+ cal.manager.addObserver(calmgrObserver);
+
+ // Register the calendar and check if its counted and observed.
+ cal.manager.registerCalendar(memory);
+ calmgrObserver.check({ registered: memory.id });
+ checkCalendarCount(0, 0, 1);
+
+ // The calendar should now have an id.
+ notEqual(memory.id, null);
+
+ // And be in the list of calendars.
+ equal(memory, cal.manager.getCalendarById(memory.id));
+ ok(cal.manager.getCalendars().some(x => x.id == memory.id));
+
+ // Make it readonly and check if the observer caught it.
+ memory.setProperty("readOnly", true);
+ equal(readOnly, true);
+
+ // Now unregister it.
+ cal.manager.unregisterCalendar(memory);
+ calmgrObserver.check({ unregistering: memory.id });
+ checkCalendarCount(0, 0, 0);
+
+ // The calendar shouldn't be in the list of ids.
+ equal(cal.manager.getCalendarById(memory.id), null);
+ ok(cal.manager.getCalendars().every(x => x.id != memory.id));
+
+ // And finally delete it.
+ cal.manager.removeCalendar(memory, Ci.calICalendarManager.REMOVE_NO_UNREGISTER);
+ calmgrObserver.check({ deleting: memory.id });
+ checkCalendarCount(0, 0, 0);
+
+ // Now remove the observer again.
+ cal.manager.removeObserver(calmgrObserver);
+ memory.removeObserver(calendarObserver);
+
+ // Check if removing it actually worked.
+ cal.manager.registerCalendar(memory);
+ cal.manager.removeCalendar(memory);
+ memory.setProperty("readOnly", false);
+ calmgrObserver.check({});
+ equal(readOnly, true);
+ checkCalendarCount(0, 0, 0);
+
+ // We are done now, start the next test.
+ run_next_test();
+});
+
+add_task(async function test_dynamic_registration() {
+ class CalendarProvider extends cal.provider.BaseClass {
+ QueryInterface = ChromeUtils.generateQI(["calICalendar"]);
+ type = "blm";
+
+ constructor() {
+ super();
+ this.initProviderBase();
+ }
+
+ getItems(itemFilter, count, rangeStart, rangeEnd, listener) {
+ return CalReadableStreamFactory.createEmptyReadableStream();
+ }
+ }
+
+ function checkCalendar(expectedCount = 1) {
+ let calendars = cal.manager.getCalendars();
+ equal(calendars.length, expectedCount);
+ let calendar = calendars[0];
+
+ if (expectedCount > 0) {
+ notEqual(calendar, null);
+ }
+ return calendar;
+ }
+
+ let calmgrObserver = new CalendarManagerObserver();
+ cal.manager.addObserver(calmgrObserver);
+ equal(cal.manager.calendarCount, 0);
+
+ // No provider registered.
+ let calendar = cal.manager.createCalendar("blm", Services.io.newURI("black-lives-matter://"));
+ equal(calendar, null);
+ ok(!cal.manager.hasCalendarProvider("blm"));
+
+ // Register dynamic provider.
+ cal.manager.registerCalendarProvider("blm", CalendarProvider);
+ calendar = cal.manager.createCalendar("blm", Services.io.newURI("black-lives-matter://"));
+ notEqual(calendar, null);
+ ok(calendar.wrappedJSObject instanceof CalendarProvider);
+ ok(cal.manager.hasCalendarProvider("blm"));
+
+ // Register a calendar using it.
+ cal.manager.registerCalendar(calendar);
+ calendar = checkCalendar();
+
+ let originalId = calendar.id;
+ calmgrObserver.check({ registered: originalId });
+
+ // Unregister the provider from under its feet.
+ cal.manager.unregisterCalendarProvider("blm");
+ calendar = checkCalendar();
+ calmgrObserver.check({ unregistering: originalId, registered: originalId });
+
+ equal(calendar.type, "blm");
+ equal(calendar.getProperty("force-disabled"), true);
+ equal(calendar.id, originalId);
+
+ // Re-register the provider should reactive it.
+ cal.manager.registerCalendarProvider("blm", CalendarProvider);
+ calendar = checkCalendar();
+ calmgrObserver.check({ unregistering: originalId, registered: originalId });
+
+ equal(calendar.type, "blm");
+ notEqual(calendar.getProperty("force-disabled"), true);
+ equal(calendar.id, originalId);
+
+ // Make sure calendar is loaded from prefs.
+ cal.manager.unregisterCalendarProvider("blm");
+ calmgrObserver.check({ unregistering: originalId, registered: originalId });
+
+ await new Promise(resolve => cal.manager.shutdown({ onResult: resolve }));
+ cal.manager.wrappedJSObject.mCache = null;
+ await new Promise(resolve => cal.manager.startup({ onResult: resolve }));
+ calmgrObserver.check({});
+
+ calendar = checkCalendar();
+ equal(calendar.type, "blm");
+ equal(calendar.getProperty("force-disabled"), true);
+ equal(calendar.id, originalId);
+
+ // Unregister the calendar for cleanup.
+ cal.manager.unregisterCalendar(calendar);
+ checkCalendar(0);
+ calmgrObserver.check({ unregistering: originalId });
+});
+
+add_test(function test_calobserver() {
+ function checkCounters(add, modify, del, alladd, allmodify, alldel) {
+ equal(calcounter.addItem, add);
+ equal(calcounter.modifyItem, modify);
+ equal(calcounter.deleteItem, del);
+ equal(allcounter.addItem, alladd === undefined ? add : alladd);
+ equal(allcounter.modifyItem, allmodify === undefined ? modify : allmodify);
+ equal(allcounter.deleteItem, alldel === undefined ? del : alldel);
+ resetCounters();
+ }
+ function resetCounters() {
+ calcounter = { addItem: 0, modifyItem: 0, deleteItem: 0 };
+ allcounter = { addItem: 0, modifyItem: 0, deleteItem: 0 };
+ }
+
+ // First of all we need a local calendar to work on and some variables
+ let memory = cal.manager.createCalendar("memory", Services.io.newURI("moz-memory-calendar://"));
+ let memory2 = cal.manager.createCalendar("memory", Services.io.newURI("moz-memory-calendar://"));
+ let calcounter, allcounter;
+
+ // These observers will end up counting calls which we will use later on
+ let calobs = cal.createAdapter(Ci.calIObserver, {
+ onAddItem: () => calcounter.addItem++,
+ onModifyItem: () => calcounter.modifyItem++,
+ onDeleteItem: () => calcounter.deleteItem++,
+ });
+ let allobs = cal.createAdapter(Ci.calIObserver, {
+ onAddItem: () => allcounter.addItem++,
+ onModifyItem: () => allcounter.modifyItem++,
+ onDeleteItem: () => allcounter.deleteItem++,
+ });
+
+ // Set up counters and observers
+ resetCounters();
+ cal.manager.registerCalendar(memory);
+ cal.manager.registerCalendar(memory2);
+ cal.manager.addCalendarObserver(allobs);
+ memory.addObserver(calobs);
+
+ // Add an item
+ let item = new CalEvent();
+ item.id = cal.getUUID();
+ item.startDate = cal.dtz.now();
+ item.endDate = cal.dtz.now();
+ memory.addItem(item);
+ checkCounters(1, 0, 0);
+
+ // Modify the item
+ let newItem = item.clone();
+ newItem.title = "title";
+ memory.modifyItem(newItem, item);
+ checkCounters(0, 1, 0);
+
+ // Delete the item
+ newItem.generation++; // circumvent generation checks for easier code
+ memory.deleteItem(newItem);
+ checkCounters(0, 0, 1);
+
+ // Now check the same for adding the item to a calendar only observed by the
+ // calendar manager. The calcounters should still be 0, but the calendar
+ // manager counter should have an item added, modified and deleted
+ memory2.addItem(item);
+ memory2.modifyItem(newItem, item);
+ memory2.deleteItem(newItem);
+ checkCounters(0, 0, 0, 1, 1, 1);
+
+ // Remove observers
+ memory.removeObserver(calobs);
+ cal.manager.removeCalendarObserver(allobs);
+
+ // Make sure removing it actually worked
+ memory.addItem(item);
+ memory.modifyItem(newItem, item);
+ memory.deleteItem(newItem);
+ checkCounters(0, 0, 0);
+
+ // We are done now, start the next test
+ run_next_test();
+});
+
+add_test(function test_removeModes() {
+ function checkCounts(modes, shouldDelete, expectCount, extraFlags = 0) {
+ if (cal.manager.calendarCount == baseCalendarCount) {
+ cal.manager.registerCalendar(memory);
+ equal(cal.manager.calendarCount, baseCalendarCount + 1);
+ }
+ deleteCalled = false;
+ removeModes = modes;
+
+ cal.manager.removeCalendar(memory, extraFlags);
+ equal(cal.manager.calendarCount, baseCalendarCount + expectCount);
+ equal(deleteCalled, shouldDelete);
+ }
+ function mockCalendar(memory) {
+ let oldGetProperty = memory.wrappedJSObject.getProperty;
+ memory.wrappedJSObject.getProperty = function (name) {
+ if (name == "capabilities.removeModes") {
+ return removeModes;
+ }
+ return oldGetProperty.apply(this, arguments);
+ };
+
+ let oldDeleteCalendar = memory.wrappedJSObject.deleteCalendar;
+ memory.wrappedJSObject.deleteCalendar = function (calendar, listener) {
+ deleteCalled = true;
+ return oldDeleteCalendar.apply(this, arguments);
+ };
+ }
+
+ // For better readability
+ const SHOULD_DELETE = true,
+ SHOULD_NOT_DELETE = false;
+
+ let memory = cal.manager.createCalendar("memory", Services.io.newURI("moz-memory-calendar://"));
+ let baseCalendarCount = cal.manager.calendarCount;
+ let removeModes = null;
+ let deleteCalled = false;
+
+ mockCalendar(memory);
+
+ checkCounts([], SHOULD_NOT_DELETE, 1);
+ checkCounts(["unsubscribe"], SHOULD_NOT_DELETE, 0);
+ checkCounts(["unsubscribe", "delete"], SHOULD_DELETE, 0);
+ checkCounts(
+ ["unsubscribe", "delete"],
+ SHOULD_NOT_DELETE,
+ 0,
+ Ci.calICalendarManager.REMOVE_NO_DELETE
+ );
+ checkCounts(["delete"], SHOULD_DELETE, 0);
+
+ run_next_test();
+});
+
+add_test(function test_calprefs() {
+ let prop;
+ let memory = cal.manager.createCalendar("memory", Services.io.newURI("moz-memory-calendar://"));
+ cal.manager.registerCalendar(memory);
+ let memid = memory.id;
+
+ // First set a few values, one of each relevant type
+ memory.setProperty("stringpref", "abc");
+ memory.setProperty("boolpref", true);
+ memory.setProperty("intpref", 123);
+ memory.setProperty("bigintpref", 1394548721296);
+ memory.setProperty("floatpref", 0.5);
+
+ // Before checking the value, reinitialize the memory calendar with the
+ // same id to make sure the pref value isn't just cached
+ memory = cal.manager.createCalendar("memory", Services.io.newURI("moz-memory-calendar://"));
+ memory.id = memid;
+
+ // First test the standard types
+ prop = memory.getProperty("stringpref");
+ equal(typeof prop, "string");
+ equal(prop, "abc");
+
+ prop = memory.getProperty("boolpref");
+ equal(typeof prop, "boolean");
+ equal(prop, true);
+
+ prop = memory.getProperty("intpref");
+ equal(typeof prop, "number");
+ equal(prop, 123);
+
+ // These two are a special case test for bug 979262
+ prop = memory.getProperty("bigintpref");
+ equal(typeof prop, "number");
+ equal(prop, 1394548721296);
+
+ prop = memory.getProperty("floatpref");
+ equal(typeof prop, "number");
+ equal(prop, 0.5);
+
+ // Check if changing pref types works. We need to reset the calendar again
+ // because retrieving the value just cached it again.
+ memory = cal.manager.createCalendar("memory", Services.io.newURI("moz-memory-calendar://"));
+ memory.id = memid;
+
+ cal.manager.setCalendarPref_(memory, "boolpref", "kinda true");
+ prop = memory.getProperty("boolpref");
+ equal(typeof prop, "string");
+ equal(prop, "kinda true");
+
+ // Check if unsetting a pref works
+ memory.setProperty("intpref", null);
+ memory = cal.manager.createCalendar("memory", Services.io.newURI("moz-memory-calendar://"));
+ memory.id = memid;
+ prop = memory.getProperty("intpref");
+ ok(prop === null);
+
+ // We are done now, start the next test
+ run_next_test();
+});