Skip to content

Commit

Permalink
Added class CRUD (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
APandamonium1 authored Jul 5, 2024
1 parent 19fe899 commit 9ad1279
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 28 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
edusync-7bd5e-firebase-adminsdk-x49uh-af084a6314.json
edusync-test-firebase-adminsdk-hk5kl-9af0162b09.json
.env
config.json
config.json
*.exe
73 changes: 73 additions & 0 deletions database.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,26 @@ func canChildAccessParent(currentUser User, parent Parent) bool {
return currentUser.GoogleID == parent.GoogleID
}

// Check if student is in the class
func isStudentInClass(currentUser User, students []Student, class Class) bool {
for _, student := range students {
if student.GoogleID == currentUser.GoogleID && student.ClassID == class.ClassID {
return true
}
}
return false
}

// Check if the parent's child is in the class
func isParentChildInClass(currentUser User, students []Student, class Class) bool {
for _, student := range students {
if student.ParentID == currentUser.GoogleID && student.ClassID == class.ClassID {
return true
}
}
return false
}

// CRUD operations with role checks

// Student CRUD
Expand Down Expand Up @@ -323,3 +343,56 @@ func deleteParent(currentUser User, parent Parent) error {
}
return ref.Delete(context.TODO())
}

// class CRUD

func createClass(currentUser User, class Class) error {
// If user is not admin, return error when attempting to create class
if !isAdmin(currentUser) {
return fmt.Errorf("unauthorized access: only admins can create classes")
}
ref := firebaseClient.NewRef("classes/" + class.ClassID)
if err := ref.Set(context.TODO(), class); err != nil {
return fmt.Errorf("error creating class: %v", err)
}
return ref.Set(context.TODO(), class)
}

func readClass(currentUser User, students []Student, class Class) (Class, error) {
// If user is not admin or (self and class), return error when attempting to read class
if !isAdmin(currentUser) && //not admin
!isInstructor(currentUser) && //not instructor
!(isStudent(currentUser) && isStudentInClass(currentUser, students, class)) &&
!(isParent(currentUser) && isParentChildInClass(currentUser, students, class)) {
return Class{}, fmt.Errorf("unauthorized access: you can only read your own details")
}
ref := firebaseClient.NewRef("classes/" + class.ClassID)
if err := ref.Get(context.TODO(), &class); err != nil {
return Class{}, fmt.Errorf("error reading class: %v", err)
}
return class, nil
}

func updateClass(currentUser User, class Class, updates map[string]interface{}) error {
// If user is not admin or (self and class), return error when attempting to update class
if !isAdmin(currentUser) {
return fmt.Errorf("unauthorized access: you can only update your own details")
}
ref := firebaseClient.NewRef("classes/" + class.ClassID)
if err := ref.Update(context.TODO(), updates); err != nil {
return fmt.Errorf("error updating class: %v", err)
}
return ref.Update(context.TODO(), updates)
}

func deleteClass(currentUser User, class Class) error {
// If user is not admin, return error when attempting to delete class
if !isAdmin(currentUser) {
return fmt.Errorf("unauthorized access: only admins can delete classes")
}
ref := firebaseClient.NewRef("classes/" + class.ClassID)
if err := ref.Delete(context.TODO()); err != nil {
return fmt.Errorf("error deleting class: %v", err)
}
return ref.Delete(context.TODO())
}
115 changes: 88 additions & 27 deletions database_test.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,27 @@
package main

import (
// // "context"
// // "fmt"

// // "os"
// "reflect"

// // "strings"
"reflect"
"testing"
// // firebase "firebase.google.com/go"
// // "google.golang.org/api/option"
)

var currentUser = User{GoogleID: "admin-user", Role: "Admin"}

