fix(comicvine): map Publisher and Editors from API responses (bookshelf-ic7s) #975
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "bd-bookshelf-ic7s"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Two ComicVine mapping gaps fixed in
internal/metadata/comicvine/mapping.go:G1 — Publisher always empty in manual fetch modal
applyVolumeInfosetm.Comic.VolumeYear+m.Comic.VolumeIDbut notm.Publisher, even though the volume search already requests and decodespublisher. Now setsm.Publisher = vol.Publisher.Namewhen non-empty and not already set upstream. Fixes the empty Publisher row in the manual fetch modal for both the free-text search path and theNewFetchIssueDetailpath.G3 — Editor credits silently dropped
Both
buildComicMetadataFromListandbuildComicMetadatahad role-dispatch switches with noeditorcase, so ComicVine Editor/editor-in-chief credits were dropped entirely (ComicMetadata.Editorsalways nil). Addedcase strings.Contains(role, "editor")to both.Refactor: extracted
applyPersonCredithelper shared by both functions — the neweditorcase pushed both functions past the CC-15 gocyclo gate. Extracting the switch brings them back under the gate and eliminates the duplication.Test plan
make test— all tests pass including newmapping_test.gospecsmake lint— gocyclo, staticcheck cleanmake coverage— 100% on changed functions (applyVolumeInfo,applyPersonCredit,buildComicMetadataFromList,buildComicMetadata)httptest.Server: publisher via free-text andNewFetchIssueDetailpaths; editors via both list and detail paths.golangci.ymlexclusions addedCloses bead bookshelf-ic7s on merge.
Security Review — bookshelf-ic7s (PR #975)
ComicVine mapping fix:
applyVolumeInfopublisher propagation +applyPersonCrediteditor-role dispatch.[MINOR] internal/metadata/comicvine/mapping_test.go:209,271 — misleading
NotTo(BeNil())assertion on a struct valueThe two
It("fetches without error")blocks in theNewFetchIssueDetaildescribe groups assertExpect(result, err).NotTo(BeNil())whereresultis of typemetadata.Metadata— a struct value, never nil. TheNotTo(BeNil())half always passes unconditionally; only the multi-actualerr-must-be-nil gate does real work. This makes the intent misleading and masks the fact that the value assertion is absent from these specificItblocks (the field-specificItblocks carry the real check). The fix is to either remove the standalone no-errorItand fold the nil-error constraint into the field-assertionItviaExpect(result.Publisher, err).To(Equal("DC Comics")), or useExpect(err).NotTo(HaveOccurred())explicitly. No security or correctness impact — the field assertions in the siblingItblocks do verify the actual values.All other checklist items: clean.
vol.Publisher.Nameandp.Name/p.Roleare provider strings flowing intometadata.Metadatastruct fields, ultimately rendered byhtml/templatewhich auto-escapes. No SQL path. No injection concern.volumePublisheris embedded by value (not a pointer) involumeSearchResult, sovol.Publisher.Nameis always a valid string access with zero value"". Thevol.Publisher.Name != ""guard is correct.applyPersonCreditreceives a non-nil*metadata.ComicMetadata(callers pass&cof a locally declared value). No panic path introduced.mapping.goimports onlystrconv,strings, andinternal/metadata. No workflow-engine import. Boundary clean.mapping_test.godeclarespackage comicvine_test. Black-box convention satisfied..golangci.yml: No new exclusions introduced.REVIEW VERDICT: 0 blocker, 0 major, 1 minor
CODE REVIEW: APPROVED
Phase 0 — DEMO Verification
No terminal-command DEMO block exists in the bead or comments. The acceptance note ("Justice League #6 → DC Comics in the modal") requires a live system with a real ComicVine API key. CI is green and the orchestrator indicated CI is the behavioral truth source for this review.
Phase 1 — Spec Compliance
All requirements from the bead description are met:
applyVolumeInfonow setsm.Publisher = vol.Publisher.Nameguarded byvol.Publisher.Name != "" && m.Publisher == ""m.Publisher, notm.Comic.Publisher) ✓search.go:121, 186, 625) and detail path (provider.go:256) callapplyVolumeInfo, so both now pick up Publisher ✓applyPersonCredithelper (mapping.go:84) withcase strings.Contains(role, "editor")dispatching toc.Editors✓.golangci.ymlexclusions (zero net diff to both files) ✓Phase 2 — Code Quality
[MINOR]
internal/metadata/comicvine/mapping_test.go— missing publisher-no-clobber assertionThe review spec explicitly required a test that verifies a pre-set
m.Publisheris NOT overwritten whenapplyVolumeInfois called with a non-emptyvol.Publisher.Name. The current tests exercise thetruebranch (publisher populated) and thevol.Publisher.Name == ""false branch (publisher stays empty), but no test exercises the case wherem.Publisheris already non-empty. Go statement coverage still reaches 100% because theifline itself is hit, but the no-clobber guard’s false-path is untested. Suggested fix: add aContext("publisher already set — not clobbered")case in the G1 free-text Describe wherem.Publisheris pre-populated (e.g. by having the issue detail already carry a publisher) and assert it remains unchanged afterapplyVolumeInfomerges the volume.All other checks pass:
applyPersonCredittakes*metadata.ComicMetadataby pointer; callers correctly pass&c✓package comicvine_testthroughout — no white-box package declaration in the new file ✓Expect(results, err).To(HaveLen(1))correctly folds the nil-error check into the value assertion per convention ✓scripts/check-coverage.shexclusions ✓REVIEW VERDICT: 0 blocker, 0 major, 1 minor
7b74f0454aae26c4ce7e