You've already forked golang-saas-starter-kit
mirror of
https://github.com/raseels-repos/golang-saas-starter-kit.git
synced 2025-12-24 00:01:31 +02:00
Basic example cleanup
Rename sales-api to web-api and remove sales-admin
This commit is contained in:
@@ -1,137 +0,0 @@
|
||||
// This program performs administrative tasks for the garage sale service.
|
||||
//
|
||||
// Run it with --cmd keygen or --cmd useradd
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/auth"
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/db"
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/flag"
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/user"
|
||||
"github.com/kelseyhightower/envconfig"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
// =========================================================================
|
||||
// Logging
|
||||
|
||||
log := log.New(os.Stdout, "sales-admin : ", log.LstdFlags|log.Lmicroseconds|log.Lshortfile)
|
||||
|
||||
// =========================================================================
|
||||
// Configuration
|
||||
|
||||
var cfg struct {
|
||||
CMD string `envconfig:"CMD"`
|
||||
DB struct {
|
||||
DialTimeout time.Duration `default:"5s" envconfig:"DIAL_TIMEOUT"`
|
||||
Host string `default:"localhost:27017/gotraining" envconfig:"HOST"`
|
||||
}
|
||||
Auth struct {
|
||||
PrivateKeyFile string `default:"private.pem" envconfig:"PRIVATE_KEY_FILE"`
|
||||
}
|
||||
User struct {
|
||||
Email string
|
||||
Password string
|
||||
}
|
||||
}
|
||||
|
||||
if err := envconfig.Process("SALES", &cfg); err != nil {
|
||||
log.Fatalf("main : Parsing Config : %v", err)
|
||||
}
|
||||
|
||||
if err := flag.Process(&cfg); err != nil {
|
||||
if err != flag.ErrHelp {
|
||||
log.Fatalf("main : Parsing Command Line : %v", err)
|
||||
}
|
||||
return // We displayed help.
|
||||
}
|
||||
|
||||
var err error
|
||||
switch cfg.CMD {
|
||||
case "keygen":
|
||||
err = keygen(cfg.Auth.PrivateKeyFile)
|
||||
case "useradd":
|
||||
err = useradd(cfg.DB.Host, cfg.DB.DialTimeout, cfg.User.Email, cfg.User.Password)
|
||||
default:
|
||||
err = errors.New("Must provide --cmd keygen or --cmd useradd")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// keygen creates an x509 private key for signing auth tokens.
|
||||
func keygen(path string) error {
|
||||
|
||||
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "generating keys")
|
||||
}
|
||||
|
||||
file, err := os.Create(path)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "creating private file")
|
||||
}
|
||||
|
||||
block := pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Bytes: x509.MarshalPKCS1PrivateKey(key),
|
||||
}
|
||||
|
||||
if err := pem.Encode(file, &block); err != nil {
|
||||
return errors.Wrap(err, "encoding to private file")
|
||||
}
|
||||
|
||||
if err := file.Close(); err != nil {
|
||||
return errors.Wrap(err, "closing private file")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func useradd(dbHost string, dbTimeout time.Duration, email, pass string) error {
|
||||
|
||||
dbConn, err := db.New(dbHost, dbTimeout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dbConn.Close()
|
||||
|
||||
if email == "" {
|
||||
return errors.New("Must provide --user_email")
|
||||
}
|
||||
if pass == "" {
|
||||
return errors.New("Must provide --user_password or set the env var SALES_USER_PASSWORD")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
newU := user.NewUser{
|
||||
Email: email,
|
||||
Password: pass,
|
||||
PasswordConfirm: pass,
|
||||
Roles: []string{auth.RoleAdmin, auth.RoleUser},
|
||||
}
|
||||
|
||||
usr, err := user.Create(ctx, dbConn, &newU, time.Now())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("User created with id: %v\n", usr.ID.Hex())
|
||||
return nil
|
||||
}
|
||||
@@ -42,7 +42,7 @@ func main() {
|
||||
ShutdownTimeout time.Duration `default:"5s" envconfig:"SHUTDOWN_TIMEOUT"`
|
||||
}
|
||||
Collect struct {
|
||||
From string `default:"http://sales-api:4000/debug/vars" envconfig:"FROM"`
|
||||
From string `default:"http://web-api:4000/debug/vars" envconfig:"FROM"`
|
||||
}
|
||||
Publish struct {
|
||||
To string `default:"console" envconfig:"TO"`
|
||||
|
||||
@@ -71,7 +71,7 @@ func (z *Zipkin) Publish(ctx context.Context, w http.ResponseWriter, r *http.Req
|
||||
|
||||
// send uses HTTP to send the data to the tracing sidecar for processing.
|
||||
func (z *Zipkin) send(sendBatch []trace.SpanData) error {
|
||||
le, err := newEndpoint("sales-api", z.localHost)
|
||||
le, err := newEndpoint("web-api", z.localHost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -6,48 +6,48 @@ import (
|
||||
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/db"
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/web"
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/product"
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/project"
|
||||
"github.com/pkg/errors"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// Product represents the Product API method handler set.
|
||||
type Product struct {
|
||||
// Project represents the Project API method handler set.
|
||||
type Project struct {
|
||||
MasterDB *db.DB
|
||||
|
||||
// ADD OTHER STATE LIKE THE LOGGER IF NEEDED.
|
||||
}
|
||||
|
||||
// List returns all the existing products in the system.
|
||||
func (p *Product) List(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
ctx, span := trace.StartSpan(ctx, "handlers.Product.List")
|
||||
// List returns all the existing projects in the system.
|
||||
func (p *Project) List(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
ctx, span := trace.StartSpan(ctx, "handlers.Project.List")
|
||||
defer span.End()
|
||||
|
||||
dbConn := p.MasterDB.Copy()
|
||||
defer dbConn.Close()
|
||||
|
||||
products, err := product.List(ctx, dbConn)
|
||||
projects, err := project.List(ctx, dbConn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return web.Respond(ctx, w, products, http.StatusOK)
|
||||
return web.Respond(ctx, w, projects, http.StatusOK)
|
||||
}
|
||||
|
||||
// Retrieve returns the specified product from the system.
|
||||
func (p *Product) Retrieve(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
ctx, span := trace.StartSpan(ctx, "handlers.Product.Retrieve")
|
||||
// Retrieve returns the specified project from the system.
|
||||
func (p *Project) Retrieve(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
ctx, span := trace.StartSpan(ctx, "handlers.Project.Retrieve")
|
||||
defer span.End()
|
||||
|
||||
dbConn := p.MasterDB.Copy()
|
||||
defer dbConn.Close()
|
||||
|
||||
prod, err := product.Retrieve(ctx, dbConn, params["id"])
|
||||
prod, err := project.Retrieve(ctx, dbConn, params["id"])
|
||||
if err != nil {
|
||||
switch err {
|
||||
case product.ErrInvalidID:
|
||||
case project.ErrInvalidID:
|
||||
return web.NewRequestError(err, http.StatusBadRequest)
|
||||
case product.ErrNotFound:
|
||||
case project.ErrNotFound:
|
||||
return web.NewRequestError(err, http.StatusNotFound)
|
||||
default:
|
||||
return errors.Wrapf(err, "ID: %s", params["id"])
|
||||
@@ -57,9 +57,9 @@ func (p *Product) Retrieve(ctx context.Context, w http.ResponseWriter, r *http.R
|
||||
return web.Respond(ctx, w, prod, http.StatusOK)
|
||||
}
|
||||
|
||||
// Create inserts a new product into the system.
|
||||
func (p *Product) Create(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
ctx, span := trace.StartSpan(ctx, "handlers.Product.Create")
|
||||
// Create inserts a new project into the system.
|
||||
func (p *Project) Create(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
ctx, span := trace.StartSpan(ctx, "handlers.Project.Create")
|
||||
defer span.End()
|
||||
|
||||
dbConn := p.MasterDB.Copy()
|
||||
@@ -70,22 +70,22 @@ func (p *Product) Create(ctx context.Context, w http.ResponseWriter, r *http.Req
|
||||
return web.NewShutdownError("web value missing from context")
|
||||
}
|
||||
|
||||
var np product.NewProduct
|
||||
var np project.NewProject
|
||||
if err := web.Decode(r, &np); err != nil {
|
||||
return errors.Wrap(err, "")
|
||||
}
|
||||
|
||||
nUsr, err := product.Create(ctx, dbConn, &np, v.Now)
|
||||
nUsr, err := project.Create(ctx, dbConn, &np, v.Now)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Product: %+v", &np)
|
||||
return errors.Wrapf(err, "Project: %+v", &np)
|
||||
}
|
||||
|
||||
return web.Respond(ctx, w, nUsr, http.StatusCreated)
|
||||
}
|
||||
|
||||
// Update updates the specified product in the system.
|
||||
func (p *Product) Update(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
ctx, span := trace.StartSpan(ctx, "handlers.Product.Update")
|
||||
// Update updates the specified project in the system.
|
||||
func (p *Project) Update(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
ctx, span := trace.StartSpan(ctx, "handlers.Project.Update")
|
||||
defer span.End()
|
||||
|
||||
dbConn := p.MasterDB.Copy()
|
||||
@@ -96,17 +96,17 @@ func (p *Product) Update(ctx context.Context, w http.ResponseWriter, r *http.Req
|
||||
return web.NewShutdownError("web value missing from context")
|
||||
}
|
||||
|
||||
var up product.UpdateProduct
|
||||
var up project.UpdateProject
|
||||
if err := web.Decode(r, &up); err != nil {
|
||||
return errors.Wrap(err, "")
|
||||
}
|
||||
|
||||
err := product.Update(ctx, dbConn, params["id"], up, v.Now)
|
||||
err := project.Update(ctx, dbConn, params["id"], up, v.Now)
|
||||
if err != nil {
|
||||
switch err {
|
||||
case product.ErrInvalidID:
|
||||
case project.ErrInvalidID:
|
||||
return web.NewRequestError(err, http.StatusBadRequest)
|
||||
case product.ErrNotFound:
|
||||
case project.ErrNotFound:
|
||||
return web.NewRequestError(err, http.StatusNotFound)
|
||||
default:
|
||||
return errors.Wrapf(err, "ID: %s Update: %+v", params["id"], up)
|
||||
@@ -116,20 +116,20 @@ func (p *Product) Update(ctx context.Context, w http.ResponseWriter, r *http.Req
|
||||
return web.Respond(ctx, w, nil, http.StatusNoContent)
|
||||
}
|
||||
|
||||
// Delete removes the specified product from the system.
|
||||
func (p *Product) Delete(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
ctx, span := trace.StartSpan(ctx, "handlers.Product.Delete")
|
||||
// Delete removes the specified project from the system.
|
||||
func (p *Project) Delete(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
ctx, span := trace.StartSpan(ctx, "handlers.Project.Delete")
|
||||
defer span.End()
|
||||
|
||||
dbConn := p.MasterDB.Copy()
|
||||
defer dbConn.Close()
|
||||
|
||||
err := product.Delete(ctx, dbConn, params["id"])
|
||||
err := project.Delete(ctx, dbConn, params["id"])
|
||||
if err != nil {
|
||||
switch err {
|
||||
case product.ErrInvalidID:
|
||||
case project.ErrInvalidID:
|
||||
return web.NewRequestError(err, http.StatusBadRequest)
|
||||
case product.ErrNotFound:
|
||||
case project.ErrNotFound:
|
||||
return web.NewRequestError(err, http.StatusNotFound)
|
||||
default:
|
||||
return errors.Wrapf(err, "Id: %s", params["id"])
|
||||
@@ -37,15 +37,15 @@ func API(shutdown chan os.Signal, log *log.Logger, masterDB *db.DB, authenticato
|
||||
// This route is not authenticated
|
||||
app.Handle("GET", "/v1/users/token", u.Token)
|
||||
|
||||
// Register product and sale endpoints.
|
||||
p := Product{
|
||||
// Register project and sale endpoints.
|
||||
p := Project{
|
||||
MasterDB: masterDB,
|
||||
}
|
||||
app.Handle("GET", "/v1/products", p.List, mid.Authenticate(authenticator))
|
||||
app.Handle("POST", "/v1/products", p.Create, mid.Authenticate(authenticator))
|
||||
app.Handle("GET", "/v1/products/:id", p.Retrieve, mid.Authenticate(authenticator))
|
||||
app.Handle("PUT", "/v1/products/:id", p.Update, mid.Authenticate(authenticator))
|
||||
app.Handle("DELETE", "/v1/products/:id", p.Delete, mid.Authenticate(authenticator))
|
||||
app.Handle("GET", "/v1/projects", p.List, mid.Authenticate(authenticator))
|
||||
app.Handle("POST", "/v1/projects", p.Create, mid.Authenticate(authenticator))
|
||||
app.Handle("GET", "/v1/projects/:id", p.Retrieve, mid.Authenticate(authenticator))
|
||||
app.Handle("PUT", "/v1/projects/:id", p.Update, mid.Authenticate(authenticator))
|
||||
app.Handle("DELETE", "/v1/projects/:id", p.Delete, mid.Authenticate(authenticator))
|
||||
|
||||
return app
|
||||
}
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/cmd/sales-api/handlers"
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/cmd/web-api/handlers"
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/auth"
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/db"
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/flag"
|
||||
@@ -45,7 +45,7 @@ func main() {
|
||||
// =========================================================================
|
||||
// Logging
|
||||
|
||||
log := log.New(os.Stdout, "SALES : ", log.LstdFlags|log.Lmicroseconds|log.Lshortfile)
|
||||
log := log.New(os.Stdout, "WEB_APP : ", log.LstdFlags|log.Lmicroseconds|log.Lshortfile)
|
||||
|
||||
// =========================================================================
|
||||
// Configuration
|
||||
@@ -75,7 +75,7 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
if err := envconfig.Process("SALES", &cfg); err != nil {
|
||||
if err := envconfig.Process("WEB_APP", &cfg); err != nil {
|
||||
log.Fatalf("main : Parsing Config : %v", err)
|
||||
}
|
||||
|
||||
@@ -10,38 +10,38 @@ import (
|
||||
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/tests"
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/web"
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/product"
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/project"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
)
|
||||
|
||||
// TestProducts is the entry point for the products
|
||||
func TestProducts(t *testing.T) {
|
||||
// TestProjects is the entry point for the projects
|
||||
func TestProjects(t *testing.T) {
|
||||
defer tests.Recover(t)
|
||||
|
||||
t.Run("getProducts200Empty", getProducts200Empty)
|
||||
t.Run("postProduct400", postProduct400)
|
||||
t.Run("postProduct401", postProduct401)
|
||||
t.Run("getProduct404", getProduct404)
|
||||
t.Run("getProduct400", getProduct400)
|
||||
t.Run("deleteProduct404", deleteProduct404)
|
||||
t.Run("putProduct404", putProduct404)
|
||||
t.Run("crudProducts", crudProduct)
|
||||
t.Run("getProjects200Empty", getProjects200Empty)
|
||||
t.Run("postProject400", postProject400)
|
||||
t.Run("postProject401", postProject401)
|
||||
t.Run("getProject404", getProject404)
|
||||
t.Run("getProject400", getProject400)
|
||||
t.Run("deleteProject404", deleteProject404)
|
||||
t.Run("putProject404", putProject404)
|
||||
t.Run("crudProjects", crudProject)
|
||||
}
|
||||
|
||||
// getProducts200Empty validates an empty products list can be retrieved with the endpoint.
|
||||
func getProducts200Empty(t *testing.T) {
|
||||
r := httptest.NewRequest("GET", "/v1/products", nil)
|
||||
// getProjects200Empty validates an empty projects list can be retrieved with the endpoint.
|
||||
func getProjects200Empty(t *testing.T) {
|
||||
r := httptest.NewRequest("GET", "/v1/projects", nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
r.Header.Set("Authorization", userAuthorization)
|
||||
|
||||
a.ServeHTTP(w, r)
|
||||
|
||||
t.Log("Given the need to fetch an empty list of products with the products endpoint.")
|
||||
t.Log("Given the need to fetch an empty list of projects with the projects endpoint.")
|
||||
{
|
||||
t.Log("\tTest 0:\tWhen fetching an empty product list.")
|
||||
t.Log("\tTest 0:\tWhen fetching an empty project list.")
|
||||
{
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("\t%s\tShould receive a status code of 200 for the response : %v", tests.Failed, w.Code)
|
||||
@@ -60,19 +60,19 @@ func getProducts200Empty(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// postProduct400 validates a product can't be created with the endpoint
|
||||
// unless a valid product document is submitted.
|
||||
func postProduct400(t *testing.T) {
|
||||
r := httptest.NewRequest("POST", "/v1/products", strings.NewReader(`{}`))
|
||||
// postProject400 validates a project can't be created with the endpoint
|
||||
// unless a valid project document is submitted.
|
||||
func postProject400(t *testing.T) {
|
||||
r := httptest.NewRequest("POST", "/v1/projects", strings.NewReader(`{}`))
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
r.Header.Set("Authorization", userAuthorization)
|
||||
|
||||
a.ServeHTTP(w, r)
|
||||
|
||||
t.Log("Given the need to validate a new product can't be created with an invalid document.")
|
||||
t.Log("Given the need to validate a new project can't be created with an invalid document.")
|
||||
{
|
||||
t.Log("\tTest 0:\tWhen using an incomplete product value.")
|
||||
t.Log("\tTest 0:\tWhen using an incomplete project value.")
|
||||
{
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Fatalf("\t%s\tShould receive a status code of 400 for the response : %v", tests.Failed, w.Code)
|
||||
@@ -110,10 +110,10 @@ func postProduct400(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// postProduct401 validates a product can't be created with the endpoint
|
||||
// postProject401 validates a project can't be created with the endpoint
|
||||
// unless the user is authenticated
|
||||
func postProduct401(t *testing.T) {
|
||||
np := product.NewProduct{
|
||||
func postProject401(t *testing.T) {
|
||||
np := project.NewProject{
|
||||
Name: "Comic Books",
|
||||
Cost: 25,
|
||||
Quantity: 60,
|
||||
@@ -124,16 +124,16 @@ func postProduct401(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
r := httptest.NewRequest("POST", "/v1/products", bytes.NewBuffer(body))
|
||||
r := httptest.NewRequest("POST", "/v1/projects", bytes.NewBuffer(body))
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
// Not setting an authorization header
|
||||
|
||||
a.ServeHTTP(w, r)
|
||||
|
||||
t.Log("Given the need to validate a new product can't be created with an invalid document.")
|
||||
t.Log("Given the need to validate a new project can't be created with an invalid document.")
|
||||
{
|
||||
t.Log("\tTest 0:\tWhen using an incomplete product value.")
|
||||
t.Log("\tTest 0:\tWhen using an incomplete project value.")
|
||||
{
|
||||
if w.Code != http.StatusUnauthorized {
|
||||
t.Fatalf("\t%s\tShould receive a status code of 401 for the response : %v", tests.Failed, w.Code)
|
||||
@@ -143,20 +143,20 @@ func postProduct401(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// getProduct400 validates a product request for a malformed id.
|
||||
func getProduct400(t *testing.T) {
|
||||
// getProject400 validates a project request for a malformed id.
|
||||
func getProject400(t *testing.T) {
|
||||
id := "12345"
|
||||
|
||||
r := httptest.NewRequest("GET", "/v1/products/"+id, nil)
|
||||
r := httptest.NewRequest("GET", "/v1/projects/"+id, nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
r.Header.Set("Authorization", userAuthorization)
|
||||
|
||||
a.ServeHTTP(w, r)
|
||||
|
||||
t.Log("Given the need to validate getting a product with a malformed id.")
|
||||
t.Log("Given the need to validate getting a project with a malformed id.")
|
||||
{
|
||||
t.Logf("\tTest 0:\tWhen using the new product %s.", id)
|
||||
t.Logf("\tTest 0:\tWhen using the new project %s.", id)
|
||||
{
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Fatalf("\t%s\tShould receive a status code of 400 for the response : %v", tests.Failed, w.Code)
|
||||
@@ -175,20 +175,20 @@ func getProduct400(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// getProduct404 validates a product request for a product that does not exist with the endpoint.
|
||||
func getProduct404(t *testing.T) {
|
||||
// getProject404 validates a project request for a project that does not exist with the endpoint.
|
||||
func getProject404(t *testing.T) {
|
||||
id := bson.NewObjectId().Hex()
|
||||
|
||||
r := httptest.NewRequest("GET", "/v1/products/"+id, nil)
|
||||
r := httptest.NewRequest("GET", "/v1/projects/"+id, nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
r.Header.Set("Authorization", userAuthorization)
|
||||
|
||||
a.ServeHTTP(w, r)
|
||||
|
||||
t.Log("Given the need to validate getting a product with an unknown id.")
|
||||
t.Log("Given the need to validate getting a project with an unknown id.")
|
||||
{
|
||||
t.Logf("\tTest 0:\tWhen using the new product %s.", id)
|
||||
t.Logf("\tTest 0:\tWhen using the new project %s.", id)
|
||||
{
|
||||
if w.Code != http.StatusNotFound {
|
||||
t.Fatalf("\t%s\tShould receive a status code of 404 for the response : %v", tests.Failed, w.Code)
|
||||
@@ -207,20 +207,20 @@ func getProduct404(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// deleteProduct404 validates deleting a product that does not exist.
|
||||
func deleteProduct404(t *testing.T) {
|
||||
// deleteProject404 validates deleting a project that does not exist.
|
||||
func deleteProject404(t *testing.T) {
|
||||
id := bson.NewObjectId().Hex()
|
||||
|
||||
r := httptest.NewRequest("DELETE", "/v1/products/"+id, nil)
|
||||
r := httptest.NewRequest("DELETE", "/v1/projects/"+id, nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
r.Header.Set("Authorization", userAuthorization)
|
||||
|
||||
a.ServeHTTP(w, r)
|
||||
|
||||
t.Log("Given the need to validate deleting a product that does not exist.")
|
||||
t.Log("Given the need to validate deleting a project that does not exist.")
|
||||
{
|
||||
t.Logf("\tTest 0:\tWhen using the new product %s.", id)
|
||||
t.Logf("\tTest 0:\tWhen using the new project %s.", id)
|
||||
{
|
||||
if w.Code != http.StatusNotFound {
|
||||
t.Fatalf("\t%s\tShould receive a status code of 404 for the response : %v", tests.Failed, w.Code)
|
||||
@@ -239,9 +239,9 @@ func deleteProduct404(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// putProduct404 validates updating a product that does not exist.
|
||||
func putProduct404(t *testing.T) {
|
||||
up := product.UpdateProduct{
|
||||
// putProject404 validates updating a project that does not exist.
|
||||
func putProject404(t *testing.T) {
|
||||
up := project.UpdateProject{
|
||||
Name: tests.StringPointer("Nonexistent"),
|
||||
}
|
||||
|
||||
@@ -252,16 +252,16 @@ func putProduct404(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
r := httptest.NewRequest("PUT", "/v1/products/"+id, bytes.NewBuffer(body))
|
||||
r := httptest.NewRequest("PUT", "/v1/projects/"+id, bytes.NewBuffer(body))
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
r.Header.Set("Authorization", userAuthorization)
|
||||
|
||||
a.ServeHTTP(w, r)
|
||||
|
||||
t.Log("Given the need to validate updating a product that does not exist.")
|
||||
t.Log("Given the need to validate updating a project that does not exist.")
|
||||
{
|
||||
t.Logf("\tTest 0:\tWhen using the new product %s.", id)
|
||||
t.Logf("\tTest 0:\tWhen using the new project %s.", id)
|
||||
{
|
||||
if w.Code != http.StatusNotFound {
|
||||
t.Fatalf("\t%s\tShould receive a status code of 404 for the response : %v", tests.Failed, w.Code)
|
||||
@@ -280,18 +280,18 @@ func putProduct404(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// crudProduct performs a complete test of CRUD against the api.
|
||||
func crudProduct(t *testing.T) {
|
||||
p := postProduct201(t)
|
||||
defer deleteProduct204(t, p.ID.Hex())
|
||||
// crudProject performs a complete test of CRUD against the api.
|
||||
func crudProject(t *testing.T) {
|
||||
p := postProject201(t)
|
||||
defer deleteProject204(t, p.ID.Hex())
|
||||
|
||||
getProduct200(t, p.ID.Hex())
|
||||
putProduct204(t, p.ID.Hex())
|
||||
getProject200(t, p.ID.Hex())
|
||||
putProject204(t, p.ID.Hex())
|
||||
}
|
||||
|
||||
// postProduct201 validates a product can be created with the endpoint.
|
||||
func postProduct201(t *testing.T) product.Product {
|
||||
np := product.NewProduct{
|
||||
// postProject201 validates a project can be created with the endpoint.
|
||||
func postProject201(t *testing.T) project.Project {
|
||||
np := project.NewProject{
|
||||
Name: "Comic Books",
|
||||
Cost: 25,
|
||||
Quantity: 60,
|
||||
@@ -302,7 +302,7 @@ func postProduct201(t *testing.T) product.Product {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
r := httptest.NewRequest("POST", "/v1/products", bytes.NewBuffer(body))
|
||||
r := httptest.NewRequest("POST", "/v1/projects", bytes.NewBuffer(body))
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
r.Header.Set("Authorization", userAuthorization)
|
||||
@@ -310,11 +310,11 @@ func postProduct201(t *testing.T) product.Product {
|
||||
a.ServeHTTP(w, r)
|
||||
|
||||
// p is the value we will return.
|
||||
var p product.Product
|
||||
var p project.Project
|
||||
|
||||
t.Log("Given the need to create a new product with the products endpoint.")
|
||||
t.Log("Given the need to create a new project with the projects endpoint.")
|
||||
{
|
||||
t.Log("\tTest 0:\tWhen using the declared product value.")
|
||||
t.Log("\tTest 0:\tWhen using the declared project value.")
|
||||
{
|
||||
if w.Code != http.StatusCreated {
|
||||
t.Fatalf("\t%s\tShould receive a status code of 201 for the response : %v", tests.Failed, w.Code)
|
||||
@@ -342,18 +342,18 @@ func postProduct201(t *testing.T) product.Product {
|
||||
return p
|
||||
}
|
||||
|
||||
// deleteProduct200 validates deleting a product that does exist.
|
||||
func deleteProduct204(t *testing.T, id string) {
|
||||
r := httptest.NewRequest("DELETE", "/v1/products/"+id, nil)
|
||||
// deleteProject200 validates deleting a project that does exist.
|
||||
func deleteProject204(t *testing.T, id string) {
|
||||
r := httptest.NewRequest("DELETE", "/v1/projects/"+id, nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
r.Header.Set("Authorization", userAuthorization)
|
||||
|
||||
a.ServeHTTP(w, r)
|
||||
|
||||
t.Log("Given the need to validate deleting a product that does exist.")
|
||||
t.Log("Given the need to validate deleting a project that does exist.")
|
||||
{
|
||||
t.Logf("\tTest 0:\tWhen using the new product %s.", id)
|
||||
t.Logf("\tTest 0:\tWhen using the new project %s.", id)
|
||||
{
|
||||
if w.Code != http.StatusNoContent {
|
||||
t.Fatalf("\t%s\tShould receive a status code of 204 for the response : %v", tests.Failed, w.Code)
|
||||
@@ -363,25 +363,25 @@ func deleteProduct204(t *testing.T, id string) {
|
||||
}
|
||||
}
|
||||
|
||||
// getProduct200 validates a product request for an existing id.
|
||||
func getProduct200(t *testing.T, id string) {
|
||||
r := httptest.NewRequest("GET", "/v1/products/"+id, nil)
|
||||
// getProject200 validates a project request for an existing id.
|
||||
func getProject200(t *testing.T, id string) {
|
||||
r := httptest.NewRequest("GET", "/v1/projects/"+id, nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
r.Header.Set("Authorization", userAuthorization)
|
||||
|
||||
a.ServeHTTP(w, r)
|
||||
|
||||
t.Log("Given the need to validate getting a product that exists.")
|
||||
t.Log("Given the need to validate getting a project that exists.")
|
||||
{
|
||||
t.Logf("\tTest 0:\tWhen using the new product %s.", id)
|
||||
t.Logf("\tTest 0:\tWhen using the new project %s.", id)
|
||||
{
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("\t%s\tShould receive a status code of 200 for the response : %v", tests.Failed, w.Code)
|
||||
}
|
||||
t.Logf("\t%s\tShould receive a status code of 200 for the response.", tests.Success)
|
||||
|
||||
var p product.Product
|
||||
var p project.Project
|
||||
if err := json.NewDecoder(w.Body).Decode(&p); err != nil {
|
||||
t.Fatalf("\t%s\tShould be able to unmarshal the response : %v", tests.Failed, err)
|
||||
}
|
||||
@@ -402,26 +402,26 @@ func getProduct200(t *testing.T, id string) {
|
||||
}
|
||||
}
|
||||
|
||||
// putProduct204 validates updating a product that does exist.
|
||||
func putProduct204(t *testing.T, id string) {
|
||||
// putProject204 validates updating a project that does exist.
|
||||
func putProject204(t *testing.T, id string) {
|
||||
body := `{"name": "Graphic Novels", "cost": 100}`
|
||||
r := httptest.NewRequest("PUT", "/v1/products/"+id, strings.NewReader(body))
|
||||
r := httptest.NewRequest("PUT", "/v1/projects/"+id, strings.NewReader(body))
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
r.Header.Set("Authorization", userAuthorization)
|
||||
|
||||
a.ServeHTTP(w, r)
|
||||
|
||||
t.Log("Given the need to update a product with the products endpoint.")
|
||||
t.Log("Given the need to update a project with the projects endpoint.")
|
||||
{
|
||||
t.Log("\tTest 0:\tWhen using the modified product value.")
|
||||
t.Log("\tTest 0:\tWhen using the modified project value.")
|
||||
{
|
||||
if w.Code != http.StatusNoContent {
|
||||
t.Fatalf("\t%s\tShould receive a status code of 204 for the response : %v", tests.Failed, w.Code)
|
||||
}
|
||||
t.Logf("\t%s\tShould receive a status code of 204 for the response.", tests.Success)
|
||||
|
||||
r = httptest.NewRequest("GET", "/v1/products/"+id, nil)
|
||||
r = httptest.NewRequest("GET", "/v1/projects/"+id, nil)
|
||||
w = httptest.NewRecorder()
|
||||
|
||||
r.Header.Set("Authorization", userAuthorization)
|
||||
@@ -433,7 +433,7 @@ func putProduct204(t *testing.T, id string) {
|
||||
}
|
||||
t.Logf("\t%s\tShould receive a status code of 200 for the retrieve.", tests.Success)
|
||||
|
||||
var ru product.Product
|
||||
var ru project.Project
|
||||
if err := json.NewDecoder(w.Body).Decode(&ru); err != nil {
|
||||
t.Fatalf("\t%s\tShould be able to unmarshal the response : %v", tests.Failed, err)
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/cmd/sales-api/handlers"
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/cmd/web-api/handlers"
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/auth"
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/tests"
|
||||
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/user"
|
||||
Reference in New Issue
Block a user