1
0
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:
Lee Brown
2019-05-16 18:05:39 -04:00
parent e6453bae45
commit b40d389579
25 changed files with 331 additions and 578 deletions

View File

@@ -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
}

View File

@@ -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"`

View File

@@ -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
}

View File

@@ -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"])

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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"