lib/api/research/research_client/industry_contract_test.go

270 lines
9.0 KiB
Go

package research_client_test
import (
"context"
"encoding/json"
"os"
"path/filepath"
"reflect"
"regexp"
"runtime"
"strings"
"testing"
"code.tnxs.net/vernonkeenan/lib/api/research/research_client/industry"
"code.tnxs.net/vernonkeenan/lib/api/research/research_client/industry_companies"
"code.tnxs.net/vernonkeenan/lib/api/research/research_client/industry_products"
"code.tnxs.net/vernonkeenan/lib/api/research/research_client/industry_services"
"code.tnxs.net/vernonkeenan/lib/api/research/research_models"
openapiruntime "github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
)
type captureTransport struct {
operation *openapiruntime.ClientOperation
}
func (transport *captureTransport) Submit(operation *openapiruntime.ClientOperation) (any, error) {
return transport.SubmitContext(context.Background(), operation)
}
func (transport *captureTransport) SubmitContext(_ context.Context, operation *openapiruntime.ClientOperation) (any, error) {
transport.operation = operation
switch operation.ID {
case "getIndustries":
return industry.NewGetIndustriesOK(), nil
case "postIndustries":
return industry.NewPostIndustriesOK(), nil
case "putIndustries":
return industry.NewPutIndustriesOK(), nil
case "getIndustryCompanies":
return industry_companies.NewGetIndustryCompaniesOK(), nil
case "postIndustryCompanies":
return industry_companies.NewPostIndustryCompaniesOK(), nil
case "getIndustryProducts":
return industry_products.NewGetIndustryProductsOK(), nil
case "postIndustryProducts":
return industry_products.NewPostIndustryProductsOK(), nil
case "getIndustryServices":
return industry_services.NewGetIndustryServicesOK(), nil
case "postIndustryServices":
return industry_services.NewPostIndustryServicesOK(), nil
default:
panic("unexpected generated operation: " + operation.ID)
}
}
func TestGeneratedIndustryOperationContract(t *testing.T) {
type operationCall func(openapiruntime.ContextualTransport) error
tests := []struct {
name string
wantID string
wantMethod string
wantPath string
call operationCall
}{
{
name: "list industries",
wantID: "getIndustries",
wantMethod: "GET",
wantPath: "/industries",
call: func(transport openapiruntime.ContextualTransport) error {
_, err := industry.New(transport, strfmt.Default).GetIndustries(industry.NewGetIndustriesParams(), nil)
return err
},
},
{
name: "create industry",
wantID: "postIndustries",
wantMethod: "POST",
wantPath: "/industries",
call: func(transport openapiruntime.ContextualTransport) error {
_, err := industry.New(transport, strfmt.Default).PostIndustries(industry.NewPostIndustriesParams(), nil)
return err
},
},
{
name: "update industry",
wantID: "putIndustries",
wantMethod: "PUT",
wantPath: "/industries",
call: func(transport openapiruntime.ContextualTransport) error {
_, err := industry.New(transport, strfmt.Default).PutIndustries(industry.NewPutIndustriesParams(), nil)
return err
},
},
{
name: "list industry companies",
wantID: "getIndustryCompanies",
wantMethod: "GET",
wantPath: "/industrycompanies",
call: func(transport openapiruntime.ContextualTransport) error {
_, err := industry_companies.New(transport, strfmt.Default).GetIndustryCompanies(industry_companies.NewGetIndustryCompaniesParams(), nil)
return err
},
},
{
name: "create industry company",
wantID: "postIndustryCompanies",
wantMethod: "POST",
wantPath: "/industrycompanies",
call: func(transport openapiruntime.ContextualTransport) error {
_, err := industry_companies.New(transport, strfmt.Default).PostIndustryCompanies(industry_companies.NewPostIndustryCompaniesParams(), nil)
return err
},
},
{
name: "list industry products",
wantID: "getIndustryProducts",
wantMethod: "GET",
wantPath: "/industryproducts",
call: func(transport openapiruntime.ContextualTransport) error {
_, err := industry_products.New(transport, strfmt.Default).GetIndustryProducts(industry_products.NewGetIndustryProductsParams(), nil)
return err
},
},
{
name: "create industry product",
wantID: "postIndustryProducts",
wantMethod: "POST",
wantPath: "/industryproducts",
call: func(transport openapiruntime.ContextualTransport) error {
_, err := industry_products.New(transport, strfmt.Default).PostIndustryProducts(industry_products.NewPostIndustryProductsParams(), nil)
return err
},
},
{
name: "list industry services",
wantID: "getIndustryServices",
wantMethod: "GET",
wantPath: "/industryservices",
call: func(transport openapiruntime.ContextualTransport) error {
_, err := industry_services.New(transport, strfmt.Default).GetIndustryServices(industry_services.NewGetIndustryServicesParams(), nil)
return err
},
},
{
name: "create industry service",
wantID: "postIndustryServices",
wantMethod: "POST",
wantPath: "/industryservices",
call: func(transport openapiruntime.ContextualTransport) error {
_, err := industry_services.New(transport, strfmt.Default).PostIndustryServices(industry_services.NewPostIndustryServicesParams(), nil)
return err
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
transport := &captureTransport{}
if err := test.call(transport); err != nil {
t.Fatalf("generated client operation failed: %v", err)
}
if transport.operation == nil {
t.Fatal("generated client did not submit an operation")
}
if transport.operation.ID != test.wantID {
t.Errorf("operation ID = %q, want %q", transport.operation.ID, test.wantID)
}
if transport.operation.Method != test.wantMethod {
t.Errorf("method = %q, want %q", transport.operation.Method, test.wantMethod)
}
if transport.operation.PathPattern != test.wantPath {
t.Errorf("path = %q, want %q", transport.operation.PathPattern, test.wantPath)
}
})
}
}
func TestIndustryServiceDoesNotInventHTML(t *testing.T) {
serviceType := reflect.TypeOf(research_models.IndustryService{})
if _, exists := serviceType.FieldByName("HTML"); exists {
t.Fatal("IndustryService must not grow an HTML field absent from the authoritative contract")
}
productType := reflect.TypeOf(research_models.IndustryProduct{})
if _, exists := productType.FieldByName("HTML"); !exists {
t.Fatal("IndustryProduct must retain its authoritative HTML field")
}
payload, err := json.Marshal(research_models.IndustryService{ID: "industry-service-id"})
if err != nil {
t.Fatalf("marshal IndustryService: %v", err)
}
if strings.Contains(string(payload), "HTML") {
t.Fatalf("IndustryService JSON invented an HTML field: %s", payload)
}
}
func TestIndustryJunctionContractDoesNotInventUpdateOperations(t *testing.T) {
interfaces := []struct {
name string
typ reflect.Type
}{
{name: "IndustryCompany", typ: reflect.TypeOf((*industry_companies.ClientService)(nil)).Elem()},
{name: "IndustryProduct", typ: reflect.TypeOf((*industry_products.ClientService)(nil)).Elem()},
{name: "IndustryService", typ: reflect.TypeOf((*industry_services.ClientService)(nil)).Elem()},
}
for _, contract := range interfaces {
for _, suffix := range []string{"", "Context"} {
method := "Put" + contract.name + suffix
if _, exists := contract.typ.MethodByName(method); exists {
t.Errorf("%s client invented unsupported operation %s", contract.name, method)
}
}
}
}
func TestGeneratedIndustrySurfaceHasNoSalesforceOrEmbeddedSecrets(t *testing.T) {
_, testFile, _, ok := runtime.Caller(0)
if !ok {
t.Fatal("resolve test source path")
}
clientRoot := filepath.Dir(testFile)
modelRoot := filepath.Join(clientRoot, "..", "research_models")
targets := []string{
filepath.Join(clientRoot, "industry"),
filepath.Join(clientRoot, "industry_companies"),
filepath.Join(clientRoot, "industry_products"),
filepath.Join(clientRoot, "industry_services"),
filepath.Join(modelRoot, "industry.go"),
filepath.Join(modelRoot, "industry_company.go"),
filepath.Join(modelRoot, "industry_product.go"),
filepath.Join(modelRoot, "industry_service.go"),
}
credentialLiteral := regexp.MustCompile(`(?i)(api[_-]?key|password|secret)\s*[:=]\s*["'][^"']+["']`)
for _, target := range targets {
err := filepath.WalkDir(target, func(path string, entry os.DirEntry, walkErr error) error {
if walkErr != nil {
return walkErr
}
if entry.IsDir() || !strings.HasSuffix(path, ".go") || strings.HasSuffix(path, "_test.go") {
return nil
}
content, err := os.ReadFile(path)
if err != nil {
return err
}
lower := strings.ToLower(string(content))
for _, forbidden := range []string{"salesforce", "sf-gate", "go-force", "private key-----"} {
if strings.Contains(lower, forbidden) {
t.Errorf("%s contains forbidden boundary %q", path, forbidden)
}
}
if credentialLiteral.Match(content) {
t.Errorf("%s contains a credential-shaped literal", path)
}
return nil
})
if err != nil {
t.Fatalf("scan generated contract target %s: %v", target, err)
}
}
}