nestlens 0.1.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/LICENSE +21 -0
- package/README.md +145 -0
- package/dist/__tests__/api/api.controller.spec.d.ts +2 -0
- package/dist/__tests__/api/api.controller.spec.d.ts.map +1 -0
- package/dist/__tests__/api/api.controller.spec.js +982 -0
- package/dist/__tests__/api/api.controller.spec.js.map +1 -0
- package/dist/__tests__/api/api.guard.spec.d.ts +2 -0
- package/dist/__tests__/api/api.guard.spec.d.ts.map +1 -0
- package/dist/__tests__/api/api.guard.spec.js +572 -0
- package/dist/__tests__/api/api.guard.spec.js.map +1 -0
- package/dist/__tests__/api/dashboard.controller.spec.d.ts +2 -0
- package/dist/__tests__/api/dashboard.controller.spec.d.ts.map +1 -0
- package/dist/__tests__/api/dashboard.controller.spec.js +474 -0
- package/dist/__tests__/api/dashboard.controller.spec.js.map +1 -0
- package/dist/__tests__/api/tag.controller.spec.d.ts +2 -0
- package/dist/__tests__/api/tag.controller.spec.d.ts.map +1 -0
- package/dist/__tests__/api/tag.controller.spec.js +280 -0
- package/dist/__tests__/api/tag.controller.spec.js.map +1 -0
- package/dist/__tests__/collector.service.spec.d.ts +2 -0
- package/dist/__tests__/collector.service.spec.d.ts.map +1 -0
- package/dist/__tests__/collector.service.spec.js +240 -0
- package/dist/__tests__/collector.service.spec.js.map +1 -0
- package/dist/__tests__/core/collector.service.spec.d.ts +2 -0
- package/dist/__tests__/core/collector.service.spec.d.ts.map +1 -0
- package/dist/__tests__/core/collector.service.spec.js +526 -0
- package/dist/__tests__/core/collector.service.spec.js.map +1 -0
- package/dist/__tests__/core/family-hash.service.spec.d.ts +2 -0
- package/dist/__tests__/core/family-hash.service.spec.d.ts.map +1 -0
- package/dist/__tests__/core/family-hash.service.spec.js +1117 -0
- package/dist/__tests__/core/family-hash.service.spec.js.map +1 -0
- package/dist/__tests__/core/pruning.service.spec.d.ts +2 -0
- package/dist/__tests__/core/pruning.service.spec.d.ts.map +1 -0
- package/dist/__tests__/core/pruning.service.spec.js +224 -0
- package/dist/__tests__/core/pruning.service.spec.js.map +1 -0
- package/dist/__tests__/core/storage/sqlite.storage.spec.d.ts +2 -0
- package/dist/__tests__/core/storage/sqlite.storage.spec.d.ts.map +1 -0
- package/dist/__tests__/core/storage/sqlite.storage.spec.js +853 -0
- package/dist/__tests__/core/storage/sqlite.storage.spec.js.map +1 -0
- package/dist/__tests__/core/tag.service.spec.d.ts +2 -0
- package/dist/__tests__/core/tag.service.spec.d.ts.map +1 -0
- package/dist/__tests__/core/tag.service.spec.js +994 -0
- package/dist/__tests__/core/tag.service.spec.js.map +1 -0
- package/dist/__tests__/family-hash.service.spec.d.ts +2 -0
- package/dist/__tests__/family-hash.service.spec.d.ts.map +1 -0
- package/dist/__tests__/family-hash.service.spec.js +325 -0
- package/dist/__tests__/family-hash.service.spec.js.map +1 -0
- package/dist/__tests__/filters/api-filters.spec.d.ts +2 -0
- package/dist/__tests__/filters/api-filters.spec.d.ts.map +1 -0
- package/dist/__tests__/filters/api-filters.spec.js +172 -0
- package/dist/__tests__/filters/api-filters.spec.js.map +1 -0
- package/dist/__tests__/filters/entry-factories.d.ts +20 -0
- package/dist/__tests__/filters/entry-factories.d.ts.map +1 -0
- package/dist/__tests__/filters/entry-factories.js +288 -0
- package/dist/__tests__/filters/entry-factories.js.map +1 -0
- package/dist/__tests__/filters/filter-contract.spec.d.ts +2 -0
- package/dist/__tests__/filters/filter-contract.spec.d.ts.map +1 -0
- package/dist/__tests__/filters/filter-contract.spec.js +230 -0
- package/dist/__tests__/filters/filter-contract.spec.js.map +1 -0
- package/dist/__tests__/filters/filter-test-data.d.ts +26 -0
- package/dist/__tests__/filters/filter-test-data.d.ts.map +1 -0
- package/dist/__tests__/filters/filter-test-data.js +374 -0
- package/dist/__tests__/filters/filter-test-data.js.map +1 -0
- package/dist/__tests__/filters/storage-filters.spec.d.ts +2 -0
- package/dist/__tests__/filters/storage-filters.spec.d.ts.map +1 -0
- package/dist/__tests__/filters/storage-filters.spec.js +699 -0
- package/dist/__tests__/filters/storage-filters.spec.js.map +1 -0
- package/dist/__tests__/filters/test-utils.d.ts +23 -0
- package/dist/__tests__/filters/test-utils.d.ts.map +1 -0
- package/dist/__tests__/filters/test-utils.js +54 -0
- package/dist/__tests__/filters/test-utils.js.map +1 -0
- package/dist/__tests__/nestlens.module.spec.d.ts +2 -0
- package/dist/__tests__/nestlens.module.spec.d.ts.map +1 -0
- package/dist/__tests__/nestlens.module.spec.js +620 -0
- package/dist/__tests__/nestlens.module.spec.js.map +1 -0
- package/dist/__tests__/pruning.service.spec.d.ts +2 -0
- package/dist/__tests__/pruning.service.spec.d.ts.map +1 -0
- package/dist/__tests__/pruning.service.spec.js +142 -0
- package/dist/__tests__/pruning.service.spec.js.map +1 -0
- package/dist/__tests__/setup.d.ts +7 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/setup.js +24 -0
- package/dist/__tests__/setup.js.map +1 -0
- package/dist/__tests__/tag.service.spec.d.ts +2 -0
- package/dist/__tests__/tag.service.spec.d.ts.map +1 -0
- package/dist/__tests__/tag.service.spec.js +482 -0
- package/dist/__tests__/tag.service.spec.js.map +1 -0
- package/dist/__tests__/watchers/batch.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/batch.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/batch.watcher.spec.js +515 -0
- package/dist/__tests__/watchers/batch.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/cache.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/cache.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/cache.watcher.spec.js +395 -0
- package/dist/__tests__/watchers/cache.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/command.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/command.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/command.watcher.spec.js +598 -0
- package/dist/__tests__/watchers/command.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/dump.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/dump.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/dump.watcher.spec.js +724 -0
- package/dist/__tests__/watchers/dump.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/event.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/event.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/event.watcher.spec.js +316 -0
- package/dist/__tests__/watchers/event.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/exception.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/exception.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/exception.watcher.spec.js +495 -0
- package/dist/__tests__/watchers/exception.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/gate.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/gate.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/gate.watcher.spec.js +683 -0
- package/dist/__tests__/watchers/gate.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/http-client.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/http-client.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/http-client.watcher.spec.js +888 -0
- package/dist/__tests__/watchers/http-client.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/job.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/job.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/job.watcher.spec.js +513 -0
- package/dist/__tests__/watchers/job.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/log.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/log.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/log.watcher.spec.js +428 -0
- package/dist/__tests__/watchers/log.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/mail.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/mail.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/mail.watcher.spec.js +425 -0
- package/dist/__tests__/watchers/mail.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/model.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/model.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/model.watcher.spec.js +675 -0
- package/dist/__tests__/watchers/model.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/notification.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/notification.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/notification.watcher.spec.js +595 -0
- package/dist/__tests__/watchers/notification.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/query/types.spec.d.ts +2 -0
- package/dist/__tests__/watchers/query/types.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/query/types.spec.js +292 -0
- package/dist/__tests__/watchers/query/types.spec.js.map +1 -0
- package/dist/__tests__/watchers/query.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/query.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/query.watcher.spec.js +597 -0
- package/dist/__tests__/watchers/query.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/redis.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/redis.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/redis.watcher.spec.js +634 -0
- package/dist/__tests__/watchers/redis.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/request.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/request.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/request.watcher.spec.js +1017 -0
- package/dist/__tests__/watchers/request.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/schedule.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/schedule.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/schedule.watcher.spec.js +338 -0
- package/dist/__tests__/watchers/schedule.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/view.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/view.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/view.watcher.spec.js +564 -0
- package/dist/__tests__/watchers/view.watcher.spec.js.map +1 -0
- package/dist/api/api.controller.d.ts +193 -0
- package/dist/api/api.controller.d.ts.map +1 -0
- package/dist/api/api.controller.js +562 -0
- package/dist/api/api.controller.js.map +1 -0
- package/dist/api/api.guard.d.ts +77 -0
- package/dist/api/api.guard.d.ts.map +1 -0
- package/dist/api/api.guard.js +294 -0
- package/dist/api/api.guard.js.map +1 -0
- package/dist/api/dashboard.controller.d.ts +49 -0
- package/dist/api/dashboard.controller.d.ts.map +1 -0
- package/dist/api/dashboard.controller.js +472 -0
- package/dist/api/dashboard.controller.js.map +1 -0
- package/dist/api/index.d.ts +5 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +21 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/tag.controller.d.ts +65 -0
- package/dist/api/tag.controller.d.ts.map +1 -0
- package/dist/api/tag.controller.js +149 -0
- package/dist/api/tag.controller.js.map +1 -0
- package/dist/core/collector.service.d.ts +80 -0
- package/dist/core/collector.service.d.ts.map +1 -0
- package/dist/core/collector.service.js +255 -0
- package/dist/core/collector.service.js.map +1 -0
- package/dist/core/family-hash.service.d.ts +64 -0
- package/dist/core/family-hash.service.d.ts.map +1 -0
- package/dist/core/family-hash.service.js +281 -0
- package/dist/core/family-hash.service.js.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +20 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/pruning.service.d.ts +16 -0
- package/dist/core/pruning.service.d.ts.map +1 -0
- package/dist/core/pruning.service.js +71 -0
- package/dist/core/pruning.service.js.map +1 -0
- package/dist/core/storage/index.d.ts +3 -0
- package/dist/core/storage/index.d.ts.map +1 -0
- package/dist/core/storage/index.js +19 -0
- package/dist/core/storage/index.js.map +1 -0
- package/dist/core/storage/sqlite.storage.d.ts +60 -0
- package/dist/core/storage/sqlite.storage.d.ts.map +1 -0
- package/dist/core/storage/sqlite.storage.js +929 -0
- package/dist/core/storage/sqlite.storage.js.map +1 -0
- package/dist/core/storage/storage.interface.d.ts +122 -0
- package/dist/core/storage/storage.interface.d.ts.map +1 -0
- package/dist/core/storage/storage.interface.js +5 -0
- package/dist/core/storage/storage.interface.js.map +1 -0
- package/dist/core/tag.service.d.ts +71 -0
- package/dist/core/tag.service.d.ts.map +1 -0
- package/dist/core/tag.service.js +568 -0
- package/dist/core/tag.service.js.map +1 -0
- package/dist/dashboard/public/assets/BatchesPage-DFT4fKlJ.js +1 -0
- package/dist/dashboard/public/assets/CachePage-CRy1Tjb8.js +1 -0
- package/dist/dashboard/public/assets/ClickableBadge-CV5J3THx.js +1 -0
- package/dist/dashboard/public/assets/CommandsPage-DdRnTm-W.js +1 -0
- package/dist/dashboard/public/assets/DashboardPage-CjaRZXYy.js +26 -0
- package/dist/dashboard/public/assets/DataTable-B6o9H8lh.js +88 -0
- package/dist/dashboard/public/assets/DumpsPage-DO8y1RTg.js +1 -0
- package/dist/dashboard/public/assets/EntryDetailPage-By-YcAGL.js +125 -0
- package/dist/dashboard/public/assets/EventsPage-u-r4AiT4.js +1 -0
- package/dist/dashboard/public/assets/ExceptionsPage-DXUcARr1.js +6 -0
- package/dist/dashboard/public/assets/GatesPage-DpeP7CDZ.js +1 -0
- package/dist/dashboard/public/assets/HttpClientPage-BJ4-5E6t.js +1 -0
- package/dist/dashboard/public/assets/JobsPage-Dv3KaX2x.js +1 -0
- package/dist/dashboard/public/assets/LogsPage-D0Q3yDb1.js +1 -0
- package/dist/dashboard/public/assets/MailPage-Bf8C6WF6.js +1 -0
- package/dist/dashboard/public/assets/ModelsPage-BMHncI5y.js +1 -0
- package/dist/dashboard/public/assets/NotificationsPage-D5-I-Oxb.js +1 -0
- package/dist/dashboard/public/assets/QueriesPage-oNp0i6Gt.js +1 -0
- package/dist/dashboard/public/assets/RedisPage-_GeS2OD8.js +1 -0
- package/dist/dashboard/public/assets/RequestsPage-BCwqu9US.js +1 -0
- package/dist/dashboard/public/assets/SchedulePage-CR0P-oX6.js +1 -0
- package/dist/dashboard/public/assets/ViewsPage-Dsy5ECRA.js +1 -0
- package/dist/dashboard/public/assets/calendar-DfK3x-6B.js +6 -0
- package/dist/dashboard/public/assets/circle-check-big-DcsYW8y8.js +6 -0
- package/dist/dashboard/public/assets/format-BFldcnCk.js +1 -0
- package/dist/dashboard/public/assets/index-DmeA1maE.css +1 -0
- package/dist/dashboard/public/assets/index-rkbGYdU7.js +351 -0
- package/dist/dashboard/public/assets/types-Cldoe2db.js +1 -0
- package/dist/dashboard/public/assets/vendor-B2nVRih0.js +43 -0
- package/dist/dashboard/public/assets/zap-DqtRi0JM.js +6 -0
- package/dist/dashboard/public/index.html +15 -0
- package/dist/dashboard/public/nestlens-icon.svg +9 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +69 -0
- package/dist/index.js.map +1 -0
- package/dist/nestlens.config.d.ts +216 -0
- package/dist/nestlens.config.d.ts.map +1 -0
- package/dist/nestlens.config.js +57 -0
- package/dist/nestlens.config.js.map +1 -0
- package/dist/nestlens.module.d.ts +10 -0
- package/dist/nestlens.module.d.ts.map +1 -0
- package/dist/nestlens.module.js +211 -0
- package/dist/nestlens.module.js.map +1 -0
- package/dist/types/entry.types.d.ts +368 -0
- package/dist/types/entry.types.d.ts.map +1 -0
- package/dist/types/entry.types.js +3 -0
- package/dist/types/entry.types.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +20 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/request.types.d.ts +9 -0
- package/dist/types/request.types.d.ts.map +1 -0
- package/dist/types/request.types.js +3 -0
- package/dist/types/request.types.js.map +1 -0
- package/dist/types/tag.types.d.ts +32 -0
- package/dist/types/tag.types.d.ts.map +1 -0
- package/dist/types/tag.types.js +3 -0
- package/dist/types/tag.types.js.map +1 -0
- package/dist/watchers/batch.watcher.d.ts +48 -0
- package/dist/watchers/batch.watcher.d.ts.map +1 -0
- package/dist/watchers/batch.watcher.js +185 -0
- package/dist/watchers/batch.watcher.js.map +1 -0
- package/dist/watchers/cache.watcher.d.ts +19 -0
- package/dist/watchers/cache.watcher.d.ts.map +1 -0
- package/dist/watchers/cache.watcher.js +158 -0
- package/dist/watchers/cache.watcher.js.map +1 -0
- package/dist/watchers/command.watcher.d.ts +32 -0
- package/dist/watchers/command.watcher.d.ts.map +1 -0
- package/dist/watchers/command.watcher.js +174 -0
- package/dist/watchers/command.watcher.js.map +1 -0
- package/dist/watchers/dump.watcher.d.ts +52 -0
- package/dist/watchers/dump.watcher.d.ts.map +1 -0
- package/dist/watchers/dump.watcher.js +234 -0
- package/dist/watchers/dump.watcher.js.map +1 -0
- package/dist/watchers/event.watcher.d.ts +20 -0
- package/dist/watchers/event.watcher.d.ts.map +1 -0
- package/dist/watchers/event.watcher.js +123 -0
- package/dist/watchers/event.watcher.js.map +1 -0
- package/dist/watchers/exception.watcher.d.ts +15 -0
- package/dist/watchers/exception.watcher.d.ts.map +1 -0
- package/dist/watchers/exception.watcher.js +117 -0
- package/dist/watchers/exception.watcher.js.map +1 -0
- package/dist/watchers/gate.watcher.d.ts +40 -0
- package/dist/watchers/gate.watcher.d.ts.map +1 -0
- package/dist/watchers/gate.watcher.js +200 -0
- package/dist/watchers/gate.watcher.js.map +1 -0
- package/dist/watchers/http-client.watcher.d.ts +34 -0
- package/dist/watchers/http-client.watcher.d.ts.map +1 -0
- package/dist/watchers/http-client.watcher.js +259 -0
- package/dist/watchers/http-client.watcher.js.map +1 -0
- package/dist/watchers/index.d.ts +19 -0
- package/dist/watchers/index.d.ts.map +1 -0
- package/dist/watchers/index.js +35 -0
- package/dist/watchers/index.js.map +1 -0
- package/dist/watchers/job.watcher.d.ts +27 -0
- package/dist/watchers/job.watcher.d.ts.map +1 -0
- package/dist/watchers/job.watcher.js +190 -0
- package/dist/watchers/job.watcher.js.map +1 -0
- package/dist/watchers/log.watcher.d.ts +26 -0
- package/dist/watchers/log.watcher.d.ts.map +1 -0
- package/dist/watchers/log.watcher.js +122 -0
- package/dist/watchers/log.watcher.js.map +1 -0
- package/dist/watchers/mail.watcher.d.ts +26 -0
- package/dist/watchers/mail.watcher.d.ts.map +1 -0
- package/dist/watchers/mail.watcher.js +154 -0
- package/dist/watchers/mail.watcher.js.map +1 -0
- package/dist/watchers/model.watcher.d.ts +54 -0
- package/dist/watchers/model.watcher.d.ts.map +1 -0
- package/dist/watchers/model.watcher.js +343 -0
- package/dist/watchers/model.watcher.js.map +1 -0
- package/dist/watchers/notification.watcher.d.ts +48 -0
- package/dist/watchers/notification.watcher.d.ts.map +1 -0
- package/dist/watchers/notification.watcher.js +215 -0
- package/dist/watchers/notification.watcher.js.map +1 -0
- package/dist/watchers/query/index.d.ts +3 -0
- package/dist/watchers/query/index.d.ts.map +1 -0
- package/dist/watchers/query/index.js +19 -0
- package/dist/watchers/query/index.js.map +1 -0
- package/dist/watchers/query/query.watcher.d.ts +27 -0
- package/dist/watchers/query/query.watcher.d.ts.map +1 -0
- package/dist/watchers/query/query.watcher.js +167 -0
- package/dist/watchers/query/query.watcher.js.map +1 -0
- package/dist/watchers/query/types.d.ts +60 -0
- package/dist/watchers/query/types.d.ts.map +1 -0
- package/dist/watchers/query/types.js +55 -0
- package/dist/watchers/query/types.js.map +1 -0
- package/dist/watchers/redis.watcher.d.ts +43 -0
- package/dist/watchers/redis.watcher.d.ts.map +1 -0
- package/dist/watchers/redis.watcher.js +225 -0
- package/dist/watchers/redis.watcher.js.map +1 -0
- package/dist/watchers/request.watcher.d.ts +21 -0
- package/dist/watchers/request.watcher.d.ts.map +1 -0
- package/dist/watchers/request.watcher.js +287 -0
- package/dist/watchers/request.watcher.js.map +1 -0
- package/dist/watchers/schedule.watcher.d.ts +25 -0
- package/dist/watchers/schedule.watcher.d.ts.map +1 -0
- package/dist/watchers/schedule.watcher.js +168 -0
- package/dist/watchers/schedule.watcher.js.map +1 -0
- package/dist/watchers/view.watcher.d.ts +51 -0
- package/dist/watchers/view.watcher.d.ts.map +1 -0
- package/dist/watchers/view.watcher.js +219 -0
- package/dist/watchers/view.watcher.js.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1,994 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const testing_1 = require("@nestjs/testing");
|
|
4
|
+
const tag_service_1 = require("../../core/tag.service");
|
|
5
|
+
const storage_interface_1 = require("../../core/storage/storage.interface");
|
|
6
|
+
describe('TagService', () => {
|
|
7
|
+
let service;
|
|
8
|
+
let mockStorage;
|
|
9
|
+
beforeEach(async () => {
|
|
10
|
+
// Arrange
|
|
11
|
+
mockStorage = {
|
|
12
|
+
addTags: jest.fn(),
|
|
13
|
+
removeTags: jest.fn(),
|
|
14
|
+
getEntryTags: jest.fn(),
|
|
15
|
+
getAllTags: jest.fn(),
|
|
16
|
+
findByTags: jest.fn(),
|
|
17
|
+
addMonitoredTag: jest.fn(),
|
|
18
|
+
removeMonitoredTag: jest.fn(),
|
|
19
|
+
getMonitoredTags: jest.fn(),
|
|
20
|
+
};
|
|
21
|
+
const module = await testing_1.Test.createTestingModule({
|
|
22
|
+
providers: [
|
|
23
|
+
tag_service_1.TagService,
|
|
24
|
+
{ provide: storage_interface_1.STORAGE, useValue: mockStorage },
|
|
25
|
+
],
|
|
26
|
+
}).compile();
|
|
27
|
+
service = module.get(tag_service_1.TagService);
|
|
28
|
+
});
|
|
29
|
+
afterEach(() => {
|
|
30
|
+
jest.clearAllMocks();
|
|
31
|
+
});
|
|
32
|
+
describe('autoTag', () => {
|
|
33
|
+
describe('Request Tags', () => {
|
|
34
|
+
it('should add ERROR and 5XX tags for 500+ status', async () => {
|
|
35
|
+
// Arrange
|
|
36
|
+
const entry = {
|
|
37
|
+
id: 1,
|
|
38
|
+
type: 'request',
|
|
39
|
+
payload: { statusCode: 500, method: 'GET', path: '/test' },
|
|
40
|
+
};
|
|
41
|
+
// Act
|
|
42
|
+
const tags = await service.autoTag(entry);
|
|
43
|
+
// Assert
|
|
44
|
+
expect(tags).toContain('ERROR');
|
|
45
|
+
expect(tags).toContain('5XX');
|
|
46
|
+
expect(mockStorage.addTags).toHaveBeenCalledWith(1, expect.arrayContaining(['ERROR', '5XX']));
|
|
47
|
+
});
|
|
48
|
+
it('should add CLIENT-ERROR and 4XX tags for 400+ status', async () => {
|
|
49
|
+
// Arrange
|
|
50
|
+
const entry = {
|
|
51
|
+
id: 1,
|
|
52
|
+
type: 'request',
|
|
53
|
+
payload: { statusCode: 404, method: 'GET', path: '/test' },
|
|
54
|
+
};
|
|
55
|
+
// Act
|
|
56
|
+
const tags = await service.autoTag(entry);
|
|
57
|
+
// Assert
|
|
58
|
+
expect(tags).toContain('CLIENT-ERROR');
|
|
59
|
+
expect(tags).toContain('4XX');
|
|
60
|
+
});
|
|
61
|
+
it('should add REDIRECT and 3XX tags for 300+ status', async () => {
|
|
62
|
+
// Arrange
|
|
63
|
+
const entry = {
|
|
64
|
+
id: 1,
|
|
65
|
+
type: 'request',
|
|
66
|
+
payload: { statusCode: 301, method: 'GET', path: '/test' },
|
|
67
|
+
};
|
|
68
|
+
// Act
|
|
69
|
+
const tags = await service.autoTag(entry);
|
|
70
|
+
// Assert
|
|
71
|
+
expect(tags).toContain('REDIRECT');
|
|
72
|
+
expect(tags).toContain('3XX');
|
|
73
|
+
});
|
|
74
|
+
it('should add SUCCESS tag for 200+ status', async () => {
|
|
75
|
+
// Arrange
|
|
76
|
+
const entry = {
|
|
77
|
+
id: 1,
|
|
78
|
+
type: 'request',
|
|
79
|
+
payload: { statusCode: 200, method: 'GET', path: '/test' },
|
|
80
|
+
};
|
|
81
|
+
// Act
|
|
82
|
+
const tags = await service.autoTag(entry);
|
|
83
|
+
// Assert
|
|
84
|
+
expect(tags).toContain('SUCCESS');
|
|
85
|
+
});
|
|
86
|
+
it('should add USER tag when user.id exists', async () => {
|
|
87
|
+
// Arrange
|
|
88
|
+
const entry = {
|
|
89
|
+
id: 1,
|
|
90
|
+
type: 'request',
|
|
91
|
+
payload: { statusCode: 200, method: 'GET', path: '/test', user: { id: 'user-123' } },
|
|
92
|
+
};
|
|
93
|
+
// Act
|
|
94
|
+
const tags = await service.autoTag(entry);
|
|
95
|
+
// Assert
|
|
96
|
+
expect(tags).toContain('USER:user-123');
|
|
97
|
+
});
|
|
98
|
+
it('should add HTTP method tag for non-GraphQL requests', async () => {
|
|
99
|
+
// Arrange
|
|
100
|
+
const entry = {
|
|
101
|
+
id: 1,
|
|
102
|
+
type: 'request',
|
|
103
|
+
payload: { statusCode: 200, method: 'POST', path: '/api/users' },
|
|
104
|
+
};
|
|
105
|
+
// Act
|
|
106
|
+
const tags = await service.autoTag(entry);
|
|
107
|
+
// Assert
|
|
108
|
+
expect(tags).toContain('POST');
|
|
109
|
+
});
|
|
110
|
+
it('should NOT add method tag for GraphQL requests', async () => {
|
|
111
|
+
// Arrange
|
|
112
|
+
const entry = {
|
|
113
|
+
id: 1,
|
|
114
|
+
type: 'request',
|
|
115
|
+
payload: { statusCode: 200, method: 'POST', path: '/graphql' },
|
|
116
|
+
};
|
|
117
|
+
// Act
|
|
118
|
+
const tags = await service.autoTag(entry);
|
|
119
|
+
// Assert
|
|
120
|
+
expect(tags).not.toContain('POST');
|
|
121
|
+
});
|
|
122
|
+
it('should add SLOW tag for requests > 1000ms', async () => {
|
|
123
|
+
// Arrange
|
|
124
|
+
const entry = {
|
|
125
|
+
id: 1,
|
|
126
|
+
type: 'request',
|
|
127
|
+
payload: { statusCode: 200, method: 'GET', path: '/test', duration: 1500 },
|
|
128
|
+
};
|
|
129
|
+
// Act
|
|
130
|
+
const tags = await service.autoTag(entry);
|
|
131
|
+
// Assert
|
|
132
|
+
expect(tags).toContain('SLOW');
|
|
133
|
+
});
|
|
134
|
+
it('should include custom tags from payload', async () => {
|
|
135
|
+
// Arrange
|
|
136
|
+
const entry = {
|
|
137
|
+
id: 1,
|
|
138
|
+
type: 'request',
|
|
139
|
+
payload: { statusCode: 200, method: 'GET', path: '/test', tags: ['important', 'debug'] },
|
|
140
|
+
};
|
|
141
|
+
// Act
|
|
142
|
+
const tags = await service.autoTag(entry);
|
|
143
|
+
// Assert
|
|
144
|
+
expect(tags).toContain('IMPORTANT');
|
|
145
|
+
expect(tags).toContain('DEBUG');
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
describe('Query Tags', () => {
|
|
149
|
+
it('should add SLOW tag for slow queries', async () => {
|
|
150
|
+
// Arrange
|
|
151
|
+
const entry = {
|
|
152
|
+
id: 1,
|
|
153
|
+
type: 'query',
|
|
154
|
+
payload: { query: 'SELECT * FROM users', slow: true, duration: 1000 },
|
|
155
|
+
};
|
|
156
|
+
// Act
|
|
157
|
+
const tags = await service.autoTag(entry);
|
|
158
|
+
// Assert
|
|
159
|
+
expect(tags).toContain('SLOW');
|
|
160
|
+
});
|
|
161
|
+
it('should add source tag', async () => {
|
|
162
|
+
// Arrange
|
|
163
|
+
const entry = {
|
|
164
|
+
id: 1,
|
|
165
|
+
type: 'query',
|
|
166
|
+
payload: { query: 'SELECT * FROM users', slow: false, duration: 10, source: 'TypeORM' },
|
|
167
|
+
};
|
|
168
|
+
// Act
|
|
169
|
+
const tags = await service.autoTag(entry);
|
|
170
|
+
// Assert
|
|
171
|
+
expect(tags).toContain('TYPEORM');
|
|
172
|
+
});
|
|
173
|
+
it('should detect SELECT query', async () => {
|
|
174
|
+
// Arrange
|
|
175
|
+
const entry = {
|
|
176
|
+
id: 1,
|
|
177
|
+
type: 'query',
|
|
178
|
+
payload: { query: 'SELECT * FROM users', slow: false, duration: 10 },
|
|
179
|
+
};
|
|
180
|
+
// Act
|
|
181
|
+
const tags = await service.autoTag(entry);
|
|
182
|
+
// Assert
|
|
183
|
+
expect(tags).toContain('SELECT');
|
|
184
|
+
});
|
|
185
|
+
it('should detect INSERT query', async () => {
|
|
186
|
+
// Arrange
|
|
187
|
+
const entry = {
|
|
188
|
+
id: 1,
|
|
189
|
+
type: 'query',
|
|
190
|
+
payload: { query: 'INSERT INTO users VALUES (1)', slow: false, duration: 10 },
|
|
191
|
+
};
|
|
192
|
+
// Act
|
|
193
|
+
const tags = await service.autoTag(entry);
|
|
194
|
+
// Assert
|
|
195
|
+
expect(tags).toContain('INSERT');
|
|
196
|
+
});
|
|
197
|
+
it('should detect UPDATE query', async () => {
|
|
198
|
+
// Arrange
|
|
199
|
+
const entry = {
|
|
200
|
+
id: 1,
|
|
201
|
+
type: 'query',
|
|
202
|
+
payload: { query: 'UPDATE users SET name = ?', slow: false, duration: 10 },
|
|
203
|
+
};
|
|
204
|
+
// Act
|
|
205
|
+
const tags = await service.autoTag(entry);
|
|
206
|
+
// Assert
|
|
207
|
+
expect(tags).toContain('UPDATE');
|
|
208
|
+
});
|
|
209
|
+
it('should detect DELETE query', async () => {
|
|
210
|
+
// Arrange
|
|
211
|
+
const entry = {
|
|
212
|
+
id: 1,
|
|
213
|
+
type: 'query',
|
|
214
|
+
payload: { query: 'DELETE FROM users WHERE id = 1', slow: false, duration: 10 },
|
|
215
|
+
};
|
|
216
|
+
// Act
|
|
217
|
+
const tags = await service.autoTag(entry);
|
|
218
|
+
// Assert
|
|
219
|
+
expect(tags).toContain('DELETE');
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
describe('Exception Tags', () => {
|
|
223
|
+
it('should add ERROR tag', async () => {
|
|
224
|
+
// Arrange
|
|
225
|
+
const entry = {
|
|
226
|
+
id: 1,
|
|
227
|
+
type: 'exception',
|
|
228
|
+
payload: { name: 'Error', message: 'Something went wrong' },
|
|
229
|
+
};
|
|
230
|
+
// Act
|
|
231
|
+
const tags = await service.autoTag(entry);
|
|
232
|
+
// Assert
|
|
233
|
+
expect(tags).toContain('ERROR');
|
|
234
|
+
});
|
|
235
|
+
it('should add exception type tag when not generic Error', async () => {
|
|
236
|
+
// Arrange
|
|
237
|
+
const entry = {
|
|
238
|
+
id: 1,
|
|
239
|
+
type: 'exception',
|
|
240
|
+
payload: { name: 'TypeError', message: 'Cannot read property' },
|
|
241
|
+
};
|
|
242
|
+
// Act
|
|
243
|
+
const tags = await service.autoTag(entry);
|
|
244
|
+
// Assert
|
|
245
|
+
expect(tags).toContain('TYPEERROR');
|
|
246
|
+
});
|
|
247
|
+
it('should NOT add exception name tag for generic Error', async () => {
|
|
248
|
+
// Arrange
|
|
249
|
+
const entry = {
|
|
250
|
+
id: 1,
|
|
251
|
+
type: 'exception',
|
|
252
|
+
payload: { name: 'Error', message: 'Generic error' },
|
|
253
|
+
};
|
|
254
|
+
// Act
|
|
255
|
+
const tags = await service.autoTag(entry);
|
|
256
|
+
// Assert
|
|
257
|
+
// ERROR tag is added for all exceptions, but 'ERROR' as exception name should not be duplicated
|
|
258
|
+
expect(tags).toContain('ERROR'); // This is the standard exception tag
|
|
259
|
+
expect(tags.filter(t => t === 'ERROR')).toHaveLength(1); // Should only appear once
|
|
260
|
+
});
|
|
261
|
+
it('should add HTTP-ERROR tag for HTTP exceptions', async () => {
|
|
262
|
+
// Arrange
|
|
263
|
+
const entry = {
|
|
264
|
+
id: 1,
|
|
265
|
+
type: 'exception',
|
|
266
|
+
payload: { name: 'HttpException', message: 'Not found' },
|
|
267
|
+
};
|
|
268
|
+
// Act
|
|
269
|
+
const tags = await service.autoTag(entry);
|
|
270
|
+
// Assert
|
|
271
|
+
expect(tags).toContain('HTTP-ERROR');
|
|
272
|
+
});
|
|
273
|
+
it('should add VALIDATION-ERROR tag for validation errors', async () => {
|
|
274
|
+
// Arrange
|
|
275
|
+
const entry = {
|
|
276
|
+
id: 1,
|
|
277
|
+
type: 'exception',
|
|
278
|
+
payload: { name: 'ValidationError', message: 'Invalid input' },
|
|
279
|
+
};
|
|
280
|
+
// Act
|
|
281
|
+
const tags = await service.autoTag(entry);
|
|
282
|
+
// Assert
|
|
283
|
+
expect(tags).toContain('VALIDATION-ERROR');
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
describe('Log Tags', () => {
|
|
287
|
+
it('should add level tag', async () => {
|
|
288
|
+
// Arrange
|
|
289
|
+
const entry = {
|
|
290
|
+
id: 1,
|
|
291
|
+
type: 'log',
|
|
292
|
+
payload: { level: 'warn', message: 'Warning message' },
|
|
293
|
+
};
|
|
294
|
+
// Act
|
|
295
|
+
const tags = await service.autoTag(entry);
|
|
296
|
+
// Assert
|
|
297
|
+
expect(tags).toContain('WARN');
|
|
298
|
+
});
|
|
299
|
+
it('should add ERROR tag for error level', async () => {
|
|
300
|
+
// Arrange
|
|
301
|
+
const entry = {
|
|
302
|
+
id: 1,
|
|
303
|
+
type: 'log',
|
|
304
|
+
payload: { level: 'error', message: 'Error message' },
|
|
305
|
+
};
|
|
306
|
+
// Act
|
|
307
|
+
const tags = await service.autoTag(entry);
|
|
308
|
+
// Assert
|
|
309
|
+
expect(tags).toContain('ERROR');
|
|
310
|
+
});
|
|
311
|
+
it('should add WARNING tag for warn level', async () => {
|
|
312
|
+
// Arrange
|
|
313
|
+
const entry = {
|
|
314
|
+
id: 1,
|
|
315
|
+
type: 'log',
|
|
316
|
+
payload: { level: 'warn', message: 'Warning message' },
|
|
317
|
+
};
|
|
318
|
+
// Act
|
|
319
|
+
const tags = await service.autoTag(entry);
|
|
320
|
+
// Assert
|
|
321
|
+
expect(tags).toContain('WARNING');
|
|
322
|
+
});
|
|
323
|
+
it('should add context tag', async () => {
|
|
324
|
+
// Arrange
|
|
325
|
+
const entry = {
|
|
326
|
+
id: 1,
|
|
327
|
+
type: 'log',
|
|
328
|
+
payload: { level: 'log', message: 'Message', context: 'UserService' },
|
|
329
|
+
};
|
|
330
|
+
// Act
|
|
331
|
+
const tags = await service.autoTag(entry);
|
|
332
|
+
// Assert
|
|
333
|
+
expect(tags).toContain('USERSERVICE');
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
describe('Job Tags', () => {
|
|
337
|
+
it('should add status tag', async () => {
|
|
338
|
+
// Arrange
|
|
339
|
+
const entry = {
|
|
340
|
+
id: 1,
|
|
341
|
+
type: 'job',
|
|
342
|
+
payload: { name: 'SendEmail', status: 'completed' },
|
|
343
|
+
};
|
|
344
|
+
// Act
|
|
345
|
+
const tags = await service.autoTag(entry);
|
|
346
|
+
// Assert
|
|
347
|
+
expect(tags).toContain('COMPLETED');
|
|
348
|
+
});
|
|
349
|
+
it('should add queue tag', async () => {
|
|
350
|
+
// Arrange
|
|
351
|
+
const entry = {
|
|
352
|
+
id: 1,
|
|
353
|
+
type: 'job',
|
|
354
|
+
payload: { name: 'SendEmail', status: 'active', queue: 'email-queue' },
|
|
355
|
+
};
|
|
356
|
+
// Act
|
|
357
|
+
const tags = await service.autoTag(entry);
|
|
358
|
+
// Assert
|
|
359
|
+
expect(tags).toContain('EMAIL-QUEUE');
|
|
360
|
+
});
|
|
361
|
+
it('should add ERROR tag for failed jobs', async () => {
|
|
362
|
+
// Arrange
|
|
363
|
+
const entry = {
|
|
364
|
+
id: 1,
|
|
365
|
+
type: 'job',
|
|
366
|
+
payload: { name: 'SendEmail', status: 'failed' },
|
|
367
|
+
};
|
|
368
|
+
// Act
|
|
369
|
+
const tags = await service.autoTag(entry);
|
|
370
|
+
// Assert
|
|
371
|
+
expect(tags).toContain('ERROR');
|
|
372
|
+
expect(tags).toContain('FAILED');
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
describe('Cache Tags', () => {
|
|
376
|
+
it('should add operation tag', async () => {
|
|
377
|
+
// Arrange
|
|
378
|
+
const entry = {
|
|
379
|
+
id: 1,
|
|
380
|
+
type: 'cache',
|
|
381
|
+
payload: { key: 'user:1', operation: 'set' },
|
|
382
|
+
};
|
|
383
|
+
// Act
|
|
384
|
+
const tags = await service.autoTag(entry);
|
|
385
|
+
// Assert
|
|
386
|
+
expect(tags).toContain('SET');
|
|
387
|
+
});
|
|
388
|
+
it('should add HIT tag for cache hit', async () => {
|
|
389
|
+
// Arrange
|
|
390
|
+
const entry = {
|
|
391
|
+
id: 1,
|
|
392
|
+
type: 'cache',
|
|
393
|
+
payload: { key: 'user:1', operation: 'get', hit: true },
|
|
394
|
+
};
|
|
395
|
+
// Act
|
|
396
|
+
const tags = await service.autoTag(entry);
|
|
397
|
+
// Assert
|
|
398
|
+
expect(tags).toContain('HIT');
|
|
399
|
+
});
|
|
400
|
+
it('should add MISS tag for cache miss', async () => {
|
|
401
|
+
// Arrange
|
|
402
|
+
const entry = {
|
|
403
|
+
id: 1,
|
|
404
|
+
type: 'cache',
|
|
405
|
+
payload: { key: 'user:1', operation: 'get', hit: false },
|
|
406
|
+
};
|
|
407
|
+
// Act
|
|
408
|
+
const tags = await service.autoTag(entry);
|
|
409
|
+
// Assert
|
|
410
|
+
expect(tags).toContain('MISS');
|
|
411
|
+
});
|
|
412
|
+
});
|
|
413
|
+
describe('Event Tags', () => {
|
|
414
|
+
it('should add event name tag', async () => {
|
|
415
|
+
// Arrange
|
|
416
|
+
const entry = {
|
|
417
|
+
id: 1,
|
|
418
|
+
type: 'event',
|
|
419
|
+
payload: { name: 'user.created', listeners: ['Handler1'] },
|
|
420
|
+
};
|
|
421
|
+
// Act
|
|
422
|
+
const tags = await service.autoTag(entry);
|
|
423
|
+
// Assert
|
|
424
|
+
expect(tags).toContain('USER.CREATED');
|
|
425
|
+
});
|
|
426
|
+
it('should add MULTI-LISTENER tag for multiple listeners', async () => {
|
|
427
|
+
// Arrange
|
|
428
|
+
const entry = {
|
|
429
|
+
id: 1,
|
|
430
|
+
type: 'event',
|
|
431
|
+
payload: { name: 'user.created', listeners: ['Handler1', 'Handler2'] },
|
|
432
|
+
};
|
|
433
|
+
// Act
|
|
434
|
+
const tags = await service.autoTag(entry);
|
|
435
|
+
// Assert
|
|
436
|
+
expect(tags).toContain('MULTI-LISTENER');
|
|
437
|
+
});
|
|
438
|
+
it('should add SLOW tag for slow events', async () => {
|
|
439
|
+
// Arrange
|
|
440
|
+
const entry = {
|
|
441
|
+
id: 1,
|
|
442
|
+
type: 'event',
|
|
443
|
+
payload: { name: 'user.created', payload: {}, listeners: [], duration: 150 },
|
|
444
|
+
};
|
|
445
|
+
// Act
|
|
446
|
+
const tags = await service.autoTag(entry);
|
|
447
|
+
// Assert
|
|
448
|
+
expect(tags).toContain('SLOW');
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
describe('Schedule Tags', () => {
|
|
452
|
+
it('should add status tag', async () => {
|
|
453
|
+
// Arrange
|
|
454
|
+
const entry = {
|
|
455
|
+
id: 1,
|
|
456
|
+
type: 'schedule',
|
|
457
|
+
payload: { name: 'CleanupTask', status: 'completed' },
|
|
458
|
+
};
|
|
459
|
+
// Act
|
|
460
|
+
const tags = await service.autoTag(entry);
|
|
461
|
+
// Assert
|
|
462
|
+
expect(tags).toContain('COMPLETED');
|
|
463
|
+
});
|
|
464
|
+
it('should add CRON tag for cron schedules', async () => {
|
|
465
|
+
// Arrange
|
|
466
|
+
const entry = {
|
|
467
|
+
id: 1,
|
|
468
|
+
type: 'schedule',
|
|
469
|
+
payload: { name: 'CleanupTask', status: 'completed', cron: '0 * * * *' },
|
|
470
|
+
};
|
|
471
|
+
// Act
|
|
472
|
+
const tags = await service.autoTag(entry);
|
|
473
|
+
// Assert
|
|
474
|
+
expect(tags).toContain('CRON');
|
|
475
|
+
});
|
|
476
|
+
it('should add INTERVAL tag for interval schedules', async () => {
|
|
477
|
+
// Arrange
|
|
478
|
+
const entry = {
|
|
479
|
+
id: 1,
|
|
480
|
+
type: 'schedule',
|
|
481
|
+
payload: { name: 'HealthCheck', status: 'started', interval: 60000 },
|
|
482
|
+
};
|
|
483
|
+
// Act
|
|
484
|
+
const tags = await service.autoTag(entry);
|
|
485
|
+
// Assert
|
|
486
|
+
expect(tags).toContain('INTERVAL');
|
|
487
|
+
});
|
|
488
|
+
});
|
|
489
|
+
describe('Mail Tags', () => {
|
|
490
|
+
it('should add status tag', async () => {
|
|
491
|
+
// Arrange
|
|
492
|
+
const entry = {
|
|
493
|
+
id: 1,
|
|
494
|
+
type: 'mail',
|
|
495
|
+
payload: { to: 'user@example.com', subject: 'Test', status: 'sent' },
|
|
496
|
+
};
|
|
497
|
+
// Act
|
|
498
|
+
const tags = await service.autoTag(entry);
|
|
499
|
+
// Assert
|
|
500
|
+
expect(tags).toContain('SENT');
|
|
501
|
+
});
|
|
502
|
+
it('should add BULK tag for multiple recipients', async () => {
|
|
503
|
+
// Arrange
|
|
504
|
+
const entry = {
|
|
505
|
+
id: 1,
|
|
506
|
+
type: 'mail',
|
|
507
|
+
payload: { to: ['user1@example.com', 'user2@example.com'], subject: 'Test', status: 'sent' },
|
|
508
|
+
};
|
|
509
|
+
// Act
|
|
510
|
+
const tags = await service.autoTag(entry);
|
|
511
|
+
// Assert
|
|
512
|
+
expect(tags).toContain('BULK');
|
|
513
|
+
});
|
|
514
|
+
it('should add HTML tag for HTML emails', async () => {
|
|
515
|
+
// Arrange
|
|
516
|
+
const entry = {
|
|
517
|
+
id: 1,
|
|
518
|
+
type: 'mail',
|
|
519
|
+
payload: { to: 'user@example.com', subject: 'Test', status: 'sent', html: '<p>Hello</p>' },
|
|
520
|
+
};
|
|
521
|
+
// Act
|
|
522
|
+
const tags = await service.autoTag(entry);
|
|
523
|
+
// Assert
|
|
524
|
+
expect(tags).toContain('HTML');
|
|
525
|
+
});
|
|
526
|
+
});
|
|
527
|
+
describe('HTTP Client Tags', () => {
|
|
528
|
+
it('should add method tag', async () => {
|
|
529
|
+
// Arrange
|
|
530
|
+
const entry = {
|
|
531
|
+
id: 1,
|
|
532
|
+
type: 'http-client',
|
|
533
|
+
payload: { method: 'POST', url: 'https://api.example.com/users', statusCode: 201 },
|
|
534
|
+
};
|
|
535
|
+
// Act
|
|
536
|
+
const tags = await service.autoTag(entry);
|
|
537
|
+
// Assert
|
|
538
|
+
expect(tags).toContain('POST');
|
|
539
|
+
});
|
|
540
|
+
it('should add hostname tag', async () => {
|
|
541
|
+
// Arrange
|
|
542
|
+
const entry = {
|
|
543
|
+
id: 1,
|
|
544
|
+
type: 'http-client',
|
|
545
|
+
payload: { method: 'GET', url: 'https://api.example.com', hostname: 'api.example.com', statusCode: 200 },
|
|
546
|
+
};
|
|
547
|
+
// Act
|
|
548
|
+
const tags = await service.autoTag(entry);
|
|
549
|
+
// Assert
|
|
550
|
+
expect(tags).toContain('API.EXAMPLE.COM');
|
|
551
|
+
});
|
|
552
|
+
});
|
|
553
|
+
describe('Redis Tags', () => {
|
|
554
|
+
it('should add command tag', async () => {
|
|
555
|
+
// Arrange
|
|
556
|
+
const entry = {
|
|
557
|
+
id: 1,
|
|
558
|
+
type: 'redis',
|
|
559
|
+
payload: { command: 'SET', args: ['user:1', 'value'], duration: 5, status: 'success' },
|
|
560
|
+
};
|
|
561
|
+
// Act
|
|
562
|
+
const tags = await service.autoTag(entry);
|
|
563
|
+
// Assert
|
|
564
|
+
expect(tags).toContain('SET');
|
|
565
|
+
});
|
|
566
|
+
it('should add ERROR tag for errors', async () => {
|
|
567
|
+
// Arrange
|
|
568
|
+
const entry = {
|
|
569
|
+
id: 1,
|
|
570
|
+
type: 'redis',
|
|
571
|
+
payload: { command: 'GET', args: ['user:1'], status: 'error', duration: 5 },
|
|
572
|
+
};
|
|
573
|
+
// Act
|
|
574
|
+
const tags = await service.autoTag(entry);
|
|
575
|
+
// Assert
|
|
576
|
+
expect(tags).toContain('ERROR');
|
|
577
|
+
});
|
|
578
|
+
it('should add SLOW tag for slow commands', async () => {
|
|
579
|
+
// Arrange
|
|
580
|
+
const entry = {
|
|
581
|
+
id: 1,
|
|
582
|
+
type: 'redis',
|
|
583
|
+
payload: { command: 'GET', args: ['user:1'], duration: 150, status: 'success' },
|
|
584
|
+
};
|
|
585
|
+
// Act
|
|
586
|
+
const tags = await service.autoTag(entry);
|
|
587
|
+
// Assert
|
|
588
|
+
expect(tags).toContain('SLOW');
|
|
589
|
+
});
|
|
590
|
+
});
|
|
591
|
+
describe('Model Tags', () => {
|
|
592
|
+
it('should add entity tag', async () => {
|
|
593
|
+
// Arrange
|
|
594
|
+
const entry = {
|
|
595
|
+
id: 1,
|
|
596
|
+
type: 'model',
|
|
597
|
+
payload: { entity: 'User', action: 'create', duration: 10 },
|
|
598
|
+
};
|
|
599
|
+
// Act
|
|
600
|
+
const tags = await service.autoTag(entry);
|
|
601
|
+
// Assert
|
|
602
|
+
expect(tags).toContain('USER');
|
|
603
|
+
});
|
|
604
|
+
it('should add action tag', async () => {
|
|
605
|
+
// Arrange
|
|
606
|
+
const entry = {
|
|
607
|
+
id: 1,
|
|
608
|
+
type: 'model',
|
|
609
|
+
payload: { entity: 'User', action: 'update', duration: 10 },
|
|
610
|
+
};
|
|
611
|
+
// Act
|
|
612
|
+
const tags = await service.autoTag(entry);
|
|
613
|
+
// Assert
|
|
614
|
+
expect(tags).toContain('UPDATE');
|
|
615
|
+
});
|
|
616
|
+
it('should add BULK tag for multiple records', async () => {
|
|
617
|
+
// Arrange
|
|
618
|
+
const entry = {
|
|
619
|
+
id: 1,
|
|
620
|
+
type: 'model',
|
|
621
|
+
payload: { entity: 'User', action: 'find', recordCount: 100, duration: 10 },
|
|
622
|
+
};
|
|
623
|
+
// Act
|
|
624
|
+
const tags = await service.autoTag(entry);
|
|
625
|
+
// Assert
|
|
626
|
+
expect(tags).toContain('BULK');
|
|
627
|
+
});
|
|
628
|
+
});
|
|
629
|
+
describe('Notification Tags', () => {
|
|
630
|
+
it('should add type tag', async () => {
|
|
631
|
+
// Arrange
|
|
632
|
+
const entry = {
|
|
633
|
+
id: 1,
|
|
634
|
+
type: 'notification',
|
|
635
|
+
payload: { type: 'email', status: 'sent', recipient: 'user@example.com' },
|
|
636
|
+
};
|
|
637
|
+
// Act
|
|
638
|
+
const tags = await service.autoTag(entry);
|
|
639
|
+
// Assert
|
|
640
|
+
expect(tags).toContain('EMAIL');
|
|
641
|
+
});
|
|
642
|
+
it('should add BULK tag for multiple recipients', async () => {
|
|
643
|
+
// Arrange
|
|
644
|
+
const entry = {
|
|
645
|
+
id: 1,
|
|
646
|
+
type: 'notification',
|
|
647
|
+
payload: { type: 'push', status: 'sent', recipient: ['user1', 'user2'] },
|
|
648
|
+
};
|
|
649
|
+
// Act
|
|
650
|
+
const tags = await service.autoTag(entry);
|
|
651
|
+
// Assert
|
|
652
|
+
expect(tags).toContain('BULK');
|
|
653
|
+
});
|
|
654
|
+
});
|
|
655
|
+
describe('View Tags', () => {
|
|
656
|
+
it('should add template name tag', async () => {
|
|
657
|
+
// Arrange
|
|
658
|
+
const entry = {
|
|
659
|
+
id: 1,
|
|
660
|
+
type: 'view',
|
|
661
|
+
payload: { template: 'users/profile.html', format: 'html', duration: 10 },
|
|
662
|
+
};
|
|
663
|
+
// Act
|
|
664
|
+
const tags = await service.autoTag(entry);
|
|
665
|
+
// Assert
|
|
666
|
+
expect(tags).toContain('USERS.PROFILE');
|
|
667
|
+
});
|
|
668
|
+
it('should add format tag', async () => {
|
|
669
|
+
// Arrange
|
|
670
|
+
const entry = {
|
|
671
|
+
id: 1,
|
|
672
|
+
type: 'view',
|
|
673
|
+
payload: { template: 'report', format: 'pdf', duration: 100 },
|
|
674
|
+
};
|
|
675
|
+
// Act
|
|
676
|
+
const tags = await service.autoTag(entry);
|
|
677
|
+
// Assert
|
|
678
|
+
expect(tags).toContain('PDF');
|
|
679
|
+
});
|
|
680
|
+
it('should add CACHED tag for cache hits', async () => {
|
|
681
|
+
// Arrange
|
|
682
|
+
const entry = {
|
|
683
|
+
id: 1,
|
|
684
|
+
type: 'view',
|
|
685
|
+
payload: { template: 'home', format: 'html', cacheHit: true, duration: 1 },
|
|
686
|
+
};
|
|
687
|
+
// Act
|
|
688
|
+
const tags = await service.autoTag(entry);
|
|
689
|
+
// Assert
|
|
690
|
+
expect(tags).toContain('CACHED');
|
|
691
|
+
});
|
|
692
|
+
});
|
|
693
|
+
describe('Command Tags', () => {
|
|
694
|
+
it('should add command name tag', async () => {
|
|
695
|
+
// Arrange
|
|
696
|
+
const entry = {
|
|
697
|
+
id: 1,
|
|
698
|
+
type: 'command',
|
|
699
|
+
payload: { name: 'CreateUser', status: 'completed' },
|
|
700
|
+
};
|
|
701
|
+
// Act
|
|
702
|
+
const tags = await service.autoTag(entry);
|
|
703
|
+
// Assert
|
|
704
|
+
expect(tags).toContain('CREATEUSER');
|
|
705
|
+
});
|
|
706
|
+
it('should add SLOW tag for slow commands', async () => {
|
|
707
|
+
// Arrange
|
|
708
|
+
const entry = {
|
|
709
|
+
id: 1,
|
|
710
|
+
type: 'command',
|
|
711
|
+
payload: { name: 'CreateUser', status: 'completed', duration: 1500 },
|
|
712
|
+
};
|
|
713
|
+
// Act
|
|
714
|
+
const tags = await service.autoTag(entry);
|
|
715
|
+
// Assert
|
|
716
|
+
expect(tags).toContain('SLOW');
|
|
717
|
+
});
|
|
718
|
+
});
|
|
719
|
+
describe('Gate Tags', () => {
|
|
720
|
+
it('should add ALLOWED tag when allowed', async () => {
|
|
721
|
+
// Arrange
|
|
722
|
+
const entry = {
|
|
723
|
+
id: 1,
|
|
724
|
+
type: 'gate',
|
|
725
|
+
payload: { gate: 'CanEdit', action: 'edit', allowed: true },
|
|
726
|
+
};
|
|
727
|
+
// Act
|
|
728
|
+
const tags = await service.autoTag(entry);
|
|
729
|
+
// Assert
|
|
730
|
+
expect(tags).toContain('ALLOWED');
|
|
731
|
+
});
|
|
732
|
+
it('should add DENIED tag when denied', async () => {
|
|
733
|
+
// Arrange
|
|
734
|
+
const entry = {
|
|
735
|
+
id: 1,
|
|
736
|
+
type: 'gate',
|
|
737
|
+
payload: { gate: 'CanDelete', action: 'delete', allowed: false },
|
|
738
|
+
};
|
|
739
|
+
// Act
|
|
740
|
+
const tags = await service.autoTag(entry);
|
|
741
|
+
// Assert
|
|
742
|
+
expect(tags).toContain('DENIED');
|
|
743
|
+
});
|
|
744
|
+
it('should add gate name tag', async () => {
|
|
745
|
+
// Arrange
|
|
746
|
+
const entry = {
|
|
747
|
+
id: 1,
|
|
748
|
+
type: 'gate',
|
|
749
|
+
payload: { gate: 'CanEdit', action: 'edit', allowed: true },
|
|
750
|
+
};
|
|
751
|
+
// Act
|
|
752
|
+
const tags = await service.autoTag(entry);
|
|
753
|
+
// Assert
|
|
754
|
+
expect(tags).toContain('CANEDIT');
|
|
755
|
+
});
|
|
756
|
+
});
|
|
757
|
+
describe('Batch Tags', () => {
|
|
758
|
+
it('should add status tag', async () => {
|
|
759
|
+
// Arrange
|
|
760
|
+
const entry = {
|
|
761
|
+
id: 1,
|
|
762
|
+
type: 'batch',
|
|
763
|
+
payload: { name: 'ImportUsers', status: 'completed', totalItems: 100, failedItems: 0 },
|
|
764
|
+
};
|
|
765
|
+
// Act
|
|
766
|
+
const tags = await service.autoTag(entry);
|
|
767
|
+
// Assert
|
|
768
|
+
expect(tags).toContain('COMPLETED');
|
|
769
|
+
});
|
|
770
|
+
it('should add LARGE tag for batches > 1000 items', async () => {
|
|
771
|
+
// Arrange
|
|
772
|
+
const entry = {
|
|
773
|
+
id: 1,
|
|
774
|
+
type: 'batch',
|
|
775
|
+
payload: { name: 'ImportUsers', status: 'completed', totalItems: 5000, failedItems: 0 },
|
|
776
|
+
};
|
|
777
|
+
// Act
|
|
778
|
+
const tags = await service.autoTag(entry);
|
|
779
|
+
// Assert
|
|
780
|
+
expect(tags).toContain('LARGE');
|
|
781
|
+
});
|
|
782
|
+
it('should add ERROR tag when failedItems > 0', async () => {
|
|
783
|
+
// Arrange
|
|
784
|
+
const entry = {
|
|
785
|
+
id: 1,
|
|
786
|
+
type: 'batch',
|
|
787
|
+
payload: { name: 'ImportUsers', status: 'partial', totalItems: 100, failedItems: 5 },
|
|
788
|
+
};
|
|
789
|
+
// Act
|
|
790
|
+
const tags = await service.autoTag(entry);
|
|
791
|
+
// Assert
|
|
792
|
+
expect(tags).toContain('ERROR');
|
|
793
|
+
});
|
|
794
|
+
});
|
|
795
|
+
describe('Dump Tags', () => {
|
|
796
|
+
it('should add operation tag', async () => {
|
|
797
|
+
// Arrange
|
|
798
|
+
const entry = {
|
|
799
|
+
id: 1,
|
|
800
|
+
type: 'dump',
|
|
801
|
+
payload: { operation: 'export', format: 'sql', status: 'completed' },
|
|
802
|
+
};
|
|
803
|
+
// Act
|
|
804
|
+
const tags = await service.autoTag(entry);
|
|
805
|
+
// Assert
|
|
806
|
+
expect(tags).toContain('EXPORT');
|
|
807
|
+
});
|
|
808
|
+
it('should add format tag', async () => {
|
|
809
|
+
// Arrange
|
|
810
|
+
const entry = {
|
|
811
|
+
id: 1,
|
|
812
|
+
type: 'dump',
|
|
813
|
+
payload: { operation: 'backup', format: 'json', status: 'completed' },
|
|
814
|
+
};
|
|
815
|
+
// Act
|
|
816
|
+
const tags = await service.autoTag(entry);
|
|
817
|
+
// Assert
|
|
818
|
+
expect(tags).toContain('JSON');
|
|
819
|
+
});
|
|
820
|
+
it('should add COMPRESSED tag', async () => {
|
|
821
|
+
// Arrange
|
|
822
|
+
const entry = {
|
|
823
|
+
id: 1,
|
|
824
|
+
type: 'dump',
|
|
825
|
+
payload: { operation: 'backup', format: 'sql', compressed: true, status: 'completed' },
|
|
826
|
+
};
|
|
827
|
+
// Act
|
|
828
|
+
const tags = await service.autoTag(entry);
|
|
829
|
+
// Assert
|
|
830
|
+
expect(tags).toContain('COMPRESSED');
|
|
831
|
+
});
|
|
832
|
+
it('should add ENCRYPTED tag', async () => {
|
|
833
|
+
// Arrange
|
|
834
|
+
const entry = {
|
|
835
|
+
id: 1,
|
|
836
|
+
type: 'dump',
|
|
837
|
+
payload: { operation: 'backup', format: 'sql', encrypted: true, status: 'completed' },
|
|
838
|
+
};
|
|
839
|
+
// Act
|
|
840
|
+
const tags = await service.autoTag(entry);
|
|
841
|
+
// Assert
|
|
842
|
+
expect(tags).toContain('ENCRYPTED');
|
|
843
|
+
});
|
|
844
|
+
});
|
|
845
|
+
describe('Entry without ID', () => {
|
|
846
|
+
it('should not call storage.addTags when entry has no id', async () => {
|
|
847
|
+
// Arrange
|
|
848
|
+
const entry = {
|
|
849
|
+
type: 'request',
|
|
850
|
+
payload: { statusCode: 200, method: 'GET', path: '/test' },
|
|
851
|
+
};
|
|
852
|
+
// Act
|
|
853
|
+
await service.autoTag(entry);
|
|
854
|
+
// Assert
|
|
855
|
+
expect(mockStorage.addTags).not.toHaveBeenCalled();
|
|
856
|
+
});
|
|
857
|
+
});
|
|
858
|
+
});
|
|
859
|
+
describe('Tag Management', () => {
|
|
860
|
+
describe('addTags', () => {
|
|
861
|
+
it('should call storage.addTags', async () => {
|
|
862
|
+
// Act
|
|
863
|
+
await service.addTags(1, ['tag1', 'tag2']);
|
|
864
|
+
// Assert
|
|
865
|
+
expect(mockStorage.addTags).toHaveBeenCalledWith(1, ['tag1', 'tag2']);
|
|
866
|
+
});
|
|
867
|
+
});
|
|
868
|
+
describe('removeTags', () => {
|
|
869
|
+
it('should call storage.removeTags', async () => {
|
|
870
|
+
// Act
|
|
871
|
+
await service.removeTags(1, ['tag1']);
|
|
872
|
+
// Assert
|
|
873
|
+
expect(mockStorage.removeTags).toHaveBeenCalledWith(1, ['tag1']);
|
|
874
|
+
});
|
|
875
|
+
});
|
|
876
|
+
describe('getEntryTags', () => {
|
|
877
|
+
it('should return tags from storage', async () => {
|
|
878
|
+
// Arrange
|
|
879
|
+
mockStorage.getEntryTags.mockResolvedValue(['ERROR', 'SLOW']);
|
|
880
|
+
// Act
|
|
881
|
+
const result = await service.getEntryTags(1);
|
|
882
|
+
// Assert
|
|
883
|
+
expect(result).toEqual(['ERROR', 'SLOW']);
|
|
884
|
+
expect(mockStorage.getEntryTags).toHaveBeenCalledWith(1);
|
|
885
|
+
});
|
|
886
|
+
});
|
|
887
|
+
describe('getAllTags', () => {
|
|
888
|
+
it('should return all tags with counts', async () => {
|
|
889
|
+
// Arrange
|
|
890
|
+
const tags = [
|
|
891
|
+
{ tag: 'ERROR', count: 50 },
|
|
892
|
+
{ tag: 'SUCCESS', count: 100 },
|
|
893
|
+
];
|
|
894
|
+
mockStorage.getAllTags.mockResolvedValue(tags);
|
|
895
|
+
// Act
|
|
896
|
+
const result = await service.getAllTags();
|
|
897
|
+
// Assert
|
|
898
|
+
expect(result).toEqual(tags);
|
|
899
|
+
});
|
|
900
|
+
});
|
|
901
|
+
describe('findByTags', () => {
|
|
902
|
+
it('should call storage.findByTags with default params', async () => {
|
|
903
|
+
// Arrange
|
|
904
|
+
mockStorage.findByTags.mockResolvedValue([]);
|
|
905
|
+
// Act
|
|
906
|
+
await service.findByTags(['ERROR']);
|
|
907
|
+
// Assert
|
|
908
|
+
expect(mockStorage.findByTags).toHaveBeenCalledWith(['ERROR'], 'OR', 50);
|
|
909
|
+
});
|
|
910
|
+
it('should pass custom logic and limit', async () => {
|
|
911
|
+
// Arrange
|
|
912
|
+
mockStorage.findByTags.mockResolvedValue([]);
|
|
913
|
+
// Act
|
|
914
|
+
await service.findByTags(['ERROR', 'SLOW'], 'AND', 100);
|
|
915
|
+
// Assert
|
|
916
|
+
expect(mockStorage.findByTags).toHaveBeenCalledWith(['ERROR', 'SLOW'], 'AND', 100);
|
|
917
|
+
});
|
|
918
|
+
});
|
|
919
|
+
});
|
|
920
|
+
describe('Monitored Tags', () => {
|
|
921
|
+
describe('addMonitoredTag', () => {
|
|
922
|
+
it('should call storage.addMonitoredTag', async () => {
|
|
923
|
+
// Arrange
|
|
924
|
+
const monitoredTag = { id: 1, tag: 'CRITICAL', createdAt: new Date().toISOString() };
|
|
925
|
+
mockStorage.addMonitoredTag.mockResolvedValue(monitoredTag);
|
|
926
|
+
// Act
|
|
927
|
+
const result = await service.addMonitoredTag('CRITICAL');
|
|
928
|
+
// Assert
|
|
929
|
+
expect(mockStorage.addMonitoredTag).toHaveBeenCalledWith('CRITICAL');
|
|
930
|
+
expect(result).toEqual(monitoredTag);
|
|
931
|
+
});
|
|
932
|
+
});
|
|
933
|
+
describe('removeMonitoredTag', () => {
|
|
934
|
+
it('should call storage.removeMonitoredTag', async () => {
|
|
935
|
+
// Act
|
|
936
|
+
await service.removeMonitoredTag('CRITICAL');
|
|
937
|
+
// Assert
|
|
938
|
+
expect(mockStorage.removeMonitoredTag).toHaveBeenCalledWith('CRITICAL');
|
|
939
|
+
});
|
|
940
|
+
});
|
|
941
|
+
describe('getMonitoredTags', () => {
|
|
942
|
+
it('should return monitored tags from storage', async () => {
|
|
943
|
+
// Arrange
|
|
944
|
+
const tags = [
|
|
945
|
+
{ id: 1, tag: 'CRITICAL', createdAt: new Date().toISOString() },
|
|
946
|
+
{ id: 2, tag: 'ERROR', createdAt: new Date().toISOString() },
|
|
947
|
+
];
|
|
948
|
+
mockStorage.getMonitoredTags.mockResolvedValue(tags);
|
|
949
|
+
// Act
|
|
950
|
+
const result = await service.getMonitoredTags();
|
|
951
|
+
// Assert
|
|
952
|
+
expect(result).toEqual(tags);
|
|
953
|
+
});
|
|
954
|
+
});
|
|
955
|
+
describe('getMonitoredTagsWithCounts', () => {
|
|
956
|
+
it('should merge monitored tags with counts', async () => {
|
|
957
|
+
// Arrange
|
|
958
|
+
const monitoredTags = [
|
|
959
|
+
{ id: 1, tag: 'CRITICAL', createdAt: '2024-01-01' },
|
|
960
|
+
{ id: 2, tag: 'ERROR', createdAt: '2024-01-02' },
|
|
961
|
+
];
|
|
962
|
+
const allTags = [
|
|
963
|
+
{ tag: 'CRITICAL', count: 10 },
|
|
964
|
+
{ tag: 'ERROR', count: 50 },
|
|
965
|
+
{ tag: 'SUCCESS', count: 100 },
|
|
966
|
+
];
|
|
967
|
+
mockStorage.getMonitoredTags.mockResolvedValue(monitoredTags);
|
|
968
|
+
mockStorage.getAllTags.mockResolvedValue(allTags);
|
|
969
|
+
// Act
|
|
970
|
+
const result = await service.getMonitoredTagsWithCounts();
|
|
971
|
+
// Assert
|
|
972
|
+
expect(result).toEqual([
|
|
973
|
+
{ id: 1, tag: 'CRITICAL', createdAt: '2024-01-01', count: 10 },
|
|
974
|
+
{ id: 2, tag: 'ERROR', createdAt: '2024-01-02', count: 50 },
|
|
975
|
+
]);
|
|
976
|
+
});
|
|
977
|
+
it('should return 0 count for tags not found in allTags', async () => {
|
|
978
|
+
// Arrange
|
|
979
|
+
const monitoredTags = [
|
|
980
|
+
{ id: 1, tag: 'NEWTYPE', createdAt: '2024-01-01' },
|
|
981
|
+
];
|
|
982
|
+
mockStorage.getMonitoredTags.mockResolvedValue(monitoredTags);
|
|
983
|
+
mockStorage.getAllTags.mockResolvedValue([]);
|
|
984
|
+
// Act
|
|
985
|
+
const result = await service.getMonitoredTagsWithCounts();
|
|
986
|
+
// Assert
|
|
987
|
+
expect(result).toEqual([
|
|
988
|
+
{ id: 1, tag: 'NEWTYPE', createdAt: '2024-01-01', count: 0 },
|
|
989
|
+
]);
|
|
990
|
+
});
|
|
991
|
+
});
|
|
992
|
+
});
|
|
993
|
+
});
|
|
994
|
+
//# sourceMappingURL=tag.service.spec.js.map
|