Compare commits
29 commits
7635791f09
...
9ec7261a94
Author | SHA1 | Date | |
---|---|---|---|
|
9ec7261a94 | ||
|
2d2b63938c | ||
|
57e969a562 | ||
|
ff07bd1ed6 | ||
|
56e566ea9b | ||
|
5e104ec7f9 | ||
|
67723bfccc | ||
|
1631c8b6b0 | ||
|
a5e3d4259d | ||
|
f57c445ead | ||
|
11341ce37e | ||
|
a266a6f7fc | ||
|
b56e4ed76e | ||
|
f61449dea1 | ||
|
fd7c609e5d | ||
|
9725a0fc48 | ||
|
6d0775586e | ||
|
badeb84282 | ||
|
e63377effa | ||
|
1fd4cd18e3 | ||
|
9d65764899 | ||
|
a81020f660 | ||
|
7e88bd69c1 | ||
|
d65bbc897d | ||
|
7964e0d1d7 | ||
|
591d0201cf | ||
|
f7f29241b3 | ||
|
1f4abc2a6a | ||
|
bcb661dc22 |
21 changed files with 1563 additions and 959 deletions
|
@ -47,7 +47,7 @@ itest:
|
||||||
make build
|
make build
|
||||||
./bin/$(PROC_NAME) >/dev/null 2>&1 &
|
./bin/$(PROC_NAME) >/dev/null 2>&1 &
|
||||||
sleep 1 # Adjust if needed
|
sleep 1 # Adjust if needed
|
||||||
python ../testing.py
|
python ../testing/testing.py || pkill $(PROC_NAME)
|
||||||
pkill $(PROC_NAME)
|
pkill $(PROC_NAME)
|
||||||
|
|
||||||
# Get dependencies target
|
# Get dependencies target
|
||||||
|
|
|
@ -13,10 +13,10 @@ require (
|
||||||
require (
|
require (
|
||||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
github.com/go-openapi/jsonpointer v0.20.3 // indirect
|
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||||
github.com/go-openapi/jsonreference v0.20.5 // indirect
|
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||||
github.com/go-openapi/spec v0.20.15 // indirect
|
github.com/go-openapi/spec v0.21.0 // indirect
|
||||||
github.com/go-openapi/swag v0.22.10 // indirect
|
github.com/go-openapi/swag v0.23.0 // indirect
|
||||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
|
@ -25,10 +25,10 @@ require (
|
||||||
github.com/swaggo/files/v2 v2.0.0 // indirect
|
github.com/swaggo/files/v2 v2.0.0 // indirect
|
||||||
golang.org/x/tools v0.19.0 // indirect
|
golang.org/x/tools v0.19.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
|
modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect
|
||||||
modernc.org/libc v1.41.0 // indirect
|
modernc.org/libc v1.49.1 // indirect
|
||||||
modernc.org/mathutil v1.6.0 // indirect
|
modernc.org/mathutil v1.6.0 // indirect
|
||||||
modernc.org/memory v1.7.2 // indirect
|
modernc.org/memory v1.8.0 // indirect
|
||||||
modernc.org/strutil v1.2.0 // indirect
|
modernc.org/strutil v1.2.0 // indirect
|
||||||
modernc.org/token v1.1.0 // indirect
|
modernc.org/token v1.1.0 // indirect
|
||||||
)
|
)
|
||||||
|
@ -42,7 +42,7 @@ require (
|
||||||
// These are all for fiber
|
// These are all for fiber
|
||||||
require (
|
require (
|
||||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||||
github.com/gofiber/fiber/v2 v2.52.2
|
github.com/gofiber/fiber/v2 v2.52.4
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/klauspost/compress v1.17.7 // indirect
|
github.com/klauspost/compress v1.17.7 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
|
@ -52,5 +52,5 @@ require (
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/valyala/fasthttp v1.52.0 // indirect
|
github.com/valyala/fasthttp v1.52.0 // indirect
|
||||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||||
golang.org/x/sys v0.18.0 // indirect
|
golang.org/x/sys v0.19.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,20 +10,20 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
github.com/go-openapi/jsonpointer v0.20.3 h1:jykzYWS/kyGtsHfRt6aV8JTB9pcQAXPIA7qlZ5aRlyk=
|
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||||
github.com/go-openapi/jsonpointer v0.20.3/go.mod h1:c7l0rjoouAuIxCm8v/JWKRgMjDG/+/7UBWsXMrv6PsM=
|
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||||
github.com/go-openapi/jsonreference v0.20.5 h1:hutI+cQI+HbSQaIGSfsBsYI0pHk+CATf8Fk5gCSj0yI=
|
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
|
||||||
github.com/go-openapi/jsonreference v0.20.5/go.mod h1:thAqAp31UABtI+FQGKAQfmv7DbFpKNUlva2UPCxKu2Y=
|
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
|
||||||
github.com/go-openapi/spec v0.20.15 h1:8bDcVxF607pTh9NpPwgsH4J5Uhh5mV5XoWnkurdiY+U=
|
github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY=
|
||||||
github.com/go-openapi/spec v0.20.15/go.mod h1:o0upgqg5uYFG7O5mADrDVmSG3Wa6y6OLhwiCqQ+sTv4=
|
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
|
||||||
github.com/go-openapi/swag v0.22.10 h1:4y86NVn7Z2yYd6pfS4Z+Nyh3aAUL3Nul+LMbhFKy0gA=
|
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||||
github.com/go-openapi/swag v0.22.10/go.mod h1:Cnn8BYtRlx6BNE3DPN86f/xkapGIcLWzh3CLEb4C1jI=
|
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
github.com/gofiber/contrib/jwt v1.0.8 h1:/GeOsm/Mr1OGr0GTy+RIVSz5VgNNyP3ZgK4wdqxF/WY=
|
github.com/gofiber/contrib/jwt v1.0.8 h1:/GeOsm/Mr1OGr0GTy+RIVSz5VgNNyP3ZgK4wdqxF/WY=
|
||||||
github.com/gofiber/contrib/jwt v1.0.8/go.mod h1:gWWBtBiLmKXRN7xy6a96QO0KGvPEyxdh8x496Ujtg84=
|
github.com/gofiber/contrib/jwt v1.0.8/go.mod h1:gWWBtBiLmKXRN7xy6a96QO0KGvPEyxdh8x496Ujtg84=
|
||||||
github.com/gofiber/fiber/v2 v2.52.2 h1:b0rYH6b06Df+4NyrbdptQL8ifuxw/Tf2DgfkZkDaxEo=
|
github.com/gofiber/fiber/v2 v2.52.4 h1:P+T+4iK7VaqUsq2PALYEfBBo6bJZ4q3FP8cZ84EggTM=
|
||||||
github.com/gofiber/fiber/v2 v2.52.2/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
github.com/gofiber/fiber/v2 v2.52.4/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
||||||
github.com/gofiber/swagger v1.0.0 h1:BzUzDS9ZT6fDUa692kxmfOjc1DZiloLiPK/W5z1H1tc=
|
github.com/gofiber/swagger v1.0.0 h1:BzUzDS9ZT6fDUa692kxmfOjc1DZiloLiPK/W5z1H1tc=
|
||||||
github.com/gofiber/swagger v1.0.0/go.mod h1:QrYNF1Yrc7ggGK6ATsJ6yfH/8Zi5bu9lA7wB8TmCecg=
|
github.com/gofiber/swagger v1.0.0/go.mod h1:QrYNF1Yrc7ggGK6ATsJ6yfH/8Zi5bu9lA7wB8TmCecg=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||||
|
@ -85,8 +85,8 @@ golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
|
||||||
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
|
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
|
||||||
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
|
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
|
||||||
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=
|
||||||
|
@ -94,16 +94,26 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
modernc.org/cc/v4 v4.20.0 h1:45Or8mQfbUqJOG9WaxvlFYOAQO0lQ5RvqBcFCXngjxk=
|
||||||
|
modernc.org/cc/v4 v4.20.0/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
|
||||||
|
modernc.org/ccgo/v4 v4.15.0 h1:uwfCZOkKhaNNotgYW7kxkJwrkQC1HfGitt/7ousudJE=
|
||||||
|
modernc.org/ccgo/v4 v4.15.0/go.mod h1:XVITcYGiI+O97UNDLMsnZ9ZjJOhC+ACX+TfxpsWWyRc=
|
||||||
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
|
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
|
||||||
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
|
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
|
||||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=
|
modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw=
|
||||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
|
modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
|
||||||
modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk=
|
modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b h1:BnN1t+pb1cy61zbvSUV7SeI0PwosMhlAEi/vBY4qxp8=
|
||||||
modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY=
|
modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
|
||||||
|
modernc.org/libc v1.49.1 h1:r4UaWllkYXRPA7Mq/KzmassZBvNJiH9egF4O/KV/gdE=
|
||||||
|
modernc.org/libc v1.49.1/go.mod h1:Hx2rWfza47GSzCluTU7Vf0Qx3z9rWCVORL6RNgq+Xog=
|
||||||
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
||||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
||||||
modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
|
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
|
||||||
modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
|
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
|
||||||
|
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||||
|
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||||
|
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
|
||||||
|
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
|
||||||
modernc.org/sqlite v1.29.5 h1:8l/SQKAjDtZFo9lkJLdk8g9JEOeYRG4/ghStDCCTiTE=
|
modernc.org/sqlite v1.29.5 h1:8l/SQKAjDtZFo9lkJLdk8g9JEOeYRG4/ghStDCCTiTE=
|
||||||
modernc.org/sqlite v1.29.5/go.mod h1:S02dvcmm7TnTRvGhv8IGYyLnIt7AS2KPaB1F/71p75U=
|
modernc.org/sqlite v1.29.5/go.mod h1:S02dvcmm7TnTRvGhv8IGYyLnIt7AS2KPaB1F/71p75U=
|
||||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
||||||
|
|
|
@ -45,6 +45,8 @@ type Database interface {
|
||||||
UpdateWeeklyReport(projectName string, userName string, week int, developmentTime int, meetingTime int, adminTime int, ownWorkTime int, studyTime int, testingTime int) error
|
UpdateWeeklyReport(projectName string, userName string, week int, developmentTime int, meetingTime int, adminTime int, ownWorkTime int, studyTime int, testingTime int) error
|
||||||
RemoveProject(projectname string) error
|
RemoveProject(projectname string) error
|
||||||
GetUserName(id int) (string, error)
|
GetUserName(id int) (string, error)
|
||||||
|
UnsignWeeklyReport(reportId int, projectManagerId int) error
|
||||||
|
DeleteReport(reportID int) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// This struct is a wrapper type that holds the database connection
|
// This struct is a wrapper type that holds the database connection
|
||||||
|
@ -372,6 +374,36 @@ func (d *Db) SignWeeklyReport(reportId int, projectManagerId int) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Db) UnsignWeeklyReport(reportId int, projectManagerId int) error {
|
||||||
|
// Retrieve the project ID associated with the report
|
||||||
|
var reportProjectID int
|
||||||
|
err := d.Get(&reportProjectID, "SELECT project_id FROM weekly_reports WHERE report_id = ?", reportId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
managerQuery := `SELECT project_id FROM user_roles
|
||||||
|
WHERE user_id = ?
|
||||||
|
AND project_id = (SELECT project_id FROM weekly_reports WHERE report_id = ?)
|
||||||
|
AND p_role = 'project_manager'`
|
||||||
|
|
||||||
|
// Retrieve the project ID associated with the project manager
|
||||||
|
var managerProjectID int
|
||||||
|
err = d.Get(&managerProjectID, managerQuery, projectManagerId, reportId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the project manager is in the same project as the report
|
||||||
|
if reportProjectID != managerProjectID {
|
||||||
|
return errors.New("project manager doesn't have permission to unsign the report")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the signed_by field of the specified report
|
||||||
|
_, err = d.Exec("UPDATE weekly_reports SET signed_by = NULL WHERE report_id = ?;", reportId)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Db) GetUnsignedWeeklyReports(projectName string) ([]types.WeeklyReport, error) {
|
func (d *Db) GetUnsignedWeeklyReports(projectName string) ([]types.WeeklyReport, error) {
|
||||||
// Define the SQL query to fetch unsigned reports for a given user
|
// Define the SQL query to fetch unsigned reports for a given user
|
||||||
query := `
|
query := `
|
||||||
|
@ -623,3 +655,8 @@ func (d *Db) GetUserName(id int) (string, error) {
|
||||||
err := d.Get(&username, "SELECT username FROM users WHERE id = ?", id)
|
err := d.Get(&username, "SELECT username FROM users WHERE id = ?", id)
|
||||||
return username, err
|
return username, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Db) DeleteReport(reportID int) error {
|
||||||
|
_, err := d.Exec("DELETE FROM weekly_reports WHERE report_id = ?", reportID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
|
@ -583,6 +583,94 @@ func TestSignWeeklyReport(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnsignWeeklyReport(t *testing.T) {
|
||||||
|
db, err := setupState()
|
||||||
|
if err != nil {
|
||||||
|
t.Error("setupState failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add project manager
|
||||||
|
err = db.AddUser("projectManager", "password")
|
||||||
|
if err != nil {
|
||||||
|
t.Error("AddUser failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a regular user
|
||||||
|
err = db.AddUser("testuser", "password")
|
||||||
|
if err != nil {
|
||||||
|
t.Error("AddUser failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add project
|
||||||
|
err = db.AddProject("testproject", "description", "projectManager")
|
||||||
|
if err != nil {
|
||||||
|
t.Error("AddProject failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add both regular users as members to the project
|
||||||
|
err = db.AddUserToProject("testuser", "testproject", "member")
|
||||||
|
if err != nil {
|
||||||
|
t.Error("AddUserToProject failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.AddUserToProject("projectManager", "testproject", "project_manager")
|
||||||
|
if err != nil {
|
||||||
|
t.Error("AddUserToProject failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a weekly report for one of the regular users
|
||||||
|
err = db.AddWeeklyReport("testproject", "testuser", 1, 1, 1, 1, 1, 1, 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("AddWeeklyReport failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the added report
|
||||||
|
report, err := db.GetWeeklyReport("testuser", "testproject", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("GetWeeklyReport failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print project manager's ID
|
||||||
|
projectManagerID, err := db.GetUserId("projectManager")
|
||||||
|
if err != nil {
|
||||||
|
t.Error("GetUserId failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign the report with the project manager
|
||||||
|
err = db.SignWeeklyReport(report.ReportId, projectManagerID)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("SignWeeklyReport failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the report again to check if it's signed
|
||||||
|
signedReport, err := db.GetWeeklyReport("testuser", "testproject", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("GetWeeklyReport failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the report is signed by the project manager
|
||||||
|
if *signedReport.SignedBy != projectManagerID {
|
||||||
|
t.Errorf("Expected SignedBy to be %d, got %d", projectManagerID, *signedReport.SignedBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unsign the report
|
||||||
|
err = db.UnsignWeeklyReport(report.ReportId, projectManagerID)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("UnsignWeeklyReport failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the report again to check if it's unsigned
|
||||||
|
unsignedReport, err := db.GetWeeklyReport("testuser", "testproject", 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("GetWeeklyReport failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the report is unsigned
|
||||||
|
if unsignedReport.SignedBy != nil {
|
||||||
|
t.Error("Expected SignedBy to be nil, got", unsignedReport.SignedBy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestSignWeeklyReportByAnotherProjectManager tests the scenario where a project manager attempts to sign a weekly report for a user who is not assigned to their project
|
// TestSignWeeklyReportByAnotherProjectManager tests the scenario where a project manager attempts to sign a weekly report for a user who is not assigned to their project
|
||||||
func TestSignWeeklyReportByAnotherProjectManager(t *testing.T) {
|
func TestSignWeeklyReportByAnotherProjectManager(t *testing.T) {
|
||||||
db, err := setupState()
|
db, err := setupState()
|
||||||
|
@ -964,3 +1052,41 @@ func TestRemoveProject(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDeleteReport(t *testing.T) {
|
||||||
|
db, err := setupAdvancedState()
|
||||||
|
if err != nil {
|
||||||
|
t.Error("setupState failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Promote user to Admin
|
||||||
|
err = db.PromoteToAdmin("demouser")
|
||||||
|
if err != nil {
|
||||||
|
t.Error("PromoteToAdmin failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a weekly report
|
||||||
|
err = db.AddWeeklyReport("projecttest", "demouser", 16, 1, 1, 1, 1, 1, 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("AddWeeklyReport failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the report was added
|
||||||
|
report, err := db.GetWeeklyReport("demouser", "projecttest", 16)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("GetWeeklyReport failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove report
|
||||||
|
err = db.DeleteReport(report.ReportId,)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("RemoveReport failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the report was removed
|
||||||
|
report, err = db.GetWeeklyReport("demouser", "projecttest", 16)
|
||||||
|
if err == nil {
|
||||||
|
t.Error("RemoveReport failed: report not removed")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -44,6 +44,10 @@ func PromoteToPm(c *fiber.Ctx) error {
|
||||||
|
|
||||||
// Add the user to the project with the specified role
|
// Add the user to the project with the specified role
|
||||||
err = db.GetDb(c).ChangeUserRole(new_pm_name, project, "project_manager")
|
err = db.GetDb(c).ChangeUserRole(new_pm_name, project, "project_manager")
|
||||||
|
if err != nil {
|
||||||
|
log.Info("Error promoting user to project manager:", err)
|
||||||
|
return c.Status(500).SendString(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
// Return success message
|
// Return success message
|
||||||
log.Info("User : ", new_pm_name, " promoted to project manager in project: ", project)
|
log.Info("User : ", new_pm_name, " promoted to project manager in project: ", project)
|
||||||
|
|
22
backend/internal/handlers/reports/DeleteReport.go
Normal file
22
backend/internal/handlers/reports/DeleteReport.go
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package reports
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
db "ttime/internal/database"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DeleteReport(c *fiber.Ctx) error {
|
||||||
|
reportID := c.Params("reportID")
|
||||||
|
reportIDInt, err := strconv.Atoi(reportID)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(400).SendString("Invalid report ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := db.GetDb(c).DeleteReport(reportIDInt); err != nil {
|
||||||
|
return c.Status(500).SendString((err.Error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(200).SendString("Weekly report deleted")
|
||||||
|
}
|
|
@ -38,7 +38,7 @@ func GetAllWeeklyReports(c *fiber.Ctx) error {
|
||||||
return c.Status(500).SendString(err.Error())
|
return c.Status(500).SendString(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if pm == false && target_user != username {
|
if !(pm || target_user == username) {
|
||||||
log.Info("Unauthorized access")
|
log.Info("Unauthorized access")
|
||||||
return c.Status(403).SendString("Unauthorized access")
|
return c.Status(403).SendString("Unauthorized access")
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ func GetWeeklyReport(c *fiber.Ctx) error {
|
||||||
return c.Status(500).SendString(err.Error())
|
return c.Status(500).SendString(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if pm == false && target_user != username {
|
if !(pm || target_user == username) {
|
||||||
log.Info("Unauthorized access")
|
log.Info("Unauthorized access")
|
||||||
return c.Status(403).SendString("Unauthorized access")
|
return c.Status(403).SendString("Unauthorized access")
|
||||||
}
|
}
|
||||||
|
|
41
backend/internal/handlers/reports/UnsignReport.go
Normal file
41
backend/internal/handlers/reports/UnsignReport.go
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
package reports
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
db "ttime/internal/database"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/gofiber/fiber/v2/log"
|
||||||
|
"github.com/golang-jwt/jwt/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UnsignReport(c *fiber.Ctx) error {
|
||||||
|
// Extract the necessary parameters from the token
|
||||||
|
user := c.Locals("user").(*jwt.Token)
|
||||||
|
claims := user.Claims.(jwt.MapClaims)
|
||||||
|
projectManagerUsername := claims["name"].(string)
|
||||||
|
|
||||||
|
// Extract report ID from the path
|
||||||
|
reportId, err := strconv.Atoi(c.Params("reportId"))
|
||||||
|
if err != nil {
|
||||||
|
log.Info("Invalid report ID")
|
||||||
|
return c.Status(400).SendString("Invalid report ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the project manager's ID
|
||||||
|
projectManagerID, err := db.GetDb(c).GetUserId(projectManagerUsername)
|
||||||
|
if err != nil {
|
||||||
|
log.Info("Failed to get project manager ID for user: ", projectManagerUsername)
|
||||||
|
return c.Status(500).SendString("Failed to get project manager ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the database function to sign the weekly report
|
||||||
|
err = db.GetDb(c).UnsignWeeklyReport(reportId, projectManagerID)
|
||||||
|
if err != nil {
|
||||||
|
log.Info("Error Unsigning weekly report:", err)
|
||||||
|
return c.Status(500).SendString(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Project manager ID: ", projectManagerID, " unsigned report ID: ", reportId)
|
||||||
|
return c.Status(200).SendString("Weekly report unsigned successfully")
|
||||||
|
}
|
|
@ -126,6 +126,7 @@ func main() {
|
||||||
api.Delete("/removeProject/:projectName", projects.RemoveProject)
|
api.Delete("/removeProject/:projectName", projects.RemoveProject)
|
||||||
api.Delete("/project/:projectID", projects.DeleteProject)
|
api.Delete("/project/:projectID", projects.DeleteProject)
|
||||||
|
|
||||||
|
|
||||||
// All report related routes
|
// All report related routes
|
||||||
// reportGroup := api.Group("/report") // Not currently in use
|
// reportGroup := api.Group("/report") // Not currently in use
|
||||||
api.Get("/getWeeklyReport", reports.GetWeeklyReport)
|
api.Get("/getWeeklyReport", reports.GetWeeklyReport)
|
||||||
|
@ -134,6 +135,8 @@ func main() {
|
||||||
api.Post("/submitWeeklyReport", reports.SubmitWeeklyReport)
|
api.Post("/submitWeeklyReport", reports.SubmitWeeklyReport)
|
||||||
api.Put("/signReport/:reportId", reports.SignReport)
|
api.Put("/signReport/:reportId", reports.SignReport)
|
||||||
api.Put("/updateWeeklyReport", reports.UpdateWeeklyReport)
|
api.Put("/updateWeeklyReport", reports.UpdateWeeklyReport)
|
||||||
|
api.Put("/unsignReport/:reportId", reports.UnsignReport)
|
||||||
|
api.Delete("/deleteReport/:reportId", reports.DeleteReport)
|
||||||
|
|
||||||
// Announce the port we are listening on and start the server
|
// Announce the port we are listening on and start the server
|
||||||
err = server.Listen(fmt.Sprintf(":%d", conf.Port))
|
err = server.Listen(fmt.Sprintf(":%d", conf.Port))
|
||||||
|
|
1792
frontend/package-lock.json
generated
1792
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -221,6 +221,15 @@ interface API {
|
||||||
*/
|
*/
|
||||||
signReport(reportId: number, token: string): Promise<APIResponse<string>>;
|
signReport(reportId: number, token: string): Promise<APIResponse<string>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsigns a report. Keep in mind that the user which the token belongs to must be
|
||||||
|
* the project manager of the project the report belongs to.
|
||||||
|
*
|
||||||
|
* @param {number} reportId The id of the report to sign
|
||||||
|
* @param {string} token The authentication token
|
||||||
|
*/
|
||||||
|
unsignReport(reportId: number, token: string): Promise<APIResponse<string>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Promotes a user to project manager within a project.
|
* Promotes a user to project manager within a project.
|
||||||
*
|
*
|
||||||
|
@ -239,6 +248,16 @@ interface API {
|
||||||
* @param {string} token Your token
|
* @param {string} token Your token
|
||||||
*/
|
*/
|
||||||
getUsername(id: number, token: string): Promise<APIResponse<string>>;
|
getUsername(id: number, token: string): Promise<APIResponse<string>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a WeeklyReport from the database
|
||||||
|
* @param {number} reportId The id of the report to delete
|
||||||
|
* @param {string} token The authentication token
|
||||||
|
*/
|
||||||
|
deleteWeeklyReport(
|
||||||
|
reportId: number,
|
||||||
|
token: string,
|
||||||
|
): Promise<APIResponse<string>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An instance of the API */
|
/** An instance of the API */
|
||||||
|
@ -846,6 +865,29 @@ export const api: API = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async unsignReport(
|
||||||
|
reportId: number,
|
||||||
|
token: string,
|
||||||
|
): Promise<APIResponse<string>> {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/api/unsignReport/${reportId}`, {
|
||||||
|
method: "PUT",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: "Bearer " + token,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
return { success: false, message: "Failed to unsign report" };
|
||||||
|
} else {
|
||||||
|
return { success: true, message: "Report unsigned" };
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
return { success: false, message: "Failed to unsign report" };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
async promoteToPm(
|
async promoteToPm(
|
||||||
userName: string,
|
userName: string,
|
||||||
projectName: string,
|
projectName: string,
|
||||||
|
@ -897,4 +939,27 @@ export const api: API = {
|
||||||
return { success: false, message: "Failed to get username" };
|
return { success: false, message: "Failed to get username" };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async deleteWeeklyReport(
|
||||||
|
reportId: number,
|
||||||
|
token: string,
|
||||||
|
): Promise<APIResponse<string>> {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/api/deleteReport/${reportId}`, {
|
||||||
|
method: "DELETE",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: "Bearer " + token,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
return { success: false, message: "Failed to delete report" };
|
||||||
|
} else {
|
||||||
|
return { success: true, message: "Report deleted" };
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
return { success: false, message: "Failed to delete report" };
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,7 +37,7 @@ function AllTimeReportsInProject(): JSX.Element {
|
||||||
<div className="border-4 border-black bg-white flex flex-col items-center justify-center min-h-[65vh] h-fit w-[50vw] rounded-3xl content-center overflow-scroll space-y-[10vh] p-[30px] text-[30px]">
|
<div className="border-4 border-black bg-white flex flex-col items-center justify-center min-h-[65vh] h-fit w-[50vw] rounded-3xl content-center overflow-scroll space-y-[10vh] p-[30px] text-[30px]">
|
||||||
{weeklyReports.map((newWeeklyReport, index) => (
|
{weeklyReports.map((newWeeklyReport, index) => (
|
||||||
<Link
|
<Link
|
||||||
to={`/editTimeReport/${projectName}/${newWeeklyReport.week}`}
|
to={`/editTimeReport/${projectName}/${newWeeklyReport.week}/${newWeeklyReport.signedBy ? "signed" : "unsigned"}`}
|
||||||
key={index}
|
key={index}
|
||||||
className="border-b-2 border-black w-full"
|
className="border-b-2 border-black w-full"
|
||||||
>
|
>
|
||||||
|
|
|
@ -39,7 +39,7 @@ function AllTimeReportsInProject(): JSX.Element {
|
||||||
<div className="border-4 border-black bg-white flex flex-col items-center justify-center min-h-[65vh] h-fit w-[50vw] rounded-3xl content-center overflow-scroll space-y-[10vh] p-[30px] text-[30px]">
|
<div className="border-4 border-black bg-white flex flex-col items-center justify-center min-h-[65vh] h-fit w-[50vw] rounded-3xl content-center overflow-scroll space-y-[10vh] p-[30px] text-[30px]">
|
||||||
{weeklyReports.map((newWeeklyReport, index) => (
|
{weeklyReports.map((newWeeklyReport, index) => (
|
||||||
<Link
|
<Link
|
||||||
to={`/editOthersTR/${projectName}/${username}/${newWeeklyReport.week}`}
|
to={`/editOthersTR/${projectName}/${username}/${newWeeklyReport.week}/${newWeeklyReport.signedBy ? "signed" : "unsigned"}`}
|
||||||
key={index}
|
key={index}
|
||||||
className="border-b-2 border-black w-full"
|
className="border-b-2 border-black w-full"
|
||||||
>
|
>
|
||||||
|
@ -60,7 +60,7 @@ function AllTimeReportsInProject(): JSX.Element {
|
||||||
</h1>
|
</h1>
|
||||||
<h1>
|
<h1>
|
||||||
<span className="font-bold">{"Signed: "}</span>
|
<span className="font-bold">{"Signed: "}</span>
|
||||||
NO
|
{newWeeklyReport.signedBy ? "YES" : "NO"}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
|
@ -18,12 +18,13 @@ export default function GetWeeklyReport(): JSX.Element {
|
||||||
const [testingTime, setTestingTime] = useState(0);
|
const [testingTime, setTestingTime] = useState(0);
|
||||||
|
|
||||||
const token = localStorage.getItem("accessToken") ?? "";
|
const token = localStorage.getItem("accessToken") ?? "";
|
||||||
const { projectName, fetchedWeek } = useParams<{
|
const { projectName, fetchedWeek, signedOrUnsigned } = useParams<{
|
||||||
projectName: string;
|
projectName: string;
|
||||||
fetchedWeek: string;
|
fetchedWeek: string;
|
||||||
|
signedOrUnsigned: string;
|
||||||
}>();
|
}>();
|
||||||
const username = localStorage.getItem("userName") ?? "";
|
const username = localStorage.getItem("userName") ?? "";
|
||||||
console.log(projectName, fetchedWeek);
|
console.log(projectName, fetchedWeek, signedOrUnsigned);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchWeeklyReport = async (): Promise<void> => {
|
const fetchWeeklyReport = async (): Promise<void> => {
|
||||||
|
@ -59,7 +60,7 @@ export default function GetWeeklyReport(): JSX.Element {
|
||||||
};
|
};
|
||||||
|
|
||||||
void fetchWeeklyReport();
|
void fetchWeeklyReport();
|
||||||
}, [projectName, fetchedWeek, token]);
|
}, [projectName, fetchedWeek, signedOrUnsigned, token]);
|
||||||
|
|
||||||
const handleUpdateWeeklyReport = async (): Promise<void> => {
|
const handleUpdateWeeklyReport = async (): Promise<void> => {
|
||||||
const updateWeeklyReport: UpdateWeeklyReport = {
|
const updateWeeklyReport: UpdateWeeklyReport = {
|
||||||
|
@ -139,6 +140,12 @@ export default function GetWeeklyReport(): JSX.Element {
|
||||||
)
|
)
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}}
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
if (signedOrUnsigned === "signed") {
|
||||||
|
alert("You cannot edit a signed report.");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
readOnly={signedOrUnsigned === "signed"}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -168,6 +175,12 @@ export default function GetWeeklyReport(): JSX.Element {
|
||||||
)
|
)
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}}
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
if (signedOrUnsigned === "signed") {
|
||||||
|
alert("You cannot edit a signed report.");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
readOnly={signedOrUnsigned === "signed"}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -197,6 +210,12 @@ export default function GetWeeklyReport(): JSX.Element {
|
||||||
)
|
)
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}}
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
if (signedOrUnsigned === "signed") {
|
||||||
|
alert("You cannot edit a signed report.");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
readOnly={signedOrUnsigned === "signed"}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -226,6 +245,12 @@ export default function GetWeeklyReport(): JSX.Element {
|
||||||
)
|
)
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}}
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
if (signedOrUnsigned === "signed") {
|
||||||
|
alert("You cannot edit a signed report.");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
readOnly={signedOrUnsigned === "signed"}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -255,6 +280,12 @@ export default function GetWeeklyReport(): JSX.Element {
|
||||||
)
|
)
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}}
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
if (signedOrUnsigned === "signed") {
|
||||||
|
alert("You cannot edit a signed report.");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
readOnly={signedOrUnsigned === "signed"}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -284,18 +315,26 @@ export default function GetWeeklyReport(): JSX.Element {
|
||||||
)
|
)
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}}
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
if (signedOrUnsigned === "signed") {
|
||||||
|
alert("You cannot edit a signed report.");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
readOnly={signedOrUnsigned === "signed"}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<Button
|
{signedOrUnsigned !== "signed" && (
|
||||||
text="Submit changes"
|
<Button
|
||||||
onClick={(): void => {
|
text="Submit changes"
|
||||||
return;
|
onClick={(): void => {
|
||||||
}}
|
return;
|
||||||
type="submit"
|
}}
|
||||||
/>
|
type="submit"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { WeeklyReport } from "../Types/goTypes";
|
import { WeeklyReport } from "../Types/goTypes";
|
||||||
import { api } from "../API/API";
|
import { api } from "../API/API";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams, useNavigate } from "react-router-dom";
|
||||||
|
import Button from "./Button";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the component for editing a weekly report.
|
* Renders the component for editing a weekly report.
|
||||||
|
@ -17,11 +18,14 @@ export default function OtherUsersTR(): JSX.Element {
|
||||||
const [ownWorkTime, setOwnWorkTime] = useState(0);
|
const [ownWorkTime, setOwnWorkTime] = useState(0);
|
||||||
const [studyTime, setStudyTime] = useState(0);
|
const [studyTime, setStudyTime] = useState(0);
|
||||||
const [testingTime, setTestingTime] = useState(0);
|
const [testingTime, setTestingTime] = useState(0);
|
||||||
|
const [reportId, setReportId] = useState(0);
|
||||||
|
|
||||||
const token = localStorage.getItem("accessToken") ?? "";
|
const token = localStorage.getItem("accessToken") ?? "";
|
||||||
const { projectName } = useParams();
|
const { projectName } = useParams();
|
||||||
const { username } = useParams();
|
const { username } = useParams();
|
||||||
const { fetchedWeek } = useParams();
|
const { fetchedWeek } = useParams();
|
||||||
|
const { signedOrUnsigned } = useParams();
|
||||||
|
console.log(projectName, username, fetchedWeek, signedOrUnsigned);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchUsersWeeklyReport = async (): Promise<void> => {
|
const fetchUsersWeeklyReport = async (): Promise<void> => {
|
||||||
|
@ -45,6 +49,7 @@ export default function OtherUsersTR(): JSX.Element {
|
||||||
studyTime: 0,
|
studyTime: 0,
|
||||||
testingTime: 0,
|
testingTime: 0,
|
||||||
};
|
};
|
||||||
|
setReportId(report.reportId);
|
||||||
setWeek(report.week);
|
setWeek(report.week);
|
||||||
setDevelopmentTime(report.developmentTime);
|
setDevelopmentTime(report.developmentTime);
|
||||||
setMeetingTime(report.meetingTime);
|
setMeetingTime(report.meetingTime);
|
||||||
|
@ -60,6 +65,27 @@ export default function OtherUsersTR(): JSX.Element {
|
||||||
void fetchUsersWeeklyReport();
|
void fetchUsersWeeklyReport();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handleUnsignWeeklyReport = async (): Promise<boolean> => {
|
||||||
|
const response = await api.unsignReport(reportId, token);
|
||||||
|
console.log(response);
|
||||||
|
console.log(reportId);
|
||||||
|
if (response.success) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDeleteWeeklyReport = async (): Promise<boolean> => {
|
||||||
|
const response = await api.deleteWeeklyReport(reportId, token);
|
||||||
|
console.log(response);
|
||||||
|
if (response.success) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1 className="text-[30px] font-bold">{username}'s Report</h1>
|
<h1 className="text-[30px] font-bold">{username}'s Report</h1>
|
||||||
|
@ -153,6 +179,48 @@ export default function OtherUsersTR(): JSX.Element {
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<div className="flex space-x-4">
|
||||||
|
{signedOrUnsigned === "signed" && (
|
||||||
|
<Button
|
||||||
|
text="Unsign Report"
|
||||||
|
onClick={(): void => {
|
||||||
|
void (async (): Promise<void> => {
|
||||||
|
const success = await handleUnsignWeeklyReport();
|
||||||
|
if (success) {
|
||||||
|
alert("Report successfully unsigned!");
|
||||||
|
navigate(-1);
|
||||||
|
} else {
|
||||||
|
alert("Failed to unsign report");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}}
|
||||||
|
type={"button"}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<Button
|
||||||
|
text="Delete Time Report"
|
||||||
|
onClick={(): void => {
|
||||||
|
void (async (): Promise<void> => {
|
||||||
|
const confirmDelete = window.confirm(
|
||||||
|
"Are you sure you want to delete this report? This action cannot be undone.",
|
||||||
|
);
|
||||||
|
if (!confirmDelete) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const success = await handleDeleteWeeklyReport();
|
||||||
|
if (success) {
|
||||||
|
alert("Report successfully deleted!");
|
||||||
|
navigate(-1);
|
||||||
|
} else {
|
||||||
|
alert("Failed to delete report");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}}
|
||||||
|
type={"button"}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Link, useParams } from "react-router-dom";
|
import { Link, useParams } from "react-router-dom";
|
||||||
import GetUsersInProject, { ProjectMember } from "./GetUsersInProject";
|
import GetUsersInProject, { ProjectMember } from "./GetUsersInProject";
|
||||||
|
import { api } from "../API/API";
|
||||||
|
|
||||||
function ProjectMembers(): JSX.Element {
|
function ProjectMembers(): JSX.Element {
|
||||||
const { projectName } = useParams();
|
const { projectName } = useParams();
|
||||||
|
@ -11,34 +12,68 @@ function ProjectMembers(): JSX.Element {
|
||||||
setUsersProp: setProjectMembers,
|
setUsersProp: setProjectMembers,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handleUserDeleteClick = async (username: string): Promise<void> => {
|
||||||
|
const token = localStorage.getItem("accessToken") ?? "";
|
||||||
|
const response = await api.removeUserFromProject(
|
||||||
|
username,
|
||||||
|
projectName ?? "",
|
||||||
|
token,
|
||||||
|
);
|
||||||
|
console.log(response.data);
|
||||||
|
|
||||||
|
// Remove the deleted user from the state
|
||||||
|
setProjectMembers((prevMembers) =>
|
||||||
|
prevMembers.filter((member) => member.Username !== username),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1 className="font-bold text-[30px] mb-[20px]">
|
<h1 className="font-bold text-[30px] mb-[20px]">
|
||||||
All Members In: {projectName}{" "}
|
All Members In: {projectName}{" "}
|
||||||
</h1>
|
</h1>
|
||||||
<div className="border-4 border-black bg-white flex flex-col items-center justify-center min-h-[65vh] h-fit w-[70vw] rounded-3xl content-center overflow-scroll space-y-[10vh] p-[30px] text-[20px]">
|
<div className="border-4 border-black bg-white flex flex-col items-center justify-center min-h-[65vh] h-fit w-[70vw] rounded-3xl content-center overflow-scroll space-y-[10vh] p-[30px] text-[20px]">
|
||||||
{projectMembers.map((projectMember: ProjectMember, index: number) => (
|
{projectMembers.map((projectMember: ProjectMember, index: number) => {
|
||||||
<h1 key={index} className="border-b-2 border-black w-full">
|
if (projectMember.Username === "admin") {
|
||||||
<div className="flex justify-between">
|
return null; // Skip rendering for admin user
|
||||||
<div className="flex">
|
}
|
||||||
<h1>{projectMember.Username}</h1>
|
return (
|
||||||
<span className="ml-6 mr-2 font-bold">Role:</span>
|
<h1 key={index} className="border-b-2 border-black w-full">
|
||||||
<h1>{projectMember.UserRole}</h1>
|
<div className="flex justify-between">
|
||||||
</div>
|
<div className="flex">
|
||||||
<div className="flex">
|
<h1>{projectMember.Username}</h1>
|
||||||
<div className="ml-auto flex space-x-4">
|
<span className="ml-6 mr-2 font-bold">Role:</span>
|
||||||
<Link
|
<h1>{projectMember.UserRole}</h1>
|
||||||
to={`/otherUsersTimeReports/${projectName}/${projectMember.Username}`}
|
</div>
|
||||||
>
|
<div className="flex">
|
||||||
<h1 className="underline cursor-pointer font-bold">
|
<div className="ml-auto flex space-x-4">
|
||||||
View Reports
|
{projectMember.Username !==
|
||||||
</h1>
|
localStorage.getItem("username") && (
|
||||||
</Link>
|
<h1
|
||||||
|
className="underline cursor-pointer font-bold"
|
||||||
|
onClick={() => {
|
||||||
|
confirm(
|
||||||
|
"Are you sure you want to delete this user? This action cannot be undone.",
|
||||||
|
) &&
|
||||||
|
void handleUserDeleteClick(projectMember.Username);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Delete User
|
||||||
|
</h1>
|
||||||
|
)}
|
||||||
|
<Link
|
||||||
|
to={`/otherUsersTimeReports/${projectName}/${projectMember.Username}`}
|
||||||
|
>
|
||||||
|
<h1 className="underline cursor-pointer font-bold">
|
||||||
|
View Reports
|
||||||
|
</h1>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</h1>
|
||||||
</h1>
|
);
|
||||||
))}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -55,7 +55,7 @@ const router = createBrowserRouter([
|
||||||
element: <UserViewTimeReportsPage />,
|
element: <UserViewTimeReportsPage />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/editTimeReport/:projectName/:fetchedWeek",
|
path: "/editTimeReport/:projectName/:fetchedWeek/:signedOrUnsigned",
|
||||||
element: <UserEditTimeReportPage />,
|
element: <UserEditTimeReportPage />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -67,7 +67,7 @@ const router = createBrowserRouter([
|
||||||
element: <PMOtherUsersTR />,
|
element: <PMOtherUsersTR />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/editOthersTR/:projectName/:username/:fetchedWeek",
|
path: "/editOthersTR/:projectName/:username/:fetchedWeek/:signedOrUnsigned",
|
||||||
element: <PMViewOtherUsersTR />,
|
element: <PMViewOtherUsersTR />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,8 +34,10 @@ getChangeUserNamePath = base_url + "/api/changeUserName"
|
||||||
getUpdateWeeklyReportPath = base_url + "/api/updateWeeklyReport"
|
getUpdateWeeklyReportPath = base_url + "/api/updateWeeklyReport"
|
||||||
removeProjectPath = base_url + "/api/removeProject"
|
removeProjectPath = base_url + "/api/removeProject"
|
||||||
promoteToPmPath = base_url + "/api/promoteToPm"
|
promoteToPmPath = base_url + "/api/promoteToPm"
|
||||||
|
unsignReportPath = base_url + "/api/unsignReport"
|
||||||
|
deleteReportPath = base_url + "/api/deleteReport"
|
||||||
|
|
||||||
debug_output = True
|
debug_output = False
|
||||||
|
|
||||||
|
|
||||||
def gprint(*args, **kwargs):
|
def gprint(*args, **kwargs):
|
||||||
|
@ -149,3 +151,14 @@ def signReport(project_manager_token: string, report_id: int):
|
||||||
signReportPath + "/" + str(report_id),
|
signReportPath + "/" + str(report_id),
|
||||||
headers={"Authorization": "Bearer " + project_manager_token},
|
headers={"Authorization": "Bearer " + project_manager_token},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def unsignReport(project_manager_token: string, report_id: int):
|
||||||
|
return requests.put(
|
||||||
|
unsignReportPath + "/" + str(report_id),
|
||||||
|
headers={"Authorization": "Bearer " + project_manager_token},
|
||||||
|
)
|
||||||
|
|
||||||
|
def deleteReport(report_id: int):
|
||||||
|
return requests.delete(
|
||||||
|
deleteReportPath + "/" + str(report_id),
|
||||||
|
)
|
||||||
|
|
|
@ -215,6 +215,72 @@ def test_sign_report():
|
||||||
assert report_id != None, "Get report failed"
|
assert report_id != None, "Get report failed"
|
||||||
gprint("test_sign_report successful")
|
gprint("test_sign_report successful")
|
||||||
|
|
||||||
|
# Test function to unsign a report
|
||||||
|
def test_unsign_report():
|
||||||
|
# Pm user
|
||||||
|
pm_username = "pm" + randomString()
|
||||||
|
pm_password = "admin_password2"
|
||||||
|
|
||||||
|
# User to add
|
||||||
|
member_user = "member" + randomString()
|
||||||
|
member_passwd = "password"
|
||||||
|
|
||||||
|
# Name of the project to be created
|
||||||
|
project_name = "project" + randomString()
|
||||||
|
|
||||||
|
# Register and get the tokens for both users
|
||||||
|
pm_token = register_and_login(pm_username, pm_password)
|
||||||
|
member_token = register_and_login(member_user, member_passwd)
|
||||||
|
|
||||||
|
# Create the project
|
||||||
|
response = create_project(pm_token, project_name)
|
||||||
|
assert response.status_code == 200, "Create project failed"
|
||||||
|
|
||||||
|
# Add the user to the project
|
||||||
|
response = addToProject(pm_token, member_user, project_name)
|
||||||
|
|
||||||
|
# Submit a report for the project
|
||||||
|
response = submitReport(
|
||||||
|
member_token,
|
||||||
|
{
|
||||||
|
"projectName": project_name,
|
||||||
|
"week": 1,
|
||||||
|
"developmentTime": 10,
|
||||||
|
"meetingTime": 5,
|
||||||
|
"adminTime": 5,
|
||||||
|
"ownWorkTime": 10,
|
||||||
|
"studyTime": 10,
|
||||||
|
"testingTime": 10,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response.status_code == 200, "Submit report failed"
|
||||||
|
|
||||||
|
# Retrieve the report ID
|
||||||
|
report_id = getReport(member_token, member_user, project_name)["reportId"]
|
||||||
|
|
||||||
|
# Sign the report as the project manager
|
||||||
|
response = signReport(pm_token, report_id)
|
||||||
|
assert response.status_code == 200, "Sign report failed"
|
||||||
|
dprint("Sign report successful")
|
||||||
|
|
||||||
|
# Retrieve the report ID again for confirmation
|
||||||
|
report = getReport(member_token, member_user, project_name)
|
||||||
|
dprint(report)
|
||||||
|
report_id = report["reportId"]
|
||||||
|
assert report_id != None, "Get report failed"
|
||||||
|
|
||||||
|
# Unsign the report as the project manager
|
||||||
|
response = unsignReport(pm_token, report_id)
|
||||||
|
assert response.status_code == 200, "Unsign report failed"
|
||||||
|
dprint("Unsign report successful")
|
||||||
|
|
||||||
|
# Retrieve the report ID again for confirmation
|
||||||
|
report = getReport(member_token, member_user, project_name)
|
||||||
|
assert report_id != None, "Get report failed"
|
||||||
|
dprint(report)
|
||||||
|
assert report["signedBy"] == None, "Report was not unsigned"
|
||||||
|
gprint("test_unsign_report successful")
|
||||||
|
|
||||||
|
|
||||||
# Test function to get weekly reports for a user in a project
|
# Test function to get weekly reports for a user in a project
|
||||||
def test_get_all_weekly_reports():
|
def test_get_all_weekly_reports():
|
||||||
|
@ -495,8 +561,75 @@ def test_promote_to_manager():
|
||||||
response = promoteToManager(pm_token, member_user, project_name)
|
response = promoteToManager(pm_token, member_user, project_name)
|
||||||
assert response.status_code == 200, "Promote to manager failed"
|
assert response.status_code == 200, "Promote to manager failed"
|
||||||
|
|
||||||
|
def test_delete_report():
|
||||||
|
# Create admin
|
||||||
|
admin_username = randomString()
|
||||||
|
admin_password = "admin_password2"
|
||||||
|
dprint(
|
||||||
|
"Registering with username: ", admin_username, " and password: ", admin_password
|
||||||
|
)
|
||||||
|
response = requests.post(
|
||||||
|
registerPath, json={"username": admin_username, "password": admin_password}
|
||||||
|
)
|
||||||
|
dprint(response.text)
|
||||||
|
|
||||||
|
# Log in as the admin
|
||||||
|
admin_token = login(admin_username, admin_password).json()["token"]
|
||||||
|
response = requests.post(
|
||||||
|
promoteToAdminPath,
|
||||||
|
json={"username": admin_username},
|
||||||
|
headers={"Authorization": "Bearer " + admin_token},
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create a new project
|
||||||
|
new_project = randomString()
|
||||||
|
response = requests.post(
|
||||||
|
addProjectPath,
|
||||||
|
json={"name": new_project, "description": "This is a project"},
|
||||||
|
headers={"Authorization": "Bearer " + admin_token},
|
||||||
|
)
|
||||||
|
assert response.status_code == 200, "Add project failed"
|
||||||
|
|
||||||
|
# Create a new report
|
||||||
|
new_report = {
|
||||||
|
"projectName": new_project,
|
||||||
|
"week": 1,
|
||||||
|
"developmentTime": 10,
|
||||||
|
"meetingTime": 5,
|
||||||
|
"adminTime": 5,
|
||||||
|
"ownWorkTime": 10,
|
||||||
|
"studyTime": 10,
|
||||||
|
"testingTime": 10,
|
||||||
|
}
|
||||||
|
response = submitReport(admin_token, new_report);
|
||||||
|
assert response.status_code == 200, "Submit report failed"
|
||||||
|
|
||||||
|
# Get the report ID
|
||||||
|
report_id = getReport(admin_token, admin_username, new_project)["reportId"]
|
||||||
|
assert report_id != None, "Get report failed"
|
||||||
|
|
||||||
|
# Delete the report
|
||||||
|
response = requests.delete(
|
||||||
|
deleteReportPath + "/" + str(report_id),
|
||||||
|
headers={"Authorization": "Bearer " + admin_token},
|
||||||
|
)
|
||||||
|
assert response.status_code == 200, "Delete report failed"
|
||||||
|
|
||||||
|
# Check if the report was deleted
|
||||||
|
response = requests.get(
|
||||||
|
getWeeklyReportPath,
|
||||||
|
headers={"Authorization": "Bearer " + admin_token},
|
||||||
|
params={"username": admin_username, "projectName": new_project, "week": 1},
|
||||||
|
)
|
||||||
|
assert response.status_code == 500, "Report was not deleted"
|
||||||
|
|
||||||
|
gprint("test_delete_report successful")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
test_delete_report()
|
||||||
|
test_unsign_report()
|
||||||
test_promote_to_manager()
|
test_promote_to_manager()
|
||||||
test_remove_project()
|
test_remove_project()
|
||||||
test_get_user_projects()
|
test_get_user_projects()
|
||||||
|
|
Loading…
Reference in a new issue