diff --git a/conf/permissions.dist.yml b/conf/permissions.dist.yml index cd310b4a..36a3d9b8 100644 --- a/conf/permissions.dist.yml +++ b/conf/permissions.dist.yml @@ -102,6 +102,9 @@ db_permissions: getUserSets: allow_self_access: true allowed_roles: ['course_admin', 'instructor'] + getUserSet: + allow_self_access: true + allowed_roles: ['course_admin', 'instructor'] addUserSet: allowed_roles: ['course_admin', 'instructor'] updateUserSet: diff --git a/lib/DB/Schema/ResultSet/Course.pm b/lib/DB/Schema/ResultSet/Course.pm index 08294bc0..9183186b 100644 --- a/lib/DB/Schema/ResultSet/Course.pm +++ b/lib/DB/Schema/ResultSet/Course.pm @@ -169,18 +169,13 @@ C, a boolean if the return is to be a result_set =head3 output -The deleted course either as a C< DBIx::Class::ResultSet::Course> object or a hashref -of the fields. See above. +Nothing (undef) is returned. =cut sub deleteCourse ($self, %args) { - my $course_to_delete = $self->getCourse(info => getCourseInfo($args{info}), as_result_set => 1); - - my $deleted_course = $course_to_delete->delete; - return $deleted_course if $args{as_result_set}; - - return { $course_to_delete->get_inflated_columns }; + $self->getCourse(info => getCourseInfo($args{info}), as_result_set => 1)->delete; + return; } =head1 updateCourse diff --git a/lib/DB/Schema/ResultSet/ProblemPool.pm b/lib/DB/Schema/ResultSet/ProblemPool.pm index 6f1f5f5b..f79db9c7 100644 --- a/lib/DB/Schema/ResultSet/ProblemPool.pm +++ b/lib/DB/Schema/ResultSet/ProblemPool.pm @@ -88,12 +88,12 @@ sub getProblemPool ($self, %args) { my $pool = $self->find($search_info, { join => [qw/courses/] }); - unless ($pool) { - my $course_name = $course->course_name; + DB::Exception::PoolNotInCourse->throw(message => 'The pool with ' + . ($args{info}{pool_name} ? ' name ' . $args{info}{pool_name} : 'id ' . $args{info}{problem_pool_id}) + . 'is not in the course ' + . $course->course_name) + unless $pool; - DB::Exception::PoolNotInCourse->throw( - message => "The pool with name \{$args{info}->{pool_name}} is not in the course $course_name"); - } return $pool if $args{as_result_set}; return { $pool->get_columns }; } @@ -102,6 +102,27 @@ sub getProblemPool ($self, %args) { Add a problem pool for a given course +=head3 arguments + +=over + +=item * C a hashref specifying information on the added problem pool +One must include either the C or C and the C. +If there is not enough info to get the course and pool, a C exception is thrown. + + +=item * C: boolean + +If C is true, then the user sets are returned as a C. +See C for more information + +=back + +=head3 output + +Either a hashref of the added problem pool or a C +if C is true. + =cut sub addProblemPool ($self, %args) { @@ -147,13 +168,32 @@ sub addProblemPool ($self, %args) { updates the parameters of an existing problem pool +=head3 arguments + +=over + +=item * C a hashref specifying information on the problem pool +One must include either the C or C and either the C +or C. If there is not enough info to get the course and pool, a +C exception is thrown. + +=item * C: a hashref containing the information to be updated. + +=item * C: boolean + +If C is true, then the user sets are returned as a C. +See C for more information + +=back + + =cut sub updateProblemPool ($self, %args) { my $pool = $self->getProblemPool(info => $args{info}, as_result_set => 1); - DB::Excpetion::PoolNotInCourse->throw( + DB::Exception::PoolNotInCourse->throw( message => 'The problem pool ' . ( $args{info}->{pool_name} @@ -173,21 +213,36 @@ sub updateProblemPool ($self, %args) { return { $updated_pool->get_columns }; } -=head2 updateProblemPool +=head2 deleteProblemPool -updates the parameters of an existing problem pool +delete a Problem Pool -=cut +=head3 arguments -sub deleteProblemPool ($self, %args) { - my $pool = $self->getProblemPool(info => $args{info}, as_result_set => 1); +=over - DB::Exception::PoolNotInCourse->throws(error => 'The problem pool does not exist') - unless defined($pool); +=item * C a hashref specifying information on the problem pool +One must include either the C or C and either the C +or C. If there is not enough info to get the course and pool, a +C exception is thrown. + + +=item * C: boolean + +If C is true, then the user sets are returned as a C. +See C for more information + +=back + +=head3 output - my $deleted_pool = $pool->delete(); +Nothing (undef) is returned. - return $args{as_result_set} ? $deleted_pool : { $deleted_pool->get_columns }; +=cut + +sub deleteProblemPool ($self, %args) { + $self->getProblemPool(info => $args{info}, as_result_set => 1)->delete; + return; } ##### @@ -257,7 +312,6 @@ This gets a single problem out of a ProblemPool. =cut sub getPoolProblem ($self, %args) { - my $problem_pool = $self->getProblemPool(info => $args{info}, as_result_set => 1); my $pool_problem_info = {}; @@ -273,6 +327,13 @@ sub getPoolProblem ($self, %args) { if (scalar(@pool_problems) == 1) { return $args{as_result_set} ? $pool_problems[0] : { $pool_problems[0]->get_inflated_columns }; + } elsif (scalar(@pool_problems) == 0) { + DB::Exception::PoolProblemNotInPool->throw(message => 'The problem with id ' + . $pool_problem_info->{pool_problem_id} + . ' is not in the pool named \'' + . $problem_pool->pool_name + . "'"); + return; } else { # Pick a random problem. my $prob = $pool_problems[ rand @pool_problems ]; @@ -374,12 +435,8 @@ remove a Problem out of a ProblemPool in a course =cut sub removePoolProblem ($self, %args) { - my $prob = $self->getPoolProblem(info => $args{info}, as_result_set => 1); - DB::Exception::PoolProblemNotInPool->throw(info => $args{info}) unless defined($prob); - - my $prob2 = $prob->delete; - return $prob2 if $args{as_result_set}; - return { $prob2->get_inflated_columns }; + $self->getPoolProblem(info => $args{info}, as_result_set => 1)->delete; + return; } # just a small subroutine to shorten access to the db. diff --git a/lib/DB/Schema/ResultSet/ProblemSet.pm b/lib/DB/Schema/ResultSet/ProblemSet.pm index c41e6fcc..c5254cd0 100644 --- a/lib/DB/Schema/ResultSet/ProblemSet.pm +++ b/lib/DB/Schema/ResultSet/ProblemSet.pm @@ -509,19 +509,13 @@ if false, a hashrefs of ProblemSet. =head3 output -An hashref of the deleted problem set or an object of type C +Nothing (undef) is returned. =cut sub deleteProblemSet ($self, %args) { - - my $set_to_delete = $self->getProblemSet(info => $args{info}, as_result_set => 1); - $set_to_delete->delete; - - return $set_to_delete if $args{as_result_set}; - my $set = { $set_to_delete->get_inflated_columns, set_type => $set_to_delete->set_type }; - delete $set->{type}; - return $set; + $self->getProblemSet(info => $args{info}, as_result_set => 1)->delete; + return; } # The following are private methods used in this module. diff --git a/lib/DB/Schema/ResultSet/SetProblem.pm b/lib/DB/Schema/ResultSet/SetProblem.pm index ea098b4f..52cd1d5e 100644 --- a/lib/DB/Schema/ResultSet/SetProblem.pm +++ b/lib/DB/Schema/ResultSet/SetProblem.pm @@ -157,7 +157,7 @@ if either the course or set doesn't exist, an exception will be thrown. =head3 output -An array of Problems (as hashrefs) or an array of C +A problem (as a hashref) or an array of C =cut @@ -350,26 +350,13 @@ if either the course or set doesn't exist, an exception will be thrown. =head3 output -A problem (as hashrefs) or an object of class C +Nothing (undef) is returned. =cut sub deleteSetProblem ($self, %args) { - my $set_problem = $self->getSetProblem(info => $args{info}, as_result_set => 1); - my $problem_set = $self->rs('ProblemSet')->getProblemSet( - info => { - course_id => $set_problem->problem_set->course_id, - set_id => $set_problem->set_id - }, - as_result_set => 1 - ); - - my $problem = $problem_set->search_related('problems', getProblemInfo($args{info}))->single; - - my $deleted_problem = $problem->delete; - - return $deleted_problem if $args{as_result_set}; - return { $deleted_problem->get_inflated_columns }; + $self->getSetProblem(info => $args{info}, as_result_set => 1)->delete; + return; } # just a small subroutine to shorten access to the db. diff --git a/lib/DB/Schema/ResultSet/User.pm b/lib/DB/Schema/ResultSet/User.pm index 9e3b8bab..60325a73 100644 --- a/lib/DB/Schema/ResultSet/User.pm +++ b/lib/DB/Schema/ResultSet/User.pm @@ -149,11 +149,8 @@ The deleted user as a C object. # TODO: Delete everything related to the user from all tables. sub deleteGlobalUser ($self, %args) { - my $user_to_delete = $self->getGlobalUser(info => $args{info}, as_result_set => 1); - - my $deleted_user = $user_to_delete->delete; - return $deleted_user if $args{as_result_set}; - return removeLoginParams({ $deleted_user->get_inflated_columns }); + $self->getGlobalUser(info => $args{info}, as_result_set => 1)->delete; + return; } =head1 updateGlobalUser @@ -533,21 +530,18 @@ from the global user table) =over =item - If either information about the user or the course is missing, an exception will be thrown -=item - If the user is already in the course, an exception will be thrown. +=item - If the user is not in the course, an exception will be thrown. =back =head3 output -An hashref of the deleted user or merged user or a C +Nothing (undef) is returned. =cut sub deleteCourseUser ($self, %args) { - my $course_user_to_delete = $self->getCourseUser(info => $args{info}, as_result_set => 1)->delete; - - return $course_user_to_delete if $args{as_result_set}; - return $args{merged} ? _getMergedUser($course_user_to_delete) : _getCourseUser($course_user_to_delete); - + $self->getCourseUser(info => $args{info}, as_result_set => 1)->delete; + return; } # This is a small subroutine to shorten access to the db. diff --git a/lib/DB/Schema/ResultSet/UserProblem.pm b/lib/DB/Schema/ResultSet/UserProblem.pm index 1c1fc071..c61b7247 100644 --- a/lib/DB/Schema/ResultSet/UserProblem.pm +++ b/lib/DB/Schema/ResultSet/UserProblem.pm @@ -490,27 +490,8 @@ or a C =cut sub deleteUserProblem ($self, %args) { - my $user_problem = - $args{info}->{user_problem_id} - ? $self->find({ user_problem_id => $args{info}->{user_problem_id} }) - : $self->getUserProblem( - info => $args{info}, - skip_throw => 1, - as_result_set => 1 - ); - - DB::Exception::UserProblemNotFound->throw(message => 'The user ' - . getUserInfo($args{info})->{username} // getUserInfo($args{info})->{user_id} - . ' already has problem number ' - . getProblemInfo($args{info})->{problem_number} - // ("(set_problem_id): " . getProblemInfo($args{info})->{set_problem_id}) - . ' in set with name' - . getSetInfo($args{info})->{set_name} // ("(set_id): " . getSetInfo($args{info})->{set_id})) - unless $user_problem; - - my $user_problem_to_delete = $user_problem->delete; - return $user_problem_to_delete if $args{as_result_set}; - return $args{merged} ? _mergeUserProblem($user_problem_to_delete) : _getUserProblem($user_problem_to_delete); + $self->getUserProblem(info => $args{info}, as_result_set => 1)->delete; + return; } =head2 getUserProblemVersions diff --git a/lib/DB/Schema/ResultSet/UserSet.pm b/lib/DB/Schema/ResultSet/UserSet.pm index 344f0b3b..9a47b5f6 100644 --- a/lib/DB/Schema/ResultSet/UserSet.pm +++ b/lib/DB/Schema/ResultSet/UserSet.pm @@ -408,18 +408,8 @@ delete a single UserSet for a given course, user, and ProblemSet =cut sub deleteUserSet ($self, %args) { - my $user_set = $self->getUserSet(info => $args{info}, as_result_set => 1); - - DB::Exception::UserSetNotInCourse->throw( - set_name => $args{info}->{set_name}, - course_name => $args{info}->{course_name}, - username => $args{info}->{username} - ) unless defined($user_set); - - $user_set->delete; - # why are we returning anything from this call? success/failure instead? - return $user_set if $args{as_result_set}; - return $args{merged} ? _mergeUserSet($user_set) : _getUserSet($user_set); + my $user_set = $self->getUserSet(info => $args{info}, as_result_set => 1)->delete; + return; } =head2 getUserSetVersions diff --git a/lib/WeBWorK3.pm b/lib/WeBWorK3.pm index cb8163a0..51e49750 100644 --- a/lib/WeBWorK3.pm +++ b/lib/WeBWorK3.pm @@ -172,6 +172,7 @@ sub problemSetRoutes ($app, $course_routes) { # CRUD for User Sets $course_routes->get('/user-sets')->to('ProblemSet#getAllUserSets'); $course_routes->get('/sets/:set_id/users')->to('ProblemSet#getUserSets'); + $course_routes->get('/sets/:set_id/users/:course_user_id')->to('ProblemSet#getUserSet'); $course_routes->post('/sets/:set_id/users')->to('ProblemSet#addUserSet'); $course_routes->put('/sets/:set_id/users/:course_user_id')->to('ProblemSet#updateUserSet'); $course_routes->delete('/sets/:set_id/users/:course_user_id')->to('ProblemSet#deleteUserSet'); diff --git a/lib/WeBWorK3/Controller/Course.pm b/lib/WeBWorK3/Controller/Course.pm index 928441eb..96b16417 100644 --- a/lib/WeBWorK3/Controller/Course.pm +++ b/lib/WeBWorK3/Controller/Course.pm @@ -32,9 +32,8 @@ sub addCourse ($c) { } sub deleteCourse ($c) { - my $course = - $c->schema->resultset('Course')->deleteCourse(info => { course_id => int($c->param('course_id')) }); - $c->render(json => $course); + $c->schema->resultset('Course')->deleteCourse(info => { course_id => int($c->param('course_id')) }); + $c->render(json => { message => 'The course was successfully deleted.' }); return; } diff --git a/lib/WeBWorK3/Controller/Problem.pm b/lib/WeBWorK3/Controller/Problem.pm index a25d14d5..8fd83d26 100644 --- a/lib/WeBWorK3/Controller/Problem.pm +++ b/lib/WeBWorK3/Controller/Problem.pm @@ -55,14 +55,14 @@ sub updateProblem ($c) { } sub deleteProblem ($c) { - my $deleted_problem = $c->schema->resultset('SetProblem')->deleteSetProblem( + $c->schema->resultset('SetProblem')->deleteSetProblem( info => { course_id => int($c->param('course_id')), set_id => int($c->param('set_id')), set_problem_id => int($c->param('set_problem_id')) } ); - $c->render(json => $deleted_problem); + $c->render(json => { message => 'The problem was successfully deleted.' }); return; } @@ -142,7 +142,7 @@ sub updateUserProblem ($c) { } sub deleteUserProblem ($c) { - my $deleted_problem = $c->schema->resultset('UserProblem')->deleteUserProblem( + $c->schema->resultset('UserProblem')->deleteUserProblem( info => { course_id => int($c->param('course_id')), set_id => int($c->param('set_id')), @@ -150,7 +150,7 @@ sub deleteUserProblem ($c) { user_problem_id => int($c->param('user_problem_id')) } ); - $c->render(json => $deleted_problem); + $c->render(json => { message => 'The user problem was successfully deleted.' }); return; } @@ -204,14 +204,14 @@ sub updateProblemPool ($c) { } sub deleteProblemPool ($c) { - my $problem_pool = $c->schema->resultset('ProblemPool')->deleteProblemPool( + $c->schema->resultset('ProblemPool')->deleteProblemPool( info => { course_id => int($c->param('course_id')), problem_pool_id => int($c->param('problem_pool_id')), }, params => $c->req->json ); - $c->render(json => $problem_pool); + $c->render(json => { message => 'The problem pool was successfully deleted.' }); return; } @@ -261,14 +261,13 @@ sub updatePoolProblem ($c) { } sub removePoolProblem ($c) { - my $problem_pool = $c->schema->resultset('ProblemPool')->removePoolProblem( + $c->schema->resultset('ProblemPool')->removePoolProblem( info => { course_id => int($c->param('course_id')), problem_pool_id => int($c->param('problem_pool_id')), - }, - params => $c->req->json + } ); - $c->render(json => $problem_pool); + $c->render(json => { message => 'The pool problem was successfully removed.' }); return; } diff --git a/lib/WeBWorK3/Controller/ProblemSet.pm b/lib/WeBWorK3/Controller/ProblemSet.pm index 739662c5..2f0a5d68 100644 --- a/lib/WeBWorK3/Controller/ProblemSet.pm +++ b/lib/WeBWorK3/Controller/ProblemSet.pm @@ -62,13 +62,13 @@ sub addProblemSet ($self) { } sub deleteProblemSet ($self) { - my $problem_set = $self->schema->resultset('ProblemSet')->deleteProblemSet( + $self->schema->resultset('ProblemSet')->deleteProblemSet( info => { course_id => int($self->param('course_id')), set_id => int($self->param('set_id')) } ); - $self->render(json => $problem_set); + $self->render(json => { message => 'The problem set was successfully deleted.' }); return; } @@ -106,6 +106,18 @@ sub getUserSets ($self) { return; } +sub getUserSet ($self) { + my $user_set = $self->schema->resultset('UserSet')->getUserSet( + info => { + course_id => int($self->param('course_id')), + set_id => int($self->param('set_id')), + course_user_id => int($self->param('course_user_id')) + } + ); + $self->render(json => $user_set); + return; +} + sub addUserSet ($self) { my $new_user_set = $self->schema->resultset('UserSet')->addUserSet( params => { @@ -132,15 +144,14 @@ sub updateUserSet ($self) { } sub deleteUserSet ($self) { - my $updated_user_set = $self->schema->resultset('UserSet')->deleteUserSet( + $self->schema->resultset('UserSet')->deleteUserSet( info => { course_id => int($self->param('course_id')), set_id => int($self->param('set_id')), course_user_id => int($self->param('course_user_id')) - }, - params => $self->req->json + } ); - $self->render(json => $updated_user_set); + $self->render(json => { message => 'The user set was successfully deleted.' }); return; } diff --git a/lib/WeBWorK3/Controller/User.pm b/lib/WeBWorK3/Controller/User.pm index 083fb084..94a32ac5 100644 --- a/lib/WeBWorK3/Controller/User.pm +++ b/lib/WeBWorK3/Controller/User.pm @@ -48,7 +48,7 @@ sub addGlobalUser ($c) { sub deleteGlobalUser ($c) { my $user = $c->schema->resultset('User')->deleteGlobalUser(info => { user_id => int($c->param('user_id')) }); - $c->render(json => $user); + $c->render(json => { message => 'The global user was successfully deleted.' }); return; } @@ -132,7 +132,7 @@ sub deleteCourseUser ($c) { user_id => int($c->param('user_id')) } ); - $c->render(json => $course_user); + $c->render(json => { message => 'The course user was successfully deleted.' }); return; } diff --git a/src/stores/courses.ts b/src/stores/courses.ts index 17dd09be..11e63684 100644 --- a/src/stores/courses.ts +++ b/src/stores/courses.ts @@ -77,15 +77,15 @@ export const useCourseStore = defineStore('courses', { /** * This deletes the course in the database and the store. */ - async deleteCourse(course: Course): Promise { - const response = await api.delete(`courses/${course.course_id}`); - if (response.status === 200) { - const deleted_course = new Course(response.data as ParseableCourse); - const index = this.courses.findIndex(course => course.course_id === deleted_course.course_id); - this.courses.splice(index, 1); - return deleted_course; - } else { - throw response.data as ResponseError; + async deleteCourse(course: Course): Promise { + const index = this.courses.findIndex(c => c.course_id === course.course_id); + if (index >= 0) { + const response = await api.delete(`courses/${course.course_id}`); + if (response.status === 200) { + this.courses.splice(index, 1); + } else { + throw response.data as ResponseError; + } } } } diff --git a/src/stores/problem_sets.ts b/src/stores/problem_sets.ts index b1c45567..cb3eecce 100644 --- a/src/stores/problem_sets.ts +++ b/src/stores/problem_sets.ts @@ -180,15 +180,20 @@ export const useProblemSetStore = defineStore('problem_sets', { /** * Delete the given ProblemSet from the database and the store. */ - async deleteProblemSet(set: ProblemSet) { - const response = await api.delete(`courses/${set.course_id}/sets/${set.set_id}`); - const set_to_delete = parseProblemSet(response.data as ParseableProblemSet); - const index = this.problem_sets.findIndex(set => set.set_id === set_to_delete.set_id); + async deleteProblemSet(set: ProblemSet): Promise { + const index = this.problem_sets.findIndex((s) => s.set_id === set.set_id); if (index >= 0) { - this.problem_sets.splice(index, 1); + const response = await api.delete(`courses/${set.course_id}/sets/${set.set_id}`); + if (response.status === 200) { + this.problem_sets.splice(index, 1); + + } else { + // splice is used so vue3 reacts to changes. + logger.error(JSON.stringify(response)); + } + } else { + logger.error('[problem_set store/deleteProblemSet]: the problem set was not found in the store'); } - // TODO: what if this fails - return set_to_delete; }, // UserSet actions @@ -268,16 +273,21 @@ export const useProblemSetStore = defineStore('problem_sets', { /** * Deletes the given UserSet from the store and the database. */ - async deleteUserSet(user_set: UserSet) { + async deleteUserSet(user_set: UserSet): Promise { const course_id = useSessionStore().course.course_id; - const response = await - api.delete(`courses/${course_id}/sets/${user_set.set_id}/users/${user_set.course_user_id ?? 0}`); - // TODO: check for errors - const deleted_user_set = parseDBUserSet(response.data as ParseableDBUserSet); - const index = this.db_user_sets.findIndex(s => s.user_set_id === deleted_user_set.user_set_id); - this.db_user_sets.splice(index, 1); - user_set.set(deleted_user_set.toObject()); - return user_set; + const index = this.db_user_sets.findIndex((set) => set.user_set_id === user_set.user_set_id); + if (index >= 0) { + const response = await + api.delete(`courses/${course_id}/sets/${user_set.set_id}/users/${user_set.course_user_id ?? 0}`); + if (response.status === 200) { + // splice is used so vue3 reacts to changes. + this.db_user_sets.splice(index, 1); + } else { + logger.error(JSON.stringify(response)); + } + } else { + logger.error('[user store/deleteUserSet]: the user set was not found in the store'); + } }, /** diff --git a/src/stores/set_problems.ts b/src/stores/set_problems.ts index b4ef07ec..04b2b734 100644 --- a/src/stores/set_problems.ts +++ b/src/stores/set_problems.ts @@ -166,16 +166,21 @@ export const useSetProblemStore = defineStore('set_problems', { /** * Delete the given SetProblem in both the store and the database. */ - async deleteSetProblem(problem: SetProblem): Promise { + async deleteSetProblem(problem: SetProblem): Promise { const course_id = useSessionStore().course.course_id; - - const response = await api.delete(`courses/${course_id}/sets/${ - problem.set_id}/problems/${problem.set_problem_id}`); - const deleted_problem = new SetProblem(response.data as ParseableSetProblem); - // TODO: check for errors - const index = this.set_problems.findIndex(prob => prob.set_problem_id === deleted_problem.set_problem_id); - this.set_problems.splice(index, 1); - return deleted_problem; + const index = this.set_problems.findIndex(prob => prob.set_problem_id === problem.set_problem_id); + if (index >= 0) { + const response = await api.delete(`courses/${course_id}/sets/${problem.set_id + }/problems/${problem.set_problem_id}`); + if (response.status === 200) { + // splice is used so vue3 reacts to changes. + this.set_problems.splice(index, 1); + } else { + logger.error(JSON.stringify(response)); + } + } else { + logger.error('[stores/set_problems/deleteSetProblem]: the set problem was not found in the store'); + } }, // UserProblem actions @@ -250,26 +255,27 @@ export const useSetProblemStore = defineStore('set_problems', { /** * Delete the given UserProblem from the database and the store. */ - async deleteUserProblem(user_problem: UserProblem): Promise { + async deleteUserProblem(user_problem: UserProblem): Promise { const course_id = useSessionStore().course.course_id; const set_problem = this.set_problems.find(prob => prob.set_problem_id === user_problem.set_problem_id); const problem_set_store = useProblemSetStore(); - const user_set = problem_set_store.findUserSet({ user_set_id: user_problem.user_set_id, }); - if (user_set == undefined) { - throw 'deleteUserProblem: returned undefined user set'; - } - const response = await api.delete(`courses/${course_id}/sets/${set_problem?.set_id ?? 0 - }/users/${user_set.user_id}/problems/${user_problem.user_problem_id}`); - const db_deleted_problem = new DBUserProblem(response.data as ParseableDBUserProblem); const index = this.db_user_problems - .findIndex(user_problem => user_problem.user_problem_id === db_deleted_problem.user_problem_id); + .findIndex(user_problem => user_problem.user_problem_id === user_problem.user_problem_id); if (index >= 0) { - this.db_user_problems.splice(index, 1); + const user_set = problem_set_store.findUserSet({ user_set_id: user_problem.user_set_id, }); + if (user_set == undefined) throw 'deleteUserProblem: returned undefined user set'; + + const response = await api.delete(`courses/${course_id}/sets/${set_problem?.set_id ?? 0 + }/users/${user_set?.user_id}/problems/${user_problem.user_problem_id}`); + if (response.status === 200) { + // splice is used so vue3 reacts to changes. + this.set_problems.splice(index, 1); + } else { + logger.error(JSON.stringify(response)); + } + } else { + logger.error('[stores/set_problems/deleteUserProblem]: the set problem was not found in the store'); } - // Create a new UserProblem to return as - const deleted_user_problem = new UserProblem(Object.assign(db_deleted_problem.toObject(), - user_problem.toObject())); - return deleted_user_problem; } } }); diff --git a/src/stores/users.ts b/src/stores/users.ts index c84f2a3d..d80a5161 100644 --- a/src/stores/users.ts +++ b/src/stores/users.ts @@ -2,7 +2,7 @@ import { api } from 'boot/axios'; import { defineStore } from 'pinia'; import { logger } from 'boot/logger'; -import { DBCourseUser, ParseableCourseUser, ParseableDBCourseUser, ParseableUser } from 'src/common/models/users'; +import { DBCourseUser, ParseableDBCourseUser, ParseableUser } from 'src/common/models/users'; import { User, CourseUser } from 'src/common/models/users'; import { invalidError, ResponseError } from 'src/common/api-requests/errors'; import { UserRole } from 'src/stores/permissions'; @@ -155,15 +155,19 @@ export const useUserStore = defineStore('user', { /** * Deletes the given User in the database and in the store. */ - async deleteUser(user: User): Promise { - const session_store = useSessionStore(); - const course_id = session_store.course.course_id; - const response = await api.delete(`courses/${course_id}/global-users/${user.user_id ?? 0}`); - if (response.status === 200) { - const index = this.users.findIndex((u) => u.user_id === user.user_id); + async deleteUser(user: User): Promise { + const course_id = useSessionStore().course.course_id; + const index = this.users.findIndex((u) => u.user_id === user.user_id); + if (index >= 0) { + const response = await api.delete(`courses/${course_id}/global-users/${user.user_id ?? 0}`); + if (response.status === 200) { // splice is used so vue3 reacts to changes. - this.users.splice(index, 1); - return new User(response.data as ParseableUser); + this.users.splice(index, 1); + } else { + logger.error(JSON.stringify(response)); + } + } else { + logger.error('[user store/deleteUser]: the user was not found in the store'); } }, @@ -261,19 +265,18 @@ export const useUserStore = defineStore('user', { /** * Deletes a Course User from the store and the database. */ - async deleteCourseUser(course_user: CourseUser): Promise { - const response = await api.delete(`courses/${course_user.course_id}/users/${course_user.user_id}`); - if (response.status === 200) { - const index = this.db_course_users.findIndex((u) => u.course_user_id === course_user.course_user_id); - - // splice is used so vue3 reacts to changes. - this.db_course_users.splice(index, 1); - const deleted_course_user = new DBCourseUser(response.data as ParseableCourseUser); - const user = this.users.find(u => u.user_id === deleted_course_user.user_id); - return new CourseUser(Object.assign({}, user?.toObject(), deleted_course_user.toObject())); - } else if (response.status === 250) { - logger.error(response.data); - throw response.data as ResponseError; + async deleteCourseUser(course_user: CourseUser): Promise { + const index = this.db_course_users.findIndex((u) => u.course_user_id === course_user.course_user_id); + if (index >= 0) { + const response = await api.delete(`courses/${course_user.course_id}/users/${course_user.user_id}`); + if (response.status === 200) { + // splice is used so vue3 reacts to changes. + this.db_course_users.splice(index, 1); + } else { + logger.error(JSON.stringify(response)); + } + } else { + logger.error('[user store/deleteCourseUser]: the user was not found in the store'); } }, clearAll() { diff --git a/t/db/001_courses.t b/t/db/001_courses.t index 0b2b72d8..a4c31095 100644 --- a/t/db/001_courses.t +++ b/t/db/001_courses.t @@ -129,10 +129,13 @@ throws_ok { 'DB::Exception::CourseNotFound', 'updateCourse: update a non-existent course_id'; # Delete a course -my $deleted_course = $course_rs->deleteCourse(info => { course_name => 'Geometry II' }); -removeIDs($deleted_course); +$course_rs->deleteCourse(info => { course_name => 'Geometry II' }); -is_deeply($new_course_params, $deleted_course, 'deleteCourse: delete a course'); +# and check that it is no longer in the database. +throws_ok { + $course_rs->getCourse(info => { course_name => 'Geometry II' }); +} +'DB::Exception::CourseNotFound', 'deleteCourse: delete a course'; # Try to delete a non-existent course by name throws_ok { diff --git a/t/db/003_users.t b/t/db/003_users.t index ace345db..d71ee4e2 100644 --- a/t/db/003_users.t +++ b/t/db/003_users.t @@ -222,26 +222,20 @@ throws_ok { qr/No such column 'invalid_field'/, 'updateUser: pass in an invalid field'; # Delete users that were created -my $user_to_delete = $users_rs->deleteGlobalUser(info => { username => $user->{username} }); - -removeIDs($user_to_delete); -cleanUndef($user_to_delete); -is_deeply($updated_user, $user_to_delete, 'deleteUser: delete a user'); - -my $deleted_selma = $users_rs->deleteGlobalUser(info => { username => 'selma' }); -removeIDs($deleted_selma); -cleanUndef($deleted_selma); -is_deeply($deleted_selma, $selma_params, 'deleteUser: deleter another user'); - -my $deleted_patty = $users_rs->deleteGlobalUser(info => { username => 'patty' }); -removeIDs($deleted_patty); -cleanUndef($deleted_patty); -is_deeply($deleted_patty, $patty_params, 'deleteUser: deleter a third user'); - -my $user_to_delete2 = $users_rs->deleteGlobalUser(info => { username => $added_user2->{username} }); -removeIDs($user_to_delete2); -cleanUndef($user_to_delete2); -is_deeply($added_user2, $user_to_delete2, 'deleteUser: delete yet another user.'); +$users_rs->deleteGlobalUser(info => { username => $user->{username} }); + +# and check they are no longer in the database: +throws_ok { + $users_rs->getGlobalUser(info => { username => $user->{username} }); +} +'DB::Exception::UserNotFound', 'deleteUser: delete a user'; + +# Delete others and no need to check because a full check to see that the database +# is restored is done below. + +$users_rs->deleteGlobalUser(info => { username => 'selma' }); +$users_rs->deleteGlobalUser(info => { username => 'patty' }); +$users_rs->deleteGlobalUser(info => { username => $added_user2->{username} }); # Delete a user that doesn't exist. throws_ok { diff --git a/t/db/004_course_users.t b/t/db/004_course_users.t index b79c4aa9..e7fd3ebb 100644 --- a/t/db/004_course_users.t +++ b/t/db/004_course_users.t @@ -328,41 +328,39 @@ throws_ok { } 'DB::Exception::InvalidParameter', 'updateCourseUser: an parameter with invalid value'; -# Delete a single user from a course. -my $deleted_user; -my $dont_delete_users; # Switch to not delete added users. +# Delete a course user +$user_rs->deleteCourseUser(info => { course_name => 'Arithmetic', username => 'quimby' }); -SKIP: { - skip 'delete added users', 5 if $dont_delete_users; - - my $deleted_course_user = $user_rs->deleteCourseUser(info => { course_name => 'Arithmetic', username => 'quimby' }); - removeIDs($deleted_course_user); - - is_deeply($course_user_params, $deleted_course_user, 'deleteCourseUser: delete a user from a course'); +# and check to ensure quimby was deleted. +throws_ok { + $user_rs->getCourseUser(info => { course_name => 'Arithmetic', username => 'quimby' }); +} +'DB::Exception::UserNotInCourse', 'deleteCourseUser: delete a user from a course'; - $deleted_user = $user_rs->deleteGlobalUser(info => { username => 'quimby' }); - removeIDs($deleted_user); +$user_rs->deleteGlobalUser(info => { username => 'quimby' }); - is_deeply($user_params, $deleted_user, 'deleteGlobalUser: delete a user'); +throws_ok { + $user_rs->getGlobalUser(info => { username => 'quimby' }); +} +'DB::Exception::UserNotFound', 'deleteGlobalUser: delete a user'; - # deleteUser: Check that if the course doesn't exist, an error is thrown: - throws_ok { - $user_rs->deleteCourseUser(info => { course_name => 'unknown_course', username => 'barney' }); - } - 'DB::Exception::CourseNotFound', "deleteUser: the course doesn't exist"; +# deleteUser: Check that if the course doesn't exist, an error is thrown: +throws_ok { + $user_rs->deleteCourseUser(info => { course_name => 'unknown_course', username => 'barney' }); +} +'DB::Exception::CourseNotFound', "deleteUser: the course doesn't exist"; - # deleteUser: Check that if the course exists, but the user not a member. - throws_ok { - $user_rs->deleteCourseUser(info => { course_name => 'Arithmetic', username => 'marge' }); - } - 'DB::Exception::UserNotInCourse', 'deleteUser: the user is not a member of the course'; +# deleteUser: Check that if the course exists, but the user not a member. +throws_ok { + $user_rs->deleteCourseUser(info => { course_name => 'Arithmetic', username => 'marge' }); +} +'DB::Exception::UserNotInCourse', 'deleteUser: the user is not a member of the course'; - # deleteUser: Send in username_name instead of username - throws_ok { - $user_rs->deleteCourseUser(info => { course_name => 'Arithmetic', username_name => 'bart' }); - } - 'DB::Exception::ParametersNeeded', 'deleteUser: the incorrect information is passed in.'; +# deleteUser: Send in username_name instead of username +throws_ok { + $user_rs->deleteCourseUser(info => { course_name => 'Arithmetic', username_name => 'bart' }); } +'DB::Exception::ParametersNeeded', 'deleteUser: the incorrect information is passed in.'; # Check that the precalc users have not changed. @precalc_users_from_db = $user_rs->getCourseUsers(info => { course_name => 'Precalculus' }, merged => 1); diff --git a/t/db/005_hwsets.t b/t/db/005_hwsets.t index ef79c073..4690e6fb 100644 --- a/t/db/005_hwsets.t +++ b/t/db/005_hwsets.t @@ -409,9 +409,13 @@ throws_ok { 'DB::Exception::ImproperDateOrder', 'updateSet: adding an illegal date order.'; # Delete a set -my $deleted_set = $problem_set_rs->deleteProblemSet(info => { course_name => 'Precalculus', set_name => 'HW #88' }); -removeIDs($deleted_set); -is_deeply($set_with_new_type_params, $deleted_set, 'deleteProblemSet: delete a set'); +$problem_set_rs->deleteProblemSet(info => { course_name => 'Precalculus', set_name => 'HW #88' }); + +# And then check that it is no longer in the database. +throws_ok { + $problem_set_rs->getProblemSet(info => { course_name => 'Precalculus', set_name => 'HW #88' }); +} +'DB::Exception::SetNotInCourse', 'deleteProblemSet: delete a set'; # Try deleting a set with invalid course_name throws_ok { diff --git a/t/db/006_quizzes.t b/t/db/006_quizzes.t index 7ca3abc8..510ff895 100644 --- a/t/db/006_quizzes.t +++ b/t/db/006_quizzes.t @@ -412,15 +412,14 @@ throws_ok { } 'DB::Exception::SetNotInCourse', 'deleteQuiz: try to delete a non-existent quiz as set_id'; -# Try to delete from a non-existent set in a course: -my $deleted_quiz = $problem_set_rs->deleteProblemSet( - info => { - course_name => 'Precalculus', - set_name => 'Quiz #9' - } -); -removeIDs($deleted_quiz); -is_deeply($deleted_quiz, $new_quiz, 'delete Quiz: successfully delete a quiz'); +# Delete a quiz +$problem_set_rs->deleteProblemSet(info => { course_name => 'Precalculus', set_name => 'Quiz #9' }); + +# And then check that it is no longer in the database. +throws_ok { + $problem_set_rs->getProblemSet(info => { course_name => 'Precalculus', set_name => 'Quiz #9' }); +} +'DB::Exception::SetNotInCourse', 'deleteProblemSet: delete a set'; # Ensure that the quizzes in the database are restored. @precalc_quizzes_from_db = $problem_set_rs->getQuizzes(info => { course_name => 'Precalculus' }); diff --git a/t/db/007_user_set.t b/t/db/007_user_set.t index fb5abff4..776ca4bd 100644 --- a/t/db/007_user_set.t +++ b/t/db/007_user_set.t @@ -132,7 +132,7 @@ for my $user_set (@merged_user_sets) { $user_set->{set_visible} = $set->{set_visible} unless defined($user_set->{set_visible}); } -# Get all user sets for a given user in a course. +# Get all user sets my @all_user_sets_from_db = $user_set_rs->getAllUserSets(); for my $set (@all_user_sets_from_db) { @@ -790,36 +790,53 @@ throws_ok { # Delete some user sets that were created. -my $deleted_user_set = $user_set_rs->deleteUserSet( +$user_set_rs->deleteUserSet( info => { username => $new_user_set2->{username}, course_name => $new_user_set2->{course_name}, set_name => $new_user_set2->{set_name} } ); -removeIDs($deleted_user_set); -cleanUndef($deleted_user_set); -removeIDs($new_user_set2); -cleanUndef($new_user_set2); -is_deeply($deleted_user_set, $new_user_set2, "deleteUserSet: successfully delete a user set"); -my $deleted_user_set2 = $user_set_rs->deleteUserSet( +# And then check that it is no longer in the database. +throws_ok { + $user_set_rs->getUserSet( + info => { + username => $new_user_set2->{username}, + course_name => $new_user_set2->{course_name}, + set_name => $new_user_set2->{set_name} + } + ); +} +'DB::Exception::UserSetNotInCourse', 'deleteUserSet: successfully delete a user set'; + +$user_set_rs->deleteUserSet( info => { username => $ralph_user_set->{username}, course_name => $ralph_user_set->{course_name}, set_name => $ralph_user_set->{set_name} } ); -removeIDs($deleted_user_set2); -cleanUndef($deleted_user_set2); -is_deeply($deleted_user_set2, $ralph_user_set, "deleteUserSet: successfully delete another user set"); -my $deleted_user_set3 = $user_set_rs->deleteUserSet(info => $otto_quiz_info); -removeIDs($deleted_user_set3); -cleanUndef($deleted_user_set3); -is_deeply($deleted_user_set3, $otto_quiz, "deleteUserSet: successfully delete yet another user set"); +# And then check that it is no longer in the database. +throws_ok { + $user_set_rs->getUserSet( + info => { + username => $ralph_user_set->{username}, + course_name => $ralph_user_set->{course_name}, + set_name => $ralph_user_set->{set_name} + } + ); +} +'DB::Exception::UserSetNotInCourse', 'deleteUserSet: successfully delete another user set'; + +$user_set_rs->deleteUserSet(info => $otto_quiz_info); +throws_ok { + $user_set_rs->getUserSet(info => $otto_quiz_info); +} +'DB::Exception::UserSetNotInCourse', 'deleteUserSet: successfully delete yet another user set'; -my $deleted_user_set4 = $user_set_rs->deleteUserSet(info => $new_merged_set); +$user_set_rs->deleteUserSet(info => $new_merged_set); # remove the rest of the user sets added for user 'otto' diff --git a/t/db/008_problem_pools.t b/t/db/008_problem_pools.t index dc731a66..298947fa 100644 --- a/t/db/008_problem_pools.t +++ b/t/db/008_problem_pools.t @@ -295,10 +295,13 @@ throws_ok { 'DB::Exception::PoolProblemNotInPool', 'updatePoolProblem: try to update a nonexisting problem'; # Delete a problem pool -my $pool_to_delete = $problem_pool_rs->deleteProblemPool(info => $updated_pool); -removeIDs($pool_to_delete); -$pool_to_delete->{course_name} = 'Arithmetic'; -is_deeply($updated_pool, $pool_to_delete, 'deleteProblemPool: delete an existing problem pool'); +$problem_pool_rs->deleteProblemPool(info => $updated_pool); + +# And check that it was successfully removed from the database +throws_ok { + $problem_pool_rs->getProblemPool(info => $updated_pool); +} +'DB::Exception::PoolNotInCourse', 'deleteProblemPool: delete an existing problem pool'; # Ensure that the problem_pool table is restored. @problem_pools_from_db = $problem_pool_rs->getAllProblemPools(); diff --git a/t/db/009_problems.t b/t/db/009_problems.t index d001c650..3bedc381 100644 --- a/t/db/009_problems.t +++ b/t/db/009_problems.t @@ -362,35 +362,63 @@ throws_ok { 'DB::Exception::ParametersNeeded', 'updateSetProblem: try to add a problem with too much library info'; # Delete a problem from a set -my $deleted_problem = $problem_rs->deleteSetProblem( +$problem_rs->deleteSetProblem( info => { course_name => 'Precalculus', set_name => 'HW #1', problem_number => 99, } ); -removeIDs($deleted_problem); -is_deeply($updated_problem, $deleted_problem, 'deleteSetProblem: delete one problem in an existing set.'); +# And check that it is sucessfully removed from the db. +throws_ok { + $problem_rs->getSetProblem( + info => { + course_name => 'Precalculus', + set_name => 'HW #1', + problem_number => 99 + } + ); +} +'DB::Exception::SetProblemNotFound', 'deleteSetProblem: delete one problem in an existing set.'; -my $deleted_problem2 = $problem_rs->deleteSetProblem( +$problem_rs->deleteSetProblem( info => { course_name => 'Precalculus', set_name => 'HW #1', - problem_number => $set_problem_to_delete->{problem_number}, + problem_number => $prob2_from_db->{problem_number}, } ); -is_deeply($deleted_problem2, $set_problem_to_delete, 'deleteSetProblem: delete another problem.'); +# And check that it is sucessfully removed from the db. +throws_ok { + $problem_rs->getSetProblem( + info => { + course_name => 'Precalculus', + set_name => 'HW #1', + problem_number => $prob2_from_db->{problem_number}, + } + ); +} +'DB::Exception::SetProblemNotFound', 'deleteSetProblem: delete another problem.'; my $deleted_problem3 = $problem_rs->deleteSetProblem( info => { course_name => 'Precalculus', set_name => 'HW #1', - problem_number => $prob2->{problem_number} + problem_number => $set_problem_to_delete->{problem_number} } ); -removeIDs($deleted_problem3); -is_deeply($deleted_problem3, $prob2, 'deleteSetProblem: delete another problem.'); +# And check that it is sucessfully removed from the db. +throws_ok { + $problem_rs->getSetProblem( + info => { + course_name => 'Precalculus', + set_name => 'HW #1', + problem_number => $set_problem_to_delete->{problem_number}, + } + ); +} +'DB::Exception::SetProblemNotFound', 'deleteSetProblem: delete another problem.'; # Make sure the set_problem table is returned to its orginal state. @problems_from_db = $problem_rs->getGlobalProblems; diff --git a/t/db/010_user_problems.t b/t/db/010_user_problems.t index 83264eb5..6494c95b 100644 --- a/t/db/010_user_problems.t +++ b/t/db/010_user_problems.t @@ -716,25 +716,20 @@ is_deeply(\@course_user_problems_from_csv, \@user_problems, 'getCourseUserProblems: get all user problems for a single user in a course'); # Delete a User Problem +$user_problem_rs->deleteUserProblem(info => $problem_info1); -my $user_problem_to_delete = $user_problem_rs->deleteUserProblem(info => $problem_info1); -removeIDs($user_problem_to_delete); -# the status needs be returned to a numerical value. -$user_problem_to_delete->{status} += 0; - -delete $user_problem_to_delete->{problem_version} unless defined $user_problem_to_delete->{problem_version}; - -is_deeply($user_problem1, $user_problem_to_delete, 'deleteUserProblem: delete a single user problem'); - -# Delete a user problem and return as a merged problem. - -my $user_problem_to_delete2 = $user_problem_rs->deleteUserProblem(info => $problem_info2, merged => 1); -removeIDs($user_problem_to_delete2); -# the status needs be returned to a numerical value. -$user_problem_to_delete2->{status} += 0; +# And check that it was successfully removed from the db. +throws_ok { + $user_problem_rs->getUserProblem(info => $problem_info1); +} +'DB::Exception::UserProblemNotFound', 'deleteUserProblem: delete a single user problem'; -is_deeply($problem2, $user_problem_to_delete2, - 'updateUserProblem: sucessfully update a field and return as a merged problem'); +# Delete another user problem. +$user_problem_rs->deleteUserProblem(info => $problem_info2); +throws_ok { + $user_problem_rs->getUserProblem(info => $problem_info2); +} +'DB::Exception::UserProblemNotFound', 'deleteUserProblem: delete another user problem'; # Attempt to delete a UserProblem to a non-existent course. diff --git a/t/db/012_set_versions.t b/t/db/012_set_versions.t index 283238f8..688ae5fe 100644 --- a/t/db/012_set_versions.t +++ b/t/db/012_set_versions.t @@ -182,9 +182,8 @@ is_deeply( 'getUserSetVersions: get all versions of a user set.' ); -# clean up the created versioned user sets. - -my $user_set_v1_to_delete = $user_set_rs->deleteUserSet( +# Clean up the created versioned user sets. +$user_set_rs->deleteUserSet( info => { course_name => $user_set1_v1_params->{course_name}, set_name => $user_set1_v1_params->{set_name}, @@ -193,11 +192,20 @@ my $user_set_v1_to_delete = $user_set_rs->deleteUserSet( } ); -removeIDs($user_set_v1_to_delete); -cleanUndef($user_set_v1_to_delete); -is_deeply($user_set_v1_to_delete, $user_set1_v1, 'deleteUserSet: delete user set with set_version = 1'); +# Make sure that the user set successfully was deleted. +throws_ok { + $user_set_rs->getUserSet( + info => { + course_name => $user_set1_v1_params->{course_name}, + set_name => $user_set1_v1_params->{set_name}, + username => $user_set1_v1_params->{username}, + set_version => $user_set1_v1_params->{set_version} + } + ) +} +'DB::Exception::UserSetNotInCourse', 'deleteUserSet: delete user set with set_version = 1'; -my $user_set_v2_to_delete = $user_set_rs->deleteUserSet( +$user_set_rs->deleteUserSet( info => { course_name => $user_set1_v2_params->{course_name}, set_name => $user_set1_v2_params->{set_name}, @@ -206,10 +214,6 @@ my $user_set_v2_to_delete = $user_set_rs->deleteUserSet( } ); -removeIDs($user_set_v2_to_delete); -cleanUndef($user_set_v2_to_delete); -is_deeply($user_set_v2_to_delete, $user_set1_v2, 'deleteUserSet: delete a versioned user set'); - # Ensure that the user_sets table is restored. my @all_user_sets_from_db = $user_set_rs->getAllUserSets(merged => 1); diff --git a/t/db/013_problem_versions.t b/t/db/013_problem_versions.t index 79c06a5c..0d3ec531 100644 --- a/t/db/013_problem_versions.t +++ b/t/db/013_problem_versions.t @@ -137,8 +137,7 @@ is_deeply( 'getUserProblemVersions: get all versions of a user problem' ); -# clean up the created versioned user sets. - +# Clean up the created versioned user problems. my $user_problem_v2_to_delete = $user_problem_rs->deleteUserProblem( info => { course_name => $user_problem1_v2_params->{course_name}, @@ -148,12 +147,22 @@ my $user_problem_v2_to_delete = $user_problem_rs->deleteUserProblem( problem_version => $user_problem1_v2_params->{problem_version} } ); -removeIDs($user_problem_v2_to_delete); -$user_problem_v2_to_delete->{status} += 0; -is_deeply($user_problem_v2_to_delete, $user_problem1_v2, 'deleteUserProblem: delete a versioned user problem'); +# Make sure that the user problem successfully was deleted. +throws_ok { + $user_problem_rs->getUserProblem( + info => { + course_name => $user_problem1_v2_params->{course_name}, + set_name => $user_problem1_v2_params->{set_name}, + username => $user_problem1_v2_params->{username}, + problem_number => $user_problem1_v2_params->{problem_number}, + problem_version => $user_problem1_v2_params->{problem_version} + } + ) +} +'DB::Exception::UserProblemNotFound', 'deleteUserProblem: delete a versioned user problem'; -my $user_problem_v3_to_delete = $user_problem_rs->deleteUserProblem( +$user_problem_rs->deleteUserProblem( info => { course_name => $user_problem1_v3_params->{course_name}, set_name => $user_problem1_v3_params->{set_name}, @@ -162,10 +171,20 @@ my $user_problem_v3_to_delete = $user_problem_rs->deleteUserProblem( problem_version => $user_problem1_v3_params->{problem_version} } ); -removeIDs($user_problem_v3_to_delete); -$user_problem_v3_to_delete->{status} += 0; -is_deeply($user_problem_v3_to_delete, $user_problem1_v3, 'deleteUserProblem: delete another versioned user problem'); +# Make sure that the user problem successfully was deleted. +throws_ok { + $user_problem_rs->getUserProblem( + info => { + course_name => $user_problem1_v3_params->{course_name}, + set_name => $user_problem1_v3_params->{set_name}, + username => $user_problem1_v3_params->{username}, + problem_number => $user_problem1_v3_params->{problem_number}, + problem_version => $user_problem1_v3_params->{problem_version} + } + ) +} +'DB::Exception::UserProblemNotFound', 'deleteUserProblem: delete another versioned user problem'; # Ensure that the user_problems table is restored. my @all_user_problems_from_db = $user_problem_rs->getAllUserProblems(); diff --git a/t/mojolicious/002_courses.t b/t/mojolicious/002_courses.t index bf84f35a..12d3b2a7 100644 --- a/t/mojolicious/002_courses.t +++ b/t/mojolicious/002_courses.t @@ -101,7 +101,11 @@ $t->delete_ok('/webwork3/api/courses/9999999')->status_is(500, 'error status') # Delete the added course. $t->delete_ok("/webwork3/api/courses/$new_course_id")->status_is(200) - ->json_is('/course_name' => $new_course->{course_name}); + ->json_is('/message' => 'The course was successfully deleted.'); + +# Check that it is deleted. +$t->get_ok("/webwork3/api/courses/$new_course_id")->status_is(500) + ->json_is('/exception' => 'DB::Exception::CourseNotFound'); # Logout of the admin user account and relogin as a non-admin: diff --git a/t/mojolicious/003_users.t b/t/mojolicious/003_users.t index 1e2ded44..18604ca7 100644 --- a/t/mojolicious/003_users.t +++ b/t/mojolicious/003_users.t @@ -147,13 +147,18 @@ $t->post_ok( my $another_new_user_id = $t->tx->res->json('/user_id'); -# For cleanup, delete the created users. Need to relogin as an admin: - +# For cleanup, delete the created users. $t->delete_ok("/webwork3/api/users/$new_user_from_db->{user_id}")->status_is(200) - ->json_is('/username' => $new_user->{username}); + ->content_type_is('application/json;charset=UTF-8') + ->json_is('/message' => 'The global user was successfully deleted.'); + +# And check that the user is no longer in the db. +$t->get_ok("/webwork3/api/users/$new_user_from_db->{user_id}")->status_is(500) + ->json_is('/exception' => 'DB::Exception::UserNotFound'); -$t->delete_ok("/webwork3/api/users/$another_new_user_id")->status_is(200) - ->json_is('/username' => $another_user->{username}); +$t->delete_ok("/webwork3/api/users/$another_new_user_id")->status_is(200); +$t->get_ok("/webwork3/api/users/$another_new_user_id")->status_is(500) + ->json_is('/exception' => 'DB::Exception::UserNotFound'); # Test that a non-admin user cannot access all of the routes # Logout the admin user and relogin as a non-admin. @@ -210,6 +215,7 @@ $t->put_ok("/webwork3/api/courses/4/global-users/$new_global_user_id" => json => ->json_is('/student_id' => 4321); $t->delete_ok("/webwork3/api/courses/4/global-users/$new_global_user_id")->status_is(200) - ->content_type_is('application/json;charset=UTF-8'); + ->content_type_is('application/json;charset=UTF-8') + ->json_is('/message' => 'The global user was successfully deleted.'); done_testing; diff --git a/t/mojolicious/004_course_users.t b/t/mojolicious/004_course_users.t index 49f44f17..743fc327 100644 --- a/t/mojolicious/004_course_users.t +++ b/t/mojolicious/004_course_users.t @@ -131,7 +131,12 @@ $t->delete_ok("/webwork3/api/courses/4/users/5")->status_is(500, 'status for exc # Delete the added course user $t->delete_ok("/webwork3/api/courses/4/users/$new_user_id")->status_is(200) - ->content_type_is('application/json;charset=UTF-8')->json_is('/user_id' => $new_user_id); + ->content_type_is('application/json;charset=UTF-8') + ->json_is('/message' => 'The course user was successfully deleted.'); + +# And make sure that the course user is no longer in the database; +$t->get_ok("/webwork3/api/courses/4/users/$new_user_id")->status_is(500) + ->json_is('/exception' => 'DB::Exception::UserNotInCourse'); # Check that a student doesn't have the same access as an instructor # The user lisa is a student in the 'Topology' course (course_id => 3) @@ -160,6 +165,10 @@ $t->post_ok('/webwork3/api/logout')->status_is(200); $t->post_ok('/webwork3/api/login' => json => { username => 'admin', password => 'admin' })->status_is(200); # Delete the added users. -$t->delete_ok("/webwork3/api/users/$new_user_id")->status_is(200)->json_is('/username' => $new_user->{username}); +$t->delete_ok("/webwork3/api/users/$new_user_id")->status_is(200) + ->json_is('/message' => 'The global user was successfully deleted.'); + +# And check that the user is no longer in the db. +$t->get_ok("/webwork3/api/users/$new_user_id")->status_is(500)->json_is('/exception' => 'DB::Exception::UserNotFound'); done_testing; diff --git a/t/mojolicious/005_problem_sets.t b/t/mojolicious/005_problem_sets.t index ecb16982..d9a5ef12 100644 --- a/t/mojolicious/005_problem_sets.t +++ b/t/mojolicious/005_problem_sets.t @@ -147,9 +147,13 @@ my $another_new_set = { name => 'this is the wrong field' }; $t->post_ok('/webwork3/api/courses/4/sets' => json => $another_new_set) ->content_type_is('application/json;charset=UTF-8')->json_is('/exception' => 'DB::Exception::ParametersNeeded'); -# Some cleanup to restore the databse +# Some cleanup to restore the database # Delete an existing set. $t->delete_ok("/webwork3/api/courses/4/sets/$new_set_id")->content_type_is('application/json;charset=UTF-8') - ->json_is('/set_name' => 'HW #11'); + ->status_is(200)->json_is('/message' => 'The problem set was successfully deleted.'); + +# And check that the problem set is no longer in the db. +$t->get_ok("/webwork3/api/courses/4/sets/$new_set_id")->status_is(500) + ->json_is('/exception' => 'DB::Exception::SetNotInCourse'); done_testing; diff --git a/t/mojolicious/006_quizzes.t b/t/mojolicious/006_quizzes.t index be15d571..11527729 100644 --- a/t/mojolicious/006_quizzes.t +++ b/t/mojolicious/006_quizzes.t @@ -129,8 +129,12 @@ ok(JSON::PP::is_bool($problem_randorder), 'testing that p ok(JSON::PP::is_bool($problem_randorder) && !$problem_randorder, 'testing that problem_randorder is a false'); # delete the added quiz -$t->delete_ok("/webwork3/api/courses/4/sets/$returned_quiz->{set_id}") - ->content_type_is('application/json;charset=UTF-8')->json_is('/set_name' => 'Quiz #20') - ->json_is('/set_type' => 'QUIZ'); +$t->delete_ok("/webwork3/api/courses/4/sets/$returned_quiz->{set_id}")->status_is(200) + ->content_type_is('application/json;charset=UTF-8') + ->json_is('/message' => 'The problem set was successfully deleted.'); + +# And check that the quiz is no longer in the db. +$t->get_ok("/webwork3/api/courses/4/sets/$returned_quiz->{set_id}")->status_is(500) + ->json_is('/exception' => 'DB::Exception::SetNotInCourse'); done_testing(); diff --git a/t/mojolicious/007_review_sets.t b/t/mojolicious/007_review_sets.t index 3f1839f4..977ca99c 100644 --- a/t/mojolicious/007_review_sets.t +++ b/t/mojolicious/007_review_sets.t @@ -124,7 +124,12 @@ ok(JSON::PP::is_bool($can_retake), 'testing that can_retake is a Mojo::JSON::tru ok(JSON::PP::is_bool($can_retake) && !$can_retake, 'testing that can_retake is a Mojo::JSON::false'); # delete the added review set -$t->delete_ok("/webwork3/api/courses/4/sets/$review_set1->{set_id}")->content_type_is('application/json;charset=UTF-8') - ->json_is('/set_type' => 'REVIEW')->json_is('/set_name' => 'Review #20'); +$t->delete_ok("/webwork3/api/courses/4/sets/$review_set1->{set_id}")->status_is(200) + ->content_type_is('application/json;charset=UTF-8') + ->json_is('/message' => 'The problem set was successfully deleted.'); + +# And check that the review set is no longer in the db. +$t->get_ok("/webwork3/api/courses/4/sets/$review_set1->{set_id}")->status_is(500) + ->json_is('/exception' => 'DB::Exception::SetNotInCourse'); done_testing(); diff --git a/t/mojolicious/008_problems.t b/t/mojolicious/008_problems.t index 72fbb83c..469f9c42 100644 --- a/t/mojolicious/008_problems.t +++ b/t/mojolicious/008_problems.t @@ -152,6 +152,7 @@ $t->put_ok( } )->status_is(403)->content_type_is('application/json;charset=UTF-8'); +# Try to delete the created problem. $t->delete_ok("/webwork3/api/courses/4/sets/$hw1->{set_id}/problems/$new_problem->{set_problem_id}")->status_is(403) ->content_type_is('application/json;charset=UTF-8'); @@ -178,6 +179,10 @@ $t->post_ok('/webwork3/api/logout')->status_is(200)->json_is('/logged_in' => 0); $t->post_ok('/webwork3/api/login' => json => { username => 'admin', password => 'admin' })->status_is(200); $t->delete_ok("/webwork3/api/courses/4/sets/$hw1->{set_id}/problems/$new_problem->{set_problem_id}")->status_is(200) - ->content_type_is('application/json;charset=UTF-8'); + ->content_type_is('application/json;charset=UTF-8')->json_is('/message' => 'The problem was successfully deleted.'); + +# And check that the problem is no longer in the db. +$t->get_ok("/webwork3/api/courses/4/sets/$hw1->{set_id}/problems/$new_problem->{set_problem_id}")->status_is(500) + ->json_is('/exception' => 'DB::Exception::SetProblemNotFound'); done_testing; diff --git a/t/mojolicious/009_user_problems.t b/t/mojolicious/009_user_problems.t index 7066715a..61600417 100644 --- a/t/mojolicious/009_user_problems.t +++ b/t/mojolicious/009_user_problems.t @@ -236,13 +236,24 @@ $t->put_ok( $t->post_ok('/webwork3/api/logout')->status_is(200)->json_is('/logged_in' => 0); $t->post_ok('/webwork3/api/login' => json => { username => 'lisa', password => 'lisa' })->status_is(200); +# Delete the user problem $t->delete_ok( "/webwork3/api/courses/4/sets/$hw1->{set_id}/users/$ralph->{user_id}/problems/$new_user_problem->{user_problem_id}") - ->status_is(200)->content_type_is('application/json;charset=UTF-8'); + ->status_is(200)->content_type_is('application/json;charset=UTF-8') + ->json_is('/message' => 'The user problem was successfully deleted.'); + +# And check that the user problem is no longer in the db. +$t->get_ok( + "/webwork3/api/courses/4/sets/$hw1->{set_id}/users/$ralph->{user_id}/problems/$new_user_problem->{user_problem_id}") + ->status_is(500)->json_is('/exception' => 'DB::Exception::UserProblemNotFound'); # Delete the added problem $t->delete_ok("/webwork3/api/courses/4/sets/$hw1->{set_id}/problems/$new_problem->{set_problem_id}")->status_is(200) - ->content_type_is('application/json;charset=UTF-8'); + ->content_type_is('application/json;charset=UTF-8')->json_is('/message' => 'The problem was successfully deleted.'); + +# And check that the problem is no longer in the db. +$t->get_ok("/webwork3/api/courses/4/sets/$hw1->{set_id}/problems/$new_problem->{set_problem_id}")->status_is(500) + ->json_is('/exception' => 'DB::Exception::SetProblemNotFound'); done_testing; diff --git a/t/mojolicious/010_problem_pools.t b/t/mojolicious/010_problem_pools.t index 83e3e992..04d3ea24 100644 --- a/t/mojolicious/010_problem_pools.t +++ b/t/mojolicious/010_problem_pools.t @@ -192,15 +192,23 @@ $t->delete_ok( $t->post_ok('/webwork3/api/logout')->status_is(200)->json_is('/logged_in' => 0); $t->post_ok('/webwork3/api/login' => json => { username => 'lisa', password => 'lisa' })->status_is(200); -# Delete the pool problem. - +# Remove the pool problem. $t->delete_ok( "/webwork3/api/courses/4/pools/$added_problem_pool->{problem_pool_id}/problems/$new_pool_problem->{pool_problem_id}" -)->status_is(200)->content_type_is('application/json;charset=UTF-8')->json_is('/params/library_id' => 8932); +)->status_is(200)->content_type_is('application/json;charset=UTF-8') + ->json_is('/message' => 'The pool problem was successfully removed.'); -# Delete the problem pool +# And check that the pool problem is no longer in the db. +$t->get_ok( + "/webwork3/api/courses/4/pools/$added_problem_pool->{problem_pool_id}/problems/$new_pool_problem->{pool_problem_id}" +)->status_is(500)->json_is('/exception' => 'DB::Exception::PoolProblemNotInPool'); +# Delete the problem pool $t->delete_ok("/webwork3/api/courses/4/pools/$added_problem_pool->{problem_pool_id}")->status_is(200) - ->content_type_is('application/json;charset=UTF-8')->json_is('/pool_name' => 'adding decimals'); + ->content_type_is('application/json;charset=UTF-8'); + +# And check that the problem pool is no longer in the db. +$t->get_ok("/webwork3/api/courses/4/pools/$added_problem_pool->{problem_pool_id}")->status_is(500) + ->json_is('/exception' => 'DB::Exception::PoolNotInCourse'); done_testing(); diff --git a/tests/stores/courses.spec.ts b/tests/stores/courses.spec.ts index 13b38dd6..fbd86408 100644 --- a/tests/stores/courses.spec.ts +++ b/tests/stores/courses.spec.ts @@ -16,6 +16,7 @@ import { api } from 'boot/axios'; import { useCourseStore } from 'src/stores/courses'; import { Course } from 'src/common/models/courses'; import { cleanIDs, loadCSV } from '../utils'; +import { AxiosError } from 'axios'; describe('Test the course store', () => { @@ -78,8 +79,18 @@ describe('Test the course store', () => { test('Delete a course', async () => { const course_store = useCourseStore(); - const deleted_course = await course_store.deleteCourse(added_course) ?? new Course(); - expect(cleanIDs(deleted_course)).toStrictEqual(cleanIDs(updated_course)); + await course_store.deleteCourse(added_course); + + // Check that the course is no longer in the database by getting an exception. + await api.get(`/courses/${added_course.course_id}`) + .then(() => { + fail('Expected failure response'); + }) + .catch((e: AxiosError) => { + expect(e.response?.status).toBe(500); + expect((e.response?.data as {exception: string}).exception) + .toBe('DB::Exception::CourseNotFound'); + }); }); }); @@ -92,8 +103,9 @@ describe('Test the course store', () => { course_name: '' }); expect(course.isValid()).toBe(false); - await expect(async () => { await course_store.addCourse(course); }) - .rejects.toThrow('The added course is invalid'); + await expect(async () => { + await course_store.addCourse(course); + }).rejects.toThrow('The added course is invalid'); }); test('Try to update an invalid course', async () => { diff --git a/tests/stores/problem_sets.spec.ts b/tests/stores/problem_sets.spec.ts index 41d1aa27..b4cf3aa3 100644 --- a/tests/stores/problem_sets.spec.ts +++ b/tests/stores/problem_sets.spec.ts @@ -11,6 +11,8 @@ import { setActivePinia, createPinia } from 'pinia'; import { createApp } from 'vue'; import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'; +import type { AxiosError } from 'axios'; +import { api } from 'src/boot/axios'; import { useProblemSetStore } from 'src/stores/problem_sets'; import { useCourseStore } from 'src/stores/courses'; @@ -129,11 +131,18 @@ describe('Problem Set store tests', () => { test('Delete a Homework Set', async () => { const problem_set_store = useProblemSetStore(); const set_to_delete = problem_set_store.findProblemSet({ set_name: 'HW #9' }); - const deleted_set = await problem_set_store.deleteProblemSet(set_to_delete as ProblemSet); - // Check that the deleted_set is the same as the original - expect(deleted_set.toObject()).toStrictEqual(set_to_delete?.toObject()); - const is_the_set_deleted = problem_set_store.findProblemSet({ set_name: 'HW #9' }); - expect(is_the_set_deleted).toBeUndefined(); + await problem_set_store.deleteProblemSet(set_to_delete as ProblemSet); + + // Check that the homework set is no longer in the database by getting an exception. + await api.get(`/courses/${precalc_course.course_id}/sets/${set_to_delete?.set_id ?? 0}`) + .then(() => { + fail('Expected failure response'); + }) + .catch((e: AxiosError) => { + expect(e.response?.status).toBe(500); + expect((e.response?.data as {exception: string}).exception) + .toBe('DB::Exception::SetNotInCourse'); + }); }); }); @@ -206,11 +215,18 @@ describe('Problem Set store tests', () => { test('Delete a Quiz', async () => { const problem_set_store = useProblemSetStore(); const set_to_delete = problem_set_store.findProblemSet({ set_name: 'Quiz #9' }); - const deleted_set = await problem_set_store.deleteProblemSet(set_to_delete as ProblemSet); - // Check that the deleted_set is the same as the original - expect(deleted_set.toObject()).toStrictEqual(set_to_delete?.toObject()); - const is_the_set_deleted = problem_set_store.findProblemSet({ set_name: 'Quiz #9' }); - expect(is_the_set_deleted).toBeUndefined(); + await problem_set_store.deleteProblemSet(set_to_delete as ProblemSet); + + // Check that the quiz is no longer in the database by getting an exception. + await api.get(`/courses/${precalc_course.course_id}/sets/${set_to_delete?.set_id ?? 0}`) + .then(() => { + fail('Expected failure response'); + }) + .catch((e: AxiosError) => { + expect(e.response?.status).toBe(500); + expect((e.response?.data as {exception: string}).exception) + .toBe('DB::Exception::SetNotInCourse'); + }); }); }); @@ -255,11 +271,18 @@ describe('Problem Set store tests', () => { test('Delete a Review Set', async () => { const problem_set_store = useProblemSetStore(); const set_to_delete = problem_set_store.findProblemSet({ set_name: 'Review Set #9' }); - const deleted_set = await problem_set_store.deleteProblemSet(set_to_delete as ProblemSet); - // Check that the deleted_set is the same as the original - expect(deleted_set.toObject()).toStrictEqual(set_to_delete?.toObject()); - const is_the_set_deleted = problem_set_store.findProblemSet({ set_name: 'Review Set #9' }); - expect(is_the_set_deleted).toBeUndefined(); + await problem_set_store.deleteProblemSet(set_to_delete as ProblemSet); + + // Check that the review set is no longer in the database by getting an exception. + await api.get(`/courses/${precalc_course.course_id}/sets/${set_to_delete?.set_id ?? 0}`) + .then(() => { + fail('Expected failure response'); + }) + .catch((e: AxiosError) => { + expect(e.response?.status).toBe(500); + expect((e.response?.data as {exception: string}).exception) + .toBe('DB::Exception::SetNotInCourse'); + }); }); }); }); diff --git a/tests/stores/set_problems.spec.ts b/tests/stores/set_problems.spec.ts index 0d4bfb2d..8c629515 100644 --- a/tests/stores/set_problems.spec.ts +++ b/tests/stores/set_problems.spec.ts @@ -11,6 +11,8 @@ import { createApp } from 'vue'; import { createPinia, setActivePinia } from 'pinia'; import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'; +import type { AxiosError } from 'axios'; +import { api } from 'boot/axios'; import { useCourseStore } from 'src/stores/courses'; import { useUserStore } from 'src/stores/users'; @@ -27,7 +29,6 @@ import { Dictionary, generic } from 'src/common/models'; import { loadCSV, cleanIDs } from '../utils'; import { checkPassword } from 'src/common/api-requests/session'; -import { logger } from 'src/boot/logger'; const app = createApp({}); @@ -141,10 +142,11 @@ describe('Problem Set store tests', () => { describe('CRUD tests for set problems', () => { let added_set_problem: SetProblem; let updated_problem: SetProblem; + let hw1: HomeworkSet; test('Add a set problem to a set', async () => { const problem_set_store = useProblemSetStore(); const set_problem_store = useSetProblemStore(); - const hw1 = problem_set_store.findProblemSet({ set_name: 'HW #1' }); + hw1 = problem_set_store.findProblemSet({ set_name: 'HW #1' }) as HomeworkSet; expect(hw1?.set_name).toStrictEqual('HW #1'); // grab the set problems for HW #1 so we know which is the next problem number. @@ -179,11 +181,19 @@ describe('Problem Set store tests', () => { test('Delete a set problem', async () => { const set_problem_store = useSetProblemStore(); - const problems = set_problem_store.findSetProblems({ set_name: 'HW #1' }); - const deleted_problem = await set_problem_store.deleteSetProblem(added_set_problem); - expect(deleted_problem).toStrictEqual(updated_problem); - expect(set_problem_store.findSetProblems({ set_name: 'HW #1' }).length) - .toBe(problems.length - 1); + await set_problem_store.deleteSetProblem(added_set_problem); + + // Check that the problem is no longer in the database by getting an exception. + await api.get(`/courses/${precalc_course.course_id}/sets/${hw1.set_id}/problems/${ + added_set_problem.set_problem_id}`) + .then(() => { + fail('Expected failure response'); + }) + .catch((e: AxiosError) => { + expect(e.response?.status).toBe(500); + expect((e.response?.data as {exception: string}).exception) + .toBe('DB::Exception::SetProblemNotFound'); + }); }); }); @@ -308,8 +318,19 @@ describe('Problem Set store tests', () => { test('Delete a user problem', async () => { const set_problem_store = useSetProblemStore(); - const deleted_problem = await set_problem_store.deleteUserProblem(updated_user_problem); - expect(cleanIDs(deleted_problem)).toStrictEqual(cleanIDs(updated_user_problem)); + await set_problem_store.deleteUserProblem(updated_user_problem); + + // Check that the course is no longer in the database by getting an exception. + await api.get(`/courses/${precalc_course.course_id}/sets/${added_hw.set_id}/users/${added_user_set.user_id + }/problems/${updated_user_problem.user_problem_id}`) + .then(() => { + fail('Expected failure response'); + }) + .catch((e: AxiosError) => { + expect(e.response?.status).toBe(500); + expect((e.response?.data as {exception: string}).exception) + .toBe('DB::Exception::UserProblemNotFound'); + }); }); // clean up some created sets. diff --git a/tests/stores/user_sets.spec.ts b/tests/stores/user_sets.spec.ts index d5c40249..177ead78 100644 --- a/tests/stores/user_sets.spec.ts +++ b/tests/stores/user_sets.spec.ts @@ -11,6 +11,7 @@ import { createApp } from 'vue'; import { createPinia, setActivePinia } from 'pinia'; import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'; +import type { AxiosError } from 'axios'; import { api } from 'boot/axios'; import { useCourseStore } from 'src/stores/courses'; @@ -172,14 +173,19 @@ describe('Tests user sets and merged user sets in the problem set store', () => test('Delete a User HW Set', async () => { const problem_set_store = useProblemSetStore(); - const user_set_to_delete = await problem_set_store.deleteUserSet(added_user_set); - if (user_set_to_delete) { - expect(cleanIDs(user_set_to_delete)).toStrictEqual(cleanIDs(added_user_set)); - } else { - test('Object was undefined', done => { - done.fail(new Error('Object was undefined')); + await problem_set_store.deleteUserSet(added_user_set); + + // Check that the homework set is no longer in the database by getting an exception. + await api.get(`/courses/${precalc_course.course_id}/sets/${added_user_set.set_id + }/users/${added_user_set.course_user_id}`) + .then(() => { + fail('Expected failure response'); + }) + .catch((e: AxiosError) => { + expect(e.response?.status).toBe(500); + expect((e.response?.data as {exception: string}).exception) + .toBe('DB::Exception::UserSetNotInCourse'); }); - } }); }); @@ -247,14 +253,19 @@ describe('Tests user sets and merged user sets in the problem set store', () => test('Delete a User Quiz', async () => { const problem_set_store = useProblemSetStore(); - const user_set_to_delete = await problem_set_store.deleteUserSet(user_set_to_update); - if (user_set_to_delete) { - expect(cleanIDs(user_set_to_delete)).toStrictEqual(cleanIDs(user_set_to_update)); - } else { - test('Object was undefined', done => { - done.fail(new Error('Object was undefined')); + await problem_set_store.deleteUserSet(user_set_to_update); + + // Check that the quiz is no longer in the database by getting an exception. + await api.get(`/courses/${precalc_course.course_id}/sets/${added_user_set.set_id + }/users/${added_user_set.course_user_id}`) + .then(() => { + fail('Expected failure response'); + }) + .catch((e: AxiosError) => { + expect(e.response?.status).toBe(500); + expect((e.response?.data as {exception: string}).exception) + .toBe('DB::Exception::UserSetNotInCourse'); }); - } }); }); @@ -296,15 +307,19 @@ describe('Tests user sets and merged user sets in the problem set store', () => test('Delete a User Review Set', async () => { const problem_set_store = useProblemSetStore(); const num_user_sets = problem_set_store.user_sets.length; - const user_set_to_delete = await problem_set_store.deleteUserSet(user_review_set_to_update); - - if (user_set_to_delete) { - expect(cleanIDs(user_set_to_delete)).toStrictEqual(cleanIDs(user_review_set_to_update)); - } else { - test('Object was undefined', done => { - done.fail(new Error('Object was undefined')); + await problem_set_store.deleteUserSet(user_review_set_to_update); + + // Check that the quiz is no longer in the database by getting an exception. + await api.get(`/courses/${precalc_course.course_id}/sets/${user_review_set_to_update.set_id + }/users/${user_review_set_to_update.course_user_id}`) + .then(() => { + fail('Expected failure response'); + }) + .catch((e: AxiosError) => { + expect(e.response?.status).toBe(500); + expect((e.response?.data as {exception: string}).exception) + .toBe('DB::Exception::UserSetNotInCourse'); }); - } expect(problem_set_store.user_sets).toHaveLength(num_user_sets - 1); }); diff --git a/tests/stores/users.spec.ts b/tests/stores/users.spec.ts index c6907599..39c71fa0 100644 --- a/tests/stores/users.spec.ts +++ b/tests/stores/users.spec.ts @@ -12,6 +12,7 @@ import { createApp } from 'vue'; import { createPinia, setActivePinia } from 'pinia'; import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'; import { api } from 'boot/axios'; +import type { AxiosError } from 'axios'; import { useCourseStore } from 'src/stores/courses'; import { useUserStore } from 'src/stores/users'; @@ -91,9 +92,18 @@ describe('User store tests', () => { }); test('Delete a global user', async () => { - const user_store = useUserStore(); - const deleted_user = await user_store.deleteUser(added_user) ?? new User(); - expect(cleanIDs(deleted_user)).toStrictEqual(cleanIDs(added_user)); + await useUserStore().deleteUser(added_user); + + // Check that the course is no longer in the database by getting an exception. + await api.get(`/users/${added_user.user_id}`) + .then(() => { + fail('Expected failure response'); + }) + .catch((e: AxiosError) => { + expect(e.response?.status).toBe(500); + expect((e.response?.data as {exception: string}).exception) + .toBe('DB::Exception::UserNotFound'); + }); }); }); @@ -167,8 +177,18 @@ describe('User store tests', () => { test('Delete Course User', async () => { const user_store = useUserStore(); const user_to_delete = user_store.course_users.find(user => user.user_id === user_not_in_precalc.user_id); - const deleted_user = await user_store.deleteCourseUser(user_to_delete as CourseUser); - expect(user_to_delete).toStrictEqual(deleted_user); + await user_store.deleteCourseUser(user_to_delete as CourseUser); + + // Check that the course user is no longer in the database by getting an exception. + await api.get(`/courses/${precalc_course.course_id}/users/${user_to_delete?.user_id ?? 0}`) + .then(() => { + fail('Expected failure response'); + }) + .catch((e: AxiosError) => { + expect(e.response?.status).toBe(500); + expect((e.response?.data as {exception: string}).exception) + .toBe('DB::Exception::UserNotInCourse'); + }); }); });