aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Anthony <sam@samanthony.xyz>2026-05-07 13:09:58 -0400
committerSam Anthony <sam@samanthony.xyz>2026-05-07 13:09:58 -0400
commitace7694bad5752aa38fec3a13c071cf7b2bebfce (patch)
tree2f391107b6aa7bce7b0a028aff8f7c5b32839852
parentb57f03381e4bccba2963cebabe51a9cf32bd96dd (diff)
downloadlulu-ace7694bad5752aa38fec3a13c071cf7b2bebfce.zip
implement GET /validate-cover
-rw-r--r--cover.go8
-rw-r--r--cover_test.go36
-rw-r--r--interior_test.go43
-rw-r--r--lulu.go25
-rw-r--r--lulu_test.go24
5 files changed, 106 insertions, 30 deletions
diff --git a/cover.go b/cover.go
index e5845a7..ba2bc2a 100644
--- a/cover.go
+++ b/cover.go
@@ -28,6 +28,14 @@ const (
CoverStatusError CoverValidationStatus = "ERROR" // file is invalid, list of errors is included in the response
)
+func (s CoverValidationStatus) IsFinal() bool {
+ switch s {
+ case CoverStatusNormalized, CoverStatusError:
+ return true
+ }
+ return false
+}
+
// coverDimensionsReq is the json body of a /cover-dimensions/ request.
type coverDimensionsReq struct {
PkgId PkgId `json:"pod_package_id"`
diff --git a/cover_test.go b/cover_test.go
index 9cbab17..140bf84 100644
--- a/cover_test.go
+++ b/cover_test.go
@@ -115,3 +115,39 @@ func TestValidateCover(t *testing.T) {
require.NoError(t, err)
require.NotZero(t, id)
}
+
+func TestGetCoverValidation(t *testing.T) {
+ c := newClient(t)
+
+ mfg := PkgId{
+ UsTrade,
+ Mono,
+ Standard,
+ Perfect,
+ P60UncoatedWhite,
+ Gloss,
+ NoLinen,
+ NoFoil,
+ }
+ id, err := c.ValidateCover(coverUrl, mfg, 210)
+ require.NoError(t, err)
+
+ poll(t, func() bool {
+ rec, err := c.GetCoverValidation(id)
+ require.NoError(t, err)
+ if rec.Status.IsFinal() {
+ require.Equal(t, CoverStatusNormalized, rec.Status)
+ require.Equal(t, id, rec.Id)
+ require.Equal(t, coverUrl, rec.SrcUrl)
+
+ //require.Equal(t, uint(210), rec.NPages)
+ // The server doesn't seem to set the page_count
+ // field, but that's OK because we already know
+ // the page count.
+
+ require.Empty(t, rec.Errors)
+ return true
+ }
+ return false
+ })
+}
diff --git a/interior_test.go b/interior_test.go
index ba3d948..59707b8 100644
--- a/interior_test.go
+++ b/interior_test.go
@@ -1,9 +1,7 @@
package lulu
import (
- "context"
"testing"
- "time"
"github.com/stretchr/testify/require"
)
@@ -87,36 +85,21 @@ func TestValidateInteriorBasic(t *testing.T) {
func TestGetInteriorValidation(t *testing.T) {
c := newClient(t)
-
- // Start validation job
id, err := c.ValidateInteriorBasic(interiorUrl)
require.NoError(t, err)
+ poll(t, func() bool {
+ rec, err := c.GetInteriorValidation(id)
+ require.NoError(t, err)
+ if rec.Status.IsFinal() {
+ require.Equal(t, InteriorStatusValidated, rec.Status)
- // Poll until done
- timeout := 15 * time.Second
- period := time.Second
- ctx, cancel := context.WithTimeout(context.Background(), timeout)
- defer cancel()
- timer := time.NewTimer(period)
- for {
- select {
- case <-timer.C:
- rec, err := c.GetInteriorValidation(id)
- require.NoError(t, err)
- if rec.Status.IsFinal() {
- require.Equal(t, InteriorStatusValidated, rec.Status)
-
- require.Equal(t, id, rec.Id)
- require.Equal(t, interiorUrl, rec.SrcUrl)
- require.Equal(t, uint(210), rec.NPages)
- require.Empty(t, rec.Errors)
- require.NotEmpty(t, rec.ValidPkgIds)
- return
- }
- timer.Reset(period)
- case <-ctx.Done():
- t.Errorf("status still not finalized after %v", timeout)
- return
+ require.Equal(t, id, rec.Id)
+ require.Equal(t, interiorUrl, rec.SrcUrl)
+ require.Equal(t, uint(210), rec.NPages)
+ require.Empty(t, rec.Errors)
+ require.NotEmpty(t, rec.ValidPkgIds)
+ return true
}
- }
+ return false
+ })
}
diff --git a/lulu.go b/lulu.go
index 621cfc1..74ef526 100644
--- a/lulu.go
+++ b/lulu.go
@@ -165,6 +165,31 @@ func (c *Client) ValidateCover(srcUrl string, mfg PkgId, npages uint) (uint, err
return rec.Id, nil
}
+// GetCoverValidiation retrieves information about a cover file validation job that was started by ValidiateCover().
+//
+// https://api.lulu.com/docs/#tag/Files-validation/operation/Validate-Cover_read
+func (c *Client) GetCoverValidation(id uint) (CoverValidationRecord, error) {
+ url, err := url.JoinPath(ApiUrl, validateCoverPath, fmt.Sprint(id))
+ if err != nil {
+ return CoverValidationRecord{}, pkgErr(err)
+ }
+ resp, err := c.c.Get(url)
+ if err != nil {
+ return CoverValidationRecord{}, pkgErr(err)
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode != http.StatusOK {
+ return CoverValidationRecord{}, pkgErr(errResp{resp})
+ }
+
+ var rec CoverValidationRecord
+ if err := decodeResponse(resp, &rec); err != nil {
+ return CoverValidationRecord{}, pkgErr(err)
+ }
+ return rec, nil
+}
+
func (c *Client) post(path string, payload any) (*http.Response, error) {
body, err := json.Marshal(payload)
if err != nil {
diff --git a/lulu_test.go b/lulu_test.go
index 05d37ad..f657681 100644
--- a/lulu_test.go
+++ b/lulu_test.go
@@ -1,11 +1,13 @@
package lulu
import (
+ "context"
"encoding/json"
"fmt"
"os"
"strings"
"testing"
+ "time"
"github.com/stretchr/testify/require"
)
@@ -18,6 +20,9 @@ const (
interiorUrl = "https://www.dropbox.com/sh/p3zh22vzsaegiri/AACOUn3LFKsITDzylh13bQpsa/161025/thesis2.pdf?dl=1"
coverUrl = "https://www.dropbox.com/sh/p3zh22vzsaegiri/AADP367j0bTWlt8fCu-_tm2ia/161025/139056_cover.pdf?dl=1"
+
+ pollTimeout = 15 * time.Second
+ pollPeriod = time.Second
)
var (
@@ -62,3 +67,22 @@ func requireUnmarshalJsonEq[T any](t *testing.T, expected T, j string) {
require.NoError(t, json.Unmarshal([]byte(j), &actual))
require.Equal(t, expected, actual)
}
+
+// poll periodically calls f() until it returns true or the deadline is exceeded.
+func poll(t *testing.T, f func() bool) {
+ t.Helper()
+ ctx, cancel := context.WithTimeout(t.Context(), pollTimeout)
+ defer cancel()
+ timer := time.NewTimer(pollPeriod)
+ for {
+ select {
+ case <-timer.C:
+ if f() {
+ return
+ }
+ timer.Reset(pollPeriod)
+ case <-ctx.Done():
+ t.Errorf("timed out after %v", pollTimeout)
+ }
+ }
+}