@memberjunction/ng-feedback 5.42.0 → 5.44.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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=feedback-button.component.dom.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-button.component.dom.test.d.ts","sourceRoot":"","sources":["../../../src/lib/components/feedback-button.component.dom.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,66 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { TestBed } from '@angular/core/testing';
3
+ import { CommonModule } from '@angular/common';
4
+ import { query, text, hasClass, attr, click } from '@memberjunction/ng-test-utils';
5
+ import { FeedbackButtonComponent } from './feedback-button.component';
6
+ import { FeedbackDialogService } from '../services/feedback-dialog.service';
7
+ /**
8
+ * DOM-level spec for <mj-feedback-button> (module-declared / standalone:false).
9
+ *
10
+ * The button's only collaborator is FeedbackDialogService, which it calls on click.
11
+ * We substitute a fake service so the template surface — label gating, position class,
12
+ * tooltip binding, and the click → OpenFeedbackDialog wiring (including the
13
+ * CurrentPageProvider plumbing) — can be asserted without the real dialog lifecycle.
14
+ */
15
+ describe('FeedbackButtonComponent (DOM)', () => {
16
+ let openSpy;
17
+ function render(inputs = {}) {
18
+ const fixture = TestBed.createComponent(FeedbackButtonComponent);
19
+ for (const [name, value] of Object.entries(inputs)) {
20
+ fixture.componentRef.setInput(name, value);
21
+ }
22
+ fixture.detectChanges();
23
+ return fixture;
24
+ }
25
+ beforeEach(() => {
26
+ openSpy = vi.fn();
27
+ TestBed.configureTestingModule({
28
+ imports: [CommonModule],
29
+ declarations: [FeedbackButtonComponent],
30
+ providers: [{ provide: FeedbackDialogService, useValue: { OpenFeedbackDialog: openSpy } }],
31
+ });
32
+ });
33
+ it('renders the floating button with the default bottom-right position class', () => {
34
+ const fixture = render();
35
+ const btn = query(fixture, 'button.feedback-floating-button');
36
+ expect(btn).not.toBeNull();
37
+ expect(hasClass(fixture, 'button.feedback-floating-button', 'position-bottom-right')).toBe(true);
38
+ });
39
+ it('applies the position class for the configured Position input', () => {
40
+ const fixture = render({ Position: 'top-left' });
41
+ expect(hasClass(fixture, 'button.feedback-floating-button', 'position-top-left')).toBe(true);
42
+ expect(hasClass(fixture, 'button.feedback-floating-button', 'position-bottom-right')).toBe(false);
43
+ });
44
+ it('hides the text label by default and shows it when ShowLabel is true', () => {
45
+ const without = render();
46
+ expect(query(without, '.button-label')).toBeNull();
47
+ const withLabel = render({ ShowLabel: true, ButtonText: 'Report Issue' });
48
+ expect(text(withLabel, '.button-label')).toBe('Report Issue');
49
+ });
50
+ it('binds ButtonText to the title (tooltip) attribute', () => {
51
+ const fixture = render({ ButtonText: 'Send us feedback' });
52
+ expect(attr(fixture, 'button.feedback-floating-button', 'title')).toBe('Send us feedback');
53
+ });
54
+ it('opens the dialog on click with no current page when no provider is supplied', () => {
55
+ const fixture = render();
56
+ click(fixture, 'button.feedback-floating-button');
57
+ expect(openSpy).toHaveBeenCalledTimes(1);
58
+ expect(openSpy).toHaveBeenCalledWith({ currentPage: undefined });
59
+ });
60
+ it('passes the CurrentPageProvider result through to the dialog options on click', () => {
61
+ const fixture = render({ CurrentPageProvider: () => 'Dashboard Tab' });
62
+ click(fixture, 'button.feedback-floating-button');
63
+ expect(openSpy).toHaveBeenCalledWith({ currentPage: 'Dashboard Tab' });
64
+ });
65
+ });
66
+ //# sourceMappingURL=feedback-button.component.dom.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-button.component.dom.test.js","sourceRoot":"","sources":["../../../src/lib/components/feedback-button.component.dom.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=feedback-form.component.dom.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-form.component.dom.test.d.ts","sourceRoot":"","sources":["../../../src/lib/components/feedback-form.component.dom.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,157 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { of } from 'rxjs';
3
+ import { TestBed } from '@angular/core/testing';
4
+ import { query, queryAll, text, click, typeInto, capture } from '@memberjunction/ng-test-utils';
5
+ import { FeedbackFormComponent } from './feedback-form.component';
6
+ import { FEEDBACK_CONFIG } from '../feedback.config';
7
+ import { FeedbackService } from '../services/feedback.service';
8
+ /**
9
+ * DOM-level spec for <mj-feedback-form>.
10
+ *
11
+ * mj-dialog projects its content inline (native <dialog> markup rendered directly into
12
+ * the component's own DOM when Visible) — no CDK overlay/portal — so the whole form
13
+ * surface lands in fixture.nativeElement and is assertable here.
14
+ *
15
+ * FeedbackService is faked at the seam: Classify is stubbed out (the debounced LLM call
16
+ * is timer-driven and not exercised here) and Submit returns a configurable Observable so
17
+ * we can drive the success / error branches. No GraphQL, no network.
18
+ */
19
+ describe('FeedbackFormComponent (DOM)', () => {
20
+ let submitResult;
21
+ const fakeService = {
22
+ Classify: async () => null,
23
+ Submit: () => of(submitResult),
24
+ };
25
+ function configure(config = {}) {
26
+ TestBed.configureTestingModule({
27
+ providers: [
28
+ { provide: FEEDBACK_CONFIG, useValue: { appName: 'Test App', ...config } },
29
+ { provide: FeedbackService, useValue: fakeService },
30
+ ],
31
+ });
32
+ }
33
+ /**
34
+ * Render in the zoneless-correct order: apply any internal-state mutations BEFORE the
35
+ * first detectChanges() so the single render sees final values (avoids NG0100 — these
36
+ * form fields are plain public properties, not @Inputs, so setInput isn't available).
37
+ */
38
+ function render(setup) {
39
+ const fixture = TestBed.createComponent(FeedbackFormComponent);
40
+ setup?.(fixture.componentInstance);
41
+ fixture.detectChanges();
42
+ return fixture;
43
+ }
44
+ function fillValidForm(instance) {
45
+ instance.Title = 'A valid title';
46
+ instance.Description = 'This description is definitely long enough to pass.';
47
+ instance.CertificationAccepted = true;
48
+ }
49
+ beforeEach(() => {
50
+ submitResult = { success: true, issueNumber: 42, issueUrl: 'https://example.com/issue/42' };
51
+ });
52
+ it('renders the dialog with the default title and the privacy notice', () => {
53
+ configure();
54
+ const fixture = render();
55
+ expect(query(fixture, '.mj-dialog-backdrop')).not.toBeNull();
56
+ expect(text(fixture, '.mj-dialog-title')).toBe('Submit Feedback');
57
+ expect(query(fixture, '.feedback-privacy-notice')).not.toBeNull();
58
+ });
59
+ it('uses the configured title and shows the subtitle when provided', () => {
60
+ configure({ title: 'Report an Issue', subtitle: 'Help us improve' });
61
+ const fixture = render();
62
+ expect(text(fixture, '.mj-dialog-title')).toBe('Report an Issue');
63
+ expect(text(fixture, '.feedback-subtitle')).toBe('Help us improve');
64
+ });
65
+ it('omits the subtitle element when no subtitle is configured', () => {
66
+ configure();
67
+ const fixture = render();
68
+ expect(query(fixture, '.feedback-subtitle')).toBeNull();
69
+ });
70
+ it('shows the title and description fields, defaulting to the bug category', () => {
71
+ configure();
72
+ const fixture = render();
73
+ // Default Category is 'bug' → bug-specific steps-to-reproduce section renders
74
+ const labels = queryAll(fixture, '.feedback-label').map((l) => l.textContent?.trim() ?? '');
75
+ expect(labels.some((l) => l.startsWith('Title'))).toBe(true);
76
+ expect(labels.some((l) => l.startsWith('Description'))).toBe(true);
77
+ expect(labels.some((l) => l.startsWith('Steps to Reproduce'))).toBe(true);
78
+ });
79
+ it('marks the title char-count as warning when below the 5-char minimum', () => {
80
+ configure();
81
+ const fixture = render();
82
+ typeInto(fixture, 'input.mj-input', 'abc');
83
+ fixture.detectChanges();
84
+ const titleSection = query(fixture, '.feedback-section');
85
+ const charCount = titleSection?.querySelector('.char-count');
86
+ expect(charCount?.classList.contains('warning')).toBe(true);
87
+ expect(charCount?.textContent).toContain('3/256');
88
+ });
89
+ it('swaps bug-specific fields for feature-specific fields when Category is feature', () => {
90
+ configure();
91
+ const fixture = render((i) => (i.Category = 'feature'));
92
+ const labels = queryAll(fixture, '.feedback-label').map((l) => l.textContent?.trim() ?? '');
93
+ expect(labels.some((l) => l.startsWith('Use Case'))).toBe(true);
94
+ expect(labels.some((l) => l.startsWith('Steps to Reproduce'))).toBe(false);
95
+ });
96
+ it('disables the submit button while the form is invalid (CanSubmit)', () => {
97
+ configure();
98
+ const fixture = render();
99
+ const submitBtn = query(fixture, 'mj-dialog-actions button[mjButton][variant="primary"]');
100
+ expect(submitBtn.disabled).toBe(true);
101
+ });
102
+ it('enables the submit button once all CanSubmit conditions are met', () => {
103
+ configure();
104
+ const fixture = render(fillValidForm);
105
+ const submitBtn = query(fixture, 'mj-dialog-actions button[mjButton][variant="primary"]');
106
+ expect(submitBtn.disabled).toBe(false);
107
+ });
108
+ it('renders the success state with the issue link after a successful submit', () => {
109
+ configure();
110
+ // Fill valid state BEFORE the first detectChanges (these are plain props bound via
111
+ // [(ngModel)], so mutating after the initial render triggers NG0100 in zoneless mode).
112
+ const fixture = render(fillValidForm);
113
+ click(fixture, 'mj-dialog-actions button[mjButton][variant="primary"]');
114
+ fixture.detectChanges();
115
+ expect(query(fixture, '.feedback-success')).not.toBeNull();
116
+ const link = query(fixture, '.feedback-success a');
117
+ expect(link).not.toBeNull();
118
+ expect(link?.getAttribute('href')).toBe('https://example.com/issue/42');
119
+ expect(text(fixture, '.feedback-success a')).toContain('42');
120
+ });
121
+ it('renders an error message when the submit response is unsuccessful', () => {
122
+ configure();
123
+ submitResult = { success: false, error: 'Server rejected the submission' };
124
+ const fixture = render(fillValidForm);
125
+ click(fixture, 'mj-dialog-actions button[mjButton][variant="primary"]');
126
+ fixture.detectChanges();
127
+ expect(query(fixture, '.feedback-success')).toBeNull();
128
+ expect(text(fixture, '.feedback-error')).toContain('Server rejected the submission');
129
+ });
130
+ it('emits Cancelled and DialogClosed when the Cancel button is clicked', () => {
131
+ configure();
132
+ const fixture = render();
133
+ const cancelled = capture(fixture.componentInstance.Cancelled);
134
+ const closed = capture(fixture.componentInstance.DialogClosed);
135
+ // Cancel is the second action button (after the primary Submit)
136
+ const buttons = queryAll(fixture, 'mj-dialog-actions button[mjButton]');
137
+ const cancelBtn = buttons.find((b) => b.textContent?.trim() === 'Cancel');
138
+ expect(cancelBtn).toBeDefined();
139
+ cancelBtn.click();
140
+ fixture.detectChanges();
141
+ expect(cancelled.length).toBe(1);
142
+ expect(closed).toEqual([{ success: false }]);
143
+ });
144
+ it('emits the built submission via Submitted on submit', () => {
145
+ configure();
146
+ // Fill valid state BEFORE the first detectChanges (these are plain props bound via
147
+ // [(ngModel)], so mutating after the initial render triggers NG0100 in zoneless mode).
148
+ const fixture = render(fillValidForm);
149
+ const submitted = capture(fixture.componentInstance.Submitted);
150
+ click(fixture, 'mj-dialog-actions button[mjButton][variant="primary"]');
151
+ fixture.detectChanges();
152
+ expect(submitted.length).toBe(1);
153
+ expect(submitted[0].title).toBe('A valid title');
154
+ expect(submitted[0].category).toBe('bug');
155
+ });
156
+ });
157
+ //# sourceMappingURL=feedback-form.component.dom.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-form.component.dom.test.js","sourceRoot":"","sources":["../../../src/lib/components/feedback-form.component.dom.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-feedback",
3
- "version": "5.42.0",
3
+ "version": "5.44.0",
4
4
  "description": "MemberJunction: Feedback and bug reporting components for Angular applications",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -8,7 +8,7 @@
