Example #1
0
func TestHandlerGetItem(t *testing.T) {
	s := mem.NewHandler()
	s.Insert(context.TODO(), []*resource.Item{
		{ID: "1", Payload: map[string]interface{}{"id": "1"}},
		{ID: "2", Payload: map[string]interface{}{"id": "2"}},
		{ID: "3", Payload: map[string]interface{}{"id": "3"}},
	})
	index := resource.NewIndex()
	test := index.Bind("test", schema.Schema{}, s, resource.DefaultConf)
	r, _ := http.NewRequest("GET", "/test/2", nil)
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "test",
				Field:    "id",
				Value:    "2",
				Resource: test,
			},
		},
	}
	status, headers, body := itemGet(context.TODO(), r, rm)
	assert.Equal(t, http.StatusOK, status)
	assert.Nil(t, headers)
	if assert.IsType(t, body, &resource.Item{}) {
		i := body.(*resource.Item)
		assert.Equal(t, "2", i.ID)
	}
}
Example #2
0
func TestHandlerDeleteItemInvalidFilter(t *testing.T) {
	index := resource.NewIndex()
	test := index.Bind("test", schema.Schema{}, nil, resource.DefaultConf)
	r, _ := http.NewRequest("DELETE", "/test/2", nil)
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "test",
				Field:    "id",
				Value:    "2",
				Resource: test,
			},
		},
		Params: url.Values{
			"filter": []string{"invalid"},
		},
	}
	status, headers, body := itemDelete(context.TODO(), r, rm)
	assert.Equal(t, 422, status)
	assert.Nil(t, headers)
	if assert.IsType(t, body, &Error{}) {
		err := body.(*Error)
		assert.Equal(t, 422, err.Code)
		assert.Equal(t, "Invalid `filter` parameter: must be valid JSON", err.Message)
	}
}
Example #3
0
func TestHandlerGetItemInvalidIfModifiedSince(t *testing.T) {
	s := mem.NewHandler()
	now := time.Now()
	s.Insert(context.TODO(), []*resource.Item{
		{ID: "1", Updated: now, Payload: map[string]interface{}{"id": "1"}},
		{ID: "2", Updated: now, Payload: map[string]interface{}{"id": "2"}},
		{ID: "3", Updated: now, Payload: map[string]interface{}{"id": "3"}},
	})
	index := resource.NewIndex()
	test := index.Bind("test", schema.Schema{}, s, resource.DefaultConf)
	r, _ := http.NewRequest("GET", "/test/2", nil)
	r.Header.Set("If-Modified-Since", "invalid date")
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "test",
				Field:    "id",
				Value:    "2",
				Resource: test,
			},
		},
	}
	status, headers, body := itemGet(context.TODO(), r, rm)
	assert.Equal(t, http.StatusBadRequest, status)
	assert.Nil(t, headers)
	if assert.IsType(t, body, &Error{}) {
		err := body.(*Error)
		assert.Equal(t, http.StatusBadRequest, err.Code)
		assert.Equal(t, "Invalid If-Modified-Since header", err.Message)
	}
}
Example #4
0
func TestHandlerGetItemInvalidLookupSort(t *testing.T) {
	index := resource.NewIndex()
	test := index.Bind("test", schema.Schema{}, nil, resource.DefaultConf)
	r, _ := http.NewRequest("GET", "/test", nil)
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "test",
				Field:    "id",
				Value:    "1",
				Resource: test,
			},
		},
		Params: url.Values{
			"sort": []string{"invalid"},
		},
	}
	status, headers, body := itemGet(context.TODO(), r, rm)
	assert.Equal(t, 422, status)
	assert.Nil(t, headers)
	if assert.IsType(t, body, &Error{}) {
		err := body.(*Error)
		assert.Equal(t, 422, err.Code)
		assert.Equal(t, "Invalid `sort` paramter: invalid sort field: invalid", err.Message)
	}
}
Example #5
0
func TestHandlerGetItemModifiedDontMatch(t *testing.T) {
	s := mem.NewHandler()
	now := time.Now()
	yesterday := now.Add(-24 * time.Hour)
	s.Insert(context.TODO(), []*resource.Item{
		{ID: "1", Updated: now, Payload: map[string]interface{}{"id": "1"}},
		{ID: "2", Updated: now, Payload: map[string]interface{}{"id": "2"}},
		{ID: "3", Updated: now, Payload: map[string]interface{}{"id": "3"}},
	})
	index := resource.NewIndex()
	test := index.Bind("test", schema.Schema{}, s, resource.DefaultConf)
	r, _ := http.NewRequest("GET", "/test/2", nil)
	r.Header.Set("If-Modified-Since", yesterday.Format(time.RFC1123))
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "test",
				Field:    "id",
				Value:    "2",
				Resource: test,
			},
		},
	}
	status, headers, body := itemGet(context.TODO(), r, rm)
	assert.Equal(t, http.StatusOK, status)
	assert.Nil(t, headers)
	if assert.IsType(t, body, &resource.Item{}) {
		i := body.(*resource.Item)
		assert.Equal(t, "2", i.ID)
	}
}
Example #6
0
func TestHandlerGetItemEtagMatch(t *testing.T) {
	s := mem.NewHandler()
	s.Insert(context.TODO(), []*resource.Item{
		{ID: "1", ETag: "a", Payload: map[string]interface{}{"id": "1"}},
		{ID: "2", ETag: "a", Payload: map[string]interface{}{"id": "2"}},
		{ID: "3", ETag: "a", Payload: map[string]interface{}{"id": "3"}},
	})
	index := resource.NewIndex()
	test := index.Bind("test", schema.Schema{}, s, resource.DefaultConf)
	r, _ := http.NewRequest("GET", "/test/2", nil)
	r.Header.Set("If-None-Match", "a")
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "test",
				Field:    "id",
				Value:    "2",
				Resource: test,
			},
		},
	}
	status, headers, body := itemGet(context.TODO(), r, rm)
	assert.Equal(t, http.StatusNotModified, status)
	assert.Nil(t, headers)
	assert.Nil(t, body)
}
Example #7
0
func main() {
	index := resource.NewIndex()

	users := index.Bind("users", resource.New(models.UserSchema, mem.NewHandler(), resource.Conf{
		AllowedModes:           resource.ReadWrite,
		PaginationDefaultLimit: 50,
	}))

	models.SetAuthUserResource(users)

	index.Bind("auth", resource.New(models.AuthSchema, mem.NewHandler(), resource.Conf{
		AllowedModes: []resource.Mode{resource.Create},
	}))

	api, err := rest.NewHandler(index)
	if err != nil {
		log.Fatal(err)
	}

	http.Handle("/", api)

	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal(err)
	}
}
Example #8
0
func TestHandlerDeleteItemEtag(t *testing.T) {
	s := mem.NewHandler()
	s.Insert(context.TODO(), []*resource.Item{
		{ID: "1", ETag: "a", Payload: map[string]interface{}{"id": "1"}},
	})
	index := resource.NewIndex()
	test := index.Bind("test", schema.Schema{
		Fields: schema.Fields{"foo": {Filterable: true}},
	}, s, resource.DefaultConf)
	r, _ := http.NewRequest("DELETE", "/test/2", nil)
	r.Header.Set("If-Match", "a")
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "test",
				Field:    "id",
				Value:    "1",
				Resource: test,
			},
		},
	}
	status, headers, body := itemDelete(context.TODO(), r, rm)
	assert.Equal(t, http.StatusNoContent, status)
	assert.Nil(t, headers)
	assert.Nil(t, body)

	l, err := s.Find(context.TODO(), resource.NewLookup(), 1, -1)
	assert.NoError(t, err)
	assert.Len(t, l.Items, 0)
}
Example #9
0
func TestHandlerPostListWithReferenceNoRouter(t *testing.T) {
	s := mem.NewHandler()
	index := resource.NewIndex()
	index.Bind("foo", schema.Schema{Fields: schema.Fields{"id": {}}}, s, resource.DefaultConf)
	bar := index.Bind("bar", schema.Schema{Fields: schema.Fields{
		"id":  {},
		"foo": {Validator: &schema.Reference{Path: "foo"}},
	}}, s, resource.DefaultConf)
	r, _ := http.NewRequest("POST", "/bar", bytes.NewBufferString(`{"id": "1", "foo": "nonexisting"}`))
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "bar",
				Resource: bar,
			},
		},
	}
	status, _, body := listPost(context.TODO(), r, rm)
	assert.Equal(t, http.StatusInternalServerError, status)
	if assert.IsType(t, &Error{}, body) {
		err := body.(*Error)
		assert.Equal(t, http.StatusInternalServerError, err.Code)
		assert.Equal(t, "Router not available in context", err.Message)
	}
}
Example #10
0
func TestNewHandler(t *testing.T) {
	i := resource.NewIndex()
	h, err := NewHandler(i)
	assert.NoError(t, err)
	assert.Equal(t, DefaultResponseSender{}, h.ResponseSender)
	assert.Equal(t, i, h.index)
}
Example #11
0
func TestHandlerPatchItemReplaceInvalidModifiedSinceDate(t *testing.T) {
	index := resource.NewIndex()
	s := mem.NewHandler()
	now := time.Now()
	s.Insert(context.TODO(), []*resource.Item{
		{ID: "1", Updated: now, Payload: map[string]interface{}{"id": "1"}},
	})
	test := index.Bind("test", schema.Schema{Fields: schema.Fields{"id": {}}}, s, resource.DefaultConf)
	r, _ := http.NewRequest("PATCH", "/test/1", bytes.NewBufferString(`{"id": "1"}`))
	r.Header.Set("If-Unmodified-Since", "invalid date")
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "test",
				Field:    "id",
				Value:    "1",
				Resource: test,
			},
		},
	}
	status, _, body := itemPatch(context.TODO(), r, rm)
	assert.Equal(t, http.StatusBadRequest, status)
	if assert.IsType(t, body, &Error{}) {
		err := body.(*Error)
		assert.Equal(t, http.StatusBadRequest, err.Code)
		assert.Equal(t, "Invalid If-Unmodified-Since header", err.Message)
	}
}
Example #12
0
func TestHandlerPatchItemNoStorage(t *testing.T) {
	index := resource.NewIndex()
	test := index.Bind("test", schema.Schema{Fields: schema.Fields{"id": {}}}, nil, resource.Conf{
		AllowedModes: []resource.Mode{resource.Replace},
	})
	r, _ := http.NewRequest("PATCH", "/test/1", bytes.NewBufferString(`{}`))
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "test",
				Field:    "id",
				Value:    "1",
				Resource: test,
			},
		},
	}
	status, headers, body := itemPatch(context.TODO(), r, rm)
	assert.Equal(t, http.StatusNotImplemented, status)
	assert.Nil(t, headers)
	if assert.IsType(t, body, &Error{}) {
		err := body.(*Error)
		assert.Equal(t, http.StatusNotImplemented, err.Code)
		assert.Equal(t, "No Storage Defined", err.Message)
	}
}
Example #13
0
func main() {
	// Create a REST API resource index
	index := resource.NewIndex()

	// Add a resource on /users[/:user_id]
	users := index.Bind("users", user, mem.NewHandler(), resource.Conf{
		// We allow all REST methods
		// (rest.ReadWrite is a shortcut for []resource.Mode{resource.Create, resource.Read, resource.Update, resource.Delete, resource,List})
		AllowedModes: resource.ReadWrite,
	})

	// Bind a sub resource on /users/:user_id/posts[/:post_id]
	// and reference the user on each post using the "user" field of the posts resource.
	posts := users.Bind("posts", "user", post, mem.NewHandler(), resource.Conf{
		// Posts can only be read, created and deleted, not updated
		AllowedModes: []resource.Mode{resource.Read, resource.List, resource.Create, resource.Delete},
	})

	// Add a friendly alias to public posts
	// (equivalent to /users/:user_id/posts?filter={"published":true})
	posts.Alias("public", url.Values{"filter": []string{"{\"published\":true}"}})

	// Create API HTTP handler for the resource graph
	api, err := rest.NewHandler(index)
	if err != nil {
		log.Fatalf("Invalid API configuration: %s", err)
	}

	c := alice.New()

	// Add close notifier handler so context is cancelled when the client closes
	// the connection
	// c.Append(xhandler.CloseHandler)

	// Add timeout handler
	// c.Append(xhandler.TimeoutHandler(2 * time.Second))

	// Install a logger (see https://github.com/rs/xlog)
	c = c.Append(xlog.NewHandler(xlog.Config{}))
	resource.LoggerLevel = resource.LogLevelDebug
	resource.Logger = func(ctx context.Context, level resource.LogLevel, msg string, fields map[string]interface{}) {
		xlog.FromContext(ctx).OutputF(xlog.Level(level), 2, msg, fields)
	}

	// Log API access
	c = c.Append(xaccess.NewHandler())

	// Add CORS support with passthrough option on so rest-layer can still
	// handle OPTIONS method
	c = c.Append(cors.New(cors.Options{OptionsPassthrough: true}).Handler)

	// Bind the API under /api/ path
	http.Handle("/api/", http.StripPrefix("/api/", c.Then(api)))

	// Serve it
	log.Print("Serving API on http://localhost:8080")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal(err)
	}
}
Example #14
0
func TestHandlerPatchItemCannotChangeID(t *testing.T) {
	index := resource.NewIndex()
	s := mem.NewHandler()
	s.Insert(context.TODO(), []*resource.Item{
		{ID: "1", Payload: map[string]interface{}{"id": "1"}},
	})
	test := index.Bind("test", schema.Schema{Fields: schema.Fields{"id": {}}}, s, resource.DefaultConf)
	r, _ := http.NewRequest("PATCH", "/test/1", bytes.NewBufferString(`{"id": "2"}`))
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "test",
				Field:    "id",
				Value:    "1",
				Resource: test,
			},
		},
	}
	status, headers, body := itemPatch(context.TODO(), r, rm)
	assert.Equal(t, 422, status)
	assert.Nil(t, headers)
	if assert.IsType(t, body, &Error{}) {
		err := body.(*Error)
		assert.Equal(t, 422, err.Code)
		assert.Equal(t, "Cannot change document ID", err.Message)
	}
}
Example #15
0
func Example() {
	session, err := mgo.Dial("")
	if err != nil {
		log.Fatalf("Can't connect to MongoDB: %s", err)
	}
	db := "test_rest_layer"

	index := resource.NewIndex()

	users := index.Bind("users", user, mongo.NewHandler(session, db, "users"), resource.Conf{
		AllowedModes: resource.ReadWrite,
	})

	users.Bind("posts", "user", post, mongo.NewHandler(session, db, "posts"), resource.Conf{
		AllowedModes: resource.ReadWrite,
	})

	api, err := rest.NewHandler(index)
	if err != nil {
		log.Fatalf("Invalid API configuration: %s", err)
	}

	http.Handle("/", cors.New(cors.Options{OptionsPassthrough: true}).Handler(api))

	log.Print("Serving API on http://localhost:8080")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal(err)
	}
}
Example #16
0
func TestHandlerPatchItemFound(t *testing.T) {
	index := resource.NewIndex()
	s := mem.NewHandler()
	s.Insert(context.TODO(), []*resource.Item{
		{ID: "1", Payload: map[string]interface{}{"id": "1", "foo": "bar"}},
		{ID: "2", Payload: map[string]interface{}{"id": "2", "foo": "bar"}},
		{ID: "3", Payload: map[string]interface{}{"id": "3", "foo": "bar"}},
	})
	test := index.Bind("test", schema.Schema{Fields: schema.Fields{
		"id":  {},
		"foo": {},
	}}, s, resource.DefaultConf)
	r, _ := http.NewRequest("PATCH", "/test/2", bytes.NewBufferString(`{"id": "2", "foo": "baz"}`))
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "test",
				Field:    "id",
				Value:    "2",
				Resource: test,
			},
		},
	}
	status, headers, body := itemPatch(context.TODO(), r, rm)
	assert.Equal(t, http.StatusOK, status)
	assert.Nil(t, headers)
	if assert.IsType(t, body, &resource.Item{}) {
		i := body.(*resource.Item)
		assert.Equal(t, "2", i.ID)
		assert.Equal(t, map[string]interface{}{"id": "2", "foo": "baz"}, i.Payload)
	}
}
Example #17
0
func TestHandlerPostListWithReference(t *testing.T) {
	s := mem.NewHandler()
	s.Insert(context.Background(), []*resource.Item{{ID: "ref", Payload: map[string]interface{}{"id": "ref"}}})
	index := resource.NewIndex()
	index.Bind("foo", schema.Schema{Fields: schema.Fields{"id": {}}}, s, resource.DefaultConf)
	bar := index.Bind("bar", schema.Schema{Fields: schema.Fields{
		"id":  {},
		"foo": {Validator: &schema.Reference{Path: "foo"}},
	}}, s, resource.DefaultConf)
	r, _ := http.NewRequest("POST", "/bar", bytes.NewBufferString(`{"id": "1", "foo": "ref"}`))
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "bar",
				Resource: bar,
			},
		},
	}
	ctx := contextWithIndex(context.Background(), index)
	status, _, body := listPost(ctx, r, rm)
	assert.Equal(t, http.StatusCreated, status)
	if assert.IsType(t, &resource.Item{}, body) {
		item := body.(*resource.Item)
		assert.Equal(t, "1", item.ID)
	}
}
Example #18
0
func TestHandlerPostListWithSubSchemaReferenceNotFound(t *testing.T) {
	s := mem.NewHandler()
	s.Insert(context.Background(), []*resource.Item{{ID: "ref", Payload: map[string]interface{}{"id": "ref"}}})
	index := resource.NewIndex()
	index.Bind("foo", schema.Schema{Fields: schema.Fields{"id": {}}}, s, resource.DefaultConf)
	bar := index.Bind("bar", schema.Schema{Fields: schema.Fields{
		"id": {},
		"sub": {
			Schema: &schema.Schema{
				Fields: schema.Fields{
					"foo": {Validator: &schema.Reference{Path: "foo"}},
				},
			},
		},
	}}, s, resource.DefaultConf)
	r, _ := http.NewRequest("POST", "/bar", bytes.NewBufferString(`{"id": "1", "sub": {"foo": "notfound"}}`))
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "bar",
				Resource: bar,
			},
		},
	}
	ctx := contextWithIndex(context.Background(), index)
	status, _, body := listPost(ctx, r, rm)
	assert.Equal(t, http.StatusNotFound, status)
	if assert.IsType(t, &Error{}, body) {
		err := body.(*Error)
		assert.Equal(t, http.StatusNotFound, err.Code)
		assert.Equal(t, "Resource reference not found for field `foo'", err.Message)
	}
}
Example #19
0
func TestHandlerGetListInvalidPage(t *testing.T) {
	index := resource.NewIndex()
	test := index.Bind("test", schema.Schema{}, nil, resource.DefaultConf)
	r, _ := http.NewRequest("GET", "/test", nil)
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "test",
				Resource: test,
			},
		},
		Params: url.Values{
			"page": []string{"invalid"},
		},
	}
	status, headers, body := listGet(context.TODO(), r, rm)
	assert.Equal(t, 422, status)
	assert.Nil(t, headers)
	if assert.IsType(t, body, &Error{}) {
		err := body.(*Error)
		assert.Equal(t, 422, err.Code)
		assert.Equal(t, "Invalid `page` parameter", err.Message)
	}

	rm.Params.Set("page", "-1")

	status, headers, body = listGet(context.TODO(), r, rm)
	assert.Equal(t, 422, status)
	assert.Nil(t, headers)
	if assert.IsType(t, body, &Error{}) {
		err := body.(*Error)
		assert.Equal(t, 422, err.Code)
		assert.Equal(t, "Invalid `page` parameter", err.Message)
	}
}
Example #20
0
func TestHandlerPostListWithReferenceOtherError(t *testing.T) {
	s := mem.NewHandler()
	index := resource.NewIndex()
	index.Bind("foo", schema.Schema{Fields: schema.Fields{"id": {}}}, nil, resource.DefaultConf)
	bar := index.Bind("bar", schema.Schema{Fields: schema.Fields{
		"id":  {},
		"foo": {Validator: &schema.Reference{Path: "foo"}},
	}}, s, resource.DefaultConf)
	r, _ := http.NewRequest("POST", "/bar", bytes.NewBufferString(`{"id": "1", "foo": "1"}`))
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "bar",
				Resource: bar,
			},
		},
	}
	ctx := contextWithIndex(context.Background(), index)
	status, _, body := listPost(ctx, r, rm)
	assert.Equal(t, http.StatusInternalServerError, status)
	if assert.IsType(t, &Error{}, body) {
		err := body.(*Error)
		assert.Equal(t, http.StatusInternalServerError, err.Code)
		assert.Equal(t, "Error fetching resource reference for field `foo': No Storage Defined", err.Message)
	}
}
Example #21
0
func TestHandlerPostListNew(t *testing.T) {
	index := resource.NewIndex()
	s := mem.NewHandler()
	test := index.Bind("test", schema.Schema{Fields: schema.Fields{
		"id":  {},
		"foo": {},
	}}, s, resource.DefaultConf)
	r, _ := http.NewRequest("POST", "/test", bytes.NewBufferString(`{"id": "2", "foo": "baz"}`))
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "test",
				Resource: test,
			},
		},
	}
	status, headers, body := listPost(context.TODO(), r, rm)
	assert.Equal(t, http.StatusCreated, status)
	assert.Equal(t, http.Header{"Content-Location": []string{"/test/2"}}, headers)
	if assert.IsType(t, body, &resource.Item{}) {
		i := body.(*resource.Item)
		assert.Equal(t, "2", i.ID)
		assert.Equal(t, map[string]interface{}{"id": "2", "foo": "baz"}, i.Payload)
	}
}
Example #22
0
func TestHandlerPutItemReplaceModeNotAllowed(t *testing.T) {
	index := resource.NewIndex()
	s := mem.NewHandler()
	s.Insert(context.TODO(), []*resource.Item{
		{ID: "1", Payload: map[string]interface{}{"id": "1"}},
	})
	test := index.Bind("test", schema.Schema{Fields: schema.Fields{"id": {}}}, s, resource.Conf{
		AllowedModes: []resource.Mode{resource.Create},
	})
	r, _ := http.NewRequest("PUT", "/test/1", bytes.NewBufferString(`{}`))
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "test",
				Field:    "id",
				Value:    "1",
				Resource: test,
			},
		},
	}
	status, headers, body := itemPut(context.TODO(), r, rm)
	assert.Equal(t, http.StatusMethodNotAllowed, status)
	assert.Nil(t, headers)
	if assert.IsType(t, body, &Error{}) {
		err := body.(*Error)
		assert.Equal(t, http.StatusMethodNotAllowed, err.Code)
		assert.Equal(t, "Invalid method", err.Message)
	}
}
Example #23
0
func TestHandlerPutItemInvalidField(t *testing.T) {
	index := resource.NewIndex()
	test := index.Bind("test", schema.Schema{Fields: schema.Fields{"id": {}}}, mem.NewHandler(), resource.DefaultConf)
	r, _ := http.NewRequest("PUT", "/test/2", bytes.NewBufferString(`{"foo": "baz"}`))
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "test",
				Field:    "id",
				Value:    "2",
				Resource: test,
			},
		},
	}
	status, headers, body := itemPut(context.TODO(), r, rm)
	assert.Equal(t, 422, status)
	assert.Nil(t, headers)
	if assert.IsType(t, body, &Error{}) {
		err := body.(*Error)
		assert.Equal(t, 422, err.Code)
		assert.Equal(t, "Document contains error(s)", err.Message)
		assert.Equal(t, map[string][]interface{}{
			"foo": []interface{}{"invalid field"}}, err.Issues)
	}
}
Example #24
0
func TestHandlerPatchItemInvalidLookupFields(t *testing.T) {
	index := resource.NewIndex()
	test := index.Bind("test", schema.Schema{}, nil, resource.DefaultConf)
	r, _ := http.NewRequest("PATCH", "/test/2", bytes.NewBufferString("{}"))
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "test",
				Field:    "id",
				Value:    "2",
				Resource: test,
			},
		},
		Params: url.Values{
			"fields": []string{"invalid"},
		},
	}
	status, headers, body := itemPatch(context.TODO(), r, rm)
	assert.Equal(t, 422, status)
	assert.Nil(t, headers)
	if assert.IsType(t, body, &Error{}) {
		err := body.(*Error)
		assert.Equal(t, 422, err.Code)
		assert.Equal(t, "Invalid `fields` paramter: invalid: unknown field", err.Message)
	}
}
Example #25
0
func TestHandlerDeleteList(t *testing.T) {
	s := mem.NewHandler()
	s.Insert(context.TODO(), []*resource.Item{
		{ID: "1", Payload: map[string]interface{}{}},
		{ID: "2", Payload: map[string]interface{}{}},
		{ID: "3", Payload: map[string]interface{}{}},
		{ID: "4", Payload: map[string]interface{}{}},
		{ID: "5", Payload: map[string]interface{}{}},
	})
	index := resource.NewIndex()
	test := index.Bind("test", schema.Schema{}, s, resource.DefaultConf)
	r, _ := http.NewRequest("DELETE", "/test", bytes.NewBufferString("{}"))
	rm := &RouteMatch{
		ResourcePath: []*ResourcePathComponent{
			&ResourcePathComponent{
				Name:     "test",
				Resource: test,
			},
		},
	}
	status, headers, body := listDelete(context.TODO(), r, rm)
	assert.Equal(t, http.StatusNoContent, status)
	assert.Equal(t, http.Header{"X-Total": []string{"5"}}, headers)
	assert.Nil(t, body)

	l, err := s.Find(context.TODO(), resource.NewLookup(), 1, -1)
	assert.NoError(t, err)
	assert.Len(t, l.Items, 0)
}
Example #26
0
func TestHandlerServeHTTPNotFound(t *testing.T) {
	h, _ := NewHandler(resource.NewIndex())
	w := httptest.NewRecorder()
	r, _ := http.NewRequest("GET", "/", nil)
	h.ServeHTTP(w, r)
	assert.Equal(t, 404, w.Code)
	b, _ := ioutil.ReadAll(w.Body)
	assert.Equal(t, "{\"code\":404,\"message\":\"Resource Not Found\"}", string(b))
}
Example #27
0
func TestHandlerServeHTTPNotFound(t *testing.T) {
	h, _ := NewHandler(resource.NewIndex())
	w := newRecorder()
	defer w.Close()
	u, _ := url.ParseRequestURI("/")
	h.ServeHTTP(w, &http.Request{Method: "GET", URL: u})
	assert.Equal(t, 404, w.Code)
	b, _ := ioutil.ReadAll(w.Body)
	assert.Equal(t, "{\"code\":404,\"message\":\"Resource Not Found\"}", string(b))
}
Example #28
0
func TestHandlerServeHTTPInvalidTimeout(t *testing.T) {
	h, _ := NewHandler(resource.NewIndex())
	w := newRecorder()
	defer w.Close()
	u, _ := url.ParseRequestURI("/?timeout=invalid")
	h.ServeHTTP(w, &http.Request{Method: "GET", URL: u})
	assert.Equal(t, 422, w.Code)
	b, _ := ioutil.ReadAll(w.Body)
	assert.Equal(t, "{\"code\":422,\"message\":\"Cannot parse timeout parameter: time: invalid duration invalid\"}", string(b))
}
Example #29
0
func TestHandlerGetContext(t *testing.T) {
	var c context.Context
	var err *Error
	h, _ := NewHandler(resource.NewIndex())
	w := newRecorder()
	defer w.Close()
	c, err = h.getContext(w, &http.Request{URL: &url.URL{}})
	assert.Nil(t, err)
	_, ok := c.Deadline()
	assert.False(t, ok)
}
Example #30
0
func TestHandlerServeHTTPGetNotFoundItem(t *testing.T) {
	i := resource.NewIndex()
	i.Bind("foo", schema.Schema{}, mem.NewHandler(), resource.DefaultConf)
	h, _ := NewHandler(i)
	w := httptest.NewRecorder()
	r, _ := http.NewRequest("GET", "/foo/1", nil)
	h.ServeHTTP(w, r)
	assert.Equal(t, 404, w.Code)
	b, _ := ioutil.ReadAll(w.Body)
	assert.Equal(t, "{\"code\":404,\"message\":\"Not Found\"}", string(b))
}