- hypr/apps.lua - hypr/autostart.lua - hypr/envs.lua - hypr/hyprland.lua - hypr/hyprsunset.conf - hypr/input.lua - hypr/looknfeel.lua - hypr/omasettings.lua - hypr/xdph.conf - omarchy/branding/about.txt - omarchy/branding/screensaver.txt - omarchy/extensions/omarchy-menu.jsonc - omarchy/hooks/battery-low.d/play-warning-sound.sample - omarchy/hooks/font-set.d/show-font-notification.sample - omarchy/hooks/post-boot.d/weather.sample - omarchy/hooks/post-update.d/install-voxtype.hook - omarchy/hooks/post-update.d/setup-agent.hook - omarchy/hooks/post-update.d/setup-fingerprint.hook - omarchy/hooks/post-update.d/show-update-notification.sample - omarchy/hooks/pre-refresh-pacman.d/add-custom-repo.sample - omarchy/hooks/theme-set.d/show-theme-notification.sample - omarchy/shell.json - omarchy/shell.toml - omarchy/theme.name - omarchy/themes/azure-glow/README.md - omarchy/themes/azure-glow/alacritty.toml - omarchy/themes/azure-glow/btop.theme - omarchy/themes/azure-glow/hyprland.conf - omarchy/themes/azure-glow/hyprlock.conf - omarchy/themes/azure-glow/icons.theme - … 269 more
88 lines
4.9 KiB
JavaScript
88 lines
4.9 KiB
JavaScript
#!/usr/bin/env node
|
|
// Tests for organization collections on the item form.
|
|
//
|
|
// Field names were read from a real `bw list org-collections` response
|
|
// (id / organizationId / name / externalId / object) and from the item
|
|
// template, which carries collectionIds.
|
|
//
|
|
// node tests/collections.test.js
|
|
|
|
const fs = require("fs")
|
|
const path = require("path")
|
|
const Model = {}
|
|
new Function("exports", fs.readFileSync(path.join(__dirname, "..", "BitwardenModel.js"), "utf8")
|
|
.replace(/^\.pragma library\s*$/m, "") + `
|
|
exports.listOrgCollectionsCommand = listOrgCollectionsCommand
|
|
exports.parseCollections = parseCollections
|
|
exports.collectionName = collectionName
|
|
exports.buildCreatePayload = buildCreatePayload
|
|
exports.buildEditPayload = buildEditPayload
|
|
exports.validateItemForm = validateItemForm
|
|
`)(Model)
|
|
|
|
let pass = 0
|
|
const failures = []
|
|
const check = (l, ok, d) => ok ? pass++ : failures.push(`${l}\n ${d}`)
|
|
|
|
// --- command ---
|
|
check("collections are listed per organization with a producer-side byte limit",
|
|
Model.listOrgCollectionsCommand("o1").join(" ").includes("bw list org-collections --organizationid o1")
|
|
&& Model.listOrgCollectionsCommand("o1").join(" ").includes("head -c"),
|
|
Model.listOrgCollectionsCommand("o1").join(" "))
|
|
check("the session is not on the command line",
|
|
!Model.listOrgCollectionsCommand("o1").join(" ").includes("--session"), "expected no --session")
|
|
|
|
// --- parsing ---
|
|
const cols = Model.parseCollections(JSON.stringify([
|
|
{ object: "org-collection", id: "c2", organizationId: "o1", name: "Ops", externalId: null },
|
|
{ object: "org-collection", id: "c1", organizationId: "o1", name: "admin", externalId: null },
|
|
{ object: "org-collection", name: "no id at all" },
|
|
]))
|
|
check("collections sort case-insensitively", cols.map(c => c.name).join(",") === "admin,Ops", cols.map(c => c.name).join(","))
|
|
check("an entry without an id is dropped", cols.length === 2, JSON.stringify(cols))
|
|
check("organizationId is carried through", cols[0].organizationId === "o1", JSON.stringify(cols[0]))
|
|
check("malformed JSON yields an empty list",
|
|
Model.parseCollections("{{").length === 0 && Model.parseCollections("").length === 0, "expected []")
|
|
check("collectionName resolves a known id", Model.collectionName(cols, "c2") === "Ops", Model.collectionName(cols, "c2"))
|
|
check("collectionName is empty for an unknown id", Model.collectionName(cols, "zz") === "", "expected empty")
|
|
|
|
// --- payloads ---
|
|
// A personal item has no collections; sending the key at all would be wrong.
|
|
check("a personal item carries no collectionIds",
|
|
!("collectionIds" in Model.buildCreatePayload(1, "n", "", "", "", "", "", false, null, null, ["c1"])),
|
|
"expected the key to be absent")
|
|
check("an org item carries the chosen collections",
|
|
JSON.stringify(Model.buildCreatePayload(1, "n", "", "", "", "", "", false, "o1", null, ["c1", "c2"]).collectionIds)
|
|
=== JSON.stringify(["c1", "c2"]), "expected both ids")
|
|
// Callers that predate collections pass ten arguments; they must not start
|
|
// sending an empty array, which is not the same as sending nothing.
|
|
check("an org item with no collections omits the key rather than sending []",
|
|
!("collectionIds" in Model.buildCreatePayload(1, "n", "", "", "", "", "", false, "o1", null)),
|
|
"expected the key to be absent")
|
|
|
|
const existing = { rawObject: { id: "1", type: 1, organizationId: "o1", collectionIds: ["keep"], login: {} } }
|
|
check("editing keeps existing collections when none are supplied",
|
|
JSON.stringify(Model.buildEditPayload(existing, "n", "", "", "", "", "", false, "o1", null).collectionIds)
|
|
=== JSON.stringify(["keep"]), "expected the existing ids to survive")
|
|
check("editing replaces collections when new ones are supplied",
|
|
JSON.stringify(Model.buildEditPayload(existing, "n", "", "", "", "", "", false, "o1", null, ["c9"]).collectionIds)
|
|
=== JSON.stringify(["c9"]), "expected the new ids")
|
|
check("moving an item to a personal vault drops its collections",
|
|
!("collectionIds" in Model.buildEditPayload(existing, "n", "", "", "", "", "", false, null, null, [])),
|
|
"expected the key to be removed")
|
|
|
|
// --- validation ---
|
|
// Bitwarden rejects an org item with no collection, so say so before the CLI does.
|
|
check("an org item with no collection is refused",
|
|
Model.validateItemForm("n", "o1", []) !== "", Model.validateItemForm("n", "o1", []))
|
|
check("an org item with a collection is accepted",
|
|
Model.validateItemForm("n", "o1", ["c1"]) === "", Model.validateItemForm("n", "o1", ["c1"]))
|
|
check("a personal item needs no collection",
|
|
Model.validateItemForm("n", null, []) === "" && Model.validateItemForm("n", "personal", []) === "",
|
|
"expected personal items to pass")
|
|
check("a blank title is still refused first",
|
|
Model.validateItemForm(" ", "o1", ["c1"]).includes("title"), Model.validateItemForm(" ", "o1", ["c1"]))
|
|
|
|
console.log(`${pass} passed, ${failures.length} failed`)
|
|
if (failures.length) { console.error("\nFAILURES:\n " + failures.join("\n ")); process.exit(1) }
|