<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kaacken2</id>
	<title>Expertiza_Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kaacken2"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Kaacken2"/>
	<updated>2026-05-17T11:49:07Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018/E1876_Completion/Progress_view&amp;diff=119916</id>
		<title>CSC/ECE 517 Fall 2018/E1876 Completion/Progress view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018/E1876_Completion/Progress_view&amp;diff=119916"/>
		<updated>2018-11-14T01:56:03Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: /* Files that will be changed */ Clean up the section.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;='''Problem Statement'''=&lt;br /&gt;
A key component of Expertiza is peer reviews, which provide feedback to authors so that they can improve their work. Expertiza also supports grading of these reviews to ensure students write quality reviews, helping them learn more about the assignment by looking at their peers' work. In addition, Expertiza allows for metareviews, which are reviews the authors of the original work write for the reviews of their original work. This author feedback is useful for grading the reviews because it indicates how helpful this review was to the authors of the original work. The objective of this project is to add metareview or author feedback information to the review report page, which shows a summary of all the reviews written by the students for an assignment.&lt;br /&gt;
&lt;br /&gt;
='''Goal'''=&lt;br /&gt;
&lt;br /&gt;
The aim of this project is to build this into the system. We need an additional column in the 'Review Report' page for reviews which shows the calculation of the author feedback. This will help instructor's to know how the reviews proved useful to the authors/team. The aim of this project is to integrate the author feedback column in the summary page&lt;br /&gt;
&lt;br /&gt;
='''Design'''=&lt;br /&gt;
&lt;br /&gt;
== User Interface Enhancements ==&lt;br /&gt;
&lt;br /&gt;
In the page &amp;quot;Review report for Design exercise&amp;quot; (Log in as an instructor then go to Manage -&amp;gt; Assignments -&amp;gt; View review report.), we are planning to add one more column to show the average ratings for the author feedback for a student's review of a particular assignment. The logic for calculating the average score for the metareviews would be similar to already implemented logic for the &amp;quot;Score Awarded/Average Score&amp;quot; column. Below is the page we are planning to edit.&lt;br /&gt;
&lt;br /&gt;
[[File:Feedback_new.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Controller-level Logic ==&lt;br /&gt;
&lt;br /&gt;
The following method shows the code logic we are planning to write for calculating the average scores for the feedback given by authors for the reviews of their work.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: black; border:1px;&amp;quot;&amp;gt;&lt;br /&gt;
 def calculate_avg_score_by_feedback(question_answers, q_max_score)&lt;br /&gt;
      # get score and summary of answers for each question&lt;br /&gt;
      # only include divide the valid_answer_sum with the number of valid answers&lt;br /&gt;
&lt;br /&gt;
      valid_answer_counter = 0&lt;br /&gt;
      question_score = 0.0&lt;br /&gt;
      question_answers.each do |ans|&lt;br /&gt;
        # calculate score per question&lt;br /&gt;
        unless ans.answer.nil?&lt;br /&gt;
          question_score += ans.answer&lt;br /&gt;
          valid_answer_counter += 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if valid_answer_counter &amp;gt; 0 and q_max_score &amp;gt; 0&lt;br /&gt;
        # convert the score in percentage&lt;br /&gt;
        question_score /= (valid_answer_counter * q_max_score)&lt;br /&gt;
        question_score = question_score.round(2) * 100&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      question_score&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Database Tables ==&lt;br /&gt;
&lt;br /&gt;
The following are the table structures we will need for this feature. First, the questions table has all the questions based on the questionnaire. We will be only concerned with the questions in the feedback questionnaire. The answers for each question in the feedback questionnaire are saved in the Answers table below based on the Question ID. Now, in order to know if the answer is a feedback by team members or a review by reviewer, the mapping for the Answers table is done by the response_id which is a foreign key to the Response table. This Response table gives us the map_id which maps to a response map table. Now, the response map table gives us information on the reviewer_id, reviewee_id, reviewed_object_id (which is the ID for the assignment being reviewed) and the type (whether it's a teammate review, author feedback, a regular review, etc.). We will have to fetch the answers from the Answer table based on response_id because in our case, the response is from a previous reviewee and not a reviewer. So, we will fetch those answers whose response type is FeedbackResponseMap and calculate scores for those questions for the corresponding ReviewScores table. Below are excerpts from the [http://wiki.expertiza.ncsu.edu/index.php/Documentation_on_Database_Tables Expertiza database documentation] which describe the database tables relevant to our design.&lt;br /&gt;
&lt;br /&gt;
=== Questions Table Structure ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Questions page already exists,so created a page with the name Questions table and gave an external link on the tables page--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
!id &lt;br /&gt;
|int(11)  &lt;br /&gt;
|unique identifier for the record&lt;br /&gt;
|- &lt;br /&gt;
!txt   &lt;br /&gt;
|text  &lt;br /&gt;
|the question string&lt;br /&gt;
|- &lt;br /&gt;
!weight   &lt;br /&gt;
|int(11)  &lt;br /&gt;
|specifies the weighting of the question&lt;br /&gt;
|- &lt;br /&gt;
!questionnaire_id   &lt;br /&gt;
|int(11)&lt;br /&gt;
|the id of the questionnaire that this question belongs to&lt;br /&gt;
|-&lt;br /&gt;
!seq&lt;br /&gt;
|DECIMAL&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!type&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|Type of question&lt;br /&gt;
|-&lt;br /&gt;
!size&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|Size of the question&lt;br /&gt;
|-&lt;br /&gt;
!alternatives&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|Other question which means the same&lt;br /&gt;
|-&lt;br /&gt;
!break_before&lt;br /&gt;
|BIT&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!max_label&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!min_label&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Answer Table Structure ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|- &lt;br /&gt;
!id   &lt;br /&gt;
|int(11)  &lt;br /&gt;
|Unique ID for each Answers record.&lt;br /&gt;
|- &lt;br /&gt;
!question_id   &lt;br /&gt;
|int(11) &lt;br /&gt;
|ID of Question.&lt;br /&gt;
|- &lt;br /&gt;
!answer   &lt;br /&gt;
|int(11)  &lt;br /&gt;
|Value of each of the answer.&lt;br /&gt;
|- &lt;br /&gt;
!comments  &lt;br /&gt;
|text  &lt;br /&gt;
|Comment given to the answer.&lt;br /&gt;
|- &lt;br /&gt;
!reponse_id   &lt;br /&gt;
|int(11) &lt;br /&gt;
|ID of the response associated with this Answer.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Response Table Structure ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
!id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The unique record id&lt;br /&gt;
|-&lt;br /&gt;
!map_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The ID of the [[response_maps|response map]] defining the relationship that this response applies to&lt;br /&gt;
|-&lt;br /&gt;
!additional_comment&lt;br /&gt;
|text&lt;br /&gt;
|An additional comment provided by the reviewer to support his/her response&lt;br /&gt;
|-&lt;br /&gt;
!updated_at&lt;br /&gt;
|datetime&lt;br /&gt;
|The timestamp indicating when this response was last modified&lt;br /&gt;
|-&lt;br /&gt;
!created_at&lt;br /&gt;
|datetime&lt;br /&gt;
|The timestamp indicating when this response was created&lt;br /&gt;
|-&lt;br /&gt;
!version_num&lt;br /&gt;
|int(11)&lt;br /&gt;
|The version of the review.&lt;br /&gt;
|-&lt;br /&gt;
!round&lt;br /&gt;
|int(11)&lt;br /&gt;
|The round the review is connected to. &lt;br /&gt;
|-&lt;br /&gt;
!is_submitted&lt;br /&gt;
|tinyint(1)&lt;br /&gt;
|Boolean Field to indicate whether the review is submitted.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Response Map Table ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
!id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The unique record id&lt;br /&gt;
|- &lt;br /&gt;
!reviewed_object_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The object being reviewed in the [[responses|response]]. Possible objects include other ResponseMaps or [[assignments]]&lt;br /&gt;
|-&lt;br /&gt;
!reviewer_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The [[participants|participant]] (actually AssignmentParticipant) providing the response&lt;br /&gt;
|-&lt;br /&gt;
!reviewee_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The [[teams|team]] (AssignmentTeam) receiving the response&lt;br /&gt;
|-&lt;br /&gt;
!type&lt;br /&gt;
|varchar(255)&lt;br /&gt;
|Used for subclassing the response map. Available subclasses are ReviewResponseMap, MetareviewResponseMap, FeedbackResponseMap, TeammateReviewResponseMap  &lt;br /&gt;
|-&lt;br /&gt;
!created_at&lt;br /&gt;
|DATETIME&lt;br /&gt;
|Date and Time for when the record was created&lt;br /&gt;
|-&lt;br /&gt;
!updated_at&lt;br /&gt;
|DATETIME&lt;br /&gt;
|Date and Time when the last update was made&lt;br /&gt;
|-&lt;br /&gt;
!calibrate_to&lt;br /&gt;
|BIT&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Files That Will be Changed ==&lt;br /&gt;
&lt;br /&gt;
1. To calculate the average author feedback score: https://github.com/jainmohit1/expertiza/blob/master/app/models/on_the_fly_calc.rb&lt;br /&gt;
&lt;br /&gt;
2. To populate the average author feedback score for the view: https://github.com/jainmohit1/expertiza/blob/master/app/controllers/review_mapping_controller.rb&lt;br /&gt;
&lt;br /&gt;
3. To add a field in the view: https://github.com/jainmohit1/expertiza/blob/master/app/views/review_mapping/response_report.html.haml&lt;br /&gt;
&lt;br /&gt;
4. To add a field in the partial : https://github.com/jainmohit1/expertiza/blob/master/app/views/review_mapping/_review_report.html.erb&lt;br /&gt;
&lt;br /&gt;
5. To add a field in the partial:  https://github.com/jainmohit1/expertiza/blob/master/app/views/review_mapping/_team_score.html.erb&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
We plan to test the response report page (/review_mapping/response_report?id={:assignmentID}) to make sure the new field (average author feedback) exists.&lt;br /&gt;
&lt;br /&gt;
Using [http://rspec.info/ RSpec] we will add a test case to review_mapping_controller_spec.rb.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context 'when type is FeedbackResponseMap' do&lt;br /&gt;
      context 'when assignment has author feedback feature' do&lt;br /&gt;
        it 'renders response_report page with average author feedback data' do&lt;br /&gt;
          allow(assignment).to receive(:varying_rubrics_by_round?).and_return(true)&lt;br /&gt;
          allow(FeedbackResponseMap).to receive(:feedback_response_report).with('1', 'FeedbackResponseMap')&lt;br /&gt;
                                                                          .and_return([participant, participant1], [1, 2], [3, 4], [])&lt;br /&gt;
          params = {&lt;br /&gt;
            id: 1,&lt;br /&gt;
            report: {type: 'FeedbackResponseMap'},&lt;br /&gt;
          }&lt;br /&gt;
          get :response_report, params&lt;br /&gt;
          expect(response).to render_template(:response_report)&lt;br /&gt;
          expect(response).to have(:avg_author_feedback)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We also plan to manually test the response report page to make sure the new field is aligning well in the UI in the expected place. We will attach the screenshot of the UI as the test result. We will test the cases of one and multiple reviews by a reviewer and verify the number and average scores of the metareviews for those reviews are rendered correctly.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
1. http://wiki.expertiza.ncsu.edu/index.php/Documentation_on_Database_Tables&lt;br /&gt;
&lt;br /&gt;
2. https://github.com/jainmohit1/expertiza&lt;br /&gt;
&lt;br /&gt;
3. https://github.com/expertiza/expertiza/pull/1290&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018/E1876_Completion/Progress_view&amp;diff=119779</id>
		<title>CSC/ECE 517 Fall 2018/E1876 Completion/Progress view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018/E1876_Completion/Progress_view&amp;diff=119779"/>
		<updated>2018-11-13T22:26:59Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: /* Test Plan */ Add more material to and clean up the section.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;='''Problem Statement'''=&lt;br /&gt;
A key component of Expertiza is peer reviews, which provide feedback to authors so that they can improve their work. Expertiza also supports grading of these reviews to ensure students write quality reviews, helping them learn more about the assignment by looking at their peers' work. In addition, Expertiza allows for metareviews, which are reviews the authors of the original work write for the reviews of their original work. This author feedback is useful for grading the reviews because it indicates how helpful this review was to the authors of the original work. The objective of this project is to add metareview or author feedback information to the review report page, which shows a summary of all the reviews written by the students for an assignment.&lt;br /&gt;
&lt;br /&gt;
='''Goal'''=&lt;br /&gt;
&lt;br /&gt;
The aim of this project is to build this into the system. We need an additional column in the 'Review Report' page for reviews which shows the calculation of the author feedback. This will help instructor's to know how the reviews proved useful to the authors/team. The aim of this project is to integrate the author feedback column in the summary page&lt;br /&gt;
&lt;br /&gt;
='''Design'''=&lt;br /&gt;
&lt;br /&gt;
== User Interface Enhancements ==&lt;br /&gt;
&lt;br /&gt;
In the page &amp;quot;Review report for Design exercise&amp;quot; (Log in as an instructor then go to Manage -&amp;gt; Assignments -&amp;gt; View review report.), we are planning to add one more column to show the average ratings for the author feedback for a student's review of a particular assignment. The logic for calculating the average score for the metareviews would be similar to already implemented logic for the &amp;quot;Score Awarded/Average Score&amp;quot; column. Below is the page we are planning to edit.&lt;br /&gt;
&lt;br /&gt;
[[File:Feedback_new.png]]&lt;br /&gt;
&lt;br /&gt;
== Controller-level Logic ==&lt;br /&gt;
&lt;br /&gt;
The following method shows the code logic we are planning to write for calculating the average scores for the feedback given by authors for the reviews of their work.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: black; border:1px;&amp;quot;&amp;gt;&lt;br /&gt;
 def calculate_avg_score_by_criterion(question_answers, q_max_score)&lt;br /&gt;
      # get score and summary of answers for each question&lt;br /&gt;
      # only include divide the valid_answer_sum with the number of valid answers&lt;br /&gt;
&lt;br /&gt;
      valid_answer_counter = 0&lt;br /&gt;
      question_score = 0.0&lt;br /&gt;
      question_answers.each do |ans|&lt;br /&gt;
        # calculate score per question&lt;br /&gt;
        unless ans.answer.nil?&lt;br /&gt;
          question_score += ans.answer&lt;br /&gt;
          valid_answer_counter += 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if valid_answer_counter &amp;gt; 0 and q_max_score &amp;gt; 0&lt;br /&gt;
        # convert the score in percentage&lt;br /&gt;
        question_score /= (valid_answer_counter * q_max_score)&lt;br /&gt;
        question_score = question_score.round(2) * 100&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      question_score&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Database Tables ==&lt;br /&gt;
&lt;br /&gt;
The following are the table structures we will need for this feature. First, the questions table has all the questions based on the questionnaire. We will be only concerned with the questions in the feedback questionnaire. The answers for each question in the feedback questionnaire are saved in the Answers table below based on the Question ID. Now, in order to know if the answer is a feedback by team members or a review by reviewer, the mapping for the Answers table is done by the response_id which is a foreign key to the Response table. This Response table gives us the map_id which maps to a response map table. Now, the response map table gives us information on the reviewer_id, reviewee_id, reviewed_object_id (which is the ID for the assignment being reviewed) and the type (whether it's a teammate review, author feedback, a regular review, etc.). We will have to fetch the answers from the Answer table based on response_id because in our case, the response is from a previous reviewee and not a reviewer. So, we will fetch those answers whose response type is FeedbackResponseMap and calculate scores for those questions for the corresponding ReviewScores table. Below are excerpts from the [http://wiki.expertiza.ncsu.edu/index.php/Documentation_on_Database_Tables Expertiza database documentation] which describe the database tables relevant to our design.&lt;br /&gt;
&lt;br /&gt;
=== Questions Table Structure ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Questions page already exists,so created a page with the name Questions table and gave an external link on the tables page--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
!id &lt;br /&gt;
|int(11)  &lt;br /&gt;
|unique identifier for the record&lt;br /&gt;
|- &lt;br /&gt;
!txt   &lt;br /&gt;
|text  &lt;br /&gt;
|the question string&lt;br /&gt;
|- &lt;br /&gt;
!weight   &lt;br /&gt;
|int(11)  &lt;br /&gt;
|specifies the weighting of the question&lt;br /&gt;
|- &lt;br /&gt;
!questionnaire_id   &lt;br /&gt;
|int(11)&lt;br /&gt;
|the id of the questionnaire that this question belongs to&lt;br /&gt;
|-&lt;br /&gt;
!seq&lt;br /&gt;
|DECIMAL&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!type&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|Type of question&lt;br /&gt;
|-&lt;br /&gt;
!size&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|Size of the question&lt;br /&gt;
|-&lt;br /&gt;
!alternatives&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|Other question which means the same&lt;br /&gt;
|-&lt;br /&gt;
!break_before&lt;br /&gt;
|BIT&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!max_label&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!min_label&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Answer Table Structure ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|- &lt;br /&gt;
!id   &lt;br /&gt;
|int(11)  &lt;br /&gt;
|Unique ID for each Answers record.&lt;br /&gt;
|- &lt;br /&gt;
!question_id   &lt;br /&gt;
|int(11) &lt;br /&gt;
|ID of Question.&lt;br /&gt;
|- &lt;br /&gt;
!answer   &lt;br /&gt;
|int(11)  &lt;br /&gt;
|Value of each of the answer.&lt;br /&gt;
|- &lt;br /&gt;
!comments  &lt;br /&gt;
|text  &lt;br /&gt;
|Comment given to the answer.&lt;br /&gt;
|- &lt;br /&gt;
!reponse_id   &lt;br /&gt;
|int(11) &lt;br /&gt;
|ID of the response associated with this Answer.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Response Table Structure ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
!id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The unique record id&lt;br /&gt;
|-&lt;br /&gt;
!map_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The ID of the [[response_maps|response map]] defining the relationship that this response applies to&lt;br /&gt;
|-&lt;br /&gt;
!additional_comment&lt;br /&gt;
|text&lt;br /&gt;
|An additional comment provided by the reviewer to support his/her response&lt;br /&gt;
|-&lt;br /&gt;
!updated_at&lt;br /&gt;
|datetime&lt;br /&gt;
|The timestamp indicating when this response was last modified&lt;br /&gt;
|-&lt;br /&gt;
!created_at&lt;br /&gt;
|datetime&lt;br /&gt;
|The timestamp indicating when this response was created&lt;br /&gt;
|-&lt;br /&gt;
!version_num&lt;br /&gt;
|int(11)&lt;br /&gt;
|The version of the review.&lt;br /&gt;
|-&lt;br /&gt;
!round&lt;br /&gt;
|int(11)&lt;br /&gt;
|The round the review is connected to. &lt;br /&gt;
|-&lt;br /&gt;
!is_submitted&lt;br /&gt;
|tinyint(1)&lt;br /&gt;
|Boolean Field to indicate whether the review is submitted.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Response Map Table ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
!id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The unique record id&lt;br /&gt;
|- &lt;br /&gt;
!reviewed_object_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The object being reviewed in the [[responses|response]]. Possible objects include other ResponseMaps or [[assignments]]&lt;br /&gt;
|-&lt;br /&gt;
!reviewer_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The [[participants|participant]] (actually AssignmentParticipant) providing the response&lt;br /&gt;
|-&lt;br /&gt;
!reviewee_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The [[teams|team]] (AssignmentTeam) receiving the response&lt;br /&gt;
|-&lt;br /&gt;
!type&lt;br /&gt;
|varchar(255)&lt;br /&gt;
|Used for subclassing the response map. Available subclasses are ReviewResponseMap, MetareviewResponseMap, FeedbackResponseMap, TeammateReviewResponseMap  &lt;br /&gt;
|-&lt;br /&gt;
!created_at&lt;br /&gt;
|DATETIME&lt;br /&gt;
|Date and Time for when the record was created&lt;br /&gt;
|-&lt;br /&gt;
!updated_at&lt;br /&gt;
|DATETIME&lt;br /&gt;
|Date and Time when the last update was made&lt;br /&gt;
|-&lt;br /&gt;
!calibrate_to&lt;br /&gt;
|BIT&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
We plan to test the response report page (/review_mapping/response_report?id={:assignmentID}) to make sure the new field (average author feedback) exists.&lt;br /&gt;
&lt;br /&gt;
Using [http://rspec.info/ RSpec] we will add a test case to review_mapping_controller_spec.rb.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context 'when type is FeedbackResponseMap' do&lt;br /&gt;
      context 'when assignment has author feedback feature' do&lt;br /&gt;
        it 'renders response_report page with average author feedback data' do&lt;br /&gt;
          allow(assignment).to receive(:varying_rubrics_by_round?).and_return(true)&lt;br /&gt;
          allow(FeedbackResponseMap).to receive(:feedback_response_report).with('1', 'FeedbackResponseMap')&lt;br /&gt;
                                                                          .and_return([participant, participant1], [1, 2], [3, 4], [])&lt;br /&gt;
          params = {&lt;br /&gt;
            id: 1,&lt;br /&gt;
            report: {type: 'FeedbackResponseMap'},&lt;br /&gt;
          }&lt;br /&gt;
          get :response_report, params&lt;br /&gt;
          expect(response).to render_template(:response_report)&lt;br /&gt;
          expect(response).to have(:avg_author_feedback)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We also plan to manually test the response report page to make sure the new field is aligning well in the UI in the expected place. We will attach the screenshot of the UI as the test result. We will test the cases of one and multiple reviews by a reviewer and verify the number and average scores of the metareviews for those reviews are rendered correctly.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
1. http://wiki.expertiza.ncsu.edu/index.php/Documentation_on_Database_Tables&lt;br /&gt;
&lt;br /&gt;
2. https://github.com/jainmohit1/expertiza&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018/E1876_Completion/Progress_view&amp;diff=119774</id>
		<title>CSC/ECE 517 Fall 2018/E1876 Completion/Progress view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018/E1876_Completion/Progress_view&amp;diff=119774"/>
		<updated>2018-11-13T22:17:58Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;='''Problem Statement'''=&lt;br /&gt;
A key component of Expertiza is peer reviews, which provide feedback to authors so that they can improve their work. Expertiza also supports grading of these reviews to ensure students write quality reviews, helping them learn more about the assignment by looking at their peers' work. In addition, Expertiza allows for metareviews, which are reviews the authors of the original work write for the reviews of their original work. This author feedback is useful for grading the reviews because it indicates how helpful this review was to the authors of the original work. The objective of this project is to add metareview or author feedback information to the review report page, which shows a summary of all the reviews written by the students for an assignment.&lt;br /&gt;
&lt;br /&gt;
='''Goal'''=&lt;br /&gt;
&lt;br /&gt;
The aim of this project is to build this into the system. We need an additional column in the 'Review Report' page for reviews which shows the calculation of the author feedback. This will help instructor's to know how the reviews proved useful to the authors/team. The aim of this project is to integrate the author feedback column in the summary page&lt;br /&gt;
&lt;br /&gt;
='''Design'''=&lt;br /&gt;
&lt;br /&gt;
== User Interface Enhancements ==&lt;br /&gt;
&lt;br /&gt;
In the page &amp;quot;Review report for Design exercise&amp;quot; (Log in as an instructor then go to Manage -&amp;gt; Assignments -&amp;gt; View review report.), we are planning to add one more column to show the average ratings for the author feedback for a student's review of a particular assignment. The logic for calculating the average score for the metareviews would be similar to already implemented logic for the &amp;quot;Score Awarded/Average Score&amp;quot; column. Below is the page we are planning to edit.&lt;br /&gt;
&lt;br /&gt;
[[File:Feedback_new.png]]&lt;br /&gt;
&lt;br /&gt;
== Controller-level Logic ==&lt;br /&gt;
&lt;br /&gt;
The following method shows the code logic we are planning to write for calculating the average scores for the feedback given by authors for the reviews of their work.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: black; border:1px;&amp;quot;&amp;gt;&lt;br /&gt;
 def calculate_avg_score_by_criterion(question_answers, q_max_score)&lt;br /&gt;
      # get score and summary of answers for each question&lt;br /&gt;
      # only include divide the valid_answer_sum with the number of valid answers&lt;br /&gt;
&lt;br /&gt;
      valid_answer_counter = 0&lt;br /&gt;
      question_score = 0.0&lt;br /&gt;
      question_answers.each do |ans|&lt;br /&gt;
        # calculate score per question&lt;br /&gt;
        unless ans.answer.nil?&lt;br /&gt;
          question_score += ans.answer&lt;br /&gt;
          valid_answer_counter += 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if valid_answer_counter &amp;gt; 0 and q_max_score &amp;gt; 0&lt;br /&gt;
        # convert the score in percentage&lt;br /&gt;
        question_score /= (valid_answer_counter * q_max_score)&lt;br /&gt;
        question_score = question_score.round(2) * 100&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      question_score&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Database Tables ==&lt;br /&gt;
&lt;br /&gt;
The following are the table structures we will need for this feature. First, the questions table has all the questions based on the questionnaire. We will be only concerned with the questions in the feedback questionnaire. The answers for each question in the feedback questionnaire are saved in the Answers table below based on the Question ID. Now, in order to know if the answer is a feedback by team members or a review by reviewer, the mapping for the Answers table is done by the response_id which is a foreign key to the Response table. This Response table gives us the map_id which maps to a response map table. Now, the response map table gives us information on the reviewer_id, reviewee_id, reviewed_object_id (which is the ID for the assignment being reviewed) and the type (whether it's a teammate review, author feedback, a regular review, etc.). We will have to fetch the answers from the Answer table based on response_id because in our case, the response is from a previous reviewee and not a reviewer. So, we will fetch those answers whose response type is FeedbackResponseMap and calculate scores for those questions for the corresponding ReviewScores table. Below are excerpts from the [http://wiki.expertiza.ncsu.edu/index.php/Documentation_on_Database_Tables Expertiza database documentation] which describe the database tables relevant to our design.&lt;br /&gt;
&lt;br /&gt;
=== Questions Table Structure ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Questions page already exists,so created a page with the name Questions table and gave an external link on the tables page--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
!id &lt;br /&gt;
|int(11)  &lt;br /&gt;
|unique identifier for the record&lt;br /&gt;
|- &lt;br /&gt;
!txt   &lt;br /&gt;
|text  &lt;br /&gt;
|the question string&lt;br /&gt;
|- &lt;br /&gt;
!weight   &lt;br /&gt;
|int(11)  &lt;br /&gt;
|specifies the weighting of the question&lt;br /&gt;
|- &lt;br /&gt;
!questionnaire_id   &lt;br /&gt;
|int(11)&lt;br /&gt;
|the id of the questionnaire that this question belongs to&lt;br /&gt;
|-&lt;br /&gt;
!seq&lt;br /&gt;
|DECIMAL&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!type&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|Type of question&lt;br /&gt;
|-&lt;br /&gt;
!size&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|Size of the question&lt;br /&gt;
|-&lt;br /&gt;
!alternatives&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|Other question which means the same&lt;br /&gt;
|-&lt;br /&gt;
!break_before&lt;br /&gt;
|BIT&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!max_label&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!min_label&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Answer Table Structure ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|- &lt;br /&gt;
!id   &lt;br /&gt;
|int(11)  &lt;br /&gt;
|Unique ID for each Answers record.&lt;br /&gt;
|- &lt;br /&gt;
!question_id   &lt;br /&gt;
|int(11) &lt;br /&gt;
|ID of Question.&lt;br /&gt;
|- &lt;br /&gt;
!answer   &lt;br /&gt;
|int(11)  &lt;br /&gt;
|Value of each of the answer.&lt;br /&gt;
|- &lt;br /&gt;
!comments  &lt;br /&gt;
|text  &lt;br /&gt;
|Comment given to the answer.&lt;br /&gt;
|- &lt;br /&gt;
!reponse_id   &lt;br /&gt;
|int(11) &lt;br /&gt;
|ID of the response associated with this Answer.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Response Table Structure ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
!id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The unique record id&lt;br /&gt;
|-&lt;br /&gt;
!map_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The ID of the [[response_maps|response map]] defining the relationship that this response applies to&lt;br /&gt;
|-&lt;br /&gt;
!additional_comment&lt;br /&gt;
|text&lt;br /&gt;
|An additional comment provided by the reviewer to support his/her response&lt;br /&gt;
|-&lt;br /&gt;
!updated_at&lt;br /&gt;
|datetime&lt;br /&gt;
|The timestamp indicating when this response was last modified&lt;br /&gt;
|-&lt;br /&gt;
!created_at&lt;br /&gt;
|datetime&lt;br /&gt;
|The timestamp indicating when this response was created&lt;br /&gt;
|-&lt;br /&gt;
!version_num&lt;br /&gt;
|int(11)&lt;br /&gt;
|The version of the review.&lt;br /&gt;
|-&lt;br /&gt;
!round&lt;br /&gt;
|int(11)&lt;br /&gt;
|The round the review is connected to. &lt;br /&gt;
|-&lt;br /&gt;
!is_submitted&lt;br /&gt;
|tinyint(1)&lt;br /&gt;
|Boolean Field to indicate whether the review is submitted.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Response Map Table ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
!id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The unique record id&lt;br /&gt;
|- &lt;br /&gt;
!reviewed_object_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The object being reviewed in the [[responses|response]]. Possible objects include other ResponseMaps or [[assignments]]&lt;br /&gt;
|-&lt;br /&gt;
!reviewer_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The [[participants|participant]] (actually AssignmentParticipant) providing the response&lt;br /&gt;
|-&lt;br /&gt;
!reviewee_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The [[teams|team]] (AssignmentTeam) receiving the response&lt;br /&gt;
|-&lt;br /&gt;
!type&lt;br /&gt;
|varchar(255)&lt;br /&gt;
|Used for subclassing the response map. Available subclasses are ReviewResponseMap, MetareviewResponseMap, FeedbackResponseMap, TeammateReviewResponseMap  &lt;br /&gt;
|-&lt;br /&gt;
!created_at&lt;br /&gt;
|DATETIME&lt;br /&gt;
|Date and Time for when the record was created&lt;br /&gt;
|-&lt;br /&gt;
!updated_at&lt;br /&gt;
|DATETIME&lt;br /&gt;
|Date and Time when the last update was made&lt;br /&gt;
|-&lt;br /&gt;
!calibrate_to&lt;br /&gt;
|BIT&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Plan to test the response report page (/review_mapping/response_report?id={:assignmentID}) to make sure the new field (avg author feedback) exists&lt;br /&gt;
** Using rspec we will add a test case to ReviewMappingControllerSpec.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    context 'when type is FeedbackResponseMap' do&lt;br /&gt;
      context 'when assignment has author feedback feature' do&lt;br /&gt;
        it 'renders response_report page with average author feedback data' do&lt;br /&gt;
          allow(assignment).to receive(:varying_rubrics_by_round?).and_return(true)&lt;br /&gt;
          allow(FeedbackResponseMap).to receive(:feedback_response_report).with('1', 'FeedbackResponseMap')&lt;br /&gt;
                                                                          .and_return([participant, participant1], [1, 2], [3, 4], [])&lt;br /&gt;
          params = {&lt;br /&gt;
            id: 1,&lt;br /&gt;
            report: {type: 'FeedbackResponseMap'},&lt;br /&gt;
          }&lt;br /&gt;
          get :response_report, params&lt;br /&gt;
          expect(response).to render_template(:response_report)&lt;br /&gt;
          expect(response).to have(:avg_author_feedback)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Also, we plan to manually test the response report page to make sure the new field is aligning well in the UI in the expected place. We will attach the screenshot of the UI as the test result.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
1. http://wiki.expertiza.ncsu.edu/index.php/Documentation_on_Database_Tables&lt;br /&gt;
&lt;br /&gt;
2. https://github.com/jainmohit1/expertiza&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018/E1876_Completion/Progress_view&amp;diff=119772</id>
		<title>CSC/ECE 517 Fall 2018/E1876 Completion/Progress view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018/E1876_Completion/Progress_view&amp;diff=119772"/>
		<updated>2018-11-13T22:16:59Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: /* Design */ Cleans up and reorders sections in the section.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;='''Problem Statement'''=&lt;br /&gt;
A key component of Expertiza is peer reviews, which provide feedback to authors so that they can improve their work. Expertiza also supports grading of these reviews to ensure students write quality reviews, helping them learn more about the assignment by looking at their peers' work. In addition, Expertiza allows for metareviews, which are reviews the authors of the original work write for the reviews of their original work. This author feedback is useful for grading the reviews because it indicates how helpful this review was to the authors of the original work. The objective of this project is to add metareview or author feedback information to the review report page, which shows a summary of all the reviews written by the students for an assignment.&lt;br /&gt;
&lt;br /&gt;
='''Goal'''=&lt;br /&gt;
&lt;br /&gt;
The aim of this project is to build this into the system. We need an additional column in the 'Review Report' page for reviews which shows the calculation of the author feedback. This will help instructor's to know how the reviews proved useful to the authors/team. The aim of this project is to integrate the author feedback column in the summary page&lt;br /&gt;
&lt;br /&gt;
='''Design'''=&lt;br /&gt;
&lt;br /&gt;
== User Interface Enhancements ==&lt;br /&gt;
&lt;br /&gt;
In the page &amp;quot;Review report for Design exercise&amp;quot; (Log in as an instructor then go to Manage -&amp;gt; Assignments -&amp;gt; View review report.), we are planning to add one more column to show the average ratings for the author feedback for a student's review of a particular assignment. The logic for calculating the average score for the metareviews would be similar to already implemented logic for the &amp;quot;Score Awarded/Average Score&amp;quot; column. Below is the page we are planning to edit.&lt;br /&gt;
&lt;br /&gt;
[[File:Feedback_new.png]]&lt;br /&gt;
&lt;br /&gt;
== Controller-level Logic ==&lt;br /&gt;
&lt;br /&gt;
The following method shows the code logic we are planning to write for calculating the average scores for the feedback given by authors for the reviews of their work.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: black; border:1px;&amp;quot;&amp;gt;&lt;br /&gt;
 def calculate_avg_score_by_criterion(question_answers, q_max_score)&lt;br /&gt;
      # get score and summary of answers for each question&lt;br /&gt;
      # only include divide the valid_answer_sum with the number of valid answers&lt;br /&gt;
&lt;br /&gt;
      valid_answer_counter = 0&lt;br /&gt;
      question_score = 0.0&lt;br /&gt;
      question_answers.each do |ans|&lt;br /&gt;
        # calculate score per question&lt;br /&gt;
        unless ans.answer.nil?&lt;br /&gt;
          question_score += ans.answer&lt;br /&gt;
          valid_answer_counter += 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if valid_answer_counter &amp;gt; 0 and q_max_score &amp;gt; 0&lt;br /&gt;
        # convert the score in percentage&lt;br /&gt;
        question_score /= (valid_answer_counter * q_max_score)&lt;br /&gt;
        question_score = question_score.round(2) * 100&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      question_score&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Relevant Database Tables ==&lt;br /&gt;
&lt;br /&gt;
The following are the table structures we will need for this feature. First, the questions table has all the questions based on the questionnaire. We will be only concerned with the questions in the feedback questionnaire. The answers for each question in the feedback questionnaire are saved in the Answers table below based on the Question ID. Now, in order to know if the answer is a feedback by team members or a review by reviewer, the mapping for the Answers table is done by the response_id which is a foreign key to the Response table. This Response table gives us the map_id which maps to a response map table. Now, the response map table gives us information on the reviewer_id, reviewee_id, reviewed_object_id (which is the ID for the assignment being reviewed) and the type (whether it's a teammate review, author feedback, a regular review, etc.). We will have to fetch the answers from the Answer table based on response_id because in our case, the response is from a previous reviewee and not a reviewer. So, we will fetch those answers whose response type is FeedbackResponseMap and calculate scores for those questions for the corresponding ReviewScores table. Below are excerpts from the [http://wiki.expertiza.ncsu.edu/index.php/Documentation_on_Database_Tables Expertiza database documentation] which describe the database tables relevant to our design.&lt;br /&gt;
&lt;br /&gt;
=== Questions Table Structure ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Questions page already exists,so created a page with the name Questions table and gave an external link on the tables page--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
!id &lt;br /&gt;
|int(11)  &lt;br /&gt;
|unique identifier for the record&lt;br /&gt;
|- &lt;br /&gt;
!txt   &lt;br /&gt;
|text  &lt;br /&gt;
|the question string&lt;br /&gt;
|- &lt;br /&gt;
!weight   &lt;br /&gt;
|int(11)  &lt;br /&gt;
|specifies the weighting of the question&lt;br /&gt;
|- &lt;br /&gt;
!questionnaire_id   &lt;br /&gt;
|int(11)&lt;br /&gt;
|the id of the questionnaire that this question belongs to&lt;br /&gt;
|-&lt;br /&gt;
!seq&lt;br /&gt;
|DECIMAL&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!type&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|Type of question&lt;br /&gt;
|-&lt;br /&gt;
!size&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|Size of the question&lt;br /&gt;
|-&lt;br /&gt;
!alternatives&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|Other question which means the same&lt;br /&gt;
|-&lt;br /&gt;
!break_before&lt;br /&gt;
|BIT&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!max_label&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!min_label&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Answer Table Structure ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|- &lt;br /&gt;
!id   &lt;br /&gt;
|int(11)  &lt;br /&gt;
|Unique ID for each Answers record.&lt;br /&gt;
|- &lt;br /&gt;
!question_id   &lt;br /&gt;
|int(11) &lt;br /&gt;
|ID of Question.&lt;br /&gt;
|- &lt;br /&gt;
!answer   &lt;br /&gt;
|int(11)  &lt;br /&gt;
|Value of each of the answer.&lt;br /&gt;
|- &lt;br /&gt;
!comments  &lt;br /&gt;
|text  &lt;br /&gt;
|Comment given to the answer.&lt;br /&gt;
|- &lt;br /&gt;
!reponse_id   &lt;br /&gt;
|int(11) &lt;br /&gt;
|ID of the response associated with this Answer.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Response Table Structure ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
!id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The unique record id&lt;br /&gt;
|-&lt;br /&gt;
!map_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The ID of the [[response_maps|response map]] defining the relationship that this response applies to&lt;br /&gt;
|-&lt;br /&gt;
!additional_comment&lt;br /&gt;
|text&lt;br /&gt;
|An additional comment provided by the reviewer to support his/her response&lt;br /&gt;
|-&lt;br /&gt;
!updated_at&lt;br /&gt;
|datetime&lt;br /&gt;
|The timestamp indicating when this response was last modified&lt;br /&gt;
|-&lt;br /&gt;
!created_at&lt;br /&gt;
|datetime&lt;br /&gt;
|The timestamp indicating when this response was created&lt;br /&gt;
|-&lt;br /&gt;
!version_num&lt;br /&gt;
|int(11)&lt;br /&gt;
|The version of the review.&lt;br /&gt;
|-&lt;br /&gt;
!round&lt;br /&gt;
|int(11)&lt;br /&gt;
|The round the review is connected to. &lt;br /&gt;
|-&lt;br /&gt;
!is_submitted&lt;br /&gt;
|tinyint(1)&lt;br /&gt;
|Boolean Field to indicate whether the review is submitted.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Response Map Table ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
!id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The unique record id&lt;br /&gt;
|- &lt;br /&gt;
!reviewed_object_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The object being reviewed in the [[responses|response]]. Possible objects include other ResponseMaps or [[assignments]]&lt;br /&gt;
|-&lt;br /&gt;
!reviewer_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The [[participants|participant]] (actually AssignmentParticipant) providing the response&lt;br /&gt;
|-&lt;br /&gt;
!reviewee_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The [[teams|team]] (AssignmentTeam) receiving the response&lt;br /&gt;
|-&lt;br /&gt;
!type&lt;br /&gt;
|varchar(255)&lt;br /&gt;
|Used for subclassing the response map. Available subclasses are ReviewResponseMap, MetareviewResponseMap, FeedbackResponseMap, TeammateReviewResponseMap  &lt;br /&gt;
|-&lt;br /&gt;
!created_at&lt;br /&gt;
|DATETIME&lt;br /&gt;
|Date and Time for when the record was created&lt;br /&gt;
|-&lt;br /&gt;
!updated_at&lt;br /&gt;
|DATETIME&lt;br /&gt;
|Date and Time when the last update was made&lt;br /&gt;
|-&lt;br /&gt;
!calibrate_to&lt;br /&gt;
|BIT&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Plan to test the response report page (/review_mapping/response_report?id={:assignmentID}) to make sure the new field (avg author feedback) exists&lt;br /&gt;
** Using rspec we will add a test case to ReviewMappingControllerSpec.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    context 'when type is FeedbackResponseMap' do&lt;br /&gt;
      context 'when assignment has author feedback feature' do&lt;br /&gt;
        it 'renders response_report page with average author feedback data' do&lt;br /&gt;
          allow(assignment).to receive(:varying_rubrics_by_round?).and_return(true)&lt;br /&gt;
          allow(FeedbackResponseMap).to receive(:feedback_response_report).with('1', 'FeedbackResponseMap')&lt;br /&gt;
                                                                          .and_return([participant, participant1], [1, 2], [3, 4], [])&lt;br /&gt;
          params = {&lt;br /&gt;
            id: 1,&lt;br /&gt;
            report: {type: 'FeedbackResponseMap'},&lt;br /&gt;
          }&lt;br /&gt;
          get :response_report, params&lt;br /&gt;
          expect(response).to render_template(:response_report)&lt;br /&gt;
          expect(response).to have(:avg_author_feedback)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Also, we plan to manually test the response report page to make sure the new field is aligning well in the UI in the expected place. We will attach the screenshot of the UI as the test result.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
1) http://wiki.expertiza.ncsu.edu/index.php/Documentation_on_Database_Tables&lt;br /&gt;
&lt;br /&gt;
2) https://github.com/jainmohit1/expertiza&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018/E1876_Completion/Progress_view&amp;diff=119768</id>
		<title>CSC/ECE 517 Fall 2018/E1876 Completion/Progress view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018/E1876_Completion/Progress_view&amp;diff=119768"/>
		<updated>2018-11-13T22:04:10Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: /* Problem Statement */ Overhauls the section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;='''Problem Statement'''=&lt;br /&gt;
A key component of Expertiza is peer reviews, which provide feedback to authors so that they can improve their work. Expertiza also supports grading of these reviews to ensure students write quality reviews, helping them learn more about the assignment by looking at their peers' work. In addition, Expertiza allows for metareviews, which are reviews the authors of the original work write for the reviews of their original work. This author feedback is useful for grading the reviews because it indicates how helpful this review was to the authors of the original work. The objective of this project is to add metareview or author feedback information to the review report page, which shows a summary of all the reviews written by the students for an assignment.&lt;br /&gt;
&lt;br /&gt;
='''Goal'''=&lt;br /&gt;
&lt;br /&gt;
The aim of this project is to build this into the system. We need an additional column in the 'Review Report' page for reviews which shows the calculation of the author feedback. This will help instructor's to know how the reviews proved useful to the authors/team. The aim of this project is to integrate the author feedback column in the summary page&lt;br /&gt;
&lt;br /&gt;
='''Design'''=&lt;br /&gt;
&lt;br /&gt;
== Database ==&lt;br /&gt;
&lt;br /&gt;
The following are the table structures we will need for mapping. First, the questions table has all the questions based on the questionnaire. We will be only concerned with the questions in the feedback questionnaire. The answers for each question in the feedback questionnaire is saved in Answers table below based on Question ID. Now, in order to know if the answers is a feedback by team members or a review by reviewer, the mapping for Answers table is done by response_id which is a foreign key to response table. Response table gives us map_id which maps to Response Maps table. Now, Response Map table gives us information of the reviewer_id, reviewee_id, reviewed_object_id (which is the id for the assignment being reviewed) and the type (whether it's a teammate review, author feedback or a regular review). We will have to fetch the answers from the Answer table based on response_id because in our case, the response is from a reviewee and not a reviewer. So, we will fetch those answers whose response type is FeedbackResponseMap and calculate scores for those questions from Review_Scores table. &lt;br /&gt;
&lt;br /&gt;
=== Questions Table Structure===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Questions page already exists,so created a page with the name Questions table and gave an external link on the tables page--&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
!id &lt;br /&gt;
|int(11)  &lt;br /&gt;
|unique identifier for the record&lt;br /&gt;
|- &lt;br /&gt;
!txt   &lt;br /&gt;
|text  &lt;br /&gt;
|the question string&lt;br /&gt;
|- &lt;br /&gt;
!weight   &lt;br /&gt;
|int(11)  &lt;br /&gt;
|specifies the weighting of the question&lt;br /&gt;
|- &lt;br /&gt;
!questionnaire_id   &lt;br /&gt;
|int(11)&lt;br /&gt;
|the id of the questionnaire that this question belongs to&lt;br /&gt;
|-&lt;br /&gt;
!seq&lt;br /&gt;
|DECIMAL&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!type&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|Type of question&lt;br /&gt;
|-&lt;br /&gt;
!size&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|Size of the question&lt;br /&gt;
|-&lt;br /&gt;
!alternatives&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|Other question which means the same&lt;br /&gt;
|-&lt;br /&gt;
!break_before&lt;br /&gt;
|BIT&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!max_label&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!min_label&lt;br /&gt;
|VARCHAR(255)&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Answer Table Structure ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|- &lt;br /&gt;
!id   &lt;br /&gt;
|int(11)  &lt;br /&gt;
|Unique ID for each Answers record.&lt;br /&gt;
|- &lt;br /&gt;
!question_id   &lt;br /&gt;
|int(11) &lt;br /&gt;
|ID of Question.&lt;br /&gt;
|- &lt;br /&gt;
!answer   &lt;br /&gt;
|int(11)  &lt;br /&gt;
|Value of each of the answer.&lt;br /&gt;
|- &lt;br /&gt;
!comments  &lt;br /&gt;
|text  &lt;br /&gt;
|Comment given to the answer.&lt;br /&gt;
|- &lt;br /&gt;
!reponse_id   &lt;br /&gt;
|int(11) &lt;br /&gt;
|ID of the response associated with this Answer.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Response Table Structure ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
!id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The unique record id&lt;br /&gt;
|-&lt;br /&gt;
!map_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The ID of the [[response_maps|response map]] defining the relationship that this response applies to&lt;br /&gt;
|-&lt;br /&gt;
!additional_comment&lt;br /&gt;
|text&lt;br /&gt;
|An additional comment provided by the reviewer to support his/her response&lt;br /&gt;
|-&lt;br /&gt;
!updated_at&lt;br /&gt;
|datetime&lt;br /&gt;
|The timestamp indicating when this response was last modified&lt;br /&gt;
|-&lt;br /&gt;
!created_at&lt;br /&gt;
|datetime&lt;br /&gt;
|The timestamp indicating when this response was created&lt;br /&gt;
|-&lt;br /&gt;
!version_num&lt;br /&gt;
|int(11)&lt;br /&gt;
|The version of the review.&lt;br /&gt;
|-&lt;br /&gt;
!round&lt;br /&gt;
|int(11)&lt;br /&gt;
|The round the review is connected to. &lt;br /&gt;
|-&lt;br /&gt;
!is_submitted&lt;br /&gt;
|tinyint(1)&lt;br /&gt;
|Boolean Field to indicate whether the review is submitted.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Response Map Table ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
!Field Name !!Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
!id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The unique record id&lt;br /&gt;
|- &lt;br /&gt;
!reviewed_object_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The object being reviewed in the [[responses|response]]. Possible objects include other ResponseMaps or [[assignments]]&lt;br /&gt;
|-&lt;br /&gt;
!reviewer_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The [[participants|participant]] (actually AssignmentParticipant) providing the response&lt;br /&gt;
|-&lt;br /&gt;
!reviewee_id&lt;br /&gt;
|int(11)&lt;br /&gt;
|The [[teams|team]] (AssignmentTeam) receiving the response&lt;br /&gt;
|-&lt;br /&gt;
!type&lt;br /&gt;
|varchar(255)&lt;br /&gt;
|Used for subclassing the response map. Available subclasses are ReviewResponseMap, MetareviewResponseMap, FeedbackResponseMap, TeammateReviewResponseMap  &lt;br /&gt;
|-&lt;br /&gt;
!created_at&lt;br /&gt;
|DATETIME&lt;br /&gt;
|Date and Time for when the record was created&lt;br /&gt;
|-&lt;br /&gt;
!updated_at&lt;br /&gt;
|DATETIME&lt;br /&gt;
|Date and Time when the last update was made&lt;br /&gt;
|-&lt;br /&gt;
!calibrate_to&lt;br /&gt;
|BIT&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== UI Implementation ==&lt;br /&gt;
&lt;br /&gt;
In the page Review report for Design exercise ( login as an instructor -&amp;gt; Manage -&amp;gt; Assignments -&amp;gt; View review report ), we are planning to add one more column to show the average ratings for the authors feedback on a particular assignment. The logic for calculating the average score for the feedback would be similar to already implemented logic for score awarded/ average score column. Below attached shows the page we are planning to edit.&lt;br /&gt;
&lt;br /&gt;
[[File:Feedback_new.png]]&lt;br /&gt;
&lt;br /&gt;
== Code Logic ==&lt;br /&gt;
&lt;br /&gt;
Following shows the code logic we are planning to write for calculating the avg scores for the feedback given by authors.&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color: black; border:1px;&amp;quot;&amp;gt;&lt;br /&gt;
 def calculate_avg_score_by_criterion(question_answers, q_max_score)&lt;br /&gt;
      # get score and summary of answers for each question&lt;br /&gt;
      # only include divide the valid_answer_sum with the number of valid answers&lt;br /&gt;
&lt;br /&gt;
      valid_answer_counter = 0&lt;br /&gt;
      question_score = 0.0&lt;br /&gt;
      question_answers.each do |ans|&lt;br /&gt;
        # calculate score per question&lt;br /&gt;
        unless ans.answer.nil?&lt;br /&gt;
          question_score += ans.answer&lt;br /&gt;
          valid_answer_counter += 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if valid_answer_counter &amp;gt; 0 and q_max_score &amp;gt; 0&lt;br /&gt;
        # convert the score in percentage&lt;br /&gt;
        question_score /= (valid_answer_counter * q_max_score)&lt;br /&gt;
        question_score = question_score.round(2) * 100&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      question_score&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Plan to test the response report page (/review_mapping/response_report?id={:assignmentID}) to make sure the new field (avg author feedback) exists&lt;br /&gt;
** Using rspec we will add a test case to ReviewMappingControllerSpec.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    context 'when type is FeedbackResponseMap' do&lt;br /&gt;
      context 'when assignment has author feedback feature' do&lt;br /&gt;
        it 'renders response_report page with average author feedback data' do&lt;br /&gt;
          allow(assignment).to receive(:varying_rubrics_by_round?).and_return(true)&lt;br /&gt;
          allow(FeedbackResponseMap).to receive(:feedback_response_report).with('1', 'FeedbackResponseMap')&lt;br /&gt;
                                                                          .and_return([participant, participant1], [1, 2], [3, 4], [])&lt;br /&gt;
          params = {&lt;br /&gt;
            id: 1,&lt;br /&gt;
            report: {type: 'FeedbackResponseMap'},&lt;br /&gt;
          }&lt;br /&gt;
          get :response_report, params&lt;br /&gt;
          expect(response).to render_template(:response_report)&lt;br /&gt;
          expect(response).to have(:avg_author_feedback)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
   end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Also, we plan to manually test the response report page to make sure the new field is aligning well in the UI in the expected place. We will attach the screenshot of the UI as the test result.&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
1) http://wiki.expertiza.ncsu.edu/index.php/Documentation_on_Database_Tables&lt;br /&gt;
&lt;br /&gt;
2) https://github.com/jainmohit1/expertiza&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018/E1876_Completion/Progress_view&amp;diff=119677</id>
		<title>CSC/ECE 517 Fall 2018/E1876 Completion/Progress view</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018/E1876_Completion/Progress_view&amp;diff=119677"/>
		<updated>2018-11-13T14:28:09Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: Adds initial section headers.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Problem Statement =&lt;br /&gt;
= Design =&lt;br /&gt;
= Test Plan =&lt;br /&gt;
= References =&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=118131</id>
		<title>CSC/ECE 517 Fall 2018- Project E1848: Writing unit tests for assignment team.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=118131"/>
		<updated>2018-11-02T20:46:47Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: /* Test Plan */ Add Courier font to method names in headings.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this project is to improve the coverage and quality of the unit tests for the assignment team model in Expertiza. This project comprised the program 3 assignment of CSC/ECE 517 in fall 2018 and is entitled &amp;quot;Project E1848: Writing unit tests for assignment_team.rb.&amp;quot; The source code for this project is in [https://github.com/expertiza/expertiza/pull/1228 pull request #1228] of the [https://github.com/expertiza Expertiza project] on [https://github.com/ GitHub].&lt;br /&gt;
&lt;br /&gt;
== Key Contributions ==&lt;br /&gt;
&lt;br /&gt;
Out of the 30 methods defined for the model AssignmentTeam.rb, test case was written for only one. Our contribution was to successfully add test cases for all remaining 29 methods.&lt;br /&gt;
&lt;br /&gt;
Hence, increasing the coverage from 5% to 100%.&lt;br /&gt;
&lt;br /&gt;
== The Class under Test ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
This class handles all functionalities for a team linked to an assignment. Some of the functionalities include, get a list of participants in the team, get the team name, team score for the given assignment, submissions for this team (files) and (hyperlinks) and topic picked by the team. Add/or remove participants from the team. It also checks for any reviews the team may have gotten for their work. Export all teams in a CSV file, import files from CSV to form teams.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
Our test plan was to test every method individually, i.e. write unit tests. We also tested multiple cases for each method. A description of all the methods in the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; model in assignment_team.rb and the RSpec unit tests we wrote for them is below.&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''includes?(participant)'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb checks if the '''participant''' passed as argument is a member of the team or not. For this, we utilize factorybot to build a user and a participant1 as follows-:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  let(:user1) { build(:student, id: 2) }&lt;br /&gt;
  let(:participant1) { build(:participant, id: 1) }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test cases checked for are-: &amp;lt;br&amp;gt;&lt;br /&gt;
1) when the team receives a user, that user is allowed to become a team participant. The method returns '''True''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has one participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes one participant&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        expect(team.includes?(participant1)).to eq true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) when the team receives a user with no arguments, that user is '''not''' allowed to become a team participant. The method returns '''False''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has no users&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([])&lt;br /&gt;
        expect(team.includes?(participant1)).to eq false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''parent_model '''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb always provides the name of the parent model which is '''Assignment'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;Assignment&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the name of the parent model&amp;quot; do&lt;br /&gt;
      expect(team.parent_model).to eq &amp;quot;Assignment&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''self.parent_model(id) '''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb takes in as argument id of the current '''Assignment''' for the team and returns an instance of the parent model.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the instance returned by this method for a given assignment id, matches the assignment or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the parent model&amp;quot; do&lt;br /&gt;
      allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
      expect(AssignmentTeam.parent_model(1)).to eq assignment&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''fullname '''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb print out the name for the current class instance. for this we first build an assignment team instance and assign it the name '''&amp;quot;abcd&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the assignment team has a name, and returns that same name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when the team has a name&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the name of the class&amp;quot; do&lt;br /&gt;
        team = build(:assignment_team, id: 1, name: &amp;quot;abcd&amp;quot;)&lt;br /&gt;
        expect(team.fullname).to eq &amp;quot;abcd&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''review_map_type'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb always provides the name of the review map type which is '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;ReviewResponseMap&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the review map type&amp;quot; do&lt;br /&gt;
      expect(team.review_map_type).to eq &amp;quot;ReviewResponseMap&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''self.prototype'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb implements the prototype pattern by returning a new instance of the class '''AssignmentTeam'''.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is a new instance of the class or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the AssignmentTeam&amp;quot; do&lt;br /&gt;
      expect(AssignmentTeam).to receive(:new).with(no_args)&lt;br /&gt;
      AssignmentTeam.prototype&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''assign_reviewer(reviewer)'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb assigns a reviewer to the team by returning a new instance of the class '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
The unit test assigns a reviewer to the team and creates an instance of ReviewResponseMap.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#assign_reviewer&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a reviewer is present&amp;quot; do&lt;br /&gt;
      it &amp;quot;assign the reviewer to the team&amp;quot; do&lt;br /&gt;
        allow(Assignment).to receive(:find).with(team.parent_id).and_return(assignment)&lt;br /&gt;
        allow(ReviewResponseMap).to receive(:create).&lt;br /&gt;
          with(reviewee_id: team.id, reviewer_id: participant1.id, reviewed_object_id: assignment.id).and_return(review_response_map)&lt;br /&gt;
        expect(team.assign_reviewer(participant1)).to eq(review_response_map)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''reviewed_by?(reviewer)'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb checks if the team has been reviewed by a reviewer.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the reviewer has reviewed the team. The test will find instances of ReviewResponseMaps belonging to the reviewer and the team, and will return true if such instances are present.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#reviewed_by?&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a team has a reviewer&amp;quot; do&lt;br /&gt;
      it &amp;quot;has been reviewed by this reviewer&amp;quot; do&lt;br /&gt;
        template = 'reviewee_id = ? &amp;amp;&amp;amp; reviewer_id = ? &amp;amp;&amp;amp; reviewed_object_id = ?'&lt;br /&gt;
        allow(ReviewResponseMap).to receive(:where).with(template, team.id, participant1.id, team.assignment.id).and_return([review_response_map])&lt;br /&gt;
        expect(team.reviewed_by?(participant1)).to eq true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''topic'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb return the id of the topic picked by the team for the assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test first stubs a topic for the given assignment, allows a SignedUpTeam object to receive that topic and AssignmentTeam id, and return the topic id to check if it matches with the topic id of the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context &amp;quot;when the team has picked a topic&amp;quot; do&lt;br /&gt;
    it &amp;quot;provides the topic id&amp;quot; do&lt;br /&gt;
      assignment = team.assignment&lt;br /&gt;
      allow(SignUpTopic).to receive(:find_by).with(assignment: assignment).and_return(topic)&lt;br /&gt;
      allow(SignedUpTeam).to receive_message_chain(:find_by, :try).with(team_id: team.id).with(:topic_id).and_return(topic.id)&lt;br /&gt;
      expect(team.topic).to eq(topic.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''has_submissions?'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
this function in assignment_team.rb is used to check if the team has submitted their work or not.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the team to receive submissions, by first receiving files as submission, then hyperlink as submission, and for each expects the the team's submission to be true when the function is called.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a team has submitted files&amp;quot; do&lt;br /&gt;
      it &amp;quot;has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_files, :any?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when the team has submitted hyperlink&amp;quot; do&lt;br /&gt;
      it &amp;quot;checks if the team has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_hyperlinks, :present?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    after(:each) do&lt;br /&gt;
      expect(team.has_submissions?).to be true&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''participants'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb returns a list of all participants in the team.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive two user instances and then adds these users as participants of the team. The test then expects the function to return a list of these two users as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has two participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;has those two participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
        expect(team.participants).to eq [participant1, participant2]&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive a user instance but does not add this user as participant of the team. The test then expects the function to return an empty list as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has a user but no participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(nil)&lt;br /&gt;
        expect(team.participants).to eq []&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''delete'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb deletes the AssignmentTeam by destroying each participant in the team and returns an instance of AssignmentTeam.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows two users to be added as team participants. The test checks if the team deleted matches the current team instance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;deletes the team&amp;quot; do&lt;br /&gt;
      allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
      expect(team.delete).to eq(team)&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''destroy'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb deletes all the reviews associated with the team.&lt;br /&gt;
&lt;br /&gt;
The unit test will delete every instance of '''ReviewResponseMaps''' associated with the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#destroy&amp;quot; do&lt;br /&gt;
    it &amp;quot;delete the reviews&amp;quot; do&lt;br /&gt;
      expect(team).to receive_message_chain(:review_response_maps, :each).with(no_args).with(no_args)&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''self.get_first_member(team_id)'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb returns the instance of the first participant of the team for the given team id.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the assignment to receive a user, add it as a participant and return the first participant in the team. The test expects the function to return an instance of this participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team id is present&amp;quot; do&lt;br /&gt;
      it &amp;quot;get first member of the  team&amp;quot; do&lt;br /&gt;
        allow(AssignmentTeam).to receive_message_chain(:find_by, :try, :try).with(id: team.id).with(:participant).with(:first).and_return(participant1)&lt;br /&gt;
        expect(AssignmentTeam.get_first_member(team.id)).to eq(participant1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''submitted_files(path = self.path)'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb returns a list of files belonging to a team for a given path.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is equal to the list of files that the team has submitted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#submitted_files&amp;quot; do&lt;br /&gt;
    context &amp;quot;given a path&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns submitted files&amp;quot; do&lt;br /&gt;
        files = [&amp;quot;file1.rb&amp;quot;]&lt;br /&gt;
        path = &amp;quot;assignment_path/5&amp;quot;&lt;br /&gt;
        allow(team).to receive(:path).with(path)&lt;br /&gt;
        allow(team).to receive(:files).with(path).and_return(files)&lt;br /&gt;
        expect(team.submitted_files(path)).to match_array(files)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''self.import(row, assignment_id, options)'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb imports a team if the team with the given id is present.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the team is not imported if the team with the given id is not already present.&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when an assignment team does not already exist with the same id&amp;quot; do&lt;br /&gt;
      it &amp;quot;cannot be imported&amp;quot; do&lt;br /&gt;
        assignment_id = 1&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: assignment_id).and_return(nil)&lt;br /&gt;
        error_message = &amp;quot;The assignment with the id \&amp;quot;&amp;quot; + assignment_id.to_s + &amp;quot;\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
        expect { AssignmentTeam.import([], assignment_id, []) }.&lt;br /&gt;
          to raise_error(ImportError, error_message)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the team is imported if the team with the given id is already present.&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when an assignment team with the same id already exists&amp;quot; do&lt;br /&gt;
      it &amp;quot;gets imported through Team.import&amp;quot; do&lt;br /&gt;
        row = []&lt;br /&gt;
        assignment_id = 1&lt;br /&gt;
        options = []&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: assignment_id).and_return(assignment)&lt;br /&gt;
        allow(Team).to receive(:import).with(row, assignment_id, options, instance_of(AssignmentTeam))&lt;br /&gt;
        expect(Team).to receive(:import).with(row, assignment_id, options, instance_of(AssignmentTeam))&lt;br /&gt;
        AssignmentTeam.import(row, assignment_id, options)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''self.export(csv, parent_id, options)'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb exports an instance of class '''AssignmentTeam'''&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is a new instance of the class '''AssignmentTeam''' or not.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;.export&amp;quot; do&lt;br /&gt;
    it &amp;quot;redirects to Team.export with a new AssignmentTeam object&amp;quot; do&lt;br /&gt;
      allow(Team).to receive(:export).with([], 1, [], instance_of(AssignmentTeam))&lt;br /&gt;
      expect(Team).to receive(:export).with([], 1, [], instance_of(AssignmentTeam))&lt;br /&gt;
      AssignmentTeam.export([], 1, [])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''copy(course_id)'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb copies the current assignment team and creates a new CourseTeam instance from the given team. It takes as parameter the id of the course assignment team has.&lt;br /&gt;
&lt;br /&gt;
The test grabs the course id from the assignment team and calls the function to check if a course team is successfully created or not. The function returns and empty array, otherwise returns '''nil''' if the course team is not created successfully.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;for given assignment team&amp;quot; do&lt;br /&gt;
      it &amp;quot;copies the assignment team to course team&amp;quot; do&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        course = assignment.course&lt;br /&gt;
        expect(team.copy(course.id)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''add_participant(assignment_id, user)'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb adds the user to the AssignmentTeam for the given assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test creates a user, and passes the user, assignment id for the team to the function and expects the result to be an instance of '''AssignmentParticipant''' meaning the user was successfully added as a participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is not a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;adds the user to the team&amp;quot; do&lt;br /&gt;
        user = build(:student, id: 10)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user)).to be_an_instance_of(AssignmentParticipant)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The unit test creates a user, adds him as a participant to the team, and passes the user, assignment id for the team to the function and expects the result to be '''nil''' as the user already exists as participant of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is already a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns without adding user to the team&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user1)).to eq(nil)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''scores(questions)'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb returns the total score of the team. This function calculates scores for a given hash of questions.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is equal to the score.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#scores&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a hash of question is given&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns the score received by the team&amp;quot; do&lt;br /&gt;
        questionnaire1 = build(:questionnaire, id: 1)&lt;br /&gt;
        questionnaire2 = build(:questionnaire, id: 2)&lt;br /&gt;
&lt;br /&gt;
        question1 = build(:question, id: 1, questionnaire: questionnaire1)&lt;br /&gt;
        question2 = build(:question, id: 2, questionnaire: questionnaire2)&lt;br /&gt;
        questions = {questionnaire1.symbol =&amp;gt; [question1], questionnaire2.symbol =&amp;gt; [question2]}&lt;br /&gt;
&lt;br /&gt;
        scores = {}&lt;br /&gt;
        scores[:team] = team&lt;br /&gt;
        scores[:questionnaire1] = {}&lt;br /&gt;
        scores[:questionnaire1][:assessments] = review_response_map&lt;br /&gt;
        scores[:questionnaire1][:scores] = 5&lt;br /&gt;
        scores[:questionnaire2] = {}&lt;br /&gt;
        scores[:questionnaire2][:assessments] = review_response_map&lt;br /&gt;
        scores[:questionnaire2][:scores] = 5&lt;br /&gt;
        scores[:total_score] = 10&lt;br /&gt;
&lt;br /&gt;
        allow(team.assignment).to receive(:questionnaires).with(no_args).and_return([questionnaire1, questionnaire2])&lt;br /&gt;
        allow(ReviewResponseMap).to receive(:where).with(reviewee_id: team.id).and_return(review_response_map)&lt;br /&gt;
        allow(Answer).to receive(:compute_scores).with(scores[:questionnaire1][:assessments], questions[:questionnaire1]).and_return(5)&lt;br /&gt;
        allow(Answer).to receive(:compute_scores).with(scores[:questionnaire2][:assessments], questions[:questionnaire2]).and_return(5)&lt;br /&gt;
        allow(questionnaire1).to receive(:symbol).with(no_args).and_return(:questionnaire1)&lt;br /&gt;
        allow(questionnaire2).to receive(:symbol).with(no_args).and_return(:questionnaire2)&lt;br /&gt;
        allow(team.assignment).to receive(:compute_total_score).with(scores.except(:total_score)).and_return(10)&lt;br /&gt;
        expect(team.scores(questions)).to eq(scores)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''files(directory)'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This method in assignment_team.rb successfully returns a list of files in any given directory path, not just the assignment teams directory path.&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned contains a specific file which is known to be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/models&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned does not contain a specific file which is known to not be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is not present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is not present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/controllers&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).not_to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''submit_hyperlink(hyperlink)'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb submits the hyperlink for the team if it is valid or not empty.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the hyperlink is empty and raises an error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a hyperlink is empty&amp;quot; do&lt;br /&gt;
      it &amp;quot;causes an exception to be raised&amp;quot; do&lt;br /&gt;
        expect { team.submit_hyperlink(&amp;quot;&amp;quot;) }.to raise_error(&amp;quot;The hyperlink cannot be empty!&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the hyperlink is invalid and raises a 404 error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a hyperlink is invalid&amp;quot; do&lt;br /&gt;
      it &amp;quot;causes an exception to be raised with the proper HTTP status code&amp;quot; do&lt;br /&gt;
        invalid_hyperlink = &amp;quot;https://expertiza.ncsu.edu/not_a_valid_path&amp;quot;&lt;br /&gt;
        allow(Net::HTTP).to receive(:get_response).and_return(&amp;quot;404&amp;quot;)&lt;br /&gt;
        expect { team.submit_hyperlink(invalid_hyperlink) }.to raise_error(&amp;quot;HTTP status code: 404&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the the hyperlink has been submitted or not.&lt;br /&gt;
    context &amp;quot;when a valid hyperlink not in a certain improper format is submitted&amp;quot; do&lt;br /&gt;
      it &amp;quot;it is fixed and is saved to the database&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([&amp;quot;https://expertiza.ncsu.edu&amp;quot;])&lt;br /&gt;
        allow(team).to receive(:submitted_hyperlinks=)&lt;br /&gt;
        allow(team).to receive(:save)&lt;br /&gt;
        allow(Net::HTTP).to receive(:get_response).and_return(&amp;quot;0&amp;quot;)&lt;br /&gt;
        allow(YAML).to receive(:dump).with([&amp;quot;https://expertiza.ncsu.edu&amp;quot;, &amp;quot;www.ncsu.edu&amp;quot;])&lt;br /&gt;
        expect(team).to receive(:submitted_hyperlinks=)&lt;br /&gt;
        expect(team).to receive(:save)&lt;br /&gt;
        expect(YAML).to receive(:dump).with([&amp;quot;https://expertiza.ncsu.edu&amp;quot;, &amp;quot;http://www.ncsu.edu&amp;quot;])&lt;br /&gt;
        team.submit_hyperlink(&amp;quot;www.ncsu.edu  &amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''remove_hyperlink(hyperlink_to_delete)'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb removes the hyperlink submitted by the team.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the hyperlink has been deleted or not.&lt;br /&gt;
  describe &amp;quot;#remove_hyperlink&amp;quot; do&lt;br /&gt;
    context &amp;quot;when the hyperlink is in the assignment team's hyperlinks&amp;quot; do&lt;br /&gt;
      it &amp;quot;is removed from the team's list of hyperlinks&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([&amp;quot;https://expertiza.ncsu.edu&amp;quot;, &amp;quot;https://www.ncsu.edu&amp;quot;])&lt;br /&gt;
        expect(team).to receive(:submitted_hyperlinks=)&lt;br /&gt;
        expect(team).to receive(:save)&lt;br /&gt;
        expect(YAML).to receive(:dump).with([&amp;quot;https://expertiza.ncsu.edu&amp;quot;])&lt;br /&gt;
        team.remove_hyperlink(&amp;quot;https://www.ncsu.edu&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''self.team(participant)'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb returns the AssingmentTeam object that the given participant belongs to.&lt;br /&gt;
&lt;br /&gt;
The unit test first builds a user and assigns that user as a participant1 of the team. Then allows that participant to be added as a team user and finally search the team for the given team user and expect the team for participant1 to be equal to the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when there is a participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the team for participant&amp;quot; do&lt;br /&gt;
        teamuser = build(:team_user, id: 1, team_id: team.id, user_id: user1.id)&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(TeamsUser).to receive(:where).with(user_id: participant1.user_id).and_return([teamuser])&lt;br /&gt;
        allow(Team).to receive(:find).with(teamuser.team_id).and_return(team)&lt;br /&gt;
        expect(AssignmentTeam.team(participant1)).to eq(team)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''self.export_fields(options)'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb exports the fields for a given set of options. It always returns a list containing [&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;] if the given set of options have a team name set to true.&lt;br /&gt;
&lt;br /&gt;
The unit test expects the method to return a static list of strings for the team passed as options, with the team having a name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team has name&amp;quot; do&lt;br /&gt;
      it &amp;quot;exports the fields&amp;quot; do&lt;br /&gt;
        expect(AssignmentTeam.export_fields(team)).to eq([&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''self.remove_team_by_id(id)'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb removes team by using its id.&lt;br /&gt;
&lt;br /&gt;
The unit test deletes the team by using its id and checks if return value is the instance of class '''AssignmentTeam'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;.remove_team_by_id&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a team has an id&amp;quot; do&lt;br /&gt;
      it &amp;quot;delete the team by id&amp;quot; do&lt;br /&gt;
        allow(AssignmentTeam).to receive(:find).with(team.id).and_return(team)&lt;br /&gt;
        expect(AssignmentTeam.remove_team_by_id(team.id)).to eq(team)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''path'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb returns a path to the directory where the team has submitted their files.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is equal to the path belonging to the team's submission.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#path&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns the path&amp;quot; do&lt;br /&gt;
      allow(team).to receive_message_chain(:assignment, :path).and_return(&amp;quot;assignment_path&amp;quot;)&lt;br /&gt;
      allow(team).to receive(:directory_num).and_return(5)&lt;br /&gt;
      expect(team.path).to eq &amp;quot;assignment_path/5&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''set_student_directory_num'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb sets the directory number for the team.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the directory number for the team has been set. The test will check if the return value is equal to true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#set_student_directory_num&amp;quot; do&lt;br /&gt;
    it &amp;quot;sets the directory for the team&amp;quot; do&lt;br /&gt;
      team = build(:assignment_team, id: 1, parent_id: 1, directory_num: -1)&lt;br /&gt;
      max_num = 0&lt;br /&gt;
      allow(AssignmentTeam).to receive_message_chain(:where, :order, :first, :directory_num).&lt;br /&gt;
        with(parent_id: team.parent_id).with(:directory_num, :desc).with(no_args).with(no_args).and_return(max_num)&lt;br /&gt;
      expect(team.set_student_directory_num).to be true&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''received_any_peer_review?'''&amp;lt;/span&amp;gt; Method ===&lt;br /&gt;
This function in assignment_team.rb checks if the team has received any peer reviews.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if any instance of '''ReviewResponseMap''' is present for the team.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#received_any_peer_review?&amp;quot; do&lt;br /&gt;
    it &amp;quot;checks if the team has received any reviews&amp;quot; do&lt;br /&gt;
      allow(ResponseMap).to receive_message_chain(:where, :any?).with(reviewee_id: team.id, reviewed_object_id: team.parent_id).with(no_args).and_return(true)&lt;br /&gt;
      expect(team.received_any_peer_review?).to be true&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test Design ==&lt;br /&gt;
We used multiple RSpec-specific and general industry best practices for testing in our unit tests. A description of our use of some of these techniques follows.&lt;br /&gt;
&lt;br /&gt;
=== Test Structure ===&lt;br /&gt;
We exploited &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''describe'''&amp;lt;/span&amp;gt; blocks in RSpec to give our unit tests a readable structure. We had &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''describe'''&amp;lt;/span&amp;gt; blocks for each method of &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt;. In these blocks, we used RSpec &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''context'''&amp;lt;/span&amp;gt; blocks where appropriate and examples to identify and test the different cases in the source code.&lt;br /&gt;
&lt;br /&gt;
=== Stubs for Isolating the UUT ===&lt;br /&gt;
In order to isolate the unit under test (UUT), i.e. the current method under test, we employed RSpec stubs. We stubbed out database calls and methods that triggered them in order to improve the run time of the unit tests, and we also stubbed out some outgoing command and query messages in order to test only the current method under test.&lt;br /&gt;
&lt;br /&gt;
=== DRY Testing Practices ===&lt;br /&gt;
We exploited factories and the RSpec helper method &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''let'''&amp;lt;/span&amp;gt; to make our unit tests shorter, more readable, and more maintainable, or, in essence, DRYer. Using the FactoryBot factories in '''factories.rb''' allowed us to use real Expertiza objects in our unit tests. We used the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''FactoryBot.build'''&amp;lt;/span&amp;gt; method to make our objects in order to avoid the run time penalty of saving (and this later having to retrieve) objects from the database. We used the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''let'''&amp;lt;/span&amp;gt; method with the factory as in the example below to make lazy-allocated objects which are cached throughout each example, improving run time.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;let(:team) { build(:assignment_team, id: 1, parent_id: 1) }&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whenever &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''team'''&amp;lt;/span&amp;gt; is called in an example, it returns the same value, i.e. the same object, which essentially allows tests that need it to have access to the same object without the need for allocating it as a class variable or instance variable for all of the tests or some of the tests. We placed these statements outside the scope of our unit test examples so the same objects could be used throughout all of them, DRYing out the test code.&lt;br /&gt;
&lt;br /&gt;
== Testing Framework ==&lt;br /&gt;
&lt;br /&gt;
=== RSpec Introduction ===&lt;br /&gt;
[http://rspec.info/ RSPEC] is a testing framework for Ruby for behavior-driven development (BDD) licensed under MIT. It is inspired by JBehave and contains fully integrated JMock based framework which has a very rich and powerful DSL (domain-specific language) which resembles a natural language specification. Composed of multiple libraries structured to work together, RSpec provides encapsulated testing via the describe block to specify the behavior of the class and the context for the unit test case.&lt;br /&gt;
&lt;br /&gt;
=== Why RSpec? ===&lt;br /&gt;
RSpec is easy to learn and implement and can be used with other testing tools like Cucumber and Minitest independently. It is extremely powerful for testing states with complicated setup and also helps in tearing down complex code to access the objects required for testing RSpec semantics encourage agile thinking and practice and it structures the tests in a more intuitive way.&lt;br /&gt;
&lt;br /&gt;
== Bugs Fixed ==&lt;br /&gt;
During testing of the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; model, we found two bugs, one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt; and one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''http://'''&amp;lt;/span&amp;gt; was ''appended'' to hyperlink strings without this tag or&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''https://'''&amp;lt;/span&amp;gt; at the start of them, rather than ''prepended''. We fixed this error in our pull request. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''id'''&amp;lt;/span&amp;gt;, an undefined parameter, was referenced while raising an exception, and we updated it to &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''assignment_id'''&amp;lt;/span&amp;gt;, which was the actual name of the parameter passed to the method.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
The model has a total of 237 lines, out of which 127 were relevant lines.&lt;br /&gt;
We achieved 100% coverage with avg hits per line at 2.3 (the number of times each specific line was run during the test suite)&lt;br /&gt;
&lt;br /&gt;
[[File:Coverage_header.png]]&lt;br /&gt;
[[File:Coverage_line.png]]&lt;br /&gt;
&lt;br /&gt;
== Future Work ==&lt;br /&gt;
&lt;br /&gt;
DRY principle could be cleaned up a little more. Sometimes it became necessary to use the '''let''' or '''build''' helper methods in each unit test. They may all be consolidated at the beginning. &amp;lt;br&amp;gt;&lt;br /&gt;
Some more edge cases could be thought of for each method, and tests written for those. Although, we have tried to cover as many as possible. &amp;lt;br&amp;gt;&lt;br /&gt;
Additionally, in the future, the code may also be refactored with a more efficient tool. &amp;lt;br&amp;gt;&lt;br /&gt;
Test coverage through quality tests consistently added throughout the development of the Expertiza project should be the future work of the project. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1. [http://expertiza.ncsu.edu Expertiza] &amp;lt;br&amp;gt;&lt;br /&gt;
2. [http://wiki.expertiza.ncsu.edu/index.php/Main_Page#Expertiza Expertiza Wikipedia ]&amp;lt;br&amp;gt;&lt;br /&gt;
3. [https://github.com/expertiza/expertiza Expertiza Github Repository]&amp;lt;br&amp;gt;&lt;br /&gt;
4. [https://relishapp.com/rspec RSpec - Relish]&amp;lt;br&amp;gt;&lt;br /&gt;
5. [https://sites.google.com/site/longlastingsoftware Engineering Software as a Service]&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=118126</id>
		<title>CSC/ECE 517 Fall 2018- Project E1848: Writing unit tests for assignment team.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=118126"/>
		<updated>2018-11-02T20:44:09Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: /* Test Plan */  Edit headings.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this project is to improve the coverage and quality of the unit tests for the assignment team model in Expertiza. This project comprised the program 3 assignment of CSC/ECE 517 in fall 2018 and is entitled &amp;quot;Project E1848: Writing unit tests for assignment_team.rb.&amp;quot; The source code for this project is in [https://github.com/expertiza/expertiza/pull/1228 pull request #1228] of the [https://github.com/expertiza Expertiza project] on [https://github.com/ GitHub].&lt;br /&gt;
&lt;br /&gt;
== Key Contributions ==&lt;br /&gt;
&lt;br /&gt;
Out of the 30 methods defined for the model AssignmentTeam.rb, test case was written for only one. Our contribution was to successfully add test cases for all remaining 29 methods.&lt;br /&gt;
&lt;br /&gt;
Hence, increasing the coverage from 5% to 100%.&lt;br /&gt;
&lt;br /&gt;
== The Class under Test ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
This class handles all functionalities for a team linked to an assignment. Some of the functionalities include, get a list of participants in the team, get the team name, team score for the given assignment, submissions for this team (files) and (hyperlinks) and topic picked by the team. Add/or remove participants from the team. It also checks for any reviews the team may have gotten for their work. Export all teams in a CSV file, import files from CSV to form teams.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
Our test plan was to test every method individually, i.e. write unit tests. We also tested multiple cases for each method. A description of all the methods in the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; model in assignment_team.rb and the RSpec unit tests we wrote for them is below.&lt;br /&gt;
&lt;br /&gt;
=== The includes?(participant) Method ===&lt;br /&gt;
This function in assignment_team.rb checks if the '''participant''' passed as argument is a member of the team or not. For this, we utilize factorybot to build a user and a participant1 as follows-:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  let(:user1) { build(:student, id: 2) }&lt;br /&gt;
  let(:participant1) { build(:participant, id: 1) }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test cases checked for are-: &amp;lt;br&amp;gt;&lt;br /&gt;
1) when the team receives a user, that user is allowed to become a team participant. The method returns '''True''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has one participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes one participant&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        expect(team.includes?(participant1)).to eq true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) when the team receives a user with no arguments, that user is '''not''' allowed to become a team participant. The method returns '''False''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has no users&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([])&lt;br /&gt;
        expect(team.includes?(participant1)).to eq false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The parent_model  Method ===&lt;br /&gt;
This function in assignment_team.rb always provides the name of the parent model which is '''Assignment'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;Assignment&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the name of the parent model&amp;quot; do&lt;br /&gt;
      expect(team.parent_model).to eq &amp;quot;Assignment&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The self.parent_model(id)  Method ===&lt;br /&gt;
This function in assignment_team.rb takes in as argument id of the current '''Assignment''' for the team and returns an instance of the parent model.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the instance returned by this method for a given assignment id, matches the assignment or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the parent model&amp;quot; do&lt;br /&gt;
      allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
      expect(AssignmentTeam.parent_model(1)).to eq assignment&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The fullname  Method ===&lt;br /&gt;
This function in assignment_team.rb print out the name for the current class instance. for this we first build an assignment team instance and assign it the name '''&amp;quot;abcd&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the assignment team has a name, and returns that same name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when the team has a name&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the name of the class&amp;quot; do&lt;br /&gt;
        team = build(:assignment_team, id: 1, name: &amp;quot;abcd&amp;quot;)&lt;br /&gt;
        expect(team.fullname).to eq &amp;quot;abcd&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The review_map_type Method ===&lt;br /&gt;
This function in assignment_team.rb always provides the name of the review map type which is '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;ReviewResponseMap&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the review map type&amp;quot; do&lt;br /&gt;
      expect(team.review_map_type).to eq &amp;quot;ReviewResponseMap&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The self.prototype Method ===&lt;br /&gt;
This function in assignment_team.rb implements the prototype pattern by returning a new instance of the class '''AssignmentTeam'''.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is a new instance of the class or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the AssignmentTeam&amp;quot; do&lt;br /&gt;
      expect(AssignmentTeam).to receive(:new).with(no_args)&lt;br /&gt;
      AssignmentTeam.prototype&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The assign_reviewer(reviewer) Method ===&lt;br /&gt;
This function in assignment_team.rb assigns a reviewer to the team by returning a new instance of the class '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
The unit test assigns a reviewer to the team and creates an instance of ReviewResponseMap.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#assign_reviewer&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a reviewer is present&amp;quot; do&lt;br /&gt;
      it &amp;quot;assign the reviewer to the team&amp;quot; do&lt;br /&gt;
        allow(Assignment).to receive(:find).with(team.parent_id).and_return(assignment)&lt;br /&gt;
        allow(ReviewResponseMap).to receive(:create).&lt;br /&gt;
          with(reviewee_id: team.id, reviewer_id: participant1.id, reviewed_object_id: assignment.id).and_return(review_response_map)&lt;br /&gt;
        expect(team.assign_reviewer(participant1)).to eq(review_response_map)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The reviewed_by?(reviewer) Method ===&lt;br /&gt;
This function in assignment_team.rb checks if the team has been reviewed by a reviewer.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the reviewer has reviewed the team. The test will find instances of ReviewResponseMaps belonging to the reviewer and the team, and will return true if such instances are present.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#reviewed_by?&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a team has a reviewer&amp;quot; do&lt;br /&gt;
      it &amp;quot;has been reviewed by this reviewer&amp;quot; do&lt;br /&gt;
        template = 'reviewee_id = ? &amp;amp;&amp;amp; reviewer_id = ? &amp;amp;&amp;amp; reviewed_object_id = ?'&lt;br /&gt;
        allow(ReviewResponseMap).to receive(:where).with(template, team.id, participant1.id, team.assignment.id).and_return([review_response_map])&lt;br /&gt;
        expect(team.reviewed_by?(participant1)).to eq true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The topic Method ===&lt;br /&gt;
This function in assignment_team.rb return the id of the topic picked by the team for the assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test first stubs a topic for the given assignment, allows a SignedUpTeam object to receive that topic and AssignmentTeam id, and return the topic id to check if it matches with the topic id of the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context &amp;quot;when the team has picked a topic&amp;quot; do&lt;br /&gt;
    it &amp;quot;provides the topic id&amp;quot; do&lt;br /&gt;
      assignment = team.assignment&lt;br /&gt;
      allow(SignUpTopic).to receive(:find_by).with(assignment: assignment).and_return(topic)&lt;br /&gt;
      allow(SignedUpTeam).to receive_message_chain(:find_by, :try).with(team_id: team.id).with(:topic_id).and_return(topic.id)&lt;br /&gt;
      expect(team.topic).to eq(topic.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The has_submissions? Method ===&lt;br /&gt;
this function in assignment_team.rb is used to check if the team has submitted their work or not.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the team to receive submissions, by first receiving files as submission, then hyperlink as submission, and for each expects the the team's submission to be true when the function is called.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a team has submitted files&amp;quot; do&lt;br /&gt;
      it &amp;quot;has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_files, :any?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when the team has submitted hyperlink&amp;quot; do&lt;br /&gt;
      it &amp;quot;checks if the team has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_hyperlinks, :present?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    after(:each) do&lt;br /&gt;
      expect(team.has_submissions?).to be true&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The participants Method ===&lt;br /&gt;
This function in assignment_team.rb returns a list of all participants in the team.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive two user instances and then adds these users as participants of the team. The test then expects the function to return a list of these two users as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has two participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;has those two participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
        expect(team.participants).to eq [participant1, participant2]&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive a user instance but does not add this user as participant of the team. The test then expects the function to return an empty list as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has a user but no participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(nil)&lt;br /&gt;
        expect(team.participants).to eq []&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The delete Method ===&lt;br /&gt;
This function in assignment_team.rb deletes the AssignmentTeam by destroying each participant in the team and returns an instance of AssignmentTeam.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows two users to be added as team participants. The test checks if the team deleted matches the current team instance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;deletes the team&amp;quot; do&lt;br /&gt;
      allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
      expect(team.delete).to eq(team)&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The destroy Method ===&lt;br /&gt;
This function in assignment_team.rb deletes all the reviews associated with the team.&lt;br /&gt;
&lt;br /&gt;
The unit test will delete every instance of '''ReviewResponseMaps''' associated with the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#destroy&amp;quot; do&lt;br /&gt;
    it &amp;quot;delete the reviews&amp;quot; do&lt;br /&gt;
      expect(team).to receive_message_chain(:review_response_maps, :each).with(no_args).with(no_args)&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The self.get_first_member(team_id) Method ===&lt;br /&gt;
This function in assignment_team.rb returns the instance of the first participant of the team for the given team id.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the assignment to receive a user, add it as a participant and return the first participant in the team. The test expects the function to return an instance of this participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team id is present&amp;quot; do&lt;br /&gt;
      it &amp;quot;get first member of the  team&amp;quot; do&lt;br /&gt;
        allow(AssignmentTeam).to receive_message_chain(:find_by, :try, :try).with(id: team.id).with(:participant).with(:first).and_return(participant1)&lt;br /&gt;
        expect(AssignmentTeam.get_first_member(team.id)).to eq(participant1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The submitted_files(path = self.path) Method ===&lt;br /&gt;
This function in assignment_team.rb returns a list of files belonging to a team for a given path.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is equal to the list of files that the team has submitted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#submitted_files&amp;quot; do&lt;br /&gt;
    context &amp;quot;given a path&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns submitted files&amp;quot; do&lt;br /&gt;
        files = [&amp;quot;file1.rb&amp;quot;]&lt;br /&gt;
        path = &amp;quot;assignment_path/5&amp;quot;&lt;br /&gt;
        allow(team).to receive(:path).with(path)&lt;br /&gt;
        allow(team).to receive(:files).with(path).and_return(files)&lt;br /&gt;
        expect(team.submitted_files(path)).to match_array(files)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The self.import(row, assignment_id, options) Method ===&lt;br /&gt;
This function in assignment_team.rb imports a team if the team with the given id is present.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the team is not imported if the team with the given id is not already present.&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when an assignment team does not already exist with the same id&amp;quot; do&lt;br /&gt;
      it &amp;quot;cannot be imported&amp;quot; do&lt;br /&gt;
        assignment_id = 1&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: assignment_id).and_return(nil)&lt;br /&gt;
        error_message = &amp;quot;The assignment with the id \&amp;quot;&amp;quot; + assignment_id.to_s + &amp;quot;\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
        expect { AssignmentTeam.import([], assignment_id, []) }.&lt;br /&gt;
          to raise_error(ImportError, error_message)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the team is imported if the team with the given id is already present.&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when an assignment team with the same id already exists&amp;quot; do&lt;br /&gt;
      it &amp;quot;gets imported through Team.import&amp;quot; do&lt;br /&gt;
        row = []&lt;br /&gt;
        assignment_id = 1&lt;br /&gt;
        options = []&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: assignment_id).and_return(assignment)&lt;br /&gt;
        allow(Team).to receive(:import).with(row, assignment_id, options, instance_of(AssignmentTeam))&lt;br /&gt;
        expect(Team).to receive(:import).with(row, assignment_id, options, instance_of(AssignmentTeam))&lt;br /&gt;
        AssignmentTeam.import(row, assignment_id, options)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
=== The self.export(csv, parent_id, options) Method ===&lt;br /&gt;
This function in assignment_team.rb exports an instance of class '''AssignmentTeam'''&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is a new instance of the class '''AssignmentTeam''' or not.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;.export&amp;quot; do&lt;br /&gt;
    it &amp;quot;redirects to Team.export with a new AssignmentTeam object&amp;quot; do&lt;br /&gt;
      allow(Team).to receive(:export).with([], 1, [], instance_of(AssignmentTeam))&lt;br /&gt;
      expect(Team).to receive(:export).with([], 1, [], instance_of(AssignmentTeam))&lt;br /&gt;
      AssignmentTeam.export([], 1, [])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The copy(course_id) Method ===&lt;br /&gt;
This function in assignment_team.rb copies the current assignment team and creates a new CourseTeam instance from the given team. It takes as parameter the id of the course assignment team has.&lt;br /&gt;
&lt;br /&gt;
The test grabs the course id from the assignment team and calls the function to check if a course team is successfully created or not. The function returns and empty array, otherwise returns '''nil''' if the course team is not created successfully.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;for given assignment team&amp;quot; do&lt;br /&gt;
      it &amp;quot;copies the assignment team to course team&amp;quot; do&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        course = assignment.course&lt;br /&gt;
        expect(team.copy(course.id)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The add_participant(assignment_id, user) Method ===&lt;br /&gt;
This function in assignment_team.rb adds the user to the AssignmentTeam for the given assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test creates a user, and passes the user, assignment id for the team to the function and expects the result to be an instance of '''AssignmentParticipant''' meaning the user was successfully added as a participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is not a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;adds the user to the team&amp;quot; do&lt;br /&gt;
        user = build(:student, id: 10)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user)).to be_an_instance_of(AssignmentParticipant)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The unit test creates a user, adds him as a participant to the team, and passes the user, assignment id for the team to the function and expects the result to be '''nil''' as the user already exists as participant of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is already a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns without adding user to the team&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user1)).to eq(nil)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The scores(questions) Method ===&lt;br /&gt;
This function in assignment_team.rb returns the total score of the team. This function calculates scores for a given hash of questions.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is equal to the score.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#scores&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a hash of question is given&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns the score received by the team&amp;quot; do&lt;br /&gt;
        questionnaire1 = build(:questionnaire, id: 1)&lt;br /&gt;
        questionnaire2 = build(:questionnaire, id: 2)&lt;br /&gt;
&lt;br /&gt;
        question1 = build(:question, id: 1, questionnaire: questionnaire1)&lt;br /&gt;
        question2 = build(:question, id: 2, questionnaire: questionnaire2)&lt;br /&gt;
        questions = {questionnaire1.symbol =&amp;gt; [question1], questionnaire2.symbol =&amp;gt; [question2]}&lt;br /&gt;
&lt;br /&gt;
        scores = {}&lt;br /&gt;
        scores[:team] = team&lt;br /&gt;
        scores[:questionnaire1] = {}&lt;br /&gt;
        scores[:questionnaire1][:assessments] = review_response_map&lt;br /&gt;
        scores[:questionnaire1][:scores] = 5&lt;br /&gt;
        scores[:questionnaire2] = {}&lt;br /&gt;
        scores[:questionnaire2][:assessments] = review_response_map&lt;br /&gt;
        scores[:questionnaire2][:scores] = 5&lt;br /&gt;
        scores[:total_score] = 10&lt;br /&gt;
&lt;br /&gt;
        allow(team.assignment).to receive(:questionnaires).with(no_args).and_return([questionnaire1, questionnaire2])&lt;br /&gt;
        allow(ReviewResponseMap).to receive(:where).with(reviewee_id: team.id).and_return(review_response_map)&lt;br /&gt;
        allow(Answer).to receive(:compute_scores).with(scores[:questionnaire1][:assessments], questions[:questionnaire1]).and_return(5)&lt;br /&gt;
        allow(Answer).to receive(:compute_scores).with(scores[:questionnaire2][:assessments], questions[:questionnaire2]).and_return(5)&lt;br /&gt;
        allow(questionnaire1).to receive(:symbol).with(no_args).and_return(:questionnaire1)&lt;br /&gt;
        allow(questionnaire2).to receive(:symbol).with(no_args).and_return(:questionnaire2)&lt;br /&gt;
        allow(team.assignment).to receive(:compute_total_score).with(scores.except(:total_score)).and_return(10)&lt;br /&gt;
        expect(team.scores(questions)).to eq(scores)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The files(directory) Method ===&lt;br /&gt;
This method in assignment_team.rb successfully returns a list of files in any given directory path, not just the assignment teams directory path.&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned contains a specific file which is known to be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/models&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned does not contain a specific file which is known to not be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is not present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is not present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/controllers&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).not_to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The submit_hyperlink(hyperlink) Method ===&lt;br /&gt;
This function in assignment_team.rb submits the hyperlink for the team if it is valid or not empty.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the hyperlink is empty and raises an error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a hyperlink is empty&amp;quot; do&lt;br /&gt;
      it &amp;quot;causes an exception to be raised&amp;quot; do&lt;br /&gt;
        expect { team.submit_hyperlink(&amp;quot;&amp;quot;) }.to raise_error(&amp;quot;The hyperlink cannot be empty!&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the hyperlink is invalid and raises a 404 error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a hyperlink is invalid&amp;quot; do&lt;br /&gt;
      it &amp;quot;causes an exception to be raised with the proper HTTP status code&amp;quot; do&lt;br /&gt;
        invalid_hyperlink = &amp;quot;https://expertiza.ncsu.edu/not_a_valid_path&amp;quot;&lt;br /&gt;
        allow(Net::HTTP).to receive(:get_response).and_return(&amp;quot;404&amp;quot;)&lt;br /&gt;
        expect { team.submit_hyperlink(invalid_hyperlink) }.to raise_error(&amp;quot;HTTP status code: 404&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the the hyperlink has been submitted or not.&lt;br /&gt;
    context &amp;quot;when a valid hyperlink not in a certain improper format is submitted&amp;quot; do&lt;br /&gt;
      it &amp;quot;it is fixed and is saved to the database&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([&amp;quot;https://expertiza.ncsu.edu&amp;quot;])&lt;br /&gt;
        allow(team).to receive(:submitted_hyperlinks=)&lt;br /&gt;
        allow(team).to receive(:save)&lt;br /&gt;
        allow(Net::HTTP).to receive(:get_response).and_return(&amp;quot;0&amp;quot;)&lt;br /&gt;
        allow(YAML).to receive(:dump).with([&amp;quot;https://expertiza.ncsu.edu&amp;quot;, &amp;quot;www.ncsu.edu&amp;quot;])&lt;br /&gt;
        expect(team).to receive(:submitted_hyperlinks=)&lt;br /&gt;
        expect(team).to receive(:save)&lt;br /&gt;
        expect(YAML).to receive(:dump).with([&amp;quot;https://expertiza.ncsu.edu&amp;quot;, &amp;quot;http://www.ncsu.edu&amp;quot;])&lt;br /&gt;
        team.submit_hyperlink(&amp;quot;www.ncsu.edu  &amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The remove_hyperlink(hyperlink_to_delete) Method ===&lt;br /&gt;
This function in assignment_team.rb removes the hyperlink submitted by the team.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the hyperlink has been deleted or not.&lt;br /&gt;
  describe &amp;quot;#remove_hyperlink&amp;quot; do&lt;br /&gt;
    context &amp;quot;when the hyperlink is in the assignment team's hyperlinks&amp;quot; do&lt;br /&gt;
      it &amp;quot;is removed from the team's list of hyperlinks&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([&amp;quot;https://expertiza.ncsu.edu&amp;quot;, &amp;quot;https://www.ncsu.edu&amp;quot;])&lt;br /&gt;
        expect(team).to receive(:submitted_hyperlinks=)&lt;br /&gt;
        expect(team).to receive(:save)&lt;br /&gt;
        expect(YAML).to receive(:dump).with([&amp;quot;https://expertiza.ncsu.edu&amp;quot;])&lt;br /&gt;
        team.remove_hyperlink(&amp;quot;https://www.ncsu.edu&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== The self.team(participant) Method ===&lt;br /&gt;
This function in assignment_team.rb returns the AssingmentTeam object that the given participant belongs to.&lt;br /&gt;
&lt;br /&gt;
The unit test first builds a user and assigns that user as a participant1 of the team. Then allows that participant to be added as a team user and finally search the team for the given team user and expect the team for participant1 to be equal to the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when there is a participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the team for participant&amp;quot; do&lt;br /&gt;
        teamuser = build(:team_user, id: 1, team_id: team.id, user_id: user1.id)&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(TeamsUser).to receive(:where).with(user_id: participant1.user_id).and_return([teamuser])&lt;br /&gt;
        allow(Team).to receive(:find).with(teamuser.team_id).and_return(team)&lt;br /&gt;
        expect(AssignmentTeam.team(participant1)).to eq(team)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The self.export_fields(options) Method ===&lt;br /&gt;
This function in assignment_team.rb exports the fields for a given set of options. It always returns a list containing [&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;] if the given set of options have a team name set to true.&lt;br /&gt;
&lt;br /&gt;
The unit test expects the method to return a static list of strings for the team passed as options, with the team having a name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team has name&amp;quot; do&lt;br /&gt;
      it &amp;quot;exports the fields&amp;quot; do&lt;br /&gt;
        expect(AssignmentTeam.export_fields(team)).to eq([&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The self.remove_team_by_id(id) Method ===&lt;br /&gt;
This function in assignment_team.rb removes team by using its id.&lt;br /&gt;
&lt;br /&gt;
The unit test deletes the team by using its id and checks if return value is the instance of class '''AssignmentTeam'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;.remove_team_by_id&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a team has an id&amp;quot; do&lt;br /&gt;
      it &amp;quot;delete the team by id&amp;quot; do&lt;br /&gt;
        allow(AssignmentTeam).to receive(:find).with(team.id).and_return(team)&lt;br /&gt;
        expect(AssignmentTeam.remove_team_by_id(team.id)).to eq(team)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The path Method ===&lt;br /&gt;
This function in assignment_team.rb returns a path to the directory where the team has submitted their files.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is equal to the path belonging to the team's submission.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#path&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns the path&amp;quot; do&lt;br /&gt;
      allow(team).to receive_message_chain(:assignment, :path).and_return(&amp;quot;assignment_path&amp;quot;)&lt;br /&gt;
      allow(team).to receive(:directory_num).and_return(5)&lt;br /&gt;
      expect(team.path).to eq &amp;quot;assignment_path/5&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The set_student_directory_num Method ===&lt;br /&gt;
This function in assignment_team.rb sets the directory number for the team.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the directory number for the team has been set. The test will check if the return value is equal to true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#set_student_directory_num&amp;quot; do&lt;br /&gt;
    it &amp;quot;sets the directory for the team&amp;quot; do&lt;br /&gt;
      team = build(:assignment_team, id: 1, parent_id: 1, directory_num: -1)&lt;br /&gt;
      max_num = 0&lt;br /&gt;
      allow(AssignmentTeam).to receive_message_chain(:where, :order, :first, :directory_num).&lt;br /&gt;
        with(parent_id: team.parent_id).with(:directory_num, :desc).with(no_args).with(no_args).and_return(max_num)&lt;br /&gt;
      expect(team.set_student_directory_num).to be true&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The received_any_peer_review? Method ===&lt;br /&gt;
This function in assignment_team.rb checks if the team has received any peer reviews.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if any instance of '''ReviewResponseMap''' is present for the team.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#received_any_peer_review?&amp;quot; do&lt;br /&gt;
    it &amp;quot;checks if the team has received any reviews&amp;quot; do&lt;br /&gt;
      allow(ResponseMap).to receive_message_chain(:where, :any?).with(reviewee_id: team.id, reviewed_object_id: team.parent_id).with(no_args).and_return(true)&lt;br /&gt;
      expect(team.received_any_peer_review?).to be true&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test Design ==&lt;br /&gt;
We used multiple RSpec-specific and general industry best practices for testing in our unit tests. A description of our use of some of these techniques follows.&lt;br /&gt;
&lt;br /&gt;
=== Test Structure ===&lt;br /&gt;
We exploited &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''describe'''&amp;lt;/span&amp;gt; blocks in RSpec to give our unit tests a readable structure. We had &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''describe'''&amp;lt;/span&amp;gt; blocks for each method of &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt;. In these blocks, we used RSpec &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''context'''&amp;lt;/span&amp;gt; blocks where appropriate and examples to identify and test the different cases in the source code.&lt;br /&gt;
&lt;br /&gt;
=== Stubs for Isolating the UUT ===&lt;br /&gt;
In order to isolate the unit under test (UUT), i.e. the current method under test, we employed RSpec stubs. We stubbed out database calls and methods that triggered them in order to improve the run time of the unit tests, and we also stubbed out some outgoing command and query messages in order to test only the current method under test.&lt;br /&gt;
&lt;br /&gt;
=== DRY Testing Practices ===&lt;br /&gt;
We exploited factories and the RSpec helper method &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''let'''&amp;lt;/span&amp;gt; to make our unit tests shorter, more readable, and more maintainable, or, in essence, DRYer. Using the FactoryBot factories in '''factories.rb''' allowed us to use real Expertiza objects in our unit tests. We used the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''FactoryBot.build'''&amp;lt;/span&amp;gt; method to make our objects in order to avoid the run time penalty of saving (and this later having to retrieve) objects from the database. We used the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''let'''&amp;lt;/span&amp;gt; method with the factory as in the example below to make lazy-allocated objects which are cached throughout each example, improving run time.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;let(:team) { build(:assignment_team, id: 1, parent_id: 1) }&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whenever &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''team'''&amp;lt;/span&amp;gt; is called in an example, it returns the same value, i.e. the same object, which essentially allows tests that need it to have access to the same object without the need for allocating it as a class variable or instance variable for all of the tests or some of the tests. We placed these statements outside the scope of our unit test examples so the same objects could be used throughout all of them, DRYing out the test code.&lt;br /&gt;
&lt;br /&gt;
== Testing Framework ==&lt;br /&gt;
&lt;br /&gt;
=== RSpec Introduction ===&lt;br /&gt;
[http://rspec.info/ RSPEC] is a testing framework for Ruby for behavior-driven development (BDD) licensed under MIT. It is inspired by JBehave and contains fully integrated JMock based framework which has a very rich and powerful DSL (domain-specific language) which resembles a natural language specification. Composed of multiple libraries structured to work together, RSpec provides encapsulated testing via the describe block to specify the behavior of the class and the context for the unit test case.&lt;br /&gt;
&lt;br /&gt;
=== Why RSpec? ===&lt;br /&gt;
RSpec is easy to learn and implement and can be used with other testing tools like Cucumber and Minitest independently. It is extremely powerful for testing states with complicated setup and also helps in tearing down complex code to access the objects required for testing RSpec semantics encourage agile thinking and practice and it structures the tests in a more intuitive way.&lt;br /&gt;
&lt;br /&gt;
== Bugs Fixed ==&lt;br /&gt;
During testing of the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; model, we found two bugs, one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt; and one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''http://'''&amp;lt;/span&amp;gt; was ''appended'' to hyperlink strings without this tag or&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''https://'''&amp;lt;/span&amp;gt; at the start of them, rather than ''prepended''. We fixed this error in our pull request. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''id'''&amp;lt;/span&amp;gt;, an undefined parameter, was referenced while raising an exception, and we updated it to &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''assignment_id'''&amp;lt;/span&amp;gt;, which was the actual name of the parameter passed to the method.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
The model has a total of 237 lines, out of which 127 were relevant lines.&lt;br /&gt;
We achieved 100% coverage with avg hits per line at 2.3 (the number of times each specific line was run during the test suite)&lt;br /&gt;
&lt;br /&gt;
[[File:Coverage_header.png]]&lt;br /&gt;
[[File:Coverage_line.png]]&lt;br /&gt;
&lt;br /&gt;
== Future Work ==&lt;br /&gt;
&lt;br /&gt;
DRY principle could be cleaned up a little more. Sometimes it became necessary to use the '''let''' or '''build''' helper methods in each unit test. They may all be consolidated at the beginning. &amp;lt;br&amp;gt;&lt;br /&gt;
Some more edge cases could be thought of for each method, and tests written for those. Although, we have tried to cover as many as possible. &amp;lt;br&amp;gt;&lt;br /&gt;
Additionally, in the future, the code may also be refactored with a more efficient tool. &amp;lt;br&amp;gt;&lt;br /&gt;
Test coverage through quality tests consistently added throughout the development of the Expertiza project should be the future work of the project. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1. [http://expertiza.ncsu.edu Expertiza] &amp;lt;br&amp;gt;&lt;br /&gt;
2. [http://wiki.expertiza.ncsu.edu/index.php/Main_Page#Expertiza Expertiza Wikipedia ]&amp;lt;br&amp;gt;&lt;br /&gt;
3. [https://github.com/expertiza/expertiza Expertiza Github Repository]&amp;lt;br&amp;gt;&lt;br /&gt;
4. [https://relishapp.com/rspec RSpec - Relish]&amp;lt;br&amp;gt;&lt;br /&gt;
5. [https://sites.google.com/site/longlastingsoftware Engineering Software as a Service]&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=118120</id>
		<title>CSC/ECE 517 Fall 2018- Project E1848: Writing unit tests for assignment team.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=118120"/>
		<updated>2018-11-02T20:37:49Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: /* DRY Testing Practices */ Cut out the subheading and the reference to context blocks.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this project is to improve the coverage and quality of the unit tests for the assignment team model in Expertiza. This project comprised the program 3 assignment of CSC/ECE 517 in fall 2018 and is entitled &amp;quot;Project E1848: Writing unit tests for assignment_team.rb.&amp;quot; The source code for this project is in [https://github.com/expertiza/expertiza/pull/1228 pull request #1228] of the [https://github.com/expertiza Expertiza project] on [https://github.com/ GitHub].&lt;br /&gt;
&lt;br /&gt;
== Key Contributions ==&lt;br /&gt;
&lt;br /&gt;
Out of the 30 methods defined for the model AssignmentTeam.rb, test case was written for only one. Our contribution was to successfully add test cases for all remaining 29 methods.&lt;br /&gt;
&lt;br /&gt;
Hence, increasing the coverage from 5% to 100%.&lt;br /&gt;
&lt;br /&gt;
== The Class under Test ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
This class handles all functionalities for a team linked to an assignment. Some of the functionalities include, get a list of participants in the team, get the team name, team score for the given assignment, submissions for this team (files) and (hyperlinks) and topic picked by the team. Add/or remove participants from the team. It also checks for any reviews the team may have gotten for their work. Export all teams in a CSV file, import files from CSV to form teams.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
Our test plan was to test every method individually, i.e. write unit tests. We also tested multiple cases for each method. A description of all the methods in the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; model in assignment_team.rb and the RSpec unit tests we wrote for them is below.&lt;br /&gt;
&lt;br /&gt;
==== '''Function name: includes?(participant)''' ====&lt;br /&gt;
This function in assignment_team.rb checks if the '''participant''' passed as argument is a member of the team or not. For this, we utilize factorybot to build a user and a participant1 as follows-:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  let(:user1) { build(:student, id: 2) }&lt;br /&gt;
  let(:participant1) { build(:participant, id: 1) }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test cases checked for are-: &amp;lt;br&amp;gt;&lt;br /&gt;
1) when the team receives a user, that user is allowed to become a team participant. The method returns '''True''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has one participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes one participant&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        expect(team.includes?(participant1)).to eq true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) when the team receives a user with no arguments, that user is '''not''' allowed to become a team participant. The method returns '''False''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has no users&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([])&lt;br /&gt;
        expect(team.includes?(participant1)).to eq false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: parent_model ====&lt;br /&gt;
This function in assignment_team.rb always provides the name of the parent model which is '''Assignment'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;Assignment&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the name of the parent model&amp;quot; do&lt;br /&gt;
      expect(team.parent_model).to eq &amp;quot;Assignment&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.parent_model(id) ====&lt;br /&gt;
This function in assignment_team.rb takes in as argument id of the current '''Assignment''' for the team and returns an instance of the parent model.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the instance returned by this method for a given assignment id, matches the assignment or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the parent model&amp;quot; do&lt;br /&gt;
      allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
      expect(AssignmentTeam.parent_model(1)).to eq assignment&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: fullname ====&lt;br /&gt;
This function in assignment_team.rb print out the name for the current class instance. for this we first build an assignment team instance and assign it the name '''&amp;quot;abcd&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the assignment team has a name, and returns that same name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when the team has a name&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the name of the class&amp;quot; do&lt;br /&gt;
        team = build(:assignment_team, id: 1, name: &amp;quot;abcd&amp;quot;)&lt;br /&gt;
        expect(team.fullname).to eq &amp;quot;abcd&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: review_map_type ====&lt;br /&gt;
This function in assignment_team.rb always provides the name of the review map type which is '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;ReviewResponseMap&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the review map type&amp;quot; do&lt;br /&gt;
      expect(team.review_map_type).to eq &amp;quot;ReviewResponseMap&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.prototype ====&lt;br /&gt;
This function in assignment_team.rb implements the prototype pattern by returning a new instance of the class '''AssignmentTeam'''.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is a new instance of the class or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the AssignmentTeam&amp;quot; do&lt;br /&gt;
      expect(AssignmentTeam).to receive(:new).with(no_args)&lt;br /&gt;
      AssignmentTeam.prototype&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: assign_reviewer(reviewer) ====&lt;br /&gt;
This function in assignment_team.rb assigns a reviewer to the team by returning a new instance of the class '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
The unit test assigns a reviewer to the team and creates an instance of ReviewResponseMap.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#assign_reviewer&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a reviewer is present&amp;quot; do&lt;br /&gt;
      it &amp;quot;assign the reviewer to the team&amp;quot; do&lt;br /&gt;
        allow(Assignment).to receive(:find).with(team.parent_id).and_return(assignment)&lt;br /&gt;
        allow(ReviewResponseMap).to receive(:create).&lt;br /&gt;
          with(reviewee_id: team.id, reviewer_id: participant1.id, reviewed_object_id: assignment.id).and_return(review_response_map)&lt;br /&gt;
        expect(team.assign_reviewer(participant1)).to eq(review_response_map)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: reviewed_by?(reviewer) ====&lt;br /&gt;
This function in assignment_team.rb checks if the team has been reviewed by a reviewer.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the reviewer has reviewed the team. The test will find instances of ReviewResponseMaps belonging to the reviewer and the team, and will return true if such instances are present.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#reviewed_by?&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a team has a reviewer&amp;quot; do&lt;br /&gt;
      it &amp;quot;has been reviewed by this reviewer&amp;quot; do&lt;br /&gt;
        template = 'reviewee_id = ? &amp;amp;&amp;amp; reviewer_id = ? &amp;amp;&amp;amp; reviewed_object_id = ?'&lt;br /&gt;
        allow(ReviewResponseMap).to receive(:where).with(template, team.id, participant1.id, team.assignment.id).and_return([review_response_map])&lt;br /&gt;
        expect(team.reviewed_by?(participant1)).to eq true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: topic ====&lt;br /&gt;
This function in assignment_team.rb return the id of the topic picked by the team for the assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test first stubs a topic for the given assignment, allows a SignedUpTeam object to receive that topic and AssignmentTeam id, and return the topic id to check if it matches with the topic id of the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context &amp;quot;when the team has picked a topic&amp;quot; do&lt;br /&gt;
    it &amp;quot;provides the topic id&amp;quot; do&lt;br /&gt;
      assignment = team.assignment&lt;br /&gt;
      allow(SignUpTopic).to receive(:find_by).with(assignment: assignment).and_return(topic)&lt;br /&gt;
      allow(SignedUpTeam).to receive_message_chain(:find_by, :try).with(team_id: team.id).with(:topic_id).and_return(topic.id)&lt;br /&gt;
      expect(team.topic).to eq(topic.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: has_submissions? ====&lt;br /&gt;
this function in assignment_team.rb is used to check if the team has submitted their work or not.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the team to receive submissions, by first receiving files as submission, then hyperlink as submission, and for each expects the the team's submission to be true when the function is called.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a team has submitted files&amp;quot; do&lt;br /&gt;
      it &amp;quot;has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_files, :any?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when the team has submitted hyperlink&amp;quot; do&lt;br /&gt;
      it &amp;quot;checks if the team has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_hyperlinks, :present?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    after(:each) do&lt;br /&gt;
      expect(team.has_submissions?).to be true&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: participants ====&lt;br /&gt;
This function in assignment_team.rb returns a list of all participants in the team.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive two user instances and then adds these users as participants of the team. The test then expects the function to return a list of these two users as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has two participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;has those two participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
        expect(team.participants).to eq [participant1, participant2]&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive a user instance but does not add this user as participant of the team. The test then expects the function to return an empty list as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has a user but no participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(nil)&lt;br /&gt;
        expect(team.participants).to eq []&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: delete ====&lt;br /&gt;
This function in assignment_team.rb deletes the AssignmentTeam by destroying each participant in the team and returns an instance of AssignmentTeam.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows two users to be added as team participants. The test checks if the team deleted matches the current team instance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;deletes the team&amp;quot; do&lt;br /&gt;
      allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
      expect(team.delete).to eq(team)&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: destroy ====&lt;br /&gt;
This function in assignment_team.rb deletes all the reviews associated with the team.&lt;br /&gt;
&lt;br /&gt;
The unit test will delete every instance of '''ReviewResponseMaps''' associated with the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#destroy&amp;quot; do&lt;br /&gt;
    it &amp;quot;delete the reviews&amp;quot; do&lt;br /&gt;
      expect(team).to receive_message_chain(:review_response_maps, :each).with(no_args).with(no_args)&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.get_first_member(team_id) ====&lt;br /&gt;
This function in assignment_team.rb returns the instance of the first participant of the team for the given team id.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the assignment to receive a user, add it as a participant and return the first participant in the team. The test expects the function to return an instance of this participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team id is present&amp;quot; do&lt;br /&gt;
      it &amp;quot;get first member of the  team&amp;quot; do&lt;br /&gt;
        allow(AssignmentTeam).to receive_message_chain(:find_by, :try, :try).with(id: team.id).with(:participant).with(:first).and_return(participant1)&lt;br /&gt;
        expect(AssignmentTeam.get_first_member(team.id)).to eq(participant1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: submitted_files(path = self.path) ====&lt;br /&gt;
This function in assignment_team.rb returns a list of files belonging to a team for a given path.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is equal to the list of files that the team has submitted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#submitted_files&amp;quot; do&lt;br /&gt;
    context &amp;quot;given a path&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns submitted files&amp;quot; do&lt;br /&gt;
        files = [&amp;quot;file1.rb&amp;quot;]&lt;br /&gt;
        path = &amp;quot;assignment_path/5&amp;quot;&lt;br /&gt;
        allow(team).to receive(:path).with(path)&lt;br /&gt;
        allow(team).to receive(:files).with(path).and_return(files)&lt;br /&gt;
        expect(team.submitted_files(path)).to match_array(files)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.import(row, assignment_id, options) ====&lt;br /&gt;
This function in assignment_team.rb imports a team if the team with the given id is present.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the team is not imported if the team with the given id is not already present.&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when an assignment team does not already exist with the same id&amp;quot; do&lt;br /&gt;
      it &amp;quot;cannot be imported&amp;quot; do&lt;br /&gt;
        assignment_id = 1&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: assignment_id).and_return(nil)&lt;br /&gt;
        error_message = &amp;quot;The assignment with the id \&amp;quot;&amp;quot; + assignment_id.to_s + &amp;quot;\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
        expect { AssignmentTeam.import([], assignment_id, []) }.&lt;br /&gt;
          to raise_error(ImportError, error_message)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the team is imported if the team with the given id is already present.&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when an assignment team with the same id already exists&amp;quot; do&lt;br /&gt;
      it &amp;quot;gets imported through Team.import&amp;quot; do&lt;br /&gt;
        row = []&lt;br /&gt;
        assignment_id = 1&lt;br /&gt;
        options = []&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: assignment_id).and_return(assignment)&lt;br /&gt;
        allow(Team).to receive(:import).with(row, assignment_id, options, instance_of(AssignmentTeam))&lt;br /&gt;
        expect(Team).to receive(:import).with(row, assignment_id, options, instance_of(AssignmentTeam))&lt;br /&gt;
        AssignmentTeam.import(row, assignment_id, options)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.export(csv, parent_id, options) ====&lt;br /&gt;
This function in assignment_team.rb exports an instance of class '''AssignmentTeam'''&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is a new instance of the class '''AssignmentTeam''' or not.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;.export&amp;quot; do&lt;br /&gt;
    it &amp;quot;redirects to Team.export with a new AssignmentTeam object&amp;quot; do&lt;br /&gt;
      allow(Team).to receive(:export).with([], 1, [], instance_of(AssignmentTeam))&lt;br /&gt;
      expect(Team).to receive(:export).with([], 1, [], instance_of(AssignmentTeam))&lt;br /&gt;
      AssignmentTeam.export([], 1, [])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: copy(course_id) ====&lt;br /&gt;
This function in assignment_team.rb copies the current assignment team and creates a new CourseTeam instance from the given team. It takes as parameter the id of the course assignment team has.&lt;br /&gt;
&lt;br /&gt;
The test grabs the course id from the assignment team and calls the function to check if a course team is successfully created or not. The function returns and empty array, otherwise returns '''nil''' if the course team is not created successfully.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;for given assignment team&amp;quot; do&lt;br /&gt;
      it &amp;quot;copies the assignment team to course team&amp;quot; do&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        course = assignment.course&lt;br /&gt;
        expect(team.copy(course.id)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: add_participant(assignment_id, user) ====&lt;br /&gt;
This function in assignment_team.rb adds the user to the AssignmentTeam for the given assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test creates a user, and passes the user, assignment id for the team to the function and expects the result to be an instance of '''AssignmentParticipant''' meaning the user was successfully added as a participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is not a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;adds the user to the team&amp;quot; do&lt;br /&gt;
        user = build(:student, id: 10)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user)).to be_an_instance_of(AssignmentParticipant)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The unit test creates a user, adds him as a participant to the team, and passes the user, assignment id for the team to the function and expects the result to be '''nil''' as the user already exists as participant of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is already a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns without adding user to the team&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user1)).to eq(nil)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: scores(questions) ====&lt;br /&gt;
This function in assignment_team.rb returns the total score of the team. This function calculates scores for a given hash of questions.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is equal to the score.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#scores&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a hash of question is given&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns the score received by the team&amp;quot; do&lt;br /&gt;
        questionnaire1 = build(:questionnaire, id: 1)&lt;br /&gt;
        questionnaire2 = build(:questionnaire, id: 2)&lt;br /&gt;
&lt;br /&gt;
        question1 = build(:question, id: 1, questionnaire: questionnaire1)&lt;br /&gt;
        question2 = build(:question, id: 2, questionnaire: questionnaire2)&lt;br /&gt;
        questions = {questionnaire1.symbol =&amp;gt; [question1], questionnaire2.symbol =&amp;gt; [question2]}&lt;br /&gt;
&lt;br /&gt;
        scores = {}&lt;br /&gt;
        scores[:team] = team&lt;br /&gt;
        scores[:questionnaire1] = {}&lt;br /&gt;
        scores[:questionnaire1][:assessments] = review_response_map&lt;br /&gt;
        scores[:questionnaire1][:scores] = 5&lt;br /&gt;
        scores[:questionnaire2] = {}&lt;br /&gt;
        scores[:questionnaire2][:assessments] = review_response_map&lt;br /&gt;
        scores[:questionnaire2][:scores] = 5&lt;br /&gt;
        scores[:total_score] = 10&lt;br /&gt;
&lt;br /&gt;
        allow(team.assignment).to receive(:questionnaires).with(no_args).and_return([questionnaire1, questionnaire2])&lt;br /&gt;
        allow(ReviewResponseMap).to receive(:where).with(reviewee_id: team.id).and_return(review_response_map)&lt;br /&gt;
        allow(Answer).to receive(:compute_scores).with(scores[:questionnaire1][:assessments], questions[:questionnaire1]).and_return(5)&lt;br /&gt;
        allow(Answer).to receive(:compute_scores).with(scores[:questionnaire2][:assessments], questions[:questionnaire2]).and_return(5)&lt;br /&gt;
        allow(questionnaire1).to receive(:symbol).with(no_args).and_return(:questionnaire1)&lt;br /&gt;
        allow(questionnaire2).to receive(:symbol).with(no_args).and_return(:questionnaire2)&lt;br /&gt;
        allow(team.assignment).to receive(:compute_total_score).with(scores.except(:total_score)).and_return(10)&lt;br /&gt;
        expect(team.scores(questions)).to eq(scores)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: files(directory) ====&lt;br /&gt;
This method in assignment_team.rb successfully returns a list of files in any given directory path, not just the assignment teams directory path.&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned contains a specific file which is known to be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/models&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned does not contain a specific file which is known to not be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is not present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is not present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/controllers&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).not_to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: submit_hyperlink(hyperlink) ====&lt;br /&gt;
This function in assignment_team.rb submits the hyperlink for the team if it is valid or not empty.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the hyperlink is empty and raises an error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a hyperlink is empty&amp;quot; do&lt;br /&gt;
      it &amp;quot;causes an exception to be raised&amp;quot; do&lt;br /&gt;
        expect { team.submit_hyperlink(&amp;quot;&amp;quot;) }.to raise_error(&amp;quot;The hyperlink cannot be empty!&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the hyperlink is invalid and raises a 404 error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a hyperlink is invalid&amp;quot; do&lt;br /&gt;
      it &amp;quot;causes an exception to be raised with the proper HTTP status code&amp;quot; do&lt;br /&gt;
        invalid_hyperlink = &amp;quot;https://expertiza.ncsu.edu/not_a_valid_path&amp;quot;&lt;br /&gt;
        allow(Net::HTTP).to receive(:get_response).and_return(&amp;quot;404&amp;quot;)&lt;br /&gt;
        expect { team.submit_hyperlink(invalid_hyperlink) }.to raise_error(&amp;quot;HTTP status code: 404&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the the hyperlink has been submitted or not.&lt;br /&gt;
    context &amp;quot;when a valid hyperlink not in a certain improper format is submitted&amp;quot; do&lt;br /&gt;
      it &amp;quot;it is fixed and is saved to the database&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([&amp;quot;https://expertiza.ncsu.edu&amp;quot;])&lt;br /&gt;
        allow(team).to receive(:submitted_hyperlinks=)&lt;br /&gt;
        allow(team).to receive(:save)&lt;br /&gt;
        allow(Net::HTTP).to receive(:get_response).and_return(&amp;quot;0&amp;quot;)&lt;br /&gt;
        allow(YAML).to receive(:dump).with([&amp;quot;https://expertiza.ncsu.edu&amp;quot;, &amp;quot;www.ncsu.edu&amp;quot;])&lt;br /&gt;
        expect(team).to receive(:submitted_hyperlinks=)&lt;br /&gt;
        expect(team).to receive(:save)&lt;br /&gt;
        expect(YAML).to receive(:dump).with([&amp;quot;https://expertiza.ncsu.edu&amp;quot;, &amp;quot;http://www.ncsu.edu&amp;quot;])&lt;br /&gt;
        team.submit_hyperlink(&amp;quot;www.ncsu.edu  &amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: remove_hyperlink(hyperlink_to_delete) ====&lt;br /&gt;
This function in assignment_team.rb removes the hyperlink submitted by the team.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the hyperlink has been deleted or not.&lt;br /&gt;
  describe &amp;quot;#remove_hyperlink&amp;quot; do&lt;br /&gt;
    context &amp;quot;when the hyperlink is in the assignment team's hyperlinks&amp;quot; do&lt;br /&gt;
      it &amp;quot;is removed from the team's list of hyperlinks&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([&amp;quot;https://expertiza.ncsu.edu&amp;quot;, &amp;quot;https://www.ncsu.edu&amp;quot;])&lt;br /&gt;
        expect(team).to receive(:submitted_hyperlinks=)&lt;br /&gt;
        expect(team).to receive(:save)&lt;br /&gt;
        expect(YAML).to receive(:dump).with([&amp;quot;https://expertiza.ncsu.edu&amp;quot;])&lt;br /&gt;
        team.remove_hyperlink(&amp;quot;https://www.ncsu.edu&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.team(participant) ====&lt;br /&gt;
This function in assignment_team.rb returns the AssingmentTeam object that the given participant belongs to.&lt;br /&gt;
&lt;br /&gt;
The unit test first builds a user and assigns that user as a participant1 of the team. Then allows that participant to be added as a team user and finally search the team for the given team user and expect the team for participant1 to be equal to the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when there is a participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the team for participant&amp;quot; do&lt;br /&gt;
        teamuser = build(:team_user, id: 1, team_id: team.id, user_id: user1.id)&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(TeamsUser).to receive(:where).with(user_id: participant1.user_id).and_return([teamuser])&lt;br /&gt;
        allow(Team).to receive(:find).with(teamuser.team_id).and_return(team)&lt;br /&gt;
        expect(AssignmentTeam.team(participant1)).to eq(team)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.export_fields(options) ====&lt;br /&gt;
This function in assignment_team.rb exports the fields for a given set of options. It always returns a list containing [&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;] if the given set of options have a team name set to true.&lt;br /&gt;
&lt;br /&gt;
The unit test expects the method to return a static list of strings for the team passed as options, with the team having a name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team has name&amp;quot; do&lt;br /&gt;
      it &amp;quot;exports the fields&amp;quot; do&lt;br /&gt;
        expect(AssignmentTeam.export_fields(team)).to eq([&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.remove_team_by_id(id) ====&lt;br /&gt;
This function in assignment_team.rb removes team by using its id.&lt;br /&gt;
&lt;br /&gt;
The unit test deletes the team by using its id and checks if return value is the instance of class '''AssignmentTeam'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;.remove_team_by_id&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a team has an id&amp;quot; do&lt;br /&gt;
      it &amp;quot;delete the team by id&amp;quot; do&lt;br /&gt;
        allow(AssignmentTeam).to receive(:find).with(team.id).and_return(team)&lt;br /&gt;
        expect(AssignmentTeam.remove_team_by_id(team.id)).to eq(team)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: path ====&lt;br /&gt;
This function in assignment_team.rb returns a path to the directory where the team has submitted their files.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is equal to the path belonging to the team's submission.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#path&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns the path&amp;quot; do&lt;br /&gt;
      allow(team).to receive_message_chain(:assignment, :path).and_return(&amp;quot;assignment_path&amp;quot;)&lt;br /&gt;
      allow(team).to receive(:directory_num).and_return(5)&lt;br /&gt;
      expect(team.path).to eq &amp;quot;assignment_path/5&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: set_student_directory_num ====&lt;br /&gt;
This function in assignment_team.rb sets the directory number for the team.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the directory number for the team has been set. The test will check if the return value is equal to true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#set_student_directory_num&amp;quot; do&lt;br /&gt;
    it &amp;quot;sets the directory for the team&amp;quot; do&lt;br /&gt;
      team = build(:assignment_team, id: 1, parent_id: 1, directory_num: -1)&lt;br /&gt;
      max_num = 0&lt;br /&gt;
      allow(AssignmentTeam).to receive_message_chain(:where, :order, :first, :directory_num).&lt;br /&gt;
        with(parent_id: team.parent_id).with(:directory_num, :desc).with(no_args).with(no_args).and_return(max_num)&lt;br /&gt;
      expect(team.set_student_directory_num).to be true&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: received_any_peer_review? ====&lt;br /&gt;
This function in assignment_team.rb checks if the team has received any peer reviews.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if any instance of '''ReviewResponseMap''' is present for the team.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#received_any_peer_review?&amp;quot; do&lt;br /&gt;
    it &amp;quot;checks if the team has received any reviews&amp;quot; do&lt;br /&gt;
      allow(ResponseMap).to receive_message_chain(:where, :any?).with(reviewee_id: team.id, reviewed_object_id: team.parent_id).with(no_args).and_return(true)&lt;br /&gt;
      expect(team.received_any_peer_review?).to be true&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test Design ==&lt;br /&gt;
We used multiple RSpec-specific and general industry best practices for testing in our unit tests. A description of our use of some of these techniques follows.&lt;br /&gt;
&lt;br /&gt;
=== Test Structure ===&lt;br /&gt;
We exploited &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''describe'''&amp;lt;/span&amp;gt; blocks in RSpec to give our unit tests a readable structure. We had &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''describe'''&amp;lt;/span&amp;gt; blocks for each method of &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt;. In these blocks, we used RSpec &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''context'''&amp;lt;/span&amp;gt; blocks where appropriate and examples to identify and test the different cases in the source code.&lt;br /&gt;
&lt;br /&gt;
=== Stubs for Isolating the UUT ===&lt;br /&gt;
In order to isolate the unit under test (UUT), i.e. the current method under test, we employed RSpec stubs. We stubbed out database calls and methods that triggered them in order to improve the run time of the unit tests, and we also stubbed out some outgoing command and query messages in order to test only the current method under test.&lt;br /&gt;
&lt;br /&gt;
=== DRY Testing Practices ===&lt;br /&gt;
We exploited factories and the RSpec helper method &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''let'''&amp;lt;/span&amp;gt; to make our unit tests shorter, more readable, and more maintainable, or, in essence, DRYer. Using the FactoryBot factories in '''factories.rb''' allowed us to use real Expertiza objects in our unit tests. We used the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''FactoryBot.build'''&amp;lt;/span&amp;gt; method to make our objects in order to avoid the run time penalty of saving (and this later having to retrieve) objects from the database. We used the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''let'''&amp;lt;/span&amp;gt; method with the factory as in the example below to make lazy-allocated objects which are cached throughout each example, improving run time.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;let(:team) { build(:assignment_team, id: 1, parent_id: 1) }&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whenever &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''team'''&amp;lt;/span&amp;gt; is called in an example, it returns the same value, i.e. the same object, which essentially allows tests that need it to have access to the same object without the need for allocating it as a class variable or instance variable for all of the tests or some of the tests. We placed these statements outside the scope of our unit test examples so the same objects could be used throughout all of them, DRYing out the test code.&lt;br /&gt;
&lt;br /&gt;
== Testing Framework ==&lt;br /&gt;
&lt;br /&gt;
=== RSpec Introduction ===&lt;br /&gt;
[http://rspec.info/ RSPEC] is a testing framework for Ruby for behavior-driven development (BDD) licensed under MIT. It is inspired by JBehave and contains fully integrated JMock based framework which has a very rich and powerful DSL (domain-specific language) which resembles a natural language specification. Composed of multiple libraries structured to work together, RSpec provides encapsulated testing via the describe block to specify the behavior of the class and the context for the unit test case.&lt;br /&gt;
&lt;br /&gt;
=== Why RSpec? ===&lt;br /&gt;
RSpec is easy to learn and implement and can be used with other testing tools like Cucumber and Minitest independently. It is extremely powerful for testing states with complicated setup and also helps in tearing down complex code to access the objects required for testing RSpec semantics encourage agile thinking and practice and it structures the tests in a more intuitive way.&lt;br /&gt;
&lt;br /&gt;
== Bugs Fixed ==&lt;br /&gt;
During testing of the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; model, we found two bugs, one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt; and one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''http://'''&amp;lt;/span&amp;gt; was ''appended'' to hyperlink strings without this tag or&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''https://'''&amp;lt;/span&amp;gt; at the start of them, rather than ''prepended''. We fixed this error in our pull request. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''id'''&amp;lt;/span&amp;gt;, an undefined parameter, was referenced while raising an exception, and we updated it to &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''assignment_id'''&amp;lt;/span&amp;gt;, which was the actual name of the parameter passed to the method.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
The model has a total of 237 lines, out of which 127 were relevant lines.&lt;br /&gt;
We achieved 100% coverage with avg hits per line at 2.3 (the number of times each specific line was run during the test suite)&lt;br /&gt;
&lt;br /&gt;
[[File:Coverage_header.png]]&lt;br /&gt;
[[File:Coverage_line.png]]&lt;br /&gt;
&lt;br /&gt;
== Future Work ==&lt;br /&gt;
&lt;br /&gt;
DRY principle could be cleaned up a little more. Sometimes it became necessary to use the '''let''' or '''build''' helper methods in each unit test. They may all be consolidated at the beginning. &amp;lt;br&amp;gt;&lt;br /&gt;
Some more edge cases could be thought of for each method, and tests written for those. Although, we have tried to cover as many as possible. &amp;lt;br&amp;gt;&lt;br /&gt;
Additionally, in the future, the code may also be refactored with a more efficient tool. &amp;lt;br&amp;gt;&lt;br /&gt;
Test coverage through quality tests consistently added throughout the development of the Expertiza project should be the future work of the project. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1. [http://expertiza.ncsu.edu Expertiza] &amp;lt;br&amp;gt;&lt;br /&gt;
2. [http://wiki.expertiza.ncsu.edu/index.php/Main_Page#Expertiza Expertiza Wikipedia ]&amp;lt;br&amp;gt;&lt;br /&gt;
3. [https://github.com/expertiza/expertiza Expertiza Github Repository]&amp;lt;br&amp;gt;&lt;br /&gt;
4. [https://relishapp.com/rspec RSpec - Relish]&amp;lt;br&amp;gt;&lt;br /&gt;
5. [https://sites.google.com/site/longlastingsoftware Engineering Software as a Service]&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=118119</id>
		<title>CSC/ECE 517 Fall 2018- Project E1848: Writing unit tests for assignment team.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=118119"/>
		<updated>2018-11-02T20:36:48Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: Edit the Test Design and Test Structure sections.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this project is to improve the coverage and quality of the unit tests for the assignment team model in Expertiza. This project comprised the program 3 assignment of CSC/ECE 517 in fall 2018 and is entitled &amp;quot;Project E1848: Writing unit tests for assignment_team.rb.&amp;quot; The source code for this project is in [https://github.com/expertiza/expertiza/pull/1228 pull request #1228] of the [https://github.com/expertiza Expertiza project] on [https://github.com/ GitHub].&lt;br /&gt;
&lt;br /&gt;
== Key Contributions ==&lt;br /&gt;
&lt;br /&gt;
Out of the 30 methods defined for the model AssignmentTeam.rb, test case was written for only one. Our contribution was to successfully add test cases for all remaining 29 methods.&lt;br /&gt;
&lt;br /&gt;
Hence, increasing the coverage from 5% to 100%.&lt;br /&gt;
&lt;br /&gt;
== The Class under Test ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
This class handles all functionalities for a team linked to an assignment. Some of the functionalities include, get a list of participants in the team, get the team name, team score for the given assignment, submissions for this team (files) and (hyperlinks) and topic picked by the team. Add/or remove participants from the team. It also checks for any reviews the team may have gotten for their work. Export all teams in a CSV file, import files from CSV to form teams.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
Our test plan was to test every method individually, i.e. write unit tests. We also tested multiple cases for each method. A description of all the methods in the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; model in assignment_team.rb and the RSpec unit tests we wrote for them is below.&lt;br /&gt;
&lt;br /&gt;
==== '''Function name: includes?(participant)''' ====&lt;br /&gt;
This function in assignment_team.rb checks if the '''participant''' passed as argument is a member of the team or not. For this, we utilize factorybot to build a user and a participant1 as follows-:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  let(:user1) { build(:student, id: 2) }&lt;br /&gt;
  let(:participant1) { build(:participant, id: 1) }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test cases checked for are-: &amp;lt;br&amp;gt;&lt;br /&gt;
1) when the team receives a user, that user is allowed to become a team participant. The method returns '''True''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has one participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes one participant&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        expect(team.includes?(participant1)).to eq true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) when the team receives a user with no arguments, that user is '''not''' allowed to become a team participant. The method returns '''False''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has no users&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([])&lt;br /&gt;
        expect(team.includes?(participant1)).to eq false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: parent_model ====&lt;br /&gt;
This function in assignment_team.rb always provides the name of the parent model which is '''Assignment'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;Assignment&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the name of the parent model&amp;quot; do&lt;br /&gt;
      expect(team.parent_model).to eq &amp;quot;Assignment&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.parent_model(id) ====&lt;br /&gt;
This function in assignment_team.rb takes in as argument id of the current '''Assignment''' for the team and returns an instance of the parent model.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the instance returned by this method for a given assignment id, matches the assignment or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the parent model&amp;quot; do&lt;br /&gt;
      allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
      expect(AssignmentTeam.parent_model(1)).to eq assignment&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: fullname ====&lt;br /&gt;
This function in assignment_team.rb print out the name for the current class instance. for this we first build an assignment team instance and assign it the name '''&amp;quot;abcd&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the assignment team has a name, and returns that same name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when the team has a name&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the name of the class&amp;quot; do&lt;br /&gt;
        team = build(:assignment_team, id: 1, name: &amp;quot;abcd&amp;quot;)&lt;br /&gt;
        expect(team.fullname).to eq &amp;quot;abcd&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: review_map_type ====&lt;br /&gt;
This function in assignment_team.rb always provides the name of the review map type which is '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;ReviewResponseMap&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the review map type&amp;quot; do&lt;br /&gt;
      expect(team.review_map_type).to eq &amp;quot;ReviewResponseMap&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.prototype ====&lt;br /&gt;
This function in assignment_team.rb implements the prototype pattern by returning a new instance of the class '''AssignmentTeam'''.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is a new instance of the class or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the AssignmentTeam&amp;quot; do&lt;br /&gt;
      expect(AssignmentTeam).to receive(:new).with(no_args)&lt;br /&gt;
      AssignmentTeam.prototype&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: assign_reviewer(reviewer) ====&lt;br /&gt;
This function in assignment_team.rb assigns a reviewer to the team by returning a new instance of the class '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
The unit test assigns a reviewer to the team and creates an instance of ReviewResponseMap.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#assign_reviewer&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a reviewer is present&amp;quot; do&lt;br /&gt;
      it &amp;quot;assign the reviewer to the team&amp;quot; do&lt;br /&gt;
        allow(Assignment).to receive(:find).with(team.parent_id).and_return(assignment)&lt;br /&gt;
        allow(ReviewResponseMap).to receive(:create).&lt;br /&gt;
          with(reviewee_id: team.id, reviewer_id: participant1.id, reviewed_object_id: assignment.id).and_return(review_response_map)&lt;br /&gt;
        expect(team.assign_reviewer(participant1)).to eq(review_response_map)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: reviewed_by?(reviewer) ====&lt;br /&gt;
This function in assignment_team.rb checks if the team has been reviewed by a reviewer.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the reviewer has reviewed the team. The test will find instances of ReviewResponseMaps belonging to the reviewer and the team, and will return true if such instances are present.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#reviewed_by?&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a team has a reviewer&amp;quot; do&lt;br /&gt;
      it &amp;quot;has been reviewed by this reviewer&amp;quot; do&lt;br /&gt;
        template = 'reviewee_id = ? &amp;amp;&amp;amp; reviewer_id = ? &amp;amp;&amp;amp; reviewed_object_id = ?'&lt;br /&gt;
        allow(ReviewResponseMap).to receive(:where).with(template, team.id, participant1.id, team.assignment.id).and_return([review_response_map])&lt;br /&gt;
        expect(team.reviewed_by?(participant1)).to eq true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: topic ====&lt;br /&gt;
This function in assignment_team.rb return the id of the topic picked by the team for the assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test first stubs a topic for the given assignment, allows a SignedUpTeam object to receive that topic and AssignmentTeam id, and return the topic id to check if it matches with the topic id of the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context &amp;quot;when the team has picked a topic&amp;quot; do&lt;br /&gt;
    it &amp;quot;provides the topic id&amp;quot; do&lt;br /&gt;
      assignment = team.assignment&lt;br /&gt;
      allow(SignUpTopic).to receive(:find_by).with(assignment: assignment).and_return(topic)&lt;br /&gt;
      allow(SignedUpTeam).to receive_message_chain(:find_by, :try).with(team_id: team.id).with(:topic_id).and_return(topic.id)&lt;br /&gt;
      expect(team.topic).to eq(topic.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: has_submissions? ====&lt;br /&gt;
this function in assignment_team.rb is used to check if the team has submitted their work or not.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the team to receive submissions, by first receiving files as submission, then hyperlink as submission, and for each expects the the team's submission to be true when the function is called.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a team has submitted files&amp;quot; do&lt;br /&gt;
      it &amp;quot;has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_files, :any?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when the team has submitted hyperlink&amp;quot; do&lt;br /&gt;
      it &amp;quot;checks if the team has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_hyperlinks, :present?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    after(:each) do&lt;br /&gt;
      expect(team.has_submissions?).to be true&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: participants ====&lt;br /&gt;
This function in assignment_team.rb returns a list of all participants in the team.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive two user instances and then adds these users as participants of the team. The test then expects the function to return a list of these two users as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has two participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;has those two participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
        expect(team.participants).to eq [participant1, participant2]&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive a user instance but does not add this user as participant of the team. The test then expects the function to return an empty list as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has a user but no participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(nil)&lt;br /&gt;
        expect(team.participants).to eq []&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: delete ====&lt;br /&gt;
This function in assignment_team.rb deletes the AssignmentTeam by destroying each participant in the team and returns an instance of AssignmentTeam.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows two users to be added as team participants. The test checks if the team deleted matches the current team instance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;deletes the team&amp;quot; do&lt;br /&gt;
      allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
      expect(team.delete).to eq(team)&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: destroy ====&lt;br /&gt;
This function in assignment_team.rb deletes all the reviews associated with the team.&lt;br /&gt;
&lt;br /&gt;
The unit test will delete every instance of '''ReviewResponseMaps''' associated with the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#destroy&amp;quot; do&lt;br /&gt;
    it &amp;quot;delete the reviews&amp;quot; do&lt;br /&gt;
      expect(team).to receive_message_chain(:review_response_maps, :each).with(no_args).with(no_args)&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.get_first_member(team_id) ====&lt;br /&gt;
This function in assignment_team.rb returns the instance of the first participant of the team for the given team id.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the assignment to receive a user, add it as a participant and return the first participant in the team. The test expects the function to return an instance of this participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team id is present&amp;quot; do&lt;br /&gt;
      it &amp;quot;get first member of the  team&amp;quot; do&lt;br /&gt;
        allow(AssignmentTeam).to receive_message_chain(:find_by, :try, :try).with(id: team.id).with(:participant).with(:first).and_return(participant1)&lt;br /&gt;
        expect(AssignmentTeam.get_first_member(team.id)).to eq(participant1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: submitted_files(path = self.path) ====&lt;br /&gt;
This function in assignment_team.rb returns a list of files belonging to a team for a given path.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is equal to the list of files that the team has submitted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#submitted_files&amp;quot; do&lt;br /&gt;
    context &amp;quot;given a path&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns submitted files&amp;quot; do&lt;br /&gt;
        files = [&amp;quot;file1.rb&amp;quot;]&lt;br /&gt;
        path = &amp;quot;assignment_path/5&amp;quot;&lt;br /&gt;
        allow(team).to receive(:path).with(path)&lt;br /&gt;
        allow(team).to receive(:files).with(path).and_return(files)&lt;br /&gt;
        expect(team.submitted_files(path)).to match_array(files)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.import(row, assignment_id, options) ====&lt;br /&gt;
This function in assignment_team.rb imports a team if the team with the given id is present.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the team is not imported if the team with the given id is not already present.&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when an assignment team does not already exist with the same id&amp;quot; do&lt;br /&gt;
      it &amp;quot;cannot be imported&amp;quot; do&lt;br /&gt;
        assignment_id = 1&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: assignment_id).and_return(nil)&lt;br /&gt;
        error_message = &amp;quot;The assignment with the id \&amp;quot;&amp;quot; + assignment_id.to_s + &amp;quot;\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
        expect { AssignmentTeam.import([], assignment_id, []) }.&lt;br /&gt;
          to raise_error(ImportError, error_message)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the team is imported if the team with the given id is already present.&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when an assignment team with the same id already exists&amp;quot; do&lt;br /&gt;
      it &amp;quot;gets imported through Team.import&amp;quot; do&lt;br /&gt;
        row = []&lt;br /&gt;
        assignment_id = 1&lt;br /&gt;
        options = []&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: assignment_id).and_return(assignment)&lt;br /&gt;
        allow(Team).to receive(:import).with(row, assignment_id, options, instance_of(AssignmentTeam))&lt;br /&gt;
        expect(Team).to receive(:import).with(row, assignment_id, options, instance_of(AssignmentTeam))&lt;br /&gt;
        AssignmentTeam.import(row, assignment_id, options)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.export(csv, parent_id, options) ====&lt;br /&gt;
This function in assignment_team.rb exports an instance of class '''AssignmentTeam'''&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is a new instance of the class '''AssignmentTeam''' or not.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;.export&amp;quot; do&lt;br /&gt;
    it &amp;quot;redirects to Team.export with a new AssignmentTeam object&amp;quot; do&lt;br /&gt;
      allow(Team).to receive(:export).with([], 1, [], instance_of(AssignmentTeam))&lt;br /&gt;
      expect(Team).to receive(:export).with([], 1, [], instance_of(AssignmentTeam))&lt;br /&gt;
      AssignmentTeam.export([], 1, [])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: copy(course_id) ====&lt;br /&gt;
This function in assignment_team.rb copies the current assignment team and creates a new CourseTeam instance from the given team. It takes as parameter the id of the course assignment team has.&lt;br /&gt;
&lt;br /&gt;
The test grabs the course id from the assignment team and calls the function to check if a course team is successfully created or not. The function returns and empty array, otherwise returns '''nil''' if the course team is not created successfully.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;for given assignment team&amp;quot; do&lt;br /&gt;
      it &amp;quot;copies the assignment team to course team&amp;quot; do&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        course = assignment.course&lt;br /&gt;
        expect(team.copy(course.id)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: add_participant(assignment_id, user) ====&lt;br /&gt;
This function in assignment_team.rb adds the user to the AssignmentTeam for the given assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test creates a user, and passes the user, assignment id for the team to the function and expects the result to be an instance of '''AssignmentParticipant''' meaning the user was successfully added as a participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is not a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;adds the user to the team&amp;quot; do&lt;br /&gt;
        user = build(:student, id: 10)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user)).to be_an_instance_of(AssignmentParticipant)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The unit test creates a user, adds him as a participant to the team, and passes the user, assignment id for the team to the function and expects the result to be '''nil''' as the user already exists as participant of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is already a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns without adding user to the team&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user1)).to eq(nil)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: scores(questions) ====&lt;br /&gt;
This function in assignment_team.rb returns the total score of the team. This function calculates scores for a given hash of questions.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is equal to the score.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#scores&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a hash of question is given&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns the score received by the team&amp;quot; do&lt;br /&gt;
        questionnaire1 = build(:questionnaire, id: 1)&lt;br /&gt;
        questionnaire2 = build(:questionnaire, id: 2)&lt;br /&gt;
&lt;br /&gt;
        question1 = build(:question, id: 1, questionnaire: questionnaire1)&lt;br /&gt;
        question2 = build(:question, id: 2, questionnaire: questionnaire2)&lt;br /&gt;
        questions = {questionnaire1.symbol =&amp;gt; [question1], questionnaire2.symbol =&amp;gt; [question2]}&lt;br /&gt;
&lt;br /&gt;
        scores = {}&lt;br /&gt;
        scores[:team] = team&lt;br /&gt;
        scores[:questionnaire1] = {}&lt;br /&gt;
        scores[:questionnaire1][:assessments] = review_response_map&lt;br /&gt;
        scores[:questionnaire1][:scores] = 5&lt;br /&gt;
        scores[:questionnaire2] = {}&lt;br /&gt;
        scores[:questionnaire2][:assessments] = review_response_map&lt;br /&gt;
        scores[:questionnaire2][:scores] = 5&lt;br /&gt;
        scores[:total_score] = 10&lt;br /&gt;
&lt;br /&gt;
        allow(team.assignment).to receive(:questionnaires).with(no_args).and_return([questionnaire1, questionnaire2])&lt;br /&gt;
        allow(ReviewResponseMap).to receive(:where).with(reviewee_id: team.id).and_return(review_response_map)&lt;br /&gt;
        allow(Answer).to receive(:compute_scores).with(scores[:questionnaire1][:assessments], questions[:questionnaire1]).and_return(5)&lt;br /&gt;
        allow(Answer).to receive(:compute_scores).with(scores[:questionnaire2][:assessments], questions[:questionnaire2]).and_return(5)&lt;br /&gt;
        allow(questionnaire1).to receive(:symbol).with(no_args).and_return(:questionnaire1)&lt;br /&gt;
        allow(questionnaire2).to receive(:symbol).with(no_args).and_return(:questionnaire2)&lt;br /&gt;
        allow(team.assignment).to receive(:compute_total_score).with(scores.except(:total_score)).and_return(10)&lt;br /&gt;
        expect(team.scores(questions)).to eq(scores)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: files(directory) ====&lt;br /&gt;
This method in assignment_team.rb successfully returns a list of files in any given directory path, not just the assignment teams directory path.&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned contains a specific file which is known to be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/models&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned does not contain a specific file which is known to not be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is not present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is not present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/controllers&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).not_to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: submit_hyperlink(hyperlink) ====&lt;br /&gt;
This function in assignment_team.rb submits the hyperlink for the team if it is valid or not empty.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the hyperlink is empty and raises an error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a hyperlink is empty&amp;quot; do&lt;br /&gt;
      it &amp;quot;causes an exception to be raised&amp;quot; do&lt;br /&gt;
        expect { team.submit_hyperlink(&amp;quot;&amp;quot;) }.to raise_error(&amp;quot;The hyperlink cannot be empty!&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the hyperlink is invalid and raises a 404 error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a hyperlink is invalid&amp;quot; do&lt;br /&gt;
      it &amp;quot;causes an exception to be raised with the proper HTTP status code&amp;quot; do&lt;br /&gt;
        invalid_hyperlink = &amp;quot;https://expertiza.ncsu.edu/not_a_valid_path&amp;quot;&lt;br /&gt;
        allow(Net::HTTP).to receive(:get_response).and_return(&amp;quot;404&amp;quot;)&lt;br /&gt;
        expect { team.submit_hyperlink(invalid_hyperlink) }.to raise_error(&amp;quot;HTTP status code: 404&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the the hyperlink has been submitted or not.&lt;br /&gt;
    context &amp;quot;when a valid hyperlink not in a certain improper format is submitted&amp;quot; do&lt;br /&gt;
      it &amp;quot;it is fixed and is saved to the database&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([&amp;quot;https://expertiza.ncsu.edu&amp;quot;])&lt;br /&gt;
        allow(team).to receive(:submitted_hyperlinks=)&lt;br /&gt;
        allow(team).to receive(:save)&lt;br /&gt;
        allow(Net::HTTP).to receive(:get_response).and_return(&amp;quot;0&amp;quot;)&lt;br /&gt;
        allow(YAML).to receive(:dump).with([&amp;quot;https://expertiza.ncsu.edu&amp;quot;, &amp;quot;www.ncsu.edu&amp;quot;])&lt;br /&gt;
        expect(team).to receive(:submitted_hyperlinks=)&lt;br /&gt;
        expect(team).to receive(:save)&lt;br /&gt;
        expect(YAML).to receive(:dump).with([&amp;quot;https://expertiza.ncsu.edu&amp;quot;, &amp;quot;http://www.ncsu.edu&amp;quot;])&lt;br /&gt;
        team.submit_hyperlink(&amp;quot;www.ncsu.edu  &amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: remove_hyperlink(hyperlink_to_delete) ====&lt;br /&gt;
This function in assignment_team.rb removes the hyperlink submitted by the team.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the hyperlink has been deleted or not.&lt;br /&gt;
  describe &amp;quot;#remove_hyperlink&amp;quot; do&lt;br /&gt;
    context &amp;quot;when the hyperlink is in the assignment team's hyperlinks&amp;quot; do&lt;br /&gt;
      it &amp;quot;is removed from the team's list of hyperlinks&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([&amp;quot;https://expertiza.ncsu.edu&amp;quot;, &amp;quot;https://www.ncsu.edu&amp;quot;])&lt;br /&gt;
        expect(team).to receive(:submitted_hyperlinks=)&lt;br /&gt;
        expect(team).to receive(:save)&lt;br /&gt;
        expect(YAML).to receive(:dump).with([&amp;quot;https://expertiza.ncsu.edu&amp;quot;])&lt;br /&gt;
        team.remove_hyperlink(&amp;quot;https://www.ncsu.edu&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.team(participant) ====&lt;br /&gt;
This function in assignment_team.rb returns the AssingmentTeam object that the given participant belongs to.&lt;br /&gt;
&lt;br /&gt;
The unit test first builds a user and assigns that user as a participant1 of the team. Then allows that participant to be added as a team user and finally search the team for the given team user and expect the team for participant1 to be equal to the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when there is a participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the team for participant&amp;quot; do&lt;br /&gt;
        teamuser = build(:team_user, id: 1, team_id: team.id, user_id: user1.id)&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(TeamsUser).to receive(:where).with(user_id: participant1.user_id).and_return([teamuser])&lt;br /&gt;
        allow(Team).to receive(:find).with(teamuser.team_id).and_return(team)&lt;br /&gt;
        expect(AssignmentTeam.team(participant1)).to eq(team)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.export_fields(options) ====&lt;br /&gt;
This function in assignment_team.rb exports the fields for a given set of options. It always returns a list containing [&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;] if the given set of options have a team name set to true.&lt;br /&gt;
&lt;br /&gt;
The unit test expects the method to return a static list of strings for the team passed as options, with the team having a name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team has name&amp;quot; do&lt;br /&gt;
      it &amp;quot;exports the fields&amp;quot; do&lt;br /&gt;
        expect(AssignmentTeam.export_fields(team)).to eq([&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.remove_team_by_id(id) ====&lt;br /&gt;
This function in assignment_team.rb removes team by using its id.&lt;br /&gt;
&lt;br /&gt;
The unit test deletes the team by using its id and checks if return value is the instance of class '''AssignmentTeam'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;.remove_team_by_id&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a team has an id&amp;quot; do&lt;br /&gt;
      it &amp;quot;delete the team by id&amp;quot; do&lt;br /&gt;
        allow(AssignmentTeam).to receive(:find).with(team.id).and_return(team)&lt;br /&gt;
        expect(AssignmentTeam.remove_team_by_id(team.id)).to eq(team)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: path ====&lt;br /&gt;
This function in assignment_team.rb returns a path to the directory where the team has submitted their files.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is equal to the path belonging to the team's submission.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#path&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns the path&amp;quot; do&lt;br /&gt;
      allow(team).to receive_message_chain(:assignment, :path).and_return(&amp;quot;assignment_path&amp;quot;)&lt;br /&gt;
      allow(team).to receive(:directory_num).and_return(5)&lt;br /&gt;
      expect(team.path).to eq &amp;quot;assignment_path/5&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: set_student_directory_num ====&lt;br /&gt;
This function in assignment_team.rb sets the directory number for the team.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the directory number for the team has been set. The test will check if the return value is equal to true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#set_student_directory_num&amp;quot; do&lt;br /&gt;
    it &amp;quot;sets the directory for the team&amp;quot; do&lt;br /&gt;
      team = build(:assignment_team, id: 1, parent_id: 1, directory_num: -1)&lt;br /&gt;
      max_num = 0&lt;br /&gt;
      allow(AssignmentTeam).to receive_message_chain(:where, :order, :first, :directory_num).&lt;br /&gt;
        with(parent_id: team.parent_id).with(:directory_num, :desc).with(no_args).with(no_args).and_return(max_num)&lt;br /&gt;
      expect(team.set_student_directory_num).to be true&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: received_any_peer_review? ====&lt;br /&gt;
This function in assignment_team.rb checks if the team has received any peer reviews.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if any instance of '''ReviewResponseMap''' is present for the team.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#received_any_peer_review?&amp;quot; do&lt;br /&gt;
    it &amp;quot;checks if the team has received any reviews&amp;quot; do&lt;br /&gt;
      allow(ResponseMap).to receive_message_chain(:where, :any?).with(reviewee_id: team.id, reviewed_object_id: team.parent_id).with(no_args).and_return(true)&lt;br /&gt;
      expect(team.received_any_peer_review?).to be true&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test Design ==&lt;br /&gt;
We used multiple RSpec-specific and general industry best practices for testing in our unit tests. A description of our use of some of these techniques follows.&lt;br /&gt;
&lt;br /&gt;
=== Test Structure ===&lt;br /&gt;
We exploited &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''describe'''&amp;lt;/span&amp;gt; blocks in RSpec to give our unit tests a readable structure. We had &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''describe'''&amp;lt;/span&amp;gt; blocks for each method of &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt;. In these blocks, we used RSpec &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''context'''&amp;lt;/span&amp;gt; blocks where appropriate and examples to identify and test the different cases in the source code.&lt;br /&gt;
&lt;br /&gt;
=== Stubs for Isolating the UUT ===&lt;br /&gt;
In order to isolate the unit under test (UUT), i.e. the current method under test, we employed RSpec stubs. We stubbed out database calls and methods that triggered them in order to improve the run time of the unit tests, and we also stubbed out some outgoing command and query messages in order to test only the current method under test.&lt;br /&gt;
&lt;br /&gt;
=== DRY Testing Practices ===&lt;br /&gt;
We exploited factories and the RSpec helper method &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''let'''&amp;lt;/span&amp;gt; as well as &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''context'''&amp;lt;/span&amp;gt; blocks to make our unit tests shorter, more readable, and more maintainable, or, in essence, DRYer.&lt;br /&gt;
&lt;br /&gt;
==== Factories and the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;let&amp;lt;/span&amp;gt; RSPEC Helper Method ====&lt;br /&gt;
Using the FactoryBot factories in '''factories.rb''' allowed us to use real Expertiza objects in our unit tests. We used the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''FactoryBot.build'''&amp;lt;/span&amp;gt; method to make our objects in order to avoid the run time penalty of saving (and this later having to retrieve) objects from the database. We used the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''let'''&amp;lt;/span&amp;gt; method with the factory as in the example below to make lazy-allocated objects which are cached throughout each example, improving run time.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;let(:team) { build(:assignment_team, id: 1, parent_id: 1) }&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whenever &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''team'''&amp;lt;/span&amp;gt; is called in an example, it returns the same value, i.e. the same object, which essentially allows tests that need it to have access to the same object without the need for allocating it as a class variable or instance variable for all of the tests or some of the tests. We placed these statements outside the scope of our unit test examples so the same objects could be used throughout all of them, DRYing out the test code.&lt;br /&gt;
&lt;br /&gt;
== Testing Framework ==&lt;br /&gt;
&lt;br /&gt;
=== RSpec Introduction ===&lt;br /&gt;
[http://rspec.info/ RSPEC] is a testing framework for Ruby for behavior-driven development (BDD) licensed under MIT. It is inspired by JBehave and contains fully integrated JMock based framework which has a very rich and powerful DSL (domain-specific language) which resembles a natural language specification. Composed of multiple libraries structured to work together, RSpec provides encapsulated testing via the describe block to specify the behavior of the class and the context for the unit test case.&lt;br /&gt;
&lt;br /&gt;
=== Why RSpec? ===&lt;br /&gt;
RSpec is easy to learn and implement and can be used with other testing tools like Cucumber and Minitest independently. It is extremely powerful for testing states with complicated setup and also helps in tearing down complex code to access the objects required for testing RSpec semantics encourage agile thinking and practice and it structures the tests in a more intuitive way.&lt;br /&gt;
&lt;br /&gt;
== Bugs Fixed ==&lt;br /&gt;
During testing of the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; model, we found two bugs, one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt; and one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''http://'''&amp;lt;/span&amp;gt; was ''appended'' to hyperlink strings without this tag or&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''https://'''&amp;lt;/span&amp;gt; at the start of them, rather than ''prepended''. We fixed this error in our pull request. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''id'''&amp;lt;/span&amp;gt;, an undefined parameter, was referenced while raising an exception, and we updated it to &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''assignment_id'''&amp;lt;/span&amp;gt;, which was the actual name of the parameter passed to the method.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
The model has a total of 237 lines, out of which 127 were relevant lines.&lt;br /&gt;
We achieved 100% coverage with avg hits per line at 2.3 (the number of times each specific line was run during the test suite)&lt;br /&gt;
&lt;br /&gt;
[[File:Coverage_header.png]]&lt;br /&gt;
[[File:Coverage_line.png]]&lt;br /&gt;
&lt;br /&gt;
== Future Work ==&lt;br /&gt;
&lt;br /&gt;
DRY principle could be cleaned up a little more. Sometimes it became necessary to use the '''let''' or '''build''' helper methods in each unit test. They may all be consolidated at the beginning. &amp;lt;br&amp;gt;&lt;br /&gt;
Some more edge cases could be thought of for each method, and tests written for those. Although, we have tried to cover as many as possible. &amp;lt;br&amp;gt;&lt;br /&gt;
Additionally, in the future, the code may also be refactored with a more efficient tool. &amp;lt;br&amp;gt;&lt;br /&gt;
Test coverage through quality tests consistently added throughout the development of the Expertiza project should be the future work of the project. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1. [http://expertiza.ncsu.edu Expertiza] &amp;lt;br&amp;gt;&lt;br /&gt;
2. [http://wiki.expertiza.ncsu.edu/index.php/Main_Page#Expertiza Expertiza Wikipedia ]&amp;lt;br&amp;gt;&lt;br /&gt;
3. [https://github.com/expertiza/expertiza Expertiza Github Repository]&amp;lt;br&amp;gt;&lt;br /&gt;
4. [https://relishapp.com/rspec RSpec - Relish]&amp;lt;br&amp;gt;&lt;br /&gt;
5. [https://sites.google.com/site/longlastingsoftware Engineering Software as a Service]&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=118117</id>
		<title>CSC/ECE 517 Fall 2018- Project E1848: Writing unit tests for assignment team.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=118117"/>
		<updated>2018-11-02T20:32:08Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: Change the headings.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this project is to improve the coverage and quality of the unit tests for the assignment team model in Expertiza. This project comprised the program 3 assignment of CSC/ECE 517 in fall 2018 and is entitled &amp;quot;Project E1848: Writing unit tests for assignment_team.rb.&amp;quot; The source code for this project is in [https://github.com/expertiza/expertiza/pull/1228 pull request #1228] of the [https://github.com/expertiza Expertiza project] on [https://github.com/ GitHub].&lt;br /&gt;
&lt;br /&gt;
== Key Contributions ==&lt;br /&gt;
&lt;br /&gt;
Out of the 30 methods defined for the model AssignmentTeam.rb, test case was written for only one. Our contribution was to successfully add test cases for all remaining 29 methods.&lt;br /&gt;
&lt;br /&gt;
Hence, increasing the coverage from 5% to 100%.&lt;br /&gt;
&lt;br /&gt;
== The Class under Test ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
This class handles all functionalities for a team linked to an assignment. Some of the functionalities include, get a list of participants in the team, get the team name, team score for the given assignment, submissions for this team (files) and (hyperlinks) and topic picked by the team. Add/or remove participants from the team. It also checks for any reviews the team may have gotten for their work. Export all teams in a CSV file, import files from CSV to form teams.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
Our test plan was to test every method individually, i.e. write unit tests. We also tested multiple cases for each method. A description of all the methods in the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; model in assignment_team.rb and the RSpec unit tests we wrote for them is below.&lt;br /&gt;
&lt;br /&gt;
==== '''Function name: includes?(participant)''' ====&lt;br /&gt;
This function in assignment_team.rb checks if the '''participant''' passed as argument is a member of the team or not. For this, we utilize factorybot to build a user and a participant1 as follows-:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  let(:user1) { build(:student, id: 2) }&lt;br /&gt;
  let(:participant1) { build(:participant, id: 1) }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test cases checked for are-: &amp;lt;br&amp;gt;&lt;br /&gt;
1) when the team receives a user, that user is allowed to become a team participant. The method returns '''True''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has one participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes one participant&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        expect(team.includes?(participant1)).to eq true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) when the team receives a user with no arguments, that user is '''not''' allowed to become a team participant. The method returns '''False''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has no users&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([])&lt;br /&gt;
        expect(team.includes?(participant1)).to eq false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: parent_model ====&lt;br /&gt;
This function in assignment_team.rb always provides the name of the parent model which is '''Assignment'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;Assignment&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the name of the parent model&amp;quot; do&lt;br /&gt;
      expect(team.parent_model).to eq &amp;quot;Assignment&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.parent_model(id) ====&lt;br /&gt;
This function in assignment_team.rb takes in as argument id of the current '''Assignment''' for the team and returns an instance of the parent model.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the instance returned by this method for a given assignment id, matches the assignment or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the parent model&amp;quot; do&lt;br /&gt;
      allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
      expect(AssignmentTeam.parent_model(1)).to eq assignment&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: fullname ====&lt;br /&gt;
This function in assignment_team.rb print out the name for the current class instance. for this we first build an assignment team instance and assign it the name '''&amp;quot;abcd&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the assignment team has a name, and returns that same name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when the team has a name&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the name of the class&amp;quot; do&lt;br /&gt;
        team = build(:assignment_team, id: 1, name: &amp;quot;abcd&amp;quot;)&lt;br /&gt;
        expect(team.fullname).to eq &amp;quot;abcd&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: review_map_type ====&lt;br /&gt;
This function in assignment_team.rb always provides the name of the review map type which is '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;ReviewResponseMap&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the review map type&amp;quot; do&lt;br /&gt;
      expect(team.review_map_type).to eq &amp;quot;ReviewResponseMap&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.prototype ====&lt;br /&gt;
This function in assignment_team.rb implements the prototype pattern by returning a new instance of the class '''AssignmentTeam'''.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is a new instance of the class or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the AssignmentTeam&amp;quot; do&lt;br /&gt;
      expect(AssignmentTeam).to receive(:new).with(no_args)&lt;br /&gt;
      AssignmentTeam.prototype&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: assign_reviewer(reviewer) ====&lt;br /&gt;
This function in assignment_team.rb assigns a reviewer to the team by returning a new instance of the class '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
The unit test assigns a reviewer to the team and creates an instance of ReviewResponseMap.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#assign_reviewer&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a reviewer is present&amp;quot; do&lt;br /&gt;
      it &amp;quot;assign the reviewer to the team&amp;quot; do&lt;br /&gt;
        allow(Assignment).to receive(:find).with(team.parent_id).and_return(assignment)&lt;br /&gt;
        allow(ReviewResponseMap).to receive(:create).&lt;br /&gt;
          with(reviewee_id: team.id, reviewer_id: participant1.id, reviewed_object_id: assignment.id).and_return(review_response_map)&lt;br /&gt;
        expect(team.assign_reviewer(participant1)).to eq(review_response_map)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: reviewed_by?(reviewer) ====&lt;br /&gt;
This function in assignment_team.rb checks if the team has been reviewed by a reviewer.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the reviewer has reviewed the team. The test will find instances of ReviewResponseMaps belonging to the reviewer and the team, and will return true if such instances are present.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#reviewed_by?&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a team has a reviewer&amp;quot; do&lt;br /&gt;
      it &amp;quot;has been reviewed by this reviewer&amp;quot; do&lt;br /&gt;
        template = 'reviewee_id = ? &amp;amp;&amp;amp; reviewer_id = ? &amp;amp;&amp;amp; reviewed_object_id = ?'&lt;br /&gt;
        allow(ReviewResponseMap).to receive(:where).with(template, team.id, participant1.id, team.assignment.id).and_return([review_response_map])&lt;br /&gt;
        expect(team.reviewed_by?(participant1)).to eq true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: topic ====&lt;br /&gt;
This function in assignment_team.rb return the id of the topic picked by the team for the assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test first stubs a topic for the given assignment, allows a SignedUpTeam object to receive that topic and AssignmentTeam id, and return the topic id to check if it matches with the topic id of the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context &amp;quot;when the team has picked a topic&amp;quot; do&lt;br /&gt;
    it &amp;quot;provides the topic id&amp;quot; do&lt;br /&gt;
      assignment = team.assignment&lt;br /&gt;
      allow(SignUpTopic).to receive(:find_by).with(assignment: assignment).and_return(topic)&lt;br /&gt;
      allow(SignedUpTeam).to receive_message_chain(:find_by, :try).with(team_id: team.id).with(:topic_id).and_return(topic.id)&lt;br /&gt;
      expect(team.topic).to eq(topic.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: has_submissions? ====&lt;br /&gt;
this function in assignment_team.rb is used to check if the team has submitted their work or not.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the team to receive submissions, by first receiving files as submission, then hyperlink as submission, and for each expects the the team's submission to be true when the function is called.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a team has submitted files&amp;quot; do&lt;br /&gt;
      it &amp;quot;has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_files, :any?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when the team has submitted hyperlink&amp;quot; do&lt;br /&gt;
      it &amp;quot;checks if the team has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_hyperlinks, :present?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    after(:each) do&lt;br /&gt;
      expect(team.has_submissions?).to be true&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: participants ====&lt;br /&gt;
This function in assignment_team.rb returns a list of all participants in the team.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive two user instances and then adds these users as participants of the team. The test then expects the function to return a list of these two users as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has two participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;has those two participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
        expect(team.participants).to eq [participant1, participant2]&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive a user instance but does not add this user as participant of the team. The test then expects the function to return an empty list as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has a user but no participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(nil)&lt;br /&gt;
        expect(team.participants).to eq []&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: delete ====&lt;br /&gt;
This function in assignment_team.rb deletes the AssignmentTeam by destroying each participant in the team and returns an instance of AssignmentTeam.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows two users to be added as team participants. The test checks if the team deleted matches the current team instance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;deletes the team&amp;quot; do&lt;br /&gt;
      allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
      expect(team.delete).to eq(team)&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: destroy ====&lt;br /&gt;
This function in assignment_team.rb deletes all the reviews associated with the team.&lt;br /&gt;
&lt;br /&gt;
The unit test will delete every instance of '''ReviewResponseMaps''' associated with the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#destroy&amp;quot; do&lt;br /&gt;
    it &amp;quot;delete the reviews&amp;quot; do&lt;br /&gt;
      expect(team).to receive_message_chain(:review_response_maps, :each).with(no_args).with(no_args)&lt;br /&gt;
      team.destroy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.get_first_member(team_id) ====&lt;br /&gt;
This function in assignment_team.rb returns the instance of the first participant of the team for the given team id.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the assignment to receive a user, add it as a participant and return the first participant in the team. The test expects the function to return an instance of this participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team id is present&amp;quot; do&lt;br /&gt;
      it &amp;quot;get first member of the  team&amp;quot; do&lt;br /&gt;
        allow(AssignmentTeam).to receive_message_chain(:find_by, :try, :try).with(id: team.id).with(:participant).with(:first).and_return(participant1)&lt;br /&gt;
        expect(AssignmentTeam.get_first_member(team.id)).to eq(participant1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: submitted_files(path = self.path) ====&lt;br /&gt;
This function in assignment_team.rb returns a list of files belonging to a team for a given path.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is equal to the list of files that the team has submitted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#submitted_files&amp;quot; do&lt;br /&gt;
    context &amp;quot;given a path&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns submitted files&amp;quot; do&lt;br /&gt;
        files = [&amp;quot;file1.rb&amp;quot;]&lt;br /&gt;
        path = &amp;quot;assignment_path/5&amp;quot;&lt;br /&gt;
        allow(team).to receive(:path).with(path)&lt;br /&gt;
        allow(team).to receive(:files).with(path).and_return(files)&lt;br /&gt;
        expect(team.submitted_files(path)).to match_array(files)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.import(row, assignment_id, options) ====&lt;br /&gt;
This function in assignment_team.rb imports a team if the team with the given id is present.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the team is not imported if the team with the given id is not already present.&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when an assignment team does not already exist with the same id&amp;quot; do&lt;br /&gt;
      it &amp;quot;cannot be imported&amp;quot; do&lt;br /&gt;
        assignment_id = 1&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: assignment_id).and_return(nil)&lt;br /&gt;
        error_message = &amp;quot;The assignment with the id \&amp;quot;&amp;quot; + assignment_id.to_s + &amp;quot;\&amp;quot; was not found. &amp;lt;a href='/assignment/new'&amp;gt;Create&amp;lt;/a&amp;gt; this assignment?&amp;quot;&lt;br /&gt;
        expect { AssignmentTeam.import([], assignment_id, []) }.&lt;br /&gt;
          to raise_error(ImportError, error_message)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the team is imported if the team with the given id is already present.&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when an assignment team with the same id already exists&amp;quot; do&lt;br /&gt;
      it &amp;quot;gets imported through Team.import&amp;quot; do&lt;br /&gt;
        row = []&lt;br /&gt;
        assignment_id = 1&lt;br /&gt;
        options = []&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: assignment_id).and_return(assignment)&lt;br /&gt;
        allow(Team).to receive(:import).with(row, assignment_id, options, instance_of(AssignmentTeam))&lt;br /&gt;
        expect(Team).to receive(:import).with(row, assignment_id, options, instance_of(AssignmentTeam))&lt;br /&gt;
        AssignmentTeam.import(row, assignment_id, options)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.export(csv, parent_id, options) ====&lt;br /&gt;
This function in assignment_team.rb exports an instance of class '''AssignmentTeam'''&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is a new instance of the class '''AssignmentTeam''' or not.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;.export&amp;quot; do&lt;br /&gt;
    it &amp;quot;redirects to Team.export with a new AssignmentTeam object&amp;quot; do&lt;br /&gt;
      allow(Team).to receive(:export).with([], 1, [], instance_of(AssignmentTeam))&lt;br /&gt;
      expect(Team).to receive(:export).with([], 1, [], instance_of(AssignmentTeam))&lt;br /&gt;
      AssignmentTeam.export([], 1, [])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: copy(course_id) ====&lt;br /&gt;
This function in assignment_team.rb copies the current assignment team and creates a new CourseTeam instance from the given team. It takes as parameter the id of the course assignment team has.&lt;br /&gt;
&lt;br /&gt;
The test grabs the course id from the assignment team and calls the function to check if a course team is successfully created or not. The function returns and empty array, otherwise returns '''nil''' if the course team is not created successfully.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;for given assignment team&amp;quot; do&lt;br /&gt;
      it &amp;quot;copies the assignment team to course team&amp;quot; do&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        course = assignment.course&lt;br /&gt;
        expect(team.copy(course.id)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: add_participant(assignment_id, user) ====&lt;br /&gt;
This function in assignment_team.rb adds the user to the AssignmentTeam for the given assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test creates a user, and passes the user, assignment id for the team to the function and expects the result to be an instance of '''AssignmentParticipant''' meaning the user was successfully added as a participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is not a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;adds the user to the team&amp;quot; do&lt;br /&gt;
        user = build(:student, id: 10)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user)).to be_an_instance_of(AssignmentParticipant)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The unit test creates a user, adds him as a participant to the team, and passes the user, assignment id for the team to the function and expects the result to be '''nil''' as the user already exists as participant of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is already a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns without adding user to the team&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user1)).to eq(nil)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: scores(questions) ====&lt;br /&gt;
This function in assignment_team.rb returns the total score of the team. This function calculates scores for a given hash of questions.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is equal to the score.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#scores&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a hash of question is given&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns the score received by the team&amp;quot; do&lt;br /&gt;
        questionnaire1 = build(:questionnaire, id: 1)&lt;br /&gt;
        questionnaire2 = build(:questionnaire, id: 2)&lt;br /&gt;
&lt;br /&gt;
        question1 = build(:question, id: 1, questionnaire: questionnaire1)&lt;br /&gt;
        question2 = build(:question, id: 2, questionnaire: questionnaire2)&lt;br /&gt;
        questions = {questionnaire1.symbol =&amp;gt; [question1], questionnaire2.symbol =&amp;gt; [question2]}&lt;br /&gt;
&lt;br /&gt;
        scores = {}&lt;br /&gt;
        scores[:team] = team&lt;br /&gt;
        scores[:questionnaire1] = {}&lt;br /&gt;
        scores[:questionnaire1][:assessments] = review_response_map&lt;br /&gt;
        scores[:questionnaire1][:scores] = 5&lt;br /&gt;
        scores[:questionnaire2] = {}&lt;br /&gt;
        scores[:questionnaire2][:assessments] = review_response_map&lt;br /&gt;
        scores[:questionnaire2][:scores] = 5&lt;br /&gt;
        scores[:total_score] = 10&lt;br /&gt;
&lt;br /&gt;
        allow(team.assignment).to receive(:questionnaires).with(no_args).and_return([questionnaire1, questionnaire2])&lt;br /&gt;
        allow(ReviewResponseMap).to receive(:where).with(reviewee_id: team.id).and_return(review_response_map)&lt;br /&gt;
        allow(Answer).to receive(:compute_scores).with(scores[:questionnaire1][:assessments], questions[:questionnaire1]).and_return(5)&lt;br /&gt;
        allow(Answer).to receive(:compute_scores).with(scores[:questionnaire2][:assessments], questions[:questionnaire2]).and_return(5)&lt;br /&gt;
        allow(questionnaire1).to receive(:symbol).with(no_args).and_return(:questionnaire1)&lt;br /&gt;
        allow(questionnaire2).to receive(:symbol).with(no_args).and_return(:questionnaire2)&lt;br /&gt;
        allow(team.assignment).to receive(:compute_total_score).with(scores.except(:total_score)).and_return(10)&lt;br /&gt;
        expect(team.scores(questions)).to eq(scores)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: files(directory) ====&lt;br /&gt;
This method in assignment_team.rb successfully returns a list of files in any given directory path, not just the assignment teams directory path.&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned contains a specific file which is known to be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/models&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned does not contain a specific file which is known to not be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is not present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is not present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/controllers&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).not_to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: submit_hyperlink(hyperlink) ====&lt;br /&gt;
This function in assignment_team.rb submits the hyperlink for the team if it is valid or not empty.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the hyperlink is empty and raises an error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a hyperlink is empty&amp;quot; do&lt;br /&gt;
      it &amp;quot;causes an exception to be raised&amp;quot; do&lt;br /&gt;
        expect { team.submit_hyperlink(&amp;quot;&amp;quot;) }.to raise_error(&amp;quot;The hyperlink cannot be empty!&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the hyperlink is invalid and raises a 404 error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a hyperlink is invalid&amp;quot; do&lt;br /&gt;
      it &amp;quot;causes an exception to be raised with the proper HTTP status code&amp;quot; do&lt;br /&gt;
        invalid_hyperlink = &amp;quot;https://expertiza.ncsu.edu/not_a_valid_path&amp;quot;&lt;br /&gt;
        allow(Net::HTTP).to receive(:get_response).and_return(&amp;quot;404&amp;quot;)&lt;br /&gt;
        expect { team.submit_hyperlink(invalid_hyperlink) }.to raise_error(&amp;quot;HTTP status code: 404&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the the hyperlink has been submitted or not.&lt;br /&gt;
    context &amp;quot;when a valid hyperlink not in a certain improper format is submitted&amp;quot; do&lt;br /&gt;
      it &amp;quot;it is fixed and is saved to the database&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([&amp;quot;https://expertiza.ncsu.edu&amp;quot;])&lt;br /&gt;
        allow(team).to receive(:submitted_hyperlinks=)&lt;br /&gt;
        allow(team).to receive(:save)&lt;br /&gt;
        allow(Net::HTTP).to receive(:get_response).and_return(&amp;quot;0&amp;quot;)&lt;br /&gt;
        allow(YAML).to receive(:dump).with([&amp;quot;https://expertiza.ncsu.edu&amp;quot;, &amp;quot;www.ncsu.edu&amp;quot;])&lt;br /&gt;
        expect(team).to receive(:submitted_hyperlinks=)&lt;br /&gt;
        expect(team).to receive(:save)&lt;br /&gt;
        expect(YAML).to receive(:dump).with([&amp;quot;https://expertiza.ncsu.edu&amp;quot;, &amp;quot;http://www.ncsu.edu&amp;quot;])&lt;br /&gt;
        team.submit_hyperlink(&amp;quot;www.ncsu.edu  &amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: remove_hyperlink(hyperlink_to_delete) ====&lt;br /&gt;
This function in assignment_team.rb removes the hyperlink submitted by the team.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the hyperlink has been deleted or not.&lt;br /&gt;
  describe &amp;quot;#remove_hyperlink&amp;quot; do&lt;br /&gt;
    context &amp;quot;when the hyperlink is in the assignment team's hyperlinks&amp;quot; do&lt;br /&gt;
      it &amp;quot;is removed from the team's list of hyperlinks&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([&amp;quot;https://expertiza.ncsu.edu&amp;quot;, &amp;quot;https://www.ncsu.edu&amp;quot;])&lt;br /&gt;
        expect(team).to receive(:submitted_hyperlinks=)&lt;br /&gt;
        expect(team).to receive(:save)&lt;br /&gt;
        expect(YAML).to receive(:dump).with([&amp;quot;https://expertiza.ncsu.edu&amp;quot;])&lt;br /&gt;
        team.remove_hyperlink(&amp;quot;https://www.ncsu.edu&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.team(participant) ====&lt;br /&gt;
This function in assignment_team.rb returns the AssingmentTeam object that the given participant belongs to.&lt;br /&gt;
&lt;br /&gt;
The unit test first builds a user and assigns that user as a participant1 of the team. Then allows that participant to be added as a team user and finally search the team for the given team user and expect the team for participant1 to be equal to the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when there is a participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the team for participant&amp;quot; do&lt;br /&gt;
        teamuser = build(:team_user, id: 1, team_id: team.id, user_id: user1.id)&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(TeamsUser).to receive(:where).with(user_id: participant1.user_id).and_return([teamuser])&lt;br /&gt;
        allow(Team).to receive(:find).with(teamuser.team_id).and_return(team)&lt;br /&gt;
        expect(AssignmentTeam.team(participant1)).to eq(team)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.export_fields(options) ====&lt;br /&gt;
This function in assignment_team.rb exports the fields for a given set of options. It always returns a list containing [&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;] if the given set of options have a team name set to true.&lt;br /&gt;
&lt;br /&gt;
The unit test expects the method to return a static list of strings for the team passed as options, with the team having a name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team has name&amp;quot; do&lt;br /&gt;
      it &amp;quot;exports the fields&amp;quot; do&lt;br /&gt;
        expect(AssignmentTeam.export_fields(team)).to eq([&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.remove_team_by_id(id) ====&lt;br /&gt;
This function in assignment_team.rb removes team by using its id.&lt;br /&gt;
&lt;br /&gt;
The unit test deletes the team by using its id and checks if return value is the instance of class '''AssignmentTeam'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;.remove_team_by_id&amp;quot; do&lt;br /&gt;
    context &amp;quot;when a team has an id&amp;quot; do&lt;br /&gt;
      it &amp;quot;delete the team by id&amp;quot; do&lt;br /&gt;
        allow(AssignmentTeam).to receive(:find).with(team.id).and_return(team)&lt;br /&gt;
        expect(AssignmentTeam.remove_team_by_id(team.id)).to eq(team)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: path ====&lt;br /&gt;
This function in assignment_team.rb returns a path to the directory where the team has submitted their files.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is equal to the path belonging to the team's submission.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#path&amp;quot; do&lt;br /&gt;
    it &amp;quot;returns the path&amp;quot; do&lt;br /&gt;
      allow(team).to receive_message_chain(:assignment, :path).and_return(&amp;quot;assignment_path&amp;quot;)&lt;br /&gt;
      allow(team).to receive(:directory_num).and_return(5)&lt;br /&gt;
      expect(team.path).to eq &amp;quot;assignment_path/5&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: set_student_directory_num ====&lt;br /&gt;
This function in assignment_team.rb sets the directory number for the team.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the directory number for the team has been set. The test will check if the return value is equal to true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#set_student_directory_num&amp;quot; do&lt;br /&gt;
    it &amp;quot;sets the directory for the team&amp;quot; do&lt;br /&gt;
      team = build(:assignment_team, id: 1, parent_id: 1, directory_num: -1)&lt;br /&gt;
      max_num = 0&lt;br /&gt;
      allow(AssignmentTeam).to receive_message_chain(:where, :order, :first, :directory_num).&lt;br /&gt;
        with(parent_id: team.parent_id).with(:directory_num, :desc).with(no_args).with(no_args).and_return(max_num)&lt;br /&gt;
      expect(team.set_student_directory_num).to be true&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: received_any_peer_review? ====&lt;br /&gt;
This function in assignment_team.rb checks if the team has received any peer reviews.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if any instance of '''ReviewResponseMap''' is present for the team.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe &amp;quot;#received_any_peer_review?&amp;quot; do&lt;br /&gt;
    it &amp;quot;checks if the team has received any reviews&amp;quot; do&lt;br /&gt;
      allow(ResponseMap).to receive_message_chain(:where, :any?).with(reviewee_id: team.id, reviewed_object_id: team.parent_id).with(no_args).and_return(true)&lt;br /&gt;
      expect(team.received_any_peer_review?).to be true&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test Design ==&lt;br /&gt;
=== Test Structure ===&lt;br /&gt;
=== Stubs for Isolating the UUT ===&lt;br /&gt;
In order to isolate the unit under test (UUT), i.e. the current method under test, we employed RSpec stubs. We stubbed out database calls and methods that triggered them in order to improve the run time of the unit tests, and we also stubbed out some outgoing command and query messages in order to test only the current method under test.&lt;br /&gt;
&lt;br /&gt;
=== DRY Testing Practices ===&lt;br /&gt;
We exploited factories and the RSpec helper method &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''let'''&amp;lt;/span&amp;gt; as well as &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''context'''&amp;lt;/span&amp;gt; blocks to make our unit tests shorter, more readable, and more maintainable, or, in essence, DRYer.&lt;br /&gt;
&lt;br /&gt;
==== Factories and the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;let&amp;lt;/span&amp;gt; RSPEC Helper Method ====&lt;br /&gt;
Using the FactoryBot factories in '''factories.rb''' allowed us to use real Expertiza objects in our unit tests. We used the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''FactoryBot.build'''&amp;lt;/span&amp;gt; method to make our objects in order to avoid the run time penalty of saving (and this later having to retrieve) objects from the database. We used the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''let'''&amp;lt;/span&amp;gt; method with the factory as in the example below to make lazy-allocated objects which are cached throughout each example, improving run time.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;let(:team) { build(:assignment_team, id: 1, parent_id: 1) }&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whenever &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''team'''&amp;lt;/span&amp;gt; is called in an example, it returns the same value, i.e. the same object, which essentially allows tests that need it to have access to the same object without the need for allocating it as a class variable or instance variable for all of the tests or some of the tests. We placed these statements outside the scope of our unit test examples so the same objects could be used throughout all of them, DRYing out the test code.&lt;br /&gt;
&lt;br /&gt;
== Testing Framework ==&lt;br /&gt;
&lt;br /&gt;
=== RSpec Introduction ===&lt;br /&gt;
[http://rspec.info/ RSPEC] is a testing framework for Ruby for behavior-driven development (BDD) licensed under MIT. It is inspired by JBehave and contains fully integrated JMock based framework which has a very rich and powerful DSL (domain-specific language) which resembles a natural language specification. Composed of multiple libraries structured to work together, RSpec provides encapsulated testing via the describe block to specify the behavior of the class and the context for the unit test case.&lt;br /&gt;
&lt;br /&gt;
=== Why RSpec? ===&lt;br /&gt;
RSpec is easy to learn and implement and can be used with other testing tools like Cucumber and Minitest independently. It is extremely powerful for testing states with complicated setup and also helps in tearing down complex code to access the objects required for testing RSpec semantics encourage agile thinking and practice and it structures the tests in a more intuitive way.&lt;br /&gt;
&lt;br /&gt;
== Bugs Fixed ==&lt;br /&gt;
During testing of the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; model, we found two bugs, one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt; and one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''http://'''&amp;lt;/span&amp;gt; was ''appended'' to hyperlink strings without this tag or&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''https://'''&amp;lt;/span&amp;gt; at the start of them, rather than ''prepended''. We fixed this error in our pull request. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''id'''&amp;lt;/span&amp;gt;, an undefined parameter, was referenced while raising an exception, and we updated it to &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''assignment_id'''&amp;lt;/span&amp;gt;, which was the actual name of the parameter passed to the method.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
The model has a total of 237 lines, out of which 127 were relevant lines.&lt;br /&gt;
We achieved 100% coverage with avg hits per line at 2.3 (the number of times each specific line was run during the test suite)&lt;br /&gt;
&lt;br /&gt;
[[File:Coverage_header.png]]&lt;br /&gt;
[[File:Coverage_line.png]]&lt;br /&gt;
&lt;br /&gt;
== Future Work ==&lt;br /&gt;
&lt;br /&gt;
DRY principle could be cleaned up a little more. Sometimes it became necessary to use the '''let''' or '''build''' helper methods in each unit test. They may all be consolidated at the beginning. &amp;lt;br&amp;gt;&lt;br /&gt;
Some more edge cases could be thought of for each method, and tests written for those. Although, we have tried to cover as many as possible. &amp;lt;br&amp;gt;&lt;br /&gt;
Additionally, in the future, the code may also be refactored with a more efficient tool. &amp;lt;br&amp;gt;&lt;br /&gt;
Test coverage through quality tests consistently added throughout the development of the Expertiza project should be the future work of the project. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1. [http://expertiza.ncsu.edu Expertiza] &amp;lt;br&amp;gt;&lt;br /&gt;
2. [http://wiki.expertiza.ncsu.edu/index.php/Main_Page#Expertiza Expertiza Wikipedia ]&amp;lt;br&amp;gt;&lt;br /&gt;
3. [https://github.com/expertiza/expertiza Expertiza Github Repository]&amp;lt;br&amp;gt;&lt;br /&gt;
4. [https://relishapp.com/rspec RSpec - Relish]&amp;lt;br&amp;gt;&lt;br /&gt;
5. [https://sites.google.com/site/longlastingsoftware Engineering Software as a Service]&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117996</id>
		<title>CSC/ECE 517 Fall 2018- Project E1848: Writing unit tests for assignment team.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117996"/>
		<updated>2018-11-02T15:27:15Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: /* DRY Testing Practices */  Add section summary and factories and let method info.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this project is to improve the coverage and quality of the unit tests for the assignment team model in Expertiza. This project comprised the program 3 assignment of CSC/ECE 517 in fall 2018 and is entitled &amp;quot;Project E1848: Writing unit tests for assignment_team.rb.&amp;quot; The source code for this project is in [https://github.com/expertiza/expertiza/pull/1228 pull request #1228] of the [https://github.com/expertiza Expertiza project] on [https://github.com/ GitHub].&lt;br /&gt;
&lt;br /&gt;
== Key Contributions ==&lt;br /&gt;
&lt;br /&gt;
Out of the 30 methods defined for the model AssignmentTeam.rb, test case was written for only one. Our contribution was to successfully add test cases for all remaining 29 methods.&lt;br /&gt;
&lt;br /&gt;
Hence, increasing the coverage from 5% to 100%.&lt;br /&gt;
&lt;br /&gt;
== The Class under Test ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
This class handles all functionalities for a team linked to an assignment. Some of the functionalities include, get a list of participants in the team, get the team name, team score for the given assignment, submissions for this team (files) and (hyperlinks) and topic picked by the team. Add/or remove participants from the team. It also checks for any reviews the team may have gotten for their work. Export all teams in a CSV file, import files from CSV to form teams.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
== Test Design ==&lt;br /&gt;
=== Test Structure ===&lt;br /&gt;
Listed below are the functionalities and the Rspec unit tests corresponding to the function names along with a list of scenarios tested.&lt;br /&gt;
&lt;br /&gt;
==== '''Function name: includes?(participant)''' ====&lt;br /&gt;
This function in assignment_team.rb checks if the '''participant''' passed as argument is a member of the team or not. For this, we utilize factorybot to build a user and a participant1 as follows-:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  let(:user1) { build(:student, id: 2) }&lt;br /&gt;
  let(:participant1) { build(:participant, id: 1) }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test cases checked for are-: &amp;lt;br&amp;gt;&lt;br /&gt;
1) when the team receives a user, that user is allowed to become a team participant. The method returns '''True''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has one participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes one participant&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        expect(team.includes?(participant1)).to eq true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) when the team receives a user with no arguments, that user is '''not''' allowed to become a team participant. The method returns '''False''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has no users&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([])&lt;br /&gt;
        expect(team.includes?(participant1)).to eq false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: parent_model ====&lt;br /&gt;
This function in assignment_team.rb always provides the name of the parent model which is '''Assignment'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;Assignment&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the name of the parent model&amp;quot; do&lt;br /&gt;
      expect(team.parent_model).to eq &amp;quot;Assignment&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.parent_model(id) ====&lt;br /&gt;
This function in assignment_team.rb takes in as argument id of the current '''Assignment''' for the team and returns an instance of the parent model.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the instance returned by this method for a given assignment id, matches the assignment or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the parent model&amp;quot; do&lt;br /&gt;
      allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
      expect(AssignmentTeam.parent_model(1)).to eq assignment&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: fullname ====&lt;br /&gt;
This function in assignment_team.rb print out the name for the current class instance. for this we first build an assignment team instance and assign it the name '''&amp;quot;abcd&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the assignment team has a name, and returns that same name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when the team has a name&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the name of the class&amp;quot; do&lt;br /&gt;
        team = build(:assignment_team, id: 1, name: &amp;quot;abcd&amp;quot;)&lt;br /&gt;
        expect(team.fullname).to eq &amp;quot;abcd&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: review_map_type ====&lt;br /&gt;
This function in assignment_team.rb always provides the name of the review map type which is '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;ReviewResponseMap&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the review map type&amp;quot; do&lt;br /&gt;
      expect(team.review_map_type).to eq &amp;quot;ReviewResponseMap&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.prototype ====&lt;br /&gt;
This function in assignment_team.rb implements the prototype pattern by returning a new instance of the class '''AssignmentTeam'''.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is a new instance of the class or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the AssignmentTeam&amp;quot; do&lt;br /&gt;
      expect(AssignmentTeam).to receive(:new).with(no_args)&lt;br /&gt;
      AssignmentTeam.prototype&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: assign_reviewer(reviewer) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: reviewed_by?(reviewer) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: topic ====&lt;br /&gt;
This function in assignment_team.rb return the id of the topic picked by the team for the assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test first stubs a topic for the given assignment, allows a SignedUpTeam object to receive that topic and AssignmentTeam id, and return the topic id to check if it matches with the topic id of the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context &amp;quot;when the team has picked a topic&amp;quot; do&lt;br /&gt;
    it &amp;quot;provides the topic id&amp;quot; do&lt;br /&gt;
      assignment = team.assignment&lt;br /&gt;
      allow(SignUpTopic).to receive(:find_by).with(assignment: assignment).and_return(topic)&lt;br /&gt;
      allow(SignedUpTeam).to receive_message_chain(:find_by, :try).with(team_id: team.id).with(:topic_id).and_return(topic.id)&lt;br /&gt;
      expect(team.topic).to eq(topic.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: has_submissions? ====&lt;br /&gt;
this function in assignment_team.rb is used to check if the team has submitted their work or not.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the team to receive submissions, by first receiving files as submission, then hyperlink as submission, and for each expects the the team's submission to be true when the function is called.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a team has submitted files&amp;quot; do&lt;br /&gt;
      it &amp;quot;has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_files, :any?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when the team has submitted hyperlink&amp;quot; do&lt;br /&gt;
      it &amp;quot;checks if the team has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_hyperlinks, :present?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    after(:each) do&lt;br /&gt;
      expect(team.has_submissions?).to be true&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: participants ====&lt;br /&gt;
This function in assignment_team.rb returns a list of all participants in the team.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive two user instances and then adds these users as participants of the team. The test then expects the function to return a list of these two users as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has two participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;has those two participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
        expect(team.participants).to eq [participant1, participant2]&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive a user instance but does not add this user as participant of the team. The test then expects the function to return an empty list as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has a user but no participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(nil)&lt;br /&gt;
        expect(team.participants).to eq []&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: delete ====&lt;br /&gt;
This function in assignment_team.rb deletes the AssignmentTeam by destroying each participant in the team and returns an instance of AssignmentTeam.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows two users to be added as team participants. The test checks if the team deleted matches the current team instance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;deletes the team&amp;quot; do&lt;br /&gt;
      allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
      expect(team.delete).to eq(team)&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: destroy ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.get_first_member(team_id) ====&lt;br /&gt;
This function in assignment_team.rb returns the instance of the first participant of the team for the given team id.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the assignment to receive a user, add it as a participant and return the first participant in the team. The test expects the function to return an instance of this participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team id is present&amp;quot; do&lt;br /&gt;
      it &amp;quot;get first member of the  team&amp;quot; do&lt;br /&gt;
        allow(AssignmentTeam).to receive_message_chain(:find_by, :try, :try).with(id: team.id).with(:participant).with(:first).and_return(participant1)&lt;br /&gt;
        expect(AssignmentTeam.get_first_member(team.id)).to eq(participant1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: submitted_files(path = self.path) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.import(row, assignment_id, options) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.export(csv, parent_id, options) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: copy(course_id) ====&lt;br /&gt;
This function in assignment_team.rb copies the current assignment team and creates a new CourseTeam instance from the given team. It takes as parameter the id of the course assignment team has.&lt;br /&gt;
&lt;br /&gt;
The test grabs the course id from the assignment team and calls the function to check if a course team is successfully created or not. The function returns and empty array, otherwise returns '''nil''' if the course team is not created successfully.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;for given assignment team&amp;quot; do&lt;br /&gt;
      it &amp;quot;copies the assignment team to course team&amp;quot; do&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        course = assignment.course&lt;br /&gt;
        expect(team.copy(course.id)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: add_participant(assignment_id, user) ====&lt;br /&gt;
This function in assignment_team.rb adds the user to the AssignmentTeam for the given assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test creates a user, and passes the user, assignment id for the team to the function and expects the result to be an instance of '''AssignmentParticipant''' meaning the user was successfully added as a participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is not a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;adds the user to the team&amp;quot; do&lt;br /&gt;
        user = build(:student, id: 10)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user)).to be_an_instance_of(AssignmentParticipant)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The unit test creates a user, adds him as a participant to the team, and passes the user, assignment id for the team to the function and expects the result to be '''nil''' as the user already exists as participant of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is already a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns without adding user to the team&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user1)).to eq(nil)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: scores(questions) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: files(directory) ====&lt;br /&gt;
This method in assignment_team.rb successfully returns a list of files in any given directory path, not just the assignment teams directory path.&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned contains a specific file which is known to be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/models&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned does not contain a specific file which is known to not be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is not present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is not present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/controllers&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).not_to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: submit_hyperlink(hyperlink) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: remove_hyperlink(hyperlink_to_delete) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.team(participant) ====&lt;br /&gt;
This function in assignment_team.rb returns the AssingmentTeam object that the given participant belongs to.&lt;br /&gt;
&lt;br /&gt;
The unit test first builds a user and assigns that user as a participant1 of the team. Then allows that participant to be added as a team user and finally search the team for the given team user and expect the team for participant1 to be equal to the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when there is a participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the team for participant&amp;quot; do&lt;br /&gt;
        teamuser = build(:team_user, id: 1, team_id: team.id, user_id: user1.id)&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(TeamsUser).to receive(:where).with(user_id: participant1.user_id).and_return([teamuser])&lt;br /&gt;
        allow(Team).to receive(:find).with(teamuser.team_id).and_return(team)&lt;br /&gt;
        expect(AssignmentTeam.team(participant1)).to eq(team)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.export_fields(options) ====&lt;br /&gt;
This function in assignment_team.rb exports the fields for a given set of options. It always returns a list containing [&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;] if the given set of options have a team name set to true.&lt;br /&gt;
&lt;br /&gt;
The unit test expects the method to return a static list of strings for the team passed as options, with the team having a name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team has name&amp;quot; do&lt;br /&gt;
      it &amp;quot;exports the fields&amp;quot; do&lt;br /&gt;
        expect(AssignmentTeam.export_fields(team)).to eq([&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.remove_team_by_id(id) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: path ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: set_student_directory_num ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: received_any_peer_review? ====&lt;br /&gt;
&lt;br /&gt;
=== Test Coverage ===&lt;br /&gt;
The model has a total of 237 lines, out of which 127 were relevant lines.&lt;br /&gt;
We achieved 100% coverage with avg hits per line at 2.3 (the number of times each specific line was run during the test suite)&lt;br /&gt;
&lt;br /&gt;
[[File:Coverage_header.png]]&lt;br /&gt;
[[File:Coverage_line.png]]&lt;br /&gt;
&lt;br /&gt;
=== Stubs for Isolating the UUT ===&lt;br /&gt;
In order to isolate the unit under test (UUT), i.e. the current method under test, we employed RSpec stubs. We stubbed out database calls and methods that triggered them in order to improve the run time of the unit tests, and we also stubbed out some outgoing command and query messages in order to test only the current method under test.&lt;br /&gt;
&lt;br /&gt;
=== DRY Testing Practices ===&lt;br /&gt;
We exploited factories and the RSpec helper method &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''let'''&amp;lt;/span&amp;gt; as well as &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''context'''&amp;lt;/span&amp;gt; blocks to make our unit tests shorter, more readable, and more maintainable, or, in essence, DRYer.&lt;br /&gt;
&lt;br /&gt;
==== Factories and the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;let&amp;lt;/span&amp;gt; RSPEC Helper Method ====&lt;br /&gt;
Using the FactoryBot factories in '''factories.rb''' allowed us to use real Expertiza objects in our unit tests. We used the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''FactoryBot.build'''&amp;lt;/span&amp;gt; method to make our objects in order to avoid the run time penalty of saving (and this later having to retrieve) objects from the database. We used the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''let'''&amp;lt;/span&amp;gt; method with the factory as in the example below to make lazy-allocated objects which are cached throughout each example, improving run time.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;let(:team) { build(:assignment_team, id: 1, parent_id: 1) }&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whenever &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''team'''&amp;lt;/span&amp;gt; is called in an example, it returns the same value, i.e. the same object, which essentially allows tests that need it to have access to the same object without the need for allocating it as a class variable or instance variable for all of the tests or some of the tests. We placed these statements outside the scope of our unit test examples so the same objects could be used throughout all of them, DRYing out the test code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Contexts ====&lt;br /&gt;
&lt;br /&gt;
== Testing Framework ==&lt;br /&gt;
&lt;br /&gt;
=== RSpec Introduction ===&lt;br /&gt;
[http://rspec.info/ RSPEC] is a testing framework for Ruby for behavior-driven development (BDD) licensed under MIT. It is inspired by JBehave and contains fully integrated JMock based framework which has a very rich and powerful DSL (domain-specific language) which resembles a natural language specification. Composed of multiple libraries structured to work together, RSpec provides encapsulated testing via the describe block to specify the behavior of the class and the context for the unit test case.&lt;br /&gt;
&lt;br /&gt;
=== Why RSpec? ===&lt;br /&gt;
RSpec is easy to learn and implement and can be used with other testing tools like Cucumber and Minitest independently. It is extremely powerful for testing states with complicated setup and also helps in tearing down complex code to access the objects required for testing RSpec semantics encourage agile thinking and practice and it structures the tests in a more intuitive way.&lt;br /&gt;
&lt;br /&gt;
== Bugs Fixed ==&lt;br /&gt;
During testing of the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; model, we found two bugs, one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt; and one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''http://'''&amp;lt;/span&amp;gt; was ''appended'' to hyperlink strings without this tag or&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''https://'''&amp;lt;/span&amp;gt; at the start of them, rather than ''prepended''. We fixed this error in our pull request. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''id'''&amp;lt;/span&amp;gt;, an undefined parameter, was referenced while raising an exception, and we updated it to &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''assignment_id'''&amp;lt;/span&amp;gt;, which was the actual name of the parameter passed to the method.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
== Future Work ==&lt;br /&gt;
&lt;br /&gt;
DRY principle could be cleaned up a little more. Sometimes it became necessary to use the '''let''' or '''build''' helper methods in each unit test. They may all be consolidated at the beginning. &amp;lt;br&amp;gt;&lt;br /&gt;
Some more edge cases could be thought of for each method, and tests written for those. Although, we have tried to cover as many as possible. &amp;lt;br&amp;gt;&lt;br /&gt;
Additionally, in the future, the code may also be refactored with a more efficient tool. &amp;lt;br&amp;gt;&lt;br /&gt;
Test coverage through quality tests consistently added throughout the development of the Expertiza project should be the future work of the project. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1. [http://expertiza.ncsu.edu Expertiza] &amp;lt;br&amp;gt;&lt;br /&gt;
2. [http://wiki.expertiza.ncsu.edu/index.php/Main_Page#Expertiza Expertiza Wikipedia ]&amp;lt;br&amp;gt;&lt;br /&gt;
3. [https://github.com/expertiza/expertiza Expertiza Github Repository]&amp;lt;br&amp;gt;&lt;br /&gt;
4. [https://relishapp.com/rspec RSpec - Relish]&amp;lt;br&amp;gt;&lt;br /&gt;
5. [https://sites.google.com/site/longlastingsoftware Engineering Software as a Service]&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117981</id>
		<title>CSC/ECE 517 Fall 2018- Project E1848: Writing unit tests for assignment team.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117981"/>
		<updated>2018-11-02T14:52:49Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: /* Stubs for Isolating the UUT */  Fill in the section.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this project is to improve the coverage and quality of the unit tests for the assignment team model in Expertiza. This project comprised the program 3 assignment of CSC/ECE 517 in fall 2018 and is entitled &amp;quot;Project E1848: Writing unit tests for assignment_team.rb.&amp;quot; The source code for this project is in [https://github.com/expertiza/expertiza/pull/1228 pull request #1228] of the [https://github.com/expertiza Expertiza project] on [https://github.com/ GitHub].&lt;br /&gt;
&lt;br /&gt;
== Key Contributions ==&lt;br /&gt;
&lt;br /&gt;
Out of the 30 methods defined for the model AssignmentTeam.rb, test case was written for only one. Our contribution was to successfully add test cases for all remaining 29 methods.&lt;br /&gt;
&lt;br /&gt;
Hence, increasing the coverage from 5% to 100%.&lt;br /&gt;
&lt;br /&gt;
== The Class under Test ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
This class handles all functionalities for a team linked to an assignment. Some of the functionalities include, get a list of participants in the team, get the team name, team score for the given assignment, submissions for this team (files) and (hyperlinks) and topic picked by the team. Add/or remove participants from the team. It also checks for any reviews the team may have gotten for their work. Export all teams in a CSV file, import files from CSV to form teams.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
== Test Design ==&lt;br /&gt;
=== Test Structure ===&lt;br /&gt;
Listed below are the functionalities and the Rspec unit tests corresponding to the function names along with a list of scenarios tested.&lt;br /&gt;
&lt;br /&gt;
==== '''Function name: includes?(participant)''' ====&lt;br /&gt;
This function in assignment_team.rb checks if the '''participant''' passed as argument is a member of the team or not. For this, we utilize factorybot to build a user and a participant1 as follows-:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  let(:user1) { build(:student, id: 2) }&lt;br /&gt;
  let(:participant1) { build(:participant, id: 1) }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test cases checked for are-: &amp;lt;br&amp;gt;&lt;br /&gt;
1) when the team receives a user, that user is allowed to become a team participant. The method returns '''True''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has one participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes one participant&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        expect(team.includes?(participant1)).to eq true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) when the team receives a user with no arguments, that user is '''not''' allowed to become a team participant. The method returns '''False''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has no users&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([])&lt;br /&gt;
        expect(team.includes?(participant1)).to eq false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: parent_model ====&lt;br /&gt;
This function in assignment_team.rb always provides the name of the parent model which is '''Assignment'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;Assignment&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the name of the parent model&amp;quot; do&lt;br /&gt;
      expect(team.parent_model).to eq &amp;quot;Assignment&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.parent_model(id) ====&lt;br /&gt;
This function in assignment_team.rb takes in as argument id of the current '''Assignment''' for the team and returns an instance of the parent model.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the instance returned by this method for a given assignment id, matches the assignment or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the parent model&amp;quot; do&lt;br /&gt;
      allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
      expect(AssignmentTeam.parent_model(1)).to eq assignment&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: fullname ====&lt;br /&gt;
This function in assignment_team.rb print out the name for the current class instance. for this we first build an assignment team instance and assign it the name '''&amp;quot;abcd&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the assignment team has a name, and returns that same name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when the team has a name&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the name of the class&amp;quot; do&lt;br /&gt;
        team = build(:assignment_team, id: 1, name: &amp;quot;abcd&amp;quot;)&lt;br /&gt;
        expect(team.fullname).to eq &amp;quot;abcd&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: review_map_type ====&lt;br /&gt;
This function in assignment_team.rb always provides the name of the review map type which is '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;ReviewResponseMap&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the review map type&amp;quot; do&lt;br /&gt;
      expect(team.review_map_type).to eq &amp;quot;ReviewResponseMap&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.prototype ====&lt;br /&gt;
This function in assignment_team.rb implements the prototype pattern by returning a new instance of the class '''AssignmentTeam'''.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is a new instance of the class or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the AssignmentTeam&amp;quot; do&lt;br /&gt;
      expect(AssignmentTeam).to receive(:new).with(no_args)&lt;br /&gt;
      AssignmentTeam.prototype&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: assign_reviewer(reviewer) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: reviewed_by?(reviewer) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: topic ====&lt;br /&gt;
This function in assignment_team.rb return the id of the topic picked by the team for the assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test first stubs a topic for the given assignment, allows a SignedUpTeam object to receive that topic and AssignmentTeam id, and return the topic id to check if it matches with the topic id of the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context &amp;quot;when the team has picked a topic&amp;quot; do&lt;br /&gt;
    it &amp;quot;provides the topic id&amp;quot; do&lt;br /&gt;
      assignment = team.assignment&lt;br /&gt;
      allow(SignUpTopic).to receive(:find_by).with(assignment: assignment).and_return(topic)&lt;br /&gt;
      allow(SignedUpTeam).to receive_message_chain(:find_by, :try).with(team_id: team.id).with(:topic_id).and_return(topic.id)&lt;br /&gt;
      expect(team.topic).to eq(topic.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: has_submissions? ====&lt;br /&gt;
this function in assignment_team.rb is used to check if the team has submitted their work or not.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the team to receive submissions, by first receiving files as submission, then hyperlink as submission, and for each expects the the team's submission to be true when the function is called.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a team has submitted files&amp;quot; do&lt;br /&gt;
      it &amp;quot;has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_files, :any?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when the team has submitted hyperlink&amp;quot; do&lt;br /&gt;
      it &amp;quot;checks if the team has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_hyperlinks, :present?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    after(:each) do&lt;br /&gt;
      expect(team.has_submissions?).to be true&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: participants ====&lt;br /&gt;
This function in assignment_team.rb returns a list of all participants in the team.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive two user instances and then adds these users as participants of the team. The test then expects the function to return a list of these two users as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has two participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;has those two participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
        expect(team.participants).to eq [participant1, participant2]&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive a user instance but does not add this user as participant of the team. The test then expects the function to return an empty list as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has a user but no participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(nil)&lt;br /&gt;
        expect(team.participants).to eq []&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: delete ====&lt;br /&gt;
This function in assignment_team.rb deletes the AssignmentTeam by destroying each participant in the team and returns an instance of AssignmentTeam.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows two users to be added as team participants. The test checks if the team deleted matches the current team instance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;deletes the team&amp;quot; do&lt;br /&gt;
      allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
      expect(team.delete).to eq(team)&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: destroy ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.get_first_member(team_id) ====&lt;br /&gt;
This function in assignment_team.rb returns the instance of the first participant of the team for the given team id.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the assignment to receive a user, add it as a participant and return the first participant in the team. The test expects the function to return an instance of this participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team id is present&amp;quot; do&lt;br /&gt;
      it &amp;quot;get first member of the  team&amp;quot; do&lt;br /&gt;
        allow(AssignmentTeam).to receive_message_chain(:find_by, :try, :try).with(id: team.id).with(:participant).with(:first).and_return(participant1)&lt;br /&gt;
        expect(AssignmentTeam.get_first_member(team.id)).to eq(participant1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: submitted_files(path = self.path) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.import(row, assignment_id, options) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.export(csv, parent_id, options) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: copy(course_id) ====&lt;br /&gt;
This function in assignment_team.rb copies the current assignment team and creates a new CourseTeam instance from the given team. It takes as parameter the id of the course assignment team has.&lt;br /&gt;
&lt;br /&gt;
The test grabs the course id from the assignment team and calls the function to check if a course team is successfully created or not. The function returns and empty array, otherwise returns '''nil''' if the course team is not created successfully.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;for given assignment team&amp;quot; do&lt;br /&gt;
      it &amp;quot;copies the assignment team to course team&amp;quot; do&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        course = assignment.course&lt;br /&gt;
        expect(team.copy(course.id)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: add_participant(assignment_id, user) ====&lt;br /&gt;
This function in assignment_team.rb adds the user to the AssignmentTeam for the given assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test creates a user, and passes the user, assignment id for the team to the function and expects the result to be an instance of '''AssignmentParticipant''' meaning the user was successfully added as a participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is not a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;adds the user to the team&amp;quot; do&lt;br /&gt;
        user = build(:student, id: 10)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user)).to be_an_instance_of(AssignmentParticipant)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The unit test creates a user, adds him as a participant to the team, and passes the user, assignment id for the team to the function and expects the result to be '''nil''' as the user already exists as participant of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is already a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns without adding user to the team&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user1)).to eq(nil)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: scores(questions) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: files(directory) ====&lt;br /&gt;
This method in assignment_team.rb successfully returns a list of files in any given directory path, not just the assignment teams directory path.&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned contains a specific file which is known to be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/models&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned does not contain a specific file which is known to not be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is not present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is not present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/controllers&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).not_to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: submit_hyperlink(hyperlink) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: remove_hyperlink(hyperlink_to_delete) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.team(participant) ====&lt;br /&gt;
This function in assignment_team.rb returns the AssingmentTeam object that the given participant belongs to.&lt;br /&gt;
&lt;br /&gt;
The unit test first builds a user and assigns that user as a participant1 of the team. Then allows that participant to be added as a team user and finally search the team for the given team user and expect the team for participant1 to be equal to the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when there is a participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the team for participant&amp;quot; do&lt;br /&gt;
        teamuser = build(:team_user, id: 1, team_id: team.id, user_id: user1.id)&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(TeamsUser).to receive(:where).with(user_id: participant1.user_id).and_return([teamuser])&lt;br /&gt;
        allow(Team).to receive(:find).with(teamuser.team_id).and_return(team)&lt;br /&gt;
        expect(AssignmentTeam.team(participant1)).to eq(team)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.export_fields(options) ====&lt;br /&gt;
This function in assignment_team.rb exports the fields for a given set of options. It always returns a list containing [&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;] if the given set of options have a team name set to true.&lt;br /&gt;
&lt;br /&gt;
The unit test expects the method to return a static list of strings for the team passed as options, with the team having a name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team has name&amp;quot; do&lt;br /&gt;
      it &amp;quot;exports the fields&amp;quot; do&lt;br /&gt;
        expect(AssignmentTeam.export_fields(team)).to eq([&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.remove_team_by_id(id) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: path ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: set_student_directory_num ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: received_any_peer_review? ====&lt;br /&gt;
&lt;br /&gt;
=== Test Coverage ===&lt;br /&gt;
The model has a total of 237 lines, out of which 127 were relevant lines.&lt;br /&gt;
We achieved 100% coverage with avg hits per line at 2.3 (the number of times each specific line was run during the test suite)&lt;br /&gt;
&lt;br /&gt;
[[File:Coverage_header.png]]&lt;br /&gt;
[[File:Coverage_line.png]]&lt;br /&gt;
&lt;br /&gt;
=== Stubs for Isolating the UUT ===&lt;br /&gt;
In order to isolate the unit under test (UUT), i.e. the current method under test, we employed RSpec stubs. We stubbed out database calls and methods that triggered them in order to improve the run time of the unit tests, and we also stubbed out some outgoing command and query messages in order to test only the current method under test.&lt;br /&gt;
&lt;br /&gt;
=== DRY Testing Practices ===&lt;br /&gt;
==== Factories and the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;let&amp;lt;/span&amp;gt; RSPEC Helper Method ====&lt;br /&gt;
==== Contexts ====&lt;br /&gt;
&lt;br /&gt;
== Testing Framework ==&lt;br /&gt;
&lt;br /&gt;
=== RSpec Introduction ===&lt;br /&gt;
[http://rspec.info/ RSPEC] is a testing framework for Ruby for behavior-driven development (BDD) licensed under MIT. It is inspired by JBehave and contains fully integrated JMock based framework which has a very rich and powerful DSL (domain-specific language) which resembles a natural language specification. Composed of multiple libraries structured to work together, RSpec provides encapsulated testing via the describe block to specify the behavior of the class and the context for the unit test case.&lt;br /&gt;
&lt;br /&gt;
=== Why RSpec? ===&lt;br /&gt;
RSpec is easy to learn and implement and can be used with other testing tools like Cucumber and Minitest independently. It is extremely powerful for testing states with complicated setup and also helps in tearing down complex code to access the objects required for testing RSpec semantics encourage agile thinking and practice and it structures the tests in a more intuitive way.&lt;br /&gt;
&lt;br /&gt;
== Bugs Fixed ==&lt;br /&gt;
During testing of the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; model, we found two bugs, one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt; and one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''http://'''&amp;lt;/span&amp;gt; was ''appended'' to hyperlink strings without this tag or&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''https://'''&amp;lt;/span&amp;gt; at the start of them, rather than ''prepended''. We fixed this error in our pull request. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''id'''&amp;lt;/span&amp;gt;, an undefined parameter, was referenced while raising an exception, and we updated it to &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''assignment_id'''&amp;lt;/span&amp;gt;, which was the actual name of the parameter passed to the method.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
== Future Work ==&lt;br /&gt;
&lt;br /&gt;
DRY principle could be cleaned up a little more. Sometimes it became necessary to use the '''let''' or '''build''' helper methods in each unit test. They may all be consolidated at the beginning. &amp;lt;br&amp;gt;&lt;br /&gt;
Some more edge cases could be thought of for each method, and tests written for those. Although, we have tried to cover as many as possible. &amp;lt;br&amp;gt;&lt;br /&gt;
Additionally, in the future, the code may also be refactored with a more efficient tool. &amp;lt;br&amp;gt;&lt;br /&gt;
Test coverage through quality tests consistently added throughout the development of the Expertiza project should be the future work of the project. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1. [http://expertiza.ncsu.edu Expertiza] &amp;lt;br&amp;gt;&lt;br /&gt;
2. [http://wiki.expertiza.ncsu.edu/index.php/Main_Page#Expertiza Expertiza Wikipedia ]&amp;lt;br&amp;gt;&lt;br /&gt;
3. [https://github.com/expertiza/expertiza Expertiza Github Repository]&amp;lt;br&amp;gt;&lt;br /&gt;
4. [https://relishapp.com/rspec RSpec - Relish]&amp;lt;br&amp;gt;&lt;br /&gt;
5. [https://sites.google.com/site/longlastingsoftware Engineering Software as a Service]&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117972</id>
		<title>CSC/ECE 517 Fall 2018- Project E1848: Writing unit tests for assignment team.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117972"/>
		<updated>2018-11-02T14:44:16Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: /* Bugs Detected */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this project is to improve the coverage and quality of the unit tests for the assignment team model in Expertiza. This project comprised the program 3 assignment of CSC/ECE 517 in fall 2018 and is entitled &amp;quot;Project E1848: Writing unit tests for assignment_team.rb.&amp;quot; The source code for this project is in [https://github.com/expertiza/expertiza/pull/1228 pull request #1228] of the [https://github.com/expertiza Expertiza project] on [https://github.com/ GitHub].&lt;br /&gt;
&lt;br /&gt;
== Key Contributions ==&lt;br /&gt;
&lt;br /&gt;
Out of the 30 methods defined for the model AssignmentTeam.rb, test case was written for only one. Our contribution was to successfully add test cases for all remaining 29 methods.&lt;br /&gt;
&lt;br /&gt;
Hence, increasing the coverage from 5% to 100%.&lt;br /&gt;
&lt;br /&gt;
== The Class under Test ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
This class handles all functionalities for a team linked to an assignment. Some of the functionalities include, get a list of participants in the team, get the team name, team score for the given assignment, submissions for this team (files) and (hyperlinks) and topic picked by the team. Add/or remove participants from the team. It also checks for any reviews the team may have gotten for their work. Export all teams in a CSV file, import files from CSV to form teams.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
== Test Design ==&lt;br /&gt;
=== Test Structure ===&lt;br /&gt;
Listed below are the functionalities and the Rspec unit tests corresponding to the function names along with a list of scenarios tested.&lt;br /&gt;
&lt;br /&gt;
==== '''Function name: includes?(participant)''' ====&lt;br /&gt;
This function in assignment_team.rb checks if the '''participant''' passed as argument is a member of the team or not. For this, we utilize factorybot to build a user and a participant1 as follows-:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  let(:user1) { build(:student, id: 2) }&lt;br /&gt;
  let(:participant1) { build(:participant, id: 1) }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test cases checked for are-: &amp;lt;br&amp;gt;&lt;br /&gt;
1) when the team receives a user, that user is allowed to become a team participant. The method returns '''True''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has one participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes one participant&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        expect(team.includes?(participant1)).to eq true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) when the team receives a user with no arguments, that user is '''not''' allowed to become a team participant. The method returns '''False''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has no users&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([])&lt;br /&gt;
        expect(team.includes?(participant1)).to eq false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: parent_model ====&lt;br /&gt;
This function in assignment_team.rb always provides the name of the parent model which is '''Assignment'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;Assignment&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the name of the parent model&amp;quot; do&lt;br /&gt;
      expect(team.parent_model).to eq &amp;quot;Assignment&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.parent_model(id) ====&lt;br /&gt;
This function in assignment_team.rb takes in as argument id of the current '''Assignment''' for the team and returns an instance of the parent model.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the instance returned by this method for a given assignment id, matches the assignment or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the parent model&amp;quot; do&lt;br /&gt;
      allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
      expect(AssignmentTeam.parent_model(1)).to eq assignment&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: fullname ====&lt;br /&gt;
This function in assignment_team.rb print out the name for the current class instance. for this we first build an assignment team instance and assign it the name '''&amp;quot;abcd&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the assignment team has a name, and returns that same name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when the team has a name&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the name of the class&amp;quot; do&lt;br /&gt;
        team = build(:assignment_team, id: 1, name: &amp;quot;abcd&amp;quot;)&lt;br /&gt;
        expect(team.fullname).to eq &amp;quot;abcd&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: review_map_type ====&lt;br /&gt;
This function in assignment_team.rb always provides the name of the review map type which is '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;ReviewResponseMap&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the review map type&amp;quot; do&lt;br /&gt;
      expect(team.review_map_type).to eq &amp;quot;ReviewResponseMap&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.prototype ====&lt;br /&gt;
This function in assignment_team.rb implements the prototype pattern by returning a new instance of the class '''AssignmentTeam'''.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is a new instance of the class or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the AssignmentTeam&amp;quot; do&lt;br /&gt;
      expect(AssignmentTeam).to receive(:new).with(no_args)&lt;br /&gt;
      AssignmentTeam.prototype&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: assign_reviewer(reviewer) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: reviewed_by?(reviewer) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: topic ====&lt;br /&gt;
This function in assignment_team.rb return the id of the topic picked by the team for the assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test first stubs a topic for the given assignment, allows a SignedUpTeam object to receive that topic and AssignmentTeam id, and return the topic id to check if it matches with the topic id of the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context &amp;quot;when the team has picked a topic&amp;quot; do&lt;br /&gt;
    it &amp;quot;provides the topic id&amp;quot; do&lt;br /&gt;
      assignment = team.assignment&lt;br /&gt;
      allow(SignUpTopic).to receive(:find_by).with(assignment: assignment).and_return(topic)&lt;br /&gt;
      allow(SignedUpTeam).to receive_message_chain(:find_by, :try).with(team_id: team.id).with(:topic_id).and_return(topic.id)&lt;br /&gt;
      expect(team.topic).to eq(topic.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: has_submissions? ====&lt;br /&gt;
this function in assignment_team.rb is used to check if the team has submitted their work or not.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the team to receive submissions, by first receiving files as submission, then hyperlink as submission, and for each expects the the team's submission to be true when the function is called.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a team has submitted files&amp;quot; do&lt;br /&gt;
      it &amp;quot;has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_files, :any?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when the team has submitted hyperlink&amp;quot; do&lt;br /&gt;
      it &amp;quot;checks if the team has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_hyperlinks, :present?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    after(:each) do&lt;br /&gt;
      expect(team.has_submissions?).to be true&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: participants ====&lt;br /&gt;
This function in assignment_team.rb returns a list of all participants in the team.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive two user instances and then adds these users as participants of the team. The test then expects the function to return a list of these two users as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has two participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;has those two participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
        expect(team.participants).to eq [participant1, participant2]&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive a user instance but does not add this user as participant of the team. The test then expects the function to return an empty list as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has a user but no participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(nil)&lt;br /&gt;
        expect(team.participants).to eq []&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: delete ====&lt;br /&gt;
This function in assignment_team.rb deletes the AssignmentTeam by destroying each participant in the team and returns an instance of AssignmentTeam.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows two users to be added as team participants. The test checks if the team deleted matches the current team instance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;deletes the team&amp;quot; do&lt;br /&gt;
      allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
      expect(team.delete).to eq(team)&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: destroy ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.get_first_member(team_id) ====&lt;br /&gt;
This function in assignment_team.rb returns the instance of the first participant of the team for the given team id.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the assignment to receive a user, add it as a participant and return the first participant in the team. The test expects the function to return an instance of this participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team id is present&amp;quot; do&lt;br /&gt;
      it &amp;quot;get first member of the  team&amp;quot; do&lt;br /&gt;
        allow(AssignmentTeam).to receive_message_chain(:find_by, :try, :try).with(id: team.id).with(:participant).with(:first).and_return(participant1)&lt;br /&gt;
        expect(AssignmentTeam.get_first_member(team.id)).to eq(participant1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: submitted_files(path = self.path) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.import(row, assignment_id, options) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.export(csv, parent_id, options) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: copy(course_id) ====&lt;br /&gt;
This function in assignment_team.rb copies the current assignment team and creates a new CourseTeam instance from the given team. It takes as parameter the id of the course assignment team has.&lt;br /&gt;
&lt;br /&gt;
The test grabs the course id from the assignment team and calls the function to check if a course team is successfully created or not. The function returns and empty array, otherwise returns '''nil''' if the course team is not created successfully.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;for given assignment team&amp;quot; do&lt;br /&gt;
      it &amp;quot;copies the assignment team to course team&amp;quot; do&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        course = assignment.course&lt;br /&gt;
        expect(team.copy(course.id)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: add_participant(assignment_id, user) ====&lt;br /&gt;
This function in assignment_team.rb adds the user to the AssignmentTeam for the given assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test creates a user, and passes the user, assignment id for the team to the function and expects the result to be an instance of '''AssignmentParticipant''' meaning the user was successfully added as a participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is not a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;adds the user to the team&amp;quot; do&lt;br /&gt;
        user = build(:student, id: 10)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user)).to be_an_instance_of(AssignmentParticipant)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The unit test creates a user, adds him as a participant to the team, and passes the user, assignment id for the team to the function and expects the result to be '''nil''' as the user already exists as participant of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is already a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns without adding user to the team&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user1)).to eq(nil)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: scores(questions) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: files(directory) ====&lt;br /&gt;
This method in assignment_team.rb successfully returns a list of files in any given directory path, not just the assignment teams directory path.&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned contains a specific file which is known to be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/models&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned does not contain a specific file which is known to not be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is not present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is not present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/controllers&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).not_to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: submit_hyperlink(hyperlink) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: remove_hyperlink(hyperlink_to_delete) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.team(participant) ====&lt;br /&gt;
This function in assignment_team.rb returns the AssingmentTeam object that the given participant belongs to.&lt;br /&gt;
&lt;br /&gt;
The unit test first builds a user and assigns that user as a participant1 of the team. Then allows that participant to be added as a team user and finally search the team for the given team user and expect the team for participant1 to be equal to the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when there is a participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the team for participant&amp;quot; do&lt;br /&gt;
        teamuser = build(:team_user, id: 1, team_id: team.id, user_id: user1.id)&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(TeamsUser).to receive(:where).with(user_id: participant1.user_id).and_return([teamuser])&lt;br /&gt;
        allow(Team).to receive(:find).with(teamuser.team_id).and_return(team)&lt;br /&gt;
        expect(AssignmentTeam.team(participant1)).to eq(team)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.export_fields(options) ====&lt;br /&gt;
This function in assignment_team.rb exports the fields for a given set of options. It always returns a list containing [&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;] if the given set of options have a team name set to true.&lt;br /&gt;
&lt;br /&gt;
The unit test expects the method to return a static list of strings for the team passed as options, with the team having a name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team has name&amp;quot; do&lt;br /&gt;
      it &amp;quot;exports the fields&amp;quot; do&lt;br /&gt;
        expect(AssignmentTeam.export_fields(team)).to eq([&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.remove_team_by_id(id) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: path ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: set_student_directory_num ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: received_any_peer_review? ====&lt;br /&gt;
&lt;br /&gt;
=== Test Coverage ===&lt;br /&gt;
The model has a total of 237 lines, out of which 127 were relevant lines.&lt;br /&gt;
We achieved 100% coverage with avg hits per line at 2.3 (the number of times each specific line was run during the test suite)&lt;br /&gt;
&lt;br /&gt;
[[File:Coverage_header.png]]&lt;br /&gt;
[[File:Coverage_line.png]]&lt;br /&gt;
&lt;br /&gt;
=== Stubs for Isolating the UUT ===&lt;br /&gt;
=== DRY Testing Practices ===&lt;br /&gt;
==== Factories and the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;let&amp;lt;/span&amp;gt; RSPEC Helper Method ====&lt;br /&gt;
==== Contexts ====&lt;br /&gt;
&lt;br /&gt;
== Testing Framework ==&lt;br /&gt;
&lt;br /&gt;
=== RSpec Introduction ===&lt;br /&gt;
[http://rspec.info/ RSPEC] is a testing framework for Ruby for behavior-driven development (BDD) licensed under MIT. It is inspired by JBehave and contains fully integrated JMock based framework which has a very rich and powerful DSL (domain-specific language) which resembles a natural language specification. Composed of multiple libraries structured to work together, RSpec provides encapsulated testing via the describe block to specify the behavior of the class and the context for the unit test case.&lt;br /&gt;
&lt;br /&gt;
=== Why RSpec? ===&lt;br /&gt;
RSpec is easy to learn and implement and can be used with other testing tools like Cucumber and Minitest independently. It is extremely powerful for testing states with complicated setup and also helps in tearing down complex code to access the objects required for testing RSpec semantics encourage agile thinking and practice and it structures the tests in a more intuitive way.&lt;br /&gt;
&lt;br /&gt;
== Bugs Fixed ==&lt;br /&gt;
During testing of the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; model, we found two bugs, one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt; and one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''http://'''&amp;lt;/span&amp;gt; was ''appended'' to hyperlink strings without this tag or&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''https://'''&amp;lt;/span&amp;gt; at the start of them, rather than ''prepended''. We fixed this error in our pull request. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''id'''&amp;lt;/span&amp;gt;, an undefined parameter, was referenced while raising an exception, and we updated it to &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''assignment_id'''&amp;lt;/span&amp;gt;, which was the actual name of the parameter passed to the method.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
== Future Work ==&lt;br /&gt;
&lt;br /&gt;
DRY principle could be cleaned up a little more. Sometimes it became necessary to use the '''let''' or '''build''' helper methods in each unit test. They may all be consolidated at the beginning. &amp;lt;br&amp;gt;&lt;br /&gt;
Some more edge cases could be thought of for each method, and tests written for those. Although, we have tried to cover as many as possible. &amp;lt;br&amp;gt;&lt;br /&gt;
Additionally, in the future, the code may also be refactored with a more efficient tool. &amp;lt;br&amp;gt;&lt;br /&gt;
Test coverage through quality tests consistently added throughout the development of the Expertiza project should be the future work of the project. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1. [http://expertiza.ncsu.edu Expertiza] &amp;lt;br&amp;gt;&lt;br /&gt;
2. [http://wiki.expertiza.ncsu.edu/index.php/Main_Page#Expertiza Expertiza Wikipedia ]&amp;lt;br&amp;gt;&lt;br /&gt;
3. [https://github.com/expertiza/expertiza Expertiza Github Repository]&amp;lt;br&amp;gt;&lt;br /&gt;
4. [https://relishapp.com/rspec RSpec - Relish]&amp;lt;br&amp;gt;&lt;br /&gt;
5. [https://sites.google.com/site/longlastingsoftware Engineering Software as a Service]&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117970</id>
		<title>CSC/ECE 517 Fall 2018- Project E1848: Writing unit tests for assignment team.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117970"/>
		<updated>2018-11-02T14:43:21Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: Fill in the bugs detected section.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this project is to improve the coverage and quality of the unit tests for the assignment team model in Expertiza. This project comprised the program 3 assignment of CSC/ECE 517 in fall 2018 and is entitled &amp;quot;Project E1848: Writing unit tests for assignment_team.rb.&amp;quot; The source code for this project is in [https://github.com/expertiza/expertiza/pull/1228 pull request #1228] of the [https://github.com/expertiza Expertiza project] on [https://github.com/ GitHub].&lt;br /&gt;
&lt;br /&gt;
== Key Contributions ==&lt;br /&gt;
&lt;br /&gt;
Out of the 30 methods defined for the model AssignmentTeam.rb, test case was written for only one. Our contribution was to successfully add test cases for all remaining 29 methods.&lt;br /&gt;
&lt;br /&gt;
Hence, increasing the coverage from 5% to 100%.&lt;br /&gt;
&lt;br /&gt;
== The Class under Test ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
This class handles all functionalities for a team linked to an assignment. Some of the functionalities include, get a list of participants in the team, get the team name, team score for the given assignment, submissions for this team (files) and (hyperlinks) and topic picked by the team. Add/or remove participants from the team. It also checks for any reviews the team may have gotten for their work. Export all teams in a CSV file, import files from CSV to form teams.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
== Test Design ==&lt;br /&gt;
=== Test Structure ===&lt;br /&gt;
Listed below are the functionalities and the Rspec unit tests corresponding to the function names along with a list of scenarios tested.&lt;br /&gt;
&lt;br /&gt;
==== '''Function name: includes?(participant)''' ====&lt;br /&gt;
This function in assignment_team.rb checks if the '''participant''' passed as argument is a member of the team or not. For this, we utilize factorybot to build a user and a participant1 as follows-:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  let(:user1) { build(:student, id: 2) }&lt;br /&gt;
  let(:participant1) { build(:participant, id: 1) }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test cases checked for are-: &amp;lt;br&amp;gt;&lt;br /&gt;
1) when the team receives a user, that user is allowed to become a team participant. The method returns '''True''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has one participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes one participant&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        expect(team.includes?(participant1)).to eq true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) when the team receives a user with no arguments, that user is '''not''' allowed to become a team participant. The method returns '''False''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has no users&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([])&lt;br /&gt;
        expect(team.includes?(participant1)).to eq false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: parent_model ====&lt;br /&gt;
This function in assignment_team.rb always provides the name of the parent model which is '''Assignment'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;Assignment&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the name of the parent model&amp;quot; do&lt;br /&gt;
      expect(team.parent_model).to eq &amp;quot;Assignment&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.parent_model(id) ====&lt;br /&gt;
This function in assignment_team.rb takes in as argument id of the current '''Assignment''' for the team and returns an instance of the parent model.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the instance returned by this method for a given assignment id, matches the assignment or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the parent model&amp;quot; do&lt;br /&gt;
      allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
      expect(AssignmentTeam.parent_model(1)).to eq assignment&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: fullname ====&lt;br /&gt;
This function in assignment_team.rb print out the name for the current class instance. for this we first build an assignment team instance and assign it the name '''&amp;quot;abcd&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the assignment team has a name, and returns that same name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when the team has a name&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the name of the class&amp;quot; do&lt;br /&gt;
        team = build(:assignment_team, id: 1, name: &amp;quot;abcd&amp;quot;)&lt;br /&gt;
        expect(team.fullname).to eq &amp;quot;abcd&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: review_map_type ====&lt;br /&gt;
This function in assignment_team.rb always provides the name of the review map type which is '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;ReviewResponseMap&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the review map type&amp;quot; do&lt;br /&gt;
      expect(team.review_map_type).to eq &amp;quot;ReviewResponseMap&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.prototype ====&lt;br /&gt;
This function in assignment_team.rb implements the prototype pattern by returning a new instance of the class '''AssignmentTeam'''.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is a new instance of the class or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the AssignmentTeam&amp;quot; do&lt;br /&gt;
      expect(AssignmentTeam).to receive(:new).with(no_args)&lt;br /&gt;
      AssignmentTeam.prototype&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: assign_reviewer(reviewer) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: reviewed_by?(reviewer) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: topic ====&lt;br /&gt;
This function in assignment_team.rb return the id of the topic picked by the team for the assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test first stubs a topic for the given assignment, allows a SignedUpTeam object to receive that topic and AssignmentTeam id, and return the topic id to check if it matches with the topic id of the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context &amp;quot;when the team has picked a topic&amp;quot; do&lt;br /&gt;
    it &amp;quot;provides the topic id&amp;quot; do&lt;br /&gt;
      assignment = team.assignment&lt;br /&gt;
      allow(SignUpTopic).to receive(:find_by).with(assignment: assignment).and_return(topic)&lt;br /&gt;
      allow(SignedUpTeam).to receive_message_chain(:find_by, :try).with(team_id: team.id).with(:topic_id).and_return(topic.id)&lt;br /&gt;
      expect(team.topic).to eq(topic.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: has_submissions? ====&lt;br /&gt;
this function in assignment_team.rb is used to check if the team has submitted their work or not.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the team to receive submissions, by first receiving files as submission, then hyperlink as submission, and for each expects the the team's submission to be true when the function is called.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a team has submitted files&amp;quot; do&lt;br /&gt;
      it &amp;quot;has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_files, :any?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when the team has submitted hyperlink&amp;quot; do&lt;br /&gt;
      it &amp;quot;checks if the team has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_hyperlinks, :present?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    after(:each) do&lt;br /&gt;
      expect(team.has_submissions?).to be true&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: participants ====&lt;br /&gt;
This function in assignment_team.rb returns a list of all participants in the team.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive two user instances and then adds these users as participants of the team. The test then expects the function to return a list of these two users as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has two participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;has those two participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
        expect(team.participants).to eq [participant1, participant2]&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive a user instance but does not add this user as participant of the team. The test then expects the function to return an empty list as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has a user but no participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(nil)&lt;br /&gt;
        expect(team.participants).to eq []&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: delete ====&lt;br /&gt;
This function in assignment_team.rb deletes the AssignmentTeam by destroying each participant in the team and returns an instance of AssignmentTeam.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows two users to be added as team participants. The test checks if the team deleted matches the current team instance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;deletes the team&amp;quot; do&lt;br /&gt;
      allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
      expect(team.delete).to eq(team)&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: destroy ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.get_first_member(team_id) ====&lt;br /&gt;
This function in assignment_team.rb returns the instance of the first participant of the team for the given team id.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the assignment to receive a user, add it as a participant and return the first participant in the team. The test expects the function to return an instance of this participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team id is present&amp;quot; do&lt;br /&gt;
      it &amp;quot;get first member of the  team&amp;quot; do&lt;br /&gt;
        allow(AssignmentTeam).to receive_message_chain(:find_by, :try, :try).with(id: team.id).with(:participant).with(:first).and_return(participant1)&lt;br /&gt;
        expect(AssignmentTeam.get_first_member(team.id)).to eq(participant1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: submitted_files(path = self.path) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.import(row, assignment_id, options) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.export(csv, parent_id, options) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: copy(course_id) ====&lt;br /&gt;
This function in assignment_team.rb copies the current assignment team and creates a new CourseTeam instance from the given team. It takes as parameter the id of the course assignment team has.&lt;br /&gt;
&lt;br /&gt;
The test grabs the course id from the assignment team and calls the function to check if a course team is successfully created or not. The function returns and empty array, otherwise returns '''nil''' if the course team is not created successfully.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;for given assignment team&amp;quot; do&lt;br /&gt;
      it &amp;quot;copies the assignment team to course team&amp;quot; do&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        course = assignment.course&lt;br /&gt;
        expect(team.copy(course.id)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: add_participant(assignment_id, user) ====&lt;br /&gt;
This function in assignment_team.rb adds the user to the AssignmentTeam for the given assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test creates a user, and passes the user, assignment id for the team to the function and expects the result to be an instance of '''AssignmentParticipant''' meaning the user was successfully added as a participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is not a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;adds the user to the team&amp;quot; do&lt;br /&gt;
        user = build(:student, id: 10)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user)).to be_an_instance_of(AssignmentParticipant)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The unit test creates a user, adds him as a participant to the team, and passes the user, assignment id for the team to the function and expects the result to be '''nil''' as the user already exists as participant of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is already a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns without adding user to the team&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user1)).to eq(nil)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: scores(questions) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: files(directory) ====&lt;br /&gt;
This method in assignment_team.rb successfully returns a list of files in any given directory path, not just the assignment teams directory path.&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned contains a specific file which is known to be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/models&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned does not contain a specific file which is known to not be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is not present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is not present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/controllers&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).not_to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: submit_hyperlink(hyperlink) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: remove_hyperlink(hyperlink_to_delete) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.team(participant) ====&lt;br /&gt;
This function in assignment_team.rb returns the AssingmentTeam object that the given participant belongs to.&lt;br /&gt;
&lt;br /&gt;
The unit test first builds a user and assigns that user as a participant1 of the team. Then allows that participant to be added as a team user and finally search the team for the given team user and expect the team for participant1 to be equal to the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when there is a participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the team for participant&amp;quot; do&lt;br /&gt;
        teamuser = build(:team_user, id: 1, team_id: team.id, user_id: user1.id)&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(TeamsUser).to receive(:where).with(user_id: participant1.user_id).and_return([teamuser])&lt;br /&gt;
        allow(Team).to receive(:find).with(teamuser.team_id).and_return(team)&lt;br /&gt;
        expect(AssignmentTeam.team(participant1)).to eq(team)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.export_fields(options) ====&lt;br /&gt;
This function in assignment_team.rb exports the fields for a given set of options. It always returns a list containing [&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;] if the given set of options have a team name set to true.&lt;br /&gt;
&lt;br /&gt;
The unit test expects the method to return a static list of strings for the team passed as options, with the team having a name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team has name&amp;quot; do&lt;br /&gt;
      it &amp;quot;exports the fields&amp;quot; do&lt;br /&gt;
        expect(AssignmentTeam.export_fields(team)).to eq([&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.remove_team_by_id(id) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: path ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: set_student_directory_num ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: received_any_peer_review? ====&lt;br /&gt;
&lt;br /&gt;
=== Test Coverage ===&lt;br /&gt;
The model has a total of 237 lines, out of which 127 were relevant lines.&lt;br /&gt;
We achieved 100% coverage with avg hits per line at 2.3 (the number of times each specific line was run during the test suite)&lt;br /&gt;
&lt;br /&gt;
[[File:Coverage_header.png]]&lt;br /&gt;
[[File:Coverage_line.png]]&lt;br /&gt;
&lt;br /&gt;
=== Stubs for Isolating the UUT ===&lt;br /&gt;
=== DRY Testing Practices ===&lt;br /&gt;
==== Factories and the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;let&amp;lt;/span&amp;gt; RSPEC Helper Method ====&lt;br /&gt;
==== Contexts ====&lt;br /&gt;
&lt;br /&gt;
== Testing Framework ==&lt;br /&gt;
&lt;br /&gt;
=== RSpec Introduction ===&lt;br /&gt;
[http://rspec.info/ RSPEC] is a testing framework for Ruby for behavior-driven development (BDD) licensed under MIT. It is inspired by JBehave and contains fully integrated JMock based framework which has a very rich and powerful DSL (domain-specific language) which resembles a natural language specification. Composed of multiple libraries structured to work together, RSpec provides encapsulated testing via the describe block to specify the behavior of the class and the context for the unit test case.&lt;br /&gt;
&lt;br /&gt;
=== Why RSpec? ===&lt;br /&gt;
RSpec is easy to learn and implement and can be used with other testing tools like Cucumber and Minitest independently. It is extremely powerful for testing states with complicated setup and also helps in tearing down complex code to access the objects required for testing RSpec semantics encourage agile thinking and practice and it structures the tests in a more intuitive way.&lt;br /&gt;
&lt;br /&gt;
== Bugs Detected ==&lt;br /&gt;
During testing of the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; model, we found two bugs, one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt; and one in &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam#submit_hyperlink'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''http://'''&amp;lt;/span&amp;gt; was ''appended'' to hyperlink strings without this tag or&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''https://'''&amp;lt;/span&amp;gt; at the start of them, rather than ''prepended''. We fixed this error in our pull request. In &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam.import'''&amp;lt;/span&amp;gt;, &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''id'''&amp;lt;/span&amp;gt;, an undefined parameter, was referenced while raising an exception, and we updated it to &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''assignment_id'''&amp;lt;/span&amp;gt;, which was the actual name of the parameter passed to the method.&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
== Future Work ==&lt;br /&gt;
&lt;br /&gt;
DRY principle could be cleaned up a little more. Sometimes it became necessary to use the '''let''' or '''build''' helper methods in each unit test. They may all be consolidated at the beginning. &amp;lt;br&amp;gt;&lt;br /&gt;
Some more edge cases could be thought of for each method, and tests written for those. Although, we have tried to cover as many as possible. &amp;lt;br&amp;gt;&lt;br /&gt;
Additionally, in the future, the code may also be refactored with a more efficient tool. &amp;lt;br&amp;gt;&lt;br /&gt;
Test coverage through quality tests consistently added throughout the development of the Expertiza project should be the future work of the project. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1. [http://expertiza.ncsu.edu Expertiza] &amp;lt;br&amp;gt;&lt;br /&gt;
2. [http://wiki.expertiza.ncsu.edu/index.php/Main_Page#Expertiza Expertiza Wikipedia ]&amp;lt;br&amp;gt;&lt;br /&gt;
3. [https://github.com/expertiza/expertiza Expertiza Github Repository]&amp;lt;br&amp;gt;&lt;br /&gt;
4. [https://relishapp.com/rspec RSpec - Relish]&amp;lt;br&amp;gt;&lt;br /&gt;
5. [https://sites.google.com/site/longlastingsoftware Engineering Software as a Service]&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117962</id>
		<title>CSC/ECE 517 Fall 2018- Project E1848: Writing unit tests for assignment team.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117962"/>
		<updated>2018-11-02T14:20:00Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: Add material to the bugs detected section.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this project is to improve the coverage and quality of the unit tests for the assignment team model in Expertiza. This project comprised the program 3 assignment of CSC/ECE 517 in fall 2018 and is entitled &amp;quot;Project E1848: Writing unit tests for assignment_team.rb.&amp;quot; The source code for this project is in [https://github.com/expertiza/expertiza/pull/1228 pull request #1228] of the [https://github.com/expertiza Expertiza project] on [https://github.com/ GitHub].&lt;br /&gt;
&lt;br /&gt;
== Key Contributions ==&lt;br /&gt;
&lt;br /&gt;
Out of the 30 methods defined for the model AssignmentTeam.rb, test case was written for only one. Our contribution was to successfully add test cases for all remaining 29 methods.&lt;br /&gt;
&lt;br /&gt;
Hence, increasing the coverage from 5% to 100%.&lt;br /&gt;
&lt;br /&gt;
== The Class under Test ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;'''AssignmentTeam'''&amp;lt;/span&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
This class handles all functionalities for a team linked to an assignment. Some of the functionalities include, get a list of participants in the team, get the team name, team score for the given assignment, submissions for this team (files) and (hyperlinks) and topic picked by the team. Add/or remove participants from the team. It also checks for any reviews the team may have gotten for their work. Export all teams in a CSV file, import files from CSV to form teams.&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
== Test Design ==&lt;br /&gt;
=== Test Structure ===&lt;br /&gt;
Listed below are the functionalities and the Rspec unit tests corresponding to the function names along with a list of scenarios tested.&lt;br /&gt;
&lt;br /&gt;
==== '''Function name: includes?(participant)''' ====&lt;br /&gt;
This function in assignment_team.rb checks if the '''participant''' passed as argument is a member of the team or not. For this, we utilize factorybot to build a user and a participant1 as follows-:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  let(:user1) { build(:student, id: 2) }&lt;br /&gt;
  let(:participant1) { build(:participant, id: 1) }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test cases checked for are-: &amp;lt;br&amp;gt;&lt;br /&gt;
1) when the team receives a user, that user is allowed to become a team participant. The method returns '''True''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has one participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes one participant&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        expect(team.includes?(participant1)).to eq true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2) when the team receives a user with no arguments, that user is '''not''' allowed to become a team participant. The method returns '''False''' for the given participant passed as argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has no users&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([])&lt;br /&gt;
        expect(team.includes?(participant1)).to eq false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: parent_model ====&lt;br /&gt;
This function in assignment_team.rb always provides the name of the parent model which is '''Assignment'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;Assignment&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the name of the parent model&amp;quot; do&lt;br /&gt;
      expect(team.parent_model).to eq &amp;quot;Assignment&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.parent_model(id) ====&lt;br /&gt;
This function in assignment_team.rb takes in as argument id of the current '''Assignment''' for the team and returns an instance of the parent model.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the instance returned by this method for a given assignment id, matches the assignment or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the parent model&amp;quot; do&lt;br /&gt;
      allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
      expect(AssignmentTeam.parent_model(1)).to eq assignment&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: fullname ====&lt;br /&gt;
This function in assignment_team.rb print out the name for the current class instance. for this we first build an assignment team instance and assign it the name '''&amp;quot;abcd&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
Hence the unit test checks if the assignment team has a name, and returns that same name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when the team has a name&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the name of the class&amp;quot; do&lt;br /&gt;
        team = build(:assignment_team, id: 1, name: &amp;quot;abcd&amp;quot;)&lt;br /&gt;
        expect(team.fullname).to eq &amp;quot;abcd&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: review_map_type ====&lt;br /&gt;
This function in assignment_team.rb always provides the name of the review map type which is '''ReviewResponseMap'''.&lt;br /&gt;
&lt;br /&gt;
Hence, the unit test also always checks if the response of this method is the string '''&amp;quot;ReviewResponseMap&amp;quot;''' or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the review map type&amp;quot; do&lt;br /&gt;
      expect(team.review_map_type).to eq &amp;quot;ReviewResponseMap&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.prototype ====&lt;br /&gt;
This function in assignment_team.rb implements the prototype pattern by returning a new instance of the class '''AssignmentTeam'''.&lt;br /&gt;
&lt;br /&gt;
The unit test checks if the response is a new instance of the class or not.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;provides the instance of the AssignmentTeam&amp;quot; do&lt;br /&gt;
      expect(AssignmentTeam).to receive(:new).with(no_args)&lt;br /&gt;
      AssignmentTeam.prototype&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: assign_reviewer(reviewer) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: reviewed_by?(reviewer) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: topic ====&lt;br /&gt;
This function in assignment_team.rb return the id of the topic picked by the team for the assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test first stubs a topic for the given assignment, allows a SignedUpTeam object to receive that topic and AssignmentTeam id, and return the topic id to check if it matches with the topic id of the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context &amp;quot;when the team has picked a topic&amp;quot; do&lt;br /&gt;
    it &amp;quot;provides the topic id&amp;quot; do&lt;br /&gt;
      assignment = team.assignment&lt;br /&gt;
      allow(SignUpTopic).to receive(:find_by).with(assignment: assignment).and_return(topic)&lt;br /&gt;
      allow(SignedUpTeam).to receive_message_chain(:find_by, :try).with(team_id: team.id).with(:topic_id).and_return(topic.id)&lt;br /&gt;
      expect(team.topic).to eq(topic.id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: has_submissions? ====&lt;br /&gt;
this function in assignment_team.rb is used to check if the team has submitted their work or not.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the team to receive submissions, by first receiving files as submission, then hyperlink as submission, and for each expects the the team's submission to be true when the function is called.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a team has submitted files&amp;quot; do&lt;br /&gt;
      it &amp;quot;has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_files, :any?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context &amp;quot;when the team has submitted hyperlink&amp;quot; do&lt;br /&gt;
      it &amp;quot;checks if the team has submissions&amp;quot; do&lt;br /&gt;
        allow(team).to receive_message_chain(:submitted_hyperlinks, :present?).with(no_args).with(no_args).and_return(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    after(:each) do&lt;br /&gt;
      expect(team.has_submissions?).to be true&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: participants ====&lt;br /&gt;
This function in assignment_team.rb returns a list of all participants in the team.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive two user instances and then adds these users as participants of the team. The test then expects the function to return a list of these two users as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has two participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;has those two participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
        expect(team.participants).to eq [participant1, participant2]&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test first allows the team to receive a user instance but does not add this user as participant of the team. The test then expects the function to return an empty list as participants of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when an assignment team has a user but no participants&amp;quot; do&lt;br /&gt;
      it &amp;quot;includes no participants&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(nil)&lt;br /&gt;
        expect(team.participants).to eq []&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: delete ====&lt;br /&gt;
This function in assignment_team.rb deletes the AssignmentTeam by destroying each participant in the team and returns an instance of AssignmentTeam.&lt;br /&gt;
&lt;br /&gt;
The unit test first allows two users to be added as team participants. The test checks if the team deleted matches the current team instance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    it &amp;quot;deletes the team&amp;quot; do&lt;br /&gt;
      allow(team).to receive(:users).with(no_args).and_return([user1, user2])&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: user2.id, parent_id: team.parent_id).and_return(participant2)&lt;br /&gt;
      expect(team.delete).to eq(team)&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: destroy ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.get_first_member(team_id) ====&lt;br /&gt;
This function in assignment_team.rb returns the instance of the first participant of the team for the given team id.&lt;br /&gt;
&lt;br /&gt;
The unit test allows the assignment to receive a user, add it as a participant and return the first participant in the team. The test expects the function to return an instance of this participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team id is present&amp;quot; do&lt;br /&gt;
      it &amp;quot;get first member of the  team&amp;quot; do&lt;br /&gt;
        allow(AssignmentTeam).to receive_message_chain(:find_by, :try, :try).with(id: team.id).with(:participant).with(:first).and_return(participant1)&lt;br /&gt;
        expect(AssignmentTeam.get_first_member(team.id)).to eq(participant1)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: submitted_files(path = self.path) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.import(row, assignment_id, options) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.export(csv, parent_id, options) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: copy(course_id) ====&lt;br /&gt;
This function in assignment_team.rb copies the current assignment team and creates a new CourseTeam instance from the given team. It takes as parameter the id of the course assignment team has.&lt;br /&gt;
&lt;br /&gt;
The test grabs the course id from the assignment team and calls the function to check if a course team is successfully created or not. The function returns and empty array, otherwise returns '''nil''' if the course team is not created successfully.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;for given assignment team&amp;quot; do&lt;br /&gt;
      it &amp;quot;copies the assignment team to course team&amp;quot; do&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        course = assignment.course&lt;br /&gt;
        expect(team.copy(course.id)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: add_participant(assignment_id, user) ====&lt;br /&gt;
This function in assignment_team.rb adds the user to the AssignmentTeam for the given assignment.&lt;br /&gt;
&lt;br /&gt;
The unit test creates a user, and passes the user, assignment id for the team to the function and expects the result to be an instance of '''AssignmentParticipant''' meaning the user was successfully added as a participant.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is not a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;adds the user to the team&amp;quot; do&lt;br /&gt;
        user = build(:student, id: 10)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user)).to be_an_instance_of(AssignmentParticipant)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The unit test creates a user, adds him as a participant to the team, and passes the user, assignment id for the team to the function and expects the result to be '''nil''' as the user already exists as participant of the team.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when a user is already a part of the team&amp;quot; do&lt;br /&gt;
      it &amp;quot;returns without adding user to the team&amp;quot; do&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        assignment = team.assignment&lt;br /&gt;
        expect(team.add_participant(assignment.id, user1)).to eq(nil)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: scores(questions) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: files(directory) ====&lt;br /&gt;
This method in assignment_team.rb successfully returns a list of files in any given directory path, not just the assignment teams directory path.&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned contains a specific file which is known to be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/models&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test assigns the directory path as given below and checks if the list of files returned does not contain a specific file which is known to not be in the list.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when file is not present in the directory&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the list of files in directory and checks if file is not present&amp;quot; do&lt;br /&gt;
        directory = &amp;quot;spec/controllers&amp;quot;&lt;br /&gt;
        expect(team.files(directory)).not_to include(&amp;quot;spec/models/assignment_team_spec.rb&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: submit_hyperlink(hyperlink) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: remove_hyperlink(hyperlink_to_delete) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.team(participant) ====&lt;br /&gt;
This function in assignment_team.rb returns the AssingmentTeam object that the given participant belongs to.&lt;br /&gt;
&lt;br /&gt;
The unit test first builds a user and assigns that user as a participant1 of the team. Then allows that participant to be added as a team user and finally search the team for the given team user and expect the team for participant1 to be equal to the AssignmentTeam.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when there is a participant&amp;quot; do&lt;br /&gt;
      it &amp;quot;provides the team for participant&amp;quot; do&lt;br /&gt;
        teamuser = build(:team_user, id: 1, team_id: team.id, user_id: user1.id)&lt;br /&gt;
        allow(team).to receive(:users).with(no_args).and_return([user1])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: user1.id, parent_id: team.parent_id).and_return(participant1)&lt;br /&gt;
        allow(TeamsUser).to receive(:where).with(user_id: participant1.user_id).and_return([teamuser])&lt;br /&gt;
        allow(Team).to receive(:find).with(teamuser.team_id).and_return(team)&lt;br /&gt;
        expect(AssignmentTeam.team(participant1)).to eq(team)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.export_fields(options) ====&lt;br /&gt;
This function in assignment_team.rb exports the fields for a given set of options. It always returns a list containing [&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;] if the given set of options have a team name set to true.&lt;br /&gt;
&lt;br /&gt;
The unit test expects the method to return a static list of strings for the team passed as options, with the team having a name.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    context &amp;quot;when team has name&amp;quot; do&lt;br /&gt;
      it &amp;quot;exports the fields&amp;quot; do&lt;br /&gt;
        expect(AssignmentTeam.export_fields(team)).to eq([&amp;quot;Team Name&amp;quot;, &amp;quot;Assignment Name&amp;quot;])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Function name: self.remove_team_by_id(id) ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: path ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: set_student_directory_num ====&lt;br /&gt;
&lt;br /&gt;
==== Function name: received_any_peer_review? ====&lt;br /&gt;
&lt;br /&gt;
=== Test Coverage ===&lt;br /&gt;
The model has a total of 237 lines, out of which 127 were relevant lines.&lt;br /&gt;
We achieved 100% coverage with avg hits per line at 2.3 (the number of times each specific line was run during the test suite)&lt;br /&gt;
&lt;br /&gt;
[[File:Coverage_header.png]]&lt;br /&gt;
[[File:Coverage_line.png]]&lt;br /&gt;
&lt;br /&gt;
=== Stubs for Isolating the UUT ===&lt;br /&gt;
=== DRY Testing Practices ===&lt;br /&gt;
==== Factories and the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;let&amp;lt;/span&amp;gt; RSPEC Helper Method ====&lt;br /&gt;
==== Contexts ====&lt;br /&gt;
&lt;br /&gt;
== Testing Framework ==&lt;br /&gt;
&lt;br /&gt;
=== RSpec Introduction ===&lt;br /&gt;
[http://rspec.info/ RSPEC] is a testing framework for Ruby for behavior-driven development (BDD) licensed under MIT. It is inspired by JBehave and contains fully integrated JMock based framework which has a very rich and powerful DSL (domain-specific language) which resembles a natural language specification. Composed of multiple libraries structured to work together, RSpec provides encapsulated testing via the describe block to specify the behavior of the class and the context for the unit test case.&lt;br /&gt;
&lt;br /&gt;
=== Why RSpec? ===&lt;br /&gt;
RSpec is easy to learn and implement and can be used with other testing tools like Cucumber and Minitest independently. It is extremely powerful for testing states with complicated setup and also helps in tearing down complex code to access the objects required for testing RSpec semantics encourage agile thinking and practice and it structures the tests in a more intuitive way.&lt;br /&gt;
&lt;br /&gt;
== Bugs Detected ==&lt;br /&gt;
During testing of the AssignmentTeam model, we found two bugs,one in #submit hyperlink and one in .import. &lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
== Future Work ==&lt;br /&gt;
&lt;br /&gt;
DRY principle could be cleaned up a little more. Sometimes it became necessary to use the '''let''' or '''build''' helper methods in each unit test. They may all be consolidated at the beginning. &amp;lt;br&amp;gt;&lt;br /&gt;
Some more edge cases could be thought of for each method, and tests written for those. Although, we have tried to cover as many as possible. &amp;lt;br&amp;gt;&lt;br /&gt;
Additionally, in the future, the code may also be refactored with a more efficient tool. &amp;lt;br&amp;gt;&lt;br /&gt;
Test coverage through quality tests consistently added throughout the development of the Expertiza project should be the future work of the project. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1. [http://expertiza.ncsu.edu Expertiza] &amp;lt;br&amp;gt;&lt;br /&gt;
2. [http://wiki.expertiza.ncsu.edu/index.php/Main_Page#Expertiza Expertiza Wikipedia ]&amp;lt;br&amp;gt;&lt;br /&gt;
3. [https://github.com/expertiza/expertiza Expertiza Github Repository]&amp;lt;br&amp;gt;&lt;br /&gt;
4. [https://relishapp.com/rspec RSpec - Relish]&amp;lt;br&amp;gt;&lt;br /&gt;
5. [https://sites.google.com/site/longlastingsoftware Engineering Software as a Service]&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117799</id>
		<title>CSC/ECE 517 Fall 2018- Project E1848: Writing unit tests for assignment team.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117799"/>
		<updated>2018-11-02T01:27:05Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this project is to improve the coverage and quality of the unit tests for the assignment team model in Expertiza. This project comprised the program 3 assignment of CSC/ECE 517 in fall 2018 and is entitled &amp;quot;Project E1848: Writing unit tests for assignment_team.rb.&amp;quot; The source code for this project is in [https://github.com/expertiza/expertiza/pull/1228 pull request #1228] of the [https://github.com/expertiza Expertiza project] on [https://github.com/ GitHub].&lt;br /&gt;
&lt;br /&gt;
== Key Contributions ==&lt;br /&gt;
== The Class under Test ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;AssignmentTeam&amp;lt;/span&amp;gt;&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
== Test Design ==&lt;br /&gt;
=== Test Structure ===&lt;br /&gt;
=== Test Coverage ===&lt;br /&gt;
=== Stubs for Isolating the UUT ===&lt;br /&gt;
=== DRY Testing Practices ===&lt;br /&gt;
==== Factories and the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;let&amp;lt;/span&amp;gt; RSPEC Helper Method ====&lt;br /&gt;
==== Contexts ====&lt;br /&gt;
== Testing Framework ==&lt;br /&gt;
[http://rspec.info/ RSPEC]&lt;br /&gt;
== Bugs Detected ==&lt;br /&gt;
== Results ==&lt;br /&gt;
== Future Work ==&lt;br /&gt;
== References ==&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117796</id>
		<title>CSC/ECE 517 Fall 2018- Project E1848: Writing unit tests for assignment team.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117796"/>
		<updated>2018-11-02T01:24:56Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: Change the headings.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this project is to improve the coverage and quality of the unit tests for the assignment team model in Expertiza. This project comprised the program 3 assignment of CSC/ECE 517 in fall 2018 and is entitled &amp;quot;Project E1848: Writing unit tests for assignment_team.rb.&amp;quot; The source code for this project is in [https://github.com/expertiza/expertiza/pull/1228 pull request #1228] of the [https://github.com/expertiza Expertiza project] on [https://github.com/ GitHub].&lt;br /&gt;
&lt;br /&gt;
== Key Contributions ==&lt;br /&gt;
== The Class under Test ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;AssignmentTeam&amp;lt;/span&amp;gt;&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
== Test Design ==&lt;br /&gt;
=== Test Structure ===&lt;br /&gt;
=== Test Coverage ===&lt;br /&gt;
=== Stubs for Isolating the UUT ===&lt;br /&gt;
=== DRY Testing Practices ===&lt;br /&gt;
==== Factories and the &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;let&amp;lt;/span&amp;gt; RSPEC Helper Method ====&lt;br /&gt;
==== Contexts ====&lt;br /&gt;
== Testing Framework ==&lt;br /&gt;
== Bugs Detected ==&lt;br /&gt;
== Results ==&lt;br /&gt;
== Future Work ==&lt;br /&gt;
== References ==&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117705</id>
		<title>CSC/ECE 517 Fall 2018- Project E1848: Writing unit tests for assignment team.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117705"/>
		<updated>2018-10-31T21:32:59Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: Edit the headings.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this project is to improve the coverage and quality of the unit tests for the assignment team model in Expertiza. This project comprised the program 3 assignment of CSC/ECE 517 in fall 2018 and is entitled &amp;quot;Project E1848: Writing unit tests for assignment_team.rb.&amp;quot; The source code for this project is in [https://github.com/expertiza/expertiza/pull/1228 pull request #1228] of the [https://github.com/expertiza Expertiza project] on [https://github.com/ GitHub].&lt;br /&gt;
&lt;br /&gt;
== Key Contributions ==&lt;br /&gt;
== &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;AssignmentTeam&amp;lt;/span&amp;gt;, the Class under Test ==&lt;br /&gt;
== Testing Framework ==&lt;br /&gt;
== Unit Tests ==&lt;br /&gt;
== Results ==&lt;br /&gt;
== References ==&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117704</id>
		<title>CSC/ECE 517 Fall 2018- Project E1848: Writing unit tests for assignment team.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117704"/>
		<updated>2018-10-31T21:17:02Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: Fix some headings.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this project is to improve the coverage and quality of the unit tests for the assignment team model in Expertiza. This project comprised the program 3 assignment of CSC/ECE 517 in fall 2018 and is entitled &amp;quot;Project E1848: Writing unit tests for assignment_team.rb.&amp;quot; The source code for this project is in [https://github.com/expertiza/expertiza/pull/1228 pull request #1228] of the [https://github.com/expertiza Expertiza project] on [https://github.com/ GitHub].&lt;br /&gt;
&lt;br /&gt;
== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;AssignmentTeam&amp;lt;/span&amp;gt; Class ==&lt;br /&gt;
== References ==&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117703</id>
		<title>CSC/ECE 517 Fall 2018- Project E1848: Writing unit tests for assignment team.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117703"/>
		<updated>2018-10-31T21:16:43Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: Add some headings.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this project is to improve the coverage and quality of the unit tests for the assignment team model in Expertiza. This project comprised the program 3 assignment of CSC/ECE 517 in fall 2018 and is entitled &amp;quot;Project E1848: Writing unit tests for assignment_team.rb.&amp;quot; The source code for this project is in [https://github.com/expertiza/expertiza/pull/1228 pull request #1228] of the [https://github.com/expertiza Expertiza project] on [https://github.com/ GitHub].&lt;br /&gt;
&lt;br /&gt;
== The &amp;lt;span style=&amp;quot;font-family:Courier;&amp;quot;&amp;gt;AssignmentTeam&amp;lt;/span&amp;gt; Class&lt;br /&gt;
== References ==&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117693</id>
		<title>CSC/ECE 517 Fall 2018- Project E1848: Writing unit tests for assignment team.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117693"/>
		<updated>2018-10-31T18:55:00Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: Add an introduction.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this project is to improve the coverage and quality of the unit tests for the assignment team model in Expertiza. This project comprised the program 3 assignment of CSC/ECE 517 in fall 2018 and is entitled &amp;quot;Project E1848: Writing unit tests for assignment_team.rb.&amp;quot; The source code for this project is in [https://github.com/expertiza/expertiza/pull/1228 pull request #1228] of the [https://github.com/expertiza Expertiza project] on [https://github.com/ GitHub].&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117688</id>
		<title>CSC/ECE 517 Fall 2018- Project E1848: Writing unit tests for assignment team.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2018-_Project_E1848:_Writing_unit_tests_for_assignment_team.rb&amp;diff=117688"/>
		<updated>2018-10-31T18:33:06Z</updated>

		<summary type="html">&lt;p&gt;Kaacken2: Add a summary.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this project is to improve the coverage and quality of the unit tests for the assignment team model in Expertiza.&lt;/div&gt;</summary>
		<author><name>Kaacken2</name></author>
	</entry>
</feed>