func TestUnmarshalResource(t *testing.T) { tests := []struct { source interface{} destination interface{} errorExpected bool }{ { // 0 users["1"], &user{}, false, }, { // 1 books["1"], &book{}, false, }, } for n, test := range tests { payload, err := MarshalResource(test.source, options[0]) tchek.UnintendedError(err) _, err = UnmarshalResource(payload, options[0], test.destination) tchek.ErrorExpected(t, n, test.errorExpected, err) tchek.AreShallowEqual(t, n, test.source, test.destination) } }
func TestBasicRequests(t *testing.T) { testApp := NewApp() testApp.UseFunc(Recoverer) testApp.UseFunc(URLParser) testApp.RegisterModel(user{}) testApp.RegisterModel(comment{}) testApp.Get("/users", func(ctx context.Context, w ResponseWriter) context.Context { w.Write([]byte("users")) return ctx }, GatePublic) testApp.Get("/users/:id", func(ctx context.Context, w ResponseWriter) context.Context { r := GetRequest(ctx) w.Write([]byte("user " + r.ResID)) return ctx }, GatePublic) testApp.Get("/users/:id/relationships/comments", func(ctx context.Context, w ResponseWriter) context.Context { r := GetRequest(ctx) w.Write([]byte("user " + r.ResID + " " + r.ResRel + " " + r.ResRelName)) return ctx }, GatePublic) testApp.Get("/users/:id/comments", func(ctx context.Context, w ResponseWriter) context.Context { r := GetRequest(ctx) w.Write([]byte("user " + r.ResID + " " + r.ResRel + " " + r.ResRelName)) return ctx }, GatePublic) testApp.Get("/comments", func(ctx context.Context, w ResponseWriter) context.Context { w.Write([]byte("comments")) return ctx }, GatePublic) server := httptest.NewServer(testApp) tests := []struct { url string expectedStatusCode int expectedBody string }{ { // 0 url: "/users", expectedStatusCode: http.StatusOK, expectedBody: "users", }, { // 1 url: "/users/abc123", expectedStatusCode: http.StatusOK, expectedBody: "user abc123", }, { // 2 url: "/users/abc123/relationships/comments", expectedStatusCode: http.StatusOK, expectedBody: "user abc123 self comments", }, { // 3 url: "/users/abc123/comments", expectedStatusCode: http.StatusOK, expectedBody: "user abc123 related comments", }, } for i, test := range tests { res := tchek.MakeRequest(server, "GET", test.url, "") fmt.Printf("\n") var body []byte body, err := ioutil.ReadAll(res.Body) tchek.UnintendedError(err) tchek.AreEqual(t, i, test.expectedStatusCode, res.StatusCode) tchek.AreEqual(t, i, test.expectedBody, string(body)) } }
func TestUnmarshalPayload(t *testing.T) { test := ` { "data": { "id": "345", "type": "users", "attributes": { "first-name": "Tim", "last-name": "John", "age": 34, "created": "2009-11-10T23:00:00Z" }, "relationships": { "best-friend": { "links": { "self": "http://example.com/articles/345/relationships/best-friend", "related": "http://example.com/articles/345/best-friend" }, "data": { "type": "users", "id": "3" } }, "articles": { "links": { "self": "http://example.com/articles/345/relationships/articles", "related": "http://example.com/articles/345/articles" }, "data": [{ "type": "articles", "id": "24" }, { "type": "articles", "id": "25" }, { "type": "articles", "id": "28" }, { "type": "articles", "id": "30" }] } } }, "included": [{ "type": "users", "id": "3", "attributes": { "first-name": "Tim", "last-name": "John", "age": 34, "created": "20011-29-12T18:20:00Z" }, "links": { "self": "http://example.com/users/3" } }] }` log.Printf("%s", test) payload, err := Unmarshal([]byte(test)) tchek.UnintendedError(err) user := user{ID: "123", Type: "unknowntype", FirstName: "Bob", LastName: "Smith", Age: 32} log.Printf("BEFORE: %v", user) // payload.Load(&user) err = payload.Load(&user) tchek.UnintendedError(err) log.Printf("AFTER: %v", user) log.Printf(" BestFriend: #%s (%s)", user.BestFriend.ID, user.BestFriend.Type) log.Printf(" BestFriend's name: %s %s", user.BestFriend.FirstName, user.BestFriend.LastName) log.Printf(" Articles: %d", len(user.Articles)) for _, article := range user.Articles { log.Printf(" --- #%s (%s)", article.ID, article.Type) } }
func TestJWTParser(t *testing.T) { testApp := NewApp() testApp.UseFunc(Recoverer) testApp.UseFunc(URLParser) testApp.UseFunc(JWTParser) testApp.Get("/jwt", func(ctx context.Context, w ResponseWriter) context.Context { r := ctx.Value(key("id")).(string) for _, s := range ctx.Value(key("groups")).([]string) { r += s } w.Write([]byte(r)) return ctx }, GatePublic) server := httptest.NewServer(testApp) tests := []struct { id string groups []string expectation string }{ { // 0 id: "abc123", groups: []string{"admin", "developer", "founder"}, expectation: "abc123admindeveloperfounder", }, { // 1 id: "abc123", groups: []string{}, expectation: "abc123", }, { // 2 id: "", groups: []string{"public"}, expectation: "public", }, { // 3 id: "", groups: []string{}, expectation: "", }, } for i, test := range tests { token, err := cybele.GenerateJWT(map[string]interface{}{ "id": test.id, "groups": test.groups, }) tchek.UnintendedError(err) res := tchek.MakeRequest(server, "GET", "/jwt", token) fmt.Printf("\n") var body []byte body, err = ioutil.ReadAll(res.Body) tchek.UnintendedError(err) tchek.AreEqual(t, i, test.expectation, string(body)) } }
func TestURLParser(t *testing.T) { testApp := NewApp() testApp.UseFunc(URLParser) testApp.UseFunc(func(ctx context.Context, w ResponseWriter, next CtxHandlerFunc) context.Context { normURL := GetRequest(ctx).NormalizedURL w.Write([]byte(fmt.Sprintf("%v", normURL))) next(ctx, w) return ctx }) server := httptest.NewServer(testApp) tests := []struct { url string expectedStatusCode int expectedBody string }{ { // 0 url: "/", expectedStatusCode: http.StatusBadRequest, expectedBody: "", }, { // 1 url: "/type/1/relationships/rel", expectedStatusCode: http.StatusOK, expectedBody: "/type/1/relationships/rel", }, { // 2 url: "/type/1/relationships/rel/", expectedStatusCode: http.StatusOK, expectedBody: "/type/1/relationships/rel", }, { // 3 url: "/this/is/an/invalid/request", expectedStatusCode: http.StatusBadRequest, expectedBody: "", }, { // 4 url: "/request//invalid", expectedStatusCode: http.StatusBadRequest, expectedBody: "", }, { // 5 url: "/groups/1/users?fields[user]=id,name,age", expectedStatusCode: http.StatusOK, expectedBody: "/groups/1/users?fields[user]=age,id,name", }, { // 6 url: "/boards?filters[lang]=fr", expectedStatusCode: http.StatusOK, expectedBody: "/boards?filters[lang]=fr", }, { // 7 url: "/users?sort=xp,age", expectedStatusCode: http.StatusOK, expectedBody: "/users?sort=xp,age", }, { // 8 url: "/users?page[size]=10&page[number]=1", expectedStatusCode: http.StatusOK, expectedBody: "/users?page[number]=1&page[size]=10", }, { // 9 url: "/users?fields[user]=id,name&filters[group]=15&sort=age,-xp,name&page[size]=10&page[number]=3", expectedStatusCode: http.StatusOK, expectedBody: "/users?fields[user]=id,name&filters[group]=15&page[number]=3&page[size]=10&sort=age,-xp,name", }, } for i, test := range tests { res := tchek.MakeRequest(server, "GET", test.url, "") fmt.Printf("\n") var body []byte body, err := ioutil.ReadAll(res.Body) tchek.UnintendedError(err) tchek.AreEqual(t, i, test.expectedStatusCode, res.StatusCode) tchek.AreEqual(t, i, test.expectedBody, string(body)) } }
func TestAuthorizer(t *testing.T) { testApp := NewApp() testApp.UseFunc(Recoverer) testApp.UseFunc(URLParser) testApp.UseFunc(JWTParser) testApp.UseFunc(Authorizer) testApp.Get("/users", func(ctx context.Context, w ResponseWriter) context.Context { return ctx }, GateAdmin) testApp.Get("/comments", func(ctx context.Context, w ResponseWriter) context.Context { return ctx }, GatePublic) testApp.Post("/comments", func(ctx context.Context, w ResponseWriter) context.Context { return ctx }, GateNotBannedUser) server := httptest.NewServer(testApp) tests := []struct { method string url string id string groups []string expectedStatusCode int }{ { // 0 method: "GET", url: "/comments", id: "", groups: []string{}, expectedStatusCode: http.StatusOK, }, { // 1 method: "GET", url: "/comments", id: "abc123", groups: []string{"banned"}, expectedStatusCode: http.StatusOK, }, { // 2 method: "POST", url: "/comments", id: "abc123", groups: []string{"banned"}, expectedStatusCode: http.StatusForbidden, }, { // 4 method: "GET", url: "/users", id: "abc123", groups: []string{"admin"}, expectedStatusCode: http.StatusOK, }, } for i, test := range tests { var err error token := "" if test.id != "" { token, err = cybele.GenerateJWT(map[string]interface{}{ "id": test.id, "groups": test.groups, }) tchek.UnintendedError(err) } res := tchek.MakeRequest(server, test.method, test.url, token) fmt.Printf("\n") tchek.AreEqual(t, i, test.expectedStatusCode, res.StatusCode) } }