/* 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/. */
add_setup(async () => {
await TabNotes.init({ basePath: PathUtils.tempDir });
});
registerCleanupFunction(async () => {
await TabNotes.reset();
await TabNotes.deinit();
IOUtils.remove(
PathUtils.join(PathUtils.tempDir, TabNotes.DATABASE_FILE_NAME),
{
ignoreAbsent:
true,
}
);
});
/**
* Fake for MozTabbrowserTab.
*/
class FakeTab
extends EventTarget {
/**
* @param {string} canonicalUrl
*/
constructor(canonicalUrl) {
super();
/** @type {string} */
this.canonicalUrl = canonicalUrl;
}
}
add_task(async
function tabNotesBasicStorageTests() {
let tab =
new FakeTab(
"https://example.com/abc");
let value =
"some note";
let updatedValue =
"some other note";
let tabNoteCreated = BrowserTestUtils.waitForEvent(tab,
"TabNote:Created");
let setNote = TabNotes.set(tab, value);
let [firstSavedNote, createdEvent] = await Promise.all([
setNote,
tabNoteCreated,
]);
Assert.ok(firstSavedNote,
"TabNotes.set returns the saved tab note");
Assert.ok(createdEvent,
"tab fired TabNote:Created");
Assert.equal(
firstSavedNote.canonicalUrl,
tab.canonicalUrl,
"TabNotes.set stores the right URL"
);
Assert.equal(
firstSavedNote.text,
value,
"TabNotes.set stores the right note text"
);
Assert.ok(firstSavedNote.created,
"TabNotes.set stores a creation timestamp");
Assert.equal(
await TabNotes.has(tab),
true,
"TabNotes.has indicates that the tab has a note"
);
Assert.deepEqual(
await TabNotes.get(tab),
firstSavedNote,
"TabNotes.get returns previously set note"
);
let tabNoteEdited = BrowserTestUtils.waitForEvent(tab,
"TabNote:Edited");
let editNote = TabNotes.set(tab, updatedValue);
let [editedSavedNote, editedEvent] = await Promise.all([
editNote,
tabNoteEdited,
]);
Assert.ok(editedSavedNote,
"TabNotes.set returns the updated tab note");
Assert.ok(editedEvent,
"tab fired TabNote:Edited");
Assert.equal(
editedSavedNote.canonicalUrl,
tab.canonicalUrl,
"TabNotes.set should keep the same URL when updating"
);
Assert.equal(
editedSavedNote.text,
updatedValue,
"TabNotes.set saved the new note text"
);
Assert.equal(
Temporal.Instant.compare(editedSavedNote.created, firstSavedNote.created),
0,
"TabNotes.set should not change the creation timestamp when updating an existing note"
);
const tabWithoutCanonicalUrl =
new FakeTab(undefined);
let wasDeleted = await TabNotes.
delete(tabWithoutCanonicalUrl);
Assert.ok(
!wasDeleted,
"TabNotes.delete should return false if nothing was deleted"
);
let tabNoteRemoved = BrowserTestUtils.waitForEvent(tab,
"TabNote:Removed");
let deleteNote = TabNotes.
delete(tab);
let [wasActuallyDeleted, removedEvent] = await Promise.all([
deleteNote,
tabNoteRemoved,
]);
Assert.ok(removedEvent,
"listeners were notified of TabNote:Removed");
Assert.ok(
wasActuallyDeleted,
"TabNotes.delete should return true if something was deleted"
);
Assert.equal(
await TabNotes.has(tab),
false,
"TabNotes.has indicates that the deleted URL no longer has a note"
);
Assert.equal(
await TabNotes.get(tab),
undefined,
"TabNotes.get returns undefined for URL that does not have a note"
);
await TabNotes.reset();
});
add_task(
function tabNotesIsEligible() {
Assert.ok(
TabNotes.isEligible(
new FakeTab(
"https://example.com/")),
"tab with a valid canonical URL is eligible"
);
Assert.ok(
!TabNotes.isEligible(
new FakeTab(undefined)),
"tab with no canonical URL is ineligible"
);
Assert.ok(
!TabNotes.isEligible(
new FakeTab(
"not a valid URL")),
"tab with an unparseable canonical URL is ineligible"
);
});
add_task(async
function tabNotesCount() {
const tab1 =
new FakeTab(
"https://example.com/1");
const tab2 =
new FakeTab(
"https://example.com/2");
Assert.equal(await TabNotes.count(),
0,
"should be zero tab notes to start");
await TabNotes.set(tab1,
"Test note 1");
Assert.equal(await TabNotes.count(),
1,
"should be one tab note");
await TabNotes.set(tab2,
"Test note 2");
Assert.equal(await TabNotes.count(),
2,
"should be two tab notes");
await TabNotes.
delete(tab2);
Assert.equal(await TabNotes.count(),
1,
"should be one tab note again");
await TabNotes.reset();
Assert.equal(await TabNotes.count(),
0,
"should be zero tab notes again");
});
add_task(async
function tabNotesSanitizationTests() {
let tab =
new FakeTab(
"https://example.com/");
let tooLongValue =
"x".repeat(
1500);
let correctValue =
"x".repeat(
1000);
const savedNote = await TabNotes.set(tab, tooLongValue);
Assert.equal(
savedNote.text,
correctValue,
"TabNotes.set truncates note length"
);
await TabNotes.reset();
});
add_task(async
function tabNotesErrors() {
await
Assert.rejects(
TabNotes.set(
new FakeTab(undefined),
"valid note text"),
/RangeError/,
"tabs without canonical URLs are not eligible for tab notes"
);
await
Assert.rejects(
TabNotes.set(
new FakeTab(
"not a valid URL"),
"valid note text"),
/RangeError/,
"invalid URLs should not be allowed in TabNotes.set"
);
await
Assert.rejects(
TabNotes.set(
new FakeTab(
"https://example.com"), ""),
/RangeError/,
"empty note text should not be allowed in TabNotes.set"
);
});