summaryrefslogtreecommitdiff
path: root/internal/api/handlers_test.go
AgeCommit message (Collapse)Author
2026-05-17Restructure repo: move Go server into player-server/Paul Buetow
2026-05-17Add progress status API routesPaul Buetow
2026-05-17Add playback repository cleanup queriesPaul Buetow
2026-05-10Move self-deletion guard from handler into AdminService (DeleteUser) to fix ↵Paul Buetow
SoC violation - Add ErrCannotDeleteSelf sentinel error in service layer. - Change DeleteUser signature to (ctx, callerID, id) across all layers. - Move self-deletion guard from handleDeleteUser handler into userAdminService.DeleteUser. - Update handleError to map ErrCannotDeleteSelf to 400 BadRequest. - Adjust all affected tests to use the new signature.
2026-05-10fix(tests): handle json.Unmarshal errors explicitly in *_test.goPaul Buetow
2026-05-10internal/service: fix ListEpisodes global pagination by using cross-feed SQL ↵Paul Buetow
query Previously ListEpisodes requested per-feed episodes with the full limit from every feed, concatenated them, and then sliced the resulting slice in memory. This silently skipped episodes from deeper pages because the per-feed DB limit never returned them. Fix: Add a new repository method ListEpisodesByFeedIDsWithStatus that takes a slice of feed IDs and applies LIMIT/OFFSET globally in a single SQL query (IN (...)). The service builds the feed ID list and delegates pagination to the database instead of emulating it in memory. Files changed: - internal/repository/podcast.go: add ListEpisodesByFeedIDsWithStatus - internal/repository/podcast_repo.go: extend PodcastRepo interface - internal/repository/mock.go: add mock implementation - internal/service/podcast.go: replace per-feed loop with new method - internal/service/podcast_test.go: add tests for ListEpisodes - internal/repository/podcast_test.go: add integration tests for new repo method - internal/api/handlers_test.go: add mockPingStore method
2026-05-10Add circuit breaker / backoff for failing podcast feeds in CheckFeedsPaul Buetow
- DB: add consecutive_failures and next_check_at to podcast_feeds - model: add ConsecutiveFailures and NextCheckAt to PodcastFeed struct - repository: update CRUD queries to handle new columns and ListFeedsNeedingCheck to skip feeds with future next_check_at - service: update CheckFeeds to use new query, update checkFeed to reset counters on success and increment exponential backoff on failure - tests: adapt mock signatures, add backoff integration test
2026-05-09Extract SessionManager interface to fix DIP violationPaul Buetow
- Introduce auth.SessionManager interface in internal/auth/interfaces.go - Rename concrete struct to sessionManager (unexported) and have it satisfy interface - Update api/service layers to depend on interface, not concrete type - Add MockSessionManager for testing - Update all call sites and tests to use interface
2026-05-09Refine media browsing and set coversPaul Buetow
2026-05-07task 31: introduce media streamer servicePaul Buetow
2026-05-07Refactor API server dependencies for task 11Paul Buetow
2026-05-05Add podcast support backend: RSS/Atom feeds, episode management, cover scrapingPaul Buetow
2026-05-04task 3: decouple API layer from repository with MediaQueryFilter and ↵Paul Buetow
AuthService abstraction
2026-05-04task 6: narrow service interfaces in Server and MiddlewarePaul Buetow
Split Server struct to accept narrow service interfaces instead of fat composites (MediaService, AdminService). Each handler now depends only on its specific slice (MediaBrowseService, MediaWriteService, etc.). Split Middleware to depend on a narrow UserStore interface instead of full repository.Store. Updated all constructors, call sites, and tests. Added negative tests for nil AdminService and ProgressService returning 501 Not Implemented. References task 6.
2026-05-03refactor(api): extract Remuxer interface and move ffmpeg/MPEG-TS/mime logic ↵Paul Buetow
to internal/probe Move LooksLikeMPEGTS, MimeTypeForFilename and the ffmpeg remux path out of the api transport layer into a new internal/probe/remux.go package. This removes os/exec and mime tables from the api layer, satisfying the DIP principle. - New probe.Remuxer interface with FFRemuxer implementation - Server depends on probe.Remuxer, injected via NewServer - Updated cmd/mediaplayer wiring and all test helpers - All tests pass: go test ./... -race -cover
2026-05-02fix detached playback and scan progressPaul Buetow
2026-05-02feat: secure shares with keyboard-first My Shares modal (hotkeys S/L)Paul Buetow
2026-05-02fix:xPaul Buetow
2026-05-01Task 1: Create AuthService and route handleBootstrap/handleLogin through itPaul Buetow
Introduce service.AuthService interface with Bootstrap and Login methods, a concrete authService implementation, and a MockAuthService for testing. Wire AuthService into api.Server and update cmd/mediaplayer/main.go to use it. This removes direct store access from handleBootstrap and handleLogin, fixing the DIP violation. Sentinel errors (ErrAlreadyBootstrapped, ErrInvalidCredentials) are added to the service package so the API layer can map them to the correct HTTP status codes without leaking DB details. Files created: - internal/service/auth.go Files modified: - internal/service/service.go - internal/service/media.go - internal/service/mock.go - internal/repository/repository.go - internal/repository/mock.go - internal/api/server.go - internal/api/handlers_auth.go - internal/api/handlers_test.go - internal/api/handlers_more_test.go - cmd/mediaplayer/main.go
2026-05-01Add support for audiobook/cover images with ancestor lookup and fix keyboard ↵Paul Buetow
navigation Backend: - Add UpdateMediaThumbnail to MediaRepo for efficient thumbnail-only updates - Update ScannerStore interface to include thumbnail update capability - Update mock implementations across repository and API layers for interface changes - Enhance scanner to detect image files in ancestor directories for audio covers - Add background goroutine for async rescan to avoid HTTP timeout Frontend: - Fix hjkl cursor keys to navigate grid properly - Implement ancestor directory cover image lookup for audiobooks Infrastructure: - Add start.sh helper script for quick server startup during development
2026-05-01Rename Go module from codeberg.org/snonux/play to codeberg.org/snonux/playerPaul Buetow
2026-04-30fix: permissions matrix UI now returns proper shape from backendPaul Buetow
The frontend admin.js expects {sets, users, permissions} but ListPermissions returned a flat []SetPermission slice. - Add PermissionsMatrix struct with JSON tags - Update AdminService.ListPermissions to return *PermissionsMatrix - Update mocks and all call sites to match new signature - Update tests to assert the new matrix shape
2026-04-30Wire playback resume end to end (task ka)Paul Buetow
- Add JSON tags to model structs so API responses use camelCase keys (e.g., id, file_name, position_seconds). - MediaDetail now includes progress; add ResumeFrom() helper on MediaDetail. - Frontend playSelected() fetches /api/media/:id and reads progress.position_seconds before starting playback, then passes resume position to selectAndPlay(). - player.js selectAndPlay/loadMedia accept resumeFrom parameter instead of reading media.resume_from from list items. - Backend test coverage: handlers_test verifies detail endpoint returns progress position in JSON; media_test verifies GetMediaDetail includes progress and ResumeFrom() value. - Frontend test coverage: added web/js/tests/playback-resume.test.js validating detail JSON shape, resume position computation, and list item contract.
2026-04-30task oa: Add SECURE_COOKIES config to control session cookie Secure flagPaul Buetow
- Add SecureCookies bool to internal.Config (default true) - Update LoadConfig in internal/config.go to parse SECURE_COOKIES env var - Update setSessionCookie and clearSessionCookie in internal/api/handlers.go to read cfg.SecureCookies - Add tests verifying Secure=true/false and logout clears cookie accordingly - Update AGENTS.md and PLAN.md with new option documentation
2026-04-30task ia: fix media listing/filtering semantics (favorites bool, filesize ↵Paul Buetow
filters, permission scoping)
2026-04-30ja: implement public share landing page and improve error mappingPaul Buetow
- Add web/share.html with a minimal HTML5 video player, theme variables, centered layout, play overlay, and Back to Home link. - Update handleSharePage to return HTML for browser Accept headers (text/html or empty) and JSON for application/json. Return 410 Gone for expired shares. - Update handleShareStream to map service errors to distinct HTTP codes: ErrShareExpired -> 410, ErrShareNotFound/ErrMediaNotFound -> 404. - Improve ValidateShareToken and StreamSharedMedia to return sentinel errors (ErrShareNotFound, ErrShareExpired, ErrMediaNotFound) instead of generic string errors. - Update and add tests for share page HTML/JSON negotiation and share stream 404/410 responses.
2026-04-30task da: enforce media access and owner/admin role permissionsPaul Buetow
Changes: - MediaService.ListMedia now accepts userID and filters by allowed sets for non-admins via AllowedSetIDs in repository.MediaFilter. - Handlers pass userID into ListMedia; API returns 403 for forbidden. - Added verifyModifyAccess and verifySetModifyAccess helpers so only owners/admins can upload, soft-delete, restore, and regenerate thumbnails/covers; viewers are blocked. - GetMediaDetail, ToggleFavorite, AssignTag, RemoveTag, notes, and shares now consistently verifyAccess before proceeding. - Handlers handle ErrForbidden with 403 for soft-delete and restore. - Added negative tests proving viewers cannot mutate and unauthorized users cannot access/detail/tag/note/favorite/share inaccessible media.
2026-04-30Rename module to codeberg.org/snonux/play (task aa)Paul Buetow
- Update go.mod module path - Replace all internal imports from github.com/paul/kiss-media-player to codeberg.org/snonux/play - Run go mod tidy and gofmt -w .
2026-04-29feat(q9): implement REST handlers, streaming, uploads, shares, notes, ↵Paul Buetow
progress, admin routes
2026-04-29feat: implement bcrypt password hashing, session management, login/logout ↵Paul Buetow
handlers, and bootstrap flow (m9)