aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/lulu/cost.go2
-rw-r--r--cmd/lulu/job.go2
-rw-r--r--cmd/lulu/jobs.go2
-rw-r--r--cost_test.go22
-rw-r--r--lulu.go66
-rw-r--r--print.go2
-rw-r--r--print_test.go74
-rw-r--r--testdata/costreq.json (renamed from testdata/printjobcostreq.json)0
-rw-r--r--testdata/costresp.json (renamed from testdata/printjobcostresp.json)0
-rw-r--r--testdata/jobsresp.json (renamed from testdata/getprintjobsresp.json)0
10 files changed, 121 insertions, 49 deletions
diff --git a/cmd/lulu/cost.go b/cmd/lulu/cost.go
index 66e1cb5..1826a5c 100644
--- a/cmd/lulu/cost.go
+++ b/cmd/lulu/cost.go
@@ -37,7 +37,7 @@ func (cmd *CostCmd) Run(cli *kong.Kong, clnt *lulu.Client) error {
for i := range cmd.Items {
items[i] = cmd.Items[i].PrintJobCostLineItem
}
- cost, addrVal, err := clnt.PrintJobCost(items, cmd.ShippingAddress.Addr(), cmd.Ship)
+ cost, addrVal, err := clnt.Cost(items, cmd.ShippingAddress.Addr(), cmd.Ship)
if err != nil {
return err
}
diff --git a/cmd/lulu/job.go b/cmd/lulu/job.go
index 49948f0..e58ec19 100644
--- a/cmd/lulu/job.go
+++ b/cmd/lulu/job.go
@@ -14,7 +14,7 @@ type JobCmd struct {
}
func (cmd JobCmd) Run(clnt *lulu.Client) error {
- job, err := clnt.GetPrintJob(cmd.Id)
+ job, err := clnt.Job(cmd.Id)
if err != nil {
return err
}
diff --git a/cmd/lulu/jobs.go b/cmd/lulu/jobs.go
index f56c3e0..19deb35 100644
--- a/cmd/lulu/jobs.go
+++ b/cmd/lulu/jobs.go
@@ -19,7 +19,7 @@ type JobsCmd struct {
}
func (cmd JobsCmd) Run(clnt *lulu.Client) error {
- jobs, err := clnt.GetPrintJobs(cmd.queries()...)
+ jobs, err := clnt.Jobs(cmd.queries()...)
if err != nil {
return err
}
diff --git a/cost_test.go b/cost_test.go
index 446440d..c2f18ec 100644
--- a/cost_test.go
+++ b/cost_test.go
@@ -10,14 +10,14 @@ import (
)
var (
- //go:embed testdata/printjobcostreq.json
- printJobCostReqJson string
+ //go:embed testdata/costreq.json
+ costReqJson string
- //go:embed testdata/printjobcostresp.json
- printJobCostRespJson string
+ //go:embed testdata/costresp.json
+ costRespJson string
)
-var printJobCostReqSample = printJobCostReq{
+var costReqSample = printJobCostReq{
[]PrintJobCostLineItem{
{
32,
@@ -129,16 +129,16 @@ var printJobCostRespSample = printJobCostResp{
}
func TestMarshalPrintJobCostReq(t *testing.T) {
- requireMarshalJsonEq(t, printJobCostReqJson, printJobCostReqSample)
+ requireMarshalJsonEq(t, costReqJson, costReqSample)
}
func TestUnmarshalPrintJobCostResp(t *testing.T) {
- requireUnmarshalJsonEq(t, printJobCostRespSample, printJobCostRespJson)
+ requireUnmarshalJsonEq(t, printJobCostRespSample, costRespJson)
}
-func TestPrintJobCost(t *testing.T) {
+func TestCost(t *testing.T) {
c := newClient(t)
- items := printJobCostReqSample.LineItems
+ items := costReqSample.LineItems
addr := ShippingAddress{
City: "Lübeck",
Country: "DE",
@@ -147,8 +147,8 @@ func TestPrintJobCost(t *testing.T) {
Street1: "Holstenstr. 40",
Phone: MustParsePhoneNumber("844-212-0689"),
}
- shiplvl := printJobCostReqSample.ShipOpt
- cost, av, err := c.PrintJobCost(items, addr, shiplvl)
+ shiplvl := costReqSample.ShipOpt
+ cost, av, err := c.Cost(items, addr, shiplvl)
require.NoError(t, err)
require.Equal(t, printJobCostRespSample.AddressValidation, av)
requireCurrency(t, cost.Currency)
diff --git a/lulu.go b/lulu.go
index 212a895..53ce2fd 100644
--- a/lulu.go
+++ b/lulu.go
@@ -217,11 +217,11 @@ func (c *Client) GetCoverValidation(id uint) (CoverValidation, error) {
return rec, nil
}
-// PrintJobCost calculates the cost of a hypothetical print order without
+// Cost calculates the cost of a hypothetical print order without
// actually creating a print job.
//
// https://api.lulu.com/docs/#tag/Print-Job-Cost-Calculations/operation/Print-Job-cost-calculations_create
-func (c *Client) PrintJobCost(items []PrintJobCostLineItem, addr ShippingAddress, shipOpt ShippingLevel) (PrintJobCost, ShippingAddressValidation, error) {
+func (c *Client) Cost(items []PrintJobCostLineItem, addr ShippingAddress, shipOpt ShippingLevel) (PrintJobCost, ShippingAddressValidation, error) {
reqAddr := printJobCostReqShipAddr{
City: addr.City,
Country: addr.Country,
@@ -240,17 +240,17 @@ func (c *Client) PrintJobCost(items []PrintJobCostLineItem, addr ShippingAddress
return resp.cost(), resp.AddressValidation, nil
}
-// GetPrintJobs retrieves a list of all print jobs that have been
-// created, filtered by a set of optional query parameters.
+// Jobs retrieves a list of all print jobs that have been created,
+// filtered by a set of optional query parameters.
//
// https://api.lulu.com/docs/#tag/Print-Jobs/operation/Print-Jobs_list
-func (c *Client) GetPrintJobs(queries ...PrintJobQuery) ([]PrintJob, error) {
+func (c *Client) Jobs(queries ...PrintJobQuery) ([]PrintJob, error) {
var q printJobQueries
q.apply(queries...)
qvals := q.vals()
verify := func(v any) error {
- resp := v.(*getPrintJobsResp)
+ 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 != "" {
@@ -262,7 +262,7 @@ func (c *Client) GetPrintJobs(queries ...PrintJobQuery) ([]PrintJob, error) {
var jobs []PrintJob
for page := 1; ; page++ {
qvals.Set("page", fmt.Sprint(page))
- var resp getPrintJobsResp
+ var resp jobsResp
if err := c.getQueryDecodeVerify(printJobsPath, qvals, &resp, verify); err != nil {
return jobs, pkgErr(err)
}
@@ -275,10 +275,10 @@ func (c *Client) GetPrintJobs(queries ...PrintJobQuery) ([]PrintJob, error) {
}
}
-// GetPrintJob retrieves the print job with the given ID.
+// Job retrieves the print job with the given ID.
//
// https://api.lulu.com/docs/#tag/Print-Jobs/operation/Print-Jobs_read
-func (c *Client) GetPrintJob(id uint64) (PrintJob, error) {
+func (c *Client) Job(id uint64) (PrintJob, error) {
var job PrintJob
path, err := url.JoinPath(printJobsPath, fmt.Sprint(id))
if err != nil {
@@ -361,6 +361,25 @@ func verifyProductionDelay(delay time.Duration) error {
return nil
}
+// Cancel cancels the print job with the given ID.
+//
+// https://api.lulu.com/docs/#tag/Print-Jobs/operation/Print-Jobs_status_cancel
+func (c *Client) Cancel(id uint64) error {
+ path, err := url.JoinPath(printJobsPath, fmt.Sprint(id), "status")
+ if err != nil {
+ return pkgErr(err)
+ }
+ req := map[string]OrderStatus{"name": OrderCanceled}
+ var status PrintJobStatus
+ if err := c.putDecode(path, req, &status); err != nil {
+ return pkgErr(err)
+ }
+ if status.Status != OrderCanceled {
+ return pkgErr(fmt.Errorf("cancel job %d: expected %s, got %s", id, OrderCanceled, status.Status))
+ }
+ return nil
+}
+
// 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 }
@@ -421,6 +440,35 @@ func (c *Client) post(path string, payload any) (*http.Response, error) {
return c.c.Post(url, "application/json", bytes.NewBuffer(body))
}
+// putDecode sends a PUT request and unmarshals the response.
+func (c *Client) putDecode(path string, payload any, v any) error {
+ body, err := json.Marshal(payload)
+ if err != nil {
+ return errEncReq{payload, path, err}
+ }
+ url, err := url.JoinPath(ApiUrl, path)
+ if err != nil {
+ return err
+ }
+
+ debugf("PUT %s request: `%s`\n", url, body)
+
+ req, err := http.NewRequest(http.MethodPut, url, bytes.NewBuffer(body))
+ if err != nil {
+ return err
+ }
+ req.Header.Set("Content-Type", "application/json")
+ resp, err := c.c.Do(req)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != http.StatusOK {
+ return errRespStatus{resp}
+ }
+ return decodeResponse(resp, v)
+}
+
func decodeResponse(resp *http.Response, v any) error {
body, err := io.ReadAll(resp.Body)
if err != nil {
diff --git a/print.go b/print.go
index 22880ed..8d48d17 100644
--- a/print.go
+++ b/print.go
@@ -70,7 +70,7 @@ type Reprintable struct {
Title string `json:"title"`
}
-type getPrintJobsResp struct {
+type jobsResp struct {
Count uint `json:"count"`
Next string `json:"next"`
Prev string `json:"previous"`
diff --git a/print_test.go b/print_test.go
index b5d87f4..79381a1 100644
--- a/print_test.go
+++ b/print_test.go
@@ -9,8 +9,8 @@ import (
"github.com/stretchr/testify/require"
)
-//go:embed testdata/getprintjobsresp.json
-var getPrintJobsRespJson string
+//go:embed testdata/jobsresp.json
+var jobsRespJson string
var printJobSample = PrintJob{
Contact: MustParseEmailAddress("test@test.com"),
@@ -85,23 +85,47 @@ var printJobSample = PrintJob{
},
}
-func TestUnmarshalGetPrintJobsResp(t *testing.T) {
- want := getPrintJobsResp{
+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, getPrintJobsRespJson)
+ requireUnmarshalJsonEq(t, want, jobsRespJson)
}
-func TestGetPrintJobs(t *testing.T) {
+func TestJobs(t *testing.T) {
t.Fail() // TODO: create a few print jobs and retrieve them
c := newClient(t)
- _, err := c.GetPrintJobs()
+ _, 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
@@ -203,7 +227,7 @@ func TestReprint(t *testing.T) {
// Wait for it to be assigned a printable_id
tpoll(t, func() bool {
- job1, err = c.GetPrintJob(id1)
+ job1, err = c.Job(id1)
require.NoError(t, err)
require.Len(t, job1.LineItems, 1)
return job1.LineItems[0].Status.Status != ItemCreated
@@ -231,30 +255,30 @@ func TestReprint(t *testing.T) {
require.Equal(t, item1.Mfg, item2.Mfg)
}
-func TestGetPrintJob(t *testing.T) {
+func TestCancel(t *testing.T) {
+ // Print
+ c := newClient(t)
contact := MustParseEmailAddress("test@test.com")
- jobEid := "demo-time"
+ jobEid := "cancel-test"
productionDelay := 120 * time.Minute
addr := shipAddrSample
shipOpt := Mail
- items := []Printable{printableSample}
-
- c := newClient(t)
- job1, err := c.Print(contact, jobEid, productionDelay, addr, shipOpt, items)
+ item := printableSample
+ job, err := c.Print(contact, jobEid, productionDelay, addr, shipOpt, []Printable{item})
require.NoError(t, err)
- require.NotZero(t, job1.Id)
+ id := job.Id
+ require.NotZero(t, id)
- job2, err := c.GetPrintJob(job1.Id)
+ // Job exists
+ _, err = c.Job(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)
-}
+ // Cancel
+ err = c.Cancel(id)
+ require.NoError(t, err)
-func TestCancel(t *testing.T) {
- t.Fail() // TODO
+ // Job canceled
+ job, err = c.Job(id)
+ require.NoError(t, err)
+ require.Equal(t, OrderCanceled, job.Status.Status)
}
diff --git a/testdata/printjobcostreq.json b/testdata/costreq.json
index d521f77..d521f77 100644
--- a/testdata/printjobcostreq.json
+++ b/testdata/costreq.json
diff --git a/testdata/printjobcostresp.json b/testdata/costresp.json
index f633183..f633183 100644
--- a/testdata/printjobcostresp.json
+++ b/testdata/costresp.json
diff --git a/testdata/getprintjobsresp.json b/testdata/jobsresp.json
index 3f43d2c..3f43d2c 100644
--- a/testdata/getprintjobsresp.json
+++ b/testdata/jobsresp.json