feature: ajouter et tester GetMembre[s]ForDisplay
Priorisent le prefered_name ("nom d'usage") et devraient être utilisés aux endroits où l'affichage est important.
This commit is contained in:
parent
e6103c6e6e
commit
e4ff1013d0
7 changed files with 315 additions and 0 deletions
35
client.go
35
client.go
|
@ -133,3 +133,38 @@ func (c APIClient) UpdateMembrePreferedName(membreID string, name string) (err e
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c APIClient) GetMembreForDisplay(membreID string) (membre MembreForDisplay, err error) {
|
||||||
|
var request MembreDisplayGETRequest
|
||||||
|
request.Param.MembreID = membreID
|
||||||
|
|
||||||
|
response, err := request.Request(c.Voki)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if code, message := response.StatusCode(), response.Message; code >= 400 {
|
||||||
|
err = fmt.Errorf("%d: %s", code, message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.Data.Membre, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c APIClient) GetMembresForDisplay(limit int) (membres []MembreForDisplay, err error) {
|
||||||
|
var request MembresDisplayGETRequest
|
||||||
|
|
||||||
|
request.Query.Limit = limit
|
||||||
|
|
||||||
|
response, err := request.Request(c.Voki)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if code, message := response.StatusCode(), response.Message; code >= 400 {
|
||||||
|
err = fmt.Errorf("%d: %s", code, message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.Data.Membres, nil
|
||||||
|
}
|
||||||
|
|
|
@ -122,4 +122,22 @@ func TestAPI(t *testing.T) {
|
||||||
}
|
}
|
||||||
t.Log(membres)
|
t.Log(membres)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("get membre for display",
|
||||||
|
func(t *testing.T) {
|
||||||
|
membre, err := apiClient.GetMembreForDisplay(testMembres[0].ID)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
t.Log(membre)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("get membres for display, max 5",
|
||||||
|
func(t *testing.T) {
|
||||||
|
membres, err := apiClient.GetMembresForDisplay(5)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
t.Log(membres)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
80
db.go
80
db.go
|
@ -272,3 +272,83 @@ WHERE
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *PostgresClient) GetMembreForDisplay(membreID string) (membre MembreForDisplay, err error) {
|
||||||
|
select {
|
||||||
|
case <-d.Ctx.Done():
|
||||||
|
err = fmt.Errorf("PostgresClient.Ctx closed: %s", d.Ctx.Err())
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
if err = d.Pool.QueryRow(d.Ctx, `
|
||||||
|
SELECT
|
||||||
|
"membres_for_display".id,
|
||||||
|
"membres_for_display".name,
|
||||||
|
"membres_for_display".programme_id,
|
||||||
|
"membres_for_display".programme_name
|
||||||
|
FROM
|
||||||
|
"membres_for_display"
|
||||||
|
WHERE
|
||||||
|
"membres_for_display".id = $1
|
||||||
|
LIMIT
|
||||||
|
1;
|
||||||
|
`, membreID).Scan(
|
||||||
|
&membre.ID,
|
||||||
|
&membre.Name,
|
||||||
|
&membre.ProgrammeID,
|
||||||
|
&membre.ProgrammeName,
|
||||||
|
); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if membre.ID == "" {
|
||||||
|
return membre, fmt.Errorf("Aucun membre trouvé avec numéro '%s'", membre.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return membre, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *PostgresClient) GetMembresForDisplay(limit int) (membres []MembreForDisplay, err error) {
|
||||||
|
select {
|
||||||
|
case <-d.Ctx.Done():
|
||||||
|
return nil, fmt.Errorf("PostgresClient.Ctx closed: %s", d.Ctx.Err())
|
||||||
|
default:
|
||||||
|
rows, err := d.Pool.Query(d.Ctx, `
|
||||||
|
SELECT
|
||||||
|
"membres_for_display".id,
|
||||||
|
"membres_for_display".name,
|
||||||
|
"membres_for_display".programme_id,
|
||||||
|
"membres_for_display".programme_name
|
||||||
|
FROM
|
||||||
|
"membres_for_display"
|
||||||
|
ORDER BY
|
||||||
|
"membres_for_display".id
|
||||||
|
LIMIT
|
||||||
|
$1;
|
||||||
|
`, limit)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var membre MembreForDisplay
|
||||||
|
|
||||||
|
if err = rows.Scan(
|
||||||
|
&membre.ID,
|
||||||
|
&membre.Name,
|
||||||
|
&membre.ProgrammeID,
|
||||||
|
&membre.ProgrammeName,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
membres = append(membres, membre)
|
||||||
|
}
|
||||||
|
if rows.Err() != nil {
|
||||||
|
return membres, rows.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
return membres, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,14 @@ type Membre struct {
|
||||||
ProgrammeID string `db:"programme_id" json:"programme_id" csv:"programme_id"`
|
ProgrammeID string `db:"programme_id" json:"programme_id" csv:"programme_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MembreForDisplay maps to the `membres_for_display` view declared in `sql/views.sql`
|
||||||
|
type MembreForDisplay struct {
|
||||||
|
ID string `db:"id" json:"membre_id" csv:"membre_id"`
|
||||||
|
Name string `db:"name" json:"name" csv:"name"`
|
||||||
|
ProgrammeID string `db:"programme_id" json:"programme_id" csv:"programme_id"`
|
||||||
|
ProgrammeName string `db:"programme_name" json:"programme_name" csv:"programme_name"`
|
||||||
|
}
|
||||||
|
|
||||||
func IsMembreID(membre_id string) bool {
|
func IsMembreID(membre_id string) bool {
|
||||||
if len(membre_id) != 7 {
|
if len(membre_id) != 7 {
|
||||||
return false
|
return false
|
||||||
|
|
75
request.go
75
request.go
|
@ -273,3 +273,78 @@ func (request ProgrammesGETRequest) Request(v *voki.Voki) (response ProgrammesGE
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ voki.Requester[MembresDisplayGETResponse] = MembresDisplayGETRequest{}
|
||||||
|
|
||||||
|
type MembresDisplayGETRequest struct {
|
||||||
|
Query struct {
|
||||||
|
Limit int `json:"limit" query:"limit"`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (request MembresDisplayGETRequest) Complete() bool { return true }
|
||||||
|
|
||||||
|
func (request MembresDisplayGETRequest) Request(v *voki.Voki) (response MembresDisplayGETResponse, err error) {
|
||||||
|
if !request.Complete() {
|
||||||
|
err = fmt.Errorf("Incomplete MembresDisplayGETRequest")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
statusCode, body, err := v.CallAndParse(
|
||||||
|
http.MethodGet,
|
||||||
|
fmt.Sprintf("/api/v7/membre/display/?limit=%d", request.Query.Limit),
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("code=%d err=%s", statusCode, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.SetStatusCode(statusCode)
|
||||||
|
if err = json.Unmarshal(body, &response); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ voki.Requester[MembreDisplayGETResponse] = MembreDisplayGETRequest{}
|
||||||
|
|
||||||
|
type MembreDisplayGETRequest struct {
|
||||||
|
Param struct {
|
||||||
|
MembreID string `json:"membre_id" param:"membre_id"`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (request MembreDisplayGETRequest) Complete() bool {
|
||||||
|
return request.Param.MembreID != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (request MembreDisplayGETRequest) Request(v *voki.Voki) (response MembreDisplayGETResponse, err error) {
|
||||||
|
if !request.Complete() {
|
||||||
|
err = fmt.Errorf("Incomplete MembreDisplayGETRequest")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if id := request.Param.MembreID; !IsMembreID(id) {
|
||||||
|
err = fmt.Errorf("MembreID '%s' invalide", id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
statusCode, body, err := v.CallAndParse(
|
||||||
|
http.MethodGet,
|
||||||
|
fmt.Sprintf("/api/v7/membre/%s/display/", request.Param.MembreID),
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("code=%d err=%s", statusCode, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.SetStatusCode(statusCode)
|
||||||
|
if err = json.Unmarshal(body, &response); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
17
response.go
17
response.go
|
@ -46,6 +46,23 @@ type MembresGETResponseData struct {
|
||||||
Membres []Membre `json:"membres"`
|
Membres []Membre `json:"membres"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MembreDisplayGETResponse struct {
|
||||||
|
APIResponse
|
||||||
|
Data MembreDisplayGETResponseData `json:"data"`
|
||||||
|
}
|
||||||
|
type MembreDisplayGETResponseData struct {
|
||||||
|
Membre MembreForDisplay `json:"membre_for_display"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MembresDisplayGETResponse struct {
|
||||||
|
APIResponse
|
||||||
|
Data MembresDisplayGETResponseData `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MembresDisplayGETResponseData struct {
|
||||||
|
Membres []MembreForDisplay `json:"membres_for_display"`
|
||||||
|
}
|
||||||
|
|
||||||
type MembresPOSTResponse struct {
|
type MembresPOSTResponse struct {
|
||||||
APIResponse
|
APIResponse
|
||||||
Data MembresPOSTResponseData `json:"data"`
|
Data MembresPOSTResponseData `json:"data"`
|
||||||
|
|
82
routes.go
82
routes.go
|
@ -297,5 +297,87 @@ func addRoutes(e *echo.Echo, db *PostgresClient) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := pave.EchoRegister[MembresDisplayGETRequest](
|
||||||
|
apiGroup,
|
||||||
|
&p,
|
||||||
|
apiPath,
|
||||||
|
http.MethodGet,
|
||||||
|
"/membre/display/",
|
||||||
|
"Get membres",
|
||||||
|
"MembresDisplayGET", func(c echo.Context) (err error) {
|
||||||
|
var request, response = MembresDisplayGETRequest{}, MembresDisplayGETResponse{}
|
||||||
|
|
||||||
|
request.Query.Limit, err = strconv.Atoi(c.QueryParam("limit"))
|
||||||
|
if err != nil {
|
||||||
|
var response voki.ResponseBadRequest
|
||||||
|
response.Message = fmt.Sprintf("parsing limit: %s", err)
|
||||||
|
return c.JSON(response.StatusCode(), response)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !request.Complete() {
|
||||||
|
var response voki.ResponseBadRequest
|
||||||
|
response.Message = "Incomplete MembresDisplayGET request received"
|
||||||
|
return c.JSON(response.StatusCode(), response)
|
||||||
|
}
|
||||||
|
|
||||||
|
response.Data.Membres, err = db.GetMembresForDisplay(request.Query.Limit)
|
||||||
|
if err != nil {
|
||||||
|
var response voki.ResponseBadRequest
|
||||||
|
response.Message = fmt.Sprintf("db: %s", err)
|
||||||
|
return c.JSON(response.StatusCode(), response)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := response.SetStatusCode(http.StatusOK); err != nil {
|
||||||
|
var response voki.ResponseInternalServerError
|
||||||
|
response.Message = fmt.Sprintf("handler: %s", err)
|
||||||
|
return c.JSON(response.StatusCode(), response)
|
||||||
|
}
|
||||||
|
|
||||||
|
response.Message = "ok"
|
||||||
|
return c.JSON(response.StatusCode(), response)
|
||||||
|
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := pave.EchoRegister[MembreDisplayGETRequest](
|
||||||
|
apiGroup,
|
||||||
|
&p,
|
||||||
|
apiPath,
|
||||||
|
http.MethodGet,
|
||||||
|
"/membre/:membre_id/display/",
|
||||||
|
"Get membre",
|
||||||
|
"MembreDisplayGET", func(c echo.Context) error {
|
||||||
|
var request, response = MembreDisplayGETRequest{}, MembreDisplayGETResponse{}
|
||||||
|
|
||||||
|
request.Param.MembreID = c.Param("membre_id")
|
||||||
|
|
||||||
|
if !request.Complete() {
|
||||||
|
var response voki.ResponseBadRequest
|
||||||
|
response.Message = "Incomplete MembreDisplayGET request received"
|
||||||
|
return c.JSON(response.StatusCode(), response)
|
||||||
|
}
|
||||||
|
|
||||||
|
membre, err := db.GetMembreForDisplay(request.Param.MembreID)
|
||||||
|
if err != nil {
|
||||||
|
var response voki.ResponseBadRequest
|
||||||
|
response.Message = fmt.Sprintf("db: %s", err)
|
||||||
|
return c.JSON(response.StatusCode(), response)
|
||||||
|
}
|
||||||
|
response.Data.Membre = membre
|
||||||
|
|
||||||
|
if err := response.SetStatusCode(http.StatusOK); err != nil {
|
||||||
|
var response voki.ResponseInternalServerError
|
||||||
|
response.Message = fmt.Sprintf("handler: %s", err)
|
||||||
|
return c.JSON(response.StatusCode(), response)
|
||||||
|
}
|
||||||
|
|
||||||
|
response.Message = "ok"
|
||||||
|
return c.JSON(response.StatusCode(), response)
|
||||||
|
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue