Skip to content

Commit

Permalink
Merge pull request #842 from maiaht/project-categories
Browse files Browse the repository at this point in the history
Change mutation to remove several project categories from question template
  • Loading branch information
maiaht authored Nov 1, 2021
2 parents e15db2e + 5500ea7 commit 62cfb93
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 63 deletions.
7 changes: 4 additions & 3 deletions backend/api/GQL/Mutation.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;

using HotChocolate.AspNetCore.Authorization;
Expand Down Expand Up @@ -397,12 +398,12 @@ string projectCategoryId
}

[Authorize(Roles = new[] { adminRole })]
public QuestionTemplate RemoveFromProjectCategory(
public QuestionTemplate RemoveFromProjectCategories(
string questionTemplateId,
string projectCategoryId
List<string> projectCategoryIds
)
{
return _questionTemplateService.RemoveFromProjectCategory(questionTemplateId, projectCategoryId);
return _questionTemplateService.RemoveFromProjectCategories(questionTemplateId, projectCategoryIds);
}

/* Helpers */
Expand Down
24 changes: 14 additions & 10 deletions backend/api/Services/QuestionTemplateService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,27 +181,31 @@ string projectCategoryId
return template;
}

public QuestionTemplate RemoveFromProjectCategory(
public QuestionTemplate RemoveFromProjectCategories(
string questionTemplateId,
string projectCategoryId
List<string> projectCategoryIds
)
{
var template = _context.QuestionTemplates
.Include(x => x.ProjectCategories)
.Single(x => x.Id == questionTemplateId)
;

var projectCategory = _context.ProjectCategories
.Single(x => x.Id == projectCategoryId)
;

if (!template.ProjectCategories.Contains(projectCategory))
foreach (var id in projectCategoryIds)
{
string msg = "QuestionTemplate is not in ProjectCategory";
throw new Exception(msg);
var projectCategory = _context.ProjectCategories
.Single(x => x.Id == id)
;

if (!template.ProjectCategories.Contains(projectCategory))
{
string msg = "QuestionTemplate is not in ProjectCategory";
throw new Exception(msg);
}

template.ProjectCategories.Remove(projectCategory);
}

template.ProjectCategories.Remove(projectCategory);
_context.SaveChanges();
return template;
}
Expand Down
42 changes: 37 additions & 5 deletions backend/tests/Services/QuestionTemplateService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -309,19 +309,51 @@ public void RemoveFromProjectCategory()
var nActive = service.ActiveQuestions(projectCategory).Count();
var nTemplates = service.GetAll().Count();

var updatedQT = service.RemoveFromProjectCategory(template.Id, projectCategory.Id);
var updatedSP = projectCategoryService.Get(projectCategory.Id);
var updatedQT = service.RemoveFromProjectCategories(template.Id, new List<string> {projectCategory.Id});
var updatedPC = projectCategoryService.Get(projectCategory.Id);

Assert.False(updatedQT.ProjectCategories.Contains(updatedSP));
Assert.False(updatedSP.QuestionTemplates.Contains(updatedQT));
Assert.False(updatedQT.ProjectCategories.Contains(updatedPC));
Assert.False(updatedPC.QuestionTemplates.Contains(updatedQT));

Assert.Equal(nActive - 1, service.ActiveQuestions(projectCategory).Count());
Assert.Equal(nTemplates, service.GetAll().Count());

/* Removing the same QuestionTemplate should fail */
Assert.Throws<Exception>(() =>
service.RemoveFromProjectCategory(template.Id, projectCategory.Id)
service.RemoveFromProjectCategories(template.Id, new List<string> {projectCategory.Id})
);
}

[Fact]
public void RemoveFromSeveralProjectCategories()
{
var projectCategoryService = new ProjectCategoryService(fixture.context);
var projectCategory1 = projectCategoryService.Create(Randomize.String());
var projectCategory2 = projectCategoryService.Create(Randomize.String());
var projectCategoryIds = new List<string> {projectCategory1.Id, projectCategory2.Id};

var service = new QuestionTemplateService(fixture.context);
var template = service.GetAll().First();

service.AddToProjectCategory(template.Id, projectCategory1.Id);
service.AddToProjectCategory(template.Id, projectCategory2.Id);

var nActiveFirstCategory = service.ActiveQuestions(projectCategory1).Count();
var nActiveSecondCategory = service.ActiveQuestions(projectCategory2).Count();
var nTemplates = service.GetAll().Count();

var updatedQT = service.RemoveFromProjectCategories(template.Id, projectCategoryIds);
var updatedPC1 = projectCategoryService.Get(projectCategory1.Id);
var updatedPC2 = projectCategoryService.Get(projectCategory2.Id);

Assert.False(updatedQT.ProjectCategories.Contains(updatedPC1));
Assert.False(updatedQT.ProjectCategories.Contains(updatedPC2));
Assert.False(updatedPC1.QuestionTemplates.Contains(updatedQT));
Assert.False(updatedPC2.QuestionTemplates.Contains(updatedQT));

Assert.Equal(nActiveFirstCategory - 1, service.ActiveQuestions(projectCategory1).Count());
Assert.Equal(nActiveSecondCategory - 1, service.ActiveQuestions(projectCategory2).Count());
Assert.Equal(nTemplates, service.GetAll().Count());
}
}
}
6 changes: 3 additions & 3 deletions frontend/src/api/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ export type Mutation = {
deleteQuestionTemplate?: Maybe<QuestionTemplate>;
reorderQuestionTemplate?: Maybe<QuestionTemplate>;
addToProjectCategory?: Maybe<QuestionTemplate>;
removeFromProjectCategory?: Maybe<QuestionTemplate>;
removeFromProjectCategories?: Maybe<QuestionTemplate>;
};


Expand Down Expand Up @@ -511,9 +511,9 @@ export type MutationAddToProjectCategoryArgs = {
};


export type MutationRemoveFromProjectCategoryArgs = {
export type MutationRemoveFromProjectCategoriesArgs = {
questionTemplateId?: Maybe<Scalars['String']>;
projectCategoryId?: Maybe<Scalars['String']>;
projectCategoryIds?: Maybe<Array<Maybe<Scalars['String']>>>;
};

export type Note = {
Expand Down
85 changes: 43 additions & 42 deletions frontend/src/views/Admin/StaticQuestionItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ const StaticQuestionItem = ({
} = useAddToProjectCategoryMutation()

const {
removeFromProjectCategory,
removeFromProjectCategories,
loading: removingFromProjectCategory,
error: removingFromProjectCategoryError,
} = useRemoveFromProjectCategoryMutation()
} = useRemoveFromProjectCategoriesMutation()

const {
deleteQuestionTemplate,
Expand Down Expand Up @@ -167,21 +167,32 @@ const StaticQuestionItem = ({

const updateProjectCategories = (selection: string[] | undefined) => {
if (selection) {
const addedItemInSelection = checkIfAddedCategory(selection)
const removedItemInSelection = checkIfRemovedCategory(selection)

if (addedItemInSelection) {
addToProjectCategory({
questionTemplateId: question.id,
projectCategoryId: addedItemInSelection.id,
if (selection.length === 0) {
const ids: string[] = []
question.projectCategories.forEach(questionProjectCategory => {
ids.push(questionProjectCategory.id)
})
}

if (removedItemInSelection) {
removeFromProjectCategory({
removeFromProjectCategories({
questionTemplateId: question.id,
projectCategoryId: removedItemInSelection.id,
projectCategoryIds: ids,
})
} else {
const addedItemInSelection = checkIfAddedCategory(selection)
const removedItemInSelection = checkIfRemovedCategory(selection)

if (addedItemInSelection) {
addToProjectCategory({
questionTemplateId: question.id,
projectCategoryId: addedItemInSelection.id,
})
}

if (removedItemInSelection) {
removeFromProjectCategories({
questionTemplateId: question.id,
projectCategoryIds: [removedItemInSelection.id],
})
}
}
}
}
Expand Down Expand Up @@ -313,13 +324,13 @@ const StaticQuestionItem = ({

export default StaticQuestionItem

export interface DataToAddToOrRemoveFromProjectCategory {
export interface DataToAddToProjectCategory {
questionTemplateId: string
projectCategoryId: string
}

interface AddToProjectCategoryMutationProps {
addToProjectCategory: (data: DataToAddToOrRemoveFromProjectCategory) => void
addToProjectCategory: (data: DataToAddToProjectCategory) => void
loading: boolean
error: ApolloError | undefined
}
Expand Down Expand Up @@ -354,7 +365,7 @@ const useAddToProjectCategoryMutation = (): AddToProjectCategoryMutationProps =>
},
})

const addToProjectCategory = (data: DataToAddToOrRemoveFromProjectCategory) => {
const addToProjectCategory = (data: DataToAddToProjectCategory) => {
addToProjectCategoryApolloFunc({
variables: { ...data },
})
Expand All @@ -367,16 +378,21 @@ const useAddToProjectCategoryMutation = (): AddToProjectCategoryMutationProps =>
}
}

interface RemoveFromProjectCategoryMutationProps {
removeFromProjectCategory: (data: DataToAddToOrRemoveFromProjectCategory) => void
export interface DataToRemoveFromProjectCategories {
questionTemplateId: string
projectCategoryIds: string[]
}

interface RemoveFromProjectCategoriesMutationProps {
removeFromProjectCategories: (data: DataToRemoveFromProjectCategories) => void
loading: boolean
error: ApolloError | undefined
}

const useRemoveFromProjectCategoryMutation = (): RemoveFromProjectCategoryMutationProps => {
const REMOVE_FROM_PROJECT_CATEGORY = gql`
mutation RemoveFromProjectCategory($questionTemplateId: String!, $projectCategoryId: String!) {
removeFromProjectCategory(questionTemplateId: $questionTemplateId, projectCategoryId: $projectCategoryId) {
const useRemoveFromProjectCategoriesMutation = (): RemoveFromProjectCategoriesMutationProps => {
const REMOVE_FROM_PROJECT_CATEGORIES = gql`
mutation RemoveFromProjectCategories($questionTemplateId: String!, $projectCategoryIds: [String]!) {
removeFromProjectCategories(questionTemplateId: $questionTemplateId, projectCategoryIds: $projectCategoryIds) {
id
projectCategories {
id
Expand All @@ -386,31 +402,16 @@ const useRemoveFromProjectCategoryMutation = (): RemoveFromProjectCategoryMutati
}
`

const [removeFromProjectCategoryApolloFunc, { loading, data, error }] = useMutation(REMOVE_FROM_PROJECT_CATEGORY, {
update(cache, mutationResult) {
const questionTemplateRemovedFrom = mutationResult.data.removeFromProjectCategory
cache.modify({
id: cache.identify({
__typename: 'QuestionTemplate',
id: questionTemplateRemovedFrom.id,
}),
fields: {
projectCategories() {
return questionTemplateRemovedFrom.projectCategories
},
},
})
},
})
const [removeFromProjectCategoriesApolloFunc, { loading, data, error }] = useMutation(REMOVE_FROM_PROJECT_CATEGORIES)

const removeFromProjectCategory = (data: DataToAddToOrRemoveFromProjectCategory) => {
removeFromProjectCategoryApolloFunc({
const removeFromProjectCategories = (data: DataToRemoveFromProjectCategories) => {
removeFromProjectCategoriesApolloFunc({
variables: { ...data },
})
}

return {
removeFromProjectCategory,
removeFromProjectCategories,
loading,
error,
}
Expand Down

0 comments on commit 62cfb93

Please sign in to comment.