1
0
mirror of https://github.com/raseels-repos/golang-saas-starter-kit.git synced 2025-06-15 00:15:15 +02:00

fixed internal package unittests

This commit is contained in:
Lee Brown
2019-06-24 22:41:21 -08:00
parent ca8670eadf
commit 8994ee4d1a
33 changed files with 1285 additions and 343 deletions

View File

@ -24,3 +24,53 @@ To build using the docker file, need to be in the project root directory. `Docke
```bash
docker build -f cmd/web-api/Dockerfile -t saas-web-api .
```
## API Documentation
Documentation is generated using [swag](https://github.com/swaggo/swag)
Download swag by using:
```bash
go get -u github.com/swaggo/swag/cmd/swag
```
Run `swag init` in the service's root folder which contains the main.go file. This will parse your comments and generate the required files (docs folder and docs/docs.go).
```bash
swag init
```
### Trouble shooting
If you run into errors running `swag init` try the following:
#### cannot find package
Try to install the packages to your $GOPATH.
```bash
GO111MODULE=off go get github.com/leodido/go-urn
GO111MODULE=off go get github.com/lib/pq/oid
GO111MODULE=off go get github.com/lib/pq/scram
GO111MODULE=off go get github.com/tinylib/msgp/msgp
GO111MODULE=off go get gopkg.in/DataDog/dd-trace-go.v1/ddtrace
```
#### error writing go.mod
Need to update pkg directory permissions.
Full error:
```bash
error writing go.mod: open /Users/leebrown/go/pkg/mod/github.com/lib/pq@v1.1.1/go.mod691440060.tmp: permission denied
```
Ensure the `pkg` directory used for go module cache has the correct permissions.
```bash
sudo chown -R $(whoami):staff ${HOME}/go/pkg
sudo chmod -R 755 ${HOME}/go/pkg
```

View File

@ -1,6 +1,6 @@
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
// This file was generated by swaggo/swag at
// 2019-06-24 15:42:25.999684 -0800 AKDT m=+0.030714022
// 2019-06-24 20:15:37.524606 -0800 AKDT m=+13.872100491
package docs
@ -16,10 +16,10 @@ var doc = `{
"info": {
"description": "This is a sample server celler server.",
"title": "SaaS Example API",
"termsOfService": "http://geeksinthewoods.com/terms",
"termsOfService": "/terms",
"contact": {
"name": "API Support",
"url": "https://gitlab.com/geeks-accelerator/oss/saas-starter-kit",
"url": "/support",
"email": "support@geeksinthewoods.com"
},
"license": {
@ -30,20 +30,140 @@ var doc = `{
},
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {},
"paths": {
"/accounts/{id}": {
"get": {
"description": "get string by ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"summary": "Read returns the specified account from the system.",
"operationId": "get-string-by-int",
"parameters": [
{
"type": "integer",
"description": "Account ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"$ref": "#/definitions/account.Account"
},
"headers": {
"Token": {
"type": "string",
"description": "qwerty"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "object",
"$ref": "#/definitions/web.Error"
}
},
"403": {
"description": "Forbidden",
"schema": {
"type": "object",
"$ref": "#/definitions/web.Error"
}
},
"404": {
"description": "Not Found",
"schema": {
"type": "object",
"$ref": "#/definitions/web.Error"
}
}
}
}
}
},
"definitions": {
"account.Account": {
"type": "object",
"properties": {
"address1": {
"type": "string"
},
"address2": {
"type": "string"
},
"archived_at": {
"type": "string"
},
"billing_user_id": {
"type": "string"
},
"city": {
"type": "string"
},
"country": {
"type": "string"
},
"created_at": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"region": {
"type": "string"
},
"signup_user_id": {
"type": "string"
},
"status": {
"type": "AccountStatus"
},
"timezone": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"zipcode": {
"type": "string"
}
}
},
"web.Error": {
"type": "object",
"properties": {
"err": {
"type": "error"
},
"fields": {
"type": "array",
"items": {
"type": "FieldError"
}
},
"status": {
"type": "integer"
}
}
}
},
"securityDefinitions": {
"ApiKeyAuth": {
"type": "apiKey",
"name": "Authorization",
"in": "header"
},
"BasicAuth": {
"type": "basic"
},
"OAuth2Password": {
"type": "oauth2",
"flow": "password",
"tokenUrl": "https://example.com/v1/oauth/token"
"tokenUrl": "/v1/oauth/token"
}
}
}`

View File

@ -3,10 +3,10 @@
"info": {
"description": "This is a sample server celler server.",
"title": "SaaS Example API",
"termsOfService": "http://geeksinthewoods.com/terms",
"termsOfService": "/terms",
"contact": {
"name": "API Support",
"url": "https://gitlab.com/geeks-accelerator/oss/saas-starter-kit",
"url": "/support",
"email": "support@geeksinthewoods.com"
},
"license": {
@ -17,20 +17,140 @@
},
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {},
"paths": {
"/accounts/{id}": {
"get": {
"description": "get string by ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"summary": "Read returns the specified account from the system.",
"operationId": "get-string-by-int",
"parameters": [
{
"type": "integer",
"description": "Account ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"$ref": "#/definitions/account.Account"
},
"headers": {
"Token": {
"type": "string",
"description": "qwerty"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "object",
"$ref": "#/definitions/web.Error"
}
},
"403": {
"description": "Forbidden",
"schema": {
"type": "object",
"$ref": "#/definitions/web.Error"
}
},
"404": {
"description": "Not Found",
"schema": {
"type": "object",
"$ref": "#/definitions/web.Error"
}
}
}
}
}
},
"definitions": {
"account.Account": {
"type": "object",
"properties": {
"address1": {
"type": "string"
},
"address2": {
"type": "string"
},
"archived_at": {
"type": "string"
},
"billing_user_id": {
"type": "string"
},
"city": {
"type": "string"
},
"country": {
"type": "string"
},
"created_at": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"region": {
"type": "string"
},
"signup_user_id": {
"type": "string"
},
"status": {
"type": "AccountStatus"
},
"timezone": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"zipcode": {
"type": "string"
}
}
},
"web.Error": {
"type": "object",
"properties": {
"err": {
"type": "error"
},
"fields": {
"type": "array",
"items": {
"type": "FieldError"
}
},
"status": {
"type": "integer"
}
}
}
},
"securityDefinitions": {
"ApiKeyAuth": {
"type": "apiKey",
"name": "Authorization",
"in": "header"
},
"BasicAuth": {
"type": "basic"
},
"OAuth2Password": {
"type": "oauth2",
"flow": "password",
"tokenUrl": "https://example.com/v1/oauth/token"
"tokenUrl": "/v1/oauth/token"
}
}
}

View File

@ -1,27 +1,106 @@
basePath: '{{.BasePath}}'
definitions:
account.Account:
properties:
address1:
type: string
address2:
type: string
archived_at:
type: string
billing_user_id:
type: string
city:
type: string
country:
type: string
created_at:
type: string
id:
type: string
name:
type: string
region:
type: string
signup_user_id:
type: string
status:
type: AccountStatus
timezone:
type: string
updated_at:
type: string
zipcode:
type: string
type: object
web.Error:
properties:
err:
type: error
fields:
items:
type: FieldError
type: array
status:
type: integer
type: object
host: '{{.Host}}'
info:
contact:
email: support@geeksinthewoods.com
name: API Support
url: https://gitlab.com/geeks-accelerator/oss/saas-starter-kit
url: /support
description: This is a sample server celler server.
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
termsOfService: http://geeksinthewoods.com/terms
termsOfService: /terms
title: SaaS Example API
version: '{{.Version}}'
paths: {}
paths:
/accounts/{id}:
get:
consumes:
- application/json
description: get string by ID
operationId: get-string-by-int
parameters:
- description: Account ID
in: path
name: id
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
headers:
Token:
description: qwerty
type: string
schema:
$ref: '#/definitions/account.Account'
type: object
"400":
description: Bad Request
schema:
$ref: '#/definitions/web.Error'
type: object
"403":
description: Forbidden
schema:
$ref: '#/definitions/web.Error'
type: object
"404":
description: Not Found
schema:
$ref: '#/definitions/web.Error'
type: object
summary: Read returns the specified account from the system.
securityDefinitions:
ApiKeyAuth:
in: header
name: Authorization
type: apiKey
BasicAuth:
type: basic
OAuth2Password:
flow: password
tokenUrl: https://example.com/v1/oauth/token
tokenUrl: /v1/oauth/token
type: oauth2
swagger: "2.0"

View File

@ -39,7 +39,19 @@ func (a *Account) Find(ctx context.Context, w http.ResponseWriter, r *http.Reque
return web.RespondJson(ctx, w, res, http.StatusOK)
}
// Read returns the specified account from the system.
// Read godoc
// @Summary Read returns the specified account from the system.
// @Description get string by ID
// @ID get-string-by-int
// @Accept json
// @Produce json
// @Param id path int true "Account ID"
// @Success 200 {object} account.Account
// @Header 200 {string} Token "qwerty"
// @Failure 400 {object} web.Error
// @Failure 403 {object} web.Error
// @Failure 404 {object} web.Error
// @Router /accounts/{id} [get]
func (a *Account) Read(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
claims, ok := ctx.Value(auth.Key).(auth.Claims)
if !ok {

View File

@ -40,7 +40,7 @@ func API(shutdown chan os.Signal, log *log.Logger, masterDB *sqlx.DB, redis *red
app.Handle("PATCH", "/v1/users/switch-account/:accountId", u.SwitchAccount, mid.Authenticate(authenticator))
// This route is not authenticated
app.Handle("GET", "/v1/oauth/token", u.Token)
app.Handle("POST", "/v1/oauth/token", u.Token)
// Register account endpoints.
a := Account{
@ -65,8 +65,10 @@ func API(shutdown chan os.Signal, log *log.Logger, masterDB *sqlx.DB, redis *red
app.Handle("DELETE", "/v1/projects/:id", p.Delete, mid.Authenticate(authenticator), mid.HasRole(auth.RoleAdmin))
// Register swagger documentation.
app.Handle("GET", "/swagger/", saasSwagger.WrapHandler, mid.Authenticate(authenticator))
app.Handle("GET", "/swagger/*", saasSwagger.WrapHandler, mid.Authenticate(authenticator))
// TODO: Add authentication. Current authenticator requires an Authorization header
// which breaks the browser experience.
app.Handle("GET", "/swagger/", saasSwagger.WrapHandler)
app.Handle("GET", "/swagger/*", saasSwagger.WrapHandler)
return app
}

View File

@ -42,23 +42,17 @@ var service = "WEB_API"
// @title SaaS Example API
// @description This is a sample server celler server.
// @termsOfService http://geeksinthewoods.com/terms
// @termsOfService http://example.com/terms
// @contact.name API Support
// @contact.email support@geeksinthewoods.com
// @contact.url https://gitlab.com/geeks-accelerator/oss/saas-starter-kit
// @contact.url http://example.com/support
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @securityDefinitions.basic BasicAuth
// @securityDefinitions.apikey ApiKeyAuth
// @in header
// @name Authorization
// @securitydefinitions.oauth2.password OAuth2Password
// @tokenUrl https://example.com/v1/oauth/token
// @tokenUrl /v1/oauth/token
func main() {
@ -101,7 +95,7 @@ func main() {
Database string `default:"shared" envconfig:"DATABASE"`
Driver string `default:"postgres" envconfig:"DRIVER"`
Timezone string `default:"utc" envconfig:"TIMEZONE"`
DisableTLS bool `default:"false" envconfig:"DISABLE_TLS"`
DisableTLS bool `default:"true" envconfig:"DISABLE_TLS"`
}
Trace struct {
Host string `default:"127.0.0.1" envconfig:"DD_TRACE_AGENT_HOSTNAME"`

View File

@ -0,0 +1,4 @@
export WEB_API_DB_HOST=127.0.0.1:5433
export WEB_API_DB_USER=postgres
export WEB_API_DB_PASS=postgres
export WEB_API_DB_DISABLE_TLS=true