8
8
  "/dist"
9
9
  ],
10
10
  "scripts": {
11
- "test": "echo \"No tests configured yet\"",
11
+ "test": "vitest run",
12
12
  "build": "ngc",
13
13
  "test:watch": "vitest"
14
14
  },
@@ -17,6 +17,7 @@
17
17
  "devDependencies": {
18
18
  "@angular/compiler": "21.1.3",
19
19
  "@angular/compiler-cli": "21.1.3",
20
+ "@memberjunction/ng-test-utils": "5.44.0",
20
21
  "vitest": "^4.0.18"
21
22
  },
22
23
  "peerDependencies": {
@@ -25,11 +26,11 @@
25
26
  "@angular/forms": "21.1.3"
26
27
  },
27
28
  "dependencies": {
28
- "@memberjunction/core": "5.42.0",
29
- "@memberjunction/ng-base-types": "5.42.0",
30
- "@memberjunction/graphql-dataprovider": "5.42.0",
31
- "@memberjunction/ng-shared-generic": "5.42.0",
32
- "@memberjunction/ng-ui-components": "5.42.0",
29
+ "@memberjunction/core": "5.44.0",
30
+ "@memberjunction/ng-base-types": "5.44.0",
31
+ "@memberjunction/graphql-dataprovider": "5.44.0",
32
+ "@memberjunction/ng-shared-generic": "5.44.0",
33
+ "@memberjunction/ng-ui-components": "5.44.0",
33
34
  "tslib": "^2.8.1",
34
35
  "rxjs": "~7.8.2"
35
36
  },