Sort Order for tasks (#110)
This commit is contained in:
parent
e890001ee1
commit
d8399e374c
22 changed files with 2080 additions and 994 deletions
|
@ -45,6 +45,8 @@ This document describes the different errors Vikunja can return.
|
||||||
| 4010 | 400 | Cannot relate a task with itself. |
|
| 4010 | 400 | Cannot relate a task with itself. |
|
||||||
| 4011 | 404 | The task attachment does not exist. |
|
| 4011 | 404 | The task attachment does not exist. |
|
||||||
| 4012 | 400 | The task attachment is too large. |
|
| 4012 | 400 | The task attachment is too large. |
|
||||||
|
| 4013 | 400 | The task sort param is invalid. |
|
||||||
|
| 4014 | 400 | The task sort order is invalid. |
|
||||||
| 5001 | 404 | The namspace does not exist. |
|
| 5001 | 404 | The namspace does not exist. |
|
||||||
| 5003 | 403 | The user does not have access to the specified namespace. |
|
| 5003 | 403 | The user does not have access to the specified namespace. |
|
||||||
| 5006 | 400 | The namespace name cannot be empty. |
|
| 5006 | 400 | The namespace name cannot be empty. |
|
||||||
|
|
13
go.mod
13
go.mod
|
@ -25,15 +25,12 @@ require (
|
||||||
github.com/c2h5oh/datasize v0.0.0-20171227191756-4eba002a5eae
|
github.com/c2h5oh/datasize v0.0.0-20171227191756-4eba002a5eae
|
||||||
github.com/client9/misspell v0.3.4
|
github.com/client9/misspell v0.3.4
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||||
github.com/creack/pty v1.1.9 // indirect
|
|
||||||
github.com/d4l3k/messagediff v1.2.1 // indirect
|
github.com/d4l3k/messagediff v1.2.1 // indirect
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||||
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835
|
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835
|
||||||
github.com/garyburd/redigo v1.6.0 // indirect
|
github.com/garyburd/redigo v1.6.0 // indirect
|
||||||
github.com/gin-gonic/gin v1.5.0 // indirect
|
|
||||||
github.com/go-openapi/jsonreference v0.19.3 // indirect
|
github.com/go-openapi/jsonreference v0.19.3 // indirect
|
||||||
github.com/go-openapi/spec v0.19.4 // indirect
|
github.com/go-openapi/spec v0.19.4 // indirect
|
||||||
github.com/go-playground/universal-translator v0.17.0 // indirect
|
|
||||||
github.com/go-redis/redis v6.15.2+incompatible
|
github.com/go-redis/redis v6.15.2+incompatible
|
||||||
github.com/go-sql-driver/mysql v1.4.1
|
github.com/go-sql-driver/mysql v1.4.1
|
||||||
github.com/go-xorm/builder v0.3.4
|
github.com/go-xorm/builder v0.3.4
|
||||||
|
@ -41,22 +38,21 @@ require (
|
||||||
github.com/go-xorm/tests v0.5.6 // indirect
|
github.com/go-xorm/tests v0.5.6 // indirect
|
||||||
github.com/go-xorm/xorm v0.7.1
|
github.com/go-xorm/xorm v0.7.1
|
||||||
github.com/go-xorm/xorm-redis-cache v0.0.0-20180727005610-859b313566b2
|
github.com/go-xorm/xorm-redis-cache v0.0.0-20180727005610-859b313566b2
|
||||||
|
github.com/golang/protobuf v1.3.2 // indirect
|
||||||
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc
|
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc
|
||||||
github.com/imdario/mergo v0.3.7
|
github.com/imdario/mergo v0.3.7
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||||
github.com/jgautheron/goconst v0.0.0-20170703170152-9740945f5dcb
|
github.com/jgautheron/goconst v0.0.0-20170703170152-9740945f5dcb
|
||||||
github.com/json-iterator/go v1.1.8 // indirect
|
|
||||||
github.com/kr/pty v1.1.8 // indirect
|
|
||||||
github.com/labstack/echo/v4 v4.1.11
|
github.com/labstack/echo/v4 v4.1.11
|
||||||
github.com/labstack/gommon v0.3.0
|
github.com/labstack/gommon v0.3.0
|
||||||
github.com/laurent22/ical-go v0.1.1-0.20181107184520-7e5d6ade8eef
|
github.com/laurent22/ical-go v0.1.1-0.20181107184520-7e5d6ade8eef
|
||||||
github.com/leodido/go-urn v1.2.0 // indirect
|
|
||||||
github.com/mailru/easyjson v0.7.0 // indirect
|
github.com/mailru/easyjson v0.7.0 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.4 // indirect
|
github.com/mattn/go-colorable v0.1.4 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.10 // indirect
|
github.com/mattn/go-isatty v0.0.10 // indirect
|
||||||
github.com/mattn/go-oci8 v0.0.0-20181130072307-052f5d97b9b6 // indirect
|
github.com/mattn/go-oci8 v0.0.0-20181130072307-052f5d97b9b6 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.4 // indirect
|
github.com/mattn/go-runewidth v0.0.4 // indirect
|
||||||
github.com/mattn/go-sqlite3 v1.10.0
|
github.com/mattn/go-sqlite3 v1.10.0
|
||||||
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
|
||||||
github.com/olekukonko/tablewriter v0.0.1
|
github.com/olekukonko/tablewriter v0.0.1
|
||||||
github.com/onsi/ginkgo v1.7.0 // indirect
|
github.com/onsi/ginkgo v1.7.0 // indirect
|
||||||
github.com/onsi/gomega v1.4.3 // indirect
|
github.com/onsi/gomega v1.4.3 // indirect
|
||||||
|
@ -79,15 +75,12 @@ require (
|
||||||
golang.org/x/crypto v0.0.0-20191128160524-b544559bb6d1
|
golang.org/x/crypto v0.0.0-20191128160524-b544559bb6d1
|
||||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422
|
golang.org/x/lint v0.0.0-20190409202823-959b441ac422
|
||||||
golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 // indirect
|
golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 // indirect
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect
|
|
||||||
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 // indirect
|
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 // indirect
|
||||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d // indirect
|
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 // indirect
|
|
||||||
google.golang.org/appengine v1.5.0 // indirect
|
google.golang.org/appengine v1.5.0 // indirect
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
||||||
gopkg.in/d4l3k/messagediff.v1 v1.2.1
|
gopkg.in/d4l3k/messagediff.v1 v1.2.1
|
||||||
gopkg.in/go-playground/validator.v9 v9.30.2 // indirect
|
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||||
gopkg.in/testfixtures.v2 v2.5.3
|
gopkg.in/testfixtures.v2 v2.5.3
|
||||||
gopkg.in/yaml.v2 v2.2.7 // indirect
|
gopkg.in/yaml.v2 v2.2.7 // indirect
|
||||||
|
@ -97,3 +90,5 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/samedi/caldav-go => github.com/kolaente/caldav-go v3.0.1-0.20190524174923-9e5cd1688227+incompatible // Branch: feature/dynamic-supported-components, PR: https://github.com/samedi/caldav-go/pull/6 and https://github.com/samedi/caldav-go/pull/7
|
replace github.com/samedi/caldav-go => github.com/kolaente/caldav-go v3.0.1-0.20190524174923-9e5cd1688227+incompatible // Branch: feature/dynamic-supported-components, PR: https://github.com/samedi/caldav-go/pull/6 and https://github.com/samedi/caldav-go/pull/7
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
119
go.sum
119
go.sum
|
@ -1,24 +1,6 @@
|
||||||
cloud.google.com/go v0.33.1/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.33.1/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg=
|
cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
code.vikunja.io/web v0.0.0-20190507193736-edb39812af9c h1:L8aPCsaLQe9qytRavkRqipse64EbDK8mFijm+9SKf7I=
|
|
||||||
code.vikunja.io/web v0.0.0-20190507193736-edb39812af9c/go.mod h1:9dOotUqYZJhDhimNh4Xo4e2i+8cR+qPFEQNCUzaplsI=
|
|
||||||
code.vikunja.io/web v0.0.0-20190628071027-b5c16e24b0a7 h1:P9ncMaJE7RbYqBXF9lwT0hab7EPwuHOPslz3k1VxFs8=
|
|
||||||
code.vikunja.io/web v0.0.0-20190628071027-b5c16e24b0a7/go.mod h1:cuP1/ieGWAZzgQGw+QPt6Y5F0fVb/8Ol5NV4QSezGdo=
|
|
||||||
code.vikunja.io/web v0.0.0-20190628075253-b457b5a1a332 h1:gXxyLkjhgN+vqrLvPyqyScyG5fbu44FJp61TvntWM24=
|
|
||||||
code.vikunja.io/web v0.0.0-20190628075253-b457b5a1a332/go.mod h1:cuP1/ieGWAZzgQGw+QPt6Y5F0fVb/8Ol5NV4QSezGdo=
|
|
||||||
code.vikunja.io/web v0.0.0-20191021211916-f7834b02a174 h1:hBY+r6bzGEfHxolaXbiVoz2LBNNnyHZK7d7Ga4Jowu8=
|
|
||||||
code.vikunja.io/web v0.0.0-20191021211916-f7834b02a174/go.mod h1:cuP1/ieGWAZzgQGw+QPt6Y5F0fVb/8Ol5NV4QSezGdo=
|
|
||||||
code.vikunja.io/web v0.0.0-20191022193355-23a3d145177a h1:exDC9eZ+SK0GT3zB/5f3OBahWzbTZlvX9OfZWgqlbeI=
|
|
||||||
code.vikunja.io/web v0.0.0-20191022193355-23a3d145177a/go.mod h1:cuP1/ieGWAZzgQGw+QPt6Y5F0fVb/8Ol5NV4QSezGdo=
|
|
||||||
code.vikunja.io/web v0.0.0-20191022195605-8edfc5d33c79 h1:U2px27G/b082nUu8vO21wFNKF9BM+5YQJj4XRZiyn2I=
|
|
||||||
code.vikunja.io/web v0.0.0-20191022195605-8edfc5d33c79/go.mod h1:cuP1/ieGWAZzgQGw+QPt6Y5F0fVb/8Ol5NV4QSezGdo=
|
|
||||||
code.vikunja.io/web v0.0.0-20191023144416-3ee093147b6d h1:zhNidbAwqJSnkql03i7aHDUMyQo1vM8yR1Ks495FKvc=
|
|
||||||
code.vikunja.io/web v0.0.0-20191023144416-3ee093147b6d/go.mod h1:cuP1/ieGWAZzgQGw+QPt6Y5F0fVb/8Ol5NV4QSezGdo=
|
|
||||||
code.vikunja.io/web v0.0.0-20191023145656-bce8b505205d h1:Fw5eiTr4p82l4PLaML1ARgx3fjyebxVNvPsCz727brk=
|
|
||||||
code.vikunja.io/web v0.0.0-20191023145656-bce8b505205d/go.mod h1:cuP1/ieGWAZzgQGw+QPt6Y5F0fVb/8Ol5NV4QSezGdo=
|
|
||||||
code.vikunja.io/web v0.0.0-20191023190415-502bbbbd9dfa h1:rtYKpdT/6wGgxGNFUzl9Q/AHgS778+rSC20AcBPNu/I=
|
|
||||||
code.vikunja.io/web v0.0.0-20191023190415-502bbbbd9dfa/go.mod h1:cuP1/ieGWAZzgQGw+QPt6Y5F0fVb/8Ol5NV4QSezGdo=
|
|
||||||
code.vikunja.io/web v0.0.0-20191023202526-f337750c3573 h1:q+nf3ao4vLpoAaksuk6lkRAMAcD2grOPNj/HwjejLl4=
|
code.vikunja.io/web v0.0.0-20191023202526-f337750c3573 h1:q+nf3ao4vLpoAaksuk6lkRAMAcD2grOPNj/HwjejLl4=
|
||||||
code.vikunja.io/web v0.0.0-20191023202526-f337750c3573/go.mod h1:cuP1/ieGWAZzgQGw+QPt6Y5F0fVb/8Ol5NV4QSezGdo=
|
code.vikunja.io/web v0.0.0-20191023202526-f337750c3573/go.mod h1:cuP1/ieGWAZzgQGw+QPt6Y5F0fVb/8Ol5NV4QSezGdo=
|
||||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
|
@ -31,8 +13,6 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN
|
||||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
|
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
|
@ -55,9 +35,6 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
|
||||||
github.com/cweill/gotests v1.5.3 h1:k3t4wW/x/YNixWZJhUIn+mivmK5iV1tJVOwVYkx0UcU=
|
|
||||||
github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U=
|
github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U=
|
||||||
github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo=
|
github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
@ -81,42 +58,27 @@ github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NB
|
||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
|
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
|
||||||
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
||||||
github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
|
|
||||||
github.com/go-chi/chi v3.3.3+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
|
github.com/go-chi/chi v3.3.3+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
|
||||||
github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0=
|
github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0=
|
||||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||||
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
|
||||||
github.com/go-openapi/jsonpointer v0.19.0 h1:FTUMcX77w5rQkClIzDtTxvn6Bsa894CcrzNj2MMfeg8=
|
|
||||||
github.com/go-openapi/jsonpointer v0.19.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
|
||||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||||
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
||||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
github.com/go-openapi/jsonreference v0.17.0 h1:yJW3HCkTHg7NOA+gZ83IPHzUSnUzGXhGmsdiCcMexbA=
|
github.com/go-openapi/jsonreference v0.17.0 h1:yJW3HCkTHg7NOA+gZ83IPHzUSnUzGXhGmsdiCcMexbA=
|
||||||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||||
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
|
||||||
github.com/go-openapi/jsonreference v0.19.0 h1:BqWKpV1dFd+AuiKlgtddwVIFQsuMpxfBDBHGfM2yNpk=
|
github.com/go-openapi/jsonreference v0.19.0 h1:BqWKpV1dFd+AuiKlgtddwVIFQsuMpxfBDBHGfM2yNpk=
|
||||||
github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||||
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
|
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
|
||||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||||
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
|
||||||
github.com/go-openapi/spec v0.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k4=
|
github.com/go-openapi/spec v0.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k4=
|
||||||
github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||||
github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc=
|
|
||||||
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
|
||||||
github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo=
|
github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo=
|
||||||
github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||||
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
|
||||||
github.com/go-openapi/swag v0.19.0 h1:Kg7Wl7LkTPlmc393QZQ/5rQadPhi7pBVEMZxyTi0Ii8=
|
|
||||||
github.com/go-openapi/swag v0.19.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
|
||||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||||
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
||||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||||
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
|
|
||||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
|
||||||
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
|
|
||||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
|
||||||
github.com/go-redis/redis v6.14.0+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
github.com/go-redis/redis v6.14.0+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||||
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
|
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
|
||||||
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||||
|
@ -147,7 +109,6 @@ github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
|
||||||
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc h1:cJlkeAx1QYgO5N80aF5xRGstVsRQwgLR7uA2FnP1ZjY=
|
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc h1:cJlkeAx1QYgO5N80aF5xRGstVsRQwgLR7uA2FnP1ZjY=
|
||||||
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
|
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
|
||||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||||
|
@ -169,63 +130,42 @@ github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqx
|
||||||
github.com/json-iterator/go v0.0.0-20180806060727-1624edc4454b/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v0.0.0-20180806060727-1624edc4454b/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
|
||||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
|
||||||
github.com/kolaente/caldav-go v3.0.1-0.20190524174923-9e5cd1688227+incompatible h1:PkEEpmbrFXlMul8cOplR8nkcIM/NDbx+H6fq2+vaKAA=
|
github.com/kolaente/caldav-go v3.0.1-0.20190524174923-9e5cd1688227+incompatible h1:PkEEpmbrFXlMul8cOplR8nkcIM/NDbx+H6fq2+vaKAA=
|
||||||
github.com/kolaente/caldav-go v3.0.1-0.20190524174923-9e5cd1688227+incompatible/go.mod h1:y1UhTNI4g0hVymJrI6yJ5/ohy09hNBeU8iJEZjgdDOw=
|
github.com/kolaente/caldav-go v3.0.1-0.20190524174923-9e5cd1688227+incompatible/go.mod h1:y1UhTNI4g0hVymJrI6yJ5/ohy09hNBeU8iJEZjgdDOw=
|
||||||
github.com/kolaente/echo/v4 v4.0.0-20190507190305-3725a216d803/go.mod h1:3LbYC6VkwmUnmLPZ8WFdHdQHG77e9GQbjyhWdb1QvC4=
|
|
||||||
github.com/kolaente/echo/v4 v4.0.0-20190621113036-3b0700f6d073 h1:vOueKBVhcaAusqPDK/g7lRYOwqfQ0YI3oLrBV+iGZV8=
|
|
||||||
github.com/kolaente/echo/v4 v4.0.0-20190621113036-3b0700f6d073/go.mod h1:kU/7PwzgNxZH4das4XNsSpBSOD09XIF5YEPzjpkGnGE=
|
|
||||||
github.com/kolaente/echo/v4 v4.0.0-20190622213746-34000ea0f7d3 h1:5RyXbSrJtkFl1EGFgyDYwiBQMbj8sMtP33aFHnT+5YE=
|
|
||||||
github.com/kolaente/echo/v4 v4.0.0-20190622213746-34000ea0f7d3/go.mod h1:kU/7PwzgNxZH4das4XNsSpBSOD09XIF5YEPzjpkGnGE=
|
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=
|
github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=
|
||||||
github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
|
github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
|
||||||
github.com/labstack/echo/v4 v4.1.5/go.mod h1:3LbYC6VkwmUnmLPZ8WFdHdQHG77e9GQbjyhWdb1QvC4=
|
|
||||||
github.com/labstack/echo/v4 v4.1.6 h1:WOvLa4T1KzWCRpANwz0HGgWDelXSSGwIKtKBbFdHTv4=
|
|
||||||
github.com/labstack/echo/v4 v4.1.6/go.mod h1:kU/7PwzgNxZH4das4XNsSpBSOD09XIF5YEPzjpkGnGE=
|
|
||||||
github.com/labstack/echo/v4 v4.1.7-0.20190627175217-8fb7b5be270f h1:fNJtR+TNyxTdYCZU40fc8Or8RyBqMOKYNv+Zay5gjvk=
|
github.com/labstack/echo/v4 v4.1.7-0.20190627175217-8fb7b5be270f h1:fNJtR+TNyxTdYCZU40fc8Or8RyBqMOKYNv+Zay5gjvk=
|
||||||
github.com/labstack/echo/v4 v4.1.7-0.20190627175217-8fb7b5be270f/go.mod h1:kU/7PwzgNxZH4das4XNsSpBSOD09XIF5YEPzjpkGnGE=
|
github.com/labstack/echo/v4 v4.1.7-0.20190627175217-8fb7b5be270f/go.mod h1:kU/7PwzgNxZH4das4XNsSpBSOD09XIF5YEPzjpkGnGE=
|
||||||
github.com/labstack/echo/v4 v4.1.11 h1:z0BZoArY4FqdpUEl+wlHp4hnr/oSR6MTmQmv8OHSoww=
|
github.com/labstack/echo/v4 v4.1.11 h1:z0BZoArY4FqdpUEl+wlHp4hnr/oSR6MTmQmv8OHSoww=
|
||||||
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
|
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
|
||||||
github.com/labstack/gommon v0.2.8 h1:JvRqmeZcfrHC5u6uVleB4NxxNbzx6gpbJiQknDbKQu0=
|
|
||||||
github.com/labstack/gommon v0.2.8/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
|
|
||||||
github.com/labstack/gommon v0.2.9 h1:heVeuAYtevIQVYkGj6A41dtfT91LrvFG220lavpWhrU=
|
github.com/labstack/gommon v0.2.9 h1:heVeuAYtevIQVYkGj6A41dtfT91LrvFG220lavpWhrU=
|
||||||
github.com/labstack/gommon v0.2.9/go.mod h1:E8ZTmW9vw5az5/ZyHWCp0Lw4OH2ecsaBP1C/NKavGG4=
|
github.com/labstack/gommon v0.2.9/go.mod h1:E8ZTmW9vw5az5/ZyHWCp0Lw4OH2ecsaBP1C/NKavGG4=
|
||||||
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
|
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
|
||||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||||
github.com/laurent22/ical-go v0.1.1-0.20181107184520-7e5d6ade8eef h1:RZnRnSID1skF35j/15KJ6hKZkdIC/teQClJK5wP5LU4=
|
github.com/laurent22/ical-go v0.1.1-0.20181107184520-7e5d6ade8eef h1:RZnRnSID1skF35j/15KJ6hKZkdIC/teQClJK5wP5LU4=
|
||||||
github.com/laurent22/ical-go v0.1.1-0.20181107184520-7e5d6ade8eef/go.mod h1:4LATl0uhhtytR6p9n1AlktDyIz4u2iUnWEdI3L/hXiw=
|
github.com/laurent22/ical-go v0.1.1-0.20181107184520-7e5d6ade8eef/go.mod h1:4LATl0uhhtytR6p9n1AlktDyIz4u2iUnWEdI3L/hXiw=
|
||||||
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
|
|
||||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
|
||||||
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
|
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
|
||||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
|
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
|
||||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
|
||||||
github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983 h1:wL11wNW7dhKIcRCHSm4sHKPWz0tt4mwBsVodG7+Xyqg=
|
|
||||||
github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
|
||||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
|
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
|
||||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||||
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
|
||||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
|
||||||
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
|
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
|
||||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
|
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
|
||||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
|
||||||
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
|
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
|
||||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
||||||
|
@ -245,10 +185,11 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||||
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||||
github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88=
|
github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88=
|
||||||
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
@ -314,31 +255,20 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
|
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
|
||||||
github.com/swaggo/gin-swagger v1.1.0/go.mod h1:FQlm07YuT1glfN3hQiO11UQ2m39vOCZ/aa3WWr5E+XU=
|
|
||||||
github.com/swaggo/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05Nn6vPhc7OI=
|
github.com/swaggo/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05Nn6vPhc7OI=
|
||||||
github.com/swaggo/swag v1.4.0/go.mod h1:hog2WgeMOrQ/LvQ+o1YGTeT+vWVrbi0SiIslBtxKTyM=
|
|
||||||
github.com/swaggo/swag v1.5.0 h1:haK8VG3hj+v/c8hQ4f3U+oYpkdI/26m9LAUTXHOv+2U=
|
|
||||||
github.com/swaggo/swag v1.5.0/go.mod h1:+xZrnu5Ut3GcUkKAJm9spnOooIS1WB1cUOkLNPrvrE0=
|
|
||||||
github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y=
|
github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y=
|
||||||
github.com/swaggo/swag v1.6.3 h1:N+uVPGP4H2hXoss2pt5dctoSUPKKRInr6qcTMOm0usI=
|
github.com/swaggo/swag v1.6.3 h1:N+uVPGP4H2hXoss2pt5dctoSUPKKRInr6qcTMOm0usI=
|
||||||
github.com/swaggo/swag v1.6.3/go.mod h1:wcc83tB4Mb2aNiL/HP4MFeQdpHUrca+Rp/DRNgWAUio=
|
github.com/swaggo/swag v1.6.3/go.mod h1:wcc83tB4Mb2aNiL/HP4MFeQdpHUrca+Rp/DRNgWAUio=
|
||||||
github.com/ugorji/go v1.1.1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
github.com/ugorji/go v1.1.1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
||||||
github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
|
||||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||||
github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0=
|
github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0=
|
||||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
|
||||||
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||||
github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
|
||||||
github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA=
|
|
||||||
github.com/ugorji/go/codec v1.1.5-pre/go.mod h1:tULtS6Gy1AE1yCENaw4Vb//HLH5njI2tfCQDUqRd8fI=
|
github.com/ugorji/go/codec v1.1.5-pre/go.mod h1:tULtS6Gy1AE1yCENaw4Vb//HLH5njI2tfCQDUqRd8fI=
|
||||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
|
||||||
github.com/ulule/limiter/v3 v3.3.0 h1:DuMRthpkl1wW9Em6xOVw5HMHnbDumSIDydiMqP0PTXs=
|
github.com/ulule/limiter/v3 v3.3.0 h1:DuMRthpkl1wW9Em6xOVw5HMHnbDumSIDydiMqP0PTXs=
|
||||||
github.com/ulule/limiter/v3 v3.3.0/go.mod h1:E6sfg3hfRgW+yFvkE/rZf6YLqXYFMWTmZaZKvdEiQsA=
|
github.com/ulule/limiter/v3 v3.3.0/go.mod h1:E6sfg3hfRgW+yFvkE/rZf6YLqXYFMWTmZaZKvdEiQsA=
|
||||||
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
|
|
||||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
|
||||||
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
|
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
|
||||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
|
@ -354,16 +284,11 @@ golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnf
|
||||||
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284 h1:rlLehGeYg6jfoyz/eDqDU1iRXLKfR42nnNh57ytKEWo=
|
|
||||||
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 h1:ydJNl0ENAG67pFbB+9tfhiL2pYqLhfoaZFw/cjLhY4A=
|
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 h1:ydJNl0ENAG67pFbB+9tfhiL2pYqLhfoaZFw/cjLhY4A=
|
||||||
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20191128160524-b544559bb6d1 h1:anGSYQpPhQwXlwsu5wmfq0nWkCNaMEMUwAv13Y92hd8=
|
golang.org/x/crypto v0.0.0-20191128160524-b544559bb6d1 h1:anGSYQpPhQwXlwsu5wmfq0nWkCNaMEMUwAv13Y92hd8=
|
||||||
golang.org/x/crypto v0.0.0-20191128160524-b544559bb6d1/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191128160524-b544559bb6d1/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI=
|
golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI=
|
||||||
|
@ -376,9 +301,7 @@ golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73r
|
||||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc h1:a3CU5tJYVj92DY2LaA1kUkrsqD5/3mLDhx2NcNqyW+0=
|
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc h1:a3CU5tJYVj92DY2LaA1kUkrsqD5/3mLDhx2NcNqyW+0=
|
||||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190322120337-addf6b3196f6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw=
|
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw=
|
||||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
@ -388,10 +311,6 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20191011234655-491137f69257 h1:ry8e2D+cwaV6hk7lb3aRTjjZo24shrbK0e11QEOkTIg=
|
|
||||||
golang.org/x/net v0.0.0-20191011234655-491137f69257/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191021144547-ec77196f6094 h1:5O4U9trLjNpuhpynaDsqwCk+Tw6seqJz1EbqbnzHrc8=
|
|
||||||
golang.org/x/net v0.0.0-20191021144547-ec77196f6094/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 h1:e6HwijUxhDe+hPNjZQQn9bA5PW3vNmnN64U2ZW759Lk=
|
golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 h1:e6HwijUxhDe+hPNjZQQn9bA5PW3vNmnN64U2ZW759Lk=
|
||||||
golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
@ -399,34 +318,20 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTm
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qdNLDHHtQ4mlgQIZPPNA=
|
|
||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190609082536-301114b31cce/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190609082536-301114b31cce/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190621203818-d432491b9138 h1:t8BZD9RDjkm9/h7yYN6kE8oaeov5r9aztkB7zKA5Tkg=
|
|
||||||
golang.org/x/sys v0.0.0-20190621203818-d432491b9138/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k=
|
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k=
|
||||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
|
|
||||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7 h1:HmbHVPwrPEKPGLAcHSrMe6+hqSUlvZU0rab6x5EXfGU=
|
|
||||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191023145028-b69606af412f h1:HNixo/W24k2W4EliZfUFl5ApIz/dMDShw52wmWfJ8/s=
|
|
||||||
golang.org/x/sys v0.0.0-20191023145028-b69606af412f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191023151326-f89234f9a2c2 h1:I7efaDQAsIQmkTF+WSdcydwVWzK07Yuz8IFF8rNkDe0=
|
|
||||||
golang.org/x/sys v0.0.0-20191023151326-f89234f9a2c2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 h1:ZBzSG/7F4eNKz2L3GE9o300RX0Az1Bw5HF7PDraD+qU=
|
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 h1:ZBzSG/7F4eNKz2L3GE9o300RX0Az1Bw5HF7PDraD+qU=
|
||||||
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
|
@ -434,31 +339,16 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190110015856-aa033095749b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac h1:MQEvx39qSf8vyrx3XRaOe+j1UDIzKwkYOVObRgGPVqI=
|
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190628034336-212fb13d595e h1:ZlQjfVdpDxeqxRfmO30CdqWWzTvgRCj0MxaUVfxEG1k=
|
golang.org/x/tools v0.0.0-20190628034336-212fb13d595e h1:ZlQjfVdpDxeqxRfmO30CdqWWzTvgRCj0MxaUVfxEG1k=
|
||||||
golang.org/x/tools v0.0.0-20190628034336-212fb13d595e/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190628034336-212fb13d595e/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a h1:TwMENskLwU2NnWBzrJGEWHqSiGUkO/B4rfyhwqDxDYQ=
|
|
||||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191022174149-ab6dbf99d100 h1:OT2Y8iVtXGHPODZd6iwpndJmAYRiZc75IYxlufvlkLg=
|
|
||||||
golang.org/x/tools v0.0.0-20191022174149-ab6dbf99d100/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191023143423-ff611c50cd12 h1:s9/f9YHBWfC3jIKMbJElk5+EwgC58Khn6t1EdLnQ9+k=
|
|
||||||
golang.org/x/tools v0.0.0-20191023143423-ff611c50cd12/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191023163450-98e333b8b3a3 h1:4haCIJia9wHJUU7z9f7PTC8Nf599Ok93njSCHb5gJas=
|
|
||||||
golang.org/x/tools v0.0.0-20191023163450-98e333b8b3a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191023202404-2b779830f9d3 h1:0vQisIa3mUFShxg7Xyq8WFt/ArQ1soDk5A5uF62IJCc=
|
|
||||||
golang.org/x/tools v0.0.0-20191023202404-2b779830f9d3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d h1:/iIZNFGxc/a7C3yWjGcnboV+Tkc7mxr+p6fDztwoxuM=
|
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d h1:/iIZNFGxc/a7C3yWjGcnboV+Tkc7mxr+p6fDztwoxuM=
|
||||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
|
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
|
||||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
@ -470,6 +360,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/d4l3k/messagediff.v1 v1.2.1 h1:70AthpjunwzUiarMHyED52mj9UwtAnE89l1Gmrt3EU0=
|
gopkg.in/d4l3k/messagediff.v1 v1.2.1 h1:70AthpjunwzUiarMHyED52mj9UwtAnE89l1Gmrt3EU0=
|
||||||
gopkg.in/d4l3k/messagediff.v1 v1.2.1/go.mod h1:EUzikiKadqXWcD1AzJLagx0j/BeeWGtn++04Xniyg44=
|
gopkg.in/d4l3k/messagediff.v1 v1.2.1/go.mod h1:EUzikiKadqXWcD1AzJLagx0j/BeeWGtn++04Xniyg44=
|
||||||
|
@ -477,8 +368,6 @@ gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||||
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
||||||
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
|
||||||
gopkg.in/go-playground/validator.v9 v9.30.2/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||||
gopkg.in/stretchr/testify.v1 v1.2.2 h1:yhQC6Uy5CqibAIlk1wlusa/MJ3iAN49/BsR/dCCKz3M=
|
gopkg.in/stretchr/testify.v1 v1.2.2 h1:yhQC6Uy5CqibAIlk1wlusa/MJ3iAN49/BsR/dCCKz3M=
|
||||||
|
@ -491,8 +380,6 @@ gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
|
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
|
||||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA=
|
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA=
|
||||||
|
|
|
@ -90,38 +90,49 @@ func TestTaskCollection(t *testing.T) {
|
||||||
assert.NotContains(t, rec.Body.String(), `task #14`)
|
assert.NotContains(t, rec.Body.String(), `task #14`)
|
||||||
})
|
})
|
||||||
t.Run("Sort Order", func(t *testing.T) {
|
t.Run("Sort Order", func(t *testing.T) {
|
||||||
// should equal priority desc
|
// TODO: Add more cases
|
||||||
|
// should equal priority asc
|
||||||
t.Run("by priority", func(t *testing.T) {
|
t.Run("by priority", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"priority"}}, urlParams)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}}, urlParams)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,`)
|
assert.Contains(t, rec.Body.String(), `{"id":33,"text":"task #33 with percent done","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0.5,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
|
||||||
})
|
})
|
||||||
t.Run("by priority desc", func(t *testing.T) {
|
t.Run("by priority desc", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"prioritydesc"}}, urlParams)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"desc"}}, urlParams)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,`)
|
assert.Contains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,`)
|
||||||
})
|
})
|
||||||
t.Run("by priority asc", func(t *testing.T) {
|
t.Run("by priority asc", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"priorityasc"}}, urlParams)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"asc"}}, urlParams)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `{"id":33,"text":"task #33 with percent done","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0.5,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
|
assert.Contains(t, rec.Body.String(), `{"id":33,"text":"task #33 with percent done","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0.5,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
|
||||||
})
|
})
|
||||||
// should equal duedate desc
|
// should equal duedate asc
|
||||||
t.Run("by duedate", func(t *testing.T) {
|
t.Run("by duedate", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"duedate"}}, urlParams)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date_unix"}}, urlParams)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
|
assert.Contains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"doneAt":0,"dueDate":1543616724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
|
||||||
})
|
})
|
||||||
t.Run("by duedate desc", func(t *testing.T) {
|
t.Run("by duedate desc", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"duedatedesc"}}, urlParams)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date_unix"}, "order_by": []string{"desc"}}, urlParams)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
|
assert.Contains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
|
||||||
})
|
})
|
||||||
t.Run("by duedate asc", func(t *testing.T) {
|
t.Run("by duedate asc", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"duedateasc"}}, urlParams)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date_unix"}, "order_by": []string{"asc"}}, urlParams)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"doneAt":0,"dueDate":1543616724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
|
assert.Contains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"doneAt":0,"dueDate":1543616724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
|
||||||
})
|
})
|
||||||
|
t.Run("invalid sort parameter", func(t *testing.T) {
|
||||||
|
_, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"loremipsum"}}, urlParams)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assertHandlerErrorCode(t, err, models.ErrCodeInvalidSortParam)
|
||||||
|
})
|
||||||
|
t.Run("invalid sort order", func(t *testing.T) {
|
||||||
|
_, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"id"}, "order_by": []string{"loremipsum"}}, urlParams)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assertHandlerErrorCode(t, err, models.ErrCodeInvalidSortOrder)
|
||||||
|
})
|
||||||
t.Run("invalid parameter", func(t *testing.T) {
|
t.Run("invalid parameter", func(t *testing.T) {
|
||||||
// Invalid parameter should not sort at all
|
// Invalid parameter should not sort at all
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"loremipsum"}}, urlParams)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"loremipsum"}}, urlParams)
|
||||||
|
@ -234,35 +245,35 @@ func TestTaskCollection(t *testing.T) {
|
||||||
assert.NotContains(t, rec.Body.String(), `task #14`)
|
assert.NotContains(t, rec.Body.String(), `task #14`)
|
||||||
})
|
})
|
||||||
t.Run("Sort Order", func(t *testing.T) {
|
t.Run("Sort Order", func(t *testing.T) {
|
||||||
// should equal priority desc
|
// should equal priority asc
|
||||||
t.Run("by priority", func(t *testing.T) {
|
t.Run("by priority", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"priority"}}, nil)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}}, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,`)
|
assert.Contains(t, rec.Body.String(), `{"id":33,"text":"task #33 with percent done","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0.5,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
|
||||||
})
|
})
|
||||||
t.Run("by priority desc", func(t *testing.T) {
|
t.Run("by priority desc", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"prioritydesc"}}, nil)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"desc"}}, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,`)
|
assert.Contains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,`)
|
||||||
})
|
})
|
||||||
t.Run("by priority asc", func(t *testing.T) {
|
t.Run("by priority asc", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"priorityasc"}}, nil)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"priority"}, "order_by": []string{"asc"}}, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `{"id":33,"text":"task #33 with percent done","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0.5,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
|
assert.Contains(t, rec.Body.String(), `{"id":33,"text":"task #33 with percent done","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0.5,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":1,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":3,"text":"task #3 high prio","description":"","done":false,"doneAt":0,"dueDate":0,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
|
||||||
})
|
})
|
||||||
// should equal duedate desc
|
// should equal duedate asc
|
||||||
t.Run("by duedate", func(t *testing.T) {
|
t.Run("by duedate", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"duedate"}}, nil)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date_unix"}}, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
|
assert.Contains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"doneAt":0,"dueDate":1543616724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
|
||||||
})
|
})
|
||||||
t.Run("by duedate desc", func(t *testing.T) {
|
t.Run("by duedate desc", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"duedatedesc"}}, nil)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date_unix"}, "order_by": []string{"desc"}}, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
|
assert.Contains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
|
||||||
})
|
})
|
||||||
t.Run("by duedate asc", func(t *testing.T) {
|
t.Run("by duedate asc", func(t *testing.T) {
|
||||||
rec, err := testHandler.testReadAllWithUser(url.Values{"sort": []string{"duedateasc"}}, nil)
|
rec, err := testHandler.testReadAllWithUser(url.Values{"sort_by": []string{"due_date_unix"}, "order_by": []string{"asc"}}, nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"doneAt":0,"dueDate":1543616724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
|
assert.Contains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"doneAt":0,"dueDate":1543616724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"doneAt":0,"dueDate":1543636724,"reminderDates":null,"listID":1,"repeatAfter":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"hexColor":"","percentDone":0,"related_tasks":{},"attachments":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":1,"username":"user1","avatarUrl":"111d68d06e2d317b5a59c2c6c5bad808","created":0,"updated":0}}]`)
|
||||||
})
|
})
|
||||||
|
|
|
@ -788,6 +788,60 @@ func (err ErrTaskAttachmentIsTooLarge) HTTPError() web.HTTPError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrInvalidSortParam represents an error where the provided sort param is invalid
|
||||||
|
type ErrInvalidSortParam struct {
|
||||||
|
SortBy sortProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsErrInvalidSortParam checks if an error is ErrInvalidSortParam.
|
||||||
|
func IsErrInvalidSortParam(err error) bool {
|
||||||
|
_, ok := err.(ErrInvalidSortParam)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err ErrInvalidSortParam) Error() string {
|
||||||
|
return fmt.Sprintf("Sort param is invalid [SortBy: %s]", err.SortBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrCodeInvalidSortParam holds the unique world-error code of this error
|
||||||
|
const ErrCodeInvalidSortParam = 4013
|
||||||
|
|
||||||
|
// HTTPError holds the http error description
|
||||||
|
func (err ErrInvalidSortParam) HTTPError() web.HTTPError {
|
||||||
|
return web.HTTPError{
|
||||||
|
HTTPCode: http.StatusBadRequest,
|
||||||
|
Code: ErrCodeInvalidSortParam,
|
||||||
|
Message: fmt.Sprintf("The task sort param '%s' is invalid.", err.SortBy),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrInvalidSortOrder represents an error where the provided sort order is invalid
|
||||||
|
type ErrInvalidSortOrder struct {
|
||||||
|
OrderBy sortOrder
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsErrInvalidSortOrder checks if an error is ErrInvalidSortOrder.
|
||||||
|
func IsErrInvalidSortOrder(err error) bool {
|
||||||
|
_, ok := err.(ErrInvalidSortOrder)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err ErrInvalidSortOrder) Error() string {
|
||||||
|
return fmt.Sprintf("Sort order is invalid [OrderBy: %s]", err.OrderBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrCodeInvalidSortOrder holds the unique world-error code of this error
|
||||||
|
const ErrCodeInvalidSortOrder = 4014
|
||||||
|
|
||||||
|
// HTTPError holds the http error description
|
||||||
|
func (err ErrInvalidSortOrder) HTTPError() web.HTTPError {
|
||||||
|
return web.HTTPError{
|
||||||
|
HTTPCode: http.StatusBadRequest,
|
||||||
|
Code: ErrCodeInvalidSortOrder,
|
||||||
|
Message: fmt.Sprintf("The task sort order '%s' is invalid. Allowed is either asc or desc.", err.OrderBy),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// =================
|
// =================
|
||||||
// Namespace errors
|
// Namespace errors
|
||||||
// =================
|
// =================
|
||||||
|
|
|
@ -209,7 +209,6 @@ func getUserTaskIDs(u *User) (taskIDs []int64, err error) {
|
||||||
tasks, _, _, err := getRawTasksForLists(lists, &taskOptions{
|
tasks, _, _, err := getRawTasksForLists(lists, &taskOptions{
|
||||||
startDate: time.Unix(0, 0),
|
startDate: time.Unix(0, 0),
|
||||||
endDate: time.Unix(0, 0),
|
endDate: time.Unix(0, 0),
|
||||||
sortby: SortTasksByUnsorted,
|
|
||||||
page: -1,
|
page: -1,
|
||||||
perPage: 0,
|
perPage: 0,
|
||||||
})
|
})
|
||||||
|
|
|
@ -24,18 +24,22 @@ import (
|
||||||
|
|
||||||
// TaskCollection is a struct used to hold filter details and not clutter the Task struct with information not related to actual tasks.
|
// TaskCollection is a struct used to hold filter details and not clutter the Task struct with information not related to actual tasks.
|
||||||
type TaskCollection struct {
|
type TaskCollection struct {
|
||||||
ListID int64 `param:"list"`
|
ListID int64 `param:"list"`
|
||||||
Sorting string `query:"sort"` // Parameter to sort by
|
StartDateSortUnix int64 `query:"startdate"`
|
||||||
StartDateSortUnix int64 `query:"startdate"`
|
EndDateSortUnix int64 `query:"enddate"`
|
||||||
EndDateSortUnix int64 `query:"enddate"`
|
|
||||||
Lists []*List
|
Lists []*List
|
||||||
|
|
||||||
|
// The query parameter to sort by. This is for ex. done, priority, etc.
|
||||||
|
SortBy []string `query:"sort_by"`
|
||||||
|
// The query parameter to order the items by. This can be either asc or desc, with asc being the default.
|
||||||
|
OrderBy []string `query:"order_by"`
|
||||||
|
|
||||||
web.CRUDable `xorm:"-" json:"-"`
|
web.CRUDable `xorm:"-" json:"-"`
|
||||||
web.Rights `xorm:"-" json:"-"`
|
web.Rights `xorm:"-" json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadAll gets all tasks for a collection
|
// ReadAll gets all tasks for a collection
|
||||||
// @Summary Get tasks on a list
|
// @Summary Get tasks in a list
|
||||||
// @Description Returns all tasks for the current list.
|
// @Description Returns all tasks for the current list.
|
||||||
// @tags task
|
// @tags task
|
||||||
// @Accept json
|
// @Accept json
|
||||||
|
@ -44,7 +48,8 @@ type TaskCollection struct {
|
||||||
// @Param page query int false "The page number. Used for pagination. If not provided, the first page of results is returned."
|
// @Param page query int false "The page number. Used for pagination. If not provided, the first page of results is returned."
|
||||||
// @Param per_page query int false "The maximum number of items per page. Note this parameter is limited by the configured maximum of items per page."
|
// @Param per_page query int false "The maximum number of items per page. Note this parameter is limited by the configured maximum of items per page."
|
||||||
// @Param s query string false "Search tasks by task text."
|
// @Param s query string false "Search tasks by task text."
|
||||||
// @Param sort query string false "The sorting parameter. Possible values to sort by are priority, prioritydesc, priorityasc, duedate, duedatedesc, duedateasc."
|
// @Param sort_by query string false "The sorting parameter. You can pass this multiple times to get the tasks ordered by multiple different parametes, along with `order_by`. Possible values to sort by are `id`, `text`, `description`, `done`, `done_at_unix`, `due_date_unix`, `created_by_id`, `list_id`, `repeat_after`, `priority`, `start_date_unix`, `end_date_unix`, `hex_color`, `percent_done`, `uid`, `created`, `updated`. Default is `id`."
|
||||||
|
// @Param order_by query string false "The ordering parameter. Possible values to order by are `asc` or `desc`. Default is `asc`."
|
||||||
// @Param startdate query int false "The start date parameter to filter by. Expects a unix timestamp. If no end date, but a start date is specified, the end date is set to the current time."
|
// @Param startdate query int false "The start date parameter to filter by. Expects a unix timestamp. If no end date, but a start date is specified, the end date is set to the current time."
|
||||||
// @Param enddate query int false "The end date parameter to filter by. Expects a unix timestamp. If no start date, but an end date is specified, the start date is set to the current time."
|
// @Param enddate query int false "The end date parameter to filter by. Expects a unix timestamp. If no start date, but an end date is specified, the start date is set to the current time."
|
||||||
// @Security JWTKeyAuth
|
// @Security JWTKeyAuth
|
||||||
|
@ -52,31 +57,32 @@ type TaskCollection struct {
|
||||||
// @Failure 500 {object} models.Message "Internal error"
|
// @Failure 500 {object} models.Message "Internal error"
|
||||||
// @Router /lists/{listID}/tasks [get]
|
// @Router /lists/{listID}/tasks [get]
|
||||||
func (tf *TaskCollection) ReadAll(a web.Auth, search string, page int, perPage int) (result interface{}, resultCount int, totalItems int64, err error) {
|
func (tf *TaskCollection) ReadAll(a web.Auth, search string, page int, perPage int) (result interface{}, resultCount int, totalItems int64, err error) {
|
||||||
var sortby SortBy
|
|
||||||
switch tf.Sorting {
|
var sort = make([]*sortParam, 0, len(tf.SortBy))
|
||||||
case "priority":
|
for i, s := range tf.SortBy {
|
||||||
sortby = SortTasksByPriorityDesc
|
param := &sortParam{
|
||||||
case "prioritydesc":
|
sortBy: sortProperty(s),
|
||||||
sortby = SortTasksByPriorityDesc
|
orderBy: orderAscending,
|
||||||
case "priorityasc":
|
}
|
||||||
sortby = SortTasksByPriorityAsc
|
// This checks if tf.OrderBy has an entry with the same index as the current entry from tf.SortBy
|
||||||
case "duedate":
|
// Taken from https://stackoverflow.com/a/27252199/10924593
|
||||||
sortby = SortTasksByDueDateDesc
|
if len(tf.OrderBy) > i {
|
||||||
case "duedatedesc":
|
param.orderBy = getSortOrderFromString(tf.OrderBy[i])
|
||||||
sortby = SortTasksByDueDateDesc
|
}
|
||||||
case "duedateasc":
|
// Param validation
|
||||||
sortby = SortTasksByDueDateAsc
|
if err := param.validate(); err != nil {
|
||||||
default:
|
return nil, 0, 0, err
|
||||||
sortby = SortTasksByUnsorted
|
}
|
||||||
|
sort = append(sort, param)
|
||||||
}
|
}
|
||||||
|
|
||||||
taskopts := &taskOptions{
|
taskopts := &taskOptions{
|
||||||
search: search,
|
search: search,
|
||||||
sortby: sortby,
|
|
||||||
startDate: time.Unix(tf.StartDateSortUnix, 0),
|
startDate: time.Unix(tf.StartDateSortUnix, 0),
|
||||||
endDate: time.Unix(tf.EndDateSortUnix, 0),
|
endDate: time.Unix(tf.EndDateSortUnix, 0),
|
||||||
page: page,
|
page: page,
|
||||||
perPage: perPage,
|
perPage: perPage,
|
||||||
|
sortby: sort,
|
||||||
}
|
}
|
||||||
|
|
||||||
shareAuth, is := a.(*LinkSharing)
|
shareAuth, is := a.(*LinkSharing)
|
||||||
|
|
233
pkg/models/task_collection_sort.go
Normal file
233
pkg/models/task_collection_sort.go
Normal file
|
@ -0,0 +1,233 @@
|
||||||
|
// Vikunja is a todo-list application to facilitate your life.
|
||||||
|
// Copyright 2019 Vikunja and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
sortParam struct {
|
||||||
|
sortBy sortProperty
|
||||||
|
orderBy sortOrder // asc or desc
|
||||||
|
}
|
||||||
|
|
||||||
|
sortProperty string
|
||||||
|
|
||||||
|
sortOrder string
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
taskPropertyID sortProperty = "id"
|
||||||
|
taskPropertyText sortProperty = "text"
|
||||||
|
taskPropertyDescription sortProperty = "description"
|
||||||
|
taskPropertyDone sortProperty = "done"
|
||||||
|
taskPropertyDoneAtUnix sortProperty = "done_at_unix"
|
||||||
|
taskPropertyDueDateUnix sortProperty = "due_date_unix"
|
||||||
|
taskPropertyCreatedByID sortProperty = "created_by_id"
|
||||||
|
taskPropertyListID sortProperty = "list_id"
|
||||||
|
taskPropertyRepeatAfter sortProperty = "repeat_after"
|
||||||
|
taskPropertyPriority sortProperty = "priority"
|
||||||
|
taskPropertyStartDateUnix sortProperty = "start_date_unix"
|
||||||
|
taskPropertyEndDateUnix sortProperty = "end_date_unix"
|
||||||
|
taskPropertyHexColor sortProperty = "hex_color"
|
||||||
|
taskPropertyPercentDone sortProperty = "percent_done"
|
||||||
|
taskPropertyUID sortProperty = "uid"
|
||||||
|
taskPropertyCreated sortProperty = "created"
|
||||||
|
taskPropertyUpdated sortProperty = "updated"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p sortProperty) String() string {
|
||||||
|
return string(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
orderInvalid sortOrder = "invalid"
|
||||||
|
orderAscending sortOrder = "asc"
|
||||||
|
orderDescending sortOrder = "desc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (o sortOrder) String() string {
|
||||||
|
return string(o)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSortOrderFromString(s string) sortOrder {
|
||||||
|
if s == "asc" {
|
||||||
|
return orderAscending
|
||||||
|
}
|
||||||
|
if s == "desc" {
|
||||||
|
return orderDescending
|
||||||
|
}
|
||||||
|
return orderInvalid
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sp *sortParam) validate() error {
|
||||||
|
if sp.orderBy != orderDescending && sp.orderBy != orderAscending {
|
||||||
|
return ErrInvalidSortOrder{OrderBy: sp.orderBy}
|
||||||
|
}
|
||||||
|
switch sp.sortBy {
|
||||||
|
case
|
||||||
|
taskPropertyID,
|
||||||
|
taskPropertyText,
|
||||||
|
taskPropertyDescription,
|
||||||
|
taskPropertyDone,
|
||||||
|
taskPropertyDoneAtUnix,
|
||||||
|
taskPropertyDueDateUnix,
|
||||||
|
taskPropertyCreatedByID,
|
||||||
|
taskPropertyListID,
|
||||||
|
taskPropertyRepeatAfter,
|
||||||
|
taskPropertyPriority,
|
||||||
|
taskPropertyStartDateUnix,
|
||||||
|
taskPropertyEndDateUnix,
|
||||||
|
taskPropertyHexColor,
|
||||||
|
taskPropertyPercentDone,
|
||||||
|
taskPropertyUID,
|
||||||
|
taskPropertyCreated,
|
||||||
|
taskPropertyUpdated:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return ErrInvalidSortParam{SortBy: sp.sortBy}
|
||||||
|
}
|
||||||
|
|
||||||
|
type taskComparator func(lhs, rhs *Task) int64
|
||||||
|
|
||||||
|
func mustMakeComparator(fieldName string) taskComparator {
|
||||||
|
field, ok := reflect.TypeOf(&Task{}).Elem().FieldByName(fieldName)
|
||||||
|
if !ok {
|
||||||
|
panic(fmt.Sprintf("Field '%s' has not been found on Task", fieldName))
|
||||||
|
}
|
||||||
|
|
||||||
|
extractProp := func(task *Task) interface{} {
|
||||||
|
return reflect.ValueOf(task).Elem().FieldByIndex(field.Index).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch field.Type.Kind() {
|
||||||
|
case reflect.Int64:
|
||||||
|
return func(lhs, rhs *Task) int64 {
|
||||||
|
return extractProp(lhs).(int64) - extractProp(rhs).(int64)
|
||||||
|
}
|
||||||
|
case reflect.Float64:
|
||||||
|
return func(lhs, rhs *Task) int64 {
|
||||||
|
floatLHS, floatRHS := extractProp(lhs).(float64), extractProp(rhs).(float64)
|
||||||
|
if floatLHS > floatRHS {
|
||||||
|
return 1
|
||||||
|
} else if floatLHS < floatRHS {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
case reflect.String:
|
||||||
|
return func(lhs, rhs *Task) int64 {
|
||||||
|
strLHS, strRHS := extractProp(lhs).(string), extractProp(rhs).(string)
|
||||||
|
if strLHS > strRHS {
|
||||||
|
return 1
|
||||||
|
} else if strLHS < strRHS {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
case reflect.Bool:
|
||||||
|
return func(lhs, rhs *Task) int64 {
|
||||||
|
boolLHS, boolRHS := extractProp(lhs).(bool), extractProp(rhs).(bool)
|
||||||
|
if !boolLHS && boolRHS {
|
||||||
|
return 1
|
||||||
|
} else if boolLHS && !boolRHS {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("Unsupported type for sorting: %s", field.Type.Name()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a map of properties that can be sorted by
|
||||||
|
// and their appropriate comparator function.
|
||||||
|
// The comparator function sorts in ascending mode.
|
||||||
|
var propertyComparators = map[sortProperty]taskComparator{
|
||||||
|
taskPropertyID: mustMakeComparator("ID"),
|
||||||
|
taskPropertyText: mustMakeComparator("Text"),
|
||||||
|
taskPropertyDescription: mustMakeComparator("Description"),
|
||||||
|
taskPropertyDone: mustMakeComparator("Done"),
|
||||||
|
taskPropertyDoneAtUnix: mustMakeComparator("DoneAtUnix"),
|
||||||
|
taskPropertyDueDateUnix: mustMakeComparator("DueDateUnix"),
|
||||||
|
taskPropertyCreatedByID: mustMakeComparator("CreatedByID"),
|
||||||
|
taskPropertyListID: mustMakeComparator("ListID"),
|
||||||
|
taskPropertyRepeatAfter: mustMakeComparator("RepeatAfter"),
|
||||||
|
taskPropertyPriority: mustMakeComparator("Priority"),
|
||||||
|
taskPropertyStartDateUnix: mustMakeComparator("StartDateUnix"),
|
||||||
|
taskPropertyEndDateUnix: mustMakeComparator("EndDateUnix"),
|
||||||
|
taskPropertyHexColor: mustMakeComparator("HexColor"),
|
||||||
|
taskPropertyPercentDone: mustMakeComparator("PercentDone"),
|
||||||
|
taskPropertyUID: mustMakeComparator("UID"),
|
||||||
|
taskPropertyCreated: mustMakeComparator("Created"),
|
||||||
|
taskPropertyUpdated: mustMakeComparator("Updated"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a taskComparator that sorts by the first comparator and falls back to
|
||||||
|
// the second one (and so on...) if the properties were equal.
|
||||||
|
func combineComparators(comparators ...taskComparator) taskComparator {
|
||||||
|
return func(lhs, rhs *Task) int64 {
|
||||||
|
for _, compare := range comparators {
|
||||||
|
res := compare(lhs, rhs)
|
||||||
|
if res != 0 {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func sortTasks(tasks []*Task, by []*sortParam) {
|
||||||
|
|
||||||
|
// Always sort at least by id asc so we have a consistent order of items every time
|
||||||
|
// If we would not do this, we would get a different order for items with the same content every time
|
||||||
|
// the slice is sorted. To circumvent this, we always order at least by ID.
|
||||||
|
if len(by) == 0 ||
|
||||||
|
(len(by) > 0 && by[len(by)-1].sortBy != taskPropertyID) { // Don't sort by ID last if the id parameter is already passed as the last parameter.
|
||||||
|
by = append(by, &sortParam{sortBy: taskPropertyID, orderBy: orderAscending})
|
||||||
|
}
|
||||||
|
|
||||||
|
comparators := make([]taskComparator, 0, len(by))
|
||||||
|
for _, param := range by {
|
||||||
|
comparator, ok := propertyComparators[param.sortBy]
|
||||||
|
if !ok {
|
||||||
|
panic("No suitable comparator for sortBy found! Param was " + param.sortBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a descending sort, so we need to negate the comparator (i.e. switch the inputs).
|
||||||
|
if param.orderBy == orderDescending {
|
||||||
|
oldComparator := comparator
|
||||||
|
comparator = func(lhs, rhs *Task) int64 {
|
||||||
|
return oldComparator(lhs, rhs) * -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
comparators = append(comparators, comparator)
|
||||||
|
}
|
||||||
|
|
||||||
|
combinedComparator := combineComparators(comparators...)
|
||||||
|
|
||||||
|
sort.Slice(tasks, func(i, j int) bool {
|
||||||
|
lhs, rhs := tasks[i], tasks[j]
|
||||||
|
|
||||||
|
res := combinedComparator(lhs, rhs)
|
||||||
|
return res <= 0
|
||||||
|
})
|
||||||
|
}
|
829
pkg/models/task_collection_sort_test.go
Normal file
829
pkg/models/task_collection_sort_test.go
Normal file
|
@ -0,0 +1,829 @@
|
||||||
|
// Vikunja is a todo-list application to facilitate your life.
|
||||||
|
// Copyright 2019 Vikunja and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mohae/deepcopy"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"math/rand"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSortParamValidation(t *testing.T) {
|
||||||
|
t.Run("Test valid order by", func(t *testing.T) {
|
||||||
|
t.Run(orderAscending.String(), func(t *testing.T) {
|
||||||
|
s := &sortParam{
|
||||||
|
orderBy: orderAscending,
|
||||||
|
sortBy: "id",
|
||||||
|
}
|
||||||
|
err := s.validate()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
})
|
||||||
|
t.Run(orderDescending.String(), func(t *testing.T) {
|
||||||
|
s := &sortParam{
|
||||||
|
orderBy: orderDescending,
|
||||||
|
sortBy: "id",
|
||||||
|
}
|
||||||
|
err := s.validate()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
t.Run("Test valid sort by", func(t *testing.T) {
|
||||||
|
for _, test := range []sortProperty{
|
||||||
|
taskPropertyID,
|
||||||
|
taskPropertyText,
|
||||||
|
taskPropertyDescription,
|
||||||
|
taskPropertyDone,
|
||||||
|
taskPropertyDoneAtUnix,
|
||||||
|
taskPropertyDueDateUnix,
|
||||||
|
taskPropertyCreatedByID,
|
||||||
|
taskPropertyListID,
|
||||||
|
taskPropertyRepeatAfter,
|
||||||
|
taskPropertyPriority,
|
||||||
|
taskPropertyStartDateUnix,
|
||||||
|
taskPropertyEndDateUnix,
|
||||||
|
taskPropertyHexColor,
|
||||||
|
taskPropertyPercentDone,
|
||||||
|
taskPropertyUID,
|
||||||
|
taskPropertyCreated,
|
||||||
|
taskPropertyUpdated,
|
||||||
|
} {
|
||||||
|
t.Run(test.String(), func(t *testing.T) {
|
||||||
|
s := &sortParam{
|
||||||
|
orderBy: orderAscending,
|
||||||
|
sortBy: test,
|
||||||
|
}
|
||||||
|
err := s.validate()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("Test invalid order by", func(t *testing.T) {
|
||||||
|
s := &sortParam{
|
||||||
|
orderBy: "somethingInvalid",
|
||||||
|
sortBy: "id",
|
||||||
|
}
|
||||||
|
err := s.validate()
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.True(t, IsErrInvalidSortOrder(err))
|
||||||
|
})
|
||||||
|
t.Run("Test invalid sort by", func(t *testing.T) {
|
||||||
|
s := &sortParam{
|
||||||
|
orderBy: orderAscending,
|
||||||
|
sortBy: "somethingInvalid",
|
||||||
|
}
|
||||||
|
err := s.validate()
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.True(t, IsErrInvalidSortParam(err))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
task1 = &Task{
|
||||||
|
ID: 1,
|
||||||
|
Text: "aaa",
|
||||||
|
Description: "Lorem Ipsum",
|
||||||
|
Done: true,
|
||||||
|
DoneAtUnix: 1543626000,
|
||||||
|
ListID: 1,
|
||||||
|
UID: "JywtBPCESImlyKugvaZWrxmXAFAWXFISMeXYImEh",
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task2 = &Task{
|
||||||
|
ID: 2,
|
||||||
|
Text: "bbb",
|
||||||
|
Description: "Arem Ipsum",
|
||||||
|
Done: true,
|
||||||
|
DoneAtUnix: 1543626724,
|
||||||
|
CreatedByID: 1,
|
||||||
|
ListID: 2,
|
||||||
|
PercentDone: 0.3,
|
||||||
|
StartDateUnix: 1543626724,
|
||||||
|
Created: 1553626724,
|
||||||
|
Updated: 1553626724,
|
||||||
|
}
|
||||||
|
task3 = &Task{
|
||||||
|
ID: 3,
|
||||||
|
Text: "ccc",
|
||||||
|
DueDateUnix: 1583626724,
|
||||||
|
Priority: 100,
|
||||||
|
ListID: 3,
|
||||||
|
HexColor: "000000",
|
||||||
|
PercentDone: 0.1,
|
||||||
|
Updated: 1555555555,
|
||||||
|
}
|
||||||
|
task4 = &Task{
|
||||||
|
ID: 4,
|
||||||
|
Text: "ddd",
|
||||||
|
Priority: 1,
|
||||||
|
StartDateUnix: 1643626724,
|
||||||
|
ListID: 1,
|
||||||
|
}
|
||||||
|
task5 = &Task{
|
||||||
|
ID: 5,
|
||||||
|
Text: "eef",
|
||||||
|
Priority: 50,
|
||||||
|
UID: "shggzCHQWLhGNMNsOGOCOjcVkInOYjTAnORqTkdL",
|
||||||
|
DueDateUnix: 1543636724,
|
||||||
|
Updated: 1565555555,
|
||||||
|
}
|
||||||
|
task6 = &Task{
|
||||||
|
ID: 6,
|
||||||
|
Text: "eef",
|
||||||
|
DueDateUnix: 1543616724,
|
||||||
|
RepeatAfter: 6400,
|
||||||
|
CreatedByID: 2,
|
||||||
|
HexColor: "ffffff",
|
||||||
|
}
|
||||||
|
task7 = &Task{
|
||||||
|
ID: 7,
|
||||||
|
Text: "mmmn",
|
||||||
|
Description: "Zoremis",
|
||||||
|
StartDateUnix: 1544600000,
|
||||||
|
EndDateUnix: 1584600000,
|
||||||
|
UID: "tyzCZuLMSKhwclJOsDyDcUdyVAPBDOPHNTBOLTcW",
|
||||||
|
}
|
||||||
|
task8 = &Task{
|
||||||
|
ID: 8,
|
||||||
|
Text: "b123",
|
||||||
|
EndDateUnix: 1544700000,
|
||||||
|
}
|
||||||
|
task9 = &Task{
|
||||||
|
ID: 9,
|
||||||
|
Done: true,
|
||||||
|
DoneAtUnix: 1573626724,
|
||||||
|
Text: "a123",
|
||||||
|
RepeatAfter: 86000,
|
||||||
|
StartDateUnix: 1544600000,
|
||||||
|
EndDateUnix: 1544700000,
|
||||||
|
}
|
||||||
|
task10 = &Task{
|
||||||
|
ID: 10,
|
||||||
|
Text: "zzz",
|
||||||
|
Priority: 10,
|
||||||
|
PercentDone: 1,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type taskSortTestCase struct {
|
||||||
|
name string
|
||||||
|
wantAsc []*Task
|
||||||
|
wantDesc []*Task
|
||||||
|
sortProperty sortProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
var taskSortTestCases = []taskSortTestCase{
|
||||||
|
{
|
||||||
|
name: "id",
|
||||||
|
sortProperty: taskPropertyID,
|
||||||
|
wantAsc: []*Task{
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
},
|
||||||
|
wantDesc: []*Task{
|
||||||
|
task10,
|
||||||
|
task9,
|
||||||
|
task8,
|
||||||
|
task7,
|
||||||
|
task6,
|
||||||
|
task5,
|
||||||
|
task4,
|
||||||
|
task3,
|
||||||
|
task2,
|
||||||
|
task1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "text",
|
||||||
|
sortProperty: taskPropertyText,
|
||||||
|
wantAsc: []*Task{
|
||||||
|
task9,
|
||||||
|
task1,
|
||||||
|
task8,
|
||||||
|
task2,
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task10,
|
||||||
|
},
|
||||||
|
wantDesc: []*Task{
|
||||||
|
task10,
|
||||||
|
task7,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task4,
|
||||||
|
task3,
|
||||||
|
task2,
|
||||||
|
task8,
|
||||||
|
task1,
|
||||||
|
task9,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "description",
|
||||||
|
sortProperty: taskPropertyDescription,
|
||||||
|
wantAsc: []*Task{
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
task2,
|
||||||
|
task1,
|
||||||
|
task7,
|
||||||
|
},
|
||||||
|
wantDesc: []*Task{
|
||||||
|
task7,
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "done",
|
||||||
|
sortProperty: taskPropertyDone,
|
||||||
|
wantAsc: []*Task{
|
||||||
|
// These are done
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task9,
|
||||||
|
// These are not
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task10,
|
||||||
|
},
|
||||||
|
wantDesc: []*Task{
|
||||||
|
// These are not
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task10,
|
||||||
|
// These are done
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task9,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "done at",
|
||||||
|
sortProperty: taskPropertyDoneAtUnix,
|
||||||
|
wantAsc: []*Task{
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task10,
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task9,
|
||||||
|
},
|
||||||
|
wantDesc: []*Task{
|
||||||
|
task9,
|
||||||
|
task2,
|
||||||
|
task1,
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "due date",
|
||||||
|
sortProperty: taskPropertyDueDateUnix,
|
||||||
|
wantAsc: []*Task{
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task4,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
task6,
|
||||||
|
task5,
|
||||||
|
task3,
|
||||||
|
},
|
||||||
|
wantDesc: []*Task{
|
||||||
|
task3,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task4,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "created by id",
|
||||||
|
sortProperty: taskPropertyCreatedByID,
|
||||||
|
wantAsc: []*Task{
|
||||||
|
task1,
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
task2,
|
||||||
|
task6,
|
||||||
|
},
|
||||||
|
wantDesc: []*Task{
|
||||||
|
task6,
|
||||||
|
task2,
|
||||||
|
task1,
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "list id",
|
||||||
|
sortProperty: taskPropertyListID,
|
||||||
|
wantAsc: []*Task{
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
task1,
|
||||||
|
task4,
|
||||||
|
task2,
|
||||||
|
task3,
|
||||||
|
},
|
||||||
|
wantDesc: []*Task{
|
||||||
|
task3,
|
||||||
|
task2,
|
||||||
|
task1,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "repeat after",
|
||||||
|
sortProperty: taskPropertyRepeatAfter,
|
||||||
|
wantAsc: []*Task{
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task10,
|
||||||
|
task6,
|
||||||
|
task9,
|
||||||
|
},
|
||||||
|
wantDesc: []*Task{
|
||||||
|
task9,
|
||||||
|
task6,
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "priority",
|
||||||
|
sortProperty: taskPropertyPriority,
|
||||||
|
wantAsc: []*Task{
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task4,
|
||||||
|
task10,
|
||||||
|
task5,
|
||||||
|
task3,
|
||||||
|
},
|
||||||
|
wantDesc: []*Task{
|
||||||
|
task3,
|
||||||
|
task5,
|
||||||
|
task10,
|
||||||
|
task4,
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "start date",
|
||||||
|
sortProperty: taskPropertyStartDateUnix,
|
||||||
|
wantAsc: []*Task{
|
||||||
|
task1,
|
||||||
|
task3,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task8,
|
||||||
|
task10,
|
||||||
|
task2,
|
||||||
|
task7,
|
||||||
|
task9,
|
||||||
|
task4,
|
||||||
|
},
|
||||||
|
wantDesc: []*Task{
|
||||||
|
task4,
|
||||||
|
task7,
|
||||||
|
task9,
|
||||||
|
task2,
|
||||||
|
task1,
|
||||||
|
task3,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task8,
|
||||||
|
task10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "end date",
|
||||||
|
sortProperty: taskPropertyEndDateUnix,
|
||||||
|
wantAsc: []*Task{
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task10,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task7,
|
||||||
|
},
|
||||||
|
wantDesc: []*Task{
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "hex color",
|
||||||
|
sortProperty: taskPropertyHexColor,
|
||||||
|
wantAsc: []*Task{
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
task3,
|
||||||
|
task6,
|
||||||
|
},
|
||||||
|
wantDesc: []*Task{
|
||||||
|
task6,
|
||||||
|
task3,
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "percent done",
|
||||||
|
sortProperty: taskPropertyPercentDone,
|
||||||
|
wantAsc: []*Task{
|
||||||
|
task1,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task3,
|
||||||
|
task2,
|
||||||
|
task10,
|
||||||
|
},
|
||||||
|
wantDesc: []*Task{
|
||||||
|
task10,
|
||||||
|
task2,
|
||||||
|
task3,
|
||||||
|
task1,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "uid",
|
||||||
|
sortProperty: taskPropertyUID,
|
||||||
|
wantAsc: []*Task{
|
||||||
|
task2,
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task6,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
task1,
|
||||||
|
task5,
|
||||||
|
task7,
|
||||||
|
},
|
||||||
|
wantDesc: []*Task{
|
||||||
|
task7,
|
||||||
|
task5,
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task6,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "created",
|
||||||
|
sortProperty: taskPropertyCreated,
|
||||||
|
wantAsc: []*Task{
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
},
|
||||||
|
wantDesc: []*Task{
|
||||||
|
task2,
|
||||||
|
task1,
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "updated",
|
||||||
|
sortProperty: taskPropertyUpdated,
|
||||||
|
wantAsc: []*Task{
|
||||||
|
task4,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task3,
|
||||||
|
task5,
|
||||||
|
},
|
||||||
|
wantDesc: []*Task{
|
||||||
|
task5,
|
||||||
|
task3,
|
||||||
|
task2,
|
||||||
|
task1,
|
||||||
|
task4,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTaskSort(t *testing.T) {
|
||||||
|
|
||||||
|
assertTestSliceMatch := func(t *testing.T, got, want []*Task) {
|
||||||
|
if !reflect.DeepEqual(got, want) {
|
||||||
|
t.Error("Slices do not match in order")
|
||||||
|
t.Error("Got\t| Want")
|
||||||
|
for in, task := range got {
|
||||||
|
fail := ""
|
||||||
|
if task.ID != want[in].ID {
|
||||||
|
fail = "wrong"
|
||||||
|
}
|
||||||
|
t.Errorf("\t%d\t| %d \t%s", task.ID, want[in].ID, fail)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range taskSortTestCases {
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
t.Run("asc default", func(t *testing.T) {
|
||||||
|
by := []*sortParam{
|
||||||
|
{
|
||||||
|
sortBy: testCase.sortProperty,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
got := deepcopy.Copy(testCase.wantAsc).([]*Task)
|
||||||
|
|
||||||
|
// Destroy wanted order to obtain some slice we can sort
|
||||||
|
rand.Shuffle(len(got), func(i, j int) {
|
||||||
|
got[i], got[j] = got[j], got[i]
|
||||||
|
})
|
||||||
|
|
||||||
|
sortTasks(got, by)
|
||||||
|
|
||||||
|
assertTestSliceMatch(t, got, testCase.wantAsc)
|
||||||
|
})
|
||||||
|
t.Run("asc", func(t *testing.T) {
|
||||||
|
by := []*sortParam{
|
||||||
|
{
|
||||||
|
sortBy: testCase.sortProperty,
|
||||||
|
orderBy: orderAscending,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
got := deepcopy.Copy(testCase.wantAsc).([]*Task)
|
||||||
|
|
||||||
|
// Destroy wanted order to obtain some slice we can sort
|
||||||
|
rand.Shuffle(len(got), func(i, j int) {
|
||||||
|
got[i], got[j] = got[j], got[i]
|
||||||
|
})
|
||||||
|
|
||||||
|
sortTasks(got, by)
|
||||||
|
|
||||||
|
assertTestSliceMatch(t, got, testCase.wantAsc)
|
||||||
|
})
|
||||||
|
t.Run("desc", func(t *testing.T) {
|
||||||
|
by := []*sortParam{
|
||||||
|
{
|
||||||
|
sortBy: testCase.sortProperty,
|
||||||
|
orderBy: orderDescending,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
got := deepcopy.Copy(testCase.wantDesc).([]*Task)
|
||||||
|
|
||||||
|
// Destroy wanted order to obtain some slice we can sort
|
||||||
|
rand.Shuffle(len(got), func(i, j int) {
|
||||||
|
got[i], got[j] = got[j], got[i]
|
||||||
|
})
|
||||||
|
|
||||||
|
sortTasks(got, by)
|
||||||
|
|
||||||
|
assertTestSliceMatch(t, got, testCase.wantDesc)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Other cases
|
||||||
|
t.Run("Order by Done Ascending and Text Descending", func(t *testing.T) {
|
||||||
|
want := []*Task{
|
||||||
|
// Done
|
||||||
|
task2,
|
||||||
|
task1,
|
||||||
|
task9,
|
||||||
|
|
||||||
|
// Not done
|
||||||
|
task10,
|
||||||
|
task7,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task4,
|
||||||
|
task3,
|
||||||
|
task8,
|
||||||
|
}
|
||||||
|
sortParams := []*sortParam{
|
||||||
|
{
|
||||||
|
sortBy: taskPropertyDone,
|
||||||
|
orderBy: orderAscending,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sortBy: taskPropertyText,
|
||||||
|
orderBy: orderDescending,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
got := deepcopy.Copy(want).([]*Task)
|
||||||
|
|
||||||
|
// Destroy wanted order to obtain some slice we can sort
|
||||||
|
rand.Shuffle(len(got), func(i, j int) {
|
||||||
|
got[i], got[j] = got[j], got[i]
|
||||||
|
})
|
||||||
|
|
||||||
|
sortTasks(got, sortParams)
|
||||||
|
|
||||||
|
assertTestSliceMatch(t, got, want)
|
||||||
|
})
|
||||||
|
t.Run("Order by Done Descending and Text Ascending", func(t *testing.T) {
|
||||||
|
want := []*Task{
|
||||||
|
// Not done
|
||||||
|
task8,
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task10,
|
||||||
|
|
||||||
|
// Done
|
||||||
|
task9,
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
}
|
||||||
|
sortParams := []*sortParam{
|
||||||
|
{
|
||||||
|
sortBy: taskPropertyDone,
|
||||||
|
orderBy: orderDescending,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sortBy: taskPropertyText,
|
||||||
|
orderBy: orderAscending,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
got := deepcopy.Copy(want).([]*Task)
|
||||||
|
|
||||||
|
// Destroy wanted order to obtain some slice we can sort
|
||||||
|
rand.Shuffle(len(got), func(i, j int) {
|
||||||
|
got[i], got[j] = got[j], got[i]
|
||||||
|
})
|
||||||
|
|
||||||
|
sortTasks(got, sortParams)
|
||||||
|
|
||||||
|
assertTestSliceMatch(t, got, want)
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
635
pkg/models/task_collection_test.go
Normal file
635
pkg/models/task_collection_test.go
Normal file
|
@ -0,0 +1,635 @@
|
||||||
|
// Vikunja is a todo-list application to facilitate your life.
|
||||||
|
// Copyright 2019 Vikunja and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.vikunja.io/api/pkg/db"
|
||||||
|
"code.vikunja.io/api/pkg/files"
|
||||||
|
"code.vikunja.io/web"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"gopkg.in/d4l3k/messagediff.v1"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTaskCollection_ReadAll(t *testing.T) {
|
||||||
|
assert.NoError(t, db.LoadFixtures())
|
||||||
|
|
||||||
|
// Dummy users
|
||||||
|
user1 := &User{
|
||||||
|
ID: 1,
|
||||||
|
Username: "user1",
|
||||||
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
IsActive: true,
|
||||||
|
AvatarURL: "111d68d06e2d317b5a59c2c6c5bad808", // hash for ""
|
||||||
|
}
|
||||||
|
user2 := &User{
|
||||||
|
ID: 2,
|
||||||
|
Username: "user2",
|
||||||
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
AvatarURL: "ab53a2911ddf9b4817ac01ddcd3d975f", // hash for ""
|
||||||
|
}
|
||||||
|
user6 := &User{
|
||||||
|
ID: 6,
|
||||||
|
Username: "user6",
|
||||||
|
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||||
|
IsActive: true,
|
||||||
|
AvatarURL: "3efbe51f864c6666bc27caf4c6ff90ed", // hash for ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// We use individual variables for the tasks here to be able to rearrange or remove ones more easily
|
||||||
|
task1 := &Task{
|
||||||
|
ID: 1,
|
||||||
|
Text: "task #1",
|
||||||
|
Description: "Lorem Ipsum",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 1,
|
||||||
|
Labels: []*Label{
|
||||||
|
{
|
||||||
|
ID: 4,
|
||||||
|
Title: "Label #4 - visible via other task",
|
||||||
|
CreatedByID: 2,
|
||||||
|
CreatedBy: user2,
|
||||||
|
Updated: 0,
|
||||||
|
Created: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{
|
||||||
|
RelationKindSubtask: {
|
||||||
|
{
|
||||||
|
ID: 29,
|
||||||
|
Text: "task #29 with parent task (1)",
|
||||||
|
CreatedByID: 1,
|
||||||
|
ListID: 1,
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Attachments: []*TaskAttachment{
|
||||||
|
{
|
||||||
|
ID: 1,
|
||||||
|
TaskID: 1,
|
||||||
|
FileID: 1,
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
File: &files.File{
|
||||||
|
ID: 1,
|
||||||
|
Name: "test",
|
||||||
|
Size: 100,
|
||||||
|
CreatedUnix: 1570998791,
|
||||||
|
CreatedByID: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: 2,
|
||||||
|
TaskID: 1,
|
||||||
|
FileID: 9999,
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task2 := &Task{
|
||||||
|
ID: 2,
|
||||||
|
Text: "task #2 done",
|
||||||
|
Done: true,
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 1,
|
||||||
|
Labels: []*Label{
|
||||||
|
{
|
||||||
|
ID: 4,
|
||||||
|
Title: "Label #4 - visible via other task",
|
||||||
|
CreatedByID: 2,
|
||||||
|
CreatedBy: user2,
|
||||||
|
Updated: 0,
|
||||||
|
Created: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task3 := &Task{
|
||||||
|
ID: 3,
|
||||||
|
Text: "task #3 high prio",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 1,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
Priority: 100,
|
||||||
|
}
|
||||||
|
task4 := &Task{
|
||||||
|
ID: 4,
|
||||||
|
Text: "task #4 low prio",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 1,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
Priority: 1,
|
||||||
|
}
|
||||||
|
task5 := &Task{
|
||||||
|
ID: 5,
|
||||||
|
Text: "task #5 higher due date",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 1,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
DueDateUnix: 1543636724,
|
||||||
|
}
|
||||||
|
task6 := &Task{
|
||||||
|
ID: 6,
|
||||||
|
Text: "task #6 lower due date",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 1,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
DueDateUnix: 1543616724,
|
||||||
|
}
|
||||||
|
task7 := &Task{
|
||||||
|
ID: 7,
|
||||||
|
Text: "task #7 with start date",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 1,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
StartDateUnix: 1544600000,
|
||||||
|
}
|
||||||
|
task8 := &Task{
|
||||||
|
ID: 8,
|
||||||
|
Text: "task #8 with end date",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 1,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
EndDateUnix: 1544700000,
|
||||||
|
}
|
||||||
|
task9 := &Task{
|
||||||
|
ID: 9,
|
||||||
|
Text: "task #9 with start and end date",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 1,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
StartDateUnix: 1544600000,
|
||||||
|
EndDateUnix: 1544700000,
|
||||||
|
}
|
||||||
|
task10 := &Task{
|
||||||
|
ID: 10,
|
||||||
|
Text: "task #10 basic",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 1,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task11 := &Task{
|
||||||
|
ID: 11,
|
||||||
|
Text: "task #11 basic",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 1,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task12 := &Task{
|
||||||
|
ID: 12,
|
||||||
|
Text: "task #12 basic",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 1,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task15 := &Task{
|
||||||
|
ID: 15,
|
||||||
|
Text: "task #15",
|
||||||
|
CreatedByID: 6,
|
||||||
|
CreatedBy: user6,
|
||||||
|
ListID: 6,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task16 := &Task{
|
||||||
|
ID: 16,
|
||||||
|
Text: "task #16",
|
||||||
|
CreatedByID: 6,
|
||||||
|
CreatedBy: user6,
|
||||||
|
ListID: 7,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task17 := &Task{
|
||||||
|
ID: 17,
|
||||||
|
Text: "task #17",
|
||||||
|
CreatedByID: 6,
|
||||||
|
CreatedBy: user6,
|
||||||
|
ListID: 8,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task18 := &Task{
|
||||||
|
ID: 18,
|
||||||
|
Text: "task #18",
|
||||||
|
CreatedByID: 6,
|
||||||
|
CreatedBy: user6,
|
||||||
|
ListID: 9,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task19 := &Task{
|
||||||
|
ID: 19,
|
||||||
|
Text: "task #19",
|
||||||
|
CreatedByID: 6,
|
||||||
|
CreatedBy: user6,
|
||||||
|
ListID: 10,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task20 := &Task{
|
||||||
|
ID: 20,
|
||||||
|
Text: "task #20",
|
||||||
|
CreatedByID: 6,
|
||||||
|
CreatedBy: user6,
|
||||||
|
ListID: 11,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task21 := &Task{
|
||||||
|
ID: 21,
|
||||||
|
Text: "task #21",
|
||||||
|
CreatedByID: 6,
|
||||||
|
CreatedBy: user6,
|
||||||
|
ListID: 12,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task22 := &Task{
|
||||||
|
ID: 22,
|
||||||
|
Text: "task #22",
|
||||||
|
CreatedByID: 6,
|
||||||
|
CreatedBy: user6,
|
||||||
|
ListID: 13,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task23 := &Task{
|
||||||
|
ID: 23,
|
||||||
|
Text: "task #23",
|
||||||
|
CreatedByID: 6,
|
||||||
|
CreatedBy: user6,
|
||||||
|
ListID: 14,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task24 := &Task{
|
||||||
|
ID: 24,
|
||||||
|
Text: "task #24",
|
||||||
|
CreatedByID: 6,
|
||||||
|
CreatedBy: user6,
|
||||||
|
ListID: 15,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task25 := &Task{
|
||||||
|
ID: 25,
|
||||||
|
Text: "task #25",
|
||||||
|
CreatedByID: 6,
|
||||||
|
CreatedBy: user6,
|
||||||
|
ListID: 16,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task26 := &Task{
|
||||||
|
ID: 26,
|
||||||
|
Text: "task #26",
|
||||||
|
CreatedByID: 6,
|
||||||
|
CreatedBy: user6,
|
||||||
|
ListID: 17,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task27 := &Task{
|
||||||
|
ID: 27,
|
||||||
|
Text: "task #27 with reminders",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
RemindersUnix: []int64{1543626724, 1543626824},
|
||||||
|
ListID: 1,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task28 := &Task{
|
||||||
|
ID: 28,
|
||||||
|
Text: "task #28 with repeat after",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 1,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
RepeatAfter: 3600,
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task29 := &Task{
|
||||||
|
ID: 29,
|
||||||
|
Text: "task #29 with parent task (1)",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 1,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{
|
||||||
|
RelationKindParenttask: {
|
||||||
|
{
|
||||||
|
ID: 1,
|
||||||
|
Text: "task #1",
|
||||||
|
Description: "Lorem Ipsum",
|
||||||
|
CreatedByID: 1,
|
||||||
|
ListID: 1,
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task30 := &Task{
|
||||||
|
ID: 30,
|
||||||
|
Text: "task #30 with assignees",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 1,
|
||||||
|
Assignees: []*User{
|
||||||
|
user1,
|
||||||
|
user2,
|
||||||
|
},
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task31 := &Task{
|
||||||
|
ID: 31,
|
||||||
|
Text: "task #31 with color",
|
||||||
|
HexColor: "f0f0f0",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 1,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task32 := &Task{
|
||||||
|
ID: 32,
|
||||||
|
Text: "task #32",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 3,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
task33 := &Task{
|
||||||
|
ID: 33,
|
||||||
|
Text: "task #33 with percent done",
|
||||||
|
CreatedByID: 1,
|
||||||
|
CreatedBy: user1,
|
||||||
|
ListID: 1,
|
||||||
|
PercentDone: 0.5,
|
||||||
|
RelatedTasks: map[RelationKind][]*Task{},
|
||||||
|
Created: 1543626724,
|
||||||
|
Updated: 1543626724,
|
||||||
|
}
|
||||||
|
|
||||||
|
type fields struct {
|
||||||
|
ListID int64
|
||||||
|
StartDateSortUnix int64
|
||||||
|
EndDateSortUnix int64
|
||||||
|
Lists []*List
|
||||||
|
SortBy []string // Is a string, since this is the place where a query string comes from the user
|
||||||
|
OrderBy []string
|
||||||
|
CRUDable web.CRUDable
|
||||||
|
Rights web.Rights
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
search string
|
||||||
|
a web.Auth
|
||||||
|
page int
|
||||||
|
}
|
||||||
|
type testcase struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
want interface{}
|
||||||
|
wantErr bool
|
||||||
|
}
|
||||||
|
tests := []testcase{
|
||||||
|
{
|
||||||
|
name: "ReadAll Tasks normally",
|
||||||
|
fields: fields{},
|
||||||
|
args: args{
|
||||||
|
search: "",
|
||||||
|
a: &User{ID: 1},
|
||||||
|
page: 0,
|
||||||
|
},
|
||||||
|
want: []*Task{
|
||||||
|
task1,
|
||||||
|
task2,
|
||||||
|
task3,
|
||||||
|
task4,
|
||||||
|
task5,
|
||||||
|
task6,
|
||||||
|
task7,
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
task10,
|
||||||
|
task11,
|
||||||
|
task12,
|
||||||
|
task15,
|
||||||
|
task16,
|
||||||
|
task17,
|
||||||
|
task18,
|
||||||
|
task19,
|
||||||
|
task20,
|
||||||
|
task21,
|
||||||
|
task22,
|
||||||
|
task23,
|
||||||
|
task24,
|
||||||
|
task25,
|
||||||
|
task26,
|
||||||
|
task27,
|
||||||
|
task28,
|
||||||
|
task29,
|
||||||
|
task30,
|
||||||
|
task31,
|
||||||
|
task32,
|
||||||
|
task33,
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// For more sorting tests see task_collection_sort_test.go
|
||||||
|
name: "ReadAll Tasks sorted by done asc and id desc",
|
||||||
|
fields: fields{
|
||||||
|
SortBy: []string{"done", "id"},
|
||||||
|
OrderBy: []string{"asc", "desc"},
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
search: "",
|
||||||
|
a: &User{ID: 1},
|
||||||
|
page: 0,
|
||||||
|
},
|
||||||
|
want: []*Task{
|
||||||
|
task2,
|
||||||
|
task33,
|
||||||
|
task32,
|
||||||
|
task31,
|
||||||
|
task30,
|
||||||
|
task29,
|
||||||
|
task28,
|
||||||
|
task27,
|
||||||
|
task26,
|
||||||
|
task25,
|
||||||
|
task24,
|
||||||
|
task23,
|
||||||
|
task22,
|
||||||
|
task21,
|
||||||
|
task20,
|
||||||
|
task19,
|
||||||
|
task18,
|
||||||
|
task17,
|
||||||
|
task16,
|
||||||
|
task15,
|
||||||
|
task12,
|
||||||
|
task11,
|
||||||
|
task10,
|
||||||
|
task9,
|
||||||
|
task8,
|
||||||
|
task7,
|
||||||
|
task6,
|
||||||
|
task5,
|
||||||
|
task4,
|
||||||
|
task3,
|
||||||
|
task1,
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ReadAll Tasks with range",
|
||||||
|
fields: fields{
|
||||||
|
StartDateSortUnix: 1544500000,
|
||||||
|
EndDateSortUnix: 1544600000,
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
search: "",
|
||||||
|
a: &User{ID: 1},
|
||||||
|
page: 0,
|
||||||
|
},
|
||||||
|
want: []*Task{
|
||||||
|
task7,
|
||||||
|
task9,
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ReadAll Tasks with range",
|
||||||
|
fields: fields{
|
||||||
|
StartDateSortUnix: 1544700000,
|
||||||
|
EndDateSortUnix: 1545000000,
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
search: "",
|
||||||
|
a: &User{ID: 1},
|
||||||
|
page: 0,
|
||||||
|
},
|
||||||
|
want: []*Task{
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ReadAll Tasks with range without end date",
|
||||||
|
fields: fields{
|
||||||
|
StartDateSortUnix: 1544700000,
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
search: "",
|
||||||
|
a: &User{ID: 1},
|
||||||
|
page: 0,
|
||||||
|
},
|
||||||
|
want: []*Task{
|
||||||
|
task8,
|
||||||
|
task9,
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
lt := &TaskCollection{
|
||||||
|
ListID: tt.fields.ListID,
|
||||||
|
StartDateSortUnix: tt.fields.StartDateSortUnix,
|
||||||
|
EndDateSortUnix: tt.fields.EndDateSortUnix,
|
||||||
|
SortBy: tt.fields.SortBy,
|
||||||
|
OrderBy: tt.fields.OrderBy,
|
||||||
|
CRUDable: tt.fields.CRUDable,
|
||||||
|
Rights: tt.fields.Rights,
|
||||||
|
}
|
||||||
|
got, _, _, err := lt.ReadAll(tt.args.a, tt.args.search, tt.args.page, 50)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("Test %s, Task.ReadAll() error = %v, wantErr %v", tt.name, err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if diff, equal := messagediff.PrettyDiff(got, tt.want); !equal {
|
||||||
|
t.Errorf("Test %s, LabelTask.ReadAll() = %v, want %v, \ndiff: %v", tt.name, got, tt.want, diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,728 +0,0 @@
|
||||||
// Vikunja is a todo-list application to facilitate your life.
|
|
||||||
// Copyright 2018-2019 Vikunja and contributors. All rights reserved.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"code.vikunja.io/api/pkg/db"
|
|
||||||
"code.vikunja.io/api/pkg/files"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"gopkg.in/d4l3k/messagediff.v1"
|
|
||||||
"sort"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"code.vikunja.io/web"
|
|
||||||
)
|
|
||||||
|
|
||||||
func sortTasksForTesting(by SortBy) (tasks []*Task) {
|
|
||||||
user1 := &User{
|
|
||||||
ID: 1,
|
|
||||||
Username: "user1",
|
|
||||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
|
||||||
IsActive: true,
|
|
||||||
AvatarURL: "111d68d06e2d317b5a59c2c6c5bad808", // hash for ""
|
|
||||||
}
|
|
||||||
user2 := &User{
|
|
||||||
ID: 2,
|
|
||||||
Username: "user2",
|
|
||||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
|
||||||
AvatarURL: "ab53a2911ddf9b4817ac01ddcd3d975f", // hash for ""
|
|
||||||
}
|
|
||||||
user6 := &User{
|
|
||||||
ID: 6,
|
|
||||||
Username: "user6",
|
|
||||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
|
||||||
IsActive: true,
|
|
||||||
AvatarURL: "3efbe51f864c6666bc27caf4c6ff90ed", // hash for ""
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks = []*Task{
|
|
||||||
{
|
|
||||||
ID: 1,
|
|
||||||
Text: "task #1",
|
|
||||||
Description: "Lorem Ipsum",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
Labels: []*Label{
|
|
||||||
{
|
|
||||||
ID: 4,
|
|
||||||
Title: "Label #4 - visible via other task",
|
|
||||||
CreatedByID: 2,
|
|
||||||
CreatedBy: user2,
|
|
||||||
Updated: 0,
|
|
||||||
Created: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{
|
|
||||||
RelationKindSubtask: {
|
|
||||||
{
|
|
||||||
ID: 29,
|
|
||||||
Text: "task #29 with parent task (1)",
|
|
||||||
CreatedByID: 1,
|
|
||||||
ListID: 1,
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Attachments: []*TaskAttachment{
|
|
||||||
{
|
|
||||||
ID: 1,
|
|
||||||
TaskID: 1,
|
|
||||||
FileID: 1,
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
File: &files.File{
|
|
||||||
ID: 1,
|
|
||||||
Name: "test",
|
|
||||||
Size: 100,
|
|
||||||
CreatedUnix: 1570998791,
|
|
||||||
CreatedByID: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 2,
|
|
||||||
TaskID: 1,
|
|
||||||
FileID: 9999,
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 2,
|
|
||||||
Text: "task #2 done",
|
|
||||||
Done: true,
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
Labels: []*Label{
|
|
||||||
{
|
|
||||||
ID: 4,
|
|
||||||
Title: "Label #4 - visible via other task",
|
|
||||||
CreatedByID: 2,
|
|
||||||
CreatedBy: user2,
|
|
||||||
Updated: 0,
|
|
||||||
Created: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 3,
|
|
||||||
Text: "task #3 high prio",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
Priority: 100,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 4,
|
|
||||||
Text: "task #4 low prio",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
Priority: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 5,
|
|
||||||
Text: "task #5 higher due date",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
DueDateUnix: 1543636724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 6,
|
|
||||||
Text: "task #6 lower due date",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
DueDateUnix: 1543616724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 7,
|
|
||||||
Text: "task #7 with start date",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
StartDateUnix: 1544600000,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 8,
|
|
||||||
Text: "task #8 with end date",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
EndDateUnix: 1544700000,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 9,
|
|
||||||
Text: "task #9 with start and end date",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
StartDateUnix: 1544600000,
|
|
||||||
EndDateUnix: 1544700000,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 10,
|
|
||||||
Text: "task #10 basic",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 11,
|
|
||||||
Text: "task #11 basic",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 12,
|
|
||||||
Text: "task #12 basic",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 15,
|
|
||||||
Text: "task #15",
|
|
||||||
CreatedByID: 6,
|
|
||||||
CreatedBy: user6,
|
|
||||||
ListID: 6,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 16,
|
|
||||||
Text: "task #16",
|
|
||||||
CreatedByID: 6,
|
|
||||||
CreatedBy: user6,
|
|
||||||
ListID: 7,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 17,
|
|
||||||
Text: "task #17",
|
|
||||||
CreatedByID: 6,
|
|
||||||
CreatedBy: user6,
|
|
||||||
ListID: 8,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 18,
|
|
||||||
Text: "task #18",
|
|
||||||
CreatedByID: 6,
|
|
||||||
CreatedBy: user6,
|
|
||||||
ListID: 9,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 19,
|
|
||||||
Text: "task #19",
|
|
||||||
CreatedByID: 6,
|
|
||||||
CreatedBy: user6,
|
|
||||||
ListID: 10,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 20,
|
|
||||||
Text: "task #20",
|
|
||||||
CreatedByID: 6,
|
|
||||||
CreatedBy: user6,
|
|
||||||
ListID: 11,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 21,
|
|
||||||
Text: "task #21",
|
|
||||||
CreatedByID: 6,
|
|
||||||
CreatedBy: user6,
|
|
||||||
ListID: 12,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 22,
|
|
||||||
Text: "task #22",
|
|
||||||
CreatedByID: 6,
|
|
||||||
CreatedBy: user6,
|
|
||||||
ListID: 13,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 23,
|
|
||||||
Text: "task #23",
|
|
||||||
CreatedByID: 6,
|
|
||||||
CreatedBy: user6,
|
|
||||||
ListID: 14,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 24,
|
|
||||||
Text: "task #24",
|
|
||||||
CreatedByID: 6,
|
|
||||||
CreatedBy: user6,
|
|
||||||
ListID: 15,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 25,
|
|
||||||
Text: "task #25",
|
|
||||||
CreatedByID: 6,
|
|
||||||
CreatedBy: user6,
|
|
||||||
ListID: 16,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 26,
|
|
||||||
Text: "task #26",
|
|
||||||
CreatedByID: 6,
|
|
||||||
CreatedBy: user6,
|
|
||||||
ListID: 17,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 27,
|
|
||||||
Text: "task #27 with reminders",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
RemindersUnix: []int64{1543626724, 1543626824},
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 28,
|
|
||||||
Text: "task #28 with repeat after",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
RepeatAfter: 3600,
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 29,
|
|
||||||
Text: "task #29 with parent task (1)",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{
|
|
||||||
RelationKindParenttask: {
|
|
||||||
{
|
|
||||||
ID: 1,
|
|
||||||
Text: "task #1",
|
|
||||||
Description: "Lorem Ipsum",
|
|
||||||
CreatedByID: 1,
|
|
||||||
ListID: 1,
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 30,
|
|
||||||
Text: "task #30 with assignees",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
Assignees: []*User{
|
|
||||||
user1,
|
|
||||||
user2,
|
|
||||||
},
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 31,
|
|
||||||
Text: "task #31 with color",
|
|
||||||
HexColor: "f0f0f0",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 32,
|
|
||||||
Text: "task #32",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 3,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 33,
|
|
||||||
Text: "task #33 with percent done",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
PercentDone: 0.5,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
switch by {
|
|
||||||
case SortTasksByPriorityDesc:
|
|
||||||
sort.Slice(tasks, func(i, j int) bool {
|
|
||||||
return tasks[i].Priority > tasks[j].Priority
|
|
||||||
})
|
|
||||||
case SortTasksByPriorityAsc:
|
|
||||||
sort.Slice(tasks, func(i, j int) bool {
|
|
||||||
return tasks[i].Priority < tasks[j].Priority
|
|
||||||
})
|
|
||||||
case SortTasksByDueDateDesc:
|
|
||||||
sort.Slice(tasks, func(i, j int) bool {
|
|
||||||
return tasks[i].DueDateUnix > tasks[j].DueDateUnix
|
|
||||||
})
|
|
||||||
case SortTasksByDueDateAsc:
|
|
||||||
sort.Slice(tasks, func(i, j int) bool {
|
|
||||||
return tasks[i].DueDateUnix < tasks[j].DueDateUnix
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTask_ReadAll(t *testing.T) {
|
|
||||||
assert.NoError(t, db.LoadFixtures())
|
|
||||||
|
|
||||||
// Dummy users
|
|
||||||
user1 := &User{
|
|
||||||
ID: 1,
|
|
||||||
Username: "user1",
|
|
||||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
|
||||||
IsActive: true,
|
|
||||||
AvatarURL: "111d68d06e2d317b5a59c2c6c5bad808", // hash for ""
|
|
||||||
}
|
|
||||||
|
|
||||||
type fields struct {
|
|
||||||
ListID int64
|
|
||||||
Sorting string
|
|
||||||
StartDateSortUnix int64
|
|
||||||
EndDateSortUnix int64
|
|
||||||
Lists []*List
|
|
||||||
CRUDable web.CRUDable
|
|
||||||
Rights web.Rights
|
|
||||||
}
|
|
||||||
type args struct {
|
|
||||||
search string
|
|
||||||
a web.Auth
|
|
||||||
page int
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
fields fields
|
|
||||||
args args
|
|
||||||
want interface{}
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "ReadAll Tasks normally",
|
|
||||||
fields: fields{},
|
|
||||||
args: args{
|
|
||||||
search: "",
|
|
||||||
a: &User{ID: 1},
|
|
||||||
page: 0,
|
|
||||||
},
|
|
||||||
want: sortTasksForTesting(SortTasksByUnsorted),
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "ReadAll Tasks sorted by priority (desc)",
|
|
||||||
fields: fields{
|
|
||||||
Sorting: "priority",
|
|
||||||
},
|
|
||||||
args: args{
|
|
||||||
search: "",
|
|
||||||
a: &User{ID: 1},
|
|
||||||
page: 0,
|
|
||||||
},
|
|
||||||
want: sortTasksForTesting(SortTasksByPriorityDesc),
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "ReadAll Tasks sorted by priority asc",
|
|
||||||
fields: fields{
|
|
||||||
Sorting: "priorityasc",
|
|
||||||
},
|
|
||||||
args: args{
|
|
||||||
search: "",
|
|
||||||
a: &User{ID: 1},
|
|
||||||
page: 0,
|
|
||||||
},
|
|
||||||
want: sortTasksForTesting(SortTasksByPriorityAsc),
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "ReadAll Tasks sorted by priority desc",
|
|
||||||
fields: fields{
|
|
||||||
Sorting: "prioritydesc",
|
|
||||||
},
|
|
||||||
args: args{
|
|
||||||
search: "",
|
|
||||||
a: &User{ID: 1},
|
|
||||||
page: 0,
|
|
||||||
},
|
|
||||||
want: sortTasksForTesting(SortTasksByPriorityDesc),
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "ReadAll Tasks sorted by due date default desc",
|
|
||||||
fields: fields{
|
|
||||||
Sorting: "duedate",
|
|
||||||
},
|
|
||||||
args: args{
|
|
||||||
search: "",
|
|
||||||
a: &User{ID: 1},
|
|
||||||
page: 0,
|
|
||||||
},
|
|
||||||
want: sortTasksForTesting(SortTasksByDueDateDesc),
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "ReadAll Tasks sorted by due date asc",
|
|
||||||
fields: fields{
|
|
||||||
Sorting: "duedateasc",
|
|
||||||
},
|
|
||||||
args: args{
|
|
||||||
search: "",
|
|
||||||
a: &User{ID: 1},
|
|
||||||
page: 0,
|
|
||||||
},
|
|
||||||
want: sortTasksForTesting(SortTasksByDueDateAsc),
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "ReadAll Tasks sorted by due date desc",
|
|
||||||
fields: fields{
|
|
||||||
Sorting: "duedatedesc",
|
|
||||||
},
|
|
||||||
args: args{
|
|
||||||
search: "",
|
|
||||||
a: &User{ID: 1},
|
|
||||||
page: 0,
|
|
||||||
},
|
|
||||||
|
|
||||||
want: sortTasksForTesting(SortTasksByDueDateDesc),
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "ReadAll Tasks with range",
|
|
||||||
fields: fields{
|
|
||||||
StartDateSortUnix: 1544500000,
|
|
||||||
EndDateSortUnix: 1544600000,
|
|
||||||
},
|
|
||||||
args: args{
|
|
||||||
search: "",
|
|
||||||
a: &User{ID: 1},
|
|
||||||
page: 0,
|
|
||||||
},
|
|
||||||
want: []*Task{
|
|
||||||
{
|
|
||||||
ID: 7,
|
|
||||||
Text: "task #7 with start date",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
StartDateUnix: 1544600000,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 9,
|
|
||||||
Text: "task #9 with start and end date",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
StartDateUnix: 1544600000,
|
|
||||||
EndDateUnix: 1544700000,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "ReadAll Tasks with range",
|
|
||||||
fields: fields{
|
|
||||||
StartDateSortUnix: 1544700000,
|
|
||||||
EndDateSortUnix: 1545000000,
|
|
||||||
},
|
|
||||||
args: args{
|
|
||||||
search: "",
|
|
||||||
a: &User{ID: 1},
|
|
||||||
page: 0,
|
|
||||||
},
|
|
||||||
want: []*Task{
|
|
||||||
{
|
|
||||||
ID: 8,
|
|
||||||
Text: "task #8 with end date",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
EndDateUnix: 1544700000,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 9,
|
|
||||||
Text: "task #9 with start and end date",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
StartDateUnix: 1544600000,
|
|
||||||
EndDateUnix: 1544700000,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "ReadAll Tasks with range without end date",
|
|
||||||
fields: fields{
|
|
||||||
StartDateSortUnix: 1544700000,
|
|
||||||
},
|
|
||||||
args: args{
|
|
||||||
search: "",
|
|
||||||
a: &User{ID: 1},
|
|
||||||
page: 0,
|
|
||||||
},
|
|
||||||
want: []*Task{
|
|
||||||
{
|
|
||||||
ID: 8,
|
|
||||||
Text: "task #8 with end date",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
EndDateUnix: 1544700000,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: 9,
|
|
||||||
Text: "task #9 with start and end date",
|
|
||||||
CreatedByID: 1,
|
|
||||||
CreatedBy: user1,
|
|
||||||
ListID: 1,
|
|
||||||
RelatedTasks: map[RelationKind][]*Task{},
|
|
||||||
Created: 1543626724,
|
|
||||||
Updated: 1543626724,
|
|
||||||
StartDateUnix: 1544600000,
|
|
||||||
EndDateUnix: 1544700000,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
lt := &TaskCollection{
|
|
||||||
ListID: tt.fields.ListID,
|
|
||||||
Sorting: tt.fields.Sorting,
|
|
||||||
StartDateSortUnix: tt.fields.StartDateSortUnix,
|
|
||||||
EndDateSortUnix: tt.fields.EndDateSortUnix,
|
|
||||||
CRUDable: tt.fields.CRUDable,
|
|
||||||
Rights: tt.fields.Rights,
|
|
||||||
}
|
|
||||||
got, _, _, err := lt.ReadAll(tt.args.a, tt.args.search, tt.args.page, 50)
|
|
||||||
if (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("Test %s, Task.ReadAll() error = %v, wantErr %v", tt.name, err, tt.wantErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if diff, equal := messagediff.PrettyDiff(got, tt.want); !equal {
|
|
||||||
t.Errorf("Test %s, LabelTask.ReadAll() = %v, want %v, \ndiff: %v", tt.name, got, tt.want, diff)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -105,25 +105,13 @@ func (TaskReminder) TableName() string {
|
||||||
return "task_reminders"
|
return "task_reminders"
|
||||||
}
|
}
|
||||||
|
|
||||||
// SortBy declares constants to sort
|
|
||||||
type SortBy int
|
|
||||||
|
|
||||||
// These are possible sort options
|
|
||||||
const (
|
|
||||||
SortTasksByUnsorted SortBy = -1
|
|
||||||
SortTasksByDueDateAsc = iota
|
|
||||||
SortTasksByDueDateDesc
|
|
||||||
SortTasksByPriorityAsc
|
|
||||||
SortTasksByPriorityDesc
|
|
||||||
)
|
|
||||||
|
|
||||||
type taskOptions struct {
|
type taskOptions struct {
|
||||||
search string
|
search string
|
||||||
sortby SortBy
|
|
||||||
startDate time.Time
|
startDate time.Time
|
||||||
endDate time.Time
|
endDate time.Time
|
||||||
page int
|
page int
|
||||||
perPage int
|
perPage int
|
||||||
|
sortby []*sortParam
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadAll is a dummy function to still have that endpoint documented
|
// ReadAll is a dummy function to still have that endpoint documented
|
||||||
|
@ -154,16 +142,19 @@ func getRawTasksForLists(lists []*List, opts *taskOptions) (taskMap map[int64]*T
|
||||||
listIDs = append(listIDs, l.ID)
|
listIDs = append(listIDs, l.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Since xorm does not use placeholders for order by, it is possible to expose this with sql injection if we're directly
|
||||||
|
// passing user input to the db.
|
||||||
|
// As a workaround to prevent this, we check for valid column names here prior to passing it to the db.
|
||||||
var orderby string
|
var orderby string
|
||||||
switch opts.sortby {
|
for i, param := range opts.sortby {
|
||||||
case SortTasksByPriorityDesc:
|
// Validate the params
|
||||||
orderby = "priority desc"
|
if err := param.validate(); err != nil {
|
||||||
case SortTasksByPriorityAsc:
|
return nil, 0, 0, err
|
||||||
orderby = "priority asc"
|
}
|
||||||
case SortTasksByDueDateDesc:
|
orderby += param.sortBy.String() + " " + param.orderBy.String()
|
||||||
orderby = "due_date_unix desc"
|
if (i + 1) < len(opts.sortby) {
|
||||||
case SortTasksByDueDateAsc:
|
orderby += ", "
|
||||||
orderby = "due_date_unix asc"
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
taskMap = make(map[int64]*Task)
|
taskMap = make(map[int64]*Task)
|
||||||
|
@ -232,34 +223,13 @@ func getTasksForLists(lists []*List, opts *taskOptions) (tasks []*Task, resultCo
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, 0, err
|
return nil, 0, 0, err
|
||||||
}
|
}
|
||||||
// Because the list is sorted by id which we don't want (since we're dealing with maps)
|
// Because the list is fully unsorted (since we're dealing with maps)
|
||||||
// we have to manually sort the tasks again here.
|
// we have to manually sort the tasks again here.
|
||||||
sortTasks(tasks, opts.sortby)
|
sortTasks(tasks, opts.sortby)
|
||||||
|
|
||||||
return tasks, resultCount, totalItems, err
|
return tasks, resultCount, totalItems, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func sortTasks(tasks []*Task, by SortBy) {
|
|
||||||
switch by {
|
|
||||||
case SortTasksByPriorityDesc:
|
|
||||||
sort.Slice(tasks, func(i, j int) bool {
|
|
||||||
return tasks[i].Priority > tasks[j].Priority
|
|
||||||
})
|
|
||||||
case SortTasksByPriorityAsc:
|
|
||||||
sort.Slice(tasks, func(i, j int) bool {
|
|
||||||
return tasks[i].Priority < tasks[j].Priority
|
|
||||||
})
|
|
||||||
case SortTasksByDueDateDesc:
|
|
||||||
sort.Slice(tasks, func(i, j int) bool {
|
|
||||||
return tasks[i].DueDateUnix > tasks[j].DueDateUnix
|
|
||||||
})
|
|
||||||
case SortTasksByDueDateAsc:
|
|
||||||
sort.Slice(tasks, func(i, j int) bool {
|
|
||||||
return tasks[i].DueDateUnix < tasks[j].DueDateUnix
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTasksByListID gets all todotasks for a list
|
// GetTasksByListID gets all todotasks for a list
|
||||||
func GetTasksByListID(listID int64) (tasks []*Task, err error) {
|
func GetTasksByListID(listID int64) (tasks []*Task, err error) {
|
||||||
// make a map so we can put in a lot of other stuff more easily
|
// make a map so we can put in a lot of other stuff more easily
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||||
// This file was generated by swaggo/swag at
|
// This file was generated by swaggo/swag at
|
||||||
// 2019-12-01 13:20:36.822585642 +0100 CET m=+0.129079038
|
// 2019-12-05 22:15:49.761451764 +0100 CET m=+0.171539379
|
||||||
|
|
||||||
package swagger
|
package swagger
|
||||||
|
|
||||||
|
@ -407,7 +407,7 @@ var doc = `{
|
||||||
"JWTKeyAuth": []
|
"JWTKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Returns a list by its ID.",
|
"description": "Returns a team by its ID.",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
|
@ -415,13 +415,13 @@ var doc = `{
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"list"
|
"team"
|
||||||
],
|
],
|
||||||
"summary": "Gets one list",
|
"summary": "Gets one team",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"description": "List ID",
|
"description": "Team ID",
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
@ -429,13 +429,13 @@ var doc = `{
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "The list",
|
"description": "The team",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/models.List"
|
"$ref": "#/definitions/models.Team"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"403": {
|
"403": {
|
||||||
"description": "The user does not have access to the list",
|
"description": "The user does not have access to the team",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/code.vikunja.io.web.HTTPError"
|
"$ref": "#/definitions/code.vikunja.io.web.HTTPError"
|
||||||
}
|
}
|
||||||
|
@ -984,7 +984,7 @@ var doc = `{
|
||||||
"tags": [
|
"tags": [
|
||||||
"task"
|
"task"
|
||||||
],
|
],
|
||||||
"summary": "Get tasks on a list",
|
"summary": "Get tasks in a list",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
|
@ -1013,8 +1013,14 @@ var doc = `{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The sorting parameter. Possible values to sort by are priority, prioritydesc, priorityasc, duedate, duedatedesc, duedateasc.",
|
"description": "The sorting parameter. You can pass this multiple times to get the tasks ordered by multiple different parametes, along with ` + "`" + `order_by` + "`" + `. Possible values to sort by are ` + "`" + `id` + "`" + `, ` + "`" + `text` + "`" + `, ` + "`" + `description` + "`" + `, ` + "`" + `done` + "`" + `, ` + "`" + `done_at_unix` + "`" + `, ` + "`" + `due_date_unix` + "`" + `, ` + "`" + `created_by_id` + "`" + `, ` + "`" + `list_id` + "`" + `, ` + "`" + `repeat_after` + "`" + `, ` + "`" + `priority` + "`" + `, ` + "`" + `start_date_unix` + "`" + `, ` + "`" + `end_date_unix` + "`" + `, ` + "`" + `hex_color` + "`" + `, ` + "`" + `percent_done` + "`" + `, ` + "`" + `uid` + "`" + `, ` + "`" + `created` + "`" + `, ` + "`" + `updated` + "`" + `. Default is ` + "`" + `id` + "`" + `.",
|
||||||
"name": "sort",
|
"name": "sort_by",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "The ordering parameter. Possible values to order by are ` + "`" + `asc` + "`" + ` or ` + "`" + `desc` + "`" + `. Default is ` + "`" + `asc` + "`" + `.",
|
||||||
|
"name": "order_by",
|
||||||
"in": "query"
|
"in": "query"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -4633,13 +4639,6 @@ var doc = `{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/models.User"
|
||||||
},
|
},
|
||||||
"tasks": {
|
|
||||||
"description": "An array of tasks which belong to the list.",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/definitions/models.Task"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"title": {
|
"title": {
|
||||||
"description": "The title of the list. You'll see this in the namespace overview.",
|
"description": "The title of the list. You'll see this in the namespace overview.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|
|
@ -389,7 +389,7 @@
|
||||||
"JWTKeyAuth": []
|
"JWTKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Returns a list by its ID.",
|
"description": "Returns a team by its ID.",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
|
@ -397,13 +397,13 @@
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"list"
|
"team"
|
||||||
],
|
],
|
||||||
"summary": "Gets one list",
|
"summary": "Gets one team",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"description": "List ID",
|
"description": "Team ID",
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
@ -411,13 +411,13 @@
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "The list",
|
"description": "The team",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/models.List"
|
"$ref": "#/definitions/models.Team"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"403": {
|
"403": {
|
||||||
"description": "The user does not have access to the list",
|
"description": "The user does not have access to the team",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/code.vikunja.io/web.HTTPError"
|
"$ref": "#/definitions/code.vikunja.io/web.HTTPError"
|
||||||
}
|
}
|
||||||
|
@ -966,7 +966,7 @@
|
||||||
"tags": [
|
"tags": [
|
||||||
"task"
|
"task"
|
||||||
],
|
],
|
||||||
"summary": "Get tasks on a list",
|
"summary": "Get tasks in a list",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
|
@ -995,8 +995,14 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The sorting parameter. Possible values to sort by are priority, prioritydesc, priorityasc, duedate, duedatedesc, duedateasc.",
|
"description": "The sorting parameter. You can pass this multiple times to get the tasks ordered by multiple different parametes, along with `order_by`. Possible values to sort by are `id`, `text`, `description`, `done`, `done_at_unix`, `due_date_unix`, `created_by_id`, `list_id`, `repeat_after`, `priority`, `start_date_unix`, `end_date_unix`, `hex_color`, `percent_done`, `uid`, `created`, `updated`. Default is `id`.",
|
||||||
"name": "sort",
|
"name": "sort_by",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "The ordering parameter. Possible values to order by are `asc` or `desc`. Default is `asc`.",
|
||||||
|
"name": "order_by",
|
||||||
"in": "query"
|
"in": "query"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -4614,13 +4620,6 @@
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"$ref": "#/definitions/models.User"
|
"$ref": "#/definitions/models.User"
|
||||||
},
|
},
|
||||||
"tasks": {
|
|
||||||
"description": "An array of tasks which belong to the list.",
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/definitions/models.Task"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"title": {
|
"title": {
|
||||||
"description": "The title of the list. You'll see this in the namespace overview.",
|
"description": "The title of the list. You'll see this in the namespace overview.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|
|
@ -236,11 +236,6 @@ definitions:
|
||||||
$ref: '#/definitions/models.User'
|
$ref: '#/definitions/models.User'
|
||||||
description: The user who created this list.
|
description: The user who created this list.
|
||||||
type: object
|
type: object
|
||||||
tasks:
|
|
||||||
description: An array of tasks which belong to the list.
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/models.Task'
|
|
||||||
type: array
|
|
||||||
title:
|
title:
|
||||||
description: The title of the list. You'll see this in the namespace overview.
|
description: The title of the list. You'll see this in the namespace overview.
|
||||||
maxLength: 250
|
maxLength: 250
|
||||||
|
@ -1138,9 +1133,9 @@ paths:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
description: Returns a list by its ID.
|
description: Returns a team by its ID.
|
||||||
parameters:
|
parameters:
|
||||||
- description: List ID
|
- description: Team ID
|
||||||
in: path
|
in: path
|
||||||
name: id
|
name: id
|
||||||
required: true
|
required: true
|
||||||
|
@ -1149,11 +1144,11 @@ paths:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: The list
|
description: The team
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/models.List'
|
$ref: '#/definitions/models.Team'
|
||||||
"403":
|
"403":
|
||||||
description: The user does not have access to the list
|
description: The user does not have access to the team
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/code.vikunja.io/web.HTTPError'
|
$ref: '#/definitions/code.vikunja.io/web.HTTPError'
|
||||||
"500":
|
"500":
|
||||||
|
@ -1162,9 +1157,9 @@ paths:
|
||||||
$ref: '#/definitions/models.Message'
|
$ref: '#/definitions/models.Message'
|
||||||
security:
|
security:
|
||||||
- JWTKeyAuth: []
|
- JWTKeyAuth: []
|
||||||
summary: Gets one list
|
summary: Gets one team
|
||||||
tags:
|
tags:
|
||||||
- list
|
- team
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
|
@ -1667,10 +1662,19 @@ paths:
|
||||||
in: query
|
in: query
|
||||||
name: s
|
name: s
|
||||||
type: string
|
type: string
|
||||||
- description: The sorting parameter. Possible values to sort by are priority,
|
- description: The sorting parameter. You can pass this multiple times to get
|
||||||
prioritydesc, priorityasc, duedate, duedatedesc, duedateasc.
|
the tasks ordered by multiple different parametes, along with `order_by`.
|
||||||
|
Possible values to sort by are `id`, `text`, `description`, `done`, `done_at_unix`,
|
||||||
|
`due_date_unix`, `created_by_id`, `list_id`, `repeat_after`, `priority`,
|
||||||
|
`start_date_unix`, `end_date_unix`, `hex_color`, `percent_done`, `uid`,
|
||||||
|
`created`, `updated`. Default is `id`.
|
||||||
in: query
|
in: query
|
||||||
name: sort
|
name: sort_by
|
||||||
|
type: string
|
||||||
|
- description: The ordering parameter. Possible values to order by are `asc`
|
||||||
|
or `desc`. Default is `asc`.
|
||||||
|
in: query
|
||||||
|
name: order_by
|
||||||
type: string
|
type: string
|
||||||
- description: The start date parameter to filter by. Expects a unix timestamp.
|
- description: The start date parameter to filter by. Expects a unix timestamp.
|
||||||
If no end date, but a start date is specified, the end date is set to the
|
If no end date, but a start date is specified, the end date is set to the
|
||||||
|
@ -1699,7 +1703,7 @@ paths:
|
||||||
$ref: '#/definitions/models.Message'
|
$ref: '#/definitions/models.Message'
|
||||||
security:
|
security:
|
||||||
- JWTKeyAuth: []
|
- JWTKeyAuth: []
|
||||||
summary: Get tasks on a list
|
summary: Get tasks in a list
|
||||||
tags:
|
tags:
|
||||||
- task
|
- task
|
||||||
/lists/{listID}/teams/{teamID}:
|
/lists/{listID}/teams/{teamID}:
|
||||||
|
|
26
vendor/github.com/mohae/deepcopy/.gitignore
generated
vendored
Normal file
26
vendor/github.com/mohae/deepcopy/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Folders
|
||||||
|
_obj
|
||||||
|
_test
|
||||||
|
|
||||||
|
# Architecture specific extensions/prefixes
|
||||||
|
*.[568vq]
|
||||||
|
[568vq].out
|
||||||
|
|
||||||
|
*.cgo1.go
|
||||||
|
*.cgo2.c
|
||||||
|
_cgo_defun.c
|
||||||
|
_cgo_gotypes.go
|
||||||
|
_cgo_export.*
|
||||||
|
|
||||||
|
_testmain.go
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
*.test
|
||||||
|
*~
|
||||||
|
*.out
|
||||||
|
*.log
|
11
vendor/github.com/mohae/deepcopy/.travis.yml
generated
vendored
Normal file
11
vendor/github.com/mohae/deepcopy/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
language: go
|
||||||
|
|
||||||
|
go:
|
||||||
|
- tip
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
allow_failures:
|
||||||
|
- go: tip
|
||||||
|
|
||||||
|
script:
|
||||||
|
- go test ./...
|
21
vendor/github.com/mohae/deepcopy/LICENSE
generated
vendored
Normal file
21
vendor/github.com/mohae/deepcopy/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Joel
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
8
vendor/github.com/mohae/deepcopy/README.md
generated
vendored
Normal file
8
vendor/github.com/mohae/deepcopy/README.md
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
deepCopy
|
||||||
|
========
|
||||||
|
[![GoDoc](https://godoc.org/github.com/mohae/deepcopy?status.svg)](https://godoc.org/github.com/mohae/deepcopy)[![Build Status](https://travis-ci.org/mohae/deepcopy.png)](https://travis-ci.org/mohae/deepcopy)
|
||||||
|
|
||||||
|
DeepCopy makes deep copies of things: unexported field values are not copied.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
cpy := deepcopy.Copy(orig)
|
125
vendor/github.com/mohae/deepcopy/deepcopy.go
generated
vendored
Normal file
125
vendor/github.com/mohae/deepcopy/deepcopy.go
generated
vendored
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
// deepcopy makes deep copies of things. A standard copy will copy the
|
||||||
|
// pointers: deep copy copies the values pointed to. Unexported field
|
||||||
|
// values are not copied.
|
||||||
|
//
|
||||||
|
// Copyright (c)2014-2016, Joel Scoble (github.com/mohae), all rights reserved.
|
||||||
|
// License: MIT, for more details check the included LICENSE file.
|
||||||
|
package deepcopy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Interface for delegating copy process to type
|
||||||
|
type Interface interface {
|
||||||
|
DeepCopy() interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iface is an alias to Copy; this exists for backwards compatibility reasons.
|
||||||
|
func Iface(iface interface{}) interface{} {
|
||||||
|
return Copy(iface)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy creates a deep copy of whatever is passed to it and returns the copy
|
||||||
|
// in an interface{}. The returned value will need to be asserted to the
|
||||||
|
// correct type.
|
||||||
|
func Copy(src interface{}) interface{} {
|
||||||
|
if src == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the interface a reflect.Value
|
||||||
|
original := reflect.ValueOf(src)
|
||||||
|
|
||||||
|
// Make a copy of the same type as the original.
|
||||||
|
cpy := reflect.New(original.Type()).Elem()
|
||||||
|
|
||||||
|
// Recursively copy the original.
|
||||||
|
copyRecursive(original, cpy)
|
||||||
|
|
||||||
|
// Return the copy as an interface.
|
||||||
|
return cpy.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
// copyRecursive does the actual copying of the interface. It currently has
|
||||||
|
// limited support for what it can handle. Add as needed.
|
||||||
|
func copyRecursive(original, cpy reflect.Value) {
|
||||||
|
// check for implement deepcopy.Interface
|
||||||
|
if original.CanInterface() {
|
||||||
|
if copier, ok := original.Interface().(Interface); ok {
|
||||||
|
cpy.Set(reflect.ValueOf(copier.DeepCopy()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle according to original's Kind
|
||||||
|
switch original.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
// Get the actual value being pointed to.
|
||||||
|
originalValue := original.Elem()
|
||||||
|
|
||||||
|
// if it isn't valid, return.
|
||||||
|
if !originalValue.IsValid() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cpy.Set(reflect.New(originalValue.Type()))
|
||||||
|
copyRecursive(originalValue, cpy.Elem())
|
||||||
|
|
||||||
|
case reflect.Interface:
|
||||||
|
// If this is a nil, don't do anything
|
||||||
|
if original.IsNil() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Get the value for the interface, not the pointer.
|
||||||
|
originalValue := original.Elem()
|
||||||
|
|
||||||
|
// Get the value by calling Elem().
|
||||||
|
copyValue := reflect.New(originalValue.Type()).Elem()
|
||||||
|
copyRecursive(originalValue, copyValue)
|
||||||
|
cpy.Set(copyValue)
|
||||||
|
|
||||||
|
case reflect.Struct:
|
||||||
|
t, ok := original.Interface().(time.Time)
|
||||||
|
if ok {
|
||||||
|
cpy.Set(reflect.ValueOf(t))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Go through each field of the struct and copy it.
|
||||||
|
for i := 0; i < original.NumField(); i++ {
|
||||||
|
// The Type's StructField for a given field is checked to see if StructField.PkgPath
|
||||||
|
// is set to determine if the field is exported or not because CanSet() returns false
|
||||||
|
// for settable fields. I'm not sure why. -mohae
|
||||||
|
if original.Type().Field(i).PkgPath != "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
copyRecursive(original.Field(i), cpy.Field(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Slice:
|
||||||
|
if original.IsNil() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Make a new slice and copy each element.
|
||||||
|
cpy.Set(reflect.MakeSlice(original.Type(), original.Len(), original.Cap()))
|
||||||
|
for i := 0; i < original.Len(); i++ {
|
||||||
|
copyRecursive(original.Index(i), cpy.Index(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Map:
|
||||||
|
if original.IsNil() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cpy.Set(reflect.MakeMap(original.Type()))
|
||||||
|
for _, key := range original.MapKeys() {
|
||||||
|
originalValue := original.MapIndex(key)
|
||||||
|
copyValue := reflect.New(originalValue.Type()).Elem()
|
||||||
|
copyRecursive(originalValue, copyValue)
|
||||||
|
copyKey := Copy(key.Interface())
|
||||||
|
cpy.SetMapIndex(reflect.ValueOf(copyKey), copyValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
cpy.Set(original)
|
||||||
|
}
|
||||||
|
}
|
2
vendor/github.com/prometheus/procfs/go.mod
generated
vendored
2
vendor/github.com/prometheus/procfs/go.mod
generated
vendored
|
@ -1,3 +1 @@
|
||||||
module github.com/prometheus/procfs
|
module github.com/prometheus/procfs
|
||||||
|
|
||||||
go 1.12
|
|
||||||
|
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
|
@ -114,6 +114,8 @@ github.com/mattn/go-sqlite3
|
||||||
github.com/matttproud/golang_protobuf_extensions/pbutil
|
github.com/matttproud/golang_protobuf_extensions/pbutil
|
||||||
# github.com/mitchellh/mapstructure v1.1.2
|
# github.com/mitchellh/mapstructure v1.1.2
|
||||||
github.com/mitchellh/mapstructure
|
github.com/mitchellh/mapstructure
|
||||||
|
# github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
|
||||||
|
github.com/mohae/deepcopy
|
||||||
# github.com/olekukonko/tablewriter v0.0.1
|
# github.com/olekukonko/tablewriter v0.0.1
|
||||||
github.com/olekukonko/tablewriter
|
github.com/olekukonko/tablewriter
|
||||||
# github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
# github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||||
|
|
Loading…
Reference in a new issue