Skip to content

Commit

Permalink
feat: 回答があっても、SOS管理者が申請を更新できるように
Browse files Browse the repository at this point in the history
  • Loading branch information
arata-nvm committed Jul 25, 2024
1 parent 4632eb7 commit 7fbea8e
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 29 deletions.
31 changes: 16 additions & 15 deletions crates/sos24-domain/src/entity/permission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,26 @@ bitflags! {
const CREATE_FORM = 1 << 11;
const READ_FORM_ALL = 1 << 12;
const UPDATE_FORM_ALL = 1 << 13;
const DELETE_FORM_ALL = 1 << 14;
const UPDATE_FORM_ALL_ANSWERED = 1 << 14;
const DELETE_FORM_ALL = 1 << 15;

const CREATE_INVITATION = 1 << 15;
const CREATE_INVITATION_ANYTIME = 1 << 16;
const READ_INVITATION_ALL = 1 << 17;
const UPDATE_INVITATION_ALL = 1 << 18;
const DELETE_INVITATION_ALL = 1 << 19;
const CREATE_INVITATION = 1 << 16;
const CREATE_INVITATION_ANYTIME = 1 << 17;
const READ_INVITATION_ALL = 1 << 18;
const UPDATE_INVITATION_ALL = 1 << 19;
const DELETE_INVITATION_ALL = 1 << 20;

const CREATE_FORM_ANSWER = 1 << 20;
const READ_FORM_ANSWER_ALL = 1 << 21;
const UPDATE_FORM_ANSWER_ALL = 1 << 22;
const UPDATE_FORM_ANSWER_ANYTIME = 1 << 23;
const CREATE_FORM_ANSWER = 1 << 21;
const READ_FORM_ANSWER_ALL = 1 << 22;
const UPDATE_FORM_ANSWER_ALL = 1 << 23;
const UPDATE_FORM_ANSWER_ANYTIME = 1 << 24;

const CREATE_FILE_PRIVATE = 1 << 24;
const CREATE_FILE_PUBLIC = 1 << 25;
const READ_FILE_ALL = 1 << 26;
const DELETE_FILE_ALL = 1 << 27;
const CREATE_FILE_PRIVATE = 1 << 25;
const CREATE_FILE_PUBLIC = 1 << 26;
const READ_FILE_ALL = 1 << 27;
const DELETE_FILE_ALL = 1 << 28;

const CREATE_PROJECT_ANYTIME = 1 << 28;
const CREATE_PROJECT_ANYTIME = 1 << 29;
}
}

Expand Down
87 changes: 73 additions & 14 deletions crates/sos24-use-case/src/form/interactor/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ impl<R: Repositories, A: Adapters> FormUseCase<R, A> {
.form_answer_repository()
.find_by_form_id(id.clone())
.await?;
if !answers.is_empty() {
let has_answer = !answers.is_empty();

// 回答がある場合、SOS管理者以外は変更できない
if has_answer && !actor.has_permission(Permissions::UPDATE_FORM_ALL_ANSWERED) {
return Err(FormUseCaseError::HasAnswers);
}

Expand All @@ -63,18 +66,23 @@ impl<R: Repositories, A: Adapters> FormUseCase<R, A> {
new_form.set_ends_at(&actor, DateTime::try_from(form_data.ends_at)?)?;
new_form.set_categories(&actor, ProjectCategories::from(form_data.categories))?;
new_form.set_attributes(&actor, ProjectAttributes::from(form_data.attributes))?;
let new_items = form_data
.items
.into_iter()
.map(FormItem::try_from)
.collect::<Result<_, _>>()?;
new_form.set_items(&actor, new_items)?;
let new_attachments = form_data
.attachments
.into_iter()
.map(FileId::try_from)
.collect::<Result<_, _>>()?;
new_form.set_attachments(&actor, new_attachments)?;
{
let new_attachments = form_data
.attachments
.into_iter()
.map(FileId::try_from)
.collect::<Result<_, _>>()?;
new_form.set_attachments(&actor, new_attachments)?;
}
// 回答がない場合のみ、申請項目を更新
if !has_answer {
let new_items = form_data
.items
.into_iter()
.map(FormItem::try_from)
.collect::<Result<_, _>>()?;
new_form.set_items(&actor, new_items)?;
}

self.repositories.form_repository().update(new_form).await?;
Ok(())
Expand Down Expand Up @@ -186,7 +194,7 @@ mod tests {
}

#[tokio::test]
async fn 回答がある申請は更新できない() {
async fn 実委人管理者は回答がある申請を更新できない() {
let mut repositories = MockRepositories::default();
repositories
.form_repository_mut()
Expand Down Expand Up @@ -230,4 +238,55 @@ mod tests {
.await;
assert!(matches!(res, Err(FormUseCaseError::HasAnswers)));
}

#[tokio::test]
#[allow(non_snake_case)]
async fn SOS管理者は回答がある申請を更新できる() {
let mut repositories = MockRepositories::default();
repositories
.form_repository_mut()
.expect_find_by_id()
.returning(|_| Ok(Some(fixture::form::form1_opened())));
repositories
.form_answer_repository_mut()
.expect_find_by_form_id()
.returning(|_| {
Ok(vec![fixture::form_answer::form_answer1(
fixture::project::id1(),
)])
});
repositories
.form_repository_mut()
.expect_update()
.returning(|_| Ok(()));
let adapters = MockAdapters::default();
let use_case = FormUseCase::new(Arc::new(repositories), Arc::new(adapters));

let ctx = TestContext::new(fixture::actor::actor1(UserRole::Administrator));
let res = use_case
.update(
&ctx,
UpdateFormCommand {
id: fixture::form::id1().value().to_string(),
title: fixture::form::title2().value(),
description: fixture::form::description2().value(),
starts_at: fixture::form::starts_at2().value().to_rfc3339(),
ends_at: fixture::form::ends_at2().value().to_rfc3339(),
categories: ProjectCategoriesDto::from(fixture::form::categories2()),
attributes: ProjectAttributesDto::from(fixture::form::attributes2()),
items: vec![NewFormItemDto::new(
fixture::form::formitem_name1().value(),
Some(fixture::form::description1().value()),
fixture::form::formitem_required1().value(),
FormItemKindDto::from(fixture::form::formitem_kind1()),
)],
attachments: fixture::form::attachments2()
.into_iter()
.map(|it| it.value().to_string())
.collect(),
},
)
.await;
assert!(res.is_ok());
}
}

0 comments on commit 7fbea8e

Please sign in to comment.