tftsr-devops_investigation/node_modules/loglevel-plugin-prefix/test/test.js
Shaun Arman 8839075805 feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.

Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)

Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)

DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload

Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 22:36:25 -05:00

109 lines
2.8 KiB
JavaScript

const expect = require('chai').expect;
const loglevel = require('loglevel');
const other = require('loglevel-plugin-mock');
const sinon = require('sinon');
const prefix = require('../lib/loglevel-plugin-prefix');
const spy = sinon.spy();
loglevel.enableAll();
describe('API', () => {
it('Methods', () => {
expect(prefix).to.have.property('apply').with.be.a('function');
expect(prefix).to.have.property('reg').with.be.a('function');
expect(prefix).not.to.have.property('noConflict');
});
it('Reg: empty arguments', () => {
expect(prefix.reg).to.throw(TypeError, 'Argument is not a root logger');
});
it('Reg: incorrect argument', () => {
expect(() => prefix.reg('logger')).to.throw(TypeError, 'Argument is not a root logger');
});
it('Apply: empty arguments', () => {
expect(prefix.apply).to.throw(TypeError, 'Argument is not a logger');
});
it('Apply: incorrect argument', () => {
expect(() => prefix.apply('logger')).to.throw(TypeError, 'Argument is not a logger');
});
});
describe('Prefix', () => {
other.apply(loglevel, { method: spy });
beforeEach(() => {
spy.reset();
});
it('Root applying', () => {
expect(() => prefix.apply(loglevel)).to.not.throw();
});
it('Root reapplyng', () => {
prefix.apply(loglevel, { template: '%l (%n):' });
loglevel.info('test');
expect(spy.calledWith('INFO (root): test')).to.be.true;
});
it('Format', () => {
prefix.apply(loglevel, {
format: (level, logger) => `${level} (${logger}):`
});
loglevel.info('test');
expect(spy.calledWith('INFO (root): test')).to.be.true;
});
it('Unformat', () => {
prefix.apply(loglevel, { template: '%l:' });
loglevel.info('test');
expect(spy.calledWith('INFO: test')).to.be.true;
});
it('The prefix must be combined with the first argument, if it is a string', () => {
prefix.apply(loglevel, { template: '%l:' });
loglevel.info('foo %s', 'bar');
expect(spy.calledWith('INFO: foo %s', 'bar')).to.be.true;
});
it('All methods of the previous plugin should be called', () => {
prefix.apply(loglevel);
// for warn in apply
spy.reset();
loglevel.trace();
loglevel.debug();
loglevel.info();
loglevel.warn();
loglevel.error();
expect(spy.callCount).to.equal(5);
});
it('Child applying', () => {
const child = loglevel.getLogger('child');
prefix.apply(child, { template: '%l (%n):' });
child.info('test');
expect(spy.calledWith('INFO (child): test')).to.be.true;
});
it('Child reapplyng', () => {
const child = loglevel.getLogger('child');
prefix.apply(child, {
levelFormatter(level) {
return level;
}
});
child.info('test');
expect(spy.calledWith('info (child): test')).to.be.true;
});
});