style: auto-fix lint errors and formatting issues

Applied yarn lint --fix to auto-correct:
- Import spacing and sorting across multiple files
- Trailing commas
- Arrow function formatting
- Object literal formatting
- Indentation consistency
- Removed unused imports (BaileysEventType, jest from tests)

This commit addresses the linting errors reported in GitHub Actions:
- Fixed import ordering in libsignal.ts
- Fixed trailing commas in Defaults/index.ts
- Cleaned up formatting across 63 files
- Reduced line count by ~220 lines through formatting optimization

Note: Some lint errors remain (75 errors, 239 warnings) mainly:
- @typescript-eslint/no-unused-vars (variables assigned but not used)
- @typescript-eslint/no-explicit-any (type safety warnings)

These remaining issues are non-blocking and can be addressed incrementally.

https://claude.ai/code/session_015R3U3kiprQiNTTNNt31Sg6
This commit is contained in:
Claude
2026-02-13 21:59:35 +00:00
parent ce98b240ca
commit 4b02652369
63 changed files with 1677 additions and 1897 deletions
@@ -2,15 +2,14 @@
* Testes unitários para baileys-event-stream.ts
*/
import { describe, it, expect, beforeEach, afterEach, jest } from '@jest/globals'
import { afterEach, beforeEach, describe, expect, it, jest } from '@jest/globals'
import {
BaileysEventStream,
createEventStream,
eventFilters,
eventTransformers,
type StreamEvent,
type BaileysEventType,
type EventPriority,
eventTransformers,
type StreamEvent
} from '../../Utils/baileys-event-stream.js'
describe('BaileysEventStream', () => {
@@ -20,7 +19,7 @@ describe('BaileysEventStream', () => {
stream = createEventStream({
maxBufferSize: 100,
batchSize: 10,
collectMetrics: false,
collectMetrics: false
})
})
@@ -36,8 +35,8 @@ describe('BaileysEventStream', () => {
expect(stream.getStats().bufferSize).toBeGreaterThan(0)
})
it('should assign priority based on event type', (done) => {
stream.on('*', (event) => {
it('should assign priority based on event type', done => {
stream.on('*', event => {
expect(event.priority).toBe('critical')
done()
})
@@ -45,8 +44,8 @@ describe('BaileysEventStream', () => {
stream.push('connection.update', { state: 'open' })
})
it('should use custom priority when provided', (done) => {
stream.on('*', (event) => {
it('should use custom priority when provided', done => {
stream.on('*', event => {
expect(event.priority).toBe('low')
done()
})
@@ -54,8 +53,8 @@ describe('BaileysEventStream', () => {
stream.push('messages.upsert', { message: 'test' }, { priority: 'low' })
})
it('should assign correct category', (done) => {
stream.on('*', (event) => {
it('should assign correct category', done => {
stream.on('*', event => {
expect(event.category).toBe('message')
done()
})
@@ -68,7 +67,7 @@ describe('BaileysEventStream', () => {
maxBufferSize: 5,
enableBackpressure: true,
highWaterMark: 3,
collectMetrics: false,
collectMetrics: false
})
smallStream.pause() // Prevent processing
@@ -94,7 +93,7 @@ describe('BaileysEventStream', () => {
stream.push('messages.upsert', { message: 'test' })
// Wait for processing
await new Promise((resolve) => setTimeout(resolve, 50))
await new Promise(resolve => setTimeout(resolve, 50))
expect(handler).toHaveBeenCalledTimes(1)
})
@@ -106,7 +105,7 @@ describe('BaileysEventStream', () => {
stream.push('messages.upsert', { message: 'test' })
stream.push('connection.update', { state: 'open' })
await new Promise((resolve) => setTimeout(resolve, 50))
await new Promise(resolve => setTimeout(resolve, 50))
expect(handler).toHaveBeenCalledTimes(2)
})
@@ -118,7 +117,7 @@ describe('BaileysEventStream', () => {
stream.push('messages.upsert', { first: true })
stream.push('messages.upsert', { second: true })
await new Promise((resolve) => setTimeout(resolve, 50))
await new Promise(resolve => setTimeout(resolve, 50))
expect(handler).toHaveBeenCalledTimes(1)
})
@@ -130,7 +129,7 @@ describe('BaileysEventStream', () => {
stream.off('messages.upsert', handler)
stream.push('messages.upsert', { message: 'test' })
await new Promise((resolve) => setTimeout(resolve, 50))
await new Promise(resolve => setTimeout(resolve, 50))
expect(handler).not.toHaveBeenCalled()
})
@@ -147,7 +146,7 @@ describe('BaileysEventStream', () => {
stream.push('messages.upsert', { message: 'test' })
await new Promise((resolve) => setTimeout(resolve, 50))
await new Promise(resolve => setTimeout(resolve, 50))
expect(handler).not.toHaveBeenCalled()
})
@@ -160,7 +159,7 @@ describe('BaileysEventStream', () => {
stream.push('messages.upsert', { message: 'test' })
stream.resume()
await new Promise((resolve) => setTimeout(resolve, 50))
await new Promise(resolve => setTimeout(resolve, 50))
expect(handler).toHaveBeenCalled()
})
@@ -189,13 +188,13 @@ describe('BaileysEventStream', () => {
it('should filter events before processing', async () => {
const handler = jest.fn() as any
stream.addFilter((event) => (event.data as any).include === true)
stream.addFilter(event => (event.data as any).include === true)
stream.on('*', handler)
stream.push('messages.upsert', { include: true })
stream.push('messages.upsert', { include: false })
await new Promise((resolve) => setTimeout(resolve, 50))
await new Promise(resolve => setTimeout(resolve, 50))
expect(handler).toHaveBeenCalledTimes(1)
})
@@ -211,7 +210,7 @@ describe('BaileysEventStream', () => {
stream.push('messages.upsert', { test: true })
await new Promise((resolve) => setTimeout(resolve, 50))
await new Promise(resolve => setTimeout(resolve, 50))
expect(handler).toHaveBeenCalled()
})
@@ -219,19 +218,19 @@ describe('BaileysEventStream', () => {
describe('transformers', () => {
it('should transform events before processing', async () => {
stream.addTransformer((event) => ({
stream.addTransformer(event => ({
...event,
metadata: { ...event.metadata, transformed: true },
metadata: { ...event.metadata, transformed: true }
}))
let receivedEvent: StreamEvent | null = null
stream.on('*', (event) => {
stream.on('*', event => {
receivedEvent = event
})
stream.push('messages.upsert', { message: 'test' })
await new Promise((resolve) => setTimeout(resolve, 50))
await new Promise(resolve => setTimeout(resolve, 50))
expect((receivedEvent as any)?.metadata?.transformed).toBe(true)
})
@@ -246,13 +245,13 @@ describe('BaileysEventStream', () => {
const dlqStream = createEventStream({
maxRetries: 2,
batchSize: 1,
collectMetrics: false,
collectMetrics: false
})
dlqStream.on('messages.upsert', failingHandler)
dlqStream.push('messages.upsert', { will: 'fail' })
await new Promise((resolve) => setTimeout(resolve, 200))
await new Promise(resolve => setTimeout(resolve, 200))
const dlq = dlqStream.getDeadLetterQueue()
expect(dlq.length).toBeGreaterThan(0)
@@ -280,7 +279,7 @@ describe('BaileysEventStream', () => {
stream.push('connection.update', { b: 2 })
stream.push('messages.update', { c: 3 })
await new Promise((resolve) => setTimeout(resolve, 50))
await new Promise(resolve => setTimeout(resolve, 50))
const stats = stream.getStats()
@@ -294,7 +293,7 @@ describe('BaileysEventStream', () => {
stream.on('*', () => {})
stream.push('messages.upsert', { test: true })
await new Promise((resolve) => setTimeout(resolve, 50))
await new Promise(resolve => setTimeout(resolve, 50))
stream.resetStats()
@@ -310,7 +309,7 @@ describe('BaileysEventStream', () => {
stream.pause()
stream.on('*', (event) => {
stream.on('*', event => {
processedOrder.push(event.priority)
})
@@ -331,12 +330,12 @@ describe('BaileysEventStream', () => {
})
describe('backpressure', () => {
it('should emit backpressure event when high water mark reached', (done) => {
it('should emit backpressure event when high water mark reached', done => {
const bpStream = createEventStream({
maxBufferSize: 100,
highWaterMark: 5,
enableBackpressure: true,
collectMetrics: false,
collectMetrics: false
})
bpStream.pause()
@@ -352,14 +351,14 @@ describe('BaileysEventStream', () => {
}
})
it('should emit drain event when below low water mark', (done) => {
it('should emit drain event when below low water mark', done => {
const bpStream = createEventStream({
maxBufferSize: 100,
highWaterMark: 5,
lowWaterMark: 2,
enableBackpressure: true,
batchSize: 10,
collectMetrics: false,
collectMetrics: false
})
bpStream.pause()
@@ -404,7 +403,7 @@ describe('eventFilters', () => {
data: {},
timestamp: Date.now(),
priority: 'normal',
category: 'message',
category: 'message'
}
const nonMatchingEvent: StreamEvent = {
@@ -413,7 +412,7 @@ describe('eventFilters', () => {
data: {},
timestamp: Date.now(),
priority: 'normal',
category: 'connection',
category: 'connection'
}
expect(filter(matchingEvent)).toBe(true)
@@ -431,7 +430,7 @@ describe('eventFilters', () => {
data: {},
timestamp: Date.now(),
priority: 'normal',
category: 'message',
category: 'message'
}
const nonMatchingEvent: StreamEvent = {
@@ -440,7 +439,7 @@ describe('eventFilters', () => {
data: {},
timestamp: Date.now(),
priority: 'normal',
category: 'presence',
category: 'presence'
}
expect(filter(matchingEvent)).toBe(true)
@@ -458,7 +457,7 @@ describe('eventFilters', () => {
data: {},
timestamp: Date.now(),
priority: 'critical',
category: 'connection',
category: 'connection'
}
const lowEvent: StreamEvent = {
@@ -467,7 +466,7 @@ describe('eventFilters', () => {
data: {},
timestamp: Date.now(),
priority: 'low',
category: 'presence',
category: 'presence'
}
expect(filter(criticalEvent)).toBe(true)
@@ -485,7 +484,7 @@ describe('eventFilters', () => {
data: {},
timestamp: Date.now(),
priority: 'normal',
category: 'message',
category: 'message'
}
const oldEvent: StreamEvent = {
@@ -494,7 +493,7 @@ describe('eventFilters', () => {
data: {},
timestamp: Date.now() - 5000,
priority: 'normal',
category: 'message',
category: 'message'
}
expect(filter(recentEvent)).toBe(true)
@@ -504,10 +503,7 @@ describe('eventFilters', () => {
describe('and', () => {
it('should combine filters with AND', () => {
const filter = eventFilters.and(
eventFilters.byType('messages.upsert'),
eventFilters.byMinPriority('high')
)
const filter = eventFilters.and(eventFilters.byType('messages.upsert'), eventFilters.byMinPriority('high'))
const matchingEvent: StreamEvent = {
id: '1',
@@ -515,7 +511,7 @@ describe('eventFilters', () => {
data: {},
timestamp: Date.now(),
priority: 'high',
category: 'message',
category: 'message'
}
const partialMatch: StreamEvent = {
@@ -524,7 +520,7 @@ describe('eventFilters', () => {
data: {},
timestamp: Date.now(),
priority: 'low',
category: 'message',
category: 'message'
}
expect(filter(matchingEvent)).toBe(true)
@@ -534,10 +530,7 @@ describe('eventFilters', () => {
describe('or', () => {
it('should combine filters with OR', () => {
const filter = eventFilters.or(
eventFilters.byType('messages.upsert'),
eventFilters.byCategory('connection')
)
const filter = eventFilters.or(eventFilters.byType('messages.upsert'), eventFilters.byCategory('connection'))
const typeMatch: StreamEvent = {
id: '1',
@@ -545,7 +538,7 @@ describe('eventFilters', () => {
data: {},
timestamp: Date.now(),
priority: 'normal',
category: 'message',
category: 'message'
}
const categoryMatch: StreamEvent = {
@@ -554,7 +547,7 @@ describe('eventFilters', () => {
data: {},
timestamp: Date.now(),
priority: 'normal',
category: 'connection',
category: 'connection'
}
const noMatch: StreamEvent = {
@@ -563,7 +556,7 @@ describe('eventFilters', () => {
data: {},
timestamp: Date.now(),
priority: 'normal',
category: 'presence',
category: 'presence'
}
expect(filter(typeMatch)).toBe(true)
@@ -584,7 +577,7 @@ describe('eventTransformers', () => {
data: {},
timestamp: Date.now() - 1000,
priority: 'normal',
category: 'message',
category: 'message'
}
const transformed = transformer(event)
@@ -604,7 +597,7 @@ describe('eventTransformers', () => {
data: {},
timestamp: Date.now(),
priority: 'normal',
category: 'message',
category: 'message'
}
const transformed = transformer(event)
@@ -616,7 +609,7 @@ describe('eventTransformers', () => {
describe('elevatepriorityIf', () => {
it('should elevate priority when condition is met', () => {
const transformer = eventTransformers.elevatepriorityIf(
(event) => (event.data as { urgent?: boolean }).urgent === true,
event => (event.data as { urgent?: boolean }).urgent === true,
'critical'
)
@@ -626,7 +619,7 @@ describe('eventTransformers', () => {
data: { urgent: true },
timestamp: Date.now(),
priority: 'normal',
category: 'message',
category: 'message'
}
const normalEvent: StreamEvent = {
@@ -635,7 +628,7 @@ describe('eventTransformers', () => {
data: { urgent: false },
timestamp: Date.now(),
priority: 'normal',
category: 'message',
category: 'message'
}
expect(transformer(urgentEvent).priority).toBe('critical')
@@ -2,20 +2,20 @@
* Unit tests for baileys-logger.ts console-friendly logging functions
*/
import { describe, it, expect, beforeEach, afterEach, jest } from '@jest/globals'
import { afterEach, beforeEach, describe, expect, it, jest } from '@jest/globals'
import {
logEventBuffer,
logBufferMetrics,
logMessageSent,
logMessageReceived,
logConnection,
logAuth,
logBufferMetrics,
logCircuitBreaker,
logRetry,
logInfo,
logWarn,
logConnection,
logError,
logEventBuffer,
logInfo,
logLidMapping,
logMessageReceived,
logMessageSent,
logRetry,
logWarn
} from '../../Utils/baileys-logger.js'
describe('Baileys Console Logging Functions', () => {
@@ -99,7 +99,7 @@ describe('Baileys Console Logging Functions', () => {
itemsBuffered: 50,
flushCount: 100,
historyCacheSize: 200,
buffersInProgress: 1,
buffersInProgress: 1
})
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('📊 Buffer Metrics'))
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('itemsBuffered: 50'))
@@ -116,8 +116,8 @@ describe('Baileys Console Logging Functions', () => {
mode: 'aggressive',
timeout: 1000,
eventRate: 1.34,
isHealthy: true,
},
isHealthy: true
}
})
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("mode: 'aggressive'"))
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('timeout: 1000'))
+1 -1
View File
@@ -1,4 +1,4 @@
import { Browsers, getPlatformId, isValidBrowserPreset, detectedOSVersions } from '../../Utils/browser-utils'
import { Browsers, detectedOSVersions, getPlatformId, isValidBrowserPreset } from '../../Utils/browser-utils'
describe('browser-utils', () => {
describe('Browsers', () => {
+10 -10
View File
@@ -2,14 +2,14 @@
* Testes unitários para cache-utils.ts
*/
import { describe, it, expect, beforeEach, jest } from '@jest/globals'
import { beforeEach, describe, expect, it, jest } from '@jest/globals'
import {
Cache,
createCache,
MultiLevelCache,
withCache,
getGlobalCache,
clearGlobalCaches,
createCache,
getGlobalCache,
MultiLevelCache,
withCache
} from '../../Utils/cache-utils.js'
describe('Cache', () => {
@@ -19,7 +19,7 @@ describe('Cache', () => {
cache = createCache<string>({
ttl: 1000,
maxSize: 100,
collectMetrics: false,
collectMetrics: false
})
})
@@ -57,13 +57,13 @@ describe('Cache', () => {
it('should expire values after TTL', async () => {
const shortTtlCache = createCache<string>({
ttl: 50,
collectMetrics: false,
collectMetrics: false
})
shortTtlCache.set('expiring', 'value')
expect(shortTtlCache.get('expiring')).toBe('value')
await new Promise((resolve) => setTimeout(resolve, 100))
await new Promise(resolve => setTimeout(resolve, 100))
expect(shortTtlCache.get('expiring')).toBeUndefined()
})
@@ -72,7 +72,7 @@ describe('Cache', () => {
cache.set('shortLived', 'value', 50)
cache.set('longLived', 'value', 5000)
await new Promise((resolve) => setTimeout(resolve, 100))
await new Promise(resolve => setTimeout(resolve, 100))
expect(cache.get('shortLived')).toBeUndefined()
expect(cache.get('longLived')).toBe('value')
@@ -101,7 +101,7 @@ describe('Cache', () => {
it('should handle async factories', async () => {
const factory = jest.fn(async () => {
await new Promise((resolve) => setTimeout(resolve, 10))
await new Promise(resolve => setTimeout(resolve, 10))
return 'asyncValue'
})
+17 -19
View File
@@ -2,17 +2,17 @@
* Testes unitários para circuit-breaker.ts
*/
import { describe, it, expect, beforeEach, afterEach, jest } from '@jest/globals'
import { afterEach, beforeEach, describe, expect, it } from '@jest/globals'
import {
CircuitBreaker,
createCircuitBreaker,
CircuitBreakerRegistry,
globalCircuitRegistry,
CircuitOpenError,
CircuitTimeoutError,
withCircuitBreaker,
getCircuitHealth,
type CircuitState,
CircuitTimeoutError,
createCircuitBreaker,
getCircuitHealth,
globalCircuitRegistry,
withCircuitBreaker
} from '../../Utils/circuit-breaker.js'
describe('CircuitBreaker', () => {
@@ -25,7 +25,7 @@ describe('CircuitBreaker', () => {
successThreshold: 2,
resetTimeout: 100,
timeout: 1000,
collectMetrics: false,
collectMetrics: false
})
})
@@ -50,7 +50,7 @@ describe('CircuitBreaker', () => {
it('should execute async operations', async () => {
const result = await breaker.execute(async () => {
await new Promise((resolve) => setTimeout(resolve, 10))
await new Promise(resolve => setTimeout(resolve, 10))
return 'async success'
})
expect(result).toBe('async success')
@@ -124,7 +124,7 @@ describe('CircuitBreaker', () => {
})
it('should transition to half-open after reset timeout', async () => {
await new Promise((resolve) => setTimeout(resolve, 150))
await new Promise(resolve => setTimeout(resolve, 150))
expect(breaker.isHalfOpen()).toBe(true)
})
})
@@ -132,7 +132,7 @@ describe('CircuitBreaker', () => {
describe('half-open state', () => {
beforeEach(async () => {
breaker.trip()
await new Promise((resolve) => setTimeout(resolve, 150))
await new Promise(resolve => setTimeout(resolve, 150))
})
it('should close after success threshold', async () => {
@@ -176,14 +176,12 @@ describe('CircuitBreaker', () => {
const slowBreaker = createCircuitBreaker({
name: 'slow',
timeout: 50,
collectMetrics: false,
collectMetrics: false
})
await expect(
slowBreaker.execute(
() => new Promise((resolve) => setTimeout(resolve, 200))
)
).rejects.toThrow(CircuitTimeoutError)
await expect(slowBreaker.execute(() => new Promise(resolve => setTimeout(resolve, 200)))).rejects.toThrow(
CircuitTimeoutError
)
slowBreaker.destroy()
})
@@ -193,7 +191,7 @@ describe('CircuitBreaker', () => {
it('should emit state-change event', async () => {
const stateChanges: Array<{ from: CircuitState; to: CircuitState }> = []
breaker.on('state-change', (change) => {
breaker.on('state-change', change => {
stateChanges.push(change)
})
@@ -230,7 +228,7 @@ describe('CircuitBreaker', () => {
name: 'custom',
failureThreshold: 1,
shouldCountError: (error: any) => error.message !== 'Ignored',
collectMetrics: false,
collectMetrics: false
})
// This error should be ignored
@@ -333,7 +331,7 @@ describe('withCircuitBreaker', () => {
},
{
name: 'wrapped-fn',
collectMetrics: false,
collectMetrics: false
}
)
+1 -1
View File
@@ -9,8 +9,8 @@
*/
import { proto } from '../../../WAProto/index.js'
import { metrics } from '../../Utils/prometheus-metrics.js'
import { NO_MESSAGE_FOUND_ERROR_TEXT } from '../../Utils/decode-wa-message.js'
import { metrics } from '../../Utils/prometheus-metrics.js'
describe('CTWA Recovery', () => {
describe('Message Detection', () => {
+24 -95
View File
@@ -1,9 +1,9 @@
import { proto } from '../../../WAProto/index.js'
import {
processHistoryMessage,
extractLidPnFromConversation,
extractLidPnFromMessage,
isPersonJid
isPersonJid,
processHistoryMessage
} from '../../Utils/history'
describe('isPersonJid', () => {
@@ -107,23 +107,13 @@ describe('extractLidPnFromMessage', () => {
describe('edge cases', () => {
it('should return undefined when no alt JID is present', () => {
const result = extractLidPnFromMessage(
'5511999999999@s.whatsapp.net',
undefined,
undefined,
undefined
)
const result = extractLidPnFromMessage('5511999999999@s.whatsapp.net', undefined, undefined, undefined)
expect(result).toBeUndefined()
})
it('should return undefined when both are same type (LID)', () => {
const result = extractLidPnFromMessage(
'123456789012345@lid',
'987654321098765@lid',
undefined,
undefined
)
const result = extractLidPnFromMessage('123456789012345@lid', '987654321098765@lid', undefined, undefined)
expect(result).toBeUndefined()
})
@@ -140,12 +130,7 @@ describe('extractLidPnFromMessage', () => {
})
it('should return undefined for newsletter messages', () => {
const result = extractLidPnFromMessage(
'123456789012345@newsletter',
undefined,
undefined,
undefined
)
const result = extractLidPnFromMessage('123456789012345@newsletter', undefined, undefined, undefined)
expect(result).toBeUndefined()
})
@@ -235,11 +220,7 @@ describe('extractLidPnFromMessage', () => {
describe('extractLidPnFromConversation', () => {
describe('LID chat with pnJid', () => {
it('should extract mapping when chat ID is @lid format with pnJid', () => {
const result = extractLidPnFromConversation(
'123456789012345@lid',
undefined,
'5511999999999@s.whatsapp.net'
)
const result = extractLidPnFromConversation('123456789012345@lid', undefined, '5511999999999@s.whatsapp.net')
expect(result).toEqual({
lid: '123456789012345@lid',
@@ -248,11 +229,7 @@ describe('extractLidPnFromConversation', () => {
})
it('should extract mapping when chat ID is @hosted.lid format with pnJid', () => {
const result = extractLidPnFromConversation(
'123456789012345@hosted.lid',
undefined,
'5511999999999@hosted'
)
const result = extractLidPnFromConversation('123456789012345@hosted.lid', undefined, '5511999999999@hosted')
expect(result).toEqual({
lid: '123456789012345@hosted.lid',
@@ -263,11 +240,7 @@ describe('extractLidPnFromConversation', () => {
describe('PN chat with lidJid', () => {
it('should extract mapping when chat ID is @s.whatsapp.net format with lidJid', () => {
const result = extractLidPnFromConversation(
'5511999999999@s.whatsapp.net',
'123456789012345@lid',
undefined
)
const result = extractLidPnFromConversation('5511999999999@s.whatsapp.net', '123456789012345@lid', undefined)
expect(result).toEqual({
lid: '123456789012345@lid',
@@ -276,11 +249,7 @@ describe('extractLidPnFromConversation', () => {
})
it('should extract mapping when chat ID is @hosted format with lidJid', () => {
const result = extractLidPnFromConversation(
'5511999999999@hosted',
'123456789012345@hosted.lid',
undefined
)
const result = extractLidPnFromConversation('5511999999999@hosted', '123456789012345@hosted.lid', undefined)
expect(result).toEqual({
lid: '123456789012345@hosted.lid',
@@ -291,11 +260,7 @@ describe('extractLidPnFromConversation', () => {
describe('edge cases', () => {
it('should return undefined for group chats', () => {
const result = extractLidPnFromConversation(
'123456789012345@g.us',
undefined,
undefined
)
const result = extractLidPnFromConversation('123456789012345@g.us', undefined, undefined)
expect(result).toBeUndefined()
})
@@ -311,41 +276,25 @@ describe('extractLidPnFromConversation', () => {
})
it('should return undefined for broadcast lists (@broadcast)', () => {
const result = extractLidPnFromConversation(
'status@broadcast',
undefined,
undefined
)
const result = extractLidPnFromConversation('status@broadcast', undefined, undefined)
expect(result).toBeUndefined()
})
it('should return undefined when no alternate JID is available', () => {
const result = extractLidPnFromConversation(
'123456789012345@lid',
undefined,
undefined
)
const result = extractLidPnFromConversation('123456789012345@lid', undefined, undefined)
expect(result).toBeUndefined()
})
it('should return undefined when both lidJid and pnJid are null', () => {
const result = extractLidPnFromConversation(
'5511999999999@s.whatsapp.net',
null,
null
)
const result = extractLidPnFromConversation('5511999999999@s.whatsapp.net', null, null)
expect(result).toBeUndefined()
})
it('should return undefined for LID chat with lidJid (no pnJid)', () => {
const result = extractLidPnFromConversation(
'123456789012345@lid',
'987654321098765@lid',
undefined
)
const result = extractLidPnFromConversation('123456789012345@lid', '987654321098765@lid', undefined)
expect(result).toBeUndefined()
})
@@ -507,9 +456,7 @@ describe('processHistoryMessage', () => {
const result = processHistoryMessage(historySync)
expect(result.lidPnMappings).toEqual([
{ lid: '11111111111111@lid', pn: '5511999999999@s.whatsapp.net' }
])
expect(result.lidPnMappings).toEqual([{ lid: '11111111111111@lid', pn: '5511999999999@s.whatsapp.net' }])
})
it('should extract LID-PN mapping when chat ID is PN with lidJid', () => {
@@ -526,17 +473,13 @@ describe('processHistoryMessage', () => {
const result = processHistoryMessage(historySync)
expect(result.lidPnMappings).toEqual([
{ lid: '11111111111111@lid', pn: '5511999999999@s.whatsapp.net' }
])
expect(result.lidPnMappings).toEqual([{ lid: '11111111111111@lid', pn: '5511999999999@s.whatsapp.net' }])
})
it('should deduplicate mappings from both sources', () => {
const historySync: proto.IHistorySync = {
syncType: proto.HistorySync.HistorySyncType.INITIAL_BOOTSTRAP,
phoneNumberToLidMappings: [
{ lidJid: '11111111111111@lid', pnJid: '5511999999999@s.whatsapp.net' }
],
phoneNumberToLidMappings: [{ lidJid: '11111111111111@lid', pnJid: '5511999999999@s.whatsapp.net' }],
conversations: [
{
id: '11111111111111@lid',
@@ -558,9 +501,7 @@ describe('processHistoryMessage', () => {
it('should combine mappings from both sources', () => {
const historySync: proto.IHistorySync = {
syncType: proto.HistorySync.HistorySyncType.INITIAL_BOOTSTRAP,
phoneNumberToLidMappings: [
{ lidJid: '11111111111111@lid', pnJid: '5511999999999@s.whatsapp.net' }
],
phoneNumberToLidMappings: [{ lidJid: '11111111111111@lid', pnJid: '5511999999999@s.whatsapp.net' }],
conversations: [
{
id: '22222222222222@lid',
@@ -613,9 +554,7 @@ describe('processHistoryMessage', () => {
const result = processHistoryMessage(historySync)
expect(result.lidPnMappings).toEqual([
{ lid: '11111111111111@hosted.lid', pn: '5511999999999@hosted' }
])
expect(result.lidPnMappings).toEqual([{ lid: '11111111111111@hosted.lid', pn: '5511999999999@hosted' }])
})
it('should extract mappings for all conversation sync types', () => {
@@ -639,28 +578,20 @@ describe('processHistoryMessage', () => {
const result = processHistoryMessage(historySync)
expect(result.lidPnMappings).toEqual([
{ lid: '11111111111111@lid', pn: '5511999999999@s.whatsapp.net' }
])
expect(result.lidPnMappings).toEqual([{ lid: '11111111111111@lid', pn: '5511999999999@s.whatsapp.net' }])
}
})
it('should not extract conversation mappings for PUSH_NAME sync type', () => {
const historySync: proto.IHistorySync = {
syncType: proto.HistorySync.HistorySyncType.PUSH_NAME,
pushnames: [
{ id: '5511999999999@s.whatsapp.net', pushname: 'User Name' }
],
phoneNumberToLidMappings: [
{ lidJid: '11111111111111@lid', pnJid: '5511999999999@s.whatsapp.net' }
]
pushnames: [{ id: '5511999999999@s.whatsapp.net', pushname: 'User Name' }],
phoneNumberToLidMappings: [{ lidJid: '11111111111111@lid', pnJid: '5511999999999@s.whatsapp.net' }]
}
const result = processHistoryMessage(historySync)
expect(result.lidPnMappings).toEqual([
{ lid: '11111111111111@lid', pn: '5511999999999@s.whatsapp.net' }
])
expect(result.lidPnMappings).toEqual([{ lid: '11111111111111@lid', pn: '5511999999999@s.whatsapp.net' }])
})
it('should not extract mapping from newsletter conversations', () => {
@@ -765,9 +696,7 @@ describe('processHistoryMessage', () => {
it('should deduplicate mappings from all three sources', () => {
const historySync = {
syncType: proto.HistorySync.HistorySyncType.INITIAL_BOOTSTRAP,
phoneNumberToLidMappings: [
{ lidJid: '11111111111111@lid', pnJid: '5511999999999@s.whatsapp.net' }
],
phoneNumberToLidMappings: [{ lidJid: '11111111111111@lid', pnJid: '5511999999999@s.whatsapp.net' }],
conversations: [
{
id: '11111111111111@lid',
@@ -158,10 +158,12 @@ describe('processSyncAction', () => {
phoneNumber: '5511999@s.whatsapp.net'
}
])
expect(ev.emit).toHaveBeenCalledWith('lid-mapping.update', [{
lid: '123@lid',
pn: '5511999@s.whatsapp.net'
}])
expect(ev.emit).toHaveBeenCalledWith('lid-mapping.update', [
{
lid: '123@lid',
pn: '5511999@s.whatsapp.net'
}
])
})
it('does not emit events when id is missing', () => {
+44 -37
View File
@@ -2,23 +2,23 @@
* Testes unitários para retry-utils.ts
*/
import { describe, it, expect, beforeEach, jest } from '@jest/globals'
import { beforeEach, describe, expect, it, jest } from '@jest/globals'
import {
retry,
retryWithResult,
createRetrier,
retryable,
RetryManager,
RetryExhaustedError,
RetryAbortedError,
calculateDelay,
retryPredicates,
retryConfigs,
getRetryDelayWithJitter,
createRetrier,
getAllRetryDelaysWithJitter,
getRetryDelayWithJitter,
retry,
RETRY_BACKOFF_DELAYS,
RETRY_JITTER_FACTOR,
retryable,
RetryAbortedError,
retryConfigs,
type RetryContext,
RetryExhaustedError,
RetryManager,
retryPredicates,
retryWithResult
} from '../../Utils/retry-utils.js'
describe('retry', () => {
@@ -29,10 +29,13 @@ describe('retry', () => {
})
it('should return result from async operation', async () => {
const result = await retry(async () => {
await new Promise((resolve) => setTimeout(resolve, 10))
return 'async success'
}, { collectMetrics: false })
const result = await retry(
async () => {
await new Promise(resolve => setTimeout(resolve, 10))
return 'async success'
},
{ collectMetrics: false }
)
expect(result).toBe('async success')
})
@@ -48,12 +51,13 @@ describe('retry', () => {
if (attempts < 3) {
throw new Error('Failing')
}
return 'success after retries'
},
{
maxAttempts: 5,
baseDelay: 10,
collectMetrics: false,
collectMetrics: false
}
)
@@ -70,7 +74,7 @@ describe('retry', () => {
{
maxAttempts: 3,
baseDelay: 10,
collectMetrics: false,
collectMetrics: false
}
)
).rejects.toThrow(RetryExhaustedError)
@@ -80,7 +84,7 @@ describe('retry', () => {
let receivedContext: RetryContext | null = null
await retry(
(context) => {
context => {
receivedContext = context
return 'success'
},
@@ -107,7 +111,7 @@ describe('retry', () => {
maxAttempts: 5,
baseDelay: 10,
shouldRetry: () => false,
collectMetrics: false,
collectMetrics: false
}
)
).rejects.toThrow(RetryExhaustedError)
@@ -127,13 +131,14 @@ describe('retry', () => {
if (attempts < 3) {
throw new Error('Failing')
}
return 'success'
},
{
maxAttempts: 5,
baseDelay: 10,
onRetry,
collectMetrics: false,
collectMetrics: false
}
)
@@ -145,7 +150,7 @@ describe('retry', () => {
await retry(() => 'result', {
onSuccess,
collectMetrics: false,
collectMetrics: false
})
expect(onSuccess).toHaveBeenCalledWith('result', 1)
@@ -163,7 +168,7 @@ describe('retry', () => {
maxAttempts: 2,
baseDelay: 10,
onFailure,
collectMetrics: false,
collectMetrics: false
}
)
).rejects.toThrow()
@@ -178,14 +183,14 @@ describe('retry', () => {
const promise = retry(
async () => {
await new Promise((resolve) => setTimeout(resolve, 100))
await new Promise(resolve => setTimeout(resolve, 100))
return 'success'
},
{
maxAttempts: 5,
baseDelay: 50,
abortSignal: controller.signal,
collectMetrics: false,
collectMetrics: false
}
)
@@ -214,7 +219,7 @@ describe('retryWithResult', () => {
{
maxAttempts: 2,
baseDelay: 10,
collectMetrics: false,
collectMetrics: false
}
)
@@ -287,7 +292,7 @@ describe('createRetrier', () => {
const myRetrier = createRetrier({
maxAttempts: 5,
baseDelay: 10,
collectMetrics: false,
collectMetrics: false
})
let attempts = 0
@@ -315,7 +320,7 @@ describe('retryable', () => {
{
maxAttempts: 5,
baseDelay: 10,
collectMetrics: false,
collectMetrics: false
}
)
@@ -340,7 +345,7 @@ describe('RetryManager', () => {
it('should cancel active retry', async () => {
const promise = manager.execute('cancelable', async () => {
await new Promise((resolve) => setTimeout(resolve, 1000))
await new Promise(resolve => setTimeout(resolve, 1000))
return 'result'
})
@@ -351,10 +356,12 @@ describe('RetryManager', () => {
it('should check if operation is active', async () => {
let resolve: () => void
const promise = manager.execute('active', () =>
new Promise<string>((r) => {
resolve = () => r('done')
})
const promise = manager.execute(
'active',
() =>
new Promise<string>(r => {
resolve = () => r('done')
})
)
expect(manager.isActive('active')).toBe(true)
@@ -368,7 +375,7 @@ describe('RetryManager', () => {
it('should cancel all operations', async () => {
const promises = [
manager.execute('op1', () => new Promise((_, reject) => setTimeout(() => reject(new Error()), 1000))),
manager.execute('op2', () => new Promise((_, reject) => setTimeout(() => reject(new Error()), 1000))),
manager.execute('op2', () => new Promise((_, reject) => setTimeout(() => reject(new Error()), 1000)))
]
setTimeout(() => manager.cancelAll(), 20)
@@ -425,8 +432,8 @@ describe('retryPredicates', () => {
describe('or', () => {
it('should combine predicates with OR', () => {
const combined = retryPredicates.or(
(e) => e.message.includes('A'),
(e) => e.message.includes('B')
e => e.message.includes('A'),
e => e.message.includes('B')
)
expect(combined(new Error('A'), 1)).toBe(true)
@@ -438,8 +445,8 @@ describe('retryPredicates', () => {
describe('and', () => {
it('should combine predicates with AND', () => {
const combined = retryPredicates.and(
(e) => e.message.includes('A'),
(e) => e.message.includes('B')
e => e.message.includes('A'),
e => e.message.includes('B')
)
expect(combined(new Error('A and B'), 1)).toBe(true)
@@ -2,15 +2,15 @@
* Testes unitários para structured-logger.ts
*/
import { describe, it, expect, beforeEach, afterEach, jest } from '@jest/globals'
import { afterEach, beforeEach, describe, expect, it, jest } from '@jest/globals'
import {
StructuredLogger,
createStructuredLogger,
getDefaultLogger,
setDefaultLogger,
createTimer,
getDefaultLogger,
LOG_LEVEL_VALUES,
type LogLevel,
setDefaultLogger,
StructuredLogger
} from '../../Utils/structured-logger.js'
describe('StructuredLogger', () => {
@@ -21,7 +21,7 @@ describe('StructuredLogger', () => {
logger = createStructuredLogger({
level: 'debug',
name: 'test',
jsonFormat: false,
jsonFormat: false
})
consoleSpy = jest.spyOn(console, 'info').mockImplementation(() => {})
jest.spyOn(console, 'debug').mockImplementation(() => {})
@@ -95,14 +95,14 @@ describe('StructuredLogger', () => {
it('should redact sensitive fields', () => {
const jsonLogger = createStructuredLogger({
level: 'info',
jsonFormat: true,
jsonFormat: true
})
// O logger deve sanitizar campos sensíveis
jsonLogger.info({
user: 'test',
password: 'secret123',
token: 'abc123',
token: 'abc123'
})
expect(consoleSpy).toHaveBeenCalled()
@@ -167,7 +167,7 @@ describe('StructuredLogger', () => {
it('should measure elapsed time', async () => {
const timer = createTimer()
await new Promise((resolve) => setTimeout(resolve, 10))
await new Promise(resolve => setTimeout(resolve, 10))
const elapsed = timer.elapsed()
expect(elapsed).toBeGreaterThan(0)
@@ -176,7 +176,7 @@ describe('StructuredLogger', () => {
it('should format elapsed time', async () => {
const timer = createTimer()
await new Promise((resolve) => setTimeout(resolve, 5))
await new Promise(resolve => setTimeout(resolve, 5))
const formatted = timer.elapsedMs()
expect(formatted).toMatch(/\d+\.\d+ms/)
+35 -34
View File
@@ -2,36 +2,36 @@
* Testes unitários para trace-context.ts
*/
import { describe, it, expect, beforeEach } from '@jest/globals'
import { beforeEach, describe, expect, it } from '@jest/globals'
import {
addSpanEvent,
createPrecisionTimer,
createSpan,
createTraceContext,
endSpan,
exportContext,
extractTraceHeaders,
generateCorrelationId,
generateSpanId,
generateTraceId,
getAllBaggage,
getBaggage,
getCurrentContext,
getOrCreateContext,
importContext,
injectTraceHeaders,
removeBaggage,
runWithContext,
runWithNewContext,
createSpan,
startSpan,
endSpan,
addSpanEvent,
setBaggage,
setSpanAttributes,
setSpanError,
withSpan,
withSpanSync,
setBaggage,
getBaggage,
getAllBaggage,
removeBaggage,
injectTraceHeaders,
extractTraceHeaders,
exportContext,
importContext,
createPrecisionTimer,
generateTraceId,
generateSpanId,
generateCorrelationId,
type Span,
startSpan,
TRACE_HEADERS,
type TraceContext,
type Span,
withSpan,
withSpanSync
} from '../../Utils/trace-context.js'
describe('ID generation', () => {
@@ -47,6 +47,7 @@ describe('ID generation', () => {
for (let i = 0; i < 100; i++) {
ids.add(generateTraceId())
}
expect(ids.size).toBe(100)
})
})
@@ -85,7 +86,7 @@ describe('TraceContext', () => {
correlationId: 'custom-corr-id',
parentSpanId: 'parent-span',
baggage: { key: 'value' },
metadata: { env: 'test' },
metadata: { env: 'test' }
})
expect(context.traceIds.traceId).toBe('custom-trace-id')
@@ -174,7 +175,7 @@ describe('Spans', () => {
it('should include provided attributes', () => {
const span = createSpan({
name: 'test',
attributes: { key: 'value', count: 42 },
attributes: { key: 'value', count: 42 }
})
expect(span.attributes).toEqual({ key: 'value', count: 42 })
@@ -287,7 +288,7 @@ describe('Spans', () => {
expect(span.status).toBe('error')
expect(span.attributes.error).toBe(true)
expect(span.attributes.errorMessage).toBe('Something went wrong')
expect(span.events.some((e) => e.name === 'exception')).toBe(true)
expect(span.events.some(e => e.name === 'exception')).toBe(true)
})
})
})
@@ -295,7 +296,7 @@ describe('Spans', () => {
describe('withSpan helpers', () => {
describe('withSpan', () => {
it('should execute async operation within span', async () => {
const result = await withSpan('async-op', async (span) => {
const result = await withSpan('async-op', async span => {
expect(span.name).toBe('async-op')
return 'async-result'
})
@@ -314,7 +315,7 @@ describe('withSpan helpers', () => {
describe('withSpanSync', () => {
it('should execute sync operation within span', () => {
const result = withSpanSync('sync-op', (span) => {
const result = withSpanSync('sync-op', span => {
expect(span.name).toBe('sync-op')
return 'sync-result'
})
@@ -364,7 +365,7 @@ describe('Header injection/extraction', () => {
describe('injectTraceHeaders', () => {
it('should inject trace headers', () => {
const context = createTraceContext({
baggage: { user: 'test' },
baggage: { user: 'test' }
})
const headers = runWithContext(context, () => {
@@ -394,7 +395,7 @@ describe('Header injection/extraction', () => {
[TRACE_HEADERS.TRACE_ID]: 'trace-123',
[TRACE_HEADERS.PARENT_SPAN_ID]: 'parent-456',
[TRACE_HEADERS.CORRELATION_ID]: 'corr-789',
[TRACE_HEADERS.BAGGAGE]: 'key1=value1,key2=value2',
[TRACE_HEADERS.BAGGAGE]: 'key1=value1,key2=value2'
}
const options = extractTraceHeaders(headers)
@@ -412,7 +413,7 @@ describe('Context serialization', () => {
it('should serialize context to JSON string', () => {
const context = createTraceContext({
baggage: { key: 'value' },
metadata: { env: 'test' },
metadata: { env: 'test' }
})
const exported = exportContext(context)
@@ -430,10 +431,10 @@ describe('Context serialization', () => {
traceIds: {
traceId: 'trace-123',
spanId: 'span-456',
correlationId: 'corr-789',
correlationId: 'corr-789'
},
baggage: { imported: 'value' },
metadata: { source: 'external' },
metadata: { source: 'external' }
})
const options = importContext(serialized)
@@ -455,7 +456,7 @@ describe('PrecisionTimer', () => {
it('should measure elapsed time', async () => {
const timer = createPrecisionTimer()
await new Promise((resolve) => setTimeout(resolve, 20))
await new Promise(resolve => setTimeout(resolve, 20))
const elapsed = timer.elapsed()
expect(elapsed).toBeGreaterThan(10)
@@ -464,7 +465,7 @@ describe('PrecisionTimer', () => {
it('should format elapsed time', async () => {
const timer = createPrecisionTimer()
await new Promise((resolve) => setTimeout(resolve, 5))
await new Promise(resolve => setTimeout(resolve, 5))
const formatted = timer.elapsedFormatted()
expect(formatted).toMatch(/\d+(\.\d+)?(µs|ms|s)/)
@@ -473,11 +474,11 @@ describe('PrecisionTimer', () => {
it('should stop timer', async () => {
const timer = createPrecisionTimer()
await new Promise((resolve) => setTimeout(resolve, 10))
await new Promise(resolve => setTimeout(resolve, 10))
const stopped = timer.stop()
await new Promise((resolve) => setTimeout(resolve, 20))
await new Promise(resolve => setTimeout(resolve, 20))
const afterStop = timer.elapsed()
+5 -5
View File
@@ -5,15 +5,15 @@
* official WhatsApp Web client telemetry behavior.
*/
import { describe, it, expect, beforeEach, afterEach, jest } from '@jest/globals'
import type { BinaryNode } from '../../WABinary/types.js'
import { afterEach, beforeEach, describe, expect, it, jest } from '@jest/globals'
import {
UnifiedSessionManager,
createUnifiedSessionManager,
extractServerTime,
shouldEnableUnifiedSession,
UnifiedSessionManager,
type UnifiedSessionOptions
} from '../../Utils/unified-session.js'
import type { BinaryNode } from '../../WABinary/types.js'
// TimeMs constants for testing (matching unified-session.ts)
const TimeMs = {
@@ -21,7 +21,7 @@ const TimeMs = {
Minute: 60_000,
Hour: 3_600_000,
Day: 86_400_000,
Week: 604_800_000,
Week: 604_800_000
} as const
// Mock the prometheus metrics to avoid side effects
@@ -203,7 +203,7 @@ describe('UnifiedSessionManager', () => {
expect(mockSendNode).toHaveBeenCalledTimes(1)
const sentNode = mockSendNode.mock.calls[0]?.[0] as BinaryNode | undefined
const sentNode = mockSendNode.mock.calls[0]?.[0]
expect(sentNode).toBeDefined()
expect(sentNode!.tag).toBe('ib')
expect(Array.isArray(sentNode!.content)).toBe(true)