Skip to content
This repository has been archived by the owner on Dec 7, 2023. It is now read-only.

Add endpoint to patch user registration #234 #272

Open
wants to merge 6 commits into
base: staging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion common/datastore/conversions.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ func toObject(raw_data interface{}, definition DataStoreDefinition) (interface{}
return nil, err
}
} else {
data[field.Name] = getDefaultValue(field.Type)
if len(field.Fields) > 0 {
data[field.Name] = getDefaultValue(field.Type)
}
}
}

Expand Down
65 changes: 65 additions & 0 deletions documentation/docs/reference/services/Registration.md
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,71 @@ Response format:
}
```

PATCH /registration/attendee/
------------------

Updates only the provided fields the registration for the user with the `id` in the JWT token provided in the Authorization header.

Request format:
```
{
"email": "[email protected]",
"lastName": "editedLastName",
"github": "editedGithub",
"graduationYear": 2023,
"interests": [
"INTERNSHIP",
"JOB"
],
"isOSContributor": true
}
```

Response format:
```
{
"age": 19,
"beginnerInfo": {
"pullRequest": 1,
"technicalSkills": [
"Java"
],
"versionControl": 3,
"yearsExperience": 3
},
"createdAt": 111111111,
"diet": [
"VEGAN"
],
"email": "[email protected]",
"extraInfo": "",
"firstName": "John",
"gender": "MALE",
"github": "editedGithub",
"graduationYear": 2023,
"id": "github0000001",
"interests": [
"INTERNSHIP",
"JOB"
],
"isBeginner": false,
"isOSContributor": true,
"lastName": "editedLastName",
"linkedin": "",
"major": "Computer Science",
"phone": "0000000000",
"priorAttendance": true,
"school": "UIUC",
"shirtSize": "M",
"skills": [
"C++"
],
"teamMembers": null,
"transportation": "NONE",
"updatedAt": 1574291036
}
```

GET /registration/mentor/USERID/
-------------------------

Expand Down
10 changes: 10 additions & 0 deletions gateway/services/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ var RegistrationRoutes = arbor.RouteCollection{
"/registration/attendee/",
alice.New(middleware.AuthMiddleware([]models.Role{models.ApplicantRole}), middleware.IdentificationMiddleware).ThenFunc(UpdateRegistration).ServeHTTP,
},
arbor.Route{
"PatchCurrentUserRegistration",
"PATCH",
"/registration/attendee/",
alice.New(middleware.AuthMiddleware([]models.Role{models.UserRole}), middleware.IdentificationMiddleware).ThenFunc(PatchRegistration).ServeHTTP,
},
arbor.Route{
"GetFilteredUserRegistrations",
"GET",
Expand Down Expand Up @@ -97,3 +103,7 @@ func CreateRegistration(w http.ResponseWriter, r *http.Request) {
func UpdateRegistration(w http.ResponseWriter, r *http.Request) {
arbor.PUT(w, config.REGISTRATION_SERVICE+r.URL.String(), RegistrationFormat, "", r)
}

func PatchRegistration(w http.ResponseWriter, r *http.Request) {
arbor.PATCH(w, config.REGISTRATION_SERVICE+r.URL.String(), RegistrationFormat, "", r)
}
57 changes: 55 additions & 2 deletions services/registration/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ func SetupController(route *mux.Route) {
router.HandleFunc("/attendee/", GetCurrentUserRegistration).Methods("GET")
router.HandleFunc("/attendee/", CreateCurrentUserRegistration).Methods("POST")
router.HandleFunc("/attendee/", UpdateCurrentUserRegistration).Methods("PUT")
router.HandleFunc("/attendee/", PatchCurrentUserRegistration).Methods("PATCH")
router.HandleFunc("/attendee/filter/", GetFilteredUserRegistrations).Methods("GET")

router.HandleFunc("/mentor/", GetCurrentMentorRegistration).Methods("GET")
router.HandleFunc("/mentor/", GetCurrentMentorRegistration).Methods("GET")
router.HandleFunc("/mentor/", CreateCurrentMentorRegistration).Methods("POST")
router.HandleFunc("/mentor/", UpdateCurrentMentorRegistration).Methods("PUT")
router.HandleFunc("/mentor/filter/", GetFilteredMentorRegistrations).Methods("GET")
Expand Down Expand Up @@ -260,6 +261,58 @@ func UpdateCurrentUserRegistration(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(updated_registration)
}

/*
Endpoint to patch the registration for the current user.
On successful patch, sends the user a confirmation mail.
*/
func PatchCurrentUserRegistration(w http.ResponseWriter, r *http.Request) {
id := r.Header.Get("HackIllinois-Identity")

if id == "" {
errors.WriteError(w, r, errors.MalformedRequestError("Must provide id in request.", "Must provide id in request."))
return
}

user_registration := datastore.NewDataStore(config.REGISTRATION_DEFINITION)

// Decode http request and write into user_registration
err := json.NewDecoder(r.Body).Decode(&user_registration)

if err != nil {
errors.WriteError(w, r, errors.InternalError(err.Error(), "Could not decode user registration information. Possible failure in JSON validation, or invalid registration format."))
return
}

user_registration.Data["id"] = id

user_registration.Data["updatedAt"] = time.Now().Unix()

err = service.PatchUserRegistration(id, user_registration)

if err != nil {
errors.WriteError(w, r, errors.InternalError(err.Error(), "Could not update user's registration."))
return
}

updated_registration, err := service.GetUserRegistration(id)

if err != nil {
errors.WriteError(w, r, errors.DatabaseError(err.Error(), "Could not fetch user's updated registration."))
return
}

mail_template := "registration_update"
err = service.SendUserMail(id, mail_template)

if err != nil {
errors.WriteError(w, r, errors.InternalError(err.Error(), "Could not send registration update email."))
return
}

json.NewEncoder(w).Encode(updated_registration)
return
}

/*
Endpoint to get user registrations based on filters
*/
Expand Down
20 changes: 19 additions & 1 deletion services/registration/service/registration_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,25 @@ func UpdateUserRegistration(id string, user_registration models.UserRegistration
}

/*
Returns db search query based on given parameters
Patches the registration associated with the given user id
*/
func PatchUserRegistration(id string, user_registration models.UserRegistration) error {
selector := database.QuerySelector{"id": id}

// Delete fields that weren't provided
for k, v := range user_registration.Data {
if v == nil {
delete(user_registration.Data, k)
}
}

err := db.Patch("attendees", selector, &user_registration.Data)

return err
}

/*
Returns db search query based on given parameters
*/
func getFilterQuery(parameters map[string][]string) (map[string]interface{}, error) {
query := make(map[string]interface{})
Expand Down
54 changes: 54 additions & 0 deletions services/registration/tests/registration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,50 @@ func TestUpdateUserRegistrationService(t *testing.T) {
CleanupTestDB(t)
}

/*
Service level test for updating user registration in the db
*/
func TestPatchUserRegistrationService(t *testing.T) {
SetupTestDB(t)
updated_registration := getEmptyUserRegistration()
updated_registration.Data["email"] = "[email protected]"
updated_registration.Data["isBeginner"] = true
updated_registration.Data["priorAttendance"] = false
updated_registration.Data["age"] = 22

err := service.PatchUserRegistration("testid", updated_registration)

// if err != nil {
// t.Fatal(err)
// }

user_registration, err := service.GetUserRegistration("testid")

if err != nil {
t.Fatal(err)
}

expected_registration := getBaseUserRegistration()
expected_registration.Data["id"] = "testid"
expected_registration.Data["firstName"] = "first"
expected_registration.Data["lastName"] = "last"
expected_registration.Data["shirtSize"] = "M"
expected_registration.Data["github"] = "githubusername"
expected_registration.Data["linkedin"] = "linkedinusername"
expected_registration.Data["createdAt"] = int64(10)

expected_registration.Data["email"] = "[email protected]"
expected_registration.Data["isBeginner"] = true
expected_registration.Data["priorAttendance"] = false
expected_registration.Data["age"] = 22

if !reflect.DeepEqual(user_registration.Data, expected_registration.Data) {
t.Errorf("Wrong user info.\nExpected %v\nGot %v\n", expected_registration.Data, user_registration.Data)
}

CleanupTestDB(t)
}

/*
Service level test for getting mentor registration from db
*/
Expand Down Expand Up @@ -426,6 +470,16 @@ func getBaseMentorRegistration() datastore.DataStore {
return base_mentor_registration
}

/*
Returns an empty user registration
*/
func getEmptyUserRegistration() datastore.DataStore {
empty_user_registration := datastore.NewDataStore(config.REGISTRATION_DEFINITION)
json.Unmarshal([]byte(empty_registration_data), &empty_user_registration)
return empty_user_registration
}

var empty_registration_data string = `{}`
var user_registration_data string = `
{
"id": "testid",
Expand Down