test(server): batch 5 authorization, transclusion, search & comment coverage
Test-only. Fills the authorization / data-integrity gaps from the strategy report. Full server suite: 100 suites / 1031 passed + 1 todo, green. Authorization (privilege-escalation catches): - workspace/space ability factories: exact can/cannot per (action,subject) — admin cannot Manage Audit, writer/reader cannot Manage Settings/Member, etc. - findHighestUserSpaceRole, isAdminActingOnOwner. - WorkspaceService role guards: last-owner lockout, admin-over-owner, self-target. - SpaceMemberService.validateLastAdmin: never orphan a space without an admin. - GroupService: default-group immutability, name uniqueness. Access / data integrity: - PageAccessService: restriction-vs-space-ability branches for view/edit/comment. - TransclusionService.unsyncReference: cross-workspace/NotFound boundary asserts NO attachment write or ref-row delete on rejection; lookupWithAccessSet positional status mapping; listReferences drops private/cross-ws/deleted refs; syncPageTransclusions/References diff (no-op on unchanged content). - SearchService.searchPage: query-mode scoping; leakage modes return empty before executing the query. - CommentService: reply-to-reply guard, agent provenance, self-mention filter, no double-notify. Pure helpers: - prosemirror extractors (mention dedup-key id-vs-entityId, attachment UUID validation, removeMarkTypeFromDoc), collaboration.util (getPageId, isEmptyParagraphDoc, stripUnknownNodes unwrap, prosemirrorNodeToYElement). Reviewed (APPROVE WITH SUGGESTIONS): mutation-resistant, not vacuous. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import { normalizeLabelName } from './utils';
|
||||
|
||||
// Pins the server-side label normalizer used by the label repo/service/DTOs to
|
||||
// dedupe labels. Contract: trim the ends, collapse every run of whitespace into
|
||||
// a single hyphen, and lowercase. A regression here would let visually-identical
|
||||
// labels (differing only by case or spacing) be treated as distinct.
|
||||
|
||||
describe('normalizeLabelName', () => {
|
||||
it('lowercases the name', () => {
|
||||
expect(normalizeLabelName('Bug')).toBe('bug');
|
||||
expect(normalizeLabelName('HIGH-PRIORITY')).toBe('high-priority');
|
||||
});
|
||||
|
||||
it('trims leading and trailing whitespace', () => {
|
||||
expect(normalizeLabelName(' bug ')).toBe('bug');
|
||||
});
|
||||
|
||||
it('collapses an internal run of spaces into a single hyphen', () => {
|
||||
expect(normalizeLabelName('high priority')).toBe('high-priority');
|
||||
});
|
||||
|
||||
it('replaces a single internal space with a hyphen', () => {
|
||||
expect(normalizeLabelName('in progress')).toBe('in-progress');
|
||||
});
|
||||
|
||||
it('collapses tabs and newlines (any whitespace) into a single hyphen', () => {
|
||||
expect(normalizeLabelName('high\tpriority')).toBe('high-priority');
|
||||
expect(normalizeLabelName('high\npriority')).toBe('high-priority');
|
||||
expect(normalizeLabelName('high \t \n priority')).toBe('high-priority');
|
||||
});
|
||||
|
||||
it('collapses unicode whitespace (e.g. non-breaking space) into a hyphen', () => {
|
||||
expect(normalizeLabelName('high priority')).toBe('high-priority');
|
||||
});
|
||||
|
||||
it('applies trim, collapse and lowercase together', () => {
|
||||
expect(normalizeLabelName(' In PROGRESS\t ')).toBe('in-progress');
|
||||
});
|
||||
|
||||
it('leaves an already-normalized name unchanged', () => {
|
||||
expect(normalizeLabelName('high-priority')).toBe('high-priority');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user