mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-23 00:33:50 +02:00
add test
This commit is contained in:
145
src/views/Sidebar/__tests__/friendsSidebarUtils.test.js
Normal file
145
src/views/Sidebar/__tests__/friendsSidebarUtils.test.js
Normal file
@@ -0,0 +1,145 @@
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import {
|
||||
buildFriendRow,
|
||||
buildInstanceHeaderRow,
|
||||
buildToggleRow,
|
||||
estimateRowSize
|
||||
} from '../friendsSidebarUtils';
|
||||
|
||||
// ─── buildToggleRow ──────────────────────────────────────────────────
|
||||
|
||||
describe('buildToggleRow', () => {
|
||||
test('creates a toggle-header row with defaults', () => {
|
||||
const row = buildToggleRow({ key: 'online', label: 'Online' });
|
||||
expect(row).toEqual({
|
||||
type: 'toggle-header',
|
||||
key: 'online',
|
||||
label: 'Online',
|
||||
count: null,
|
||||
expanded: true,
|
||||
headerPadding: null,
|
||||
paddingBottom: null,
|
||||
onClick: null
|
||||
});
|
||||
});
|
||||
|
||||
test('accepts all optional parameters', () => {
|
||||
const onClick = () => {};
|
||||
const row = buildToggleRow({
|
||||
key: 'vip',
|
||||
label: 'VIP',
|
||||
count: 5,
|
||||
expanded: false,
|
||||
headerPadding: 10,
|
||||
paddingBottom: 8,
|
||||
onClick
|
||||
});
|
||||
expect(row.count).toBe(5);
|
||||
expect(row.expanded).toBe(false);
|
||||
expect(row.headerPadding).toBe(10);
|
||||
expect(row.paddingBottom).toBe(8);
|
||||
expect(row.onClick).toBe(onClick);
|
||||
});
|
||||
|
||||
test('always sets type to toggle-header', () => {
|
||||
const row = buildToggleRow({ key: 'x', label: 'X' });
|
||||
expect(row.type).toBe('toggle-header');
|
||||
});
|
||||
});
|
||||
|
||||
// ─── buildFriendRow ──────────────────────────────────────────────────
|
||||
|
||||
describe('buildFriendRow', () => {
|
||||
const friend = { id: 'usr_123', displayName: 'TestUser' };
|
||||
|
||||
test('creates a friend-item row with defaults', () => {
|
||||
const row = buildFriendRow(friend, 'friend:usr_123');
|
||||
expect(row).toEqual({
|
||||
type: 'friend-item',
|
||||
key: 'friend:usr_123',
|
||||
friend,
|
||||
isGroupByInstance: undefined,
|
||||
paddingBottom: undefined,
|
||||
itemStyle: undefined
|
||||
});
|
||||
});
|
||||
|
||||
test('passes options through', () => {
|
||||
const style = { opacity: 0.5 };
|
||||
const row = buildFriendRow(friend, 'k', {
|
||||
isGroupByInstance: true,
|
||||
paddingBottom: 4,
|
||||
itemStyle: style
|
||||
});
|
||||
expect(row.isGroupByInstance).toBe(true);
|
||||
expect(row.paddingBottom).toBe(4);
|
||||
expect(row.itemStyle).toBe(style);
|
||||
});
|
||||
|
||||
test('always sets type to friend-item', () => {
|
||||
const row = buildFriendRow(friend, 'k');
|
||||
expect(row.type).toBe('friend-item');
|
||||
});
|
||||
});
|
||||
|
||||
// ─── buildInstanceHeaderRow ──────────────────────────────────────────
|
||||
|
||||
describe('buildInstanceHeaderRow', () => {
|
||||
test('creates an instance-header row', () => {
|
||||
const row = buildInstanceHeaderRow(
|
||||
'wrld_123:456~private',
|
||||
3,
|
||||
'inst:wrld_123'
|
||||
);
|
||||
expect(row).toEqual({
|
||||
type: 'instance-header',
|
||||
key: 'inst:wrld_123',
|
||||
location: 'wrld_123:456~private',
|
||||
count: 3,
|
||||
paddingBottom: 4
|
||||
});
|
||||
});
|
||||
|
||||
test('always has paddingBottom of 4', () => {
|
||||
const row = buildInstanceHeaderRow('loc', 1, 'k');
|
||||
expect(row.paddingBottom).toBe(4);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── estimateRowSize ─────────────────────────────────────────────────
|
||||
|
||||
describe('estimateRowSize', () => {
|
||||
test('returns 44 for null/undefined', () => {
|
||||
expect(estimateRowSize(null)).toBe(44);
|
||||
expect(estimateRowSize(undefined)).toBe(44);
|
||||
});
|
||||
|
||||
test('returns 28 + paddingBottom for toggle-header', () => {
|
||||
expect(estimateRowSize({ type: 'toggle-header' })).toBe(28);
|
||||
expect(
|
||||
estimateRowSize({ type: 'toggle-header', paddingBottom: 8 })
|
||||
).toBe(36);
|
||||
});
|
||||
|
||||
test('returns 24 + paddingBottom for vip-subheader', () => {
|
||||
expect(estimateRowSize({ type: 'vip-subheader' })).toBe(24);
|
||||
expect(
|
||||
estimateRowSize({ type: 'vip-subheader', paddingBottom: 4 })
|
||||
).toBe(28);
|
||||
});
|
||||
|
||||
test('returns 26 + paddingBottom for instance-header', () => {
|
||||
expect(estimateRowSize({ type: 'instance-header' })).toBe(26);
|
||||
expect(
|
||||
estimateRowSize({ type: 'instance-header', paddingBottom: 4 })
|
||||
).toBe(30);
|
||||
});
|
||||
|
||||
test('returns 52 + paddingBottom for any other type (friend-item)', () => {
|
||||
expect(estimateRowSize({ type: 'friend-item' })).toBe(52);
|
||||
expect(estimateRowSize({ type: 'friend-item', paddingBottom: 6 })).toBe(
|
||||
58
|
||||
);
|
||||
});
|
||||
});
|
||||
159
src/views/Sidebar/__tests__/groupsSidebarUtils.test.js
Normal file
159
src/views/Sidebar/__tests__/groupsSidebarUtils.test.js
Normal file
@@ -0,0 +1,159 @@
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import {
|
||||
buildGroupHeaderRow,
|
||||
buildGroupItemRow,
|
||||
estimateGroupRowSize,
|
||||
getGroupId
|
||||
} from '../groupsSidebarUtils';
|
||||
|
||||
// ─── getGroupId ──────────────────────────────────────────────────────
|
||||
|
||||
describe('getGroupId', () => {
|
||||
test('extracts groupId from first element', () => {
|
||||
const group = [{ group: { groupId: 'grp_abc' } }];
|
||||
expect(getGroupId(group)).toBe('grp_abc');
|
||||
});
|
||||
|
||||
test('returns empty string for empty array', () => {
|
||||
expect(getGroupId([])).toBe('');
|
||||
});
|
||||
|
||||
test('returns empty string when group property is missing', () => {
|
||||
expect(getGroupId([{}])).toBe('');
|
||||
expect(getGroupId([{ group: {} }])).toBe('');
|
||||
});
|
||||
});
|
||||
|
||||
// ─── buildGroupHeaderRow ─────────────────────────────────────────────
|
||||
|
||||
describe('buildGroupHeaderRow', () => {
|
||||
const group = [
|
||||
{ group: { groupId: 'grp_1', name: 'Test Group' } },
|
||||
{ group: { groupId: 'grp_1', name: 'Test Group' } }
|
||||
];
|
||||
|
||||
test('builds header row with correct properties', () => {
|
||||
const cfg = { grp_1: { isCollapsed: false } };
|
||||
const row = buildGroupHeaderRow(group, 0, cfg);
|
||||
expect(row).toEqual({
|
||||
type: 'group-header',
|
||||
key: 'group-header:grp_1',
|
||||
groupId: 'grp_1',
|
||||
label: 'Test Group',
|
||||
count: 2,
|
||||
isCollapsed: false,
|
||||
headerPaddingTop: '0px'
|
||||
});
|
||||
});
|
||||
|
||||
test('sets headerPaddingTop to 10px for non-first groups', () => {
|
||||
const cfg = {};
|
||||
const row = buildGroupHeaderRow(group, 1, cfg);
|
||||
expect(row.headerPaddingTop).toBe('10px');
|
||||
});
|
||||
|
||||
test('reflects collapsed state from config', () => {
|
||||
const cfg = { grp_1: { isCollapsed: true } };
|
||||
const row = buildGroupHeaderRow(group, 0, cfg);
|
||||
expect(row.isCollapsed).toBe(true);
|
||||
});
|
||||
|
||||
test('defaults to not collapsed when cfg entry is missing', () => {
|
||||
const cfg = {};
|
||||
const row = buildGroupHeaderRow(group, 0, cfg);
|
||||
expect(row.isCollapsed).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── buildGroupItemRow ───────────────────────────────────────────────
|
||||
|
||||
describe('buildGroupItemRow', () => {
|
||||
const ref = {
|
||||
group: { iconUrl: 'https://example.com/icon.png', name: 'My Group' },
|
||||
instance: {
|
||||
id: 'inst_123',
|
||||
ownerId: 'usr_456',
|
||||
userCount: 5,
|
||||
capacity: 16,
|
||||
location: 'wrld_abc:inst_123~private'
|
||||
}
|
||||
};
|
||||
|
||||
test('builds item row with correct properties', () => {
|
||||
const row = buildGroupItemRow(ref, 0, 'grp_1', true);
|
||||
expect(row).toEqual({
|
||||
type: 'group-item',
|
||||
key: 'group-item:grp_1:inst_123',
|
||||
ownerId: 'usr_456',
|
||||
iconUrl: 'https://example.com/icon.png',
|
||||
name: 'My Group',
|
||||
userCount: 5,
|
||||
capacity: 16,
|
||||
location: 'wrld_abc:inst_123~private',
|
||||
isVisible: true
|
||||
});
|
||||
});
|
||||
|
||||
test('uses index as fallback key when instance id is missing', () => {
|
||||
const row = buildGroupItemRow({}, 7, 'grp_1', true);
|
||||
expect(row.key).toBe('group-item:grp_1:7');
|
||||
});
|
||||
|
||||
test('defaults to empty/zero values for missing properties', () => {
|
||||
const row = buildGroupItemRow({}, 0, 'grp_1', true);
|
||||
expect(row.ownerId).toBe('');
|
||||
expect(row.iconUrl).toBe('');
|
||||
expect(row.name).toBe('');
|
||||
expect(row.userCount).toBe(0);
|
||||
expect(row.capacity).toBe(0);
|
||||
expect(row.location).toBe('');
|
||||
});
|
||||
|
||||
test('hides age-gated instances when isAgeGatedVisible is false', () => {
|
||||
const ageGatedRef = { ...ref, ageGate: true };
|
||||
const row = buildGroupItemRow(ageGatedRef, 0, 'grp_1', false);
|
||||
expect(row.isVisible).toBe(false);
|
||||
});
|
||||
|
||||
test('shows age-gated instances when isAgeGatedVisible is true', () => {
|
||||
const ageGatedRef = { ...ref, ageGate: true };
|
||||
const row = buildGroupItemRow(ageGatedRef, 0, 'grp_1', true);
|
||||
expect(row.isVisible).toBe(true);
|
||||
});
|
||||
|
||||
test('detects age gate from location string', () => {
|
||||
const refWithAgeGateLocation = {
|
||||
...ref,
|
||||
location: 'wrld_abc:inst_123~ageGate'
|
||||
};
|
||||
const row = buildGroupItemRow(
|
||||
refWithAgeGateLocation,
|
||||
0,
|
||||
'grp_1',
|
||||
false
|
||||
);
|
||||
expect(row.isVisible).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── estimateGroupRowSize ────────────────────────────────────────────
|
||||
|
||||
describe('estimateGroupRowSize', () => {
|
||||
test('returns 44 for null/undefined', () => {
|
||||
expect(estimateGroupRowSize(null)).toBe(44);
|
||||
expect(estimateGroupRowSize(undefined)).toBe(44);
|
||||
});
|
||||
|
||||
test('returns 30 for group-header', () => {
|
||||
expect(estimateGroupRowSize({ type: 'group-header' })).toBe(30);
|
||||
});
|
||||
|
||||
test('returns 52 for group-item', () => {
|
||||
expect(estimateGroupRowSize({ type: 'group-item' })).toBe(52);
|
||||
});
|
||||
|
||||
test('returns 52 for unknown type', () => {
|
||||
expect(estimateGroupRowSize({ type: 'unknown' })).toBe(52);
|
||||
});
|
||||
});
|
||||
69
src/views/Sidebar/__tests__/sidebarSettingsUtils.test.js
Normal file
69
src/views/Sidebar/__tests__/sidebarSettingsUtils.test.js
Normal file
@@ -0,0 +1,69 @@
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import {
|
||||
normalizeFavoriteGroupsChange,
|
||||
resolveFavoriteGroups
|
||||
} from '../sidebarSettingsUtils';
|
||||
|
||||
// ─── resolveFavoriteGroups ───────────────────────────────────────────
|
||||
|
||||
describe('resolveFavoriteGroups', () => {
|
||||
const allKeys = ['group_1', 'group_2', 'local:MyGroup'];
|
||||
|
||||
test('returns allKeys when stored is empty (= all)', () => {
|
||||
expect(resolveFavoriteGroups([], allKeys)).toEqual(allKeys);
|
||||
});
|
||||
|
||||
test('returns stored value when not empty', () => {
|
||||
const stored = ['group_1'];
|
||||
expect(resolveFavoriteGroups(stored, allKeys)).toEqual(stored);
|
||||
});
|
||||
|
||||
test('returns stored even if it equals allKeys', () => {
|
||||
expect(resolveFavoriteGroups([...allKeys], allKeys)).toEqual(allKeys);
|
||||
});
|
||||
|
||||
test('handles empty allKeys', () => {
|
||||
expect(resolveFavoriteGroups([], [])).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── normalizeFavoriteGroupsChange ───────────────────────────────────
|
||||
|
||||
describe('normalizeFavoriteGroupsChange', () => {
|
||||
const allKeys = ['group_1', 'group_2', 'local:MyGroup'];
|
||||
|
||||
test('returns [] when value is null', () => {
|
||||
expect(normalizeFavoriteGroupsChange(null, allKeys)).toEqual([]);
|
||||
});
|
||||
|
||||
test('returns [] when value is empty array', () => {
|
||||
expect(normalizeFavoriteGroupsChange([], allKeys)).toEqual([]);
|
||||
});
|
||||
|
||||
test('returns [] when all groups are selected', () => {
|
||||
expect(normalizeFavoriteGroupsChange([...allKeys], allKeys)).toEqual(
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
test('returns [] when value is superset of allKeys', () => {
|
||||
expect(
|
||||
normalizeFavoriteGroupsChange([...allKeys, 'extra'], allKeys)
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
test('returns filter subset when not all selected', () => {
|
||||
const subset = ['group_1'];
|
||||
expect(normalizeFavoriteGroupsChange(subset, allKeys)).toEqual(subset);
|
||||
});
|
||||
|
||||
test('returns filter subset with two items', () => {
|
||||
const subset = ['group_1', 'group_2'];
|
||||
expect(normalizeFavoriteGroupsChange(subset, allKeys)).toEqual(subset);
|
||||
});
|
||||
|
||||
test('treats non-empty value as all-selected when allKeys is empty (vacuous truth)', () => {
|
||||
expect(normalizeFavoriteGroupsChange(['group_1'], [])).toEqual([]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user