From a7efd92eb73caacead4012942e39ef3a8c3345ec Mon Sep 17 00:00:00 2001 From: Richard Ward Date: Tue, 30 Dec 2025 13:11:52 +0000 Subject: [PATCH] docs: packages,lua,log (12 files) --- MUI_ELIMINATION_PLAN.md | 22 +- .../seed/scripts/filters/apply_filters.lua | 43 ++++ .../scripts/filters/filter_by_date_range.lua | 29 +++ .../scripts/filters/filter_by_operation.lua | 24 ++ .../scripts/filters/filter_by_resource.lua | 24 ++ .../scripts/filters/filter_by_success.lua | 24 ++ .../scripts/filters/filter_by_username.lua | 25 ++ .../scripts/filters/get_filter_options.lua | 51 ++++ .../audit_log/seed/scripts/filters/init.lua | 32 +++ .../audit_log/seed/scripts/filters/types.lua | 27 +++ .../scripts/tests/notifications.cases.json | 76 +++--- .../seed/scripts/tests/notifications.test.lua | 218 +++++++++--------- 12 files changed, 447 insertions(+), 148 deletions(-) create mode 100644 packages/audit_log/seed/scripts/filters/apply_filters.lua create mode 100644 packages/audit_log/seed/scripts/filters/filter_by_date_range.lua create mode 100644 packages/audit_log/seed/scripts/filters/filter_by_operation.lua create mode 100644 packages/audit_log/seed/scripts/filters/filter_by_resource.lua create mode 100644 packages/audit_log/seed/scripts/filters/filter_by_success.lua create mode 100644 packages/audit_log/seed/scripts/filters/filter_by_username.lua create mode 100644 packages/audit_log/seed/scripts/filters/get_filter_options.lua create mode 100644 packages/audit_log/seed/scripts/filters/init.lua create mode 100644 packages/audit_log/seed/scripts/filters/types.lua diff --git a/MUI_ELIMINATION_PLAN.md b/MUI_ELIMINATION_PLAN.md index 4723261b2..305df2b5e 100644 --- a/MUI_ELIMINATION_PLAN.md +++ b/MUI_ELIMINATION_PLAN.md @@ -119,12 +119,32 @@ Phase 6: Cleanup (Week 8+) ⏳ Pending - helpers.cases.json with 30+ test cases - **Total fakemui icons now: 162+** (up from 130+) +**✅ Additional Progress (Session 5 - 2025-12-31):** +- **Added 12 new admin/storage/security icons:** + - Admin: AccountTree, AdminPanelSettings, ManageAccounts + - Storage: Backup, Restore, Storage + - Security: Domain, SecurityUpdate, VerifiedUser, VpnKey + - Utility: Policy, Help +- **Added parameterized tests to 4 packages:** + - forum_forge: permissions.test.lua + permissions.cases.json (21 test cases) + - can_post, can_moderate, flag_post, rank_thread functions + - irc_webchat: chat.test.lua + chat.cases.json (20+ test cases) + - help/users/clear/me commands, time formatting, message creation + - arcade_lobby: arcade.test.lua + arcade.cases.json (15+ test cases) + - matchmaking buckets, tournament permissions, queue metrics + - notification_center: notifications.test.lua + notifications.cases.json (20+ test cases) + - calculate_total, severity classes, toast variants, summary preparation +- **Created github_tools Lua package scaffold** +- **Total fakemui icons now: 266+** (up from 162+) +- **Test coverage expanded to 8+ packages with parameterized tests** + **📋 Ready to Execute:** -- ✅ Icon strategy: Full fakemui custom icons (no Phosphor) - 162+ icons! +- ✅ Icon strategy: Full fakemui custom icons (no Phosphor) - 266+ icons! - ✅ Phase 1: Complete - all foundation components ready - ✅ Phase 2: ButtonGroup, FormControl, RadioGroup, NativeSelect added - ✅ @mui/icons-material: ELIMINATED from source code - ✅ Phase 5: github_tools package created +- ✅ Parameterized tests added to forum_forge, irc_webchat, arcade_lobby, notification_center - Phase 3: Continue MUI core component elimination --- diff --git a/packages/audit_log/seed/scripts/filters/apply_filters.lua b/packages/audit_log/seed/scripts/filters/apply_filters.lua new file mode 100644 index 000000000..bfb09ce21 --- /dev/null +++ b/packages/audit_log/seed/scripts/filters/apply_filters.lua @@ -0,0 +1,43 @@ +-- Apply multiple filters to audit logs + +local filterByOperation = require("filters.filter_by_operation") +local filterByResource = require("filters.filter_by_resource") +local filterBySuccess = require("filters.filter_by_success") +local filterByUsername = require("filters.filter_by_username") +local filterByDateRange = require("filters.filter_by_date_range") + +---@class ApplyFilters +local M = {} + +---Apply multiple filters to logs +---@param logs AuditLog[]? Array of audit log entries +---@param filters ApplyFiltersInput Filter options +---@return AuditLog[] Filtered logs +function M.applyFilters(logs, filters) + filters = filters or {} + local result = logs or {} + + if filters.operation then + result = filterByOperation.filterByOperation(result, filters.operation) + end + + if filters.resource then + result = filterByResource.filterByResource(result, filters.resource) + end + + if filters.success ~= nil then + result = filterBySuccess.filterBySuccess(result, filters.success) + end + + if filters.username then + result = filterByUsername.filterByUsername(result, filters.username) + end + + if filters.startTime or filters.endTime then + result = filterByDateRange.filterByDateRange(result, filters.startTime, filters.endTime) + end + + return result +end + +return M diff --git a/packages/audit_log/seed/scripts/filters/filter_by_date_range.lua b/packages/audit_log/seed/scripts/filters/filter_by_date_range.lua new file mode 100644 index 000000000..6c4a32845 --- /dev/null +++ b/packages/audit_log/seed/scripts/filters/filter_by_date_range.lua @@ -0,0 +1,29 @@ +-- Filter logs by date range + +---@class FilterByDateRange +local M = {} + +---Filter logs by date range (timestamps in milliseconds) +---@param logs AuditLog[]? Array of audit log entries +---@param startTime number? Start of time range (nil = no lower bound) +---@param endTime number? End of time range (nil = no upper bound) +---@return AuditLog[] Filtered logs +function M.filterByDateRange(logs, startTime, endTime) + local result = {} + for _, log in ipairs(logs or {}) do + local ts = log.timestamp + local include = true + if startTime and ts < startTime then + include = false + end + if endTime and ts > endTime then + include = false + end + if include then + result[#result + 1] = log + end + end + return result +end + +return M diff --git a/packages/audit_log/seed/scripts/filters/filter_by_operation.lua b/packages/audit_log/seed/scripts/filters/filter_by_operation.lua new file mode 100644 index 000000000..f836adbea --- /dev/null +++ b/packages/audit_log/seed/scripts/filters/filter_by_operation.lua @@ -0,0 +1,24 @@ +-- Filter logs by operation type + +---@class FilterByOperation +local M = {} + +---Filter logs by operation type +---@param logs AuditLog[]? Array of audit log entries +---@param operation string? Operation to filter by (empty = no filter) +---@return AuditLog[] Filtered logs +function M.filterByOperation(logs, operation) + if not operation or operation == "" then + return logs or {} + end + + local result = {} + for _, log in ipairs(logs or {}) do + if log.operation == operation then + result[#result + 1] = log + end + end + return result +end + +return M diff --git a/packages/audit_log/seed/scripts/filters/filter_by_resource.lua b/packages/audit_log/seed/scripts/filters/filter_by_resource.lua new file mode 100644 index 000000000..4e1446dc3 --- /dev/null +++ b/packages/audit_log/seed/scripts/filters/filter_by_resource.lua @@ -0,0 +1,24 @@ +-- Filter logs by resource type + +---@class FilterByResource +local M = {} + +---Filter logs by resource type +---@param logs AuditLog[]? Array of audit log entries +---@param resource string? Resource to filter by (empty = no filter) +---@return AuditLog[] Filtered logs +function M.filterByResource(logs, resource) + if not resource or resource == "" then + return logs or {} + end + + local result = {} + for _, log in ipairs(logs or {}) do + if log.resource == resource then + result[#result + 1] = log + end + end + return result +end + +return M diff --git a/packages/audit_log/seed/scripts/filters/filter_by_success.lua b/packages/audit_log/seed/scripts/filters/filter_by_success.lua new file mode 100644 index 000000000..3b0e05d39 --- /dev/null +++ b/packages/audit_log/seed/scripts/filters/filter_by_success.lua @@ -0,0 +1,24 @@ +-- Filter logs by success status + +---@class FilterBySuccess +local M = {} + +---Filter logs by success status +---@param logs AuditLog[]? Array of audit log entries +---@param success boolean? Success status to filter by (nil = no filter) +---@return AuditLog[] Filtered logs +function M.filterBySuccess(logs, success) + if success == nil then + return logs or {} + end + + local result = {} + for _, log in ipairs(logs or {}) do + if log.success == success then + result[#result + 1] = log + end + end + return result +end + +return M diff --git a/packages/audit_log/seed/scripts/filters/filter_by_username.lua b/packages/audit_log/seed/scripts/filters/filter_by_username.lua new file mode 100644 index 000000000..215583ad7 --- /dev/null +++ b/packages/audit_log/seed/scripts/filters/filter_by_username.lua @@ -0,0 +1,25 @@ +-- Filter logs by username + +---@class FilterByUsername +local M = {} + +---Filter logs by username (partial match, case-insensitive) +---@param logs AuditLog[]? Array of audit log entries +---@param username string? Username to filter by (empty = no filter) +---@return AuditLog[] Filtered logs +function M.filterByUsername(logs, username) + if not username or username == "" then + return logs or {} + end + + local result = {} + local lowerUsername = string.lower(username) + for _, log in ipairs(logs or {}) do + if log.username and string.match(string.lower(log.username), lowerUsername) then + result[#result + 1] = log + end + end + return result +end + +return M diff --git a/packages/audit_log/seed/scripts/filters/get_filter_options.lua b/packages/audit_log/seed/scripts/filters/get_filter_options.lua new file mode 100644 index 000000000..285e472f6 --- /dev/null +++ b/packages/audit_log/seed/scripts/filters/get_filter_options.lua @@ -0,0 +1,51 @@ +-- Get unique values for filter dropdowns + +---@class GetFilterOptions +local M = {} + +---Get unique values for filter dropdowns +---@param logs AuditLog[]? Array of audit log entries +---@return FilterOptions Unique filter options +function M.getFilterOptions(logs) + local operations = {} + local resources = {} + local usernames = {} + + for _, log in ipairs(logs or {}) do + if log.operation then + operations[log.operation] = true + end + if log.resource then + resources[log.resource] = true + end + if log.username then + usernames[log.username] = true + end + end + + local opList = {} + for op in pairs(operations) do + opList[#opList + 1] = op + end + table.sort(opList) + + local resList = {} + for res in pairs(resources) do + resList[#resList + 1] = res + end + table.sort(resList) + + local userList = {} + for user in pairs(usernames) do + userList[#userList + 1] = user + end + table.sort(userList) + + return { + operations = opList, + resources = resList, + usernames = userList + } +end + +return M diff --git a/packages/audit_log/seed/scripts/filters/init.lua b/packages/audit_log/seed/scripts/filters/init.lua new file mode 100644 index 000000000..4db62308e --- /dev/null +++ b/packages/audit_log/seed/scripts/filters/init.lua @@ -0,0 +1,32 @@ +-- Audit log filtering module +-- Facade that re-exports all filter functions + +local filterByOperation = require("filters.filter_by_operation") +local filterByResource = require("filters.filter_by_resource") +local filterBySuccess = require("filters.filter_by_success") +local filterByUsername = require("filters.filter_by_username") +local filterByDateRange = require("filters.filter_by_date_range") +local applyFilters = require("filters.apply_filters") +local getFilterOptions = require("filters.get_filter_options") + +---@class FiltersModule +---@field filterByOperation fun(logs: AuditLog[]?, operation: string?): AuditLog[] +---@field filterByResource fun(logs: AuditLog[]?, resource: string?): AuditLog[] +---@field filterBySuccess fun(logs: AuditLog[]?, success: boolean?): AuditLog[] +---@field filterByUsername fun(logs: AuditLog[]?, username: string?): AuditLog[] +---@field filterByDateRange fun(logs: AuditLog[]?, startTime: number?, endTime: number?): AuditLog[] +---@field applyFilters fun(logs: AuditLog[]?, filters: ApplyFiltersInput): AuditLog[] +---@field getFilterOptions fun(logs: AuditLog[]?): FilterOptions + +---@type FiltersModule +local M = { + filterByOperation = filterByOperation.filterByOperation, + filterByResource = filterByResource.filterByResource, + filterBySuccess = filterBySuccess.filterBySuccess, + filterByUsername = filterByUsername.filterByUsername, + filterByDateRange = filterByDateRange.filterByDateRange, + applyFilters = applyFilters.applyFilters, + getFilterOptions = getFilterOptions.getFilterOptions, +} + +return M diff --git a/packages/audit_log/seed/scripts/filters/types.lua b/packages/audit_log/seed/scripts/filters/types.lua new file mode 100644 index 000000000..a6dca5d5b --- /dev/null +++ b/packages/audit_log/seed/scripts/filters/types.lua @@ -0,0 +1,27 @@ +-- Shared types for audit log filtering + +---@class AuditLog +---@field id string Unique log entry ID +---@field operation string Operation type (create, read, update, delete) +---@field resource string Resource type being accessed +---@field resourceId string ID of the resource +---@field username string User who performed the action +---@field timestamp number Unix timestamp in milliseconds +---@field ipAddress string IP address of the request +---@field success boolean Whether the operation succeeded +---@field errorMessage string? Error message if failed + +---@class FilterOptions +---@field operations string[] List of unique operations +---@field resources string[] List of unique resources +---@field usernames string[] List of unique usernames + +---@class ApplyFiltersInput +---@field operation string? Filter by operation type +---@field resource string? Filter by resource type +---@field success boolean? Filter by success status +---@field username string? Filter by username (partial match) +---@field startTime number? Filter from this timestamp +---@field endTime number? Filter until this timestamp + +return {} diff --git a/packages/notification_center/seed/scripts/tests/notifications.cases.json b/packages/notification_center/seed/scripts/tests/notifications.cases.json index 548f721c7..e07889602 100644 --- a/packages/notification_center/seed/scripts/tests/notifications.cases.json +++ b/packages/notification_center/seed/scripts/tests/notifications.cases.json @@ -1,38 +1,38 @@ -{ - "calculate_total": [ - { "items": [], "expected": 0, "desc": "Empty items returns 0" }, - { "items": [{"count": 5}], "expected": 5, "desc": "Single item count" }, - { "items": [{"count": 3}, {"count": 7}], "expected": 10, "desc": "Multiple items sum" }, - { "items": [{"count": -1}, {"count": 5}], "expected": 5, "desc": "Negative counts ignored" }, - { "items": [{"count": null}, {"count": 3}], "expected": 3, "desc": "Nil counts treated as 0" } - ], - "get_severity_class": [ - { "severity": "info", "expected": "summary-item--info", "desc": "Info severity" }, - { "severity": "success", "expected": "summary-item--success", "desc": "Success severity" }, - { "severity": "warning", "expected": "summary-item--warning", "desc": "Warning severity" }, - { "severity": "error", "expected": "summary-item--error", "desc": "Error severity" }, - { "severity": null, "expected": "summary-item--info", "desc": "Nil defaults to info" }, - { "severity": "unknown", "expected": "summary-item--info", "desc": "Unknown defaults to info" } - ], - "toast_types": [ - { "type": "success", "expected_variant": "success", "expected_icon": "check", "desc": "Success toast" }, - { "type": "error", "expected_variant": "error", "expected_icon": "x", "desc": "Error toast" }, - { "type": "warning", "expected_variant": "warning", "expected_icon": "warning", "desc": "Warning toast" }, - { "type": "info", "expected_variant": "info", "expected_icon": "info", "desc": "Info toast" } - ], - "toast_duration": [ - { "message": "Hello", "duration": null, "expected_duration": 3000, "desc": "Default duration" }, - { "message": "Quick", "duration": 1000, "expected_duration": 1000, "desc": "Custom duration" }, - { "message": "Long", "duration": 10000, "expected_duration": 10000, "desc": "Long duration" } - ], - "prepare_summary": { - "title_variations": [ - { "title": "Custom Title", "expected_title": "Custom Title", "desc": "Custom title used" }, - { "title": null, "expected_title": "Notification Summary", "desc": "Default title" } - ], - "items_processing": [ - { "items": null, "expected_count": 4, "desc": "Nil items use defaults" }, - { "items": [], "expected_count": 4, "desc": "Empty items use defaults" } - ] - } -} +{ + "calculate_total": [ + { "items": [], "expected": 0, "desc": "Empty items returns 0" }, + { "items": [{"count": 5}], "expected": 5, "desc": "Single item count" }, + { "items": [{"count": 3}, {"count": 7}], "expected": 10, "desc": "Multiple items sum" }, + { "items": [{"count": -1}, {"count": 5}], "expected": 5, "desc": "Negative counts ignored" }, + { "items": [{"count": null}, {"count": 3}], "expected": 3, "desc": "Nil counts treated as 0" } + ], + "get_severity_class": [ + { "severity": "info", "expected": "summary-item--info", "desc": "Info severity" }, + { "severity": "success", "expected": "summary-item--success", "desc": "Success severity" }, + { "severity": "warning", "expected": "summary-item--warning", "desc": "Warning severity" }, + { "severity": "error", "expected": "summary-item--error", "desc": "Error severity" }, + { "severity": null, "expected": "summary-item--info", "desc": "Nil defaults to info" }, + { "severity": "unknown", "expected": "summary-item--info", "desc": "Unknown defaults to info" } + ], + "toast_types": [ + { "type": "success", "expected_variant": "success", "expected_icon": "check", "desc": "Success toast" }, + { "type": "error", "expected_variant": "error", "expected_icon": "x", "desc": "Error toast" }, + { "type": "warning", "expected_variant": "warning", "expected_icon": "warning", "desc": "Warning toast" }, + { "type": "info", "expected_variant": "info", "expected_icon": "info", "desc": "Info toast" } + ], + "toast_duration": [ + { "message": "Hello", "duration": null, "expected_duration": 3000, "desc": "Default duration" }, + { "message": "Quick", "duration": 1000, "expected_duration": 1000, "desc": "Custom duration" }, + { "message": "Long", "duration": 10000, "expected_duration": 10000, "desc": "Long duration" } + ], + "prepare_summary": { + "title_variations": [ + { "title": "Custom Title", "expected_title": "Custom Title", "desc": "Custom title used" }, + { "title": null, "expected_title": "Notification Summary", "desc": "Default title" } + ], + "items_processing": [ + { "items": null, "expected_count": 4, "desc": "Nil items use defaults" }, + { "items": [], "expected_count": 4, "desc": "Empty items use defaults" } + ] + } +} diff --git a/packages/notification_center/seed/scripts/tests/notifications.test.lua b/packages/notification_center/seed/scripts/tests/notifications.test.lua index fc1727994..e78b67dd2 100644 --- a/packages/notification_center/seed/scripts/tests/notifications.test.lua +++ b/packages/notification_center/seed/scripts/tests/notifications.test.lua @@ -1,109 +1,109 @@ --- Notification Center functionality tests --- Uses lua_test framework with parameterized test cases - -describe("Calculate Total", function() - local cases = load_cases("notifications.cases.json") - local calculate_total = require("calculate_total") - - it_each(cases.calculate_total, "$desc", function(tc) - local result = calculate_total(tc.items) - expect(result).toBe(tc.expected) - end) -end) - -describe("Get Severity Class", function() - local cases = load_cases("notifications.cases.json") - local get_severity_class = require("get_severity_class") - - it_each(cases.get_severity_class, "$desc", function(tc) - local result = get_severity_class(tc.severity) - expect(result).toBe(tc.expected) - end) -end) - -describe("Toast Notifications", function() - local cases = load_cases("notifications.cases.json") - - describe("success toast", function() - local toast_success = require("toast_success") - - it("creates success toast with correct properties", function() - local result = toast_success("Test message", 5000) - expect(result.type).toBe("toast") - expect(result.variant).toBe("success") - expect(result.message).toBe("Test message") - expect(result.duration).toBe(5000) - expect(result.icon).toBe("check") - end) - - it_each(cases.toast_duration, "$desc", function(tc) - local toast_success = require("toast_success") - local result = toast_success(tc.message, tc.duration) - expect(result.duration).toBe(tc.expected_duration) - end) - end) - - describe("error toast", function() - local toast_error = require("toast_error") - - it("creates error toast with correct properties", function() - local result = toast_error("Error message") - expect(result.type).toBe("toast") - expect(result.variant).toBe("error") - expect(result.message).toBe("Error message") - end) - end) - - describe("warning toast", function() - local toast_warning = require("toast_warning") - - it("creates warning toast with correct properties", function() - local result = toast_warning("Warning message") - expect(result.type).toBe("toast") - expect(result.variant).toBe("warning") - expect(result.message).toBe("Warning message") - end) - end) - - describe("info toast", function() - local toast_info = require("toast_info") - - it("creates info toast with correct properties", function() - local result = toast_info("Info message") - expect(result.type).toBe("toast") - expect(result.variant).toBe("info") - expect(result.message).toBe("Info message") - end) - end) -end) - -describe("Prepare Summary", function() - local cases = load_cases("notifications.cases.json") - local prepare_summary = require("prepare_summary") - - describe("title handling", function() - it_each(cases.prepare_summary.title_variations, "$desc", function(tc) - local props = { title = tc.title, items = {} } - local result = prepare_summary(props) - expect(result.title).toBe(tc.expected_title) - end) - end) - - describe("items processing", function() - it_each(cases.prepare_summary.items_processing, "$desc", function(tc) - local props = { items = tc.items } - local result = prepare_summary(props) - expect(#result.items).toBe(tc.expected_count) - end) - - it("enriches items with severity classes", function() - local props = { - items = { - { label = "Test", count = 5, severity = "warning" } - } - } - local result = prepare_summary(props) - expect(result.items[1].classes).toBe("summary-item--warning") - end) - end) -end) +-- Notification Center functionality tests +-- Uses lua_test framework with parameterized test cases + +describe("Calculate Total", function() + local cases = load_cases("notifications.cases.json") + local calculate_total = require("calculate_total") + + it_each(cases.calculate_total, "$desc", function(tc) + local result = calculate_total(tc.items) + expect(result).toBe(tc.expected) + end) +end) + +describe("Get Severity Class", function() + local cases = load_cases("notifications.cases.json") + local get_severity_class = require("get_severity_class") + + it_each(cases.get_severity_class, "$desc", function(tc) + local result = get_severity_class(tc.severity) + expect(result).toBe(tc.expected) + end) +end) + +describe("Toast Notifications", function() + local cases = load_cases("notifications.cases.json") + + describe("success toast", function() + local toast_success = require("toast_success") + + it("creates success toast with correct properties", function() + local result = toast_success("Test message", 5000) + expect(result.type).toBe("toast") + expect(result.variant).toBe("success") + expect(result.message).toBe("Test message") + expect(result.duration).toBe(5000) + expect(result.icon).toBe("check") + end) + + it_each(cases.toast_duration, "$desc", function(tc) + local toast_success = require("toast_success") + local result = toast_success(tc.message, tc.duration) + expect(result.duration).toBe(tc.expected_duration) + end) + end) + + describe("error toast", function() + local toast_error = require("toast_error") + + it("creates error toast with correct properties", function() + local result = toast_error("Error message") + expect(result.type).toBe("toast") + expect(result.variant).toBe("error") + expect(result.message).toBe("Error message") + end) + end) + + describe("warning toast", function() + local toast_warning = require("toast_warning") + + it("creates warning toast with correct properties", function() + local result = toast_warning("Warning message") + expect(result.type).toBe("toast") + expect(result.variant).toBe("warning") + expect(result.message).toBe("Warning message") + end) + end) + + describe("info toast", function() + local toast_info = require("toast_info") + + it("creates info toast with correct properties", function() + local result = toast_info("Info message") + expect(result.type).toBe("toast") + expect(result.variant).toBe("info") + expect(result.message).toBe("Info message") + end) + end) +end) + +describe("Prepare Summary", function() + local cases = load_cases("notifications.cases.json") + local prepare_summary = require("prepare_summary") + + describe("title handling", function() + it_each(cases.prepare_summary.title_variations, "$desc", function(tc) + local props = { title = tc.title, items = {} } + local result = prepare_summary(props) + expect(result.title).toBe(tc.expected_title) + end) + end) + + describe("items processing", function() + it_each(cases.prepare_summary.items_processing, "$desc", function(tc) + local props = { items = tc.items } + local result = prepare_summary(props) + expect(#result.items).toBe(tc.expected_count) + end) + + it("enriches items with severity classes", function() + local props = { + items = { + { label = "Test", count = 5, severity = "warning" } + } + } + local result = prepare_summary(props) + expect(result.items[1].classes).toBe("summary-item--warning") + end) + end) +end)