This diff extracts the fakefiller inside of internal/ooapi (a currently unused package) into its own package. The fakefiller knows how to fill many fields that are typically shared as data structures across processes. It is not perfect in that it cannot fill logger or http client fields, but still helps with better filling and testing. So, here we're using the fakefiller to improve testing of httpx and, nicely enough, we've already catched a bug in the way in which APIClientTemplate.Build misses to forward Authorization from the original template. Yay! Work part of https://github.com/ooni/probe/issues/1951
899 lines
35 KiB
Go
899 lines
35 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func (d *Descriptor) genTestRegisterAndLoginSuccess(sb *strings.Builder) {
|
|
fmt.Fprintf(sb, "func TestRegisterAndLogin%sSuccess(t *testing.T) {\n", d.Name)
|
|
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
|
|
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&expect)\n")
|
|
|
|
fmt.Fprint(sb, "\tregisterAPI := &FakeRegisterAPI{\n")
|
|
fmt.Fprint(sb, "\t\tResponse: &apimodel.RegisterResponse{\n")
|
|
fmt.Fprint(sb, "\t\t\tClientID: \"antani-antani\",\n")
|
|
fmt.Fprint(sb, "\t\t},\n")
|
|
fmt.Fprint(sb, "\t\tCountCall: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t\tloginAPI := &FakeLoginAPI{\n")
|
|
fmt.Fprint(sb, "\t\t\tResponse: &apimodel.LoginResponse{\n")
|
|
fmt.Fprint(sb, "\t\t\t\tExpire: time.Now().Add(3600*time.Second),\n")
|
|
fmt.Fprint(sb, "\t\t\t\tToken: \"antani-antani-token\",\n")
|
|
fmt.Fprint(sb, "\t\t\t},\n")
|
|
fmt.Fprint(sb, "\t\t\tCountCall: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
|
|
fmt.Fprintf(sb, "\t\tAPI: &%s{\n", d.FakeAPIStructName())
|
|
fmt.Fprintf(sb, "\t\t\tWithResult: &%s{\n", d.FakeAPIStructName())
|
|
fmt.Fprint(sb, "\t\t\t\tResponse: expect,\n")
|
|
fmt.Fprint(sb, "\t\t\t},\n")
|
|
fmt.Fprint(sb, "\t\t},\n")
|
|
fmt.Fprint(sb, "\t\tRegisterAPI: registerAPI,\n")
|
|
fmt.Fprint(sb, "\t\tLoginAPI: loginAPI,\n")
|
|
fmt.Fprint(sb, "\t\tKVStore: &kvstore.Memory{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&req)\n")
|
|
fmt.Fprint(sb, "\tctx := context.Background()\n")
|
|
fmt.Fprint(sb, "\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\tif err != nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(err)\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tif resp == nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"expected non-nil response\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tif diff := cmp.Diff(expect, resp); diff != \"\" {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(diff)\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif loginAPI.CountCall.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid loginAPI.CountCall\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif registerAPI.CountCall.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid registerAPI.CountCall\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "}\n\n")
|
|
}
|
|
|
|
func (d *Descriptor) genTestContinueUsingToken(sb *strings.Builder) {
|
|
fmt.Fprintf(sb, "func Test%sContinueUsingToken(t *testing.T) {\n", d.Name)
|
|
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
|
|
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&expect)\n")
|
|
|
|
fmt.Fprint(sb, "\tregisterAPI := &FakeRegisterAPI{\n")
|
|
fmt.Fprint(sb, "\t\tResponse: &apimodel.RegisterResponse{\n")
|
|
fmt.Fprint(sb, "\t\t\tClientID: \"antani-antani\",\n")
|
|
fmt.Fprint(sb, "\t\t},\n")
|
|
fmt.Fprint(sb, "\t\tCountCall: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t\tloginAPI := &FakeLoginAPI{\n")
|
|
fmt.Fprint(sb, "\t\t\tResponse: &apimodel.LoginResponse{\n")
|
|
fmt.Fprint(sb, "\t\t\t\tExpire: time.Now().Add(3600*time.Second),\n")
|
|
fmt.Fprint(sb, "\t\t\t\tToken: \"antani-antani-token\",\n")
|
|
fmt.Fprint(sb, "\t\t\t},\n")
|
|
fmt.Fprint(sb, "\t\t\tCountCall: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
|
|
fmt.Fprintf(sb, "\t\tAPI: &%s{\n", d.FakeAPIStructName())
|
|
fmt.Fprintf(sb, "\t\t\tWithResult: &%s{\n", d.FakeAPIStructName())
|
|
fmt.Fprint(sb, "\t\t\t\tResponse: expect,\n")
|
|
fmt.Fprint(sb, "\t\t\t},\n")
|
|
fmt.Fprint(sb, "\t\t},\n")
|
|
fmt.Fprint(sb, "\t\tRegisterAPI: registerAPI,\n")
|
|
fmt.Fprint(sb, "\t\tLoginAPI: loginAPI,\n")
|
|
fmt.Fprint(sb, "\t\tKVStore: &kvstore.Memory{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&req)\n")
|
|
fmt.Fprint(sb, "\tctx := context.Background()\n")
|
|
|
|
fmt.Fprint(sb, "\t// step 1: we register and login and use the token\n")
|
|
fmt.Fprint(sb, "\t// inside a scope just to avoid mistakes\n")
|
|
|
|
fmt.Fprint(sb, "\t{\n")
|
|
fmt.Fprint(sb, "\t\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\t\tif err != nil {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(err)\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprint(sb, "\t\tif resp == nil {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"expected non-nil response\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprint(sb, "\t\tif diff := cmp.Diff(expect, resp); diff != \"\" {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(diff)\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t\tif loginAPI.CountCall.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"invalid loginAPI.CountCall\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t\tif registerAPI.CountCall.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"invalid registerAPI.CountCall\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t// step 2: we disable register and login but we\n")
|
|
fmt.Fprint(sb, "\t// should be okay because of the token\n")
|
|
fmt.Fprint(sb, "\terrMocked := errors.New(\"mocked error\")\n")
|
|
fmt.Fprint(sb, "\tregisterAPI.Err = errMocked\n")
|
|
fmt.Fprint(sb, "\tregisterAPI.Response = nil\n")
|
|
fmt.Fprint(sb, "\tloginAPI.Err = errMocked\n")
|
|
fmt.Fprint(sb, "\tloginAPI.Response = nil\n")
|
|
|
|
fmt.Fprint(sb, "\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\tif err != nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(err)\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tif resp == nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"expected non-nil response\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tif diff := cmp.Diff(expect, resp); diff != \"\" {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(diff)\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif loginAPI.CountCall.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid loginAPI.CountCall\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif registerAPI.CountCall.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid registerAPI.CountCall\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "}\n\n")
|
|
}
|
|
|
|
func (d *Descriptor) genTestWithValidButExpiredToken(sb *strings.Builder) {
|
|
fmt.Fprintf(sb, "func Test%sWithValidButExpiredToken(t *testing.T) {\n", d.Name)
|
|
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
|
|
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&expect)\n")
|
|
|
|
fmt.Fprint(sb, "\terrMocked := errors.New(\"mocked error\")\n")
|
|
fmt.Fprint(sb, "\tregisterAPI := &FakeRegisterAPI{\n")
|
|
fmt.Fprint(sb, "\t\tErr: errMocked,\n")
|
|
fmt.Fprint(sb, "\t\tCountCall: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t\tloginAPI := &FakeLoginAPI{\n")
|
|
fmt.Fprint(sb, "\t\t\tResponse: &apimodel.LoginResponse{\n")
|
|
fmt.Fprint(sb, "\t\t\t\tExpire: time.Now().Add(3600*time.Second),\n")
|
|
fmt.Fprint(sb, "\t\t\t\tToken: \"antani-antani-token\",\n")
|
|
fmt.Fprint(sb, "\t\t\t},\n")
|
|
fmt.Fprint(sb, "\t\t\tCountCall: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
|
|
fmt.Fprintf(sb, "\t\tAPI: &%s{\n", d.FakeAPIStructName())
|
|
fmt.Fprintf(sb, "\t\t\tWithResult: &%s{\n", d.FakeAPIStructName())
|
|
fmt.Fprint(sb, "\t\t\t\tResponse: expect,\n")
|
|
fmt.Fprint(sb, "\t\t\t},\n")
|
|
fmt.Fprint(sb, "\t\t},\n")
|
|
fmt.Fprint(sb, "\t\tRegisterAPI: registerAPI,\n")
|
|
fmt.Fprint(sb, "\t\tLoginAPI: loginAPI,\n")
|
|
fmt.Fprint(sb, "\t\tKVStore: &kvstore.Memory{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tls := &loginState{\n")
|
|
fmt.Fprintf(sb, "\t\tClientID: \"antani-antani\",\n")
|
|
fmt.Fprintf(sb, "\t\tExpire: time.Now().Add(-5 * time.Second),\n")
|
|
fmt.Fprintf(sb, "\t\tToken: \"antani-antani-token\",\n")
|
|
fmt.Fprintf(sb, "\t\tPassword: \"antani-antani-password\",\n")
|
|
fmt.Fprintf(sb, "\t}\n")
|
|
fmt.Fprintf(sb, "\tif err := login.writestate(ls); err != nil {\n")
|
|
fmt.Fprintf(sb, "\t\tt.Fatal(err)\n")
|
|
fmt.Fprintf(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&req)\n")
|
|
fmt.Fprint(sb, "\tctx := context.Background()\n")
|
|
fmt.Fprint(sb, "\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\tif err != nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(err)\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tif resp == nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"expected non-nil response\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tif diff := cmp.Diff(expect, resp); diff != \"\" {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(diff)\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif loginAPI.CountCall.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid loginAPI.CountCall\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif registerAPI.CountCall.Load() != 0 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid registerAPI.CountCall\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "}\n\n")
|
|
}
|
|
|
|
func (d *Descriptor) genTestWithRegisterAPIError(sb *strings.Builder) {
|
|
fmt.Fprintf(sb, "func Test%sWithRegisterAPIError(t *testing.T) {\n", d.Name)
|
|
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
|
|
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&expect)\n")
|
|
|
|
fmt.Fprint(sb, "\terrMocked := errors.New(\"mocked error\")\n")
|
|
fmt.Fprint(sb, "\tregisterAPI := &FakeRegisterAPI{\n")
|
|
fmt.Fprint(sb, "\t\tErr: errMocked,\n")
|
|
fmt.Fprint(sb, "\t\tCountCall: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
|
|
fmt.Fprintf(sb, "\t\tAPI: &%s{\n", d.FakeAPIStructName())
|
|
fmt.Fprintf(sb, "\t\t\tWithResult: &%s{\n", d.FakeAPIStructName())
|
|
fmt.Fprint(sb, "\t\t\t\tResponse: expect,\n")
|
|
fmt.Fprint(sb, "\t\t\t},\n")
|
|
fmt.Fprint(sb, "\t\t},\n")
|
|
fmt.Fprint(sb, "\t\tRegisterAPI: registerAPI,\n")
|
|
fmt.Fprint(sb, "\t\tKVStore: &kvstore.Memory{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&req)\n")
|
|
fmt.Fprint(sb, "\tctx := context.Background()\n")
|
|
fmt.Fprint(sb, "\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\tif !errors.Is(err, errMocked) {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"not the error we expected\", err)\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tif resp != nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"expected nil response\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif registerAPI.CountCall.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid registerAPI.CountCall\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "}\n\n")
|
|
}
|
|
|
|
func (d *Descriptor) genTestWithLoginFailure(sb *strings.Builder) {
|
|
fmt.Fprintf(sb, "func Test%sWithLoginFailure(t *testing.T) {\n", d.Name)
|
|
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
|
|
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&expect)\n")
|
|
|
|
fmt.Fprint(sb, "\tregisterAPI := &FakeRegisterAPI{\n")
|
|
fmt.Fprint(sb, "\t\tResponse: &apimodel.RegisterResponse{\n")
|
|
fmt.Fprint(sb, "\t\t\tClientID: \"antani-antani\",\n")
|
|
fmt.Fprint(sb, "\t\t},\n")
|
|
fmt.Fprint(sb, "\t\tCountCall: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\terrMocked := errors.New(\"mocked error\")\n")
|
|
fmt.Fprint(sb, "\t\tloginAPI := &FakeLoginAPI{\n")
|
|
fmt.Fprint(sb, "\t\t\tErr: errMocked,\n")
|
|
fmt.Fprint(sb, "\t\t\tCountCall: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
|
|
fmt.Fprintf(sb, "\t\tAPI: &%s{\n", d.FakeAPIStructName())
|
|
fmt.Fprintf(sb, "\t\t\tWithResult: &%s{\n", d.FakeAPIStructName())
|
|
fmt.Fprint(sb, "\t\t\t\tResponse: expect,\n")
|
|
fmt.Fprint(sb, "\t\t\t},\n")
|
|
fmt.Fprint(sb, "\t\t},\n")
|
|
fmt.Fprint(sb, "\t\tRegisterAPI: registerAPI,\n")
|
|
fmt.Fprint(sb, "\t\tLoginAPI: loginAPI,\n")
|
|
fmt.Fprint(sb, "\t\tKVStore: &kvstore.Memory{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&req)\n")
|
|
fmt.Fprint(sb, "\tctx := context.Background()\n")
|
|
fmt.Fprint(sb, "\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\tif !errors.Is(err, errMocked) {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"not the error we expected\", err)\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tif resp != nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"expected nil response\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif loginAPI.CountCall.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid loginAPI.CountCall\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif registerAPI.CountCall.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid registerAPI.CountCall\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "}\n\n")
|
|
}
|
|
|
|
func (d *Descriptor) genTestRegisterAndLoginThenFail(sb *strings.Builder) {
|
|
fmt.Fprintf(sb, "func TestRegisterAndLogin%sThenFail(t *testing.T) {\n", d.Name)
|
|
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
|
|
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&expect)\n")
|
|
|
|
fmt.Fprint(sb, "\tregisterAPI := &FakeRegisterAPI{\n")
|
|
fmt.Fprint(sb, "\t\tResponse: &apimodel.RegisterResponse{\n")
|
|
fmt.Fprint(sb, "\t\t\tClientID: \"antani-antani\",\n")
|
|
fmt.Fprint(sb, "\t\t},\n")
|
|
fmt.Fprint(sb, "\t\tCountCall: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t\tloginAPI := &FakeLoginAPI{\n")
|
|
fmt.Fprint(sb, "\t\t\tResponse: &apimodel.LoginResponse{\n")
|
|
fmt.Fprint(sb, "\t\t\t\tExpire: time.Now().Add(3600*time.Second),\n")
|
|
fmt.Fprint(sb, "\t\t\t\tToken: \"antani-antani-token\",\n")
|
|
fmt.Fprint(sb, "\t\t\t},\n")
|
|
fmt.Fprint(sb, "\t\t\tCountCall: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprint(sb, "\terrMocked := errors.New(\"mocked error\")\n")
|
|
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
|
|
fmt.Fprintf(sb, "\t\tAPI: &%s{\n", d.FakeAPIStructName())
|
|
fmt.Fprintf(sb, "\t\t\tWithResult: &%s{\n", d.FakeAPIStructName())
|
|
fmt.Fprint(sb, "\t\t\t\tErr: errMocked,\n")
|
|
fmt.Fprint(sb, "\t\t\t},\n")
|
|
fmt.Fprint(sb, "\t\t},\n")
|
|
fmt.Fprint(sb, "\t\tRegisterAPI: registerAPI,\n")
|
|
fmt.Fprint(sb, "\t\tLoginAPI: loginAPI,\n")
|
|
fmt.Fprint(sb, "\t\tKVStore: &kvstore.Memory{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&req)\n")
|
|
fmt.Fprint(sb, "\tctx := context.Background()\n")
|
|
fmt.Fprint(sb, "\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\tif !errors.Is(err, errMocked) {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"not the error we expected\", err)\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tif resp != nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"expected nil response\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif loginAPI.CountCall.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid loginAPI.CountCall\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif registerAPI.CountCall.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid registerAPI.CountCall\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "}\n\n")
|
|
}
|
|
|
|
func (d *Descriptor) genTestTheDatabaseIsReplaced(sb *strings.Builder) {
|
|
fmt.Fprintf(sb, "func Test%sTheDatabaseIsReplaced(t *testing.T) {\n", d.Name)
|
|
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
|
|
fmt.Fprint(sb, "\thandler := &LoginHandler{\n")
|
|
fmt.Fprint(sb, "\t\tlogins: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t\tregisters: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t\tt: t,\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tsrvr := httptest.NewServer(handler)\n")
|
|
fmt.Fprint(sb, "\tdefer srvr.Close()\n")
|
|
|
|
fmt.Fprint(sb, "\tregisterAPI := &simpleRegisterAPI{\n")
|
|
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
|
|
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\t\tloginAPI := &simpleLoginAPI{\n")
|
|
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
|
|
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprintf(sb, "\tbaseAPI := &%s{\n", d.APIStructName())
|
|
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
|
|
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
|
|
fmt.Fprintf(sb, "\tAPI : baseAPI,\n")
|
|
fmt.Fprint(sb, "\tRegisterAPI: registerAPI,\n")
|
|
fmt.Fprint(sb, "\tLoginAPI: loginAPI,\n")
|
|
fmt.Fprint(sb, "\tKVStore: &kvstore.Memory{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&req)\n")
|
|
fmt.Fprint(sb, "\tctx := context.Background()\n")
|
|
|
|
fmt.Fprint(sb, "\t// step 1: we register and login and use the token\n")
|
|
fmt.Fprint(sb, "\t// inside a scope just to avoid mistakes\n")
|
|
|
|
fmt.Fprint(sb, "\t{\n")
|
|
fmt.Fprint(sb, "\t\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\t\tif err != nil {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(err)\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprint(sb, "\t\tif resp == nil {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"expected non-nil response\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t\tif handler.logins.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"invalid handler.logins\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t\tif handler.registers.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"invalid handler.registers\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t// step 2: we forget accounts and try again.\n")
|
|
fmt.Fprint(sb, "\thandler.forgetLogins()\n")
|
|
|
|
fmt.Fprint(sb, "\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\tif err != nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(err)\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tif resp == nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"expected non-nil response\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif handler.logins.Load() != 3 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid handler.logins\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif handler.registers.Load() != 2 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid handler.registers\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "}\n\n")
|
|
}
|
|
|
|
func (d *Descriptor) genTestTheDatabaseIsReplacedThenFailure(sb *strings.Builder) {
|
|
fmt.Fprintf(sb, "func Test%sTheDatabaseIsReplacedThenFailure(t *testing.T) {\n", d.Name)
|
|
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
|
|
fmt.Fprint(sb, "\thandler := &LoginHandler{\n")
|
|
fmt.Fprint(sb, "\t\tlogins: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t\tregisters: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t\tt: t,\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tsrvr := httptest.NewServer(handler)\n")
|
|
fmt.Fprint(sb, "\tdefer srvr.Close()\n")
|
|
|
|
fmt.Fprint(sb, "\tregisterAPI := &simpleRegisterAPI{\n")
|
|
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
|
|
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\t\tloginAPI := &simpleLoginAPI{\n")
|
|
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
|
|
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprintf(sb, "\tbaseAPI := &%s{\n", d.APIStructName())
|
|
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
|
|
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
|
|
fmt.Fprintf(sb, "\tAPI : baseAPI,\n")
|
|
fmt.Fprint(sb, "\tRegisterAPI: registerAPI,\n")
|
|
fmt.Fprint(sb, "\tLoginAPI: loginAPI,\n")
|
|
fmt.Fprint(sb, "\tKVStore: &kvstore.Memory{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&req)\n")
|
|
fmt.Fprint(sb, "\tctx := context.Background()\n")
|
|
|
|
fmt.Fprint(sb, "\t// step 1: we register and login and use the token\n")
|
|
fmt.Fprint(sb, "\t// inside a scope just to avoid mistakes\n")
|
|
|
|
fmt.Fprint(sb, "\t{\n")
|
|
fmt.Fprint(sb, "\t\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\t\tif err != nil {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(err)\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprint(sb, "\t\tif resp == nil {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"expected non-nil response\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t\tif handler.logins.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"invalid handler.logins\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t\tif handler.registers.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"invalid handler.registers\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t// step 2: we forget accounts and try again.\n")
|
|
fmt.Fprint(sb, "\t// but registrations are also failing.\n")
|
|
fmt.Fprint(sb, "\thandler.forgetLogins()\n")
|
|
fmt.Fprint(sb, "\thandler.noRegister = true\n")
|
|
|
|
fmt.Fprint(sb, "\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\tif !errors.Is(err, ErrHTTPFailure) {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"not the error we expected\", err)\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tif resp != nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"expected nil response\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif handler.logins.Load() != 2 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid handler.logins\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif handler.registers.Load() != 2 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid handler.registers\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "}\n\n")
|
|
}
|
|
|
|
func (d *Descriptor) genTestRegisterAndLoginCannotWriteState(sb *strings.Builder) {
|
|
fmt.Fprintf(sb, "func TestRegisterAndLogin%sCannotWriteState(t *testing.T) {\n", d.Name)
|
|
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
|
|
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&expect)\n")
|
|
|
|
fmt.Fprint(sb, "\tregisterAPI := &FakeRegisterAPI{\n")
|
|
fmt.Fprint(sb, "\t\tResponse: &apimodel.RegisterResponse{\n")
|
|
fmt.Fprint(sb, "\t\t\tClientID: \"antani-antani\",\n")
|
|
fmt.Fprint(sb, "\t\t},\n")
|
|
fmt.Fprint(sb, "\t\tCountCall: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t\tloginAPI := &FakeLoginAPI{\n")
|
|
fmt.Fprint(sb, "\t\t\tResponse: &apimodel.LoginResponse{\n")
|
|
fmt.Fprint(sb, "\t\t\t\tExpire: time.Now().Add(3600*time.Second),\n")
|
|
fmt.Fprint(sb, "\t\t\t\tToken: \"antani-antani-token\",\n")
|
|
fmt.Fprint(sb, "\t\t\t},\n")
|
|
fmt.Fprint(sb, "\t\t\tCountCall: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprint(sb, "\terrMocked := errors.New(\"mocked error\")\n")
|
|
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
|
|
fmt.Fprintf(sb, "\t\tAPI: &%s{\n", d.FakeAPIStructName())
|
|
fmt.Fprintf(sb, "\t\t\tWithResult: &%s{\n", d.FakeAPIStructName())
|
|
fmt.Fprint(sb, "\t\t\t\tResponse: expect,\n")
|
|
fmt.Fprint(sb, "\t\t\t},\n")
|
|
fmt.Fprint(sb, "\t\t},\n")
|
|
fmt.Fprint(sb, "\t\tRegisterAPI: registerAPI,\n")
|
|
fmt.Fprint(sb, "\t\tLoginAPI: loginAPI,\n")
|
|
fmt.Fprint(sb, "\t\tKVStore: &kvstore.Memory{},\n")
|
|
fmt.Fprint(sb, "\t\tJSONCodec: &FakeCodec{\n")
|
|
fmt.Fprint(sb, "\t\t\tEncodeErr: errMocked,\n")
|
|
fmt.Fprint(sb, "\t\t},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&req)\n")
|
|
fmt.Fprint(sb, "\tctx := context.Background()\n")
|
|
fmt.Fprint(sb, "\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\tif !errors.Is(err, errMocked) {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"not the error we expected\", err)\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tif resp != nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"expected nil response\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif loginAPI.CountCall.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid loginAPI.CountCall\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif registerAPI.CountCall.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid registerAPI.CountCall\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "}\n\n")
|
|
}
|
|
|
|
func (d *Descriptor) genTestReadStateDecodeFailure(sb *strings.Builder) {
|
|
fmt.Fprintf(sb, "func Test%sReadStateDecodeFailure(t *testing.T) {\n", d.Name)
|
|
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
|
|
fmt.Fprintf(sb, "\tvar expect %s\n", d.ResponseTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&expect)\n")
|
|
|
|
fmt.Fprint(sb, "\terrMocked := errors.New(\"mocked error\")\n")
|
|
|
|
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
|
|
fmt.Fprint(sb, "\t\tKVStore: &kvstore.Memory{},\n")
|
|
fmt.Fprint(sb, "\t\tJSONCodec: &FakeCodec{DecodeErr: errMocked},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tls := &loginState{\n")
|
|
fmt.Fprintf(sb, "\t\tClientID: \"antani-antani\",\n")
|
|
fmt.Fprintf(sb, "\t\tExpire: time.Now().Add(-5 * time.Second),\n")
|
|
fmt.Fprintf(sb, "\t\tToken: \"antani-antani-token\",\n")
|
|
fmt.Fprintf(sb, "\t\tPassword: \"antani-antani-password\",\n")
|
|
fmt.Fprintf(sb, "\t}\n")
|
|
fmt.Fprintf(sb, "\tif err := login.writestate(ls); err != nil {\n")
|
|
fmt.Fprintf(sb, "\t\tt.Fatal(err)\n")
|
|
fmt.Fprintf(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tout, err := login.forceLogin(context.Background())\n")
|
|
fmt.Fprintf(sb, "if !errors.Is(err, errMocked) {\n")
|
|
fmt.Fprintf(sb, "\t\tt.Fatal(\"not the error we expected\", err)\n")
|
|
fmt.Fprintf(sb, "\t}\n")
|
|
fmt.Fprintf(sb, "if out != \"\" {\n")
|
|
fmt.Fprintf(sb, "\t\tt.Fatal(\"expected empty string here\")\n")
|
|
fmt.Fprintf(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "}\n\n")
|
|
}
|
|
|
|
func (d *Descriptor) genTestClockIsOffThenSuccess(sb *strings.Builder) {
|
|
fmt.Fprintf(sb, "func Test%sClockIsOffThenSuccess(t *testing.T) {\n", d.Name)
|
|
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
|
|
fmt.Fprint(sb, "\thandler := &LoginHandler{\n")
|
|
fmt.Fprint(sb, "\t\tlogins: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t\tregisters: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t\tt: t,\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tsrvr := httptest.NewServer(handler)\n")
|
|
fmt.Fprint(sb, "\tdefer srvr.Close()\n")
|
|
|
|
fmt.Fprint(sb, "\tregisterAPI := &simpleRegisterAPI{\n")
|
|
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
|
|
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\t\tloginAPI := &simpleLoginAPI{\n")
|
|
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
|
|
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprintf(sb, "\tbaseAPI := &%s{\n", d.APIStructName())
|
|
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
|
|
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
|
|
fmt.Fprintf(sb, "\tAPI : baseAPI,\n")
|
|
fmt.Fprint(sb, "\tRegisterAPI: registerAPI,\n")
|
|
fmt.Fprint(sb, "\tLoginAPI: loginAPI,\n")
|
|
fmt.Fprint(sb, "\tKVStore: &kvstore.Memory{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&req)\n")
|
|
fmt.Fprint(sb, "\tctx := context.Background()\n")
|
|
|
|
fmt.Fprint(sb, "\t// step 1: we register and login and use the token\n")
|
|
fmt.Fprint(sb, "\t// inside a scope just to avoid mistakes\n")
|
|
|
|
fmt.Fprint(sb, "\t{\n")
|
|
fmt.Fprint(sb, "\t\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\t\tif err != nil {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(err)\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprint(sb, "\t\tif resp == nil {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"expected non-nil response\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t\tif handler.logins.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"invalid handler.logins\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t\tif handler.registers.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"invalid handler.registers\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t// step 2: we forget tokens and try again.\n")
|
|
fmt.Fprint(sb, "\t// this should simulate the client clock\n")
|
|
fmt.Fprint(sb, "\t// being off and considering a token still valid\n")
|
|
fmt.Fprint(sb, "\thandler.forgetTokens()\n")
|
|
|
|
fmt.Fprint(sb, "\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\tif err != nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(err)\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tif resp == nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"expected non-nil response\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif handler.logins.Load() != 2 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid handler.logins\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif handler.registers.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid handler.registers\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "}\n\n")
|
|
}
|
|
|
|
func (d *Descriptor) genTestClockIsOffThen401(sb *strings.Builder) {
|
|
fmt.Fprintf(sb, "func Test%sClockIsOffThen401(t *testing.T) {\n", d.Name)
|
|
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
|
|
fmt.Fprint(sb, "\thandler := &LoginHandler{\n")
|
|
fmt.Fprint(sb, "\t\tlogins: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t\tregisters: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t\tt: t,\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tsrvr := httptest.NewServer(handler)\n")
|
|
fmt.Fprint(sb, "\tdefer srvr.Close()\n")
|
|
|
|
fmt.Fprint(sb, "\tregisterAPI := &simpleRegisterAPI{\n")
|
|
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
|
|
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\t\tloginAPI := &simpleLoginAPI{\n")
|
|
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
|
|
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprintf(sb, "\tbaseAPI := &%s{\n", d.APIStructName())
|
|
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
|
|
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
|
|
fmt.Fprintf(sb, "\tAPI : baseAPI,\n")
|
|
fmt.Fprint(sb, "\tRegisterAPI: registerAPI,\n")
|
|
fmt.Fprint(sb, "\tLoginAPI: loginAPI,\n")
|
|
fmt.Fprint(sb, "\tKVStore: &kvstore.Memory{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&req)\n")
|
|
fmt.Fprint(sb, "\tctx := context.Background()\n")
|
|
|
|
fmt.Fprint(sb, "\t// step 1: we register and login and use the token\n")
|
|
fmt.Fprint(sb, "\t// inside a scope just to avoid mistakes\n")
|
|
|
|
fmt.Fprint(sb, "\t{\n")
|
|
fmt.Fprint(sb, "\t\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\t\tif err != nil {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(err)\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprint(sb, "\t\tif resp == nil {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"expected non-nil response\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t\tif handler.logins.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"invalid handler.logins\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t\tif handler.registers.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"invalid handler.registers\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t// step 2: we forget tokens and try again.\n")
|
|
fmt.Fprint(sb, "\t// this should simulate the client clock\n")
|
|
fmt.Fprint(sb, "\t// being off and considering a token still valid\n")
|
|
fmt.Fprint(sb, "\thandler.forgetTokens()\n")
|
|
fmt.Fprint(sb, "\thandler.failCallWith = []int{401, 401}\n")
|
|
|
|
fmt.Fprint(sb, "\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\tif err != nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"not the error we expected\", err)\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tif resp == nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"expected non-nil response\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif handler.logins.Load() != 3 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid handler.logins\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif handler.registers.Load() != 2 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid handler.registers\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "}\n\n")
|
|
}
|
|
|
|
func (d *Descriptor) genTestClockIsOffThen500(sb *strings.Builder) {
|
|
fmt.Fprintf(sb, "func Test%sClockIsOffThen500(t *testing.T) {\n", d.Name)
|
|
fmt.Fprint(sb, "\tff := &fakeFill{}\n")
|
|
fmt.Fprint(sb, "\thandler := &LoginHandler{\n")
|
|
fmt.Fprint(sb, "\t\tlogins: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t\tregisters: &atomicx.Int64{},\n")
|
|
fmt.Fprint(sb, "\t\tt: t,\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tsrvr := httptest.NewServer(handler)\n")
|
|
fmt.Fprint(sb, "\tdefer srvr.Close()\n")
|
|
|
|
fmt.Fprint(sb, "\tregisterAPI := &simpleRegisterAPI{\n")
|
|
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
|
|
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\t\tloginAPI := &simpleLoginAPI{\n")
|
|
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
|
|
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprintf(sb, "\tbaseAPI := &%s{\n", d.APIStructName())
|
|
fmt.Fprint(sb, "\t\tHTTPClient: &VerboseHTTPClient{T: t},\n")
|
|
fmt.Fprint(sb, "\t\tBaseURL: srvr.URL,\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tlogin := &%s{\n", d.WithLoginAPIStructName())
|
|
fmt.Fprintf(sb, "\tAPI : baseAPI,\n")
|
|
fmt.Fprint(sb, "\tRegisterAPI: registerAPI,\n")
|
|
fmt.Fprint(sb, "\tLoginAPI: loginAPI,\n")
|
|
fmt.Fprint(sb, "\tKVStore: &kvstore.Memory{},\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprintf(sb, "\tvar req %s\n", d.RequestTypeName())
|
|
fmt.Fprint(sb, "\tff.Fill(&req)\n")
|
|
fmt.Fprint(sb, "\tctx := context.Background()\n")
|
|
|
|
fmt.Fprint(sb, "\t// step 1: we register and login and use the token\n")
|
|
fmt.Fprint(sb, "\t// inside a scope just to avoid mistakes\n")
|
|
|
|
fmt.Fprint(sb, "\t{\n")
|
|
fmt.Fprint(sb, "\t\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\t\tif err != nil {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(err)\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprint(sb, "\t\tif resp == nil {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"expected non-nil response\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t\tif handler.logins.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"invalid handler.logins\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t\tif handler.registers.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\t\tt.Fatal(\"invalid handler.registers\")\n")
|
|
fmt.Fprint(sb, "\t\t}\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\t// step 2: we forget tokens and try again.\n")
|
|
fmt.Fprint(sb, "\t// this should simulate the client clock\n")
|
|
fmt.Fprint(sb, "\t// being off and considering a token still valid\n")
|
|
fmt.Fprint(sb, "\thandler.forgetTokens()\n")
|
|
fmt.Fprint(sb, "\thandler.failCallWith = []int{401, 500}\n")
|
|
|
|
fmt.Fprint(sb, "\tresp, err := login.Call(ctx, req)\n")
|
|
fmt.Fprint(sb, "\tif !errors.Is(err, ErrHTTPFailure) {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"not the error we expected\", err)\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
fmt.Fprint(sb, "\tif resp != nil {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"expected nil response\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif handler.logins.Load() != 2 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid handler.logins\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "\tif handler.registers.Load() != 1 {\n")
|
|
fmt.Fprint(sb, "\t\tt.Fatal(\"invalid handler.registers\")\n")
|
|
fmt.Fprint(sb, "\t}\n")
|
|
|
|
fmt.Fprint(sb, "}\n\n")
|
|
}
|
|
|
|
// GenLoginTestGo generates login_test.go.
|
|
func GenLoginTestGo(file string) {
|
|
var sb strings.Builder
|
|
fmt.Fprint(&sb, "// Code generated by go generate; DO NOT EDIT.\n")
|
|
fmt.Fprintf(&sb, "// %s\n\n", time.Now())
|
|
fmt.Fprint(&sb, "package ooapi\n\n")
|
|
fmt.Fprintf(&sb, "//go:generate go run ./internal/generator -file %s\n\n", file)
|
|
fmt.Fprint(&sb, "import (\n")
|
|
fmt.Fprint(&sb, "\t\"context\"\n")
|
|
fmt.Fprint(&sb, "\t\"errors\"\n")
|
|
fmt.Fprint(&sb, "\t\"net/http/httptest\"\n")
|
|
fmt.Fprint(&sb, "\t\"testing\"\n")
|
|
fmt.Fprint(&sb, "\t\"time\"\n")
|
|
fmt.Fprint(&sb, "\n")
|
|
fmt.Fprint(&sb, "\t\"github.com/google/go-cmp/cmp\"\n")
|
|
fmt.Fprint(&sb, "\t\"github.com/ooni/probe-cli/v3/internal/atomicx\"\n")
|
|
fmt.Fprint(&sb, "\t\"github.com/ooni/probe-cli/v3/internal/kvstore\"\n")
|
|
fmt.Fprint(&sb, "\t\"github.com/ooni/probe-cli/v3/internal/ooapi/apimodel\"\n")
|
|
fmt.Fprint(&sb, ")\n")
|
|
for _, desc := range Descriptors {
|
|
if !desc.RequiresLogin {
|
|
continue
|
|
}
|
|
desc.genTestRegisterAndLoginSuccess(&sb)
|
|
desc.genTestContinueUsingToken(&sb)
|
|
desc.genTestWithValidButExpiredToken(&sb)
|
|
desc.genTestWithRegisterAPIError(&sb)
|
|
desc.genTestWithLoginFailure(&sb)
|
|
desc.genTestRegisterAndLoginThenFail(&sb)
|
|
desc.genTestTheDatabaseIsReplaced(&sb)
|
|
desc.genTestRegisterAndLoginCannotWriteState(&sb)
|
|
desc.genTestReadStateDecodeFailure(&sb)
|
|
desc.genTestTheDatabaseIsReplacedThenFailure(&sb)
|
|
desc.genTestClockIsOffThenSuccess(&sb)
|
|
desc.genTestClockIsOffThen401(&sb)
|
|
desc.genTestClockIsOffThen500(&sb)
|
|
}
|
|
writefile(file, &sb)
|
|
}
|