diff --git a/fakemui/icons/FilterOff.tsx b/fakemui/icons/FilterOff.tsx new file mode 100644 index 000000000..e9752dc15 --- /dev/null +++ b/fakemui/icons/FilterOff.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import { Icon, IconProps } from './Icon' + +export const FilterOff = (props: IconProps) => ( + + + + + +) diff --git a/fakemui/icons/Flag.tsx b/fakemui/icons/Flag.tsx new file mode 100644 index 000000000..035068a76 --- /dev/null +++ b/fakemui/icons/Flag.tsx @@ -0,0 +1,9 @@ +import React from 'react' +import { Icon, IconProps } from './Icon' + +export const Flag = (props: IconProps) => ( + + + + +) diff --git a/fakemui/icons/ShieldSlash.tsx b/fakemui/icons/ShieldSlash.tsx new file mode 100644 index 000000000..d5402fc50 --- /dev/null +++ b/fakemui/icons/ShieldSlash.tsx @@ -0,0 +1,9 @@ +import React from 'react' +import { Icon, IconProps } from './Icon' + +export const ShieldSlash = (props: IconProps) => ( + + + + +) diff --git a/fakemui/icons/index.ts b/fakemui/icons/index.ts index 20e01738d..6814d0fa9 100644 --- a/fakemui/icons/index.ts +++ b/fakemui/icons/index.ts @@ -16,6 +16,7 @@ export { Stop } from './Stop' export { Download } from './Download' export { Upload } from './Upload' export { Filter } from './Filter' +export { FilterOff } from './FilterOff' export { Refresh } from './Refresh' // Navigation @@ -138,6 +139,7 @@ export { LockOpen } from './LockOpen' export { Key } from './Key' export { Shield } from './Shield' export { UserShield } from './UserShield' +export { ShieldSlash } from './ShieldSlash' export { Globe } from './Globe' export { Cloud } from './Cloud' diff --git a/fakemui/index.ts b/fakemui/index.ts index 4e7ca736b..6bb78dcd0 100644 --- a/fakemui/index.ts +++ b/fakemui/index.ts @@ -10,6 +10,8 @@ export { Copy, Check, X, + Filter, + FilterOff, // Navigation ArrowUp, ArrowDown, diff --git a/packages/audit_log/seed/tests/filters.test.lua b/packages/audit_log/seed/tests/filters.test.lua index 24c03968d..9beaac8c4 100644 --- a/packages/audit_log/seed/tests/filters.test.lua +++ b/packages/audit_log/seed/tests/filters.test.lua @@ -20,6 +20,14 @@ local M = {} ---@field resources string[] ---@field usernames string[] +---@class ApplyFiltersInput +---@field operation string|nil +---@field resource string|nil +---@field success boolean|nil +---@field username string|nil +---@field startTime number|nil +---@field endTime number|nil + ---@class FilterByOperationCase ---@field operation string|nil ---@field expected integer diff --git a/packages/nav_menu/seed/scripts/tests/menu.cases.json b/packages/nav_menu/seed/scripts/tests/menu.cases.json new file mode 100644 index 000000000..b4a262200 --- /dev/null +++ b/packages/nav_menu/seed/scripts/tests/menu.cases.json @@ -0,0 +1,48 @@ +{ + "can_show": [ + { + "user": { "level": 0 }, + "item": { "label": "Home" }, + "expected": true, + "desc": "item with no minLevel" + }, + { + "user": { "level": 0 }, + "item": { "label": "Admin", "minLevel": 3 }, + "expected": false, + "desc": "low level user for admin" + }, + { + "user": { "level": 3 }, + "item": { "label": "Admin", "minLevel": 3 }, + "expected": true, + "desc": "admin for admin item" + }, + { + "user": { "level": 5 }, + "item": { "label": "Admin", "minLevel": 3 }, + "expected": true, + "desc": "high level for admin item" + }, + { + "user": {}, + "item": { "label": "Users", "minLevel": 2 }, + "expected": false, + "desc": "no level user" + } + ], + "render": [ + { + "props": { + "user": { "level": 2 }, + "items": [ + { "label": "Home", "path": "/" }, + { "label": "Admin", "path": "/admin", "minLevel": 3 }, + { "label": "Users", "path": "/users", "minLevel": 2 } + ] + }, + "expectedChildren": 2, + "desc": "filters items by permission" + } + ] +} diff --git a/packages/nav_menu/seed/scripts/tests/menu.test.lua b/packages/nav_menu/seed/scripts/tests/menu.test.lua index 43856bcf8..d6e55b79f 100644 --- a/packages/nav_menu/seed/scripts/tests/menu.test.lua +++ b/packages/nav_menu/seed/scripts/tests/menu.test.lua @@ -14,15 +14,21 @@ ---@field user MenuUser ---@field items MenuItem[] ----@class MenuShowTestCase ----@field user MenuUser ----@field item MenuItem ----@field expected boolean ----@field desc string - -describe("Menu", function() - -- Mock check module - local original_can_access +---@class MenuShowTestCase +---@field user MenuUser +---@field item MenuItem +---@field expected boolean +---@field desc string + +---@class MenuRenderTestCase +---@field props MenuRenderProps +---@field expectedChildren integer +---@field desc string + +describe("Menu", function() + -- Mock check module + ---@type { can_show: MenuShowTestCase[], render: MenuRenderTestCase[] } + local cases = load_cases("menu.cases.json") before(function() -- Create mock for check.can_access @@ -33,20 +39,14 @@ describe("Menu", function() } end) - local menu = require("menu") - - describe("can_show", function() - it.each({ - { user = { level = 0 }, item = { label = "Home" }, expected = true, desc = "item with no minLevel" }, - { user = { level = 0 }, item = { label = "Admin", minLevel = 3 }, expected = false, desc = "low level user for admin" }, - { user = { level = 3 }, item = { label = "Admin", minLevel = 3 }, expected = true, desc = "admin for admin item" }, - { user = { level = 5 }, item = { label = "Admin", minLevel = 3 }, expected = true, desc = "high level for admin item" }, - { user = {}, item = { label = "Users", minLevel = 2 }, expected = false, desc = "no level user" }, - })("should return $expected for $desc", function(testCase) - local result = menu.can_show(testCase.user, testCase.item) - expect(result).toBe(testCase.expected) - end) - end) + local menu = require("menu") + + describe("can_show", function() + it.each(cases.can_show, "$desc", function(testCase) + local result = menu.can_show(testCase.user, testCase.item) + expect(result).toBe(testCase.expected) + end) + end) describe("item", function() it("should render button for simple item", function() @@ -69,19 +69,11 @@ describe("Menu", function() end) end) - describe("render", function() - it("should filter items by permission", function() - local props = { - user = { level = 2 }, - items = { - { label = "Home", path = "/" }, - { label = "Admin", path = "/admin", minLevel = 3 }, - { label = "Users", path = "/users", minLevel = 2 } - } - } - local result = menu.render(props) - expect(result.type).toBe("Flex") - expect(#result.children).toBe(2) -- Home and Users, not Admin - end) - end) -end) + describe("render", function() + it.each(cases.render, "$desc", function(testCase) + local result = menu.render(testCase.props) + expect(result.type).toBe("Flex") + expect(#result.children).toBe(testCase.expectedChildren) + end) + end) +end) diff --git a/packages/ui_level3/seed/scripts/moderation/types.lua b/packages/ui_level3/seed/scripts/moderation/types.lua index 0e6fc5d5f..191f85be8 100644 --- a/packages/ui_level3/seed/scripts/moderation/types.lua +++ b/packages/ui_level3/seed/scripts/moderation/types.lua @@ -1,9 +1,13 @@ -- Type definitions for moderation module -- Shared across all moderation functions ----@class ModerationContext ----@field user table User object for permission checking ----@field targetId string ID of the target user for moderation action +---@class ModerationUser +---@field id string +---@field level? number + +---@class ModerationContext +---@field user ModerationUser User object for permission checking +---@field targetId string ID of the target user for moderation action ---@class ActionResult ---@field success boolean Whether the action was successful