func TestGetCollectionRequestTimeout(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("collection", res.GetCollection(func(r res.CollectionRequest) {
			r.Timeout(time.Second * 42)
			r.NotFound()
		}))
	}, func(s *restest.Session) {
		req := s.Get("test.collection")
		req.Response().AssertRawPayload([]byte(`timeout:"42000"`))
		req.Response().AssertError(res.ErrNotFound)
	})
}
Test that Timeout sends the pre-response with timeout on a collection get request.
package test
import (
	"errors"
	"testing"
	"time"
	"github.com/jirenius/go-res"
	"github.com/jirenius/go-res/restest"
)
func TestGetModel(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("model.foo", res.GetModel(func(r res.ModelRequest) {
			restest.AssertEqualJSON(t, "r.ForValue()", r.ForValue(), false)
			restest.AssertEqualJSON(t, "r.ResourceType()", r.ResourceType(), res.TypeModel)
			r.Model(mock.Model)
		}))
	}, func(s *restest.Session) {
		s.Get("test.model.foo").
			Response().
			AssertModel(mock.Model)
		s.Get("test.model").
			Response().
			AssertError(res.ErrNotFound)
		s.Get("test.model.foo.bar").
			Response().
			AssertError(res.ErrNotFound)
	})
}
func TestGetCollection(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("collection.foo", res.GetCollection(func(r res.CollectionRequest) {
			restest.AssertEqualJSON(t, "r.ForValue()", r.ForValue(), false)
			restest.AssertEqualJSON(t, "r.ResourceType()", r.ResourceType(), res.TypeCollection)
			r.Collection(mock.Collection)
		}))
	}, func(s *restest.Session) {
		s.Get("test.collection.foo").
			Response().
			AssertCollection(mock.Collection)
		s.Get("test.collection").
			Response().
			AssertError(res.ErrNotFound)
		s.Get("test.collection.foo.bar").
			Response().
			AssertError(res.ErrNotFound)
	})
}
func TestGetResource(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("model.foo", res.GetResource(func(r res.GetRequest) {
			restest.AssertEqualJSON(t, "r.ForValue()", r.ForValue(), false)
			restest.AssertEqualJSON(t, "r.ResourceType()", r.ResourceType(), res.TypeUnset)
			r.Model(mock.Model)
		}))
	}, func(s *restest.Session) {
		s.Get("test.model.foo").
			Response().
			AssertModel(mock.Model)
	})
}
func TestGetResourceTypedModel(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("model.foo",
			res.Model,
			res.GetResource(func(r res.GetRequest) {
				restest.AssertEqualJSON(t, "r.ForValue()", r.ForValue(), false)
				restest.AssertEqualJSON(t, "r.ResourceType()", r.ResourceType(), res.TypeModel)
				r.Model(mock.Model)
			}),
		)
	}, func(s *restest.Session) {
		s.Get("test.model.foo").
			Response().
			AssertModel(mock.Model)
	})
}
func TestGetResourceTypedCollection(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("collection.foo",
			res.Collection,
			res.GetResource(func(r res.GetRequest) {
				restest.AssertEqualJSON(t, "r.ForValue()", r.ForValue(), false)
				restest.AssertEqualJSON(t, "r.ResourceType()", r.ResourceType(), res.TypeCollection)
				r.Collection(mock.Collection)
			}),
		)
	}, func(s *restest.Session) {
		s.Get("test.collection.foo").
			Response().
			AssertCollection(mock.Collection)
	})
}
func TestGetModelNotFound(t *testing.T) {
	isCalled := false
	runTest(t, func(s *res.Service) {
		s.Handle("model", res.GetModel(func(r res.ModelRequest) {
			isCalled = true
			r.NotFound()
		}))
	}, func(s *restest.Session) {
		s.Get("test.model").
			Response().
			AssertError(res.ErrNotFound)
		if !isCalled {
			t.Fatalf("expected handler to be called, but it wasn't")
		}
	})
}
func TestGetCollectionNotFound(t *testing.T) {
	isCalled := false
	runTest(t, func(s *res.Service) {
		s.Handle("collection", res.GetCollection(func(r res.CollectionRequest) {
			isCalled = true
			r.NotFound()
		}))
	}, func(s *restest.Session) {
		s.Get("test.collection").
			Response().
			AssertError(res.ErrNotFound)
		if !isCalled {
			t.Fatalf("expected handler to be called, but it wasn't")
		}
	})
}
func TestGetModelError(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("model", res.GetModel(func(r res.ModelRequest) {
			r.Error(res.ErrMethodNotFound)
		}))
	}, func(s *restest.Session) {
		for i := 0; i < 10; i++ {
			s.Get("test.model").
				Response().
				AssertError(res.ErrMethodNotFound)
		}
	})
}
func TestGetCollectionError(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("collection", res.GetCollection(func(r res.CollectionRequest) {
			r.Error(res.ErrMethodNotFound)
		}))
	}, func(s *restest.Session) {
		for i := 0; i < 10; i++ {
			s.Get("test.collection").
				Response().
				AssertError(res.ErrMethodNotFound)
		}
	})
}
func TestModelInvalidQuery_EmptyMessage(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("model", res.GetModel(func(r res.ModelRequest) {
			r.InvalidQuery("")
		}))
	}, func(s *restest.Session) {
		s.Get("test.model?zoo=baz&foo=bar").
			Response().
			AssertError(res.ErrInvalidQuery)
	})
}
func TestModelInvalidQuery_CustomMessage(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("model", res.GetModel(func(r res.ModelRequest) {
			r.InvalidQuery(mock.ErrorMessage)
		}))
	}, func(s *restest.Session) {
		s.Get("test.model?zoo=baz&foo=bar").
			Response().
			AssertError(&res.Error{
				Code:    res.CodeInvalidQuery,
				Message: mock.ErrorMessage,
			})
	})
}
func TestCollectionInvalidQuery_EmptyMessage(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("collection", res.GetCollection(func(r res.CollectionRequest) {
			r.InvalidQuery("")
		}))
	}, func(s *restest.Session) {
		s.Get("test.collection?zoo=baz&foo=bar").
			Response().
			AssertError(res.ErrInvalidQuery)
	})
}
func TestCollectionInvalidQuery_CustomMessage(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("collection", res.GetCollection(func(r res.CollectionRequest) {
			r.InvalidQuery(mock.ErrorMessage)
		}))
	}, func(s *restest.Session) {
		s.Get("test.collection?zoo=baz&foo=bar").
			Response().
			AssertError(&res.Error{
				Code:    res.CodeInvalidQuery,
				Message: mock.ErrorMessage,
			})
	})
}
func TestPanicOnGetModel(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("model", res.GetModel(func(r res.ModelRequest) {
			panic("panic")
		}))
	}, func(s *restest.Session) {
		for i := 0; i < 10; i++ {
			s.Get("test.model").
				Response().
				AssertErrorCode("system.internalError")
		}
	})
}
func TestPanicWithErrorOnGetModel(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("model", res.GetModel(func(r res.ModelRequest) {
			panic(res.ErrMethodNotFound)
		}))
	}, func(s *restest.Session) {
		s.Get("test.model").
			Response().
			AssertError(res.ErrMethodNotFound)
	})
}
func TestPanicWithOsErrorOnGetModel(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("model", res.GetModel(func(r res.ModelRequest) {
			panic(errors.New("panic"))
		}))
	}, func(s *restest.Session) {
		s.Get("test.model").
			Response().
			AssertErrorCode(res.CodeInternalError)
	})
}
func TestPanicWithGenericValueOnGetModel(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("model", res.GetModel(func(r res.ModelRequest) {
			panic(42)
		}))
	}, func(s *restest.Session) {
		for i := 0; i < 10; i++ {
			s.Get("test.model").
				Response().
				AssertErrorCode("system.internalError")
		}
	})
}
func TestPanicOnGetCollection(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("collection", res.GetCollection(func(r res.CollectionRequest) {
			panic("panic")
		}))
	}, func(s *restest.Session) {
		for i := 0; i < 10; i++ {
			s.Get("test.collection").
				Response().
				AssertErrorCode("system.internalError")
		}
	})
}
func TestPanicWithErrorOnGetCollection(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("collection", res.GetCollection(func(r res.CollectionRequest) {
			panic(res.ErrMethodNotFound)
		}))
	}, func(s *restest.Session) {
		s.Get("test.collection").
			Response().
			AssertError(res.ErrMethodNotFound)
	})
}
func TestPanicWithOsErrorOnGetCollection(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("collection", res.GetCollection(func(r res.CollectionRequest) {
			panic(errors.New("panic"))
		}))
	}, func(s *restest.Session) {
		s.Get("test.collection").
			Response().
			AssertErrorCode(res.CodeInternalError)
	})
}
func TestPanicWithGenericValueOnGetCollection(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("collection", res.GetCollection(func(r res.CollectionRequest) {
			panic(42)
		}))
	}, func(s *restest.Session) {
		s.Get("test.collection").
			Response().
			AssertErrorCode(res.CodeInternalError)
	})
}
func TestMultipleGetModel(t *testing.T) {
	const requestCount = 100
	runTest(t, func(s *res.Service) {
		s.Handle("model", res.GetModel(func(r res.ModelRequest) {
			r.Model(mock.Model)
		}))
	}, func(s *restest.Session) {
		reqs := make([]*restest.NATSRequest, requestCount)
		for i := 0; i < requestCount; i++ {
			reqs[i] = s.Get("test.model")
		}
		for _, req := range reqs {
			req.Response().AssertModel(mock.Model)
		}
	})
}
func TestMultipleGetCollection(t *testing.T) {
	const requestCount = 100
	runTest(t, func(s *res.Service) {
		s.Handle("collection", res.GetCollection(func(r res.CollectionRequest) {
			r.Collection(mock.Collection)
		}))
	}, func(s *restest.Session) {
		reqs := make([]*restest.NATSRequest, requestCount)
		for i := 0; i < requestCount; i++ {
			reqs[i] = s.Get("test.collection")
		}
		for _, req := range reqs {
			req.Response().AssertCollection(mock.Collection)
		}
	})
}
func TestMultipleGetDifferentResources(t *testing.T) {
	const requestCount = 50
	runTest(t, func(s *res.Service) {
		s.Handle("model", res.GetModel(func(r res.ModelRequest) {
			r.Model(mock.Model)
		}))
		s.Handle("collection", res.GetCollection(func(r res.CollectionRequest) {
			r.Collection(mock.Collection)
		}))
	}, func(s *restest.Session) {
		minbs := make([]string, requestCount)
		cinbs := make([]string, requestCount)
		for i := 0; i < requestCount; i++ {
			minbs[i] = s.RequestRaw("get.test.model", nil)
			cinbs[i] = s.RequestRaw("get.test.collection", nil)
		}
		var mi, ci int
		for i := 0; i < requestCount*2; i++ {
			m := s.GetMsg()
			switch {
			case mi < requestCount && minbs[mi] == m.Subject:
				m.AssertModel(mock.Model)
				mi++
			case ci < requestCount && cinbs[ci] == m.Subject:
				m.AssertCollection(mock.Collection)
				ci++
			default:
				t.Fatalf("expected message subject to be a for a collection or model request, but got %#v", m.Subject)
			}
		}
	})
}
func TestGetModelRequestTimeout(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("model", res.GetModel(func(r res.ModelRequest) {
			r.Timeout(time.Second * 42)
			r.NotFound()
		}))
	}, func(s *restest.Session) {
		req := s.Get("test.model")
		req.Response().AssertRawPayload([]byte(`timeout:"42000"`))
		req.Response().AssertError(res.ErrNotFound)
	})
}
func TestGetModelRequestTimeoutWithDurationLessThanZero(t *testing.T) {
	runTest(t, func(s *res.Service) {
		s.Handle("model", res.GetModel(func(r res.ModelRequest) {
			panicked := true
			defer func() {
				if !panicked {
					t.Errorf("expected Timeout to panic, but nothing happened")
				}
			}()
			r.Timeout(-time.Millisecond * 10)
			r.NotFound()
			panicked = false
		}))
	}, func(s *restest.Session) {
		s.Get("test.model").
			Response().
			AssertErrorCode("system.internalError")
	})
}