Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weos 1245 #40

Merged
merged 17 commits into from
Jan 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
210 changes: 187 additions & 23 deletions end2end_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ import (
"testing"
"time"

"github.com/wepala/weos-service/utils"

"github.com/cucumber/godog"
"github.com/labstack/echo/v4"
ds "github.com/ompluscator/dynamic-struct"
api "github.com/wepala/weos-service/controllers/rest"
"github.com/wepala/weos-service/utils"
"gorm.io/gorm"
)

Expand All @@ -31,9 +30,11 @@ var errors error
var buf bytes.Buffer
var payload ContentType
var rec *httptest.ResponseRecorder
var header http.Header
var db *sql.DB
var requests map[string]map[string]interface{}
var currScreen string
var contentTypeID map[string]bool

type User struct {
Name string
Expand All @@ -57,6 +58,7 @@ type ContentType struct {

func InitializeSuite(ctx *godog.TestSuiteContext) {
requests = map[string]map[string]interface{}{}
contentTypeID = map[string]bool{}
Developer = &User{}
e = echo.New()
e.Logger.SetOutput(&buf)
Expand Down Expand Up @@ -105,8 +107,10 @@ components:

func reset(ctx context.Context, sc *godog.Scenario) (context.Context, error) {
requests = map[string]map[string]interface{}{}
contentTypeID = map[string]bool{}
Developer = &User{}
errors = nil
header = make(http.Header)
rec = httptest.NewRecorder()
os.Remove("e2e.db")
var err error
Expand Down Expand Up @@ -281,8 +285,32 @@ func anErrorShouldBeReturned() error {
return nil
}

func blogsInTheApi(arg1 *godog.Table) error {
return godog.ErrPending
func blogsInTheApi(details *godog.Table) error {

head := details.Rows[0].Cells

for i := 1; i < len(details.Rows); i++ {
req := make(map[string]interface{})
for n, cell := range details.Rows[i].Cells {
req[head[n].Value] = cell.Value
}
reqBytes, _ := json.Marshal(req)
body := bytes.NewReader(reqBytes)
var request *http.Request

request = httptest.NewRequest("POST", "/blog", body)

request = request.WithContext(context.TODO())
header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
request.Header = header
request.Close = true
rec = httptest.NewRecorder()
e.ServeHTTP(rec, request)
if rec.Code != http.StatusCreated {
return fmt.Errorf("expected the status to be %d got %d", http.StatusCreated, rec.Code)
}
}
return nil
}

func entersInTheField(userName, value, field string) error {
Expand Down Expand Up @@ -322,8 +350,14 @@ func theIsCreated(contentType string, details *godog.Table) error {
}

contentEntity := map[string]interface{}{}
idEtag, seqNoEtag := api.SplitEtag(rec.Result().Header.Get("Etag"))
result := API.Application.DB().Table(strings.Title(contentType)).Find(&contentEntity, "weos_id = ?", idEtag, "sequence_no = ?", seqNoEtag)
var result *gorm.DB
//ETag would help with this
for key, value := range compare {
result = API.Application.DB().Table(strings.Title(contentType)).Find(&contentEntity, key+" = ?", value)
if contentEntity != nil {
break
}
}

if contentEntity == nil {
return fmt.Errorf("unexpected error finding content type in db")
Expand All @@ -339,6 +373,7 @@ func theIsCreated(contentType string, details *godog.Table) error {
}
}

contentTypeID[strings.ToLower(contentType)] = true
return nil
}

Expand All @@ -351,9 +386,15 @@ func theIsSubmitted(contentType string) error {

reqBytes, _ := json.Marshal(req)
body := bytes.NewReader(reqBytes)
request := httptest.NewRequest("POST", "/"+strings.ToLower(contentType), body)
var request *http.Request
if strings.Contains(currScreen, "create") {
request = httptest.NewRequest("POST", "/"+strings.ToLower(contentType), body)
} else if strings.Contains(currScreen, "update") {
request = httptest.NewRequest("PUT", "/"+strings.ToLower(contentType), body)
}
request = request.WithContext(context.TODO())
request.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
request.Header = header
request.Close = true
rec = httptest.NewRecorder()
e.ServeHTTP(rec, request)
Expand All @@ -362,11 +403,9 @@ func theIsSubmitted(contentType string) error {

func theShouldHaveAnId(contentType string) error {

idEtag, _ := api.SplitEtag(rec.Result().Header.Get("Etag"))
if idEtag == "" {
return fmt.Errorf("expected the "+contentType+" to have an ID, got %s", idEtag)
if !contentTypeID[strings.ToLower(contentType)] {
return fmt.Errorf("expected the " + contentType + " to have an ID")
}

return nil
}

Expand Down Expand Up @@ -448,19 +487,138 @@ func aEntityConfigurationShouldBeSetup(arg1 string, arg2 *godog.DocString) error
return nil
}

func theHeaderShouldBe(header, value string) error {
//Table has no value to compare against so just checking for id existance
Etag := rec.Result().Header.Get(header)
idEtag, seqNoEtag := api.SplitEtag(Etag)
if Etag == "" {
return fmt.Errorf("expected the Etag to be added to header, got %s", Etag)
func aHeaderWithValue(key, value string) error {
header.Add(key, value)
return godog.ErrPending
}

func aResponseShouldBeReturned(code int) error {
if rec.Code != code {
return fmt.Errorf("expected the code to be %d got %d", code, rec.Code)
}
return nil
}

func isOnTheEditScreenWithId(user, contentType, id string) error {
requests[strings.ToLower(contentType+"_update")] = map[string]interface{}{}
currScreen = strings.ToLower(contentType + "_update")
return nil
}

func theHeaderShouldBe(key, value string) error {
if key == "ETag" {
Etag := rec.Result().Header.Get(key)
idEtag, seqNoEtag := api.SplitEtag(Etag)
if Etag == "" {
return fmt.Errorf("expected the Etag to be added to header, got %s", Etag)
}
if idEtag == "" {
return fmt.Errorf("expected the Etag to contain a weos id, got %s", idEtag)
}
if seqNoEtag == "" {
return fmt.Errorf("expected the Etag to contain a sequence no, got %s", seqNoEtag)
}

if seqNoEtag != strings.Split(value, ".")[1] {
return fmt.Errorf("expected the Etag to contain a sequence no %s, got %s", strings.Split(value, ".")[1], seqNoEtag)
}
return nil
}

headers := rec.Result().Header
val := []string{}

for k, v := range headers {
if strings.EqualFold(k, key) {
val = v
break
}
}

if len(val) > 0 {
if strings.EqualFold(val[0], value) {
return nil
}
}
if idEtag == "" {
return fmt.Errorf("expected the Etag to contain a weos id, got %s", idEtag)
return fmt.Errorf("expected the header %s value to be %s got %v", key, value, val)
}

func theIsUpdated(contentType string, details *godog.Table) error {
if rec.Result().StatusCode != http.StatusOK {
return fmt.Errorf("expected the status code to be '%d', got '%d'", http.StatusOK, rec.Result().StatusCode)
}
if seqNoEtag == "" {
return fmt.Errorf("expected the Etag to contain a sequence no, got %s", seqNoEtag)

head := details.Rows[0].Cells
compare := map[string]interface{}{}

for i := 1; i < len(details.Rows); i++ {
for n, cell := range details.Rows[i].Cells {
compare[head[n].Value] = cell.Value
}
}

contentEntity := map[string]interface{}{}
var result *gorm.DB
//ETag would help with this
for key, value := range compare {
result = API.Application.DB().Table(strings.Title(contentType)).Find(&contentEntity, key+" = ?", value)
if contentEntity != nil {
break
}
}

if contentEntity == nil {
return fmt.Errorf("unexpected error finding content type in db")
}

if result.Error != nil {
return fmt.Errorf("unexpected error finding content type: %s", result.Error)
}

for key, value := range compare {
if contentEntity[key] != value {
return fmt.Errorf("expected %s %s %s, got %s", contentType, key, value, contentEntity[key])
}
}

contentTypeID[strings.ToLower(contentType)] = true
return nil
}

func theEndpointIsHit(endpoint, url string) error {
request := httptest.NewRequest(endpoint, url, nil)
request = request.WithContext(context.TODO())
header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
request.Header = header
request.Close = true
rec = httptest.NewRecorder()
e.ServeHTTP(rec, request)
return nil
}

func aBlogShouldBeReturned(details *godog.Table) error {
head := details.Rows[0].Cells
compare := map[string]interface{}{}

for i := 1; i < len(details.Rows); i++ {
for n, cell := range details.Rows[i].Cells {
compare[head[n].Value] = cell.Value
}
}

contentEntity := map[string]interface{}{}
err := json.NewDecoder(rec.Body).Decode(&contentEntity)

if err != nil {
return err
}

for key, value := range compare {
if contentEntity[key] != value {
return fmt.Errorf("expected %s %s %s, got %s", "Blog", key, value, contentEntity[key])
}
}

return nil
}

Expand All @@ -487,8 +645,14 @@ func InitializeScenario(ctx *godog.ScenarioContext) {
ctx.Step(`^the "([^"]*)" should have an id$`, theShouldHaveAnId)
ctx.Step(`^the specification is$`, theSpecificationIs)
ctx.Step(`^the "([^"]*)" specification is parsed$`, theSpecificationIsParsed)
ctx.Step(`^a "([^"]*)" entity configuration should be setup$`, aEntityConfigurationShouldBeSetup)
ctx.Step(`^the "([^"]*)" header should be "([^"]*)"$`, theHeaderShouldBe)
ctx.Step(`^a "([^"]*)" entity configuration should be setup$`, aEntityConfigurationShouldBeSetup)
ctx.Step(`^"([^"]*)" is on the "([^"]*)" edit screen with id "([^"]*)"$`, isOnTheEditScreenWithId)
ctx.Step(`^the "([^"]*)" is updated$`, theIsUpdated)
ctx.Step(`^a header "([^"]*)" with value "([^"]*)"$`, aHeaderWithValue)
ctx.Step(`^a (\d+) response should be returned$`, aResponseShouldBeReturned)
ctx.Step(`^the "([^"]*)" endpoint "([^"]*)" is hit$`, theEndpointIsHit)
ctx.Step(`^a blog should be returned$`, aBlogShouldBeReturned)

}

Expand Down
29 changes: 28 additions & 1 deletion features/edit-content.feature
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
@skipped
Feature: Edit content

Background:
Expand All @@ -13,6 +12,34 @@ Feature: Edit content
title: Blog Aggregator Rest API
version: 0.1.0
description: REST API for interacting with the Blog Aggregator
servers:
- url: https://prod1.weos.sh/blog/dev
description: WeOS Dev
- url: https://prod1.weos.sh/blog/v1
x-weos-config:
logger:
level: warn
report-caller: true
formatter: json
database:
driver: sqlite3
database: e2e.db
event-source:
- title: default
driver: service
endpoint: https://prod1.weos.sh/events/v1
- title: event
driver: sqlite3
database: e2e.db
databases:
- title: default
driver: sqlite3
database: e2e.db
rest:
middleware:
- RequestID
- Recover
- ZapLogger
components:
schemas:
Blog:
Expand Down
Loading