diff --git a/controller/adapter.go b/controller/adapter.go index b385a31a..cd173d10 100644 --- a/controller/adapter.go +++ b/controller/adapter.go @@ -12,14 +12,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, @@ -150,20 +150,20 @@ func convertRespondents(respondents []model.Respondents) []string { func questionnaire2QuestionnaireDetail(questionnaires model.Questionnaires, adminUsers []string, adminGroups []uuid.UUID, targetUsers []string, targetGroups []uuid.UUID, respondents []string) openapi.QuestionnaireDetail { res := openapi.QuestionnaireDetail{ - Admins: createUsersAndGroups(adminUsers, adminGroups), - CreatedAt: questionnaires.CreatedAt, - Description: questionnaires.Description, - // IsAllowingMultipleResponses: questionnaires.IsAllowingMultipleResponses, - IsAnonymous: questionnaires.IsAnonymous, - IsPublished: questionnaires.IsPublished, - ModifiedAt: questionnaires.ModifiedAt, - QuestionnaireId: questionnaires.ID, - Questions: convertQuestions(questionnaires.Questions), - Respondents: respondents, - ResponseDueDateTime: &questionnaires.ResTimeLimit.Time, - ResponseViewableBy: convertResSharedTo(questionnaires.ResSharedTo), - Targets: createUsersAndGroups(targetUsers, targetGroups), - Title: questionnaires.Title, + Admins: createUsersAndGroups(adminUsers, adminGroups), + CreatedAt: questionnaires.CreatedAt, + Description: questionnaires.Description, + IsDuplicateAnswerAllowed: questionnaires.IsDuplicateAnswerAllowed, + IsAnonymous: questionnaires.IsAnonymous, + IsPublished: questionnaires.IsPublished, + ModifiedAt: questionnaires.ModifiedAt, + QuestionnaireId: questionnaires.ID, + Questions: convertQuestions(questionnaires.Questions), + Respondents: respondents, + ResponseDueDateTime: &questionnaires.ResTimeLimit.Time, + ResponseViewableBy: convertResSharedTo(questionnaires.ResSharedTo), + Targets: createUsersAndGroups(targetUsers, targetGroups), + Title: questionnaires.Title, } return res } diff --git a/controller/questionnaire.go b/controller/questionnaire.go index 99e0ccaf..efe111d9 100644 --- a/controller/questionnaire.go +++ b/controller/questionnaire.go @@ -132,7 +132,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, params.IsAnonymous) + questionnaireID, err := q.InsertQuestionnaire(ctx, params.Title, params.Description, responseDueDateTime, convertResponseViewableBy(params.ResponseViewableBy), params.IsPublished, params.IsAnonymous, params.IsDuplicateAnswerAllowed) if err != nil { c.Logger().Errorf("failed to insert questionnaire: %+v", err) return err @@ -359,7 +359,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, params.IsAnonymous) + err := q.UpdateQuestionnaire(ctx, params.Title, params.Description, responseDueDateTime, string(params.ResponseViewableBy), questionnaireID, params.IsPublished, params.IsAnonymous, params.IsDuplicateAnswerAllowed) if err != nil && !errors.Is(err, model.ErrNoRecordUpdated) { c.Logger().Errorf("failed to update questionnaire: %+v", err) return err diff --git a/docs/swagger/swagger.yaml b/docs/swagger/swagger.yaml index 7bbea625..35dc86b0 100644 --- a/docs/swagger/swagger.yaml +++ b/docs/swagger/swagger.yaml @@ -457,7 +457,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: @@ -496,7 +496,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" @@ -585,16 +585,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/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/questionnaires.go b/model/questionnaires.go index 0ed2780b..67d20177 100644 --- a/model/questionnaires.go +++ b/model/questionnaires.go @@ -11,8 +11,8 @@ import ( // IQuestionnaire QuestionnaireのRepository type IQuestionnaire interface { - InsertQuestionnaire(ctx context.Context, title string, description string, resTimeLimit null.Time, resSharedTo string, isPublished bool, isAnonymous bool) (int, error) - UpdateQuestionnaire(ctx context.Context, title string, description string, resTimeLimit null.Time, resSharedTo string, questionnaireID int, isPublished bool, isAnonymous bool) error + InsertQuestionnaire(ctx context.Context, title string, description string, resTimeLimit null.Time, resSharedTo string, isPublished bool, isAnonymous bool, IsDuplicateAnswerAllowed bool) (int, error) + UpdateQuestionnaire(ctx context.Context, title string, description string, resTimeLimit null.Time, resSharedTo string, questionnaireID int, isPublished bool, isAnonymous bool, IsDuplicateAnswerAllowed bool) error DeleteQuestionnaire(ctx context.Context, questionnaireID int) error GetQuestionnaires(ctx context.Context, userID string, sort string, search string, pageNum int, onlyTargetingMe bool, onlyAdministratedByMe 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 f8fa8c3d..eb93db5f 100755 --- a/model/questionnaires_impl.go +++ b/model/questionnaires_impl.go @@ -22,21 +22,22 @@ 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"` - IsAnonymous bool `json:"is_anonymous" gorm:"type:boolean;not null;default:false"` - 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"` + IsAnonymous bool `json:"is_anonymous" gorm:"type:boolean;not null;default:false"` + IsDuplicateAnswerAllowed bool `json:"is_duplicate_answer_allowed" gorm:"type:tinyint(4);size:4;not null;default:0"` } // BeforeCreate Update時に自動でmodified_atを現在時刻に @@ -83,7 +84,7 @@ type ResponseReadPrivilegeInfo struct { } // InsertQuestionnaire アンケートの追加 -func (*Questionnaire) InsertQuestionnaire(ctx context.Context, title string, description string, resTimeLimit null.Time, resSharedTo string, isPublished bool, isAnonymous bool) (int, error) { +func (*Questionnaire) InsertQuestionnaire(ctx context.Context, title string, description string, resTimeLimit null.Time, resSharedTo string, isPublished bool, isAnonymous bool, isDuplicateAnswerAllowed bool) (int, error) { db, err := getTx(ctx) if err != nil { return 0, fmt.Errorf("failed to get tx: %w", err) @@ -92,20 +93,22 @@ func (*Questionnaire) InsertQuestionnaire(ctx context.Context, title string, des var questionnaire Questionnaires if !resTimeLimit.Valid { questionnaire = Questionnaires{ - Title: title, - Description: description, - ResSharedTo: resSharedTo, - IsPublished: isPublished, - IsAnonymous: isAnonymous, + Title: title, + Description: description, + ResSharedTo: resSharedTo, + IsPublished: isPublished, + IsAnonymous: isAnonymous, + IsDuplicateAnswerAllowed: isDuplicateAnswerAllowed, } } else { questionnaire = Questionnaires{ - Title: title, - Description: description, - ResTimeLimit: resTimeLimit, - ResSharedTo: resSharedTo, - IsPublished: isPublished, - IsAnonymous: isAnonymous, + Title: title, + Description: description, + ResTimeLimit: resTimeLimit, + ResSharedTo: resSharedTo, + IsPublished: isPublished, + IsAnonymous: isAnonymous, + IsDuplicateAnswerAllowed: isDuplicateAnswerAllowed, } } @@ -118,7 +121,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, isPublished bool, isAnonymous bool) error { +func (*Questionnaire) UpdateQuestionnaire(ctx context.Context, title string, description string, resTimeLimit null.Time, resSharedTo string, questionnaireID int, isPublished bool, isAnonymous bool, isDuplicateAnswerAllowed bool) error { db, err := getTx(ctx) if err != nil { return fmt.Errorf("failed to get tx: %w", err) @@ -127,21 +130,23 @@ 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, - IsPublished: isPublished, - IsAnonymous: isAnonymous, + Title: title, + Description: description, + ResTimeLimit: resTimeLimit, + ResSharedTo: resSharedTo, + IsPublished: isPublished, + IsAnonymous: isAnonymous, + IsDuplicateAnswerAllowed: isDuplicateAnswerAllowed, } } else { questionnaire = map[string]interface{}{ - "title": title, - "description": description, - "res_time_limit": gorm.Expr("NULL"), - "res_shared_to": resSharedTo, - "is_published": isPublished, - "is_anonymous": isAnonymous, + "title": title, + "description": description, + "res_time_limit": gorm.Expr("NULL"), + "res_shared_to": resSharedTo, + "is_published": isPublished, + "is_anonymous": isAnonymous, + "is_duplicate_answer_allowed": isDuplicateAnswerAllowed, } } diff --git a/model/questionnaires_test.go b/model/questionnaires_test.go index d828e7f8..bb173f15 100644 --- a/model/questionnaires_test.go +++ b/model/questionnaires_test.go @@ -364,12 +364,13 @@ func insertQuestionnaireTest(t *testing.T) { assertion := assert.New(t) type args struct { - title string - description string - resTimeLimit null.Time - resSharedTo string - isPublished bool - isAnonymous bool + title string + description string + resTimeLimit null.Time + resSharedTo string + isPublished bool + isAnonymous bool + isDuplicateAnswerAllowed bool } type expect struct { isErr bool @@ -504,7 +505,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, testCase.args.isPublished, testCase.args.isAnonymous) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, testCase.args.title, testCase.args.description, testCase.args.resTimeLimit, testCase.args.resSharedTo, testCase.args.isPublished, testCase.args.isAnonymous, testCase.args.isDuplicateAnswerAllowed) if !testCase.expect.isErr { assertion.NoError(err, testCase.description, "no error") @@ -529,6 +530,7 @@ func insertQuestionnaireTest(t *testing.T) { 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.isPublished, questionnaire.IsPublished, testCase.description, "is_published") + 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") @@ -541,12 +543,13 @@ func updateQuestionnaireTest(t *testing.T) { assertion := assert.New(t) type args struct { - title string - description string - resTimeLimit null.Time - resSharedTo string - isPublished bool - isAnonymous bool + title string + description string + resTimeLimit null.Time + resSharedTo string + isPublished bool + isAnonymous bool + isDuplicateAnswerAllowed bool } type expect struct { isErr bool @@ -777,11 +780,12 @@ func updateQuestionnaireTest(t *testing.T) { before := &testCase.before questionnaire := Questionnaires{ - Title: before.title, - Description: before.description, - ResTimeLimit: before.resTimeLimit, - ResSharedTo: before.resSharedTo, - IsPublished: before.isPublished, + Title: before.title, + Description: before.description, + ResTimeLimit: before.resTimeLimit, + ResSharedTo: before.resSharedTo, + IsPublished: before.isPublished, + IsDuplicateAnswerAllowed: before.isDuplicateAnswerAllowed, } err := db. Session(&gorm.Session{NewDB: true}). @@ -793,7 +797,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, after.isPublished, false) + err = questionnaireImpl.UpdateQuestionnaire(ctx, after.title, after.description, after.resTimeLimit, after.resSharedTo, questionnaireID, after.isPublished, after.isAnonymous, after.isDuplicateAnswerAllowed) if !testCase.expect.isErr { assertion.NoError(err, testCase.description, "no error") @@ -818,6 +822,7 @@ func updateQuestionnaireTest(t *testing.T) { 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.isPublished, questionnaire.IsPublished, testCase.description, "is_published") + 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") @@ -862,7 +867,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, arg.isPublished, arg.isAnonymous) + err := questionnaireImpl.UpdateQuestionnaire(ctx, arg.title, arg.description, arg.resTimeLimit, arg.resSharedTo, invalidQuestionnaireID, arg.isPublished, arg.isAnonymous, arg.isDuplicateAnswerAllowed) if !errors.Is(err, ErrNoRecordUpdated) { if err == nil { t.Errorf("Succeeded with invalid questionnaireID") @@ -879,12 +884,13 @@ func deleteQuestionnaireTest(t *testing.T) { assertion := assert.New(t) type args struct { - title string - description string - resTimeLimit null.Time - resSharedTo string - isPublished bool - isAnonymous bool + title string + description string + resTimeLimit null.Time + resSharedTo string + isPublished bool + isAnonymous bool + isDuplicateAnswerAllowed bool } type expect struct { isErr bool @@ -912,12 +918,13 @@ 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, - IsPublished: testCase.isPublished, - IsAnonymous: testCase.args.isAnonymous, + Title: testCase.args.title, + Description: testCase.args.description, + ResTimeLimit: testCase.args.resTimeLimit, + ResSharedTo: testCase.args.resSharedTo, + IsPublished: testCase.isPublished, + IsAnonymous: testCase.args.isAnonymous, + IsDuplicateAnswerAllowed: testCase.args.isDuplicateAnswerAllowed, } err := db. Session(&gorm.Session{NewDB: true}). @@ -1025,11 +1032,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 @@ -1047,81 +1055,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, @@ -1131,21 +1147,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, @@ -1155,21 +1173,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, @@ -1179,11 +1199,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, @@ -1195,7 +1375,7 @@ func getQuestionnairesTest(t *testing.T) { for _, testCase := range testCases { ctx := context.Background() - questionnaires, pageMax, err := questionnaireImpl.GetQuestionnaires(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") @@ -1222,11 +1402,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)") } @@ -1235,7 +1420,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) @@ -1468,6 +1653,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 { @@ -1484,6 +1672,7 @@ func getQuestionnaireInfoTest(t *testing.T) { 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.IsPublished, actualQuestionnaire.IsPublished, testCase.description, "questionnaire(IsPublished)") + 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_impl.go b/model/respondents_impl.go index 233dbcfc..456e3488 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,26 @@ func (*Respondent) InsertRespondent(ctx context.Context, userID string, question } } + if !questionnaire.IsDuplicateAnswerAllowed { + err = db. + Where("questionnaire_id = ? AND user_traqid = ?", questionnaireID, userID). + First(&Respondents{}).Error + if err == nil { + return 0, ErrDuplicatedAnswered + } + if !errors.Is(err, gorm.ErrRecordNotFound) { + return 0, fmt.Errorf("failed to check duplicate answer: %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 投稿日時更新 diff --git a/model/respondents_test.go b/model/respondents_test.go index 41078f11..2805fc3f 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true, false, 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true, false, 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true, false, 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第2回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, false, true) require.NoError(t, err) - questionnaireID2, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第2回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, false) + questionnaireID2, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第2回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, false, 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true, false, 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true, false, 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, false, "") + 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, false, 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true, false, true) require.NoError(t, err) respondents := []Respondents{ @@ -1096,7 +1261,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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true, false, 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 cd6793f3..37b0a676 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, false, 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, false, 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 12e12b11..780db5d9 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, false, 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, false, 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, false, 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, false, 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, false, 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 b525eb6e..6028d1fb 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "private", true, false, true) require.NoError(t, err) err = targetImpl.InsertTargets(ctx, questionnaireID, []string{userOne}) diff --git a/model/v3.go b/model/v3.go index 2bf827b9..b28160e9 100644 --- a/model/v3.go +++ b/model/v3.go @@ -34,20 +34,22 @@ func (*v3Targets) TableName() string { } 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"` - IsAnonymous bool `json:"is_anonymous" gorm:"type:boolean;not null;default:false"` - 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"` - 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"` + IsAnonymous bool `json:"is_anonymous" gorm:"type:boolean;not null;default:false"` + IsDuplicateAnswerAllowed bool `json:"is_duplicate_answer_allowed" gorm:"type:tinyint(4);size:4;not null;default:0"` } func (*v3Questionnaires) TableName() string { diff --git a/model/validations_test.go b/model/validations_test.go index c59e1adf..dd84b715 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, false, 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, false, 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, false, 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, false) + questionnaireID, err := questionnaireImpl.InsertQuestionnaire(ctx, "第1回集会らん☆ぷろ募集アンケート", "第1回メンバー集会でのらん☆ぷろで発表したい人を募集します らん☆ぷろで発表したい人あつまれー!", null.NewTime(time.Now(), false), "public", true, false, true) require.NoError(t, err) err = administratorImpl.InsertAdministrators(ctx, questionnaireID, []string{userOne}) diff --git a/openapi/spec.go b/openapi/spec.go index 88e3e723..a18514d4 100644 --- a/openapi/spec.go +++ b/openapi/spec.go @@ -1,6 +1,6 @@ // Package openapi provides primitives to interact with the openapi HTTP API. // -// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.4.1 DO NOT EDIT. +// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.3.0 DO NOT EDIT. package openapi import ( @@ -17,74 +17,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 f033c075..49d72551 100644 --- a/openapi/types.go +++ b/openapi/types.go @@ -149,12 +149,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"` @@ -312,12 +312,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"` @@ -346,12 +346,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"` @@ -386,18 +386,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 アンケートが公開されているかどうか @@ -453,12 +453,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"`