Commit 5d0caa15 authored by Julien Schröter's avatar Julien Schröter Committed by Simon Metzler

Return resource_id of image in api calls instead of uri

parent 0ba634e5
......@@ -1225,7 +1225,8 @@ components:
type: boolean
image:
description: URI to an image on the resource server.
type: string
type: integer
format: uint32
text:
type: string
minLength: 2
......@@ -1256,7 +1257,7 @@ components:
image:
description: A nice image that can be displayed in some pool selection UI.
type: integer
format: uint32a
format: uint32
selected:
description: Whether the user making the request has selected this pool.
type: boolean
......@@ -1274,8 +1275,8 @@ components:
format: uint32
image:
description: uri of the image resource. The actual image can be queried form /resource separately using this uri.
type: string
format: uri
type: integer
format: uint32
level:
description: Level a user need to have to unlock this avatar.
type: integer
......
......@@ -29,7 +29,7 @@ func (MySQLAvatarQuery) Select(userID uint32) ([]schemas.AvatarSchema, error) {
return nil, fmt.Errorf("Could not ping database connection. ")
}
stmt, errPrep := db.Prepare("SELECT idavatar, resource.uri, avatar.level FROM avatar INNER JOIN user ON (iduser=? AND user.level>=avatar.level) JOIN resource ON idresource=image")
stmt, errPrep := db.Prepare("SELECT idavatar, avatar.image, avatar.level FROM avatar INNER JOIN user ON (iduser=? AND user.level>=avatar.level)")
// check for problems with the created query
if errPrep != nil {
......@@ -81,7 +81,7 @@ func (MySQLAvatarQuery) SelectAll() ([]schemas.AvatarSchema, error) {
return nil, fmt.Errorf("Could not ping database connection. ")
}
stmt, errPrep := db.Prepare("SELECT idavatar, resource.uri, level FROM avatar JOIN resource ON idresource=image")
stmt, errPrep := db.Prepare("SELECT idavatar, image, level FROM avatar")
// check for problems with the created query
if errPrep != nil {
......
......@@ -21,7 +21,7 @@ import (
// TODO: Move to schemas and make public
type nullableAvatar struct {
ID sql.NullInt64
Image sql.NullString
Image sql.NullInt64
Level sql.NullInt64
}
......@@ -52,7 +52,7 @@ type nullablePool struct {
ID sql.NullInt64
Name sql.NullString
Code sql.NullString
Image sql.NullString
Image sql.NullInt64
}
type nullableParticipant struct {
......@@ -84,7 +84,7 @@ func (nA *nullableAvatar) ToAvatar(avatar *schemas.AvatarSchema) bool {
avatar.ID = uint32(nA.ID.Int64)
}
if nA.Image.Valid {
avatar.Image = string(nA.Image.String)
avatar.Image = uint32(nA.Image.Int64)
}
if nA.Level.Valid {
avatar.Level = uint32(nA.Level.Int64)
......@@ -185,7 +185,7 @@ func (nP *nullablePool) ToPool(pool *schemas.PoolSchema) {
pool.ID = uint32(nP.ID.Int64)
pool.Name = nP.Name.String
pool.Code = nP.Code.String
pool.Image = nP.Image.String
pool.Image = uint32(nP.Image.Int64)
}
// ErrNotPermitted is returned when a user tries to access a duel the user does not participate in
......@@ -231,7 +231,7 @@ var ErrBadRequest = errors.New("The request was either formatted incorrectly or
const TotalRounds = 2
const QuestionsPerRound = 2
const queryDuelsByID = "SELECT `duel`.`idduel`, `duel`.`round_current`, `duel`.`round_max`, `duel`.`started_on`, `duel`.`modified_on`, `duel`.`finished_on`, `duel`.`running`, `duel`.`started`, `duel`.`next`, `duel_player_score`.`score`, `participant`.`iduser`, `participant`.`username`, idavatar, avatar_resource.uri, avatar.level, title.idtitle, title.name, subject.idsubject, subject.name, subject.shortform, subject.department, subject.description, title.unlock_score, title.unlock_win, `round`.`idround`, `round`.`number`, `round`.`started`, `pool`.`idpool`, `pool`.`name`, `pool`.`shortform`, `poolimage_resource`.`uri`" +
const queryDuelsByID = "SELECT `duel`.`idduel`, `duel`.`round_current`, `duel`.`round_max`, `duel`.`started_on`, `duel`.`modified_on`, `duel`.`finished_on`, `duel`.`running`, `duel`.`started`, `duel`.`next`, `duel_player_score`.`score`, `participant`.`iduser`, `participant`.`username`, idavatar, avatar.image, avatar.level, title.idtitle, title.name, subject.idsubject, subject.name, subject.shortform, subject.department, subject.description, title.unlock_score, title.unlock_win, `round`.`idround`, `round`.`number`, `round`.`started`, `pool`.`idpool`, `pool`.`name`, `pool`.`shortform`, `pool`.`image`" +
"FROM `duel`" +
......@@ -240,14 +240,12 @@ const queryDuelsByID = "SELECT `duel`.`idduel`, `duel`.`round_current`, `duel`.`
"LEFT JOIN `title` ON (`idtitle` = `participant`.`selected_title`)" +
"LEFT JOIN `subject` ON (`idsubject` = `title`.`subject`)" +
"LEFT JOIN `avatar` ON (`idavatar` = `participant`.`selected_avatar`)" +
"LEFT JOIN `resource` AS `avatar_resource` ON (`avatar_resource`.`idresource` = `avatar`.`image`)" +
"LEFT JOIN `round` ON (`round`.`duel` = `duel`.`idduel`)" +
"LEFT JOIN `pool` ON (`round`.`pool` = `pool`.`idpool`)" +
"LEFT JOIN `resource` AS `poolimage_resource` ON (`poolimage_resource`.`idresource` = `pool`.`image`)" +
"WHERE `idduel` = ?;"
const queryDuelsByUser = "SELECT `duel`.`idduel`, `duel`.`round_current`, `duel`.`round_max`, `duel`.`started_on`, `duel`.`modified_on`, `duel`.`finished_on`, `duel`.`running`, `duel`.`started`, `duel`.`next`, `duel_player_score`.`score`, `participant`.`iduser`, `participant`.`username`, idavatar, avatar_resource.uri, avatar.level, title.idtitle, title.name, subject.idsubject, subject.name, subject.shortform, subject.department, subject.description, title.unlock_score, title.unlock_win, `round`.`idround`, `round`.`number`, `round`.`started`, `pool`.`idpool`, `pool`.`name`, `pool`.`shortform`, `poolimage_resource`.`uri`" +
const queryDuelsByUser = "SELECT `duel`.`idduel`, `duel`.`round_current`, `duel`.`round_max`, `duel`.`started_on`, `duel`.`modified_on`, `duel`.`finished_on`, `duel`.`running`, `duel`.`started`, `duel`.`next`, `duel_player_score`.`score`, `participant`.`iduser`, `participant`.`username`, idavatar, avatar.image, avatar.level, title.idtitle, title.name, subject.idsubject, subject.name, subject.shortform, subject.department, subject.description, title.unlock_score, title.unlock_win, `round`.`idround`, `round`.`number`, `round`.`started`, `pool`.`idpool`, `pool`.`name`, `pool`.`shortform`, `pool`.`image`" +
"FROM `duel`" +
......@@ -256,11 +254,9 @@ const queryDuelsByUser = "SELECT `duel`.`idduel`, `duel`.`round_current`, `duel`
"LEFT JOIN `title` ON (`idtitle` = `participant`.`selected_title`)" +
"LEFT JOIN `subject` ON (`idsubject` = `title`.`subject`)" +
"LEFT JOIN `avatar` ON (`idavatar` = `participant`.`selected_avatar`)" +
"LEFT JOIN `resource` AS `avatar_resource` ON (`avatar_resource`.`idresource` = `avatar`.`image`)" +
"LEFT JOIN `round` ON (`round`.`duel` = `duel`.`idduel`)" +
"LEFT JOIN `pool` ON (`round`.`pool` = `pool`.`idpool`)" +
"LEFT JOIN `resource` AS `poolimage_resource` ON (`poolimage_resource`.`idresource` = `pool`.`image`)" +
"WHERE `idduel` IN (SELECT `duel` FROM `duel_player_score` WHERE `user` = ?)" +
"ORDER BY `idduel`"
......@@ -911,18 +907,15 @@ func (m *MySQLDuelQuery) GetRoundByID(roundID uint32, userID uint32) (*schemas.F
return nil, fmt.Errorf("failed to connect to database." + errPing.Error())
}
queryRoundByID := "SELECT round.idround, round.duel, pool.idpool, pool.name, pool.shortform, pool_resource.uri, round.number, user.iduser, user.username, idavatar, avatar_resource.uri, avatar.level, title.idtitle, title.name, title_subject.idsubject, title_subject.name, title_subject.shortform, title_subject.department, title_subject.description, title.unlock_score, title.unlock_win, question.idquestion, maintainer.name, question.text, question_resource.uri, subject.name, question.answertype FROM round" +
queryRoundByID := "SELECT round.idround, round.duel, pool.idpool, pool.name, pool.shortform, pool.image, round.number, user.iduser, user.username, idavatar, avatar.image, avatar.level, title.idtitle, title.name, title_subject.idsubject, title_subject.name, title_subject.shortform, title_subject.department, title_subject.description, title.unlock_score, title.unlock_win, question.idquestion, maintainer.name, question.text, question.image, subject.name, question.answertype FROM round" +
" LEFT JOIN user ON (user.iduser=round.started)" +
" LEFT JOIN title ON (title.idtitle=user.selected_title)" +
" LEFT JOIN avatar ON (idavatar=user.selected_avatar)" +
" LEFT JOIN subject AS title_subject ON (title_subject.idsubject=title.subject)" +
" LEFT JOIN resource AS avatar_resource ON (avatar_resource.idresource=avatar.image)" +
" LEFT JOIN roundquestion ON (roundquestion.round=round.idround)" +
" LEFT JOIN question ON (roundquestion.question=question.idquestion)" +
" LEFT JOIN pool ON (round.pool=pool.idpool)" +
" LEFT JOIN resource AS pool_resource ON (pool_resource.idresource=pool.image)" +
" LEFT JOIN subject ON (subject.idsubject=question.subject)" +
" LEFT JOIN resource AS question_resource ON(question_resource.idresource=question.image)" +
" LEFT JOIN maintainer ON (maintainer.idmaintainer=question.author)" +
" WHERE idround=?;"
......@@ -943,9 +936,9 @@ func (m *MySQLDuelQuery) GetRoundByID(roundID uint32, userID uint32) (*schemas.F
for res.Next() {
var question schemas.QuestionSchema
var nullAuthor, nullText, nullImageURI, nullSubject, nullAnswerType sql.NullString
var nullAuthor, nullText, nullSubject, nullAnswerType sql.NullString
var nullRound nullableRound
var nullID sql.NullInt64
var nullID, nullImage sql.NullInt64
errScan := res.Scan(
&nullRound.ID,
......@@ -972,7 +965,7 @@ func (m *MySQLDuelQuery) GetRoundByID(roundID uint32, userID uint32) (*schemas.F
&nullID,
&nullAuthor,
&nullText,
&nullImageURI,
&nullImage,
&nullSubject,
&nullAnswerType)
......@@ -994,7 +987,7 @@ func (m *MySQLDuelQuery) GetRoundByID(roundID uint32, userID uint32) (*schemas.F
question.ID = uint32(nullID.Int64)
question.Author = nullAuthor.String
question.Text = nullText.String
question.Image = nullImageURI.String
question.Image = uint32(nullImage.Int64)
question.Subject = nullSubject.String
if pendings, errPednings := m.pendingQuestions(db, round.ID, userID); errPednings != nil {
......@@ -1051,22 +1044,22 @@ func (m *MySQLDuelQuery) getAnswer(db dbhandler.DBAccess, questionID uint32, ans
func (m *MySQLDuelQuery) getExplanation(db dbhandler.DBAccess, questionID uint32) (*schemas.ExplanationSchema, error) {
queryString := "SELECT text, uri FROM explanation LEFT JOIN resource ON idresource=image WHERE question=?"
queryString := "SELECT text, image FROM explanation WHERE question=?"
var text, uri sql.NullString
var text sql.NullString
var image sql.NullInt64
res := db.QueryRow(queryString, questionID)
if errScan := res.Scan(&text, &uri); errScan != nil {
if errScan := res.Scan(&text, &image); errScan != nil {
return nil, fmt.Errorf("failed to query explanation for question %d. %s SQL: %s", questionID, errScan.Error(), queryString)
}
return &schemas.ExplanationSchema{Text: text.String, Image: uri.String}, nil
return &schemas.ExplanationSchema{Text: text.String, Image: uint32(image.Int64)}, nil
}
func (m *MySQLDuelQuery) getOptionAnswer(db dbhandler.DBAccess, questionID uint32) (*schemas.MultipleChoiceAnswerSchema, error) {
queryString := "SELECT idoptionanswer, correct, option_resource.uri, text FROM optionanswer" +
" LEFT JOIN resource AS option_resource ON (option_resource.idresource=optionanswer.image)" +
queryString := "SELECT idoptionanswer, correct, image, text FROM optionanswer" +
" WHERE optionanswer.question=? ORDER BY idoptionanswer;"
res, errQuery := db.Query(queryString, questionID)
......@@ -1078,13 +1071,14 @@ func (m *MySQLDuelQuery) getOptionAnswer(db dbhandler.DBAccess, questionID uint3
for res.Next() {
var option schemas.MultipleChoiceAnswerItemSchema
var nullText, nullImage sql.NullString
var nullText sql.NullString
var nullImage sql.NullInt64
errScan := res.Scan(&option.ID, &option.Correct, &nullImage, &nullText)
if errScan != nil {
return nil, errScan
}
option.Text = nullText.String
option.Image = nullImage.String
option.Image = uint32(nullImage.Int64)
options = append(options, option)
}
......
......@@ -20,7 +20,7 @@ type MySQLPoolQuery struct{}
// Select returns a list of all available playable pools.
func (m MySQLPoolQuery) Select(userID uint32) ([]schemas.PoolSchema, error) {
queryString := "SELECT `idpool`, `name`, `shortform`, `resource`.`uri`, `idpool` IN (SELECT DISTINCT pool from user_pool WHERE user=?) AS selected FROM `pool` LEFT JOIN `resource` ON `idresource` = `image` WHERE `idpool` IN (SELECT `pool` FROM `pool_question` GROUP BY `pool` HAVING COUNT(DISTINCT `question`) >= ?)"
queryString := "SELECT `idpool`, `name`, `shortform`, `image`, `idpool` IN (SELECT DISTINCT pool from user_pool WHERE user=?) AS selected FROM `pool` WHERE `idpool` IN (SELECT `pool` FROM `pool_question` GROUP BY `pool` HAVING COUNT(DISTINCT `question`) >= ?)"
db, err := dbhandler.GetDBConnection()
......@@ -129,7 +129,7 @@ func (m MySQLPoolQuery) PatchUserPools(userID uint32, selection []uint32) error
func (MySQLPoolQuery) getAllPools(db dbhandler.DBAccess) ([]schemas.PoolSchema, error) {
// Fetch available pools from database
rows, errRows := db.Query("SELECT `idpool`, `name`, `shortform`, `resource`.`uri` FROM `pool` LEFT JOIN `resource` ON `idresource` = `image`")
rows, errRows := db.Query("SELECT `idpool`, `name`, `shortform`, `image` FROM `pool`")
// Check whether query failed
if errRows != nil {
......
......@@ -152,7 +152,7 @@ func (MySQLUserQuery) Select(id uint32) ([]schemas.FullUserSchema, error) {
}
//create statement to fetch user from db
stmt, err := db.Prepare("select iduser, time_registered, username, email, semester, experience, idavatar, resource.uri, avatar.level, title.idtitle, title.name, subject.idsubject, subject.name, subject.shortform, subject.department, subject.description, title.unlock_score, title.unlock_win, verified, user.university, user.level FROM user LEFT JOIN title ON (title.idtitle=selected_title) LEFT JOIN subject ON (idsubject=title.subject) LEFT JOIN avatar ON (idavatar=selected_avatar) LEFT JOIN resource ON (idresource=avatar.image) WHERE iduser = ?")
stmt, err := db.Prepare("select iduser, time_registered, username, email, semester, experience, idavatar, avatar.image, avatar.level, title.idtitle, title.name, subject.idsubject, subject.name, subject.shortform, subject.department, subject.description, title.unlock_score, title.unlock_win, verified, user.university, user.level FROM user LEFT JOIN title ON (title.idtitle=selected_title) LEFT JOIN subject ON (idsubject=title.subject) LEFT JOIN avatar ON (idavatar=selected_avatar) WHERE iduser = ?")
if err != nil {
return nil, fmt.Errorf("Could not prepare sql statement to retrieve user from Datase. " + err.Error())
}
......@@ -220,7 +220,7 @@ func (MySQLUserQuery) SelectByUsername(username string) ([]schemas.InfoUserSchem
}
//create statement to fetch user from db
stmt, err := db.Prepare("select iduser, username, idavatar, resource.uri, avatar.level, title.idtitle, title.name, subject.idsubject, subject.name, subject.shortform, subject.department, subject.description, title.unlock_score, title.unlock_win FROM user LEFT JOIN title ON (title.idtitle=selected_title) LEFT JOIN subject ON (idsubject=title.subject) LEFT JOIN avatar ON (idavatar=selected_avatar) LEFT JOIN resource ON (idresource=avatar.image) WHERE username = ?")
stmt, err := db.Prepare("select iduser, username, idavatar, avatar.image, avatar.level, title.idtitle, title.name, subject.idsubject, subject.name, subject.shortform, subject.department, subject.description, title.unlock_score, title.unlock_win FROM user LEFT JOIN title ON (title.idtitle=selected_title) LEFT JOIN subject ON (idsubject=title.subject) LEFT JOIN avatar ON (idavatar=selected_avatar) WHERE username = ?")
if err != nil {
return nil, fmt.Errorf("Could not prepare sql statement to retrieve user from Datase. " + err.Error())
}
......@@ -428,7 +428,7 @@ func (MySQLUserQuery) SelectAll() ([]schemas.InfoUserSchema, error) {
return nil, errors.New("Unable to ping database")
}
stmt, errPrep := db.Prepare("SELECT iduser, username, idavatar, resource.uri, avatar.level, title.idtitle, title.name, subject.idsubject, subject.name, subject.shortform, subject.department, subject.description, title.unlock_score, title.unlock_win FROM user LEFT JOIN title ON (title.idtitle=selected_title) LEFT JOIN subject ON (idsubject=title.subject) LEFT JOIN avatar ON (idavatar=selected_avatar) LEFT JOIN resource ON (idresource=avatar.image)")
stmt, errPrep := db.Prepare("SELECT iduser, username, idavatar, avatar.image, avatar.level, title.idtitle, title.name, subject.idsubject, subject.name, subject.shortform, subject.department, subject.description, title.unlock_score, title.unlock_win FROM user LEFT JOIN title ON (title.idtitle=selected_title) LEFT JOIN subject ON (idsubject=title.subject) LEFT JOIN avatar ON (idavatar=selected_avatar)")
if errPrep != nil {
return nil, errors.New("An error occurred while preparing database access. " + errDB.Error())
......
......@@ -2,6 +2,6 @@ package schemas
type AvatarSchema struct {
ID uint32 `json:"id"`
Image string `json:"image"`
Image uint32 `json:"image"`
Level uint32 `json:"level"`
}
package schemas
type PoolSchema struct {
ID uint32 `json:"id" binding:"required"`
Name string `json:"name" binding:"required"`
Code string `json:"code" binding:"required"`
Image string `json:"image" binding:"required"`
ID uint32 `json:"id" binding:"required"`
Name string `json:"name" binding:"required"`
Code string `json:"code" binding:"required"`
Image uint32 `json:"image" binding:"required"`
// use of pointer leads to omit of only nil but not false.
Selected *bool `json:"selected,omitempty"`
Selected *bool `json:"selected,omitempty"`
}
......@@ -2,14 +2,14 @@ package schemas
type ExplanationSchema struct {
Text string `json:"text" binding:"required"`
Image string `json:"image,omitempty"`
Image uint32 `json:"image,omitempty"`
}
type QuestionSchema struct {
ID uint32 `json:"id" binding:"required"`
Author string `json:"author"`
Text string `json:"text" binding:"required"`
Image string `json:"image,omitempty"`
Image uint32 `json:"image,omitempty"`
Subject string `json:"subject" binding:"required"`
Pool PoolSchema `json:"pool" binding:"required"`
Answer AnswerSchema `json:"answer" binding:"required"`
......@@ -23,7 +23,7 @@ type MultipleChoiceAnswerSchema struct {
type MultipleChoiceAnswerItemSchema struct {
ID uint32 `json:"id"`
Correct bool `json:"correct"`
Image string `json:"image,omitempty"`
Image uint32 `json:"image,omitempty"`
Text string `json:"text,omitempty"`
}
......
......@@ -11,9 +11,9 @@ import (
)
var avatars = []schemas.AvatarSchema{
schemas.AvatarSchema{ID: 0, Image: "uri5", Level: 0},
schemas.AvatarSchema{ID: 1, Image: "uri4", Level: 5},
schemas.AvatarSchema{ID: 2, Image: "uri3", Level: 10},
schemas.AvatarSchema{ID: 0, Image: 5, Level: 0},
schemas.AvatarSchema{ID: 1, Image: 4, Level: 5},
schemas.AvatarSchema{ID: 2, Image: 3, Level: 10},
}
type mockAvatar struct{}
......@@ -41,7 +41,7 @@ func Test_getAvatars200(t *testing.T) {
router.ServeHTTP(res, req)
assert.Equal(t, 200, res.Code)
assert.JSONEq(t, "[{\"id\":0,\"image\":\"uri5\",\"level\":0},{\"id\":1,\"image\":\"uri4\",\"level\":5}]", res.Body.String())
assert.JSONEq(t, "[{\"id\":0,\"image\":5,\"level\":0},{\"id\":1,\"image\":4,\"level\":5}]", res.Body.String())
}
func Test_getAvatars401(t *testing.T) {
......@@ -70,7 +70,7 @@ func Test_getAllAvatars200(t *testing.T) {
router.ServeHTTP(res, req)
assert.Equal(t, 200, res.Code)
assert.JSONEq(t, "[{\"id\":0,\"image\":\"uri5\",\"level\":0},{\"id\":1,\"image\":\"uri4\",\"level\":5},{\"id\":2,\"image\":\"uri3\",\"level\":10}]", res.Body.String())
assert.JSONEq(t, "[{\"id\":0,\"image\":5,\"level\":0},{\"id\":1,\"image\":4,\"level\":5},{\"id\":2,\"image\":3,\"level\":10}]", res.Body.String())
}
func Test_getAllAvatars401(t *testing.T) {
......
......@@ -189,7 +189,7 @@ func newMockDuel() mockDuel {
ID: 1,
Name: "Sample 1",
Code: "sample-1",
Image: "uri1",
Image: 1,
},
UserStarted: getMockUserInfo(mockUsers[2]),
},
......@@ -200,7 +200,7 @@ func newMockDuel() mockDuel {
ID: 2,
Name: "Sample 2",
Code: "sample-2",
Image: "uri2",
Image: 2,
},
UserStarted: getMockUserInfo(mockUsers[1]),
},
......@@ -231,7 +231,7 @@ func newMockDuel() mockDuel {
ID: 3,
Name: "Sample 3",
Code: "sample-3",
Image: "uri3",
Image: 3,
},
UserStarted: getMockUserInfo(mockUsers[1]),
},
......@@ -242,7 +242,7 @@ func newMockDuel() mockDuel {
ID: 4,
Name: "Sample 4",
Code: "sample-4",
Image: "uri4",
Image: 4,
},
UserStarted: getMockUserInfo(mockUsers[3]),
},
......@@ -253,7 +253,7 @@ func newMockDuel() mockDuel {
ID: 1,
Name: "Sample 1",
Code: "sample-1",
Image: "uri1",
Image: 1,
},
UserStarted: getMockUserInfo(mockUsers[1]),
},
......@@ -264,7 +264,7 @@ func newMockDuel() mockDuel {
ID: 2,
Name: "Sample 2",
Code: "sample-2",
Image: "uri2",
Image: 2,
},
UserStarted: getMockUserInfo(mockUsers[3]),
},
......@@ -277,19 +277,19 @@ func newMockDuel() mockDuel {
ID: 1,
Name: "Mathematik 1 für Informatiker",
Code: "math1",
Image: "uri1",
Image: 1,
},
schemas.PoolSchema{
ID: 2,
Name: "Funktionale und Objektorientierte Programmierkonzepte",
Code: "fop",
Image: "uri2",
Image: 2,
},
schemas.PoolSchema{
ID: 3,
Name: "Automaten, formale Sprachen und Entscheidbarkeit",
Code: "afe",
Image: "uri8",
Image: 8,
},
}
......
......@@ -13,7 +13,7 @@
},
"avatar":{
"id": 1,
"image": "a01_v2.png",
"image": 1,
"level": 1
}
},
......@@ -29,7 +29,7 @@
},
"avatar":{
"id": 1,
"image": "a01_v2.png",
"image": 1,
"level": 1
}
},
......@@ -47,7 +47,7 @@
},
"avatar":{
"id": 1,
"image": "a01_v2.png",
"image": 1,
"level": 1
},
"score": 0
......@@ -64,7 +64,7 @@
},
"avatar":{
"id": 1,
"image": "a01_v2.png",
"image": 1,
"level": 1
},
"score":16
......@@ -98,7 +98,7 @@
},
"avatar":{
"id": 1,
"image": "a01_v2.png",
"image": 1,
"level": 1
}
}
......
......@@ -20,7 +20,7 @@
},
"avatar":{
"id": 1,
"image": "a01_v2.png",
"image": 1,
"level": 1
}
},
......
{
"id":2,
"number":1,
"pool":{
"id":1,
"name":"pool1",
"code":"p1",
"image":"<<PRESENCE>>"
"id": 2,
"number": 1,
"pool": {
"id": 1,
"name": "pool1",
"code": "p1",
"image": "<<PRESENCE>>"
},
"is-answered": false,
"started": {
"id": 2,
"username": "user2",
"title": {
"id": 1,
"name": "Test-Title",
"subject": "<<PRESENCE>>",
"unlock_score": 1,
"unlock_win": 1
},
"is-answered":false,
"started": {
"id": 2,
"username":"user2",
"title": {
"id": 1,
"name": "Test-Title",
"subject": "<<PRESENCE>>",
"unlock_score": 1,
"unlock_win": 1
"avatar": {
"id": 1,
"image": 1,
"level": 1
}
},
"questions": [
{
"id": "<<PRESENCE>>",
"author": "<<PRESENCE>>",
"text": "<<PRESENCE>>",
"subject": "<<PRESENCE>>",
"pool": {
"id": 1,
"name": "pool1",
"code": "p1",
"image": "<<PRESENCE>>"
},
"answer": {
"id": "<<PRESENCE>>",
"type": "option",
"option-answer": {
"options": [
{ "id": "<<PRESENCE>>", "correct": true, "text": "A" },
{ "id": "<<PRESENCE>>", "correct": false, "text": "B" },
{ "id": "<<PRESENCE>>", "correct": false, "text": "C" },
{ "id": "<<PRESENCE>>", "correct": false, "text": "D" }
]
},
"avatar":{
"id": 1,
"image": "a01_v2.png",
"level": 1
}
"text-answer": null
},
"explanation": {
"text": "<<PRESENCE>>"
}
},
"questions":[
{
"id": "<<PRESENCE>>",
"author": "<<PRESENCE>>",
"text": "<<PRESENCE>>",
"subject": "<<PRESENCE>>",
"pool":{
"id":1,
"name":"pool1",
"code":"p1",
"image":"<<PRESENCE>>"
},
"answer":{
"id":"<<PRESENCE>>",
"type":"option",
"option-answer":{
"options":[
{"id": "<<PRESENCE>>", "correct": true, "text": "A"},
{"id": "<<PRESENCE>>", "correct": false, "text": "B"},
{"id": "<<PRESENCE>>", "correct": false, "text": "C"},
{"id": "<<PRESENCE>>", "correct": false, "text": "D"}
]
},
"text-answer": null
},
"explanation":{
"text":"<<PRESENCE>>"
}
{
"id": "<<PRESENCE>>",
"author": "<<PRESENCE>>",
"text": "<<PRESENCE>>",
"subject": "<<PRESENCE>>",
"pool": {
"id": 1,
"name": "pool1",
"code": "p1",
"image": "<<PRESENCE>>"
},
"answer": {
"id": "<<PRESENCE>>",
"type": "option",
"option-answer": {
"options": [
{ "id": "<<PRESENCE>>", "correct": true, "text": "A" },
{ "id": "<<PRESENCE>>", "correct": false, "text": "B" },
{ "id": "<<PRESENCE>>", "correct": false, "text": "C" },
{ "id": "<<PRESENCE>>", "correct": false, "text": "D" }
]
},
{
"id": "<<PRESENCE>>",
"author": "<<PRESENCE>>",
"text": "<<PRESENCE>>",
"subject": "<<PRESENCE>>",
"pool":{
"id":1,