-
Notifications
You must be signed in to change notification settings - Fork 1
Sprint3
During Sprint 3, the backend team implemented the event management system. An event denotes a sport event that any user can create, and other users can join. This includes endpoints for creating, updating, joining, and deleting sports events, along with database schema enhancements. On the Frontend part the site went into major look overhaul for making it more aesthetically pleasing so it now has a new background and custom logo and we added the my profile page which displays the profile information for each user and now there is also a "+" symbol on the nav bar from which you can create events which has the location autocomplete feature implemented though google maps api, the event gets displayed on home page after creation and the enhancement which we'll be working on is making it all integrated with the backend by the next sprint.
| Issue Number | Title | Objective | Status |
|---|---|---|---|
| 34 | Create Event API | Implement API to create new events. | Completed |
| 47 | Update Event API | Implement API to update existing events. | Completed |
| 48 | Fetch All Events API | Develop API to retrieve event list. | Completed |
| 49 | Get Event by ID API | Implement API to fetch event details by ID. | Completed |
| 50 | Join Event API | Develop API to allow users to join events. | Completed |
| 51 | Leave Event API | Implement API to allow users to leave events. | Completed |
| 52 | Delete Event API | Create API to delete existing events. | Completed |
| 61 | New Event tile | Generate new event till on home page | Completed |
| 60 | unit tests for new page | write tests for new pages and features | Completed |
| 59 | Integrate Google map api | add address api in event create form | Completed |
| 58 | add event create to the nav bar | Add option to create events on home page | Completed |
| 57 | Event create page | frontend for the page for event creation | Completed |
| 56 | MyProfile Page | frontend for the MyProfile page | Completed |
-
Database Schema Additions:
-
eventstableCREATE TABLE events ( id SERIAL PRIMARY KEY, event_owner INT REFERENCES users(id) ON DELETE CASCADE, sport TEXT NOT NULL, event_datetime TIMESTAMP NOT NULL, max_players INT NOT NULL CHECK (max_players > 0), location_name TEXT NOT NULL, latitude DECIMAL(9,6) NOT NULL, longitude DECIMAL(9,6) NOT NULL, description TEXT, title TEXT, is_full BOOLEAN, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
-
event_participantstableCREATE TABLE event_participants ( id SERIAL PRIMARY KEY, event_id INT REFERENCES events(id) ON DELETE CASCADE, user_id INT REFERENCES users(id) ON DELETE CASCADE, joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
-
-
New Event Endpoints:
-
POST /events: Create a new event. -
GET /events: Retrieve all events with optional filters. -
GET /events/:id: Retrieve a single event by ID. -
PUT /events/:id: Update an event. -
POST /events/:id/join: Join an event. -
DELETE /events/:id/leave: Leave an event. -
DELETE /events/:id: Delete an event.
-
-
Example Request/Response:
-
POST
/eventsRequest:{ "sport": "Football", "event_date": "2025-03-25T15:00:00Z", "max_players": 20, "location_name": "Central Park, NY", "latitude": 40.785091, "longitude": -73.968285, "description": "Need players for a friendly football match", "title": "Lets football!" } -
POST
/eventsResponse:{ "id": 1, "event_owner": 1, "sport": "Football", "event_datetime": "2025-03-25T15:00:00Z", "max_players": 20, "location_name": "Central Park, NY", "latitude": 40.785091, "longitude": -73.968285, "description": "Friendly football match", "title": "Lets football!", "created_at": "2025-03-25T10:00:00Z", "updated_at": "2025-03-25T10:00:00Z", "is_full": false, "registered_count": 0 }
-
-
Business Logic:
- Event capacity is updated automatically when users join or leave.
- Events are marked as full (
is_full=true) whenregistered_count >= max_players.
-
Site Overhaul:
-
The site went through a major aesthetic overhaul to make it more visually appealing. This includes:
-
A new background for the pages.
-
A custom logo to represent the brand.
-
-
-
My Profile Page:
- A "My Profile" page has been added, where users can view their profile information.
-
Event Creation via Menu Bar:
-
We added a "+" button to the menu bar, which allows users to create events.
-
The Create Event page includes a location autocomplete feature to help users select a location easily.
-
-
Home Page Display:
- After creating an event, the event is displayed on the home page for users to view.
-
Future Enhancements:
- In the next sprint, we will work on integrating the frontend with the backend to make the event creation and other features fully functional.
-
src/test/:
-
CreateEvent_test
- Test Purpose:
-
The test checks that the
CreateEventform renders correctly with all required fields and elements (heading, form fields, and submit button).-
Test Setup:
-
render: Therenderfunction from React Testing Library is used to render theCreateEventcomponent within aBrowserRouterwrapper. This is necessary because the component likely uses routing viareact-router-dom. -
Check for Heading:
-
expect(screen.getByRole('heading', { name: /Create Event/i })): -
This checks that the heading with the text "Create Event" is present in the DOM. The regular expression
/Create Event/iensures that it is case-insensitive. -
Check for Form Fields:
-
expect(screen.getByLabelText(/Event Title/i)): -
This checks that the form input field for "Event Title" is present in the DOM. The
getByLabelTextmethod looks for form fields by their associated label text.
-
-
Similarly, the other form fields checked are:
-
Description -
Sport -
Maximum Players -
Location -
Date and Time -
Check for Submit Button:
-
expect(screen.getByRole('button', { name: /Create Event/i })): -
This checks that the submit button labeled "Create Event" is present and can be interacted with. The
getByRolemethod is used to find buttons or other interactive elements by their role. -
Assertions:
-
Each
expect()statement asserts that a specific element (heading, form field, or button) is rendered correctly. If any of these elements are missing, the test will fail.
-
-
MyProfile.test.js *- Test Setup:
-
The
renderfunction from React Testing Library is used to render theMyProfilecomponent wrapped inMemoryRouter(to handle routing in tests). -
useNavigatefromreact-router-domis mocked usingjest.fn()to simulate navigation during the tests.
-
-
Test 1: "should render the My profile form correctly":
-
Verifies that all required input fields (First Name, Last Name, Age, Gender, and Sports dropdown) are rendered correctly on the page.
-
Assertions: Check for placeholders and text content in the form.
-
-
Test 2: "should allow user to enter profile details":
-
Simulates user input by firing
changeevents on the form fields (First Name, Last Name, Age). -
Assertions: Ensures that the form fields' values are updated correctly after user input.
-
-
Test 3: "should allow user to select gender":
-
Simulates the selection of a gender from a dropdown.
-
Assertions: Checks if the selected gender value is updated correctly after user interaction.
-
-
Test 4: "should open and close sports dropdown":
-
Simulates opening and closing the sports dropdown.
-
Assertions: Ensures that the dropdown content (e.g., "Football") is displayed when opened and hidden when closed.
-
-
Test 5: "should allow user to select and deselect sports preferences":
-
Simulates selecting and deselecting a sports preference checkbox (e.g., "Football").
-
Assertions: Ensures that the checkbox toggles between checked and unchecked states as expected.
-
-
Test 6: "should navigate to /home when form is submitted":
-
Simulates clicking the "Update" button to submit the form.
-
Assertions: Ensures that clicking the button triggers navigation to the
/homeroute (via the mockeduseNavigatefunction).
-
-
-
cmd/api/events_test:
-
createEventHandler_test
- Should allow creation of a valid event via the
/eventsroute and return201 Created. - Should reject event creation with invalid/missing fields via the
/eventsroute and return400 Bad Request. - Should reject unauthorized event creation via the
/eventsroute and return401 Unauthorized.
- Should allow creation of a valid event via the
-
getEventHandler_test
- Should return event details successfully via the
/events/{id}route and return200 OK. - Should reject request with invalid event ID via the
/events/{id}route and return400 Bad Request. - Should reject unauthorized access to event via the
/events/{id}route and return401 Unauthorized.
- Should return event details successfully via the
-
updateEventHandler_test
- Should allow valid updates to an event via the
/events/{id}route and return200 OK. - Should reject unauthorized update requests via the
/events/{id}route and return401 Unauthorized. - Should reject update attempts by non-owners via the
/events/{id}route and return403 Forbidden.
- Should allow valid updates to an event via the
-
deleteEventHandler_test
- Should allow event deletion by owner via the
/events/{id}route and return200 OK. - Should reject unauthorized delete requests via the
/events/{id}route and return401 Unauthorized. - Should reject delete attempts by non-owners via the
/events/{id}route and return403 Forbidden.
- Should allow event deletion by owner via the
-
-
internal/store/events_test:
-
eventStore_Create_test
- Should create a valid event in the database and return success.
- Should return an error when creating an event with missing required fields.
-
eventStore_GetByID_test
- Should retrieve an existing event by ID and return correct event details.
- Should return
ErrEventNotFoundfor a non-existent event ID.
-
eventStore_Delete_test
- Should delete an existing event and confirm it no longer exists in the database.
- Should return
ErrEventNotFoundwhen attempting to delete a non-existent event.
-
eventStore_Join_test
- Should allow a valid user to join an existing event and update participant list.
- Should return
ErrAlreadyJoinedif the same user attempts to join the event again. - Should return an error when attempting to join a non-existent event.
-
-
Also updated all existing tests to work with auth middleware
All backend endpoints are documented using Swagger UI at:
http://localhost:8080/v1/swagger/index.html#/
- Description: Creates a new event.
-
Headers:
Authorization: Bearer JWT_TOKEN_HERE Content-Type: application/json -
Request Body:
{ "sport": "Football", "event_date": "2025-03-25T15:00:00Z", "max_players": 20, "location_name": "Central Park, NY", "latitude": 40.785091, "longitude": -73.968285, "description": "Need players for a friendly football match", "title": "Lets football!" } -
Response (200 OK):
{ "id": 1, "event_owner": 1, "sport": "Football", "event_datetime": "2025-03-25T15:00:00Z", "max_players": 20, "location_name": "Central Park, NY", "latitude": 40.785091, "longitude": -73.968285, "description": "Friendly football match", "title": "Lets football!", "created_at": "2025-03-25T10:00:00Z", "updated_at": "2025-03-25T10:00:00Z", "is_full": false, "registered_count": 0 }
- Description: Retrieves a list of events with optional filters.
-
Headers:
Authorization: Bearer JWT_TOKEN_HERE Content-Type: application/json -
Response (200 OK):
[ { "id": 1, "event_owner": 1, "sport": "Football", "event_datetime": "2025-03-25T15:00:00Z", "max_players": 20, "location_name": "Central Park, NY", "latitude": 40.785091, "longitude": -73.968285, "description": "Friendly football match", "title": "Lets football!", "created_at": "2025-03-25T10:00:00Z", "updated_at": "2025-03-25T10:00:00Z", "is_full": false, "registered_count": 2, "event_participants": [ { "id": 2, "name": "John Doe", "email": "johndoe@gmail.com" }, { "id": 3, "name": "John Does", "email": "johndoes@gmail.com" } ] } ]
- Description: Retrieves details of a single event by ID.
-
Headers:
Authorization: Bearer JWT_TOKEN_HERE - Response (200 OK): Same structure as above.
- Description: Updates the given fields of an event.
-
Headers:
Authorization: Bearer JWT_TOKEN_HERE Content-Type: application/json - Request Body: Any subset of event fields.
-
Response (200 OK):
{ "message": "Event updated successfully." }
- Description: User joins an event.
-
Headers:
Authorization: Bearer JWT_TOKEN_HERE -
Response (200 OK):
{ "message": "You have successfully joined the event!" }
- Description: User leaves an event.
-
Headers:
Authorization: Bearer JWT_TOKEN_HERE -
Response (200 OK):
{ "message": "You have successfully left the event!" }
- Description: Deletes an event.
-
Headers:
Authorization: Bearer JWT_TOKEN_HERE -
Response (200 OK):
{ "message": "You have successfully deleted the event!" }
Here's our Github Repository for Sportify - Sportify Repo
Here's our Github Project Board - Sportify Project Board
This document is also available in our Github Wiki Page
Along with this, we also added our design documentation (originally or Atlassian Confluence) onto our Github Repo