@memberjunction/ng-conversations 4.2.0 → 4.3.1

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=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ describe('@memberjunction/ng-conversations', () => {
3
+ it('should have a passing test', () => {
4
+ expect(true).toBe(true);
5
+ });
6
+ });
7
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/__tests__/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE9C,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;IAChD,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mention-parser.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mention-parser.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/mention-parser.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,154 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ // Mock Angular and MJ deps
3
+ vi.mock('@angular/core', () => ({ Injectable: () => () => { } }));
4
+ vi.mock('@memberjunction/ai-core-plus', () => ({
5
+ AIAgentEntityExtended: class {
6
+ },
7
+ ConversationUtility: {
8
+ ToPlainText: vi.fn((text) => text.replace(/@\{[^}]+\}/g, '@MockName'))
9
+ }
10
+ }));
11
+ vi.mock('@memberjunction/core', () => ({
12
+ UserInfo: class {
13
+ ID = '';
14
+ Name = '';
15
+ Email = '';
16
+ }
17
+ }));
18
+ import { MentionParserService } from '../lib/services/mention-parser.service';
19
+ // Create mock agents matching AIAgentEntityExtended shape
20
+ function createMockAgent(id, name) {
21
+ return { ID: id, Name: name };
22
+ }
23
+ function createMockUser(id, name, email) {
24
+ return { ID: id, Name: name, Email: email };
25
+ }
26
+ describe('MentionParserService', () => {
27
+ let service;
28
+ beforeEach(() => {
29
+ service = new MentionParserService();
30
+ });
31
+ describe('parseMentions - JSON format', () => {
32
+ it('should parse JSON mention format', () => {
33
+ const text = '@{"type":"agent","id":"123","name":"Sage"} help me';
34
+ const agents = [createMockAgent('123', 'Sage')];
35
+ const result = service.parseMentions(text, agents);
36
+ expect(result.mentions).toHaveLength(1);
37
+ expect(result.mentions[0].type).toBe('agent');
38
+ expect(result.mentions[0].id).toBe('123');
39
+ expect(result.mentions[0].name).toBe('Sage');
40
+ expect(result.agentMention).not.toBeNull();
41
+ });
42
+ it('should parse JSON mention with config', () => {
43
+ const text = '@{"type":"agent","id":"123","name":"Sage","configId":"cfg-1"} hello';
44
+ const agents = [createMockAgent('123', 'Sage')];
45
+ const result = service.parseMentions(text, agents);
46
+ expect(result.mentions[0].configurationId).toBe('cfg-1');
47
+ });
48
+ it('should handle invalid JSON gracefully', () => {
49
+ const text = '@{invalid json} hello';
50
+ const agents = [];
51
+ const result = service.parseMentions(text, agents);
52
+ expect(result.mentions).toHaveLength(0);
53
+ });
54
+ it('should skip mentions missing required fields', () => {
55
+ const text = '@{"type":"agent"} hello';
56
+ const agents = [];
57
+ const result = service.parseMentions(text, agents);
58
+ expect(result.mentions).toHaveLength(0);
59
+ });
60
+ });
61
+ describe('parseMentions - legacy format', () => {
62
+ it('should match agent by exact name', () => {
63
+ const text = '@Sage help me';
64
+ const agents = [createMockAgent('a1', 'Sage')];
65
+ const result = service.parseMentions(text, agents);
66
+ expect(result.mentions).toHaveLength(1);
67
+ expect(result.agentMention).not.toBeNull();
68
+ expect(result.agentMention.name).toBe('Sage');
69
+ });
70
+ it('should match quoted names with spaces', () => {
71
+ const text = '@"Data Agent" help me';
72
+ const agents = [createMockAgent('a2', 'Data Agent')];
73
+ const result = service.parseMentions(text, agents);
74
+ expect(result.mentions).toHaveLength(1);
75
+ expect(result.agentMention.name).toBe('Data Agent');
76
+ });
77
+ it('should match agent by starts-with', () => {
78
+ const text = '@Sag help me';
79
+ const agents = [createMockAgent('a1', 'Sage')];
80
+ const result = service.parseMentions(text, agents);
81
+ expect(result.mentions).toHaveLength(1);
82
+ });
83
+ it('should match users if no agent matches', () => {
84
+ const text = '@John hello';
85
+ const agents = [];
86
+ const users = [createMockUser('u1', 'John Doe', 'john@test.com')];
87
+ const result = service.parseMentions(text, agents, users);
88
+ expect(result.mentions).toHaveLength(1);
89
+ expect(result.mentions[0].type).toBe('user');
90
+ expect(result.userMentions).toHaveLength(1);
91
+ });
92
+ it('should separate agent and user mentions', () => {
93
+ const result = service.parseMentions('hello', []);
94
+ expect(result.agentMention).toBeNull();
95
+ expect(result.userMentions).toHaveLength(0);
96
+ });
97
+ });
98
+ describe('extractMentionNames', () => {
99
+ it('should extract names from JSON mentions', () => {
100
+ const text = '@{"type":"agent","id":"1","name":"Sage"} and @{"type":"user","id":"2","name":"John"}';
101
+ const names = service.extractMentionNames(text);
102
+ expect(names).toContain('Sage');
103
+ expect(names).toContain('John');
104
+ });
105
+ it('should extract names from legacy mentions', () => {
106
+ const text = '@Sage and @"John Doe" hello';
107
+ const names = service.extractMentionNames(text);
108
+ expect(names).toContain('Sage');
109
+ expect(names).toContain('John Doe');
110
+ });
111
+ it('should return empty for no mentions', () => {
112
+ const names = service.extractMentionNames('no mentions here');
113
+ expect(names).toHaveLength(0);
114
+ });
115
+ });
116
+ describe('validateMentions', () => {
117
+ it('should return invalid JSON mentions', () => {
118
+ const text = '@{"type":"agent","id":"1","name":"Unknown"}';
119
+ const agents = [];
120
+ const invalid = service.validateMentions(text, agents);
121
+ expect(invalid).toContain('Unknown');
122
+ });
123
+ it('should return empty for valid mentions', () => {
124
+ const text = '@{"type":"agent","id":"1","name":"Sage"}';
125
+ const agents = [createMockAgent('1', 'Sage')];
126
+ const invalid = service.validateMentions(text, agents);
127
+ expect(invalid).toHaveLength(0);
128
+ });
129
+ it('should validate legacy mentions against agents', () => {
130
+ const text = '@Unknown hello';
131
+ const agents = [];
132
+ const invalid = service.validateMentions(text, agents);
133
+ expect(invalid).toContain('Unknown');
134
+ });
135
+ });
136
+ describe('formatMentions', () => {
137
+ it('should format mentions with proper names', () => {
138
+ const text = '@"sage" hello';
139
+ const mentions = [{ type: 'agent', id: '1', name: 'Sage' }];
140
+ const formatted = service.formatMentions(text, mentions);
141
+ expect(formatted).toContain('@Sage');
142
+ });
143
+ });
144
+ describe('toPlainText', () => {
145
+ it('should return empty string for empty input', () => {
146
+ expect(service.toPlainText('')).toBe('');
147
+ });
148
+ it('should delegate to ConversationUtility.ToPlainText', () => {
149
+ const result = service.toPlainText('@{"type":"agent","id":"1","name":"Sage"} hello');
150
+ expect(result).toBeDefined();
151
+ });
152
+ });
153
+ });
154
+ //# sourceMappingURL=mention-parser.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mention-parser.test.js","sourceRoot":"","sources":["../../src/__tests__/mention-parser.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAE9D,2BAA2B;AAC3B,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACjE,EAAE,CAAC,IAAI,CAAC,8BAA8B,EAAE,GAAG,EAAE,CAAC,CAAC;IAC7C,qBAAqB,EAAE;KAAQ;IAC/B,mBAAmB,EAAE;QACnB,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;KAC/E;CACF,CAAC,CAAC,CAAC;AACJ,EAAE,CAAC,IAAI,CAAC,sBAAsB,EAAE,GAAG,EAAE,CAAC,CAAC;IACrC,QAAQ,EAAE;QAAQ,EAAE,GAAG,EAAE,CAAC;QAAC,IAAI,GAAG,EAAE,CAAC;QAAC,KAAK,GAAG,EAAE,CAAC;KAAE;CACpD,CAAC,CAAC,CAAC;AAEJ,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAE9E,0DAA0D;AAC1D,SAAS,eAAe,CAAC,EAAU,EAAE,IAAY;IAC/C,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAChC,CAAC;AAED,SAAS,cAAc,CAAC,EAAU,EAAE,IAAY,EAAE,KAAc;IAC9D,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC9C,CAAC;AAED,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,IAAI,OAA6B,CAAC;IAElC,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,GAAG,IAAI,oBAAoB,EAAE,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;QAC3C,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,IAAI,GAAG,oDAAoD,CAAC;YAClE,MAAM,MAAM,GAAG,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAY,CAAC;YAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAEnD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC9C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,IAAI,GAAG,qEAAqE,CAAC;YACnF,MAAM,MAAM,GAAG,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAY,CAAC;YAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAEnD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,IAAI,GAAG,uBAAuB,CAAC;YACrC,MAAM,MAAM,GAAY,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACnD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,MAAM,IAAI,GAAG,yBAAyB,CAAC;YACvC,MAAM,MAAM,GAAY,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACnD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;QAC7C,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,IAAI,GAAG,eAAe,CAAC;YAC7B,MAAM,MAAM,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAY,CAAC;YAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAEnD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC3C,MAAM,CAAC,MAAM,CAAC,YAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,IAAI,GAAG,uBAAuB,CAAC;YACrC,MAAM,MAAM,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,YAAY,CAAC,CAAY,CAAC;YAChE,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAEnD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,YAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,IAAI,GAAG,cAAc,CAAC;YAC5B,MAAM,MAAM,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAY,CAAC;YAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAEnD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,IAAI,GAAG,aAAa,CAAC;YAC3B,MAAM,MAAM,GAAY,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,eAAe,CAAC,CAAY,CAAC;YAC7E,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;YAE1D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,EAAa,CAAC,CAAC;YAC7D,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;YACvC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;QACnC,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,IAAI,GAAG,sFAAsF,CAAC;YACpG,MAAM,KAAK,GAAG,OAAO,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAChD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAChC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,MAAM,IAAI,GAAG,6BAA6B,CAAC;YAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAChD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAChC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;YAC9D,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,IAAI,GAAG,6CAA6C,CAAC;YAC3D,MAAM,MAAM,GAAY,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACvD,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,IAAI,GAAG,0CAA0C,CAAC;YACxD,MAAM,MAAM,GAAG,CAAC,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAY,CAAC;YACzD,MAAM,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACvD,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,IAAI,GAAG,gBAAgB,CAAC;YAC9B,MAAM,MAAM,GAAY,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACvD,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,IAAI,GAAG,eAAe,CAAC;YAC7B,MAAM,QAAQ,GAAG,CAAC,EAAE,IAAI,EAAE,OAAgB,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YACrE,MAAM,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACzD,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;QAC3B,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,gDAAgD,CAAC,CAAC;YACrF,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=notification-model.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-model.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/notification-model.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,68 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { DEFAULT_NOTIFICATION_PREFERENCES } from '../lib/models/notification.model';
3
+ describe('DEFAULT_NOTIFICATION_PREFERENCES', () => {
4
+ it('should have sound disabled by default', () => {
5
+ expect(DEFAULT_NOTIFICATION_PREFERENCES.enableSound).toBe(false);
6
+ });
7
+ it('should have desktop notifications disabled by default', () => {
8
+ expect(DEFAULT_NOTIFICATION_PREFERENCES.enableDesktopNotifications).toBe(false);
9
+ });
10
+ it('should have in-app notifications enabled by default', () => {
11
+ expect(DEFAULT_NOTIFICATION_PREFERENCES.enableInAppNotifications).toBe(true);
12
+ });
13
+ it('should have badges enabled by default', () => {
14
+ expect(DEFAULT_NOTIFICATION_PREFERENCES.showBadges).toBe(true);
15
+ });
16
+ it('should have empty muted conversations list', () => {
17
+ expect(DEFAULT_NOTIFICATION_PREFERENCES.mutedConversations).toEqual([]);
18
+ });
19
+ });
20
+ describe('Notification types', () => {
21
+ it('should support all notification types', () => {
22
+ const types = ['message', 'artifact', 'agent_process', 'task'];
23
+ expect(types).toHaveLength(4);
24
+ });
25
+ it('should support all priority levels', () => {
26
+ const priorities = ['low', 'normal', 'high', 'urgent'];
27
+ expect(priorities).toHaveLength(4);
28
+ });
29
+ });
30
+ describe('ConversationNotification shape', () => {
31
+ it('should be constructable with required fields', () => {
32
+ const notification = {
33
+ conversationId: 'conv-1',
34
+ unreadMessageCount: 5,
35
+ lastReadMessageTimestamp: null,
36
+ lastMessageTimestamp: new Date(),
37
+ hasNewArtifacts: true,
38
+ hasActiveAgentProcesses: false,
39
+ newArtifactCount: 2,
40
+ activeAgentProcessCount: 0,
41
+ lastNotificationTimestamp: new Date(),
42
+ highestPriority: 'high'
43
+ };
44
+ expect(notification.conversationId).toBe('conv-1');
45
+ expect(notification.unreadMessageCount).toBe(5);
46
+ expect(notification.hasNewArtifacts).toBe(true);
47
+ });
48
+ });
49
+ describe('BadgeConfig shape', () => {
50
+ it('should represent hidden badge', () => {
51
+ const badge = { show: false };
52
+ expect(badge.show).toBe(false);
53
+ expect(badge.count).toBeUndefined();
54
+ });
55
+ it('should represent visible badge with count', () => {
56
+ const badge = {
57
+ show: true,
58
+ count: 3,
59
+ type: 'count',
60
+ priority: 'normal',
61
+ animate: false
62
+ };
63
+ expect(badge.show).toBe(true);
64
+ expect(badge.count).toBe(3);
65
+ expect(badge.type).toBe('count');
66
+ });
67
+ });
68
+ //# sourceMappingURL=notification-model.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-model.test.js","sourceRoot":"","sources":["../../src/__tests__/notification-model.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=search-service.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-service.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/search-service.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,114 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { BehaviorSubject } from 'rxjs';
3
+ /**
4
+ * Pure logic extraction from SearchService for testing
5
+ */
6
+ class TestableSearchLogic {
7
+ state = new BehaviorSubject({
8
+ query: '',
9
+ results: [],
10
+ isSearching: false,
11
+ totalResults: 0
12
+ });
13
+ get currentState() {
14
+ return this.state.value;
15
+ }
16
+ setQuery(query) {
17
+ this.state.next({ ...this.state.value, query });
18
+ }
19
+ setSearching(isSearching) {
20
+ this.state.next({ ...this.state.value, isSearching });
21
+ }
22
+ setResults(results) {
23
+ this.state.next({
24
+ ...this.state.value,
25
+ results,
26
+ totalResults: results.length,
27
+ isSearching: false
28
+ });
29
+ }
30
+ clearResults() {
31
+ this.state.next({
32
+ ...this.state.value,
33
+ query: '',
34
+ results: [],
35
+ totalResults: 0,
36
+ isSearching: false
37
+ });
38
+ }
39
+ highlightMatch(text, query) {
40
+ if (!query || !text)
41
+ return text;
42
+ const regex = new RegExp(`(${query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi');
43
+ return text.replace(regex, '<mark>$1</mark>');
44
+ }
45
+ }
46
+ describe('SearchService logic', () => {
47
+ let service;
48
+ beforeEach(() => {
49
+ service = new TestableSearchLogic();
50
+ });
51
+ describe('initial state', () => {
52
+ it('should start with empty query', () => {
53
+ expect(service.currentState.query).toBe('');
54
+ });
55
+ it('should start with empty results', () => {
56
+ expect(service.currentState.results).toHaveLength(0);
57
+ });
58
+ it('should not be searching', () => {
59
+ expect(service.currentState.isSearching).toBe(false);
60
+ });
61
+ });
62
+ describe('setQuery', () => {
63
+ it('should update the query', () => {
64
+ service.setQuery('hello');
65
+ expect(service.currentState.query).toBe('hello');
66
+ });
67
+ });
68
+ describe('setSearching', () => {
69
+ it('should update searching state', () => {
70
+ service.setSearching(true);
71
+ expect(service.currentState.isSearching).toBe(true);
72
+ });
73
+ });
74
+ describe('setResults', () => {
75
+ it('should set results and count', () => {
76
+ const results = [
77
+ { conversationId: 'c1', conversationName: 'Conv 1', matchingMessages: [], score: 0.9 },
78
+ { conversationId: 'c2', conversationName: 'Conv 2', matchingMessages: [], score: 0.5 }
79
+ ];
80
+ service.setResults(results);
81
+ expect(service.currentState.results).toHaveLength(2);
82
+ expect(service.currentState.totalResults).toBe(2);
83
+ expect(service.currentState.isSearching).toBe(false);
84
+ });
85
+ });
86
+ describe('clearResults', () => {
87
+ it('should reset to empty state', () => {
88
+ service.setQuery('test');
89
+ service.setResults([{ conversationId: 'c1', conversationName: 'C', matchingMessages: [], score: 1 }]);
90
+ service.clearResults();
91
+ expect(service.currentState.query).toBe('');
92
+ expect(service.currentState.results).toHaveLength(0);
93
+ expect(service.currentState.totalResults).toBe(0);
94
+ });
95
+ });
96
+ describe('highlightMatch', () => {
97
+ it('should wrap matched text in mark tags', () => {
98
+ expect(service.highlightMatch('Hello World', 'World')).toBe('Hello <mark>World</mark>');
99
+ });
100
+ it('should be case insensitive', () => {
101
+ expect(service.highlightMatch('Hello World', 'hello')).toBe('<mark>Hello</mark> World');
102
+ });
103
+ it('should handle regex special chars in query', () => {
104
+ expect(service.highlightMatch('Price: $10.00', '$10')).toBe('Price: <mark>$10</mark>.00');
105
+ });
106
+ it('should return text unchanged for empty query', () => {
107
+ expect(service.highlightMatch('Hello', '')).toBe('Hello');
108
+ });
109
+ it('should return text unchanged for empty text', () => {
110
+ expect(service.highlightMatch('', 'test')).toBe('');
111
+ });
112
+ });
113
+ });
114
+ //# sourceMappingURL=search-service.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-service.test.js","sourceRoot":"","sources":["../../src/__tests__/search-service.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=toast-service.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toast-service.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/toast-service.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,143 @@
1
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
2
+ // We test ToastService logic directly without Angular DI
3
+ // The service uses BehaviorSubject which is pure RxJS
4
+ import { BehaviorSubject } from 'rxjs';
5
+ /**
6
+ * Reimplemented ToastService logic for testing without Angular @Injectable
7
+ */
8
+ class TestableToastService {
9
+ toastsSubject = new BehaviorSubject([]);
10
+ toasts$ = this.toastsSubject.asObservable();
11
+ idCounter = 0;
12
+ show(message, type = 'info', duration = 3000) {
13
+ const toast = {
14
+ id: `toast-${++this.idCounter}-${Date.now()}`,
15
+ message,
16
+ type,
17
+ duration,
18
+ timestamp: Date.now()
19
+ };
20
+ const currentToasts = this.toastsSubject.value;
21
+ this.toastsSubject.next([...currentToasts, toast]);
22
+ if (duration > 0) {
23
+ setTimeout(() => { this.dismiss(toast.id); }, duration);
24
+ }
25
+ return toast.id;
26
+ }
27
+ success(message, duration = 3000) {
28
+ return this.show(message, 'success', duration);
29
+ }
30
+ error(message, duration = 5000) {
31
+ return this.show(message, 'error', duration);
32
+ }
33
+ warning(message, duration = 4000) {
34
+ return this.show(message, 'warning', duration);
35
+ }
36
+ info(message, duration = 3000) {
37
+ return this.show(message, 'info', duration);
38
+ }
39
+ dismiss(id) {
40
+ const currentToasts = this.toastsSubject.value;
41
+ const filteredToasts = currentToasts.filter(t => t.id !== id);
42
+ this.toastsSubject.next(filteredToasts);
43
+ }
44
+ clear() {
45
+ this.toastsSubject.next([]);
46
+ }
47
+ get currentToasts() {
48
+ return this.toastsSubject.value;
49
+ }
50
+ }
51
+ describe('ToastService', () => {
52
+ let service;
53
+ beforeEach(() => {
54
+ vi.useFakeTimers();
55
+ service = new TestableToastService();
56
+ });
57
+ describe('show', () => {
58
+ it('should add a toast to the list', () => {
59
+ service.show('Hello');
60
+ expect(service.currentToasts).toHaveLength(1);
61
+ expect(service.currentToasts[0].message).toBe('Hello');
62
+ });
63
+ it('should default to info type', () => {
64
+ service.show('Test');
65
+ expect(service.currentToasts[0].type).toBe('info');
66
+ });
67
+ it('should return a toast ID', () => {
68
+ const id = service.show('Test');
69
+ expect(id).toBeDefined();
70
+ expect(id).toContain('toast-');
71
+ });
72
+ it('should auto-dismiss after duration', () => {
73
+ service.show('Temporary', 'info', 3000);
74
+ expect(service.currentToasts).toHaveLength(1);
75
+ vi.advanceTimersByTime(3001);
76
+ expect(service.currentToasts).toHaveLength(0);
77
+ });
78
+ it('should not auto-dismiss when duration is 0', () => {
79
+ service.show('Persistent', 'info', 0);
80
+ vi.advanceTimersByTime(10000);
81
+ expect(service.currentToasts).toHaveLength(1);
82
+ });
83
+ it('should support multiple toasts', () => {
84
+ service.show('First');
85
+ service.show('Second');
86
+ service.show('Third');
87
+ expect(service.currentToasts).toHaveLength(3);
88
+ });
89
+ });
90
+ describe('convenience methods', () => {
91
+ it('success should use success type', () => {
92
+ service.success('Done!');
93
+ expect(service.currentToasts[0].type).toBe('success');
94
+ });
95
+ it('error should use error type with 5s default duration', () => {
96
+ service.error('Oops');
97
+ expect(service.currentToasts[0].type).toBe('error');
98
+ expect(service.currentToasts[0].duration).toBe(5000);
99
+ });
100
+ it('warning should use warning type with 4s default duration', () => {
101
+ service.warning('Careful');
102
+ expect(service.currentToasts[0].type).toBe('warning');
103
+ expect(service.currentToasts[0].duration).toBe(4000);
104
+ });
105
+ it('info should use info type', () => {
106
+ service.info('FYI');
107
+ expect(service.currentToasts[0].type).toBe('info');
108
+ });
109
+ });
110
+ describe('dismiss', () => {
111
+ it('should remove specific toast by ID', () => {
112
+ const id1 = service.show('First');
113
+ service.show('Second');
114
+ service.dismiss(id1);
115
+ expect(service.currentToasts).toHaveLength(1);
116
+ expect(service.currentToasts[0].message).toBe('Second');
117
+ });
118
+ it('should do nothing for unknown ID', () => {
119
+ service.show('Test');
120
+ service.dismiss('unknown-id');
121
+ expect(service.currentToasts).toHaveLength(1);
122
+ });
123
+ });
124
+ describe('clear', () => {
125
+ it('should remove all toasts', () => {
126
+ service.show('First');
127
+ service.show('Second');
128
+ service.show('Third');
129
+ service.clear();
130
+ expect(service.currentToasts).toHaveLength(0);
131
+ });
132
+ });
133
+ describe('toasts$ observable', () => {
134
+ it('should emit toast updates', () => {
135
+ const emissions = [];
136
+ service.toasts$.subscribe(toasts => emissions.push(toasts));
137
+ service.show('Test');
138
+ expect(emissions).toHaveLength(2); // initial [] + one add
139
+ expect(emissions[1]).toHaveLength(1);
140
+ });
141
+ });
142
+ });
143
+ //# sourceMappingURL=toast-service.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toast-service.test.js","sourceRoot":"","sources":["../../src/__tests__/toast-service.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-conversations",
3
- "version": "4.2.0",
3
+ "version": "4.3.1",
4
4
  "description": "MemberJunction: Conversation, Collection, and Artifact management components for any Angular application",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -8,8 +8,9 @@
8
8
  "/dist"
9
9
  ],
10
10
  "scripts": {
11
- "test": "echo \"Error: no test specified\" && exit 1",
12
- "build": "ngc"
11
+ "test": "echo \"No tests configured yet\"",
12
+ "build": "ngc",
13
+ "test:watch": "vitest"
13
14
  },
14
15
  "keywords": [],
15
16
  "author": "",
@@ -17,7 +18,8 @@
17
18
  "devDependencies": {
18
19
  "@angular/compiler": "21.1.3",
19
20
  "@angular/compiler-cli": "21.1.3",
20
- "sass": "^1.97.3"
21
+ "sass": "^1.97.3",
22
+ "vitest": "^4.0.18"
21
23
  },
22
24
  "peerDependencies": {
23
25
  "@angular/common": "21.1.3",
@@ -29,21 +31,21 @@
29
31
  "dependencies": {
30
32
  "@angular/animations": "21.1.3",
31
33
  "@angular/cdk": "21.1.3",
32
- "@memberjunction/ai": "4.2.0",
33
- "@memberjunction/ai-core-plus": "4.2.0",
34
- "@memberjunction/ai-engine-base": "4.2.0",
35
- "@memberjunction/core": "4.2.0",
36
- "@memberjunction/core-entities": "4.2.0",
37
- "@memberjunction/global": "4.2.0",
38
- "@memberjunction/graphql-dataprovider": "4.2.0",
39
- "@memberjunction/ng-artifacts": "4.2.0",
40
- "@memberjunction/ng-base-types": "4.2.0",
41
- "@memberjunction/ng-code-editor": "4.2.0",
42
- "@memberjunction/ng-container-directives": "4.2.0",
43
- "@memberjunction/ng-notifications": "4.2.0",
44
- "@memberjunction/ng-shared-generic": "4.2.0",
45
- "@memberjunction/ng-tasks": "4.2.0",
46
- "@memberjunction/ng-testing": "4.2.0",
34
+ "@memberjunction/ai": "4.3.1",
35
+ "@memberjunction/ai-core-plus": "4.3.1",
36
+ "@memberjunction/ai-engine-base": "4.3.1",
37
+ "@memberjunction/core": "4.3.1",
38
+ "@memberjunction/core-entities": "4.3.1",
39
+ "@memberjunction/global": "4.3.1",
40
+ "@memberjunction/graphql-dataprovider": "4.3.1",
41
+ "@memberjunction/ng-artifacts": "4.3.1",
42
+ "@memberjunction/ng-base-types": "4.3.1",
43
+ "@memberjunction/ng-code-editor": "4.3.1",
44
+ "@memberjunction/ng-container-directives": "4.3.1",
45
+ "@memberjunction/ng-notifications": "4.3.1",
46
+ "@memberjunction/ng-shared-generic": "4.3.1",
47
+ "@memberjunction/ng-tasks": "4.3.1",
48
+ "@memberjunction/ng-testing": "4.3.1",
47
49
  "@progress/kendo-angular-buttons": "22.0.1",
48
50
  "@progress/kendo-angular-dateinputs": "22.0.1",
49
51
  "@progress/kendo-angular-dialog": "22.0.1",
@@ -53,7 +55,7 @@
53
55
  "@progress/kendo-angular-layout": "22.0.1",
54
56
  "@progress/kendo-angular-notification": "22.0.1",
55
57
  "@progress/kendo-angular-upload": "22.0.1",
56
- "@memberjunction/ng-markdown": "4.2.0",
58
+ "@memberjunction/ng-markdown": "4.3.1",
57
59
  "rxjs": "^7.8.2",
58
60
  "tslib": "^2.8.1"
59
61
  },