diff --git a/CHANGELOG.md b/CHANGELOG.md index c659a6b..a447d88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.7.38] - 2026-05-29 + +### Fixed + +- **SABnzbd History Legacy Slot Name Compatibility (Issue #74)** — Hardened SABnzbd active-download and history slot title matching in `DownloadMatcher.js` to support all slot name property variations (`filename`, `nzbname`, `name`, `nzb_name`). This ensures history matching succeeds against cached/legacy data schemas where the name is stored solely under the `filename` property, preventing completed downloads awaiting import from incorrectly displaying as `"Unknown"` client cards. Added unit tests for legacy `filename` slot matching compatibility. + ## [1.7.37] - 2026-05-29 ### Fixed diff --git a/package-lock.json b/package-lock.json index 0ba6824..f603434 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sofarr", - "version": "1.7.37", + "version": "1.7.38", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sofarr", - "version": "1.7.37", + "version": "1.7.38", "license": "MIT", "dependencies": { "axios": "^1.6.0", diff --git a/package.json b/package.json index 12927ab..fc89a70 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sofarr", - "version": "1.7.37", + "version": "1.7.38", "description": "A personal media download dashboard that shows your downloads 'so far' while you relax on the sofa waiting for your *arr services to finish", "main": "server/index.js", "scripts": { diff --git a/server/app.js b/server/app.js index 025be49..564ffe9 100644 --- a/server/app.js +++ b/server/app.js @@ -133,7 +133,7 @@ function createApp({ skipRateLimits = false } = {}) { * version: * type: string * description: sofarr version - * example: "1.7.37" + * example: "1.7.38" * x-code-samples: * - lang: curl * label: cURL diff --git a/server/openapi.yaml b/server/openapi.yaml index b11a17b..91a3790 100644 --- a/server/openapi.yaml +++ b/server/openapi.yaml @@ -22,7 +22,7 @@ info: ## SSE Streaming Real-time updates are available via Server-Sent Events at GET /api/dashboard/stream. - version: 1.7.37 + version: 1.7.38 contact: name: sofarr license: diff --git a/server/services/DownloadMatcher.js b/server/services/DownloadMatcher.js index 09c719a..3aaf259 100644 --- a/server/services/DownloadMatcher.js +++ b/server/services/DownloadMatcher.js @@ -290,7 +290,7 @@ async function matchSabSlots(slots, context) { const matched = []; for (const slot of slots) { - const nzbName = slot.filename || slot.nzbname; + const nzbName = slot.filename || slot.nzbname || slot.name || slot.nzb_name; if (!nzbName) continue; const slotState = getSlotStatusAndSpeed(slot, queueStatus, queueSpeed, queueKbpersec); @@ -347,7 +347,7 @@ async function matchSabHistory(slots, context) { const matched = []; for (const slot of slots) { - const nzbName = slot.name || slot.nzb_name || slot.nzbname; + const nzbName = slot.filename || slot.nzbname || slot.name || slot.nzb_name; if (!nzbName) continue; const sabDownloadId = slot.nzo_id || slot.id; diff --git a/tests/unit/services/DownloadMatcher.test.js b/tests/unit/services/DownloadMatcher.test.js index 038470e..4d20705 100644 --- a/tests/unit/services/DownloadMatcher.test.js +++ b/tests/unit/services/DownloadMatcher.test.js @@ -263,6 +263,24 @@ describe('DownloadMatcher', () => { expect(result[0].arrQueueId).toBe(301); expect(result[0].arrType).toBe('radarr'); }); + + it('matches when history slots only have the filename field (cached legacy format)', async () => { + const testContext = { + ...context, + sonarrHistoryRecords: [], + sonarrQueueRecords: [ + { id: 201, seriesId: 1, title: 'My.Cool.Show.S01E01.720p-Group' } + ], + seriesMap: new Map([[1, { id: 1, title: 'My Cool Show', tags: [1] }]]) + }; + + const slots = [{ id: null, filename: 'My_Cool_Show_S01E01_720p-Group.nzb', status: 'Completed', mb: 1000 }]; + const result = await DownloadMatcher.matchSabHistory(slots, testContext); + + expect(result).toHaveLength(1); + expect(result[0].arrQueueId).toBe(201); + expect(result[0].arrType).toBe('sonarr'); + }); }); describe('titleMatches helper', () => {