// Create a new student
var student = Student{
User: User{
GoogleID: "test-student",
Name: "John Doe",
Email: "[email protected]",
ContactNumber: "91234567",
Role: "Student",
var students = []Student{
{
User: User{
GoogleID: "test-student",
Name: "John Doe",
Email: "[email protected]",
ContactNumber: "91234567",
Role: "Student",
},
Age: 12,
LessonCredits: 10.0,
ClassID: "te-6-10",
ParentID: "test-parent",
},
Age: 12,
LessonCredits: 10.0,
ClassID: "te-6-10",
ParentID: "test-parent",
}

// Create a new instructor
Expand Down Expand Up @@ -92,23 +85,23 @@ func TestInitializeFirebase(t *testing.T) {

// Testing for student CRUD operations
func TestCreateStudent(t *testing.T) {
err := createStudent(currentUser, student)
err := createStudent(currentUser, students[0])
if err != nil {
t.Fatalf("Error creating student: %v", err)
}

readStudent, err := readStudent(currentUser, student, classes)
readStudent, err := readStudent(currentUser, students[0], classes)
if err != nil {
t.Fatalf("Error reading student: %v", err)
}

if !reflect.DeepEqual(student, readStudent) {
if !reflect.DeepEqual(students[0], readStudent) {
t.Errorf("Created and read students do not match")
}
}

func TestReadStudent(t *testing.T) {
readStudent, err := readStudent(currentUser, student, classes)
readStudent, err := readStudent(currentUser, students[0], classes)
if err != nil {
t.Fatalf("Error reading student: %v", err)
}
Expand All @@ -124,13 +117,13 @@ func TestUpdateStudent(t *testing.T) {
"name": "Updated Student",
}

err := updateStudent(currentUser, student, classes, updates)
err := updateStudent(currentUser, students[0], classes, updates)
if err != nil {
t.Fatalf("Error updating student: %v", err)
}

// Read the updated student
readStudent, err := readStudent(currentUser, student, classes)
readStudent, err := readStudent(currentUser, students[0], classes)
if err != nil {
t.Fatalf("Error reading student after updating: %v", err)
}
Expand All @@ -143,7 +136,7 @@ func TestUpdateStudent(t *testing.T) {

func TestDeleteStudent(t *testing.T) {
// Delete the student
err := deleteStudent(currentUser, student)
err := deleteStudent(currentUser, students[0])
if err != nil {
t.Fatalf("Error deleting student: %v", err)
}
Expand Down Expand Up @@ -356,3 +349,71 @@ func TestDeleteParent(t *testing.T) {
// t.Error("Deleted parent still exists")
// }
}

// Testing for class CRUD operations

func TestCreateClass(t *testing.T) {
err := createClass(currentUser, classes[0])
if err != nil {
t.Fatalf("Error creating class: %v", err)
}

// Read the created class
readClass, err := readClass(currentUser, students, classes[0])
if err != nil {
t.Fatalf("Error reading class: %v", err)
}

// Assert that the created and read class are equal
if !reflect.DeepEqual(classes[0], readClass) {
t.Error("Created and read classes are not equal")
}
}

func TestReadClass(t *testing.T) {
class, err := readClass(currentUser, students, classes[0])
if err != nil {
t.Fatalf("Failed to read class: %v", err)
}

if class.ClassID != classes[0].ClassID {
t.Fatalf("Expected ID %v, got %v", classes[0].ClassID, class.ClassID)
}
}

func TestUpdateClass(t *testing.T) {
// Update the class's name
updates := map[string]interface{}{
"class_name": "DN",
}

err := updateClass(currentUser, classes[0], updates)
if err != nil {
t.Fatalf("Error updating class: %v", err)
}

// Read the updated class
readClass, err := readClass(currentUser, students, classes[0])
if err != nil {
t.Fatalf("Error reading class: %v", err)
}

// Assert that the updated class's name is correct
if readClass.Name != updates["class_name"] {
t.Errorf("Updated class's name is incorrect. Expected: %v, Got: %v", updates["class_name"], readClass.Name)
}
}

func TestDeleteClass(t *testing.T) {
// Delete the class
err := deleteClass(currentUser, classes[0])
if err != nil {
t.Fatalf("Error deleting class: %v", err)
}

// Try to read the deleted class
// _, err = readClass(currentUser, students, classes[0])
// if err == nil {
// t.Error("Deleted class still exists")
// }
}

0 comments on commit 9ad1279

Please sign in to comment.