Skip to content

Commit 029ef43

Browse files
committed
refactored functions andadded test cases
1 parent 456fc6a commit 029ef43

File tree

7 files changed

+206
-71
lines changed

7 files changed

+206
-71
lines changed

class.go

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"io/ioutil"
6+
"net/http"
7+
8+
"github.com/julienschmidt/httprouter"
9+
)
10+
11+
// Models
12+
type Class struct {
13+
ID int `json:"id"`
14+
Name string `json:"name"`
15+
StartDate string `json:"startdate"`
16+
EndDate string `json:"enddate"`
17+
Capacity string `json:"capacity"`
18+
}
19+
20+
var classes = []Class{}
21+
22+
func addClass(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
23+
24+
body, err := ioutil.ReadAll(r.Body)
25+
if err != nil {
26+
failureResponse(w, err.Error())
27+
return
28+
}
29+
30+
type addClassRequestBody struct {
31+
Name *string `json:"name"`
32+
StartDate *string `json:"startdate"`
33+
EndDate *string `json:"enddate"`
34+
Capacity *string `json:"capacity"`
35+
}
36+
37+
var classBody addClassRequestBody
38+
39+
err = json.Unmarshal(body, &classBody)
40+
if err != nil {
41+
failureResponse(w, err.Error())
42+
return
43+
}
44+
45+
if classBody.Name == nil {
46+
failureResponse(w, `name parameter is not specified or empty`)
47+
return
48+
}
49+
50+
if classBody.StartDate == nil {
51+
failureResponse(w, `startdate parameter is not specified or empty`)
52+
return
53+
}
54+
55+
if classBody.EndDate == nil {
56+
failureResponse(w, `end date parameter is not specified or empty`)
57+
return
58+
}
59+
60+
newClass := Class{
61+
ID: len(classes) + 1,
62+
Name: *classBody.Name,
63+
StartDate: *classBody.StartDate,
64+
EndDate: *classBody.EndDate,
65+
Capacity: *classBody.Capacity,
66+
}
67+
68+
classes = append(classes, newClass)
69+
70+
type Output struct {
71+
Message string `json:"message"`
72+
}
73+
var output Output
74+
output.Message = "Successful Class Creation"
75+
76+
j, err := json.Marshal(output)
77+
if err != nil {
78+
failureResponse(w, `Internal Server Error! `)
79+
return
80+
}
81+
82+
successResponse(w, j)
83+
84+
}
85+
86+
func listClass(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
87+
classes, err := json.Marshal(classes)
88+
89+
if err != nil {
90+
w.WriteHeader(http.StatusInternalServerError)
91+
return
92+
}
93+
94+
w.Write(classes)
95+
}

class_test.go

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package main
2+
3+
import (
4+
"io"
5+
"io/ioutil"
6+
"net/http"
7+
"strings"
8+
"testing"
9+
)
10+
11+
const (
12+
BadRequestCode = 400
13+
SuccessRequestCode = 200
14+
)
15+
16+
type TestStruct struct {
17+
requestBody string
18+
expectedStatusCode int
19+
responseBody string
20+
observedStatusCode int
21+
}
22+
23+
//Inside user_test.go
24+
func TestAddClass(t *testing.T) {
25+
26+
url := "http://localhost:8080/classes_list"
27+
28+
tests := []TestStruct{
29+
{`{"name":"workout101","startdate":"10 Jun 20","enddate" : "20 Jun 20", "capacity": "10"}`, SuccessRequestCode, "", 0},
30+
}
31+
32+
for i, testCase := range tests {
33+
34+
var reader io.Reader
35+
reader = strings.NewReader(testCase.requestBody) //Convert string to reader
36+
37+
request, err := http.NewRequest("GET", url, reader)
38+
39+
res, err := http.DefaultClient.Do(request)
40+
41+
if err != nil {
42+
t.Error(err) //Something is wrong while sending request
43+
}
44+
body, _ := ioutil.ReadAll(res.Body)
45+
46+
tests[i].responseBody = strings.TrimSpace(string(body))
47+
tests[i].observedStatusCode = res.StatusCode
48+
49+
}
50+
51+
DisplayTestCaseResults("addClass", tests, t)
52+
53+
}
54+
55+
func DisplayTestCaseResults(functionalityName string, tests []TestStruct, t *testing.T) {
56+
57+
for _, test := range tests {
58+
59+
if test.observedStatusCode == test.expectedStatusCode {
60+
t.Logf("Passed Case:\n request body : %s \n expectedStatus : %d \n responseBody : %s \n observedStatusCode : %d \n", test.requestBody, test.expectedStatusCode, test.responseBody, test.observedStatusCode)
61+
} else {
62+
t.Errorf("Failed Case:\n request body : %s \n expectedStatus : %d \n responseBody : %s \n observedStatusCode : %d \n", test.requestBody, test.expectedStatusCode, test.responseBody, test.observedStatusCode)
63+
}
64+
}
65+
}

glofox_task

5.51 MB
Binary file not shown.

go.mod

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@ module github.com/AlexSwiss/glofox_task
22

33
go 1.14
44

5-
require github.com/gorilla/mux v1.7.4
5+
require (
6+
github.com/gorilla/mux v1.7.4
7+
github.com/julienschmidt/httprouter v1.3.0
8+
)

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
22
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
3+
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
4+
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=

main.go

+7-70
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,19 @@
11
package main
22

33
import (
4-
"encoding/json"
54
"fmt"
6-
"io/ioutil"
75
"log"
86
"net/http"
97

10-
"github.com/gorilla/mux"
8+
"github.com/julienschmidt/httprouter"
119
)
1210

13-
// Our class model
14-
type class struct {
15-
ID string `json:"ID"`
16-
Name string `json:"name"`
17-
StartDate string `json:"startdate"`
18-
EndDate string `json:"enddate"`
19-
Capacity int `json: "capacty"`
20-
}
21-
22-
type allClasses []class
23-
24-
var classes allClasses
25-
26-
// Dummy database
27-
func initClasses() {
28-
classes = allClasses{
29-
{
30-
ID: "1",
31-
Name: "Pilate",
32-
StartDate: "21 Jun 20",
33-
EndDate: "02 Dec 20",
34-
Capacity: 10,
35-
},
36-
}
37-
}
38-
3911
func main() {
12+
router := httprouter.New()
4013

41-
initClasses()
42-
43-
// Initialize mux router
44-
router := mux.NewRouter().StrictSlash(true)
45-
46-
// API endpoints
47-
router.HandleFunc("/classes", createClass).Methods("POST")
48-
router.HandleFunc("/allclasses", getClasses).Methods("GET")
49-
router.HandleFunc("/allclasses/{id}", getClass).Methods("GET")
50-
51-
log.Fatal(http.ListenAndServe(":8080", router))
52-
}
53-
54-
// create new classes
55-
func createClass(w http.ResponseWriter, r *http.Request) {
56-
var newClass class
57-
reqBody, err := ioutil.ReadAll(r.Body)
58-
if err != nil {
59-
fmt.Fprintln(w, "Kindly enter values with ClassID, Name, StartDate, EndDate and Capacity only")
60-
}
61-
json.Unmarshal(reqBody, &newClass)
62-
classes = append(classes, newClass)
63-
w.WriteHeader(http.StatusCreated)
64-
65-
json.NewEncoder(w).Encode(newClass)
66-
}
67-
68-
// Get all classes
69-
func getClasses(w http.ResponseWriter, r *http.Request) {
70-
json.NewEncoder(w).Encode(classes)
71-
}
72-
73-
// Get single class
74-
func getClass(w http.ResponseWriter, r *http.Request) {
75-
classID := mux.Vars(r)["id"]
76-
77-
for _, singleClass := range classes {
78-
if singleClass.ID == classID {
79-
json.NewEncoder(w).Encode(singleClass)
80-
}
81-
}
14+
router.POST("/classes", addClass)
15+
router.GET("/classes_list", listClass)
16+
port := ":8080"
17+
fmt.Println("Starting server on ", port)
18+
log.Fatal(http.ListenAndServe(port, router))
8219
}

response.go

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"fmt"
7+
"net/http"
8+
)
9+
10+
func failureResponse(w http.ResponseWriter, message string) {
11+
12+
w.Header().Set("Content-Type", "application/json")
13+
w.WriteHeader(http.StatusBadRequest)
14+
15+
json.NewEncoder(w).Encode(struct {
16+
Error string
17+
IsError bool `json:"error"`
18+
}{
19+
Error: message,
20+
IsError: true,
21+
})
22+
}
23+
24+
func successResponse(w http.ResponseWriter, j []byte) {
25+
26+
w.Header().Set("Content-Type", "application/json")
27+
w.WriteHeader(http.StatusOK)
28+
if bytes.Equal(j, []byte("null")) {
29+
fmt.Fprintf(w, "%s", "{}")
30+
} else {
31+
fmt.Fprintf(w, "%s", j)
32+
}
33+
}

0 commit comments

Comments
 (0)