From 0594075ecc77c672f33ce9e36dbf1c1a6c89ccb7 Mon Sep 17 00:00:00 2001 From: Sam Anthony Date: Wed, 29 Jul 2026 14:56:34 -0230 Subject: test Jobs() --- job_test.go | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lulu.go | 40 +++++++++++---------------- print_test.go | 47 +------------------------------ 3 files changed, 106 insertions(+), 70 deletions(-) create mode 100644 job_test.go diff --git a/job_test.go b/job_test.go new file mode 100644 index 0000000..fe6ea48 --- /dev/null +++ b/job_test.go @@ -0,0 +1,89 @@ +package lulu + +import ( + _ "embed" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +//go:embed testdata/jobsresp.json +var jobsRespJson string + +func TestUnmarshaljobsResp(t *testing.T) { + want := jobsResp{ + Count: 1, + Next: "https://api.lulu.com/resources/?page=1&page_size=1", + Prev: "https://api.lulu.com/resources/?page=1&page_size=1", + Results: []PrintJob{printJobSample}, + } + requireUnmarshalJsonEq(t, want, jobsRespJson) +} + +func TestJob(t *testing.T) { + contact := MustParseEmailAddress("test@test.com") + jobEid := "demo-time" + productionDelay := 120 * time.Minute + addr := shipAddrSample + shipOpt := Mail + items := []Printable{printableSample} + + c := newClient(t) + job1, err := c.Print(contact, jobEid, productionDelay, addr, shipOpt, items) + require.NoError(t, err) + require.NotZero(t, job1.Id) + + job2, err := c.Job(job1.Id) + require.NoError(t, err) + + // Ignore timestamp because job gets marked as 'modified' between + // creation and retrieval time even if it hasn't actually + // changed. + job2.Modified = job1.Modified + + require.Equal(t, job1, job2) +} + +func TestJobs(t *testing.T) { + // Create some jobs + c := newClient(t) + jobParams := []struct { + contact string + extid string + delay time.Duration + addr ShippingAddress + opt ShippingLevel + items []Printable + }{ + {"test@example.com", "testjobs1", 2 * time.Hour, shipAddrSample, Mail, []Printable{printableSample}}, + {"timmy@timmers.com", "testjobs2", 3 * time.Hour, shipAddrSample, Mail, []Printable{printableSample}}, + } + jobsIn := make([]PrintJob, len(jobParams)) + for i, j := range jobParams { + var err error + contact := MustParseEmailAddress(j.contact) + jobsIn[i], err = c.Print(contact, j.extid, j.delay, j.addr, j.opt, j.items) + require.NoError(t, err) + } + + // Retrieve them + jobsOut, err := c.Jobs() + require.NoError(t, err) + + // Are they all present? + require.Truef(t, len(jobsOut) >= len(jobsIn), "expected >=%d jobs, got %d", len(jobsIn), len(jobsOut)) + for _, j := range jobsOut { + for i := range jobsIn { + if j.Id == jobsIn[i].Id { + jobsIn[i].Modified = j.Modified // ignore timestamp + require.Equal(t, jobsIn[i], j) + jobsIn = append(jobsIn[:i], jobsIn[i+1:]...) + break + } + } + } + if len(jobsIn) > 0 { + t.Errorf("some jobs not found: %v", jobsIn) + } +} diff --git a/lulu.go b/lulu.go index 9228e28..8532052 100644 --- a/lulu.go +++ b/lulu.go @@ -255,30 +255,30 @@ func (c *Client) Jobs(queries ...PrintJobQuery) ([]PrintJob, error) { q.apply(queries...) qvals := q.vals() - verify := func(v any) error { - resp := v.(*jobsResp) - if int(resp.Count) != len(resp.Results) { - return fmt.Errorf("count (%d) != len(results) (%d)", resp.Count, len(resp.Results)) - } else if len(resp.Results) == 0 && resp.Next != "" { - return fmt.Errorf("no results on this page, but server returned a next page: %s", resp.Next) - } - return nil - } - var jobs []PrintJob + var cnt uint for page := 1; ; page++ { qvals.Set("page", fmt.Sprint(page)) var resp jobsResp - if err := c.getQueryDecodeVerify(printJobsPath, qvals, &resp, verify); err != nil { + if err := c.getQueryDecode(printJobsPath, qvals, &resp); err != nil { return jobs, pkgErr(err) } + + cnt = resp.Count + if len(resp.Results) == 0 && resp.Next != "" { + return jobs, pkgErr(fmt.Errorf("no results on this page, but server returned a next page: %s", resp.Next)) + } if len(resp.Results) > 0 { jobs = append(jobs, resp.Results...) } if len(resp.Results) == 0 || len(resp.Next) == 0 { - return jobs, nil + break } } + if uint(len(jobs)) != cnt { + return jobs, pkgErr(fmt.Errorf("expected %d jobs, got %d", cnt, len(jobs))) + } + return jobs, nil } // Job retrieves the print job with the given ID. @@ -388,13 +388,11 @@ func (c *Client) Cancel(id uint64) error { // getDecode sends a GET request and unmarshals the response. func (c *Client) getDecode(path string, v any) error { - verify := func(v any) error { return nil } - return c.getQueryDecodeVerify(path, nil, v, verify) + return c.getQueryDecode(path, url.Values{}, v) } -// getDecodeVerify sends a GET /path/?query request and unmarshals and -// verifies the response. -func (c *Client) getQueryDecodeVerify(path string, query url.Values, v any, verify func(any) error) error { +// getQueryDecode sends a GET path?query request and unmarshals the response into v. +func (c *Client) getQueryDecode(path string, query url.Values, v any) error { url, err := url.JoinPath(ApiUrl, path) if err != nil { return err @@ -409,13 +407,7 @@ func (c *Client) getQueryDecodeVerify(path string, query url.Values, v any, veri if resp.StatusCode != http.StatusOK { return errRespStatus{resp} } - if err := decodeResponse(resp, v); err != nil { - return err - } - if err := verify(v); err != nil { - return errResp{resp, err} - } - return nil + return decodeResponse(resp, v) } // postDecode sends a POST request and unmarshals the response. diff --git a/print_test.go b/print_test.go index 993ead1..6ff55ba 100644 --- a/print_test.go +++ b/print_test.go @@ -38,12 +38,9 @@ func TestMarshalUnmarshalPrintableNormalization(t *testing.T) { requireUnmarshalJsonEq(t, norm, printableNormalizationJson) } -//go:embed testdata/jobsresp.json -var jobsRespJson string - var printJobSample = PrintJob{ Contact: MustParseEmailAddress("test@test.com"), - Cost: PrintJobCost{ + Cost: Cost{ LineItemCosts: nil, ShipCost: FulfillmentCost{ TotalCostExclTax: decimal.RequireFromString("132.74"), @@ -115,47 +112,6 @@ var printJobSample = PrintJob{ }, } -func TestUnmarshaljobsResp(t *testing.T) { - want := jobsResp{ - Count: 1, - Next: "https://api.lulu.com/resources/?page=1&page_size=1", - Prev: "https://api.lulu.com/resources/?page=1&page_size=1", - Results: []PrintJob{printJobSample}, - } - requireUnmarshalJsonEq(t, want, jobsRespJson) -} - -func TestJobs(t *testing.T) { - t.Fail() // TODO: create a few print jobs and retrieve them - c := newClient(t) - _, err := c.Jobs() - require.NoError(t, err) -} - -func TestJob(t *testing.T) { - contact := MustParseEmailAddress("test@test.com") - jobEid := "demo-time" - productionDelay := 120 * time.Minute - addr := shipAddrSample - shipOpt := Mail - items := []Printable{printableSample} - - c := newClient(t) - job1, err := c.Print(contact, jobEid, productionDelay, addr, shipOpt, items) - require.NoError(t, err) - require.NotZero(t, job1.Id) - - job2, err := c.Job(job1.Id) - require.NoError(t, err) - - // Ignore timestamp because job gets marked as 'modified' between - // creation and retrieval time even if it hasn't actually - // changed. - job2.Modified = job1.Modified - - require.Equal(t, job1, job2) -} - //go:embed testdata/printreq.json var printReqJson string @@ -235,7 +191,6 @@ func TestPrint(t *testing.T) { require.NotEmpty(t, jobItem.Status.Messages.Info) require.NotEmpty(t, jobItem.Status.Status) require.Equal(t, productionDelay, job.ProductionDelay) - requireMatchShipAddrValidationSample(t, job.AddressValidation) require.Equal(t, shipOpt, job.ShipOpt) requireAfter(t, job.Status.Changed, startTime) require.NotEmpty(t, job.Status.Msg) -- cgit v1.2.3