From a4bd5cc24f03b258ed5053ddcbda082b997756a8 Mon Sep 17 00:00:00 2001 From: ramdos0207 Date: Wed, 20 Dec 2023 23:57:15 +0900 Subject: [PATCH 1/6] add isDuplicateAnswerAllowed --- model/questionnaires.go | 4 +-- model/questionnaires_impl.go | 63 +++++++++++++++++++---------------- model/questionnaires_test.go | 54 +++++++++++++++++------------- model/respondents_test.go | 18 +++++----- model/responses_test.go | 4 +-- model/scale_labels_test.go | 10 +++--- model/validations_test.go | 8 ++--- router/questionnaires.go | 59 ++++++++++++++++---------------- router/questionnaires_test.go | 3 ++ 9 files changed, 121 insertions(+), 102 deletions(-) diff --git a/model/questionnaires.go b/model/questionnaires.go index ec759d2e..ca34e422 100644 --- a/model/questionnaires.go +++ b/model/questionnaires.go @@ -10,8 +10,8 @@ import ( // IQuestionnaire QuestionnaireのRepository type IQuestionnaire interface { - InsertQuestionnaire(ctx context.Context, title string, description string, resTimeLimit null.Time, resSharedTo string) (int, error) - UpdateQuestionnaire(ctx context.Context, title string, description string, resTimeLimit null.Time, resSharedTo string, questionnaireID int) error + InsertQuestionnaire(ctx context.Context, title string, description string, resTimeLimit null.Time, resSharedTo string, IsDuplicateAnswerAllowed bool) (int, error) + UpdateQuestionnaire(ctx context.Context, title string, description string, resTimeLimit null.Time, resSharedTo string, IsDuplicateAnswerAllowed bool, questionnaireID int) error DeleteQuestionnaire(ctx context.Context, questionnaireID int) error GetQuestionnaires(ctx context.Context, userID string, sort string, search string, pageNum int, nontargeted bool) ([]QuestionnaireInfo, int, error) GetAdminQuestionnaires(ctx context.Context, userID string) ([]Questionnaires, error) diff --git a/model/questionnaires_impl.go b/model/questionnaires_impl.go index e7756bc7..386f6cc5 100755 --- a/model/questionnaires_impl.go +++ b/model/questionnaires_impl.go @@ -21,18 +21,19 @@ func NewQuestionnaire() *Questionnaire { // Questionnaires questionnairesテーブルの構造体 type Questionnaires struct { - ID int `json:"questionnaireID" gorm:"type:int(11) AUTO_INCREMENT;not null;primaryKey"` - Title string `json:"title" gorm:"type:char(50);size:50;not null"` - Description string `json:"description" gorm:"type:text;not null"` - ResTimeLimit null.Time `json:"res_time_limit,omitempty" gorm:"type:TIMESTAMP NULL;default:NULL;"` - DeletedAt gorm.DeletedAt `json:"-" gorm:"type:TIMESTAMP NULL;default:NULL;"` - ResSharedTo string `json:"res_shared_to" gorm:"type:char(30);size:30;not null;default:administrators"` - CreatedAt time.Time `json:"created_at" gorm:"type:timestamp;not null;default:CURRENT_TIMESTAMP"` - ModifiedAt time.Time `json:"modified_at" gorm:"type:timestamp;not null;default:CURRENT_TIMESTAMP"` - Administrators []Administrators `json:"-" gorm:"foreignKey:QuestionnaireID"` - Targets []Targets `json:"-" gorm:"foreignKey:QuestionnaireID"` - Questions []Questions `json:"-" gorm:"foreignKey:QuestionnaireID"` - Respondents []Respondents `json:"-" gorm:"foreignKey:QuestionnaireID"` + ID int `json:"questionnaireID" gorm:"type:int(11) AUTO_INCREMENT;not null;primaryKey"` + Title string `json:"title" gorm:"type:char(50);size:50;not null"` + Description string `json:"description" gorm:"type:text;not null"` + ResTimeLimit null.Time `json:"res_time_limit,omitempty" gorm:"type:TIMESTAMP NULL;default:NULL;"` + DeletedAt gorm.DeletedAt `json:"-" gorm:"type:TIMESTAMP NULL;default:NULL;"` + ResSharedTo string `json:"res_shared_to" gorm:"type:char(30);size:30;not null;default:administrators"` + IsDuplicateAnswerAllowed bool `json:"is_duplicate_answer_allowed" gorm:"type:tinyint(4);size:4;not null;default:0"` + CreatedAt time.Time `json:"created_at" gorm:"type:timestamp;not null;default:CURRENT_TIMESTAMP"` + ModifiedAt time.Time `json:"modified_at" gorm:"type:timestamp;not null;default:CURRENT_TIMESTAMP"` + Administrators []Administrators `json:"-" gorm:"foreignKey:QuestionnaireID"` + Targets []Targets `json:"-" gorm:"foreignKey:QuestionnaireID"` + Questions []Questions `json:"-" gorm:"foreignKey:QuestionnaireID"` + Respondents []Respondents `json:"-" gorm:"foreignKey:QuestionnaireID"` } // BeforeCreate Update時に自動でmodified_atを現在時刻に @@ -79,7 +80,7 @@ type ResponseReadPrivilegeInfo struct { } // InsertQuestionnaire アンケートの追加 -func (*Questionnaire) InsertQuestionnaire(ctx context.Context, title string, description string, resTimeLimit null.Time, resSharedTo string) (int, error) { +func (*Questionnaire) InsertQuestionnaire(ctx context.Context, title string, description string, resTimeLimit null.Time, resSharedTo string, isDuplicateAnswerAllowed bool) (int, error) { db, err := getTx(ctx) if err != nil { return 0, fmt.Errorf("failed to get tx: %w", err) @@ -88,16 +89,18 @@ func (*Questionnaire) InsertQuestionnaire(ctx context.Context, title string, des var questionnaire Questionnaires if !resTimeLimit.Valid { questionnaire = Questionnaires{ - Title: title, - Description: description, - ResSharedTo: resSharedTo, + Title: title, + Description: description, + ResSharedTo: resSharedTo, + IsDuplicateAnswerAllowed: isDuplicateAnswerAllowed, } } else { questionnaire = Questionnaires{ - Title: title, - Description: description, - ResTimeLimit: resTimeLimit, - ResSharedTo: resSharedTo, + Title: title, + Description: description, + ResTimeLimit: resTimeLimit, + ResSharedTo: resSharedTo, + IsDuplicateAnswerAllowed: isDuplicateAnswerAllowed, } } @@ -110,7 +113,7 @@ func (*Questionnaire) InsertQuestionnaire(ctx context.Context, title string, des } // UpdateQuestionnaire アンケートの更新 -func (*Questionnaire) UpdateQuestionnaire(ctx context.Context, title string, description string, resTimeLimit null.Time, resSharedTo string, questionnaireID int) error { +func (*Questionnaire) UpdateQuestionnaire(ctx context.Context, title string, description string, resTimeLimit null.Time, resSharedTo string, isDuplicateAnswerAllowed bool, questionnaireID int) error { db, err := getTx(ctx) if err != nil { return fmt.Errorf("failed to get tx: %w", err) @@ -119,17 +122,19 @@ func (*Questionnaire) UpdateQuestionnaire(ctx context.Context, title string, des var questionnaire interface{} if resTimeLimit.Valid { questionnaire = Questionnaires{ - Title: title, - Description: description, - ResTimeLimit: resTimeLimit, - ResSharedTo: resSharedTo, + Title: title, + Description: description, + ResTimeLimit: resTimeLimit, + ResSharedTo: resSharedTo, + IsDuplicateAnswerAllowed: isDuplicateAnswerAllowed, } } else { questionnaire = map[string]interface{}{ - "title": title, - "description": description, - "res_time_limit": gorm.Expr("NULL"), - "res_shared_to": resSharedTo, + "title": title, + "description": description, + "res_time_limit": gorm.Expr("NULL"), + "res_shared_to": resSharedTo, + "is_duplicate_answer_allowed": isDuplicateAnswerAllowed, } } diff --git a/model/questionnaires_test.go b/model/questionnaires_test.go index 16b80506..949a91b3 100644 --- a/model/questionnaires_test.go +++ b/model/questionnaires_test.go @@ -351,10 +351,11 @@ func insertQuestionnaireTest(t *testing.T) { assertion := assert.New(t) type args struct { - title string - description string - resTimeLimit null.Time - resSharedTo string + title string + description string + resTimeLimit null.Time + resSharedTo string + isDuplicateAnswerAllowed bool } type expect struct { isErr bool @@ -451,7 +452,7 @@ func insertQuestionnaireTest(t *testing.T) { for _, testCase := range testCases { ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, testCase.args.title, testCase.args.description, testCase.args.resTimeLimit, testCase.args.resSharedTo) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, testCase.args.title, testCase.args.description, testCase.args.resTimeLimit, testCase.args.resSharedTo, testCase.args.isDuplicateAnswerAllowed) if !testCase.expect.isErr { assertion.NoError(err, testCase.description, "no error") @@ -475,6 +476,7 @@ func insertQuestionnaireTest(t *testing.T) { assertion.Equal(testCase.args.description, questionnaire.Description, testCase.description, "description") assertion.WithinDuration(testCase.args.resTimeLimit.ValueOrZero(), questionnaire.ResTimeLimit.ValueOrZero(), 2*time.Second, testCase.description, "res_time_limit") assertion.Equal(testCase.args.resSharedTo, questionnaire.ResSharedTo, testCase.description, "res_shared_to") + assertion.Equal(testCase.args.isDuplicateAnswerAllowed, questionnaire.IsDuplicateAnswerAllowed, testCase.description, "is_duplicate_answer_allowed") assertion.WithinDuration(time.Now(), questionnaire.CreatedAt, 2*time.Second, testCase.description, "created_at") assertion.WithinDuration(time.Now(), questionnaire.ModifiedAt, 2*time.Second, testCase.description, "modified_at") @@ -487,10 +489,11 @@ func updateQuestionnaireTest(t *testing.T) { assertion := assert.New(t) type args struct { - title string - description string - resTimeLimit null.Time - resSharedTo string + title string + description string + resTimeLimit null.Time + resSharedTo string + isDuplicateAnswerAllowed bool } type expect struct { isErr bool @@ -647,10 +650,11 @@ func updateQuestionnaireTest(t *testing.T) { before := &testCase.before questionnaire := Questionnaires{ - Title: before.title, - Description: before.description, - ResTimeLimit: before.resTimeLimit, - ResSharedTo: before.resSharedTo, + Title: before.title, + Description: before.description, + ResTimeLimit: before.resTimeLimit, + ResSharedTo: before.resSharedTo, + IsDuplicateAnswerAllowed: before.isDuplicateAnswerAllowed, } err := db. Session(&gorm.Session{NewDB: true}). @@ -662,7 +666,7 @@ func updateQuestionnaireTest(t *testing.T) { createdAt := questionnaire.CreatedAt questionnaireID := questionnaire.ID after := &testCase.after - err = questionnaireImpl.UpdateQuestionnaire(ctx, after.title, after.description, after.resTimeLimit, after.resSharedTo, questionnaireID) + err = questionnaireImpl.UpdateQuestionnaire(ctx, after.title, after.description, after.resTimeLimit, after.resSharedTo, after.isDuplicateAnswerAllowed, questionnaireID) if !testCase.expect.isErr { assertion.NoError(err, testCase.description, "no error") @@ -686,6 +690,7 @@ func updateQuestionnaireTest(t *testing.T) { assertion.Equal(after.description, questionnaire.Description, testCase.description, "description") assertion.WithinDuration(after.resTimeLimit.ValueOrZero(), questionnaire.ResTimeLimit.ValueOrZero(), 2*time.Second, testCase.description, "res_time_limit") assertion.Equal(after.resSharedTo, questionnaire.ResSharedTo, testCase.description, "res_shared_to") + assertion.Equal(after.isDuplicateAnswerAllowed, questionnaire.IsDuplicateAnswerAllowed, testCase.description, "is_duplicate_answer_allowed") assertion.WithinDuration(createdAt, questionnaire.CreatedAt, 2*time.Second, testCase.description, "created_at") assertion.WithinDuration(time.Now(), questionnaire.ModifiedAt, 2*time.Second, testCase.description, "modified_at") @@ -726,7 +731,7 @@ func updateQuestionnaireTest(t *testing.T) { for _, arg := range invalidTestCases { ctx := context.Background() - err := questionnaireImpl.UpdateQuestionnaire(ctx, arg.title, arg.description, arg.resTimeLimit, arg.resSharedTo, invalidQuestionnaireID) + err := questionnaireImpl.UpdateQuestionnaire(ctx, arg.title, arg.description, arg.resTimeLimit, arg.resSharedTo, arg.isDuplicateAnswerAllowed, invalidQuestionnaireID) if !errors.Is(err, ErrNoRecordUpdated) { if err == nil { t.Errorf("Succeeded with invalid questionnaireID") @@ -743,10 +748,11 @@ func deleteQuestionnaireTest(t *testing.T) { assertion := assert.New(t) type args struct { - title string - description string - resTimeLimit null.Time - resSharedTo string + title string + description string + resTimeLimit null.Time + resSharedTo string + isDuplicateAnswerAllowed bool } type expect struct { isErr bool @@ -772,10 +778,11 @@ func deleteQuestionnaireTest(t *testing.T) { ctx := context.Background() questionnaire := Questionnaires{ - Title: testCase.args.title, - Description: testCase.args.description, - ResTimeLimit: testCase.args.resTimeLimit, - ResSharedTo: testCase.args.resSharedTo, + Title: testCase.args.title, + Description: testCase.args.description, + ResTimeLimit: testCase.args.resTimeLimit, + ResSharedTo: testCase.args.resSharedTo, + IsDuplicateAnswerAllowed: testCase.args.isDuplicateAnswerAllowed, } err := db. Session(&gorm.Session{NewDB: true}). @@ -1341,6 +1348,7 @@ func getQuestionnaireInfoTest(t *testing.T) { assertion.Equal(testCase.expect.questionnaire.Title, actualQuestionnaire.Title, testCase.description, "questionnaire(Title)") assertion.Equal(testCase.expect.questionnaire.Description, actualQuestionnaire.Description, testCase.description, "questionnaire(Description)") assertion.Equal(testCase.expect.questionnaire.ResSharedTo, actualQuestionnaire.ResSharedTo, testCase.description, "questionnaire(ResSharedTo)") + assertion.Equal(testCase.expect.questionnaire.IsDuplicateAnswerAllowed, actualQuestionnaire.IsDuplicateAnswerAllowed, testCase.description, "questionnaire(IsDuplicateAnswerAllowed)") assertion.WithinDuration(testCase.expect.questionnaire.ResTimeLimit.ValueOrZero(), actualQuestionnaire.ResTimeLimit.ValueOrZero(), 2*time.Second, testCase.description, "questionnaire(ResTimeLimit)") assertion.WithinDuration(testCase.expect.questionnaire.CreatedAt, actualQuestionnaire.CreatedAt, 2*time.Second, testCase.description, "questionnaire(CreatedAt)") assertion.WithinDuration(testCase.expect.questionnaire.ModifiedAt, actualQuestionnaire.ModifiedAt, 2*time.Second, testCase.description, "questionnaire(ModifiedAt)") diff --git a/model/respondents_test.go b/model/respondents_test.go index cafc7dd7..95820f64 100644 --- a/model/respondents_test.go +++ b/model/respondents_test.go @@ -19,7 +19,7 @@ func TestInsertRespondent(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -129,7 +129,7 @@ func TestUpdateSubmittedAt(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -203,7 +203,7 @@ func TestDeleteRespondent(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -390,9 +390,9 @@ func TestGetRespondentInfos(t *testing.T) { args expect } - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第2回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第2回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) require.NoError(t, err) - questionnaireID2, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第2回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public") + questionnaireID2, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第2回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) require.NoError(t, err) questionnaire := Questionnaires{} @@ -522,7 +522,7 @@ func TestGetRespondentDetail(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true) require.NoError(t, err) questionnaire := Questionnaires{} @@ -619,7 +619,7 @@ func TestGetRespondentDetails(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true) require.NoError(t, err) questionnaire := Questionnaires{} @@ -908,7 +908,7 @@ func TestGetRespondentsUserIDs(t *testing.T) { } questionnaireIDs := make([]int, 0, 3) for i := 0; i < 3; i++ { - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) require.NoError(t, err) questionnaireIDs = append(questionnaireIDs, questionnaireID) } @@ -996,7 +996,7 @@ func TestTestCheckRespondent(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) diff --git a/model/responses_test.go b/model/responses_test.go index 9790b350..ec0b5b1d 100644 --- a/model/responses_test.go +++ b/model/responses_test.go @@ -19,7 +19,7 @@ func TestInsertResponses(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -142,7 +142,7 @@ func TestDeleteResponse(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) diff --git a/model/scale_labels_test.go b/model/scale_labels_test.go index f4f79ccd..ad5ea98e 100644 --- a/model/scale_labels_test.go +++ b/model/scale_labels_test.go @@ -20,7 +20,7 @@ func TestInsertScaleLabel(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -163,7 +163,7 @@ func TestUpdateScaleLabel(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -283,7 +283,7 @@ func TestDeleteScaleLabel(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -371,7 +371,7 @@ func TestGetScaleLabels(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -489,7 +489,7 @@ func TestCheckScaleLabel(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) diff --git a/model/validations_test.go b/model/validations_test.go index a56434a3..54ab6548 100644 --- a/model/validations_test.go +++ b/model/validations_test.go @@ -20,7 +20,7 @@ func TestInsertValidation(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -212,7 +212,7 @@ func TestUpdateValidation(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -360,7 +360,7 @@ func TestDeleteValidation(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -458,7 +458,7 @@ func TestGetValidations(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public") + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) diff --git a/router/questionnaires.go b/router/questionnaires.go index b33db7f4..44dcd962 100644 --- a/router/questionnaires.go +++ b/router/questionnaires.go @@ -141,12 +141,13 @@ func (q *Questionnaire) GetQuestionnaires(c echo.Context) error { } type PostAndEditQuestionnaireRequest struct { - Title string `json:"title" validate:"required,max=50"` - Description string `json:"description"` - ResTimeLimit null.Time `json:"res_time_limit"` - ResSharedTo string `json:"res_shared_to" validate:"required,oneof=administrators respondents public"` - Targets []string `json:"targets" validate:"dive,max=32"` - Administrators []string `json:"administrators" validate:"required,min=1,dive,max=32"` + Title string `json:"title" validate:"required,max=50"` + Description string `json:"description"` + ResTimeLimit null.Time `json:"res_time_limit"` + ResSharedTo string `json:"res_shared_to" validate:"required,oneof=administrators respondents public"` + Targets []string `json:"targets" validate:"dive,max=32"` + Administrators []string `json:"administrators" validate:"required,min=1,dive,max=32"` + IsDuplicateAnswerAllowed bool `json:"is_duplicate_answer_allowed"` } // PostQuestionnaire POST /questionnaires @@ -182,7 +183,7 @@ func (q *Questionnaire) PostQuestionnaire(c echo.Context) error { var questionnaireID int err = q.ITransaction.Do(c.Request().Context(), nil, func(ctx context.Context) error { - questionnaireID, err = q.InsertQuestionnaire(ctx, req.Title, req.Description, req.ResTimeLimit, req.ResSharedTo) + questionnaireID, err = q.InsertQuestionnaire(ctx, req.Title, req.Description, req.ResTimeLimit, req.ResSharedTo, req.IsDuplicateAnswerAllowed) if err != nil { c.Logger().Errorf("failed to insert a questionnaire: %+v", err) return err @@ -228,16 +229,17 @@ func (q *Questionnaire) PostQuestionnaire(c echo.Context) error { now := time.Now() return c.JSON(http.StatusCreated, map[string]interface{}{ - "questionnaireID": questionnaireID, - "title": req.Title, - "description": req.Description, - "res_time_limit": req.ResTimeLimit, - "deleted_at": "NULL", - "created_at": now.Format(time.RFC3339), - "modified_at": now.Format(time.RFC3339), - "res_shared_to": req.ResSharedTo, - "targets": req.Targets, - "administrators": req.Administrators, + "questionnaireID": questionnaireID, + "title": req.Title, + "description": req.Description, + "res_time_limit": req.ResTimeLimit, + "deleted_at": "NULL", + "created_at": now.Format(time.RFC3339), + "modified_at": now.Format(time.RFC3339), + "res_shared_to": req.ResSharedTo, + "targets": req.Targets, + "administrators": req.Administrators, + "is_duplicate_answer_allowed": req.IsDuplicateAnswerAllowed, }) } @@ -261,16 +263,17 @@ func (q *Questionnaire) GetQuestionnaire(c echo.Context) error { } return c.JSON(http.StatusOK, map[string]interface{}{ - "questionnaireID": questionnaire.ID, - "title": questionnaire.Title, - "description": questionnaire.Description, - "res_time_limit": questionnaire.ResTimeLimit, - "created_at": questionnaire.CreatedAt.Format(time.RFC3339), - "modified_at": questionnaire.ModifiedAt.Format(time.RFC3339), - "res_shared_to": questionnaire.ResSharedTo, - "targets": targets, - "administrators": administrators, - "respondents": respondents, + "questionnaireID": questionnaire.ID, + "title": questionnaire.Title, + "description": questionnaire.Description, + "res_time_limit": questionnaire.ResTimeLimit, + "created_at": questionnaire.CreatedAt.Format(time.RFC3339), + "modified_at": questionnaire.ModifiedAt.Format(time.RFC3339), + "res_shared_to": questionnaire.ResSharedTo, + "targets": targets, + "administrators": administrators, + "respondents": respondents, + "is_duplicate_answer_allowed": questionnaire.IsDuplicateAnswerAllowed, }) } @@ -409,7 +412,7 @@ func (q *Questionnaire) EditQuestionnaire(c echo.Context) error { } err = q.ITransaction.Do(c.Request().Context(), nil, func(ctx context.Context) error { - err = q.UpdateQuestionnaire(ctx, req.Title, req.Description, req.ResTimeLimit, req.ResSharedTo, questionnaireID) + err = q.UpdateQuestionnaire(ctx, req.Title, req.Description, req.ResTimeLimit, req.ResSharedTo, req.IsDuplicateAnswerAllowed, questionnaireID) if err != nil && !errors.Is(err, model.ErrNoRecordUpdated) { c.Logger().Errorf("failed to update questionnaire: %+v", err) return err diff --git a/router/questionnaires_test.go b/router/questionnaires_test.go index 8e934895..c542dbb5 100644 --- a/router/questionnaires_test.go +++ b/router/questionnaires_test.go @@ -601,6 +601,7 @@ func TestPostQuestionnaire(t *testing.T) { testCase.request.Description, mockTimeLimit, testCase.request.ResSharedTo, + testCase.request.IsDuplicateAnswerAllowed, ). Return(testCase.questionnaireID, testCase.InsertQuestionnaireError) @@ -659,6 +660,7 @@ func TestPostQuestionnaire(t *testing.T) { assert.Nil(t, questionnaire["res_time_limit"], "resTimeLimit nil") } assert.Equal(t, testCase.request.ResSharedTo, questionnaire["res_shared_to"], "resSharedTo") + assert.Equal(t, testCase.request.IsDuplicateAnswerAllowed, questionnaire["is_duplicate_answer_allowed"], "isDuplicateAnswerAllowed") strCreatedAt, ok := questionnaire["created_at"].(string) assert.True(t, ok, "created_at convert") @@ -1489,6 +1491,7 @@ func TestEditQuestionnaire(t *testing.T) { testCase.request.Description, mockTimeLimit, testCase.request.ResSharedTo, + testCase.request.IsDuplicateAnswerAllowed, testCase.questionnaireID, ). Return(testCase.InsertQuestionnaireError) From eb083bdbc28904beb55c0a9dfae664c578dbf577 Mon Sep 17 00:00:00 2001 From: kaitoyama <45167401+kaitoyama@users.noreply.github.com> Date: Thu, 2 May 2024 13:26:09 +0900 Subject: [PATCH 2/6] impl delete duplicate answer --- model/respondents_impl.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/model/respondents_impl.go b/model/respondents_impl.go index 29019230..74b14742 100755 --- a/model/respondents_impl.go +++ b/model/respondents_impl.go @@ -72,7 +72,19 @@ func (*Respondent) InsertRespondent(ctx context.Context, userID string, question return 0, fmt.Errorf("failed to get tx: %w", err) } + var questionnaire Questionnaires var respondent Respondents + + err = db. + Where("id = ?", questionnaireID). + First(&questionnaire).Error + if errors.Is(err, gorm.ErrRecordNotFound) { + return 0, ErrRecordNotFound + } + if err != nil { + return 0, fmt.Errorf("failed to get questionnaire: %w", err) + } + if submittedAt.Valid { respondent = Respondents{ QuestionnaireID: questionnaireID, @@ -86,12 +98,28 @@ func (*Respondent) InsertRespondent(ctx context.Context, userID string, question } } + if !questionnaire.IsDuplicateAnswerAllowed && submittedAt.Valid { + // delete old answers + err = db. + Where("questionnaire_id = ? AND user_traqid = ?", questionnaireID, userID). + Delete(&Respondents{}).Error + // 既存の回答がなかった場合はそのまま進む + if errors.Is(err, ErrNoRecordDeleted) { + err = nil + } + if err != nil { + return 0, fmt.Errorf("failed to delete old answers: %w", err) + } + + } + err = db.Create(&respondent).Error if err != nil { return 0, fmt.Errorf("failed to insert a respondent record: %w", err) } return respondent.ResponseID, nil + } // UpdateSubmittedAt 投稿日時更新 From 8062e5d57c52382fe9355e8f6ee67816994f38d9 Mon Sep 17 00:00:00 2001 From: kaitoyama <45167401+kaitoyama@users.noreply.github.com> Date: Thu, 2 May 2024 14:59:25 +0900 Subject: [PATCH 3/6] change error handling --- model/errors.go | 2 ++ model/respondents_impl.go | 14 ++++++-------- router/responses.go | 3 +++ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/model/errors.go b/model/errors.go index 9c7df7cc..eb74acac 100755 --- a/model/errors.go +++ b/model/errors.go @@ -29,4 +29,6 @@ var ( ErrInvalidTx = errors.New("invalid tx") // ErrDeadlineExceeded deadline exceeded ErrDeadlineExceeded = errors.New("deadline exceeded") + // ErrDuplicatedAnswered + ErrDuplicatedAnswered = errors.New("duplicated answered is not allowed") ) diff --git a/model/respondents_impl.go b/model/respondents_impl.go index 74b14742..0b6bd005 100755 --- a/model/respondents_impl.go +++ b/model/respondents_impl.go @@ -98,17 +98,15 @@ func (*Respondent) InsertRespondent(ctx context.Context, userID string, question } } - if !questionnaire.IsDuplicateAnswerAllowed && submittedAt.Valid { - // delete old answers + if !questionnaire.IsDuplicateAnswerAllowed { err = db. Where("questionnaire_id = ? AND user_traqid = ?", questionnaireID, userID). - Delete(&Respondents{}).Error - // 既存の回答がなかった場合はそのまま進む - if errors.Is(err, ErrNoRecordDeleted) { - err = nil + First(&Respondents{}).Error + if err == nil { + return 0, ErrDuplicatedAnswered } - if err != nil { - return 0, fmt.Errorf("failed to delete old answers: %w", err) + if !errors.Is(err, gorm.ErrRecordNotFound) { + return 0, fmt.Errorf("failed to check duplicate answer: %w", err) } } diff --git a/router/responses.go b/router/responses.go index 81d11d64..d741ae8f 100644 --- a/router/responses.go +++ b/router/responses.go @@ -166,6 +166,9 @@ func (r *Response) PostResponse(c echo.Context) error { } responseID, err := r.InsertRespondent(c.Request().Context(), userID, req.ID, null.NewTime(submittedAt, !req.Temporarily)) + if errors.Is(err, model.ErrDuplicatedAnswered) { + return echo.NewHTTPError(http.StatusConflict, err) + } if err != nil { c.Logger().Errorf("failed to insert respondent: %+v", err) return echo.NewHTTPError(http.StatusInternalServerError, err) From 94b936ab26d827de2d87bee3bada99232f64dedd Mon Sep 17 00:00:00 2001 From: Eraxyso <130852025+Eraxyso@users.noreply.github.com> Date: Sat, 2 Nov 2024 18:38:31 +0000 Subject: [PATCH 4/6] fix: fix parameter mismatch in test files caused by new parameter --- model/questionnaires_test.go | 327 +++++++++++++++++++++++++++-------- model/respondents_test.go | 189 ++++++++++++++++++-- model/responses_test.go | 4 +- model/scale_labels_test.go | 10 +- model/targets_test.go | 2 +- model/validations_test.go | 8 +- 6 files changed, 443 insertions(+), 97 deletions(-) diff --git a/model/questionnaires_test.go b/model/questionnaires_test.go index b88dd65b..fc60adba 100644 --- a/model/questionnaires_test.go +++ b/model/questionnaires_test.go @@ -966,11 +966,12 @@ func getQuestionnairesTest(t *testing.T) { } type args struct { - userID string - sort string - search string - pageNum int - nontargeted bool + userID string + sort string + search string + pageNum int + onlyTargetingMe bool + onlyAdministratedByMe bool } type expect struct { isErr bool @@ -988,81 +989,89 @@ func getQuestionnairesTest(t *testing.T) { { description: "userID:valid, sort:no, search:no, page:1", args: args{ - userID: questionnairesTestUserID, - sort: "", - search: "", - pageNum: 1, - nontargeted: false, + userID: questionnairesTestUserID, + sort: "", + search: "", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: true, }, }, { description: "userID:valid, sort:created_at, search:no, page:1", args: args{ - userID: questionnairesTestUserID, - sort: "created_at", - search: "", - pageNum: 1, - nontargeted: false, + userID: questionnairesTestUserID, + sort: "created_at", + search: "", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: true, }, }, { description: "userID:valid, sort:-created_at, search:no, page:1", args: args{ - userID: questionnairesTestUserID, - sort: "-created_at", - search: "", - pageNum: 1, - nontargeted: false, + userID: questionnairesTestUserID, + sort: "-created_at", + search: "", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: true, }, }, { description: "userID:valid, sort:title, search:no, page:1", args: args{ - userID: questionnairesTestUserID, - sort: "title", - search: "", - pageNum: 1, - nontargeted: false, + userID: questionnairesTestUserID, + sort: "title", + search: "", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: true, }, }, { description: "userID:valid, sort:-title, search:no, page:1", args: args{ - userID: questionnairesTestUserID, - sort: "-title", - search: "", - pageNum: 1, - nontargeted: false, + userID: questionnairesTestUserID, + sort: "-title", + search: "", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: true, }, }, { description: "userID:valid, sort:modified_at, search:no, page:1", args: args{ - userID: questionnairesTestUserID, - sort: "modified_at", - search: "", - pageNum: 1, - nontargeted: false, + userID: questionnairesTestUserID, + sort: "modified_at", + search: "", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: true, }, }, { description: "userID:valid, sort:-modified_at, search:no, page:1", args: args{ - userID: questionnairesTestUserID, - sort: "-modified_at", - search: "", - pageNum: 1, - nontargeted: false, + userID: questionnairesTestUserID, + sort: "-modified_at", + search: "", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: true, }, }, { description: "userID:valid, sort:no, search:GetQuestionnaireTest$, page:1", args: args{ - userID: questionnairesTestUserID, - sort: "", - search: "GetQuestionnaireTest$", - pageNum: 1, - nontargeted: false, + userID: questionnairesTestUserID, + sort: "", + search: "GetQuestionnaireTest$", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: true, }, expect: expect{ isCheckLen: true, @@ -1072,21 +1081,23 @@ func getQuestionnairesTest(t *testing.T) { { description: "userID:valid, sort:no, search:no, page:2", args: args{ - userID: questionnairesTestUserID, - sort: "", - search: "", - pageNum: 2, - nontargeted: false, + userID: questionnairesTestUserID, + sort: "", + search: "", + pageNum: 2, + onlyTargetingMe: true, + onlyAdministratedByMe: true, }, }, { description: "too large page", args: args{ - userID: questionnairesTestUserID, - sort: "", - search: "", - pageNum: 100000, - nontargeted: false, + userID: questionnairesTestUserID, + sort: "", + search: "", + pageNum: 100000, + onlyTargetingMe: true, + onlyAdministratedByMe: true, }, expect: expect{ isErr: true, @@ -1096,21 +1107,23 @@ func getQuestionnairesTest(t *testing.T) { { description: "userID:valid, sort:no, search:no, page:1, nontargetted", args: args{ - userID: questionnairesTestUserID, - sort: "", - search: "", - pageNum: 1, - nontargeted: true, + userID: questionnairesTestUserID, + sort: "", + search: "", + pageNum: 1, + onlyTargetingMe: true, + onlyAdministratedByMe: true, }, }, { description: "userID:valid, sort:no, search:notFoundQuestionnaire, page:1", args: args{ - userID: questionnairesTestUserID, - sort: "", - search: "notFoundQuestionnaire", - pageNum: 1, - nontargeted: true, + userID: questionnairesTestUserID, + sort: "", + search: "notFoundQuestionnaire", + pageNum: 1, + onlyTargetingMe: true, + onlyAdministratedByMe: true, }, expect: expect{ isCheckLen: false, @@ -1120,11 +1133,171 @@ func getQuestionnairesTest(t *testing.T) { { description: "userID:valid, sort:invalid, search:no, page:1", args: args{ - userID: questionnairesTestUserID, - sort: "hogehoge", - search: "", - pageNum: 1, - nontargeted: false, + userID: questionnairesTestUserID, + sort: "hogehoge", + search: "", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: true, + }, + expect: expect{ + isErr: true, + err: ErrInvalidSortParam, + }, + }, + { + description: "userID:valid, sort:no, search:no, page:1", + args: args{ + userID: questionnairesTestUserID, + sort: "", + search: "", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: false, + }, + }, + { + description: "userID:valid, sort:created_at, search:no, page:1", + args: args{ + userID: questionnairesTestUserID, + sort: "created_at", + search: "", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: false, + }, + }, + { + description: "userID:valid, sort:-created_at, search:no, page:1", + args: args{ + userID: questionnairesTestUserID, + sort: "-created_at", + search: "", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: false, + }, + }, + { + description: "userID:valid, sort:title, search:no, page:1", + args: args{ + userID: questionnairesTestUserID, + sort: "title", + search: "", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: false, + }, + }, + { + description: "userID:valid, sort:-title, search:no, page:1", + args: args{ + userID: questionnairesTestUserID, + sort: "-title", + search: "", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: false, + }, + }, + { + description: "userID:valid, sort:modified_at, search:no, page:1", + args: args{ + userID: questionnairesTestUserID, + sort: "modified_at", + search: "", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: false, + }, + }, + { + description: "userID:valid, sort:-modified_at, search:no, page:1", + args: args{ + userID: questionnairesTestUserID, + sort: "-modified_at", + search: "", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: false, + }, + }, + { + description: "userID:valid, sort:no, search:GetQuestionnaireTest$, page:1", + args: args{ + userID: questionnairesTestUserID, + sort: "", + search: "GetQuestionnaireTest$", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: false, + }, + expect: expect{ + isCheckLen: true, + length: 4, + }, + }, + { + description: "userID:valid, sort:no, search:no, page:2", + args: args{ + userID: questionnairesTestUserID, + sort: "", + search: "", + pageNum: 2, + onlyTargetingMe: true, + onlyAdministratedByMe: false, + }, + }, + { + description: "too large page", + args: args{ + userID: questionnairesTestUserID, + sort: "", + search: "", + pageNum: 100000, + onlyTargetingMe: true, + onlyAdministratedByMe: false, + }, + expect: expect{ + isErr: true, + err: ErrTooLargePageNum, + }, + }, + { + description: "userID:valid, sort:no, search:no, page:1, nontargetted", + args: args{ + userID: questionnairesTestUserID, + sort: "", + search: "", + pageNum: 1, + onlyTargetingMe: true, + onlyAdministratedByMe: false, + }, + }, + { + description: "userID:valid, sort:no, search:notFoundQuestionnaire, page:1", + args: args{ + userID: questionnairesTestUserID, + sort: "", + search: "notFoundQuestionnaire", + pageNum: 1, + onlyTargetingMe: true, + onlyAdministratedByMe: false, + }, + expect: expect{ + isCheckLen: false, + length: 0, + }, + }, + { + description: "userID:valid, sort:invalid, search:no, page:1", + args: args{ + userID: questionnairesTestUserID, + sort: "hogehoge", + search: "", + pageNum: 1, + onlyTargetingMe: false, + onlyAdministratedByMe: false, }, expect: expect{ isErr: true, @@ -1136,7 +1309,7 @@ func getQuestionnairesTest(t *testing.T) { for _, testCase := range testCases { ctx := context.Background() - questionnaires, pageMax, err := questionnaireImpl. (ctx, testCase.args.userID, testCase.args.sort, testCase.args.search, testCase.args.pageNum, testCase.args.nontargeted) + questionnaires, pageMax, err := questionnaireImpl.GetQuestionnaires(ctx, testCase.args.userID, testCase.args.sort, testCase.args.search, testCase.args.pageNum, testCase.args.onlyTargetingMe, testCase.args.onlyAdministratedByMe) if !testCase.expect.isErr { assertion.NoError(err, testCase.description, "no error") @@ -1163,11 +1336,16 @@ func getQuestionnairesTest(t *testing.T) { for _, questionnaire := range questionnaires { actualQuestionnaireIDs = append(actualQuestionnaireIDs, questionnaire.ID) } - if testCase.args.nontargeted { + if testCase.args.onlyTargetingMe { for _, targettedQuestionnaireID := range userTargetMap[questionnairesTestUserID] { assertion.NotContains(actualQuestionnaireIDs, targettedQuestionnaireID, testCase.description, "not contain(targetted)") } } + if testCase.args.onlyAdministratedByMe { + for _, targettedQuestionnaireID := range userTargetMap[questionnairesTestUserID] { + assertion.NotContains(actualQuestionnaireIDs, targettedQuestionnaireID, testCase.description, "not contain(administrated)") + } + } for _, deletedQuestionnaireID := range deletedQuestionnaireIDs { assertion.NotContains(actualQuestionnaireIDs, deletedQuestionnaireID, testCase.description, "not contain(deleted)") } @@ -1176,7 +1354,7 @@ func getQuestionnairesTest(t *testing.T) { assertion.Regexp(testCase.args.search, questionnaire.Title, testCase.description, "regexp") } - if len(testCase.args.search) == 0 && !testCase.args.nontargeted { + if len(testCase.args.search) == 0 && !testCase.args.onlyTargetingMe && !testCase.args.onlyAdministratedByMe { fmt.Println(testCase.description) fmt.Println(questionnaireNum) fmt.Println(pageMax) @@ -1409,6 +1587,9 @@ func getQuestionnaireInfoTest(t *testing.T) { actualQuestionnaire, actualTargets, actualTargetGroups, actualAdministrators, actualAdministratorGroups, actualRespondents, err := questionnaireImpl.GetQuestionnaireInfo(ctx, testCase.questionnaireID) + _ = actualTargetGroups + _ = actualAdministratorGroups + if !testCase.expect.isErr { assertion.NoError(err, testCase.description, "no error") } else if testCase.expect.err != nil { diff --git a/model/respondents_test.go b/model/respondents_test.go index a9f353bc..97aa7105 100644 --- a/model/respondents_test.go +++ b/model/respondents_test.go @@ -19,7 +19,7 @@ func TestInsertRespondent(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true, true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -129,7 +129,7 @@ func TestUpdateSubmittedAt(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true, true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -203,7 +203,7 @@ func TestDeleteRespondent(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true, true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -391,9 +391,9 @@ func TestGetRespondentInfos(t *testing.T) { args expect } - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第2回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第2回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, true) require.NoError(t, err) - questionnaireID2, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第2回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) + questionnaireID2, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第2回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, true) require.NoError(t, err) questionnaire := Questionnaires{} @@ -523,7 +523,7 @@ func TestGetRespondentDetail(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true, true) require.NoError(t, err) questionnaire := Questionnaires{} @@ -620,7 +620,7 @@ func TestGetRespondentDetails(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true, true) require.NoError(t, err) questionnaire := Questionnaires{} @@ -637,6 +637,8 @@ func TestGetRespondentDetails(t *testing.T) { type args struct { questionnaireID int sort string + onlyMyResponse bool + userID string } type expect struct { isErr bool @@ -683,7 +685,6 @@ func TestGetRespondentDetails(t *testing.T) { questionID, err := questionImpl.InsertQuestion(ctx, question.QuestionnaireID, question.PageNum, question.QuestionNum, question.Type, question.Body, question.IsRequired) require.NoError(t, err) questionIDs = append(questionIDs, questionID) - } respondents := []Respondents{ @@ -750,6 +751,150 @@ func TestGetRespondentDetails(t *testing.T) { args: args{ questionnaireID: questionnaireID, sort: "traqid", + onlyMyResponse: false, + userID: userOne, + }, + expect: expect{ + length: 3, + sortIdx: []int{0, 1, 2}, + }, + }, + { + description: "-traqid", + args: args{ + questionnaireID: questionnaireID, + sort: "-traqid", + onlyMyResponse: false, + userID: userOne, + }, + expect: expect{ + length: 3, + sortIdx: []int{2, 1, 0}, + }, + }, + { + description: "submitted_at", + args: args{ + questionnaireID: questionnaireID, + sort: "submitted_at", + onlyMyResponse: false, + userID: userOne, + }, + expect: expect{ + length: 3, + sortIdx: []int{0, 2, 1}, + }, + }, + { + description: "-submitted_at", + args: args{ + questionnaireID: questionnaireID, + sort: "-submitted_at", + onlyMyResponse: false, + userID: userOne, + }, + expect: expect{ + length: 3, + sortIdx: []int{1, 2, 0}, + }, + }, + { + description: "questionnaire does not exist", + args: args{ + questionnaireID: -1, + sort: "1", + onlyMyResponse: false, + userID: userOne, + }, + expect: expect{ + length: 0, + sortIdx: []int{}, + }, + }, + { + description: "sortNum Number", + args: args{ + questionnaireID: questionnaireID, + sort: "3", + onlyMyResponse: false, + userID: userOne, + }, + expect: expect{ + length: 3, + sortIdx: []int{2, 1, 0}, + }, + }, + { + description: "sortNum Number", + args: args{ + questionnaireID: questionnaireID, + sort: "-3", + onlyMyResponse: false, + userID: userOne, + }, + expect: expect{ + length: 3, + sortIdx: []int{0, 1, 2}, + }, + }, + { + description: "sortNum Text", + args: args{ + questionnaireID: questionnaireID, + sort: "1", + onlyMyResponse: false, + userID: userOne, + }, + expect: expect{ + length: 3, + sortIdx: []int{0, 1, 2}, + }, + }, + { + description: "sortNum Text desc", + args: args{ + questionnaireID: questionnaireID, + sort: "-1", + onlyMyResponse: false, + userID: userOne, + }, + expect: expect{ + length: 3, + sortIdx: []int{2, 1, 0}, + }, + }, + { + description: "invalid sortnum", + args: args{ + questionnaireID: questionnaireID, + sort: "a", + onlyMyResponse: false, + userID: userOne, + }, + expect: expect{ + isErr: true, + }, + }, + { + description: "empty sortnum", + args: args{ + questionnaireID: questionnaireID, + sort: "", + onlyMyResponse: false, + userID: userOne, + }, + expect: expect{ + length: 3, + sortIdx: []int{0, 1, 2}, + }, + }, + { + description: "traqid", + args: args{ + questionnaireID: questionnaireID, + sort: "traqid", + onlyMyResponse: true, + userID: userOne, }, expect: expect{ length: 3, @@ -761,6 +906,8 @@ func TestGetRespondentDetails(t *testing.T) { args: args{ questionnaireID: questionnaireID, sort: "-traqid", + onlyMyResponse: true, + userID: userOne, }, expect: expect{ length: 3, @@ -772,6 +919,8 @@ func TestGetRespondentDetails(t *testing.T) { args: args{ questionnaireID: questionnaireID, sort: "submitted_at", + onlyMyResponse: true, + userID: userOne, }, expect: expect{ length: 3, @@ -783,6 +932,8 @@ func TestGetRespondentDetails(t *testing.T) { args: args{ questionnaireID: questionnaireID, sort: "-submitted_at", + onlyMyResponse: true, + userID: userOne, }, expect: expect{ length: 3, @@ -794,6 +945,8 @@ func TestGetRespondentDetails(t *testing.T) { args: args{ questionnaireID: -1, sort: "1", + onlyMyResponse: true, + userID: userOne, }, expect: expect{ length: 0, @@ -805,6 +958,8 @@ func TestGetRespondentDetails(t *testing.T) { args: args{ questionnaireID: questionnaireID, sort: "3", + onlyMyResponse: true, + userID: userOne, }, expect: expect{ length: 3, @@ -816,6 +971,8 @@ func TestGetRespondentDetails(t *testing.T) { args: args{ questionnaireID: questionnaireID, sort: "-3", + onlyMyResponse: true, + userID: userOne, }, expect: expect{ length: 3, @@ -827,6 +984,8 @@ func TestGetRespondentDetails(t *testing.T) { args: args{ questionnaireID: questionnaireID, sort: "1", + onlyMyResponse: true, + userID: userOne, }, expect: expect{ length: 3, @@ -838,6 +997,8 @@ func TestGetRespondentDetails(t *testing.T) { args: args{ questionnaireID: questionnaireID, sort: "-1", + onlyMyResponse: true, + userID: userOne, }, expect: expect{ length: 3, @@ -849,6 +1010,8 @@ func TestGetRespondentDetails(t *testing.T) { args: args{ questionnaireID: questionnaireID, sort: "a", + onlyMyResponse: true, + userID: userOne, }, expect: expect{ isErr: true, @@ -859,6 +1022,8 @@ func TestGetRespondentDetails(t *testing.T) { args: args{ questionnaireID: questionnaireID, sort: "", + onlyMyResponse: true, + userID: userOne, }, expect: expect{ length: 3, @@ -868,7 +1033,7 @@ func TestGetRespondentDetails(t *testing.T) { } for _, testCase := range testCases { - respondentDetails, err := respondentImpl.GetRespondentDetails(ctx, testCase.args.questionnaireID, testCase.args.sort) + respondentDetails, err := respondentImpl.GetRespondentDetails(ctx, testCase.args.questionnaireID, testCase.args.sort, testCase.args.onlyMyResponse, testCase.args.userID) if !testCase.expect.isErr { assertion.NoError(err, testCase.description, "no error") } else if testCase.expect.err != nil { @@ -909,7 +1074,7 @@ func TestGetRespondentsUserIDs(t *testing.T) { } questionnaireIDs := make([]int, 0, 3) for i := 0; i < 3; i++ { - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, true) require.NoError(t, err) questionnaireIDs = append(questionnaireIDs, questionnaireID) } @@ -997,7 +1162,7 @@ func TestGetMyResponseIDs(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true, true) require.NoError(t, err) respondents := []Respondents{ @@ -1092,7 +1257,7 @@ func TestTestCheckRespondent(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true, true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) diff --git a/model/responses_test.go b/model/responses_test.go index ec0b5b1d..60e64a64 100644 --- a/model/responses_test.go +++ b/model/responses_test.go @@ -19,7 +19,7 @@ func TestInsertResponses(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -142,7 +142,7 @@ func TestDeleteResponse(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) diff --git a/model/scale_labels_test.go b/model/scale_labels_test.go index ad5ea98e..cbbbbc6e 100644 --- a/model/scale_labels_test.go +++ b/model/scale_labels_test.go @@ -20,7 +20,7 @@ func TestInsertScaleLabel(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -163,7 +163,7 @@ func TestUpdateScaleLabel(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -283,7 +283,7 @@ func TestDeleteScaleLabel(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -371,7 +371,7 @@ func TestGetScaleLabels(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -489,7 +489,7 @@ func TestCheckScaleLabel(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) diff --git a/model/targets_test.go b/model/targets_test.go index 79adf7c6..e55fca6b 100644 --- a/model/targets_test.go +++ b/model/targets_test.go @@ -318,7 +318,7 @@ func TestIsTargetingMe(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true, true) require.NoError(t, err) err = targetImpl.InsertTargets(ctx, questionnaireID, []string{userOne}) diff --git a/model/validations_test.go b/model/validations_test.go index 54ab6548..b150805d 100644 --- a/model/validations_test.go +++ b/model/validations_test.go @@ -20,7 +20,7 @@ func TestInsertValidation(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -212,7 +212,7 @@ func TestUpdateValidation(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -360,7 +360,7 @@ func TestDeleteValidation(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) @@ -458,7 +458,7 @@ func TestGetValidations(t *testing.T) { assertion := assert.New(t) ctx := context.Background() - questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) From 934657455a883617d21f8d55d07fefba625f3034 Mon Sep 17 00:00:00 2001 From: Eraxyso <130852025+Eraxyso@users.noreply.github.com> Date: Sat, 2 Nov 2024 18:39:56 +0000 Subject: [PATCH 5/6] feat: add IsDuplicateAnswerAllowed parameter for db migration --- model/v3.go | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/model/v3.go b/model/v3.go index 1935453a..dce971e5 100644 --- a/model/v3.go +++ b/model/v3.go @@ -21,22 +21,23 @@ func v3() *gormigrate.Migration { } type v3Questionnaires struct { - ID int `json:"questionnaireID" gorm:"type:int(11) AUTO_INCREMENT;not null;primaryKey"` - Title string `json:"title" gorm:"type:char(50);size:50;not null"` - Description string `json:"description" gorm:"type:text;not null"` - ResTimeLimit null.Time `json:"res_time_limit,omitempty" gorm:"type:TIMESTAMP NULL;default:NULL;"` - DeletedAt gorm.DeletedAt `json:"-" gorm:"type:TIMESTAMP NULL;default:NULL;"` - ResSharedTo string `json:"res_shared_to" gorm:"type:char(30);size:30;not null;default:administrators"` - CreatedAt time.Time `json:"created_at" gorm:"type:timestamp;not null;default:CURRENT_TIMESTAMP"` - ModifiedAt time.Time `json:"modified_at" gorm:"type:timestamp;not null;default:CURRENT_TIMESTAMP"` - Administrators []Administrators `json:"-" gorm:"foreignKey:QuestionnaireID"` - Targets []Targets `json:"-" gorm:"foreignKey:QuestionnaireID"` - TargetGroups []TargetGroups `json:"-" gorm:"foreignKey:QuestionnaireID"` - Questions []Questions `json:"-" gorm:"foreignKey:QuestionnaireID"` - Respondents []Respondents `json:"-" gorm:"foreignKey:QuestionnaireID"` - IsPublished bool `json:"is_published" gorm:"type:boolean;default:false"` + ID int `json:"questionnaireID" gorm:"type:int(11) AUTO_INCREMENT;not null;primaryKey"` + Title string `json:"title" gorm:"type:char(50);size:50;not null"` + Description string `json:"description" gorm:"type:text;not null"` + ResTimeLimit null.Time `json:"res_time_limit,omitempty" gorm:"type:TIMESTAMP NULL;default:NULL;"` + DeletedAt gorm.DeletedAt `json:"-" gorm:"type:TIMESTAMP NULL;default:NULL;"` + ResSharedTo string `json:"res_shared_to" gorm:"type:char(30);size:30;not null;default:administrators"` + CreatedAt time.Time `json:"created_at" gorm:"type:timestamp;not null;default:CURRENT_TIMESTAMP"` + ModifiedAt time.Time `json:"modified_at" gorm:"type:timestamp;not null;default:CURRENT_TIMESTAMP"` + Administrators []Administrators `json:"-" gorm:"foreignKey:QuestionnaireID"` + Targets []Targets `json:"-" gorm:"foreignKey:QuestionnaireID"` + TargetGroups []TargetGroups `json:"-" gorm:"foreignKey:QuestionnaireID"` + Questions []Questions `json:"-" gorm:"foreignKey:QuestionnaireID"` + Respondents []Respondents `json:"-" gorm:"foreignKey:QuestionnaireID"` + IsPublished bool `json:"is_published" gorm:"type:boolean;default:false"` + IsDuplicateAnswerAllowed bool `json:"is_duplicate_answer_allowed" gorm:"type:tinyint(4);size:4;not null;default:0"` } func (*v3Questionnaires) TableName() string { return "questionnaires" -} \ No newline at end of file +} From 84a33d2ffd07b8acd99cbfcf935230c56cc84472 Mon Sep 17 00:00:00 2001 From: Eraxyso <130852025+Eraxyso@users.noreply.github.com> Date: Sat, 2 Nov 2024 19:20:28 +0000 Subject: [PATCH 6/6] feat: unify IsAllowingMultipleResponses to IsDuplicateAnswerAllowed and update controller with new parameter --- controller/adapter.go | 24 +++---- controller/questionnaire.go | 20 +++--- docs/swagger/swagger.yaml | 10 +-- openapi/spec.go | 140 ++++++++++++++++++------------------ openapi/types.go | 36 +++++----- 5 files changed, 115 insertions(+), 115 deletions(-) diff --git a/controller/adapter.go b/controller/adapter.go index 4284a385..020bd885 100644 --- a/controller/adapter.go +++ b/controller/adapter.go @@ -11,14 +11,14 @@ import ( func questionnaireInfo2questionnaireSummary(questionnaireInfo model.QuestionnaireInfo, allResponded bool, hasMyDraft bool, hasMyResponse bool, respondedDateTimeByMe null.Time) *openapi.QuestionnaireSummary { res := openapi.QuestionnaireSummary{ - AllResponded: allResponded, - CreatedAt: questionnaireInfo.CreatedAt, - Description: questionnaireInfo.Description, - HasMyDraft: hasMyDraft, - HasMyResponse: hasMyResponse, - // IsAllowingMultipleResponses: questionnaireInfo.IsAllowingMultipleResponses, + AllResponded: allResponded, + CreatedAt: questionnaireInfo.CreatedAt, + Description: questionnaireInfo.Description, + HasMyDraft: hasMyDraft, + HasMyResponse: hasMyResponse, + IsDuplicateAnswerAllowed: questionnaireInfo.IsDuplicateAnswerAllowed, // IsAnonymous: questionnaireInfo.IsAnonymous, - // IsPublished: questionnaireInfo.IsPublished, + IsPublished: questionnaireInfo.IsPublished, IsTargetingMe: questionnaireInfo.IsTargeted, ModifiedAt: questionnaireInfo.ModifiedAt, QuestionnaireId: questionnaireInfo.ID, @@ -149,12 +149,12 @@ func convertRespondents(respondents []model.Respondents) []string { func questionnaire2QuestionnaireDetail(questionnaires model.Questionnaires, adminUsers []string, adminGroups []string, targetUsers []string, targetGroups []string, respondents []string) openapi.QuestionnaireDetail { res := openapi.QuestionnaireDetail{ - Admins: createUsersAndGroups(adminUsers, adminGroups), - CreatedAt: questionnaires.CreatedAt, - Description: questionnaires.Description, - // IsAllowingMultipleResponses: questionnaires.IsAllowingMultipleResponses, + Admins: createUsersAndGroups(adminUsers, adminGroups), + CreatedAt: questionnaires.CreatedAt, + Description: questionnaires.Description, + IsDuplicateAnswerAllowed: questionnaires.IsDuplicateAnswerAllowed, // IsAnonymous: questionnaires.IsAnonymous, - // IsPublished: questionnaires.IsPublished, + IsPublished: questionnaires.IsPublished, ModifiedAt: questionnaires.ModifiedAt, QuestionnaireId: questionnaires.ID, Questions: convertQuestions(questionnaires.Questions), diff --git a/controller/questionnaire.go b/controller/questionnaire.go index 622a658f..74bf5962 100644 --- a/controller/questionnaire.go +++ b/controller/questionnaire.go @@ -111,7 +111,7 @@ func (q Questionnaire) PostQuestionnaire(c echo.Context, userID string, params o questionnaireID := 0 err := q.ITransaction.Do(c.Request().Context(), nil, func(ctx context.Context) error { - questionnaireID, err := q.InsertQuestionnaire(ctx, params.Title, params.Description, responseDueDateTime, convertResponseViewableBy(params.ResponseViewableBy), params.IsPublished) + questionnaireID, err := q.InsertQuestionnaire(ctx, params.Title, params.Description, responseDueDateTime, convertResponseViewableBy(params.ResponseViewableBy), params.IsPublished, params.IsDuplicateAnswerAllowed) if err != nil { c.Logger().Errorf("failed to insert questionnaire: %+v", err) return err @@ -214,12 +214,12 @@ func (q Questionnaire) PostQuestionnaire(c echo.Context, userID string, params o c.Logger().Errorf("failed to get question settings: %+v", err) return openapi.QuestionnaireDetail{}, echo.NewHTTPError(http.StatusInternalServerError, "failed to get question settings") } - err = q.IScaleLabel.InsertScaleLabel(c.Request().Context(), question.ID, + err = q.IScaleLabel.InsertScaleLabel(c.Request().Context(), question.ID, model.ScaleLabels{ - ScaleLabelLeft: *b.MinLabel, + ScaleLabelLeft: *b.MinLabel, ScaleLabelRight: *b.MaxLabel, - ScaleMax: b.MaxValue, - ScaleMin: b.MinValue, + ScaleMax: b.MaxValue, + ScaleMin: b.MinValue, }) if err != nil { c.Logger().Errorf("failed to insert scale label: %+v", err) @@ -302,7 +302,7 @@ func (q Questionnaire) EditQuestionnaire(c echo.Context, questionnaireID int, pa responseDueDateTime.Time = *params.ResponseDueDateTime } err := q.ITransaction.Do(c.Request().Context(), nil, func(ctx context.Context) error { - err := q.UpdateQuestionnaire(ctx, params.Title, params.Description, responseDueDateTime, string(params.ResponseViewableBy), questionnaireID, params.IsPublished) + err := q.UpdateQuestionnaire(ctx, params.Title, params.Description, responseDueDateTime, string(params.ResponseViewableBy), questionnaireID, params.IsPublished, params.IsDuplicateAnswerAllowed) if err != nil && !errors.Is(err, model.ErrNoRecordUpdated) { c.Logger().Errorf("failed to update questionnaire: %+v", err) return err @@ -397,12 +397,12 @@ func (q Questionnaire) EditQuestionnaire(c echo.Context, questionnaireID int, pa c.Logger().Errorf("failed to get question settings: %+v", err) return echo.NewHTTPError(http.StatusInternalServerError, "failed to get question settings") } - err = q.IScaleLabel.UpdateScaleLabel(c.Request().Context(), question.ID, + err = q.IScaleLabel.UpdateScaleLabel(c.Request().Context(), question.ID, model.ScaleLabels{ - ScaleLabelLeft: *b.MinLabel, + ScaleLabelLeft: *b.MinLabel, ScaleLabelRight: *b.MaxLabel, - ScaleMax: b.MaxValue, - ScaleMin: b.MinValue, + ScaleMax: b.MaxValue, + ScaleMin: b.MinValue, }) if err != nil && !errors.Is(err, model.ErrNoRecordUpdated) { c.Logger().Errorf("failed to insert scale label: %+v", err) diff --git a/docs/swagger/swagger.yaml b/docs/swagger/swagger.yaml index fe99b014..b02dd05e 100644 --- a/docs/swagger/swagger.yaml +++ b/docs/swagger/swagger.yaml @@ -480,7 +480,7 @@ components: - $ref: "#/components/schemas/QuestionnaireResponseDueDateTime" - $ref: "#/components/schemas/QuestionnaireResponseViewableBy" - $ref: "#/components/schemas/QuestionnaireIsAnonymous" - - $ref: "#/components/schemas/QuestionnaireIsAllowingMultipleResponses" + - $ref: "#/components/schemas/QuestionnaireIsDuplicateAnswerAllowed" - $ref: "#/components/schemas/QuestionnaireIsPublished" - $ref: "#/components/schemas/QuestionnaireTargetsAndAdmins" NewQuestionnaire: @@ -519,7 +519,7 @@ components: - $ref: "#/components/schemas/QuestionnaireResponseDueDateTime" - $ref: "#/components/schemas/QuestionnaireResponseViewableBy" - $ref: "#/components/schemas/QuestionnaireIsAnonymous" - - $ref: "#/components/schemas/QuestionnaireIsAllowingMultipleResponses" + - $ref: "#/components/schemas/QuestionnaireIsDuplicateAnswerAllowed" - $ref: "#/components/schemas/QuestionnaireIsPublished" - $ref: "#/components/schemas/QuestionnaireIsTargetingMe" - $ref: "#/components/schemas/QuestionnaireCreatedAt" @@ -608,16 +608,16 @@ components: 匿名回答かどうか required: - is_anonymous - QuestionnaireIsAllowingMultipleResponses: + QuestionnaireIsDuplicateAnswerAllowed: type: object properties: - is_allowing_multiple_responses: + is_duplicate_answer_allowed: type: boolean example: true description: | 一人が複数回回答できるかどうか required: - - is_allowing_multiple_responses + - is_duplicate_answer_allowed QuestionnaireIsPublished: type: object properties: diff --git a/openapi/spec.go b/openapi/spec.go index 6b165df9..44a370ac 100644 --- a/openapi/spec.go +++ b/openapi/spec.go @@ -18,76 +18,76 @@ import ( // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/openapi/types.go b/openapi/types.go index b0ca79bc..350002bc 100644 --- a/openapi/types.go +++ b/openapi/types.go @@ -151,12 +151,12 @@ type NewQuestionnaire struct { Admins UsersAndGroups `json:"admins"` Description string `json:"description"` - // IsAllowingMultipleResponses 一人が複数回回答できるかどうか - IsAllowingMultipleResponses bool `json:"is_allowing_multiple_responses"` - // IsAnonymous 匿名回答かどうか IsAnonymous bool `json:"is_anonymous"` + // IsDuplicateAnswerAllowed 一人が複数回回答できるかどうか + IsDuplicateAnswerAllowed bool `json:"is_duplicate_answer_allowed"` + // IsPublished アンケートが公開されているかどうか IsPublished bool `json:"is_published"` Questions []NewQuestion `json:"questions"` @@ -315,12 +315,12 @@ type QuestionnaireBase struct { Admins UsersAndGroups `json:"admins"` Description string `json:"description"` - // IsAllowingMultipleResponses 一人が複数回回答できるかどうか - IsAllowingMultipleResponses bool `json:"is_allowing_multiple_responses"` - // IsAnonymous 匿名回答かどうか IsAnonymous bool `json:"is_anonymous"` + // IsDuplicateAnswerAllowed 一人が複数回回答できるかどうか + IsDuplicateAnswerAllowed bool `json:"is_duplicate_answer_allowed"` + // IsPublished アンケートが公開されているかどうか IsPublished bool `json:"is_published"` @@ -349,12 +349,12 @@ type QuestionnaireDetail struct { CreatedAt time.Time `json:"created_at"` Description string `json:"description"` - // IsAllowingMultipleResponses 一人が複数回回答できるかどうか - IsAllowingMultipleResponses bool `json:"is_allowing_multiple_responses"` - // IsAnonymous 匿名回答かどうか IsAnonymous bool `json:"is_anonymous"` + // IsDuplicateAnswerAllowed 一人が複数回回答できるかどうか + IsDuplicateAnswerAllowed bool `json:"is_duplicate_answer_allowed"` + // IsPublished アンケートが公開されているかどうか IsPublished bool `json:"is_published"` ModifiedAt time.Time `json:"modified_at"` @@ -389,18 +389,18 @@ type QuestionnaireInfo struct { Title string `json:"title"` } -// QuestionnaireIsAllowingMultipleResponses defines model for QuestionnaireIsAllowingMultipleResponses. -type QuestionnaireIsAllowingMultipleResponses struct { - // IsAllowingMultipleResponses 一人が複数回回答できるかどうか - IsAllowingMultipleResponses bool `json:"is_allowing_multiple_responses"` -} - // QuestionnaireIsAnonymous defines model for QuestionnaireIsAnonymous. type QuestionnaireIsAnonymous struct { // IsAnonymous 匿名回答かどうか IsAnonymous bool `json:"is_anonymous"` } +// QuestionnaireIsDuplicateAnswerAllowed defines model for QuestionnaireIsDuplicateAnswerAllowed. +type QuestionnaireIsDuplicateAnswerAllowed struct { + // IsDuplicateAnswerAllowed 一人が複数回回答できるかどうか + IsDuplicateAnswerAllowed bool `json:"is_duplicate_answer_allowed"` +} + // QuestionnaireIsPublished defines model for QuestionnaireIsPublished. type QuestionnaireIsPublished struct { // IsPublished アンケートが公開されているかどうか @@ -456,12 +456,12 @@ type QuestionnaireSummary struct { // HasMyResponse 回答が存在する HasMyResponse bool `json:"has_my_response"` - // IsAllowingMultipleResponses 一人が複数回回答できるかどうか - IsAllowingMultipleResponses bool `json:"is_allowing_multiple_responses"` - // IsAnonymous 匿名回答かどうか IsAnonymous bool `json:"is_anonymous"` + // IsDuplicateAnswerAllowed 一人が複数回回答できるかどうか + IsDuplicateAnswerAllowed bool `json:"is_duplicate_answer_allowed"` + // IsPublished アンケートが公開されているかどうか IsPublished bool `json:"is_published"`