Files
bookhoard/internal/services/conversion_service_test.go
T
john-okeefe d12911d3c8 feat(api): make device rate limits, OPDS page size, and conversion cache configurable
Move three more hardcoded values behind the settings registry. All
apply immediately on the next request (no restart needed).

device_auth.go:
- DeviceAuthMiddleware reads per-route device rate limits (sync /
  progress / metadata per minute) from the registry on each
  authenticated request via a rateLimitConfig() helper, falling back to
  the Default* constants when no registry is wired.
- The X-RateLimit-Limit response header previously hardcoded "60" for
  every request type; it now reflects the actual configured limit for
  the request type via rateLimitForRequestType().

opds.go:
- Default (50) and maximum (200) OPDS page sizes come from the
  registry's OpdsDefaultPageSize()/OpdsMaxPageSize() instead of inline
  literals, so catalog pagination can be tuned without a redeploy.

conversion_service.go:
- The 24h kepub cache lifetime is read from the registry via a
  cacheTTL() helper (was a bare 24 * time.Hour literal in the
  constructor). The field default is retained for tests that construct
  the service directly.
- conversion_service_test.go updated to assert both the field default
  and the cacheTTL() accessor return 24h.
2026-08-10 08:01:28 -04:00

72 lines
2.1 KiB
Go

package services
import (
"crypto/sha256"
"encoding/hex"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestCalculateSHA256(t *testing.T) {
service := &ConversionService{}
dir := t.TempDir()
testFile := filepath.Join(dir, "test.epub")
content := "test content for hash calculation"
err := os.WriteFile(testFile, []byte(content), 0644)
require.NoError(t, err)
hash, err := service.calculateSHA256(testFile)
require.NoError(t, err)
expectedHash := sha256.New()
expectedHash.Write([]byte(content))
expectedHashStr := hex.EncodeToString(expectedHash.Sum(nil))
assert.Equal(t, expectedHashStr, hash)
assert.Len(t, hash, 64)
}
func TestConvertEPUBToKEPUBCreatesCacheDir(t *testing.T) {
cacheDir := filepath.Join(t.TempDir(), "cache", "kepub")
_ = NewConversionService(nil, cacheDir)
assert.NoFileExists(t, cacheDir, "Cache directory should not exist initially")
err := os.MkdirAll(cacheDir, 0755)
require.NoError(t, err, "Should be able to create cache directory")
assert.DirExists(t, cacheDir, "Cache directory should exist after creation")
}
func TestConvertedKEPUBStructure(t *testing.T) {
validHash := "abc123def456789abc123def456789abc123def456789abc123def456789abcd"
result := &ConvertedKEPUB{
Path: "/path/to/book.kepub.epub",
SHA256: validHash,
Cached: false,
}
assert.NotEmpty(t, result.Path)
assert.NotEmpty(t, result.SHA256)
assert.False(t, result.Cached)
assert.Len(t, result.SHA256, 64)
}
func TestConversionServiceDefaults(t *testing.T) {
cacheDir := t.TempDir()
service := NewConversionService(nil, cacheDir)
assert.NotNil(t, service)
assert.Equal(t, cacheDir, service.cacheDir)
assert.Equal(t, "/usr/bin/kepubify", service.conversionTool)
assert.Equal(t, int64(24*3600*1000000000), service.conversionCacheTTL.Nanoseconds(), "Default TTL field should be 24 hours")
// cacheTTL() must reflect the same default when no registry is wired.
assert.Equal(t, int64(24*3600*1000000000), service.cacheTTL().Nanoseconds(), "Default TTL accessor should return 24 hours")
}