...
 
Commits (6)
......@@ -14,10 +14,10 @@ import (
// Product defines the structure of a product
type Product struct {
ID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
ID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL" json:",omitempty"`
CreatedAt time.Time `json:",omitempty"`
UpdatedAt time.Time `json:",omitempty"`
DeletedAt *time.Time `json:",omitempty"`
Name string
Slug string
......@@ -28,20 +28,20 @@ var Products []Product
// Version defines the structure of a product
type Version struct {
ID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
ID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL" json:",omitempty"`
CreatedAt time.Time `json:",omitempty"`
UpdatedAt time.Time `json:",omitempty"`
DeletedAt *time.Time `json:",omitempty"`
Name string
Slug string
GitRepo string
Ignore bool
ProductID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL"`
Product Product
ProductID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL" json:",omitempty"`
Product Product `json:"-"`
Crashes []*Crash `gorm:"many2many:crash_versions;"`
Crashes []*Crash `gorm:"many2many:crash_versions;" json:"-"`
}
// Versions contains all currently available versions and is used for the switcher in the header
......@@ -49,69 +49,69 @@ var Versions []Version
// User defines the structure of a user
type User struct {
ID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
ID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL" json:",omitempty"`
CreatedAt time.Time `json:",omitempty"`
UpdatedAt time.Time `json:",omitempty"`
DeletedAt *time.Time `json:",omitempty"`
Name string
IsAdmin bool
Comments []Comment
Comments []Comment `json:"-"`
}
// Comment defines the structure of a comment
type Comment struct {
ID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
ID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL" json:",omitempty"`
CreatedAt time.Time `json:",omitempty"`
UpdatedAt time.Time `json:",omitempty"`
DeletedAt *time.Time `json:",omitempty"`
CrashID uuid.UUID `sql:"type:uuid DEFAULT NULL"`
ReportID uuid.UUID `sql:"type:uuid DEFAULT NULL"`
CrashID uuid.UUID `sql:"type:uuid DEFAULT NULL" json:",omitempty"`
ReportID uuid.UUID `sql:"type:uuid DEFAULT NULL" json:",omitempty"`
UserID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL"`
User User
UserID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL" json:",omitempty"`
User User `json:"-"`
Content template.HTML
}
// Crash database model
type Crash struct {
ID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
ID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL" json:",omitempty"`
CreatedAt time.Time `json:",omitempty"`
UpdatedAt time.Time `json:",omitempty"`
DeletedAt *time.Time `json:",omitempty"`
Signature string
Module string
AllCrashCount uint `gorm:"-"`
WinCrashCount uint `gorm:"-"`
MacCrashCount uint `gorm:"-"`
AllCrashCount uint `gorm:"-" json:",omitempty"`
WinCrashCount uint `gorm:"-" json:",omitempty"`
MacCrashCount uint `gorm:"-" json:",omitempty"`
Reports []Report
Comments []Comment
Reports []Report `json:",omitempty"`
Comments []Comment `json:",omitempty"`
FirstReported time.Time
LastReported time.Time
ProductID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL"`
Product Product
ProductID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL" json:",omitempty"`
Product Product `json:"-"`
Versions []*Version `gorm:"many2many:crash_versions;"`
Versions []*Version `gorm:"many2many:crash_versions;" json:",omitempty"`
Fixed *time.Time `sql:"DEFAULT NULL"`
}
// Report database model
type Report struct {
ID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
ID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL" json:",omitempty"`
CreatedAt time.Time `json:",omitempty"`
UpdatedAt time.Time `json:",omitempty"`
DeletedAt *time.Time `json:",omitempty"`
CrashID uuid.UUID `sql:"type:uuid DEFAULT NULL"`
Crash Crash
CrashID uuid.UUID `sql:"type:uuid DEFAULT NULL" json:",omitempty"`
Crash Crash `json:"-"`
ProcessUptime int
EMail string
......@@ -127,26 +127,26 @@ type Report struct {
CrashPath string
CrashLine int
Comments []Comment
Comments []Comment `json:"-"`
ReportContentJSON string `sql:"type:JSONB NOT NULL DEFAULT '{}'::JSONB" json:"-"`
Report ReportContent `gorm:"-"`
Report ReportContent `gorm:"-" json:",omitempty"`
ProductID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL"`
Product Product
ProductID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL" json:",omitempty"`
Product Product `json:"-"`
VersionID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL"`
Version Version
VersionID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL" json:",omitempty"`
Version Version `json:"-"`
ProcessingTime float64
}
// Symfile database model
type Symfile struct {
ID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
ID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL" json:",omitempty"`
CreatedAt time.Time `json:",omitempty"`
UpdatedAt time.Time `json:",omitempty"`
DeletedAt *time.Time `json:",omitempty"`
Os string
......@@ -154,11 +154,11 @@ type Symfile struct {
Code string `gorm:"unique;index"`
Name string
ProductID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL"`
Product Product
ProductID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL" json:",omitempty"`
Product Product `json:"-"`
VersionID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL"`
Version Version
VersionID uuid.UUID `sql:"type:uuid NOT NULL DEFAULT NULL" json:",omitempty"`
Version Version `json:"-"`
}
// ReportContent of a crashreport
......
This diff is collapsed.
......@@ -59,31 +59,36 @@ func initRouter() *gin.Engine {
// Admin JSON endpoints
apiv1 := auth.Group("/api/v1")
apiv1.GET("/products", APIGetProducts)
apiv1.GET("/products/:id", APIGetProduct)
apiv1.POST("/products", APINewProduct)
apiv1.PUT("/products/:id", APIUpdateProduct)
apiv1.DELETE("/products/:id", APIDeleteProduct)
apiv1.GET("/versions", APIGetVersions)
apiv1.GET("/versions/:id", APIGetVersion)
apiv1.POST("/versions", APINewVersion)
apiv1.PUT("/versions/:id", APIUpdateVersion)
apiv1.DELETE("/versions/:id", APIDeleteVersion)
apiv1.GET("/users", APIGetUsers)
apiv1.GET("/users/:id", APIGetUser)
apiv1.POST("/users", APINewUser)
apiv1.PUT("/users/:id", APIUpdateUser)
apiv1.DELETE("/users/:id", APIDeleteUser)
apiv1.GET("/stats", GetIndex)
apiv1.GET("/crashes", GetCrashes)
apiv1.GET("/crashes/:id", GetCrash)
apiv1.GET("/reports", GetReports)
apiv1.GET("/reports/:id", GetReport)
apiv1.GET("/symfiles", GetSymfiles)
apiv1.GET("/symfiles/:id", GetSymfile)
apiv1.GET("/crashes", APIv1GetCrashes)
apiv1.GET("/crashes/:id", APIv1GetCrash)
apiv1.GET("/reports", APIv1GetReports)
apiv1.GET("/reports/:id", APIv1GetReport)
apiv1.GET("/symfiles", APIv1GetSymfiles)
apiv1.GET("/symfiles/:id", APIv1GetSymfile)
apiv1.GET("/products", APIv1GetProducts)
apiv1.GET("/products/:id", APIv1GetProduct)
apiv1.POST("/products", APIv1NewProduct)
apiv1.PUT("/products/:id", APIv1UpdateProduct)
apiv1.DELETE("/products/:id", APIv1DeleteProduct)
apiv1.GET("/versions", APIv1GetVersions)
apiv1.GET("/versions/:id", APIv1GetVersion)
apiv1.POST("/versions", APIv1NewVersion)
apiv1.PUT("/versions/:id", APIv1UpdateVersion)
apiv1.DELETE("/versions/:id", APIv1DeleteVersion)
apiv1.GET("/users", APIv1GetUsers)
apiv1.GET("/users/:id", APIv1GetUser)
apiv1.POST("/users", APIv1NewUser)
apiv1.PUT("/users/:id", APIv1UpdateUser)
apiv1.DELETE("/users/:id", APIv1DeleteUser)
apiv1.GET("/comments", APIv1GetComments)
apiv1.GET("/comments/:id", APIv1GetComment)
apiv1.POST("/comments", APIv1NewComment)
apiv1.PUT("/comments/:id", APIv1UpdateComment)
apiv1.DELETE("/comments/:id", APIv1DeleteComment)
// simple-breakpad endpoints
router.GET("/", GetIndex)
......
package main
import (
"encoding/json"
"io/ioutil"
"log"
"net/http"
"strings"
"code.videolan.org/videolan/CrashDragon/database"
)
type apiProdResp struct {
Error string
Item database.Product
}
type apiProdListResp struct {
Error string
Items []database.Product
}
func testProduct() {
client := &http.Client{}
var Product database.Product
Product.Name = "Testproduct 1"
Product.Slug = "tp1"
j, err := json.Marshal(Product)
if err != nil {
log.Panic(err)
}
// Test POST
res, err := http.Post("http://admin:12345@127.0.0.1:8080/api/v1/products", "application/json", strings.NewReader(string(j)))
if err != nil {
log.Panic(err)
}
s, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Panic(err)
}
var Product2 apiProdResp
err = json.Unmarshal(s, &Product2)
if err != nil {
log.Panic(err)
}
if Product2.Item.Name == Product.Name && Product2.Item.Slug == Product.Slug {
log.Println("Product POSTed with ID", Product2.Item.ID.String())
} else {
log.Println("Should:", Product)
log.Println("Is:", Product2.Item)
log.Fatalln("Product could not be POSTed, error:", Product2.Error)
}
// Test LIST
res2, err := http.Get("http://admin:12345@127.0.0.1:8080/api/v1/products")
if err != nil {
log.Panic(err)
}
s2, err := ioutil.ReadAll(res2.Body)
if err != nil {
log.Panic(err)
}
var Product3 apiProdListResp
err = json.Unmarshal(s2, &Product3)
if err != nil {
log.Panic(err)
}
found := false
for _, prod := range Product3.Items {
if prod.Name == Product.Name && prod.Slug == Product.Slug {
found = true
log.Println("Product found with ID", prod.ID.String())
}
}
if found == false {
log.Println("Should:", Product)
log.Println("Is:", Product3.Items)
log.Fatalln("Product could not be found, error:", Product3.Error)
}
// Test GET
res3, err := http.Get("http://admin:12345@127.0.0.1:8080/api/v1/products/" + Product2.Item.ID.String())
if err != nil {
log.Panic(err)
}
s3, err := ioutil.ReadAll(res3.Body)
if err != nil {
log.Panic(err)
}
var Product4 apiProdResp
err = json.Unmarshal(s3, &Product4)
if err != nil {
log.Panic(err)
}
if Product4.Item.Name == Product.Name && Product4.Item.Slug == Product.Slug {
log.Println("Product GOT with ID", Product4.Item.ID.String())
} else {
log.Println("Should:", Product)
log.Println("Is:", Product4.Item)
log.Fatalln("Product could not be GOT, error:", Product4.Error)
}
// Test PUT
Product.Name = "Testproduct 2"
Product.Slug = "tp2"
j, err = json.Marshal(Product)
if err != nil {
log.Panic(err)
}
req, err := http.NewRequest("PUT", "http://admin:12345@127.0.0.1:8080/api/v1/products/"+Product2.Item.ID.String(), strings.NewReader(string(j)))
if err != nil {
log.Panic(err)
}
res4, err := client.Do(req)
if err != nil {
log.Panic(err)
}
s4, err := ioutil.ReadAll(res4.Body)
if err != nil {
log.Panic(err)
}
var Product5 apiProdResp
err = json.Unmarshal(s4, &Product5)
if err != nil {
log.Panic(err)
}
if Product5.Item.Name == Product.Name && Product5.Item.Slug == Product.Slug {
log.Println("Product PUTed with ID", Product5.Item.ID.String())
} else {
log.Println("Should:", Product)
log.Println("Is:", Product5.Item)
log.Fatalln("Product could not be PUTed, error:", Product5.Error)
}
// Test DELETE
req2, err := http.NewRequest("DELETE", "http://admin:12345@127.0.0.1:8080/api/v1/products/"+Product2.Item.ID.String(), nil)
if err != nil {
log.Panic(err)
}
res5, err := client.Do(req2)
if err != nil {
log.Panic(err)
}
s5, err := ioutil.ReadAll(res5.Body)
if err != nil {
log.Panic(err)
}
var Product6 apiProdResp
err = json.Unmarshal(s5, &Product6)
if err != nil {
log.Panic(err)
}
if Product6.Error == "" {
log.Println("Product DELETEd with ID", Product2.Item.ID.String())
} else {
log.Fatalln("Product could not be DELETEd, error:", Product6.Error)
}
}
func runTests() {
testProduct()
}
func main() {
log.Println("Running CrashDragon tests...")
runTests()
log.Println("All tests finished successfully")
}