@memberjunction/ng-base-forms 5.37.0 → 5.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -0
- package/dist/lib/base-form-component.d.ts +46 -0
- package/dist/lib/base-form-component.d.ts.map +1 -1
- package/dist/lib/base-form-component.js +68 -2
- package/dist/lib/base-form-component.js.map +1 -1
- package/dist/lib/container/record-form-container.component.d.ts +77 -1
- package/dist/lib/container/record-form-container.component.d.ts.map +1 -1
- package/dist/lib/container/record-form-container.component.js +157 -39
- package/dist/lib/container/record-form-container.component.js.map +1 -1
- package/dist/lib/field/fk-search-utils.d.ts +31 -0
- package/dist/lib/field/fk-search-utils.d.ts.map +1 -0
- package/dist/lib/field/fk-search-utils.js +47 -0
- package/dist/lib/field/fk-search-utils.js.map +1 -0
- package/dist/lib/field/form-field.component.d.ts +401 -6
- package/dist/lib/field/form-field.component.d.ts.map +1 -1
- package/dist/lib/field/form-field.component.js +1646 -214
- package/dist/lib/field/form-field.component.js.map +1 -1
- package/dist/lib/field/linked-field-options.d.ts +76 -0
- package/dist/lib/field/linked-field-options.d.ts.map +1 -0
- package/dist/lib/field/linked-field-options.js +80 -0
- package/dist/lib/field/linked-field-options.js.map +1 -0
- package/dist/lib/host/entity-form-host.component.d.ts +159 -0
- package/dist/lib/host/entity-form-host.component.d.ts.map +1 -0
- package/dist/lib/host/entity-form-host.component.js +539 -0
- package/dist/lib/host/entity-form-host.component.js.map +1 -0
- package/dist/lib/interactive-form/interactive-form.component.d.ts +181 -0
- package/dist/lib/interactive-form/interactive-form.component.d.ts.map +1 -0
- package/dist/lib/interactive-form/interactive-form.component.js +560 -0
- package/dist/lib/interactive-form/interactive-form.component.js.map +1 -0
- package/dist/lib/isa-related-panel/isa-related-card.component.js +2 -2
- package/dist/lib/overlays/base-form-overlay.d.ts +114 -0
- package/dist/lib/overlays/base-form-overlay.d.ts.map +1 -0
- package/dist/lib/overlays/base-form-overlay.js +227 -0
- package/dist/lib/overlays/base-form-overlay.js.map +1 -0
- package/dist/lib/overlays/form-dialog.component.d.ts +35 -0
- package/dist/lib/overlays/form-dialog.component.d.ts.map +1 -0
- package/dist/lib/overlays/form-dialog.component.js +92 -0
- package/dist/lib/overlays/form-dialog.component.js.map +1 -0
- package/dist/lib/overlays/form-presenter.service.d.ts +37 -0
- package/dist/lib/overlays/form-presenter.service.d.ts.map +1 -0
- package/dist/lib/overlays/form-presenter.service.js +130 -0
- package/dist/lib/overlays/form-presenter.service.js.map +1 -0
- package/dist/lib/overlays/form-presenter.types.d.ts +65 -0
- package/dist/lib/overlays/form-presenter.types.d.ts.map +1 -0
- package/dist/lib/overlays/form-presenter.types.js +25 -0
- package/dist/lib/overlays/form-presenter.types.js.map +1 -0
- package/dist/lib/overlays/form-slide-in.component.d.ts +38 -0
- package/dist/lib/overlays/form-slide-in.component.d.ts.map +1 -0
- package/dist/lib/overlays/form-slide-in.component.js +106 -0
- package/dist/lib/overlays/form-slide-in.component.js.map +1 -0
- package/dist/lib/overlays/form-window.component.d.ts +32 -0
- package/dist/lib/overlays/form-window.component.d.ts.map +1 -0
- package/dist/lib/overlays/form-window.component.js +93 -0
- package/dist/lib/overlays/form-window.component.js.map +1 -0
- package/dist/lib/panel/collapsible-panel.component.d.ts +19 -2
- package/dist/lib/panel/collapsible-panel.component.d.ts.map +1 -1
- package/dist/lib/panel/collapsible-panel.component.js +70 -13
- package/dist/lib/panel/collapsible-panel.component.js.map +1 -1
- package/dist/lib/panel-slot/base-form-panel.d.ts +97 -0
- package/dist/lib/panel-slot/base-form-panel.d.ts.map +1 -0
- package/dist/lib/panel-slot/base-form-panel.js +64 -0
- package/dist/lib/panel-slot/base-form-panel.js.map +1 -0
- package/dist/lib/panel-slot/form-panel-slot.component.d.ts +78 -0
- package/dist/lib/panel-slot/form-panel-slot.component.d.ts.map +1 -0
- package/dist/lib/panel-slot/form-panel-slot.component.js +227 -0
- package/dist/lib/panel-slot/form-panel-slot.component.js.map +1 -0
- package/dist/lib/panel-slot/form-slot-coordinator.service.d.ts +57 -0
- package/dist/lib/panel-slot/form-slot-coordinator.service.d.ts.map +1 -0
- package/dist/lib/panel-slot/form-slot-coordinator.service.js +104 -0
- package/dist/lib/panel-slot/form-slot-coordinator.service.js.map +1 -0
- package/dist/lib/resolver/form-resolver.service.d.ts +139 -0
- package/dist/lib/resolver/form-resolver.service.d.ts.map +1 -0
- package/dist/lib/resolver/form-resolver.service.js +235 -0
- package/dist/lib/resolver/form-resolver.service.js.map +1 -0
- package/dist/lib/section-manager/section-manager.component.js +2 -2
- package/dist/lib/toolbar/form-toolbar.component.d.ts +56 -1
- package/dist/lib/toolbar/form-toolbar.component.d.ts.map +1 -1
- package/dist/lib/toolbar/form-toolbar.component.js +294 -136
- package/dist/lib/toolbar/form-toolbar.component.js.map +1 -1
- package/dist/lib/types/entity-form-config.d.ts +125 -0
- package/dist/lib/types/entity-form-config.d.ts.map +1 -0
- package/dist/lib/types/entity-form-config.js +75 -0
- package/dist/lib/types/entity-form-config.js.map +1 -0
- package/dist/lib/types/form-types.d.ts +24 -0
- package/dist/lib/types/form-types.d.ts.map +1 -1
- package/dist/lib/types/form-types.js.map +1 -1
- package/dist/lib/types/navigation-events.d.ts +64 -2
- package/dist/lib/types/navigation-events.d.ts.map +1 -1
- package/dist/lib/types/navigation-events.js.map +1 -1
- package/dist/lib/types/toolbar-config.d.ts +11 -0
- package/dist/lib/types/toolbar-config.d.ts.map +1 -1
- package/dist/lib/types/toolbar-config.js +3 -0
- package/dist/lib/types/toolbar-config.js.map +1 -1
- package/dist/module.d.ts +14 -7
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +40 -7
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +15 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +21 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +17 -11
- package/dist/__tests__/sanity.test.d.ts +0 -2
- package/dist/__tests__/sanity.test.d.ts.map +0 -1
- package/dist/__tests__/sanity.test.js +0 -12
- package/dist/__tests__/sanity.test.js.map +0 -1
- package/dist/__tests__/tag-count-badge.test.d.ts +0 -2
- package/dist/__tests__/tag-count-badge.test.d.ts.map +0 -1
- package/dist/__tests__/tag-count-badge.test.js +0 -70
- package/dist/__tests__/tag-count-badge.test.js.map +0 -1
- package/dist/lib/__tests__/base-forms.test.d.ts +0 -2
- package/dist/lib/__tests__/base-forms.test.d.ts.map +0 -1
- package/dist/lib/__tests__/base-forms.test.js +0 -256
- package/dist/lib/__tests__/base-forms.test.js.map +0 -1
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for badge count loading logic in MjRecordFormContainerComponent.
|
|
3
|
-
*
|
|
4
|
-
* We test the pure data logic without Angular TestBed by extracting
|
|
5
|
-
* the badge count update patterns used in the container component.
|
|
6
|
-
*/
|
|
7
|
-
import { describe, it, expect } from 'vitest';
|
|
8
|
-
/**
|
|
9
|
-
* Simulates the TagCount update pattern from LoadTagCount.
|
|
10
|
-
* The real method queries RunView; here we test the state update logic.
|
|
11
|
-
*/
|
|
12
|
-
function updateTagCount(currentCount, queryResults) {
|
|
13
|
-
return queryResults.length;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Simulates the VersionCount update pattern from LoadVersionCount.
|
|
17
|
-
* The real method queries RunView; here we test the state update logic.
|
|
18
|
-
*/
|
|
19
|
-
function updateVersionCount(trackRecordChanges, queryResults) {
|
|
20
|
-
if (!trackRecordChanges)
|
|
21
|
-
return 0;
|
|
22
|
-
return queryResults.length;
|
|
23
|
-
}
|
|
24
|
-
describe('TagCount badge', () => {
|
|
25
|
-
it('should set TagCount from query result length', () => {
|
|
26
|
-
const results = [{ ID: 'a' }, { ID: 'b' }, { ID: 'c' }];
|
|
27
|
-
expect(updateTagCount(0, results)).toBe(3);
|
|
28
|
-
});
|
|
29
|
-
it('should set TagCount to 0 when no tags exist', () => {
|
|
30
|
-
expect(updateTagCount(5, [])).toBe(0);
|
|
31
|
-
});
|
|
32
|
-
it('should update TagCount when tags change', () => {
|
|
33
|
-
// Initially 2 tags
|
|
34
|
-
let count = updateTagCount(0, [{ ID: 'a' }, { ID: 'b' }]);
|
|
35
|
-
expect(count).toBe(2);
|
|
36
|
-
// After adding a tag
|
|
37
|
-
count = updateTagCount(count, [{ ID: 'a' }, { ID: 'b' }, { ID: 'c' }]);
|
|
38
|
-
expect(count).toBe(3);
|
|
39
|
-
// After removing all tags
|
|
40
|
-
count = updateTagCount(count, []);
|
|
41
|
-
expect(count).toBe(0);
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
describe('VersionCount badge', () => {
|
|
45
|
-
it('should set VersionCount from query result length', () => {
|
|
46
|
-
const results = [{ ID: 'v1' }, { ID: 'v2' }];
|
|
47
|
-
expect(updateVersionCount(true, results)).toBe(2);
|
|
48
|
-
});
|
|
49
|
-
it('should return 0 when trackRecordChanges is false', () => {
|
|
50
|
-
const results = [{ ID: 'v1' }, { ID: 'v2' }];
|
|
51
|
-
expect(updateVersionCount(false, results)).toBe(0);
|
|
52
|
-
});
|
|
53
|
-
it('should set VersionCount to 0 when no changes exist', () => {
|
|
54
|
-
expect(updateVersionCount(true, [])).toBe(0);
|
|
55
|
-
});
|
|
56
|
-
it('should reflect new versions after save', () => {
|
|
57
|
-
// Initial: 3 versions
|
|
58
|
-
let count = updateVersionCount(true, [{ ID: 'v1' }, { ID: 'v2' }, { ID: 'v3' }]);
|
|
59
|
-
expect(count).toBe(3);
|
|
60
|
-
// After a save creates a new version
|
|
61
|
-
count = updateVersionCount(true, [
|
|
62
|
-
{ ID: 'v1' },
|
|
63
|
-
{ ID: 'v2' },
|
|
64
|
-
{ ID: 'v3' },
|
|
65
|
-
{ ID: 'v4' },
|
|
66
|
-
]);
|
|
67
|
-
expect(count).toBe(4);
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
//# sourceMappingURL=tag-count-badge.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tag-count-badge.test.js","sourceRoot":"","sources":["../../src/__tests__/tag-count-badge.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tests for badge count loading logic in MjRecordFormContainerComponent.\n *\n * We test the pure data logic without Angular TestBed by extracting\n * the badge count update patterns used in the container component.\n */\nimport { describe, it, expect } from 'vitest';\n\n/**\n * Simulates the TagCount update pattern from LoadTagCount.\n * The real method queries RunView; here we test the state update logic.\n */\nfunction updateTagCount(currentCount: number, queryResults: { ID: string }[]): number {\n return queryResults.length;\n}\n\n/**\n * Simulates the VersionCount update pattern from LoadVersionCount.\n * The real method queries RunView; here we test the state update logic.\n */\nfunction updateVersionCount(\n trackRecordChanges: boolean,\n queryResults: { ID: string }[]\n): number {\n if (!trackRecordChanges) return 0;\n return queryResults.length;\n}\n\ndescribe('TagCount badge', () => {\n it('should set TagCount from query result length', () => {\n const results = [{ ID: 'a' }, { ID: 'b' }, { ID: 'c' }];\n expect(updateTagCount(0, results)).toBe(3);\n });\n\n it('should set TagCount to 0 when no tags exist', () => {\n expect(updateTagCount(5, [])).toBe(0);\n });\n\n it('should update TagCount when tags change', () => {\n // Initially 2 tags\n let count = updateTagCount(0, [{ ID: 'a' }, { ID: 'b' }]);\n expect(count).toBe(2);\n\n // After adding a tag\n count = updateTagCount(count, [{ ID: 'a' }, { ID: 'b' }, { ID: 'c' }]);\n expect(count).toBe(3);\n\n // After removing all tags\n count = updateTagCount(count, []);\n expect(count).toBe(0);\n });\n});\n\ndescribe('VersionCount badge', () => {\n it('should set VersionCount from query result length', () => {\n const results = [{ ID: 'v1' }, { ID: 'v2' }];\n expect(updateVersionCount(true, results)).toBe(2);\n });\n\n it('should return 0 when trackRecordChanges is false', () => {\n const results = [{ ID: 'v1' }, { ID: 'v2' }];\n expect(updateVersionCount(false, results)).toBe(0);\n });\n\n it('should set VersionCount to 0 when no changes exist', () => {\n expect(updateVersionCount(true, [])).toBe(0);\n });\n\n it('should reflect new versions after save', () => {\n // Initial: 3 versions\n let count = updateVersionCount(true, [{ ID: 'v1' }, { ID: 'v2' }, { ID: 'v3' }]);\n expect(count).toBe(3);\n\n // After a save creates a new version\n count = updateVersionCount(true, [\n { ID: 'v1' },\n { ID: 'v2' },\n { ID: 'v3' },\n { ID: 'v4' },\n ]);\n expect(count).toBe(4);\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base-forms.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/base-forms.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for base-forms package:
|
|
3
|
-
* - BaseFormSectionInfo
|
|
4
|
-
* - FormState interfaces and defaults
|
|
5
|
-
* - FormStateService (state management logic)
|
|
6
|
-
*/
|
|
7
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
8
|
-
// Mock Angular
|
|
9
|
-
vi.mock('@angular/core', () => ({
|
|
10
|
-
Injectable: () => (target) => target,
|
|
11
|
-
Component: () => (target) => target,
|
|
12
|
-
Directive: () => (target) => target,
|
|
13
|
-
Input: () => () => { },
|
|
14
|
-
Output: () => () => { },
|
|
15
|
-
EventEmitter: class {
|
|
16
|
-
emit() { }
|
|
17
|
-
},
|
|
18
|
-
ViewChild: () => () => { },
|
|
19
|
-
ContentChild: () => () => { },
|
|
20
|
-
ContentChildren: () => () => { },
|
|
21
|
-
ChangeDetectorRef: class {
|
|
22
|
-
detectChanges() { }
|
|
23
|
-
markForCheck() { }
|
|
24
|
-
},
|
|
25
|
-
ChangeDetectionStrategy: { OnPush: 1 },
|
|
26
|
-
ElementRef: class {
|
|
27
|
-
},
|
|
28
|
-
Injector: class {
|
|
29
|
-
},
|
|
30
|
-
ViewContainerRef: class {
|
|
31
|
-
},
|
|
32
|
-
}));
|
|
33
|
-
vi.mock('@memberjunction/core', () => {
|
|
34
|
-
const MockMetadata = class {
|
|
35
|
-
CurrentUser = { ID: 'user-123' };
|
|
36
|
-
};
|
|
37
|
-
MockMetadata.Provider = { CurrentUser: { ID: 'user-123' } };
|
|
38
|
-
return {
|
|
39
|
-
Metadata: MockMetadata,
|
|
40
|
-
BaseEntity: class {
|
|
41
|
-
},
|
|
42
|
-
RunView: class {
|
|
43
|
-
},
|
|
44
|
-
CompositeKey: class {
|
|
45
|
-
},
|
|
46
|
-
EntityField: class {
|
|
47
|
-
},
|
|
48
|
-
EntityFieldInfo: class {
|
|
49
|
-
},
|
|
50
|
-
EntityInfo: class {
|
|
51
|
-
},
|
|
52
|
-
LogError: vi.fn(),
|
|
53
|
-
};
|
|
54
|
-
});
|
|
55
|
-
vi.mock('@memberjunction/core-entities', () => ({
|
|
56
|
-
UserInfoEngine: {
|
|
57
|
-
Instance: {
|
|
58
|
-
UserSettings: [],
|
|
59
|
-
GetSetting: vi.fn(),
|
|
60
|
-
SetSetting: vi.fn(),
|
|
61
|
-
SetSettingDebounced: vi.fn(),
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
}));
|
|
65
|
-
vi.mock('rxjs', async () => {
|
|
66
|
-
const actual = await vi.importActual('rxjs');
|
|
67
|
-
return actual;
|
|
68
|
-
});
|
|
69
|
-
// ======================= BaseFormSectionInfo =======================
|
|
70
|
-
describe('BaseFormSectionInfo', () => {
|
|
71
|
-
let BaseFormSectionInfo;
|
|
72
|
-
beforeEach(async () => {
|
|
73
|
-
const mod = await import('../base-form-section-info');
|
|
74
|
-
BaseFormSectionInfo = mod.BaseFormSectionInfo;
|
|
75
|
-
});
|
|
76
|
-
it('should create with required parameters', () => {
|
|
77
|
-
const info = new BaseFormSectionInfo('details', 'Details');
|
|
78
|
-
expect(info.sectionKey).toBe('details');
|
|
79
|
-
expect(info.sectionName).toBe('Details');
|
|
80
|
-
expect(info.isExpanded).toBe(false);
|
|
81
|
-
expect(info.rowCount).toBeUndefined();
|
|
82
|
-
expect(info.metadata).toBeUndefined();
|
|
83
|
-
});
|
|
84
|
-
it('should create with all parameters', () => {
|
|
85
|
-
const info = new BaseFormSectionInfo('related', 'Related Records', true, 42, { custom: true });
|
|
86
|
-
expect(info.sectionKey).toBe('related');
|
|
87
|
-
expect(info.sectionName).toBe('Related Records');
|
|
88
|
-
expect(info.isExpanded).toBe(true);
|
|
89
|
-
expect(info.rowCount).toBe(42);
|
|
90
|
-
expect(info.metadata).toEqual({ custom: true });
|
|
91
|
-
});
|
|
92
|
-
it('should default isExpanded to false', () => {
|
|
93
|
-
const info = new BaseFormSectionInfo('section', 'Section');
|
|
94
|
-
expect(info.isExpanded).toBe(false);
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
// ======================= FormState defaults =======================
|
|
98
|
-
describe('FormState defaults', () => {
|
|
99
|
-
it('should have expected default values', async () => {
|
|
100
|
-
const { DEFAULT_FORM_STATE, DEFAULT_SECTION_STATE } = await import('../form-state.interface');
|
|
101
|
-
expect(DEFAULT_FORM_STATE.sections).toEqual({});
|
|
102
|
-
expect(DEFAULT_FORM_STATE.showEmptyFields).toBe(false);
|
|
103
|
-
expect(DEFAULT_FORM_STATE.widthMode).toBe('centered');
|
|
104
|
-
expect(DEFAULT_FORM_STATE.sectionOrder).toBeUndefined();
|
|
105
|
-
expect(DEFAULT_SECTION_STATE.isExpanded).toBe(true);
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
// ======================= FormStateService =======================
|
|
109
|
-
describe('FormStateService', () => {
|
|
110
|
-
let service;
|
|
111
|
-
beforeEach(async () => {
|
|
112
|
-
vi.clearAllMocks();
|
|
113
|
-
const mod = await import('../form-state.service');
|
|
114
|
-
service = new mod.FormStateService();
|
|
115
|
-
});
|
|
116
|
-
describe('getCurrentState', () => {
|
|
117
|
-
it('should return default state for unknown entity', () => {
|
|
118
|
-
const state = service.getCurrentState('MJTestEntity');
|
|
119
|
-
expect(state.sections).toEqual({});
|
|
120
|
-
expect(state.showEmptyFields).toBe(false);
|
|
121
|
-
expect(state.widthMode).toBe('centered');
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
describe('getSectionState', () => {
|
|
125
|
-
it('should return default section state for unknown section', () => {
|
|
126
|
-
const sectionState = service.getSectionState('MJTestEntity', 'details');
|
|
127
|
-
expect(sectionState.isExpanded).toBe(true);
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
describe('isSectionExpanded', () => {
|
|
131
|
-
it('should return default when no persisted state', () => {
|
|
132
|
-
expect(service.isSectionExpanded('MJTestEntity', 'details')).toBe(true);
|
|
133
|
-
});
|
|
134
|
-
it('should respect custom default when no persisted state', () => {
|
|
135
|
-
expect(service.isSectionExpanded('MJTestEntity', 'details', false)).toBe(false);
|
|
136
|
-
});
|
|
137
|
-
it('should return persisted value when state exists', () => {
|
|
138
|
-
service.setSectionExpanded('MJTestEntity', 'details', false);
|
|
139
|
-
expect(service.isSectionExpanded('MJTestEntity', 'details')).toBe(false);
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
describe('setSectionExpanded', () => {
|
|
143
|
-
it('should update section expanded state', () => {
|
|
144
|
-
service.setSectionExpanded('MJTestEntity', 'details', false);
|
|
145
|
-
expect(service.isSectionExpanded('MJTestEntity', 'details')).toBe(false);
|
|
146
|
-
service.setSectionExpanded('MJTestEntity', 'details', true);
|
|
147
|
-
expect(service.isSectionExpanded('MJTestEntity', 'details')).toBe(true);
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
describe('toggleSection', () => {
|
|
151
|
-
it('should toggle section expanded state', () => {
|
|
152
|
-
// Default is expanded (true)
|
|
153
|
-
expect(service.isSectionExpanded('MJTestEntity', 'sec1')).toBe(true);
|
|
154
|
-
service.toggleSection('MJTestEntity', 'sec1');
|
|
155
|
-
expect(service.isSectionExpanded('MJTestEntity', 'sec1')).toBe(false);
|
|
156
|
-
service.toggleSection('MJTestEntity', 'sec1');
|
|
157
|
-
expect(service.isSectionExpanded('MJTestEntity', 'sec1')).toBe(true);
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
describe('widthMode', () => {
|
|
161
|
-
it('should default to centered', () => {
|
|
162
|
-
expect(service.getWidthMode('MJTestEntity')).toBe('centered');
|
|
163
|
-
});
|
|
164
|
-
it('should set width mode', () => {
|
|
165
|
-
service.setWidthMode('MJTestEntity', 'full-width');
|
|
166
|
-
expect(service.getWidthMode('MJTestEntity')).toBe('full-width');
|
|
167
|
-
});
|
|
168
|
-
it('should toggle width mode', () => {
|
|
169
|
-
service.toggleWidthMode('MJTestEntity');
|
|
170
|
-
expect(service.getWidthMode('MJTestEntity')).toBe('full-width');
|
|
171
|
-
service.toggleWidthMode('MJTestEntity');
|
|
172
|
-
expect(service.getWidthMode('MJTestEntity')).toBe('centered');
|
|
173
|
-
});
|
|
174
|
-
});
|
|
175
|
-
describe('showEmptyFields', () => {
|
|
176
|
-
it('should default to false', () => {
|
|
177
|
-
expect(service.getShowEmptyFields('MJTestEntity')).toBe(false);
|
|
178
|
-
});
|
|
179
|
-
it('should set showEmptyFields', () => {
|
|
180
|
-
service.setShowEmptyFields('MJTestEntity', true);
|
|
181
|
-
expect(service.getShowEmptyFields('MJTestEntity')).toBe(true);
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
describe('expandAllSections / collapseAllSections', () => {
|
|
185
|
-
it('should expand all sections', () => {
|
|
186
|
-
const keys = ['sec1', 'sec2', 'sec3'];
|
|
187
|
-
// Collapse some first
|
|
188
|
-
service.setSectionExpanded('MJTestEntity', 'sec1', false);
|
|
189
|
-
service.setSectionExpanded('MJTestEntity', 'sec2', false);
|
|
190
|
-
service.expandAllSections('MJTestEntity', keys);
|
|
191
|
-
keys.forEach(key => {
|
|
192
|
-
expect(service.isSectionExpanded('MJTestEntity', key)).toBe(true);
|
|
193
|
-
});
|
|
194
|
-
});
|
|
195
|
-
it('should collapse all sections', () => {
|
|
196
|
-
const keys = ['sec1', 'sec2', 'sec3'];
|
|
197
|
-
service.collapseAllSections('MJTestEntity', keys);
|
|
198
|
-
keys.forEach(key => {
|
|
199
|
-
expect(service.isSectionExpanded('MJTestEntity', key)).toBe(false);
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
describe('sectionOrder', () => {
|
|
204
|
-
it('should return undefined by default', () => {
|
|
205
|
-
expect(service.getSectionOrder('MJTestEntity')).toBeUndefined();
|
|
206
|
-
});
|
|
207
|
-
it('should set custom section order', () => {
|
|
208
|
-
const order = ['sec3', 'sec1', 'sec2'];
|
|
209
|
-
service.setSectionOrder('MJTestEntity', order);
|
|
210
|
-
expect(service.getSectionOrder('MJTestEntity')).toEqual(order);
|
|
211
|
-
});
|
|
212
|
-
it('should detect custom section order', () => {
|
|
213
|
-
expect(service.hasCustomSectionOrder('MJTestEntity')).toBe(false);
|
|
214
|
-
service.setSectionOrder('MJTestEntity', ['sec1', 'sec2']);
|
|
215
|
-
expect(service.hasCustomSectionOrder('MJTestEntity')).toBe(true);
|
|
216
|
-
});
|
|
217
|
-
it('should reset section order', () => {
|
|
218
|
-
service.setSectionOrder('MJTestEntity', ['sec1', 'sec2']);
|
|
219
|
-
service.resetSectionOrder('MJTestEntity');
|
|
220
|
-
expect(service.getSectionOrder('MJTestEntity')).toBeUndefined();
|
|
221
|
-
});
|
|
222
|
-
});
|
|
223
|
-
describe('getExpandedCount', () => {
|
|
224
|
-
it('should count expanded sections', () => {
|
|
225
|
-
const keys = ['sec1', 'sec2', 'sec3'];
|
|
226
|
-
// Default is all expanded
|
|
227
|
-
expect(service.getExpandedCount('MJTestEntity', keys)).toBe(3);
|
|
228
|
-
service.setSectionExpanded('MJTestEntity', 'sec1', false);
|
|
229
|
-
expect(service.getExpandedCount('MJTestEntity', keys)).toBe(2);
|
|
230
|
-
});
|
|
231
|
-
});
|
|
232
|
-
describe('resetToDefaults', () => {
|
|
233
|
-
it('should reset all state for entity', () => {
|
|
234
|
-
service.setSectionExpanded('MJTestEntity', 'sec1', false);
|
|
235
|
-
service.setWidthMode('MJTestEntity', 'full-width');
|
|
236
|
-
service.setShowEmptyFields('MJTestEntity', true);
|
|
237
|
-
service.resetToDefaults('MJTestEntity');
|
|
238
|
-
expect(service.getCurrentState('MJTestEntity').sections).toEqual({});
|
|
239
|
-
expect(service.getWidthMode('MJTestEntity')).toBe('centered');
|
|
240
|
-
expect(service.getShowEmptyFields('MJTestEntity')).toBe(false);
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
|
-
describe('getState$ (observable)', () => {
|
|
244
|
-
it('should emit state changes', async () => {
|
|
245
|
-
const states = [];
|
|
246
|
-
const sub = service.getState$('MJTestEntity').subscribe(s => states.push(s));
|
|
247
|
-
// Initial state emission
|
|
248
|
-
expect(states.length).toBeGreaterThanOrEqual(1);
|
|
249
|
-
expect(states[0].widthMode).toBe('centered');
|
|
250
|
-
service.setWidthMode('MJTestEntity', 'full-width');
|
|
251
|
-
expect(states[states.length - 1].widthMode).toBe('full-width');
|
|
252
|
-
sub.unsubscribe();
|
|
253
|
-
});
|
|
254
|
-
});
|
|
255
|
-
});
|
|
256
|
-
//# sourceMappingURL=base-forms.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base-forms.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/base-forms.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAE9D,eAAe;AACf,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9B,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,MAAgB,EAAE,EAAE,CAAC,MAAM;IAC9C,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,MAAgB,EAAE,EAAE,CAAC,MAAM;IAC7C,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,MAAgB,EAAE,EAAE,CAAC,MAAM;IAC7C,KAAK,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC;IACrB,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC;IACtB,YAAY,EAAE;QAAQ,IAAI,KAAI,CAAC;KAAE;IACjC,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC;IACzB,YAAY,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC;IAC5B,eAAe,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC;IAC/B,iBAAiB,EAAE;QAAQ,aAAa,KAAI,CAAC;QAAC,YAAY,KAAI,CAAC;KAAE;IACjE,uBAAuB,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;IACtC,UAAU,EAAE;KAAQ;IACpB,QAAQ,EAAE;KAAQ;IAClB,gBAAgB,EAAE;KAAQ;CAC3B,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACnC,MAAM,YAAY,GAAQ;QACxB,WAAW,GAAG,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC;KAClC,CAAC;IACF,YAAY,CAAC,QAAQ,GAAG,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC;IAC5D,OAAO;QACL,QAAQ,EAAE,YAAY;QACtB,UAAU,EAAE;SAAQ;QACpB,OAAO,EAAE;SAAQ;QACjB,YAAY,EAAE;SAAQ;QACtB,WAAW,EAAE;SAAQ;QACrB,eAAe,EAAE;SAAQ;QACzB,UAAU,EAAE;SAAQ;QACpB,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE;KAClB,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,IAAI,CAAC,+BAA+B,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9C,cAAc,EAAE;QACd,QAAQ,EAAE;YACR,YAAY,EAAE,EAAE;YAChB,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE;YACnB,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE;YACnB,mBAAmB,EAAE,EAAE,CAAC,EAAE,EAAE;SAC7B;KACF;CACF,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE;IACzB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,YAAY,CAAwB,MAAM,CAAC,CAAC;IACpE,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH,sEAAsE;AACtE,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,IAAI,mBAAmF,CAAC;IAExF,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,2BAA2B,CAAC,CAAC;QACtD,mBAAmB,GAAG,GAAG,CAAC,mBAAmB,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,IAAI,GAAG,IAAI,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAC3D,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,aAAa,EAAE,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,aAAa,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,IAAI,GAAG,IAAI,mBAAmB,CAAC,SAAS,EAAE,iBAAiB,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/F,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,IAAI,GAAG,IAAI,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAC3D,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,qEAAqE;AACrE,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;QAE9F,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChD,MAAM,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvD,MAAM,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtD,MAAM,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,aAAa,EAAE,CAAC;QAExD,MAAM,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,mEAAmE;AACnE,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,IAAI,OAA8E,CAAC;IAEnF,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;QAClD,OAAO,GAAG,IAAI,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,KAAK,GAAG,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;YACtD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACnC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1C,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;YACjE,MAAM,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;YACxE,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;YAC/D,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,cAAc,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,OAAO,CAAC,kBAAkB,CAAC,cAAc,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YAC7D,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,OAAO,CAAC,kBAAkB,CAAC,cAAc,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YAC7D,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAEzE,OAAO,CAAC,kBAAkB,CAAC,cAAc,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;YAC5D,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,6BAA6B;YAC7B,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAErE,OAAO,CAAC,aAAa,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;YAC9C,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAEtE,OAAO,CAAC,aAAa,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;YAC9C,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;QACzB,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;YACpC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;YAC/B,OAAO,CAAC,YAAY,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;YACnD,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;YAClC,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;YACxC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAEhE,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;YACxC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;YACjC,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;YACpC,OAAO,CAAC,kBAAkB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;YACjD,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACvD,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;YACpC,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YACtC,sBAAsB;YACtB,OAAO,CAAC,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;YAC1D,OAAO,CAAC,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;YAE1D,OAAO,CAAC,iBAAiB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;YAChD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBACjB,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YACtC,OAAO,CAAC,mBAAmB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;YAClD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBACjB,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACzC,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YACvC,OAAO,CAAC,eAAe,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;YAC/C,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAElE,OAAO,CAAC,eAAe,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;YAC1D,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;YACpC,OAAO,CAAC,eAAe,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;YAC1D,OAAO,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC;YAC1C,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QAClE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YACtC,0BAA0B;YAC1B,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAE/D,OAAO,CAAC,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;YAC1D,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,OAAO,CAAC,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;YAC1D,OAAO,CAAC,YAAY,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;YACnD,OAAO,CAAC,kBAAkB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;YAEjD,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;YAExC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACrE,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC9D,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;YACzC,MAAM,MAAM,GAAiC,EAAE,CAAC;YAChD,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAE7E,yBAAyB;YACzB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;YAChD,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAE7C,OAAO,CAAC,YAAY,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;YACnD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAE/D,GAAG,CAAC,WAAW,EAAE,CAAC;QACpB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/**\n * Tests for base-forms package:\n * - BaseFormSectionInfo\n * - FormState interfaces and defaults\n * - FormStateService (state management logic)\n */\nimport { describe, it, expect, vi, beforeEach } from 'vitest';\n\n// Mock Angular\nvi.mock('@angular/core', () => ({\n Injectable: () => (target: Function) => target,\n Component: () => (target: Function) => target,\n Directive: () => (target: Function) => target,\n Input: () => () => {},\n Output: () => () => {},\n EventEmitter: class { emit() {} },\n ViewChild: () => () => {},\n ContentChild: () => () => {},\n ContentChildren: () => () => {},\n ChangeDetectorRef: class { detectChanges() {} markForCheck() {} },\n ChangeDetectionStrategy: { OnPush: 1 },\n ElementRef: class {},\n Injector: class {},\n ViewContainerRef: class {},\n}));\n\nvi.mock('@memberjunction/core', () => {\n const MockMetadata: any = class {\n CurrentUser = { ID: 'user-123' };\n };\n MockMetadata.Provider = { CurrentUser: { ID: 'user-123' } };\n return {\n Metadata: MockMetadata,\n BaseEntity: class {},\n RunView: class {},\n CompositeKey: class {},\n EntityField: class {},\n EntityFieldInfo: class {},\n EntityInfo: class {},\n LogError: vi.fn(),\n };\n});\n\nvi.mock('@memberjunction/core-entities', () => ({\n UserInfoEngine: {\n Instance: {\n UserSettings: [],\n GetSetting: vi.fn(),\n SetSetting: vi.fn(),\n SetSettingDebounced: vi.fn(),\n }\n },\n}));\n\nvi.mock('rxjs', async () => {\n const actual = await vi.importActual<typeof import('rxjs')>('rxjs');\n return actual;\n});\n\n// ======================= BaseFormSectionInfo =======================\ndescribe('BaseFormSectionInfo', () => {\n let BaseFormSectionInfo: typeof import('../base-form-section-info').BaseFormSectionInfo;\n\n beforeEach(async () => {\n const mod = await import('../base-form-section-info');\n BaseFormSectionInfo = mod.BaseFormSectionInfo;\n });\n\n it('should create with required parameters', () => {\n const info = new BaseFormSectionInfo('details', 'Details');\n expect(info.sectionKey).toBe('details');\n expect(info.sectionName).toBe('Details');\n expect(info.isExpanded).toBe(false);\n expect(info.rowCount).toBeUndefined();\n expect(info.metadata).toBeUndefined();\n });\n\n it('should create with all parameters', () => {\n const info = new BaseFormSectionInfo('related', 'Related Records', true, 42, { custom: true });\n expect(info.sectionKey).toBe('related');\n expect(info.sectionName).toBe('Related Records');\n expect(info.isExpanded).toBe(true);\n expect(info.rowCount).toBe(42);\n expect(info.metadata).toEqual({ custom: true });\n });\n\n it('should default isExpanded to false', () => {\n const info = new BaseFormSectionInfo('section', 'Section');\n expect(info.isExpanded).toBe(false);\n });\n});\n\n// ======================= FormState defaults =======================\ndescribe('FormState defaults', () => {\n it('should have expected default values', async () => {\n const { DEFAULT_FORM_STATE, DEFAULT_SECTION_STATE } = await import('../form-state.interface');\n\n expect(DEFAULT_FORM_STATE.sections).toEqual({});\n expect(DEFAULT_FORM_STATE.showEmptyFields).toBe(false);\n expect(DEFAULT_FORM_STATE.widthMode).toBe('centered');\n expect(DEFAULT_FORM_STATE.sectionOrder).toBeUndefined();\n\n expect(DEFAULT_SECTION_STATE.isExpanded).toBe(true);\n });\n});\n\n// ======================= FormStateService =======================\ndescribe('FormStateService', () => {\n let service: InstanceType<typeof import('../form-state.service').FormStateService>;\n\n beforeEach(async () => {\n vi.clearAllMocks();\n const mod = await import('../form-state.service');\n service = new mod.FormStateService();\n });\n\n describe('getCurrentState', () => {\n it('should return default state for unknown entity', () => {\n const state = service.getCurrentState('MJTestEntity');\n expect(state.sections).toEqual({});\n expect(state.showEmptyFields).toBe(false);\n expect(state.widthMode).toBe('centered');\n });\n });\n\n describe('getSectionState', () => {\n it('should return default section state for unknown section', () => {\n const sectionState = service.getSectionState('MJTestEntity', 'details');\n expect(sectionState.isExpanded).toBe(true);\n });\n });\n\n describe('isSectionExpanded', () => {\n it('should return default when no persisted state', () => {\n expect(service.isSectionExpanded('MJTestEntity', 'details')).toBe(true);\n });\n\n it('should respect custom default when no persisted state', () => {\n expect(service.isSectionExpanded('MJTestEntity', 'details', false)).toBe(false);\n });\n\n it('should return persisted value when state exists', () => {\n service.setSectionExpanded('MJTestEntity', 'details', false);\n expect(service.isSectionExpanded('MJTestEntity', 'details')).toBe(false);\n });\n });\n\n describe('setSectionExpanded', () => {\n it('should update section expanded state', () => {\n service.setSectionExpanded('MJTestEntity', 'details', false);\n expect(service.isSectionExpanded('MJTestEntity', 'details')).toBe(false);\n\n service.setSectionExpanded('MJTestEntity', 'details', true);\n expect(service.isSectionExpanded('MJTestEntity', 'details')).toBe(true);\n });\n });\n\n describe('toggleSection', () => {\n it('should toggle section expanded state', () => {\n // Default is expanded (true)\n expect(service.isSectionExpanded('MJTestEntity', 'sec1')).toBe(true);\n\n service.toggleSection('MJTestEntity', 'sec1');\n expect(service.isSectionExpanded('MJTestEntity', 'sec1')).toBe(false);\n\n service.toggleSection('MJTestEntity', 'sec1');\n expect(service.isSectionExpanded('MJTestEntity', 'sec1')).toBe(true);\n });\n });\n\n describe('widthMode', () => {\n it('should default to centered', () => {\n expect(service.getWidthMode('MJTestEntity')).toBe('centered');\n });\n\n it('should set width mode', () => {\n service.setWidthMode('MJTestEntity', 'full-width');\n expect(service.getWidthMode('MJTestEntity')).toBe('full-width');\n });\n\n it('should toggle width mode', () => {\n service.toggleWidthMode('MJTestEntity');\n expect(service.getWidthMode('MJTestEntity')).toBe('full-width');\n\n service.toggleWidthMode('MJTestEntity');\n expect(service.getWidthMode('MJTestEntity')).toBe('centered');\n });\n });\n\n describe('showEmptyFields', () => {\n it('should default to false', () => {\n expect(service.getShowEmptyFields('MJTestEntity')).toBe(false);\n });\n\n it('should set showEmptyFields', () => {\n service.setShowEmptyFields('MJTestEntity', true);\n expect(service.getShowEmptyFields('MJTestEntity')).toBe(true);\n });\n });\n\n describe('expandAllSections / collapseAllSections', () => {\n it('should expand all sections', () => {\n const keys = ['sec1', 'sec2', 'sec3'];\n // Collapse some first\n service.setSectionExpanded('MJTestEntity', 'sec1', false);\n service.setSectionExpanded('MJTestEntity', 'sec2', false);\n\n service.expandAllSections('MJTestEntity', keys);\n keys.forEach(key => {\n expect(service.isSectionExpanded('MJTestEntity', key)).toBe(true);\n });\n });\n\n it('should collapse all sections', () => {\n const keys = ['sec1', 'sec2', 'sec3'];\n service.collapseAllSections('MJTestEntity', keys);\n keys.forEach(key => {\n expect(service.isSectionExpanded('MJTestEntity', key)).toBe(false);\n });\n });\n });\n\n describe('sectionOrder', () => {\n it('should return undefined by default', () => {\n expect(service.getSectionOrder('MJTestEntity')).toBeUndefined();\n });\n\n it('should set custom section order', () => {\n const order = ['sec3', 'sec1', 'sec2'];\n service.setSectionOrder('MJTestEntity', order);\n expect(service.getSectionOrder('MJTestEntity')).toEqual(order);\n });\n\n it('should detect custom section order', () => {\n expect(service.hasCustomSectionOrder('MJTestEntity')).toBe(false);\n\n service.setSectionOrder('MJTestEntity', ['sec1', 'sec2']);\n expect(service.hasCustomSectionOrder('MJTestEntity')).toBe(true);\n });\n\n it('should reset section order', () => {\n service.setSectionOrder('MJTestEntity', ['sec1', 'sec2']);\n service.resetSectionOrder('MJTestEntity');\n expect(service.getSectionOrder('MJTestEntity')).toBeUndefined();\n });\n });\n\n describe('getExpandedCount', () => {\n it('should count expanded sections', () => {\n const keys = ['sec1', 'sec2', 'sec3'];\n // Default is all expanded\n expect(service.getExpandedCount('MJTestEntity', keys)).toBe(3);\n\n service.setSectionExpanded('MJTestEntity', 'sec1', false);\n expect(service.getExpandedCount('MJTestEntity', keys)).toBe(2);\n });\n });\n\n describe('resetToDefaults', () => {\n it('should reset all state for entity', () => {\n service.setSectionExpanded('MJTestEntity', 'sec1', false);\n service.setWidthMode('MJTestEntity', 'full-width');\n service.setShowEmptyFields('MJTestEntity', true);\n\n service.resetToDefaults('MJTestEntity');\n\n expect(service.getCurrentState('MJTestEntity').sections).toEqual({});\n expect(service.getWidthMode('MJTestEntity')).toBe('centered');\n expect(service.getShowEmptyFields('MJTestEntity')).toBe(false);\n });\n });\n\n describe('getState$ (observable)', () => {\n it('should emit state changes', async () => {\n const states: Array<{ widthMode: string }> = [];\n const sub = service.getState$('MJTestEntity').subscribe(s => states.push(s));\n\n // Initial state emission\n expect(states.length).toBeGreaterThanOrEqual(1);\n expect(states[0].widthMode).toBe('centered');\n\n service.setWidthMode('MJTestEntity', 'full-width');\n expect(states[states.length - 1].widthMode).toBe('full-width');\n\n sub.unsubscribe();\n });\n });\n});\n"]}
|