@smartsoft001/pro-claude-plugins 0.2.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.
Files changed (198) hide show
  1. package/.claude-plugin/marketplace.json +26 -0
  2. package/README.md +56 -0
  3. package/package.json +14 -0
  4. package/plugins/flow/.claude-plugin/README.md +91 -0
  5. package/plugins/flow/.claude-plugin/merge-permissions.js +115 -0
  6. package/plugins/flow/.claude-plugin/plugin.json +5 -0
  7. package/plugins/flow/.claude-plugin/settings.template.json +86 -0
  8. package/plugins/flow/agents/angular-component-scaffolder.md +176 -0
  9. package/plugins/flow/agents/angular-directive-builder.md +154 -0
  10. package/plugins/flow/agents/angular-guard-builder.md +244 -0
  11. package/plugins/flow/agents/angular-jest-test-writer.md +475 -0
  12. package/plugins/flow/agents/angular-pipe-builder.md +170 -0
  13. package/plugins/flow/agents/angular-resolver-builder.md +287 -0
  14. package/plugins/flow/agents/angular-service-builder.md +162 -0
  15. package/plugins/flow/agents/angular-signal-state-builder.md +340 -0
  16. package/plugins/flow/agents/angular-test-diagnostician.md +279 -0
  17. package/plugins/flow/agents/angular-testbed-configurator.md +315 -0
  18. package/plugins/flow/agents/arch-scaffolder.md +278 -0
  19. package/plugins/flow/agents/e2e-data-testid-injector.md +195 -0
  20. package/plugins/flow/agents/e2e-project-scaffolder.md +194 -0
  21. package/plugins/flow/agents/e2e-test-writer.md +357 -0
  22. package/plugins/flow/agents/shared-agent-evolver.md +294 -0
  23. package/plugins/flow/agents/shared-build-verifier.md +160 -0
  24. package/plugins/flow/agents/shared-config-updater.md +310 -0
  25. package/plugins/flow/agents/shared-coverage-enforcer.md +184 -0
  26. package/plugins/flow/agents/shared-error-handler.md +217 -0
  27. package/plugins/flow/agents/shared-file-creator.md +344 -0
  28. package/plugins/flow/agents/shared-impl-orchestrator.md +312 -0
  29. package/plugins/flow/agents/shared-impl-reporter.md +368 -0
  30. package/plugins/flow/agents/shared-impl-teammate.md +201 -0
  31. package/plugins/flow/agents/shared-linear-subtask-iterator.md +337 -0
  32. package/plugins/flow/agents/shared-logic-implementer.md +244 -0
  33. package/plugins/flow/agents/shared-maia-api.md +26 -0
  34. package/plugins/flow/agents/shared-parallelization-analyzer.md +343 -0
  35. package/plugins/flow/agents/shared-performance-validator.md +168 -0
  36. package/plugins/flow/agents/shared-plan-perspective.md +271 -0
  37. package/plugins/flow/agents/shared-project-standardizer.md +205 -0
  38. package/plugins/flow/agents/shared-report-synthesizer.md +188 -0
  39. package/plugins/flow/agents/shared-review-teammate.md +189 -0
  40. package/plugins/flow/agents/shared-security-scanner.md +186 -0
  41. package/plugins/flow/agents/shared-style-enforcer.md +230 -0
  42. package/plugins/flow/agents/shared-subtask-dependency-analyzer.md +189 -0
  43. package/plugins/flow/agents/shared-tdd-developer.md +350 -0
  44. package/plugins/flow/agents/shared-team-coordinator.md +192 -0
  45. package/plugins/flow/agents/shared-test-fixer.md +186 -0
  46. package/plugins/flow/agents/shared-test-runner.md +191 -0
  47. package/plugins/flow/agents/shared-ui-classifier.md +263 -0
  48. package/plugins/flow/agents/shared-verification-orchestrator.md +194 -0
  49. package/plugins/flow/agents/shared-verification-runner.md +140 -0
  50. package/plugins/flow/agents/ui-a11y-validator.md +305 -0
  51. package/plugins/flow/agents/ui-screenshot-reporter.md +329 -0
  52. package/plugins/flow/agents/ui-web-designer.md +214 -0
  53. package/plugins/flow/scripts/compute-session-tokens.sh +39 -0
  54. package/plugins/flow/skills/a11y-audit/SKILL.md +214 -0
  55. package/plugins/flow/skills/angular-patterns/SKILL.md +191 -0
  56. package/plugins/flow/skills/browser-capture/SKILL.md +238 -0
  57. package/plugins/flow/skills/commit/SKILL.md +259 -0
  58. package/plugins/flow/skills/debug-helper/SKILL.md +375 -0
  59. package/plugins/flow/skills/impl/SKILL.md +992 -0
  60. package/plugins/flow/skills/karpathy-guidelines/SKILL.md +72 -0
  61. package/plugins/flow/skills/linear-suggestion/SKILL.md +132 -0
  62. package/plugins/flow/skills/maia-files-delete/SKILL.md +59 -0
  63. package/plugins/flow/skills/maia-files-upload/SKILL.md +57 -0
  64. package/plugins/flow/skills/nx-conventions/SKILL.md +326 -0
  65. package/plugins/flow/skills/plan/SKILL.md +1033 -0
  66. package/plugins/flow/skills/push/SKILL.md +759 -0
  67. package/plugins/flow/skills/review/SKILL.md +443 -0
  68. package/plugins/flow/skills/test-e2e/SKILL.md +164 -0
  69. package/plugins/flow/skills/test-unit/SKILL.md +456 -0
  70. package/plugins/flow-external/.claude-plugin/README.md +146 -0
  71. package/plugins/flow-external/.claude-plugin/merge-permissions.js +94 -0
  72. package/plugins/flow-external/.claude-plugin/plugin.json +5 -0
  73. package/plugins/flow-external/.claude-plugin/settings.template.json +78 -0
  74. package/plugins/flow-external/agents/angular-component-scaffolder.md +271 -0
  75. package/plugins/flow-external/agents/angular-directive-builder.md +134 -0
  76. package/plugins/flow-external/agents/angular-guard-builder.md +73 -0
  77. package/plugins/flow-external/agents/angular-pipe-builder.md +90 -0
  78. package/plugins/flow-external/agents/angular-resolver-builder.md +79 -0
  79. package/plugins/flow-external/agents/angular-service-builder.md +168 -0
  80. package/plugins/flow-external/agents/angular-state-builder.md +263 -0
  81. package/plugins/flow-external/agents/shared-build-verifier.md +67 -0
  82. package/plugins/flow-external/agents/shared-impl-orchestrator.md +90 -0
  83. package/plugins/flow-external/agents/shared-impl-reporter.md +135 -0
  84. package/plugins/flow-external/agents/shared-linear-subtask-iterator.md +70 -0
  85. package/plugins/flow-external/agents/shared-ui-classifier.md +38 -0
  86. package/plugins/flow-external/agents/ui-web-designer.md +203 -0
  87. package/plugins/flow-external/scripts/compute-session-tokens.sh +39 -0
  88. package/plugins/flow-external/skills/a11y-audit/SKILL.md +97 -0
  89. package/plugins/flow-external/skills/angular-cli-conventions/SKILL.md +268 -0
  90. package/plugins/flow-external/skills/angular-patterns/SKILL.md +182 -0
  91. package/plugins/flow-external/skills/browser-capture/SKILL.md +74 -0
  92. package/plugins/flow-external/skills/commit/SKILL.md +114 -0
  93. package/plugins/flow-external/skills/debug-helper/SKILL.md +135 -0
  94. package/plugins/flow-external/skills/impl/SKILL.md +218 -0
  95. package/plugins/flow-external/skills/karpathy-guidelines/SKILL.md +72 -0
  96. package/plugins/flow-external/skills/linear-suggestion/SKILL.md +62 -0
  97. package/plugins/flow-external/skills/maia-files-delete/SKILL.md +34 -0
  98. package/plugins/flow-external/skills/maia-files-upload/SKILL.md +41 -0
  99. package/plugins/flow-external/skills/plan/SKILL.md +334 -0
  100. package/plugins/flow-external/skills/push/SKILL.md +232 -0
  101. package/plugins/flow-legacy/.claude-plugin/README.md +143 -0
  102. package/plugins/flow-legacy/.claude-plugin/merge-permissions.js +94 -0
  103. package/plugins/flow-legacy/.claude-plugin/plugin.json +5 -0
  104. package/plugins/flow-legacy/.claude-plugin/settings.template.json +79 -0
  105. package/plugins/flow-legacy/agents/angular-component-scaffolder.md +327 -0
  106. package/plugins/flow-legacy/agents/angular-directive-builder.md +253 -0
  107. package/plugins/flow-legacy/agents/angular-guard-builder.md +326 -0
  108. package/plugins/flow-legacy/agents/angular-pipe-builder.md +238 -0
  109. package/plugins/flow-legacy/agents/angular-resolver-builder.md +339 -0
  110. package/plugins/flow-legacy/agents/angular-service-builder.md +271 -0
  111. package/plugins/flow-legacy/agents/angular-state-builder.md +480 -0
  112. package/plugins/flow-legacy/agents/shared-impl-orchestrator.md +174 -0
  113. package/plugins/flow-legacy/agents/shared-impl-reporter.md +232 -0
  114. package/plugins/flow-legacy/agents/shared-linear-subtask-iterator.md +198 -0
  115. package/plugins/flow-legacy/agents/shared-tdd-developer.md +307 -0
  116. package/plugins/flow-legacy/agents/shared-test-runner.md +133 -0
  117. package/plugins/flow-legacy/agents/shared-ui-classifier.md +145 -0
  118. package/plugins/flow-legacy/scripts/compute-session-tokens.sh +39 -0
  119. package/plugins/flow-legacy/skills/a11y-audit/SKILL.md +214 -0
  120. package/plugins/flow-legacy/skills/angular-patterns/SKILL.md +346 -0
  121. package/plugins/flow-legacy/skills/browser-capture/SKILL.md +238 -0
  122. package/plugins/flow-legacy/skills/commit/SKILL.md +215 -0
  123. package/plugins/flow-legacy/skills/debug-helper/SKILL.md +395 -0
  124. package/plugins/flow-legacy/skills/impl/SKILL.md +710 -0
  125. package/plugins/flow-legacy/skills/karpathy-guidelines/SKILL.md +72 -0
  126. package/plugins/flow-legacy/skills/linear-suggestion/SKILL.md +132 -0
  127. package/plugins/flow-legacy/skills/maia-files-delete/SKILL.md +59 -0
  128. package/plugins/flow-legacy/skills/maia-files-upload/SKILL.md +57 -0
  129. package/plugins/flow-legacy/skills/nx-conventions/SKILL.md +368 -0
  130. package/plugins/flow-legacy/skills/plan/SKILL.md +742 -0
  131. package/plugins/flow-legacy/skills/push/SKILL.md +645 -0
  132. package/plugins/flow-legacy/skills/test-unit/SKILL.md +500 -0
  133. package/plugins/smart-pro/.claude-plugin/README.md +115 -0
  134. package/plugins/smart-pro/.claude-plugin/merge-permissions.js +129 -0
  135. package/plugins/smart-pro/.claude-plugin/plugin.json +5 -0
  136. package/plugins/smart-pro/.claude-plugin/settings.template.json +94 -0
  137. package/plugins/smart-pro/agents/angular-components/AGENT.md +214 -0
  138. package/plugins/smart-pro/hooks/CONFIG.md +198 -0
  139. package/plugins/smart-pro/hooks/README.md +139 -0
  140. package/plugins/smart-pro/hooks/audit_logger.py +107 -0
  141. package/plugins/smart-pro/hooks/auto_format.sh +11 -0
  142. package/plugins/smart-pro/hooks/hooks.json +79 -0
  143. package/plugins/smart-pro/hooks/safety_validator.py +129 -0
  144. package/plugins/smart-pro/hooks/sensitive_file_blocker.py +58 -0
  145. package/plugins/smart-pro/hooks/skill_validator.py +220 -0
  146. package/plugins/smart-pro/skills/angular-components-action-panel/SKILL.md +159 -0
  147. package/plugins/smart-pro/skills/angular-components-avatar/SKILL.md +142 -0
  148. package/plugins/smart-pro/skills/angular-components-badge/SKILL.md +110 -0
  149. package/plugins/smart-pro/skills/angular-components-breadcrumbs/SKILL.md +91 -0
  150. package/plugins/smart-pro/skills/angular-components-button/SKILL.md +146 -0
  151. package/plugins/smart-pro/skills/angular-components-button-group/SKILL.md +121 -0
  152. package/plugins/smart-pro/skills/angular-components-calendar/SKILL.md +78 -0
  153. package/plugins/smart-pro/skills/angular-components-card/SKILL.md +110 -0
  154. package/plugins/smart-pro/skills/angular-components-card-heading/SKILL.md +105 -0
  155. package/plugins/smart-pro/skills/angular-components-command-palette/SKILL.md +168 -0
  156. package/plugins/smart-pro/skills/angular-components-container/SKILL.md +93 -0
  157. package/plugins/smart-pro/skills/angular-components-description-list/SKILL.md +102 -0
  158. package/plugins/smart-pro/skills/angular-components-details/SKILL.md +70 -0
  159. package/plugins/smart-pro/skills/angular-components-divider/SKILL.md +110 -0
  160. package/plugins/smart-pro/skills/angular-components-drawer/SKILL.md +136 -0
  161. package/plugins/smart-pro/skills/angular-components-dropdown/SKILL.md +131 -0
  162. package/plugins/smart-pro/skills/angular-components-empty-state/SKILL.md +103 -0
  163. package/plugins/smart-pro/skills/angular-components-feed/SKILL.md +110 -0
  164. package/plugins/smart-pro/skills/angular-components-form/SKILL.md +77 -0
  165. package/plugins/smart-pro/skills/angular-components-grid-list/SKILL.md +91 -0
  166. package/plugins/smart-pro/skills/angular-components-input/SKILL.md +118 -0
  167. package/plugins/smart-pro/skills/angular-components-list/SKILL.md +75 -0
  168. package/plugins/smart-pro/skills/angular-components-list-container/SKILL.md +106 -0
  169. package/plugins/smart-pro/skills/angular-components-media-object/SKILL.md +133 -0
  170. package/plugins/smart-pro/skills/angular-components-modal/SKILL.md +159 -0
  171. package/plugins/smart-pro/skills/angular-components-multi-column-layout/SKILL.md +84 -0
  172. package/plugins/smart-pro/skills/angular-components-navbar/SKILL.md +93 -0
  173. package/plugins/smart-pro/skills/angular-components-notification/SKILL.md +147 -0
  174. package/plugins/smart-pro/skills/angular-components-page/SKILL.md +162 -0
  175. package/plugins/smart-pro/skills/angular-components-page-heading/SKILL.md +96 -0
  176. package/plugins/smart-pro/skills/angular-components-paging/SKILL.md +86 -0
  177. package/plugins/smart-pro/skills/angular-components-progress-bars/SKILL.md +94 -0
  178. package/plugins/smart-pro/skills/angular-components-searchbar/SKILL.md +113 -0
  179. package/plugins/smart-pro/skills/angular-components-section-heading/SKILL.md +156 -0
  180. package/plugins/smart-pro/skills/angular-components-select-menu/SKILL.md +101 -0
  181. package/plugins/smart-pro/skills/angular-components-sidebar-layout/SKILL.md +121 -0
  182. package/plugins/smart-pro/skills/angular-components-sidebar-navigation/SKILL.md +80 -0
  183. package/plugins/smart-pro/skills/angular-components-sign-in-form/SKILL.md +91 -0
  184. package/plugins/smart-pro/skills/angular-components-stacked-layout/SKILL.md +114 -0
  185. package/plugins/smart-pro/skills/angular-components-stacked-list/SKILL.md +93 -0
  186. package/plugins/smart-pro/skills/angular-components-stats/SKILL.md +87 -0
  187. package/plugins/smart-pro/skills/angular-components-table/SKILL.md +98 -0
  188. package/plugins/smart-pro/skills/angular-components-tabs/SKILL.md +99 -0
  189. package/plugins/smart-pro/skills/angular-components-textarea/SKILL.md +111 -0
  190. package/plugins/smart-pro/skills/angular-components-toggle/SKILL.md +109 -0
  191. package/plugins/smart-pro/skills/angular-components-vertical-navigation/SKILL.md +139 -0
  192. package/plugins/smart-pro/skills/audit-log/SKILL.md +82 -0
  193. package/plugins/smart-pro/skills/format-code/SKILL.md +46 -0
  194. package/plugins/smart-pro/skills/project-conventions/SKILL.md +90 -0
  195. package/plugins/smart-pro/skills/safety-check/SKILL.md +0 -0
  196. package/src/index.d.ts +6 -0
  197. package/src/index.js +7 -0
  198. package/src/index.js.map +1 -0
@@ -0,0 +1,500 @@
1
+ ---
2
+ name: test-unit
3
+ description: Write unit tests following project conventions for Angular 14 legacy projects. Generates Jest tests for components, services, and NestJS using AAA pattern.
4
+ allowed-tools:
5
+ - Bash
6
+ - Read
7
+ - Write
8
+ - Edit
9
+ - Glob
10
+ - Grep
11
+ ---
12
+
13
+ # Unit Test Skill (Angular 14 Legacy)
14
+
15
+ Write unit tests following project conventions using Jest framework with AAA (Arrange-Act-Assert) pattern for Angular 14 legacy projects.
16
+
17
+ ## Testing Framework
18
+
19
+ - **Framework**: Jest for all unit tests
20
+ - **File naming**: `{name}.spec.ts` alongside source files
21
+ - **Test runner**: Nx 14 (`nx test {project}`)
22
+
23
+ ## Test File Location
24
+
25
+ Place test files next to the source files they test:
26
+
27
+ ```
28
+ feature/
29
+ ├── feature.service.ts
30
+ ├── feature.service.spec.ts
31
+ ├── feature.component.ts
32
+ └── feature.component.spec.ts
33
+ ```
34
+
35
+ ## Naming Convention
36
+
37
+ - **Describe blocks**: `@{package-name}: ClassName`
38
+ - **Test format**: `it('should...')` with clear behavior description
39
+
40
+ ## Test Structure (AAA Pattern)
41
+
42
+ Always use Arrange-Act-Assert pattern with blank line separation (no comments):
43
+
44
+ ```typescript
45
+ it('should perform expected operation', () => {
46
+ const input = 'test';
47
+
48
+ const result = service.performOperation(input);
49
+
50
+ expect(result).toBe('expected output');
51
+ });
52
+ ```
53
+
54
+ ## Angular 14 Component Testing
55
+
56
+ ### Basic Component Test (NgModule-based)
57
+
58
+ ```typescript
59
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
60
+ import { NO_ERRORS_SCHEMA } from '@angular/core';
61
+
62
+ import { FeatureComponent } from './feature.component';
63
+
64
+ describe('@mms/shared-angular: FeatureComponent', () => {
65
+ let component: FeatureComponent;
66
+ let fixture: ComponentFixture<FeatureComponent>;
67
+
68
+ beforeEach(async () => {
69
+ await TestBed.configureTestingModule({
70
+ declarations: [FeatureComponent], // NOT imports (not standalone)
71
+ schemas: [NO_ERRORS_SCHEMA],
72
+ }).compileComponents();
73
+
74
+ fixture = TestBed.createComponent(FeatureComponent);
75
+ component = fixture.componentInstance;
76
+ fixture.detectChanges();
77
+ });
78
+
79
+ it('should create', () => {
80
+ expect(component).toBeTruthy();
81
+ });
82
+
83
+ it('should display expected content', () => {
84
+ component.title = 'Test Title';
85
+ fixture.detectChanges();
86
+
87
+ const compiled = fixture.nativeElement;
88
+ expect(compiled.querySelector('h1')?.textContent).toContain('Test Title');
89
+ });
90
+ });
91
+ ```
92
+
93
+ ### Testing Components with @Input/@Output
94
+
95
+ ```typescript
96
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
97
+ import { NO_ERRORS_SCHEMA } from '@angular/core';
98
+
99
+ import { FormFieldComponent } from './form-field.component';
100
+
101
+ describe('@mms/shared-angular: FormFieldComponent', () => {
102
+ let component: FormFieldComponent;
103
+ let fixture: ComponentFixture<FormFieldComponent>;
104
+
105
+ beforeEach(async () => {
106
+ await TestBed.configureTestingModule({
107
+ declarations: [FormFieldComponent],
108
+ schemas: [NO_ERRORS_SCHEMA],
109
+ }).compileComponents();
110
+
111
+ fixture = TestBed.createComponent(FormFieldComponent);
112
+ component = fixture.componentInstance;
113
+ });
114
+
115
+ it('should accept input value', () => {
116
+ component.label = 'Test Label';
117
+ fixture.detectChanges();
118
+
119
+ expect(component.label).toBe('Test Label');
120
+ });
121
+
122
+ it('should emit output event', () => {
123
+ const spy = jest.fn();
124
+ component.changed.subscribe(spy);
125
+
126
+ component.onValueChange('new value');
127
+
128
+ expect(spy).toHaveBeenCalledWith('new value');
129
+ });
130
+
131
+ it('should support two-way binding', () => {
132
+ const valueChangeSpy = jest.fn();
133
+ component.valueChange.subscribe(valueChangeSpy);
134
+
135
+ component.value = 'initial';
136
+ component.onInputChange('updated');
137
+
138
+ expect(valueChangeSpy).toHaveBeenCalledWith('updated');
139
+ });
140
+ });
141
+ ```
142
+
143
+ ### Testing with BehaviorSubject State
144
+
145
+ ```typescript
146
+ import {
147
+ ComponentFixture,
148
+ TestBed,
149
+ fakeAsync,
150
+ tick,
151
+ } from '@angular/core/testing';
152
+ import { of, BehaviorSubject } from 'rxjs';
153
+
154
+ import { ListComponent } from './list.component';
155
+ import { StateService } from './state.service';
156
+
157
+ describe('@mms/shared-angular: ListComponent', () => {
158
+ let component: ListComponent;
159
+ let fixture: ComponentFixture<ListComponent>;
160
+ let mockStateService: {
161
+ items$: BehaviorSubject<Item[]>;
162
+ isLoading$: BehaviorSubject<boolean>;
163
+ };
164
+
165
+ beforeEach(async () => {
166
+ mockStateService = {
167
+ items$: new BehaviorSubject<Item[]>([]),
168
+ isLoading$: new BehaviorSubject<boolean>(false),
169
+ };
170
+
171
+ await TestBed.configureTestingModule({
172
+ declarations: [ListComponent],
173
+ providers: [{ provide: StateService, useValue: mockStateService }],
174
+ }).compileComponents();
175
+
176
+ fixture = TestBed.createComponent(ListComponent);
177
+ component = fixture.componentInstance;
178
+ fixture.detectChanges();
179
+ });
180
+
181
+ it('should display items from state', () => {
182
+ mockStateService.items$.next([
183
+ { id: '1', name: 'Item 1' },
184
+ { id: '2', name: 'Item 2' },
185
+ ]);
186
+ fixture.detectChanges();
187
+
188
+ const items = fixture.nativeElement.querySelectorAll('li');
189
+ expect(items.length).toBe(2);
190
+ });
191
+
192
+ it('should show loading spinner', () => {
193
+ mockStateService.isLoading$.next(true);
194
+ fixture.detectChanges();
195
+
196
+ const spinner = fixture.nativeElement.querySelector('app-spinner');
197
+ expect(spinner).toBeTruthy();
198
+ });
199
+ });
200
+ ```
201
+
202
+ ### Testing with Services (Constructor DI)
203
+
204
+ ```typescript
205
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
206
+ import { of } from 'rxjs';
207
+
208
+ import { FeatureComponent } from './feature.component';
209
+ import { DataService } from './data.service';
210
+
211
+ describe('@mms/shared-angular: FeatureComponent', () => {
212
+ let component: FeatureComponent;
213
+ let fixture: ComponentFixture<FeatureComponent>;
214
+ let mockDataService: jest.Mocked<DataService>;
215
+
216
+ beforeEach(async () => {
217
+ mockDataService = {
218
+ getData: jest.fn().mockReturnValue(of(['item1', 'item2'])),
219
+ saveData: jest.fn().mockReturnValue(of(true)),
220
+ } as unknown as jest.Mocked<DataService>;
221
+
222
+ await TestBed.configureTestingModule({
223
+ declarations: [FeatureComponent],
224
+ providers: [{ provide: DataService, useValue: mockDataService }],
225
+ }).compileComponents();
226
+
227
+ fixture = TestBed.createComponent(FeatureComponent);
228
+ component = fixture.componentInstance;
229
+ fixture.detectChanges();
230
+ });
231
+
232
+ it('should load data on init', () => {
233
+ expect(mockDataService.getData).toHaveBeenCalled();
234
+ expect(component.items).toEqual(['item1', 'item2']);
235
+ });
236
+ });
237
+ ```
238
+
239
+ ## Angular 14 Service Testing
240
+
241
+ ### Service with BehaviorSubject
242
+
243
+ ```typescript
244
+ import { TestBed } from '@angular/core/testing';
245
+ import { take } from 'rxjs/operators';
246
+
247
+ import { StateService } from './state.service';
248
+
249
+ describe('@mms/shared-angular: StateService', () => {
250
+ let service: StateService;
251
+
252
+ beforeEach(() => {
253
+ TestBed.configureTestingModule({
254
+ providers: [StateService],
255
+ });
256
+ service = TestBed.inject(StateService);
257
+ });
258
+
259
+ it('should be created', () => {
260
+ expect(service).toBeTruthy();
261
+ });
262
+
263
+ it('should emit initial state', (done) => {
264
+ service.items$.pipe(take(1)).subscribe((items) => {
265
+ expect(items).toEqual([]);
266
+ done();
267
+ });
268
+ });
269
+
270
+ it('should update items', (done) => {
271
+ const newItems = [{ id: '1', name: 'Test' }];
272
+
273
+ service.setItems(newItems);
274
+
275
+ service.items$.pipe(take(1)).subscribe((items) => {
276
+ expect(items).toEqual(newItems);
277
+ done();
278
+ });
279
+ });
280
+
281
+ it('should return current value', () => {
282
+ const items = [{ id: '1', name: 'Test' }];
283
+ service.setItems(items);
284
+
285
+ expect(service.currentItems).toEqual(items);
286
+ });
287
+ });
288
+ ```
289
+
290
+ ### Service with HTTP (Angular 14 HttpClientTestingModule)
291
+
292
+ ```typescript
293
+ import { TestBed } from '@angular/core/testing';
294
+ import {
295
+ HttpClientTestingModule,
296
+ HttpTestingController,
297
+ } from '@angular/common/http/testing';
298
+
299
+ import { DataService } from './data.service';
300
+
301
+ describe('@mms/shared-angular: DataService', () => {
302
+ let service: DataService;
303
+ let httpMock: HttpTestingController;
304
+
305
+ beforeEach(() => {
306
+ TestBed.configureTestingModule({
307
+ imports: [HttpClientTestingModule],
308
+ providers: [DataService],
309
+ });
310
+
311
+ service = TestBed.inject(DataService);
312
+ httpMock = TestBed.inject(HttpTestingController);
313
+ });
314
+
315
+ afterEach(() => {
316
+ httpMock.verify();
317
+ });
318
+
319
+ it('should be created', () => {
320
+ expect(service).toBeTruthy();
321
+ });
322
+
323
+ it('should fetch data', () => {
324
+ const mockData = [{ id: 1, name: 'Test' }];
325
+
326
+ service.getData().subscribe((data) => {
327
+ expect(data).toEqual(mockData);
328
+ });
329
+
330
+ const req = httpMock.expectOne('/api/data');
331
+ expect(req.request.method).toBe('GET');
332
+ req.flush(mockData);
333
+ });
334
+ });
335
+ ```
336
+
337
+ ## NestJS Service Testing
338
+
339
+ ### Basic Service Test
340
+
341
+ ```typescript
342
+ import { TestingModule, Test } from '@nestjs/testing';
343
+
344
+ import { FeatureService } from './feature.service';
345
+
346
+ describe('@mms/module-name: FeatureService', () => {
347
+ let service: FeatureService;
348
+ let module: TestingModule;
349
+
350
+ beforeEach(async () => {
351
+ module = await Test.createTestingModule({
352
+ providers: [FeatureService],
353
+ }).compile();
354
+
355
+ service = module.get<FeatureService>(FeatureService);
356
+ });
357
+
358
+ afterEach(async () => {
359
+ await module.close();
360
+ });
361
+
362
+ it('should be defined', () => {
363
+ expect(service).toBeDefined();
364
+ });
365
+
366
+ it('should perform expected operation', () => {
367
+ const input = 'test';
368
+
369
+ const result = service.performOperation(input);
370
+
371
+ expect(result).toBe('expected output');
372
+ });
373
+ });
374
+ ```
375
+
376
+ ## Mocking Patterns
377
+
378
+ ### Service Mock
379
+
380
+ ```typescript
381
+ const mockService = {
382
+ getData: jest.fn().mockReturnValue(of(mockData)),
383
+ createItem: jest.fn().mockReturnValue(of(mockItem)),
384
+ updateItem: jest.fn().mockReturnValue(of(updatedMockItem)),
385
+ };
386
+ ```
387
+
388
+ ### LocalStorage Mock
389
+
390
+ ```typescript
391
+ let localStorageMock: any;
392
+
393
+ beforeEach(() => {
394
+ localStorageMock = (() => {
395
+ let store: Record<string, string> = {};
396
+ return {
397
+ getItem: jest.fn((key: string) => store[key] || null),
398
+ setItem: jest.fn((key: string, value: string) => {
399
+ store[key] = value;
400
+ }),
401
+ removeItem: jest.fn((key: string) => {
402
+ delete store[key];
403
+ }),
404
+ clear: jest.fn(() => {
405
+ store = {};
406
+ }),
407
+ };
408
+ })();
409
+ Object.defineProperty(window, 'localStorage', { value: localStorageMock });
410
+ });
411
+ ```
412
+
413
+ ### Router Mock
414
+
415
+ ```typescript
416
+ const mockRouter = {
417
+ navigate: jest.fn(),
418
+ navigateByUrl: jest.fn(),
419
+ createUrlTree: jest.fn(),
420
+ };
421
+
422
+ // In providers
423
+ { provide: Router, useValue: mockRouter }
424
+ ```
425
+
426
+ ### ActivatedRoute Mock
427
+
428
+ ```typescript
429
+ const mockActivatedRoute = {
430
+ params: of({ id: '123' }),
431
+ queryParams: of({ filter: 'active' }),
432
+ snapshot: {
433
+ params: { id: '123' },
434
+ queryParams: { filter: 'active' },
435
+ },
436
+ };
437
+
438
+ // In providers
439
+ { provide: ActivatedRoute, useValue: mockActivatedRoute }
440
+ ```
441
+
442
+ ## Test Commands (Nx 14)
443
+
444
+ ```bash
445
+ # Run tests for specific project
446
+ nx test web
447
+ nx test shared-angular
448
+
449
+ # Run tests in watch mode
450
+ nx test web --watch
451
+
452
+ # Run tests with coverage
453
+ nx test web --coverage
454
+
455
+ # Run all tests
456
+ nx run-many --target=test
457
+
458
+ # Run specific test file
459
+ nx test shared-angular --testFile=feature.service.spec.ts
460
+ ```
461
+
462
+ ## What to Test
463
+
464
+ - Business logic in services
465
+ - Component behavior and state changes
466
+ - Public API contracts (@Input/@Output)
467
+ - BehaviorSubject state management
468
+ - Error handling scenarios
469
+ - Input validation
470
+ - Edge cases and boundary conditions
471
+
472
+ ## What NOT to Test
473
+
474
+ - Third-party libraries
475
+ - Framework internals (Angular/NestJS)
476
+ - Simple getters/setters without logic
477
+ - Auto-generated code
478
+ - Private methods directly (test through public API)
479
+
480
+ ## Workflow
481
+
482
+ 1. **Read source file** to understand the code being tested
483
+ 2. **Create test file** with `.spec.ts` extension next to source
484
+ 3. **Write describe block** with package and class name
485
+ 4. **Add beforeEach** with TestBed setup (declarations, not imports)
486
+ 5. **Write tests** using AAA pattern
487
+ 6. **Run tests** with `nx test {project}`
488
+ 7. **Fix failures** and ensure all pass
489
+
490
+ ## Best Practices (Angular 14)
491
+
492
+ 1. **One assertion per test** when practical
493
+ 2. **Descriptive test names** that explain behavior
494
+ 3. **Independent tests** - no shared state between tests
495
+ 4. **Mock external dependencies** - isolate unit under test
496
+ 5. **Test edge cases** - empty arrays, null values, boundaries
497
+ 6. **Keep tests fast** - avoid real HTTP calls or timers
498
+ 7. **Clean up** - use afterEach for cleanup when needed
499
+ 8. **Use declarations** - components are NOT standalone in Angular 14
500
+ 9. **Mock BehaviorSubjects** - not signals (no signals in Angular 14)
@@ -0,0 +1,115 @@
1
+ # Smart Plugin for Claude Code
2
+
3
+ Smart-pro integration - safety validation, audit logging, auto-formatting hooks, and project convention skills.
4
+
5
+ ## Features
6
+
7
+ | Feature | Type | Description |
8
+ |---------|------|-------------|
9
+ | Safety validation | Hook | Blocks destructive bash commands (`rm -rf /`, etc.) |
10
+ | Sensitive file protection | Hook | Blocks access to `.env`, credentials, secrets |
11
+ | Audit logging | Hook | Logs all Claude actions to `.claude/audit_logs/` |
12
+ | Skill validation | Hook | Validates skill file structure (soft warnings) |
13
+ | Auto-formatting | Hook | Formats files after Write/Edit operations |
14
+ | Safety check | Skill (background) | Safety rules knowledge for Claude |
15
+ | Project conventions | Skill (background) | Monorepo conventions and patterns |
16
+ | Audit log viewer | Skill (user-invocable) | `/smart:audit-log` to query audit logs |
17
+ | Format code | Skill (user-invocable) | `/smart:format-code` to run formatting |
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ claude plugin update smart-pro@smart-pro --scope project
23
+ ```
24
+
25
+ ## Architecture
26
+
27
+ ```
28
+ smart/
29
+ ├── .claude-plugin/
30
+ │ ├── plugin.json # Plugin metadata
31
+ │ └── README.md # This file
32
+ ├── hooks/
33
+ │ ├── hooks.json # Hook configuration
34
+ │ ├── safety_validator.py # Blocks destructive commands
35
+ │ ├── sensitive_file_blocker.py # Blocks access to sensitive files
36
+ │ ├── audit_logger.py # Logs all Claude actions
37
+ │ ├── skill_validator.py # Validates skill file structure
38
+ │ ├── auto_format.sh # Formats code after changes
39
+ │ ├── CONFIG.md # Hook customization guide
40
+ │ └── README.md # Hook documentation
41
+ ├── skills/
42
+ │ ├── safety-check/SKILL.md # Background: safety rules
43
+ │ ├── audit-log/SKILL.md # User-invocable: /smart:audit-log
44
+ │ ├── format-code/SKILL.md # User-invocable: /smart:format-code
45
+ │ ├── project-conventions/SKILL.md # Background: project knowledge
46
+ │ ├── angular-components-button/SKILL.md # Background: button API
47
+ │ └── angular-components-card/SKILL.md # Background: card API
48
+ ├── _legacy/
49
+ │ ├── settings.template.json # Deprecated settings template
50
+ │ └── merge-permissions.js # Deprecated merge script
51
+ └── MIGRATION.md # Migration guide from legacy
52
+ ```
53
+
54
+ ## Skills
55
+
56
+ ### User-Invocable
57
+
58
+ | Skill | Command | Purpose |
59
+ |-------|---------|---------|
60
+ | audit-log | `/smart:audit-log [today\|yesterday\|YYYYMMDD]` | Query audit logs |
61
+ | format-code | `/smart:format-code` | Run `npm run format` |
62
+
63
+ ### Background (automatic)
64
+
65
+ | Skill | Purpose |
66
+ |-------|---------|
67
+ | safety-check | Blocked patterns and sensitive file rules |
68
+ | project-conventions | Nx monorepo structure, conventions, patterns |
69
+ | angular-components-button | Button component API, variants, and usage patterns |
70
+ | angular-components-card | Card component API, variants, and usage patterns |
71
+
72
+ ## Hooks
73
+
74
+ Hooks are configured in `hooks/hooks.json` and run automatically:
75
+
76
+ ### PreToolUse
77
+
78
+ | Hook | Matcher | Purpose |
79
+ |------|---------|---------|
80
+ | `safety_validator.py` | Bash\|Write\|Edit | Blocks destructive commands |
81
+ | `sensitive_file_blocker.py` | Read\|Edit\|Write | Blocks sensitive files |
82
+ | `audit_logger.py` | * | Logs all events |
83
+ | `skill_validator.py` | Write\|Edit | Validates skill files |
84
+
85
+ ### PostToolUse
86
+
87
+ | Hook | Matcher | Purpose |
88
+ |------|---------|---------|
89
+ | `auto_format.sh` | Write\|Edit | Runs formatting pipeline |
90
+ | `audit_logger.py` | * | Logs all events |
91
+
92
+ ### UserPromptSubmit
93
+
94
+ | Hook | Purpose |
95
+ |------|---------|
96
+ | `audit_logger.py` | Logs user prompts |
97
+
98
+ ## Audit Logs
99
+
100
+ Logs are stored in `.claude/audit_logs/YYYYMMDD_audit.jsonl`:
101
+
102
+ ```json
103
+ {"timestamp":"2024-01-15T10:30:00Z","event_type":"PreToolUse","session_id":"abc123","event_data":{...}}
104
+ ```
105
+
106
+ ## Customization
107
+
108
+ See `hooks/CONFIG.md` for:
109
+ - Adding custom blocked patterns
110
+ - Changing log location
111
+ - Creating new hooks
112
+
113
+ ## Migration from Legacy
114
+
115
+ If upgrading from the old `settings.template.json` approach, see `MIGRATION.md`.