2023-06-28 17:21:59 +02:00
|
|
|
package file
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"reflect"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"git.andreafazzi.eu/andrea/probo/client"
|
2023-07-10 13:23:46 +02:00
|
|
|
"git.andreafazzi.eu/andrea/probo/hasher/sha256"
|
2023-06-28 17:21:59 +02:00
|
|
|
"git.andreafazzi.eu/andrea/probo/models"
|
2023-07-10 13:23:46 +02:00
|
|
|
"git.andreafazzi.eu/andrea/probo/store/memory"
|
2023-06-28 17:21:59 +02:00
|
|
|
"github.com/remogatto/prettytest"
|
|
|
|
)
|
|
|
|
|
|
|
|
type testSuite struct {
|
|
|
|
prettytest.Suite
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRunner(t *testing.T) {
|
|
|
|
prettytest.Run(
|
|
|
|
t,
|
|
|
|
new(testSuite),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *testSuite) TestQuizFromMarkdown() {
|
|
|
|
markdown := `Question text (1).
|
|
|
|
|
|
|
|
Question text (2).
|
|
|
|
|
|
|
|
Question text (3).
|
|
|
|
|
|
|
|
* Answer 1
|
|
|
|
* Answer 2
|
|
|
|
* Answer 3
|
|
|
|
* Answer 4`
|
|
|
|
|
|
|
|
expectedQuiz := &client.Quiz{
|
|
|
|
Question: &client.Question{Text: "Question text (1).\n\nQuestion text (2).\n\nQuestion text (3)."},
|
|
|
|
Answers: []*client.Answer{
|
|
|
|
{Text: "Answer 1", Correct: true},
|
|
|
|
{Text: "Answer 2", Correct: false},
|
|
|
|
{Text: "Answer 3", Correct: false},
|
|
|
|
{Text: "Answer 4", Correct: false},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
quiz, err := QuizFromMarkdown(markdown)
|
|
|
|
t.Nil(err, fmt.Sprintf("Quiz should be parsed without errors: %v", err))
|
|
|
|
|
|
|
|
if !t.Failed() {
|
|
|
|
t.True(reflect.DeepEqual(quiz, expectedQuiz), fmt.Sprintf("Expected %+v, got %+v", expectedQuiz, quiz))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *testSuite) TestReadAllQuizzes() {
|
2023-07-10 13:23:46 +02:00
|
|
|
store, err := NewFileProboCollectorStore("./testdata/quizzes")
|
2023-06-28 17:21:59 +02:00
|
|
|
t.True(err == nil, fmt.Sprintf("A file store should be initialized without problems but an error occurred: %v", err))
|
|
|
|
|
|
|
|
if !t.Failed() {
|
|
|
|
result, err := store.ReadAllQuizzes()
|
|
|
|
|
|
|
|
t.True(err == nil, fmt.Sprintf("Quizzes should be returned without errors: %v", err))
|
|
|
|
|
|
|
|
if !t.Failed() {
|
|
|
|
t.Equal(
|
|
|
|
2,
|
|
|
|
len(result),
|
|
|
|
fmt.Sprintf("The store contains 3 files but only 2 should be parsed (duplicated quiz). Total of parsed quizzes are instead %v", len(result)),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-07-10 13:23:46 +02:00
|
|
|
func (t *testSuite) TestMarkdownFromQuiz() {
|
|
|
|
store := memory.NewMemoryProboCollectorStore(sha256.NewDefault256Hasher(sha256.DefaultSHA256HashingFn))
|
|
|
|
quiz, err := store.CreateQuiz(
|
2023-06-28 17:21:59 +02:00
|
|
|
&client.CreateUpdateQuizRequest{
|
|
|
|
Quiz: &client.Quiz{
|
|
|
|
Question: &client.Question{Text: "Newly created question text."},
|
|
|
|
Answers: []*client.Answer{
|
|
|
|
{Text: "Answer 1", Correct: true},
|
|
|
|
{Text: "Answer 2", Correct: false},
|
|
|
|
{Text: "Answer 3", Correct: false},
|
|
|
|
{Text: "Answer 4", Correct: false},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
2023-07-10 13:23:46 +02:00
|
|
|
md, err := MarkdownFromQuiz(quiz)
|
|
|
|
t.Nil(err, "Conversion to markdown should not raise an error")
|
|
|
|
if !t.Failed() {
|
|
|
|
t.Equal(`Newly created question text.
|
|
|
|
|
|
|
|
* Answer 1
|
|
|
|
* Answer 2
|
|
|
|
* Answer 3
|
|
|
|
* Answer 4
|
|
|
|
`, md)
|
|
|
|
}
|
|
|
|
}
|
2023-06-28 17:21:59 +02:00
|
|
|
|
2023-07-10 13:23:46 +02:00
|
|
|
func (t *testSuite) TestCreateQuiz() {
|
|
|
|
dirname := "./testdata/quizzes"
|
|
|
|
store, err := NewFileProboCollectorStore(dirname)
|
2023-06-28 17:21:59 +02:00
|
|
|
|
2023-07-10 13:23:46 +02:00
|
|
|
t.True(err == nil, fmt.Sprintf("A file store should be initialized without problems but an error occurred: %v", err))
|
2023-06-28 17:21:59 +02:00
|
|
|
|
|
|
|
if !t.Failed() {
|
2023-07-10 13:23:46 +02:00
|
|
|
clientQuiz := &client.Quiz{
|
|
|
|
Question: &client.Question{Text: "Newly created question text."},
|
|
|
|
Answers: []*client.Answer{
|
|
|
|
{Text: "Answer 1", Correct: true},
|
|
|
|
{Text: "Answer 2", Correct: false},
|
|
|
|
{Text: "Answer 3", Correct: false},
|
|
|
|
{Text: "Answer 4", Correct: false},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
quiz, err := store.CreateQuiz(
|
|
|
|
&client.CreateUpdateQuizRequest{
|
|
|
|
Quiz: clientQuiz,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
t.Nil(err, fmt.Sprintf("An error was raised when saving the quiz on disk: %v", err))
|
|
|
|
|
|
|
|
if !t.Failed() {
|
|
|
|
path, err := store.GetPath(quiz)
|
|
|
|
t.Nil(err, "GetPath should not raise an error.")
|
|
|
|
|
|
|
|
if !t.Failed() {
|
|
|
|
exists, err := os.Stat(path)
|
|
|
|
t.Nil(err, "Stat should not return an error")
|
|
|
|
|
|
|
|
if !t.Failed() {
|
|
|
|
t.True(exists != nil, "The new quiz file was not created.")
|
|
|
|
if !t.Failed() {
|
|
|
|
quizFromDisk, err := readQuizFromDisk(path)
|
|
|
|
t.Nil(err, "Quiz should be read from disk without errors.")
|
|
|
|
if !t.Failed() {
|
|
|
|
t.True(reflect.DeepEqual(quizFromDisk, clientQuiz), "Quiz read from disk and stored in memory should be equal.")
|
|
|
|
err := os.Remove(path)
|
|
|
|
t.Nil(err, "Test file should be removed without errors.")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-06-28 17:21:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-07 18:01:17 +02:00
|
|
|
func (t *testSuite) TestUpdateQuiz() {
|
2023-07-10 13:23:46 +02:00
|
|
|
dirname := "./testdata/quizzes"
|
2023-07-07 18:01:17 +02:00
|
|
|
store, err := NewFileProboCollectorStore(dirname)
|
|
|
|
t.True(err == nil, fmt.Sprintf("A file store should be initialized without problems but an error occurred: %v", err))
|
|
|
|
|
|
|
|
if !t.Failed() {
|
|
|
|
quiz, err := createQuizOnDisk(store, &client.CreateUpdateQuizRequest{
|
|
|
|
Quiz: &client.Quiz{
|
|
|
|
Question: &client.Question{Text: "Newly created question text."},
|
|
|
|
Answers: []*client.Answer{
|
|
|
|
{Text: "Answer 1", Correct: true},
|
|
|
|
{Text: "Answer 2", Correct: false},
|
|
|
|
{Text: "Answer 3", Correct: false},
|
|
|
|
{Text: "Answer 4", Correct: false},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2023-07-07 18:15:09 +02:00
|
|
|
t.Nil(err, "The quiz to be updated should be created without issue")
|
2023-07-07 18:01:17 +02:00
|
|
|
|
|
|
|
if !t.Failed() {
|
2023-07-10 13:23:46 +02:00
|
|
|
clientQuiz := &client.Quiz{
|
|
|
|
Question: &client.Question{Text: "Newly created question text."},
|
|
|
|
Answers: []*client.Answer{
|
|
|
|
{Text: "Answer 1", Correct: true},
|
|
|
|
{Text: "Answer 2", Correct: false},
|
|
|
|
{Text: "Answer 3", Correct: false},
|
|
|
|
{Text: "Answer 4", Correct: false},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
updatedQuiz, err := store.UpdateQuiz(
|
2023-07-07 18:01:17 +02:00
|
|
|
&client.CreateUpdateQuizRequest{
|
2023-07-10 13:23:46 +02:00
|
|
|
Quiz: clientQuiz,
|
2023-07-07 18:01:17 +02:00
|
|
|
}, quiz.ID)
|
2023-07-10 13:23:46 +02:00
|
|
|
|
|
|
|
t.Nil(err, fmt.Sprintf("Quiz should be updated without errors: %v", err))
|
2023-07-12 15:57:10 +02:00
|
|
|
// t.Equal(updatedQuiz.ID, quiz.ID, "Quiz ID should remain the same")
|
2023-07-10 13:23:46 +02:00
|
|
|
|
|
|
|
if !t.Failed() {
|
|
|
|
path, err := store.GetPath(updatedQuiz)
|
|
|
|
|
|
|
|
if !t.Failed() {
|
|
|
|
t.Nil(err, "GetPath should not raise an error.")
|
|
|
|
|
|
|
|
if !t.Failed() {
|
|
|
|
quizFromDisk, err := readQuizFromDisk(path)
|
|
|
|
t.Nil(err, "Quiz should be read from disk without errors.")
|
|
|
|
if !t.Failed() {
|
|
|
|
t.True(reflect.DeepEqual(clientQuiz, quizFromDisk), "Quiz should be updated.")
|
|
|
|
err := os.Remove(path)
|
|
|
|
t.Nil(err, "Stat should not return an error")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-07-07 18:01:17 +02:00
|
|
|
}
|
|
|
|
}
|
2023-07-07 18:15:09 +02:00
|
|
|
|
2023-07-07 18:01:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func createQuizOnDisk(store *FileProboCollectorStore, req *client.CreateUpdateQuizRequest) (*models.Quiz, error) {
|
|
|
|
return store.CreateQuiz(req)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-07-10 13:23:46 +02:00
|
|
|
func readQuizFromDisk(path string) (*client.Quiz, error) {
|
|
|
|
content, err := os.ReadFile(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return QuizFromMarkdown(string(content))
|
|
|
|
}
|
|
|
|
|
2023-06-28 17:21:59 +02:00
|
|
|
func testsAreEqual(got, want []*models.Quiz) bool {
|
|
|
|
return reflect.DeepEqual(got, want)
|
|
|
|
}
|