Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change mutation to remove several project categories from question template #842

Merged
merged 2 commits into from
Nov 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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