Skip to content

Commit

Permalink
test: contact CRUD fin
Browse files Browse the repository at this point in the history
  • Loading branch information
Olivier Ndjike Nzia committed Feb 7, 2024
1 parent 7fb839a commit b63de3a
Show file tree
Hide file tree
Showing 9 changed files with 555 additions and 310 deletions.
137 changes: 124 additions & 13 deletions backend/src/controllers/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ func NewClubController(clubService services.ClubServiceInterface) *ClubControlle
return &ClubController{clubService: clubService}
}

// GetAllClubs returns all clubs.
//
// @Summary Get all clubs
// @Description Get all clubs with pagination support
// @ID get-all-clubs
// @Tags club
// @Produce json
// @Param limit query int false "Number of clubs per page"
// @Param page query int false "Page number"
// @Success 200 {object} []models.Club
// @Failure 400 {string} string "failed to get clubs"
// @Router /api/v1/clubs/ [get]
func (l *ClubController) GetAllClubs(c *fiber.Ctx) error {
defaultLimit := 10
defaultPage := 1
Expand All @@ -29,6 +41,18 @@ func (l *ClubController) GetAllClubs(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).JSON(clubs)
}

// CreateClub creates a new club.
//
// @Summary Create a club
// @Description Create a new club
// @ID create-club
// @Tags club
// @Accept json
// @Produce json
// @Param clubBody body models.CreateClubRequestBody true "Club details"
// @Success 201 {object} models.Club
// @Failure 400 {string} string "failed to create club"
// @Router /api/v1/clubs/ [post]
func (l *ClubController) CreateClub(c *fiber.Ctx) error {
var clubBody models.CreateClubRequestBody
if err := c.BodyParser(&clubBody); err != nil {
Expand All @@ -43,6 +67,17 @@ func (l *ClubController) CreateClub(c *fiber.Ctx) error {
return c.Status(fiber.StatusCreated).JSON(club)
}

// GetClub returns a club by ID.
//
// @Summary Get a club by ID
// @Description Get a club by its ID
// @ID get-club
// @Tags club
// @Produce json
// @Param id path string true "Club ID"
// @Success 200 {object} models.Club
// @Failure 400 {string} string "failed to get club"
// @Router /api/v1/clubs/{id} [get]
func (l *ClubController) GetClub(c *fiber.Ctx) error {
club, err := l.clubService.GetClub(c.Params("id"))
if err != nil {
Expand All @@ -52,6 +87,19 @@ func (l *ClubController) GetClub(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).JSON(club)
}

// UpdateClub updates a club by ID.
//
// @Summary Update a club by ID
// @Description Update a club by its ID
// @ID update-club
// @Tags club
// @Accept json
// @Produce json
// @Param id path string true "Club ID"
// @Param clubBody body models.UpdateClubRequestBody true "Club details"
// @Success 200 {object} models.Club
// @Failure 400 {string} string "failed to update club"
// @Router /api/v1/clubs/{id} [put]
func (l *ClubController) UpdateClub(c *fiber.Ctx) error {
var clubBody models.UpdateClubRequestBody

Expand All @@ -67,6 +115,17 @@ func (l *ClubController) UpdateClub(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).JSON(updatedClub)
}

// DeleteClub deletes a club by ID.
//
// @Summary Delete a club by ID
// @Description Delete a club by its ID
// @ID delete-club
// @Tags club
// @Produce json
// @Param id path string true "Club ID"
// @Success 204 - No Content
// @Failure 400 {string} string "failed to delete club"
// @Router /api/v1/clubs/{id} [delete]
func (l *ClubController) DeleteClub(c *fiber.Ctx) error {
err := l.clubService.DeleteClub(c.Params("id"))
if err != nil {
Expand All @@ -76,10 +135,38 @@ func (l *ClubController) DeleteClub(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusNoContent)
}

// func (l* ClubController) GetContact(c *fiber.Ctx) error {
// GetContact returns a contact by ID.
//
// @Summary Get a contact by ID
// @Description Get a contact by its ID
// @ID get-contact
// @Tags club
// @Produce json
// @Param id path string true "Contact ID"
// @Success 200 {object} models.Contact
// @Failure 400 {string} string "failed to get contact"
// @Router /api/v1/contacts/{id} [get]
func (l *ClubController) GetContact(c *fiber.Ctx) error {
contact, err := l.clubService.GetContact(c.Params("id"))
if err != nil {
return err.FiberError(c)
}

// }
return c.Status(fiber.StatusOK).JSON(contact)
}

// GetContacts returns all contacts.
//
// @Summary Get all contacts
// @Description Get all contacts with pagination support
// @ID get-all-contacts
// @Tags club
// @Produce json
// @Param limit query int false "Number of contacts per page"
// @Param page query int false "Page number"
// @Success 200 {object} []models.Contact
// @Failure 400 {string} string "failed to get contacts"
// @Router /api/v1/contacts/ [get]
func (l *ClubController) GetContacts(c *fiber.Ctx) error {
defaultLimit := 10
defaultPage := 1
Expand All @@ -92,6 +179,17 @@ func (l *ClubController) GetContacts(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).JSON(contacts)
}

// GetClubContacts returns all contacts of a club.
//
// @Summary Get all contacts of a club
// @Description Get all contacts of a club with pagination support
// @ID get-club-contacts
// @Tags club
// @Produce json
// @Param id path string true "Club ID"
// @Success 200 {object} []models.Contact
// @Failure 400 {string} string "failed to get club contacts"
// @Router /api/v1/clubs/{id}/contacts [get]
func (l *ClubController) GetClubContacts(c *fiber.Ctx) error {
contacts, err := l.clubService.GetClubContacts(c.Params("id"))
if err != nil {
Expand All @@ -101,17 +199,19 @@ func (l *ClubController) GetClubContacts(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).JSON(contacts)
}

// TODO fix godoc
// PutContact godoc
// PutContact creates or updates a contact for a club.
//
// @Summary Creates a contact for a club, if it does not exist, other wise updates an existing contact
// @Description Returns the updated contact
// @ID put-contact
// @Tags club
// @Produce json
// @Success 200 {object} []models.Contact
// @Failure 400 {string} string "failed to update contact"
// @Router /api/v1/users/ [put]
// @Summary Create or update a contact for a club
// @Description Creates a contact for a club if it does not exist, otherwise updates an existing contact
// @ID put-contact
// @Tags club
// @Accept json
// @Produce json
// @Param id path string true "Club ID"
// @Param contactBody body models.PutContactRequestBody true "Contact details"
// @Success 200 {object} models.Contact
// @Failure 400 {string} string "failed to create/update contact"
// @Router /api/v1/clubs/{id}/contacts [put]
func (l *ClubController) PutContact(c *fiber.Ctx) error {
var contactBody models.PutContactRequestBody

Expand All @@ -127,8 +227,19 @@ func (l *ClubController) PutContact(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).JSON(contact)
}

// DeleteContact deletes a contact by ID.
//
// @Summary Delete a contact by ID
// @Description Delete a contact by its ID
// @ID delete-contact
// @Tags club
// @Produce json
// @Param id path string true "Contact ID"
// @Success 204 - No Content
// @Failure 400 {string} string "failed to delete contact"
// @Router /api/v1/contacts/{id} [delete]
func (l *ClubController) DeleteContact(c *fiber.Ctx) error {
err := l.clubService.DeleteContact(c.Params("contactID"))
err := l.clubService.DeleteContact(c.Params("id"))
if err != nil {
return err.FiberError(c)
}
Expand Down
8 changes: 8 additions & 0 deletions backend/src/errors/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ var (
StatusCode: fiber.StatusInternalServerError,
Message: "failed to get contacts",
}
FailedToGetContact = Error{
StatusCode: fiber.StatusInternalServerError,
Message: "failed to get contact",
}
ContactNotFound = Error{
StatusCode: fiber.StatusNotFound,
Message: "contact not found",
}
FailedToCreateContact = Error{
StatusCode: fiber.StatusInternalServerError,
Message: "failed to create contact",
Expand Down
4 changes: 2 additions & 2 deletions backend/src/models/contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type Contact struct {
}

type PutContactRequestBody struct {
Type ContactType `gorm:"type:varchar(255)" json:"type" validate:"required,max=255,oneof=facebook instagram twitter linkedin youtube github slack discord email customSite,contact_pointer"`
Type ContactType `json:"type" validate:"required,max=255,oneof=facebook instagram twitter linkedin youtube github slack discord email customSite,contact_pointer"`

Content string `gorm:"type:varchar(255)" json:"content" validate:"required,max=255"`
Content string `json:"content" validate:"required,max=255"`
}
4 changes: 3 additions & 1 deletion backend/src/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func Init(db *gorm.DB) *fiber.App {

userRoutes(apiv1, &services.UserService{DB: db, Validate: validate})
clubRoutes(apiv1, &services.ClubService{DB: db, Validate: validate})
contactRoutes(apiv1, &services.ClubService{DB: db, Validate: validate})
categoryRouter := categoryRoutes(apiv1, &services.CategoryService{DB: db, Validate: validate})
tagRoutes(categoryRouter, &services.TagService{DB: db, Validate: validate})

Expand Down Expand Up @@ -99,7 +100,6 @@ func clubRoutes(router fiber.Router, clubService services.ClubServiceInterface)
// club-dependent contact routes
contacts.Get("/", clubController.GetClubContacts)
contacts.Put("/", clubController.PutContact) // contact to be updated is identified in the body media type
contacts.Delete("/:contactID", clubController.DeleteContact)
}

func contactRoutes(router fiber.Router, clubService services.ClubServiceInterface) {
Expand All @@ -108,6 +108,8 @@ func contactRoutes(router fiber.Router, clubService services.ClubServiceInterfac
contacts := router.Group("/contacts")

contacts.Get("/", clubController.GetContacts)
contacts.Get("/:id", clubController.GetContact)
contacts.Delete("/:id", clubController.DeleteContact)
}

func categoryRoutes(router fiber.Router, categoryService services.CategoryServiceInterface) fiber.Router {
Expand Down
10 changes: 10 additions & 0 deletions backend/src/services/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type ClubServiceInterface interface {
UpdateClub(id string, clubBody models.UpdateClubRequestBody) (*models.Club, *errors.Error)
DeleteClub(id string) *errors.Error
GetContacts(limit string, page string) ([]models.Contact, *errors.Error)
GetContact(id string) (*models.Contact, *errors.Error)
GetClubContacts(id string) ([]models.Contact, *errors.Error)
// GetClubContact(contactId string) (*models.Contact, *errors.Error)
PutContact(clubID string, contactBody models.PutContactRequestBody) (*models.Contact, *errors.Error)
Expand Down Expand Up @@ -113,6 +114,15 @@ func (c *ClubService) GetContacts(limit string, page string) ([]models.Contact,
return transactions.GetContacts(c.DB, *limitAsInt, offset)
}

func (c *ClubService) GetContact(id string) (*models.Contact, *errors.Error) {
idAsUUID, err := utilities.ValidateID(id)
if err != nil {
return nil, &errors.FailedToValidateID
}

return transactions.GetContact(c.DB, *idAsUUID)
}

func (c *ClubService) GetClubContacts(id string) ([]models.Contact, *errors.Error) {
idAsUUID, err := utilities.ValidateID(id)
if err != nil {
Expand Down
23 changes: 19 additions & 4 deletions backend/src/transactions/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,19 @@ func GetClubContacts(db *gorm.DB, id uuid.UUID) ([]models.Contact, *errors.Error
return club.Contact, nil
}

func GetContact(db *gorm.DB, id uuid.UUID) (*models.Contact, *errors.Error) {
var contact models.Contact
if err := db.First(&contact, id).Error; err != nil {
if stdliberrors.Is(err, gorm.ErrRecordNotFound) {
return nil, &errors.ContactNotFound
} else {
return nil, &errors.FailedToGetContact
}
}

return &contact, nil
}

func PutContact(db *gorm.DB, clubID uuid.UUID, contact models.Contact) (*models.Contact, *errors.Error) {
// if the club already has a contact of the same type, update the existing contact
err := db.Clauses(clause.OnConflict{
Expand All @@ -107,11 +120,13 @@ func PutContact(db *gorm.DB, clubID uuid.UUID, contact models.Contact) (*models.
}

func DeleteContact(db *gorm.DB, id uuid.UUID) *errors.Error {
result := db.Delete(&models.Contact{}, id)
if result.Error != nil {
return &errors.FailedToDeleteClub
if result := db.Delete(&models.Contact{}, id); result.RowsAffected == 0 {
if result.Error == nil {
return &errors.ContactNotFound
} else {
return &errors.FailedToDeleteContact
}
}

return nil
}
func UpdateClub(db *gorm.DB, id uuid.UUID, club models.Club) (*models.Club, *errors.Error) {
Expand Down
1 change: 0 additions & 1 deletion backend/src/utilities/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ func validateS3URL(fl validator.FieldLevel) bool {
func validateContactPointer(validate *validator.Validate, fl validator.FieldLevel) bool {
contact, ok := fl.Parent().Interface().(models.PutContactRequestBody)
if !ok {
println("Failed to cast to PutContactRequestBody")
return false
}
switch contact.Type {
Expand Down
Loading

0 comments on commit b63de3a

Please sign in to comment.