CSC/ECE 517 Fall 2017/E1793. Help students find teams to join

From Expertiza_Wiki
Jump to navigation Jump to search

Introduction

Problem Statement

For team-based assignments, it always takes time to find suitable team members. We already have bidding, which could help you to join in a team with other team members hold similar bidding preferences. However, you may not be satisfied with automated team formation and want to switch to another team. In this project, we will build a new feature to help students find teams to join.

Currently, there are 2 ways to find other students to join your team:

1.If your team is not full, you could invite people by inputting his/her UnityID. It will send an invitation to certain user. If s/he accept your invitation,s/he will leave original team and join your team. 2.You could create an advisement by clicking “Your team” link and then clicking “Create” link under “Advertisement for teammates” section. Then your advertisement will appear the last column of the signup sheet page with a horn icon. In this way, all classmates could see your advisement. Someone could send a request to join your team. If you accept their request, s/he will leave original team and join in your team.

It would be better for students who do not have team yet or whose team is not full yet to be able to see a list of students who don’t already have teams. So too for instructors.

Task Description

Fix the second way to find other students to join your team.

Currently, after you create an advertisement, the horn icon does not appear in the the last column of the signup sheet.

For student end:

Display a list of students who do not have a team with invitation links in student_teams#view page You could invite students to your team by clicking invitation links. If s/he accept your invitation,s/he will leave original team and join in your team. It will be more straightforward than typing UnityID.

For instructor end:

Display a list of students who do not have team in teams#list page

Write feature tests to verify your modifications:

Create team_invitation_spec.rb file in spec/features folder

Modified Files

1)app/views/student_teams/view.html.erb

2)app/views/join_team_requests/_list_received.erb

3)app/controllers/join_team_requests_controller.rb

4)app/models/join_team_request.rb

5)app/models/sign_up_sheet.rb

6)app/views/sign_up_sheet/_table_line.html.erb

7)app/views/sign_up_sheet/_all_actions.html.erb

8)app/views/teams/list.html.erb

9)spec/features/team_invitation_spec.rb

Approach taken to resolve the issues

Issue1

When someone creates an ad ,the horny icon does not appear in the the last column of the signup sheet.the code that show horny icon is below:

<% if SignUpSheet.has_teammate_ads?(topic.id) %>
<%= link_to image_tag('ad.png', :border => 0, :title => 'Ad', :align => 'middle', :style => 'width: 24px; height:24px'), :controller=>'sign_up_sheet', 
:action=> 'show_team',assignment_id=>@assignment.id, :id=>topic.id%>
<% end %>

After debugging ,I found even if you create an ad before ,the if block of code will not be executed. Therefore something must be wrong with has_teammate_ads? method.Then I rewrite that method.Signupteam has an attribute:advertise_for_partner ,it will be set true after team members create an ad for their team.i return this attribute to the has_teammate_ads? method and the horny icon appears.This method code is below:

  def self.has_teammate_ads?(topic_id)
    @ads_exsit=false
    @result=SignedUpTeam.where("topic_id = ?", topic_id.to_s)
    @result.each do |result|
     team=result.team
     @ads_exsit=team.advertise_for_partner
     end
     @ads_exsit
   end

Issue2

I found currently when you sent join team request in the ad,the team received that request would see invite and decline button on their student teams#view page.if they are willing to add the student who send request as member ,they have to send invitation and wait for reply. This is not reasonable and convenient. what should happen is that when the student send join team request,the team members could see accept and decline button ,After they click accept button ,the student would leave his/her original team and join the new team. What I have done is that I add accept method in join team request controller.The method is below:

  def accept
     unless JoinTeamRequest.accept_invite(params[:team_id], @inviter_userid,  @invited_userid, @assignment_id)
     flash[:error] = 'The system failed to add you to the team that invited you.'
    end
    redirect_to view_student_teams_path student_id: params[:student_id]
 end

Here @invited_userid is acquired from the student who sent join team request. inviter_userid is from the team members who received the request. team_id is invited student's team id.

Issue3

We build a new feature to help students find teams to join. Students who do not have teams or whose team is not full are able to see a list of students who do not haven a team.The code for this issue is showed below:

 <% if @student.user_id!=nil %>
 <%if @student.assignment.max_team_size > 1 %>
 <% if @student.team==nil|| !@student.team.full? %>
 Students without teams
  <%@student.assignment.participants.each do |participant| %> 
  <% if participant.team==nil  %>
  <% if User.find(participant.user_id).role.name=="Student"  %>
  <% if participant.user.name!=@student.name  %>

<%= participant.user.name %>

     <%if @student.team==nil
            @teamid="0"
          else
          @teamid=@student.team.id
        end%>

<%= form_tag :controller => 'invitations', :action => 'create' do %>

             <%= hidden_field_tag 'team_id', @teamid %>
             <%= hidden_field_tag 'student_id', @student.id %>
            <%= hidden_field_tag 'session[:dummy][:assignment_id]', @student.parent_id %>
             <%= hidden_field_tag 'user[name]',  participant.user.name%>
             <%=  submit_tag "invite"%>
        <% end %>

<% end %> <% end %> <% end %> <% end %> <% end %>

      <% end %>
      <% end %>

In the code above, if @student.assignment.max_team_size > 1 we then execute the below code ,this is because our new feature is only available when assignment team size greater than 1.we use if @student.team==nil|| !@student.team.full? to allow students who have no team or whose team is not full to see this list.Next we found all participants ,we use if statement to sample those who has no team , their role are students and they won't see themselves if they do not have teams.We then put these sampled participants on the list .these achieved by the code below

  <%@student.assignment.participants.each do |participant| %> 
  <% if participant.team==nil  %>
  <% if User.find(participant.user_id).role.name=="Student"  %>
  <% if participant.user.name!=@student.name  %>

<%= participant.user.name %>

We also need to add invitation links next to students without teams,before adding links , we need to know whether students who want to invite the students on the list have team or not .if they do not have their own teams. we will automatically create a team for them ,this mechanism is called team lazy initialization.the code for this part is below

      <%if @student.team==nil
      @teamid="0"
      else
      @teamid=@student.team.id
      end%>
      def check_inviterteam_before_invitation
     @student = AssignmentParticipant.find(params[:student_id])
     @team_id=params[:team_id]
     if @team_id=="0"
     team = AssignmentTeam.create_team_and_node(@student.parent_id)
     user = User.find(@student.user_id)
     # create TeamsUser and TeamUserNode
     teamuser = ApplicationController.helpers.create_team_users(user, team.id)
     @team_id=team.id
     end
     end

Finally we just use form_tag to create invite button which is related to invitation controller and create method in it .

Issue4

we also display a list of students who do not have team in teams#list page for instructor.This part of code is showed below.

     <% @assignment.participants.each do |participant| %> 
     <% if participant.team==nil  %>
      <% if User.find(participant.user_id).role.name=="Student"  %>

<%= participant.user.name %>

      <% end %>
     <% end %>
    <% end %>


Screenshots of new feature

1)The horny icons appear in the the last column of the signup sheet.

2)Received request from advertisement and the changed team members after clicking accept button.



3)For student end ,the list of students who do not have a team with invitation links

4)For instructor end ,the list of students who do not have a team.

Test Plan

The last part of this project is to test all the modifications. And in order to test the new features we created a new Rspec file, which is spec/features/team_invitation_spec.rb. The codes below are all tests we created.

Some edge cases:

1) The owner of a team can accept or decline the request sent by other students, if the team is already full, the team will remain the same even the request is accepted.

context 'when team owner declining the invitation' do
 it 'makes team members remain the same as before' do
 find("input[type=submit][value='Decline']").click
 stub_current_user(@user, @user.role.name, @user.role)
 visit '/student_task/list'
 click_link 'TestAssignment'
 visit '/student_task/list'
 click_link 'TestAssignment'
 click_link 'Your team'
 page.should have_no_content('student2064')
  end
end
context 'when team owner accepting the invitation' do
 context 'when the team is not full' do
  it 'makes requester joins the team' do
  allow_any_instance_of(TeamController).to receive(full?).and_return(false)
  find("input[type=submit][value='Accept']").click
  stub_current_user(@user, @user.role.name, @user.role)
  visit '/student_task/list'
  click_link 'TestAssignment'
  visit '/student_task/list'
  click_link 'TestAssignment'
  click_link 'Your team'
  page.should have_content('student2064')
  end
end
context 'when the team is already full' do
 it 'makes team members remain the same as before' do
 allow_any_instance_of(TeamController).to receive(full?).and_return(true)
 find("input[type=submit][value='Accept']").click
 stub_current_user(@user, @user.role.name, @user.role)
 visit '/student_task/list'
 click_link 'TestAssignment'
 visit '/student_task/list'
 click_link 'TestAssignment'
 click_link 'Your team'
 page.should have_no_content('student2064')
 end
end

2) In the student_team#view page, students should see a list of students who don't have teams and can be invited at present, if the invitation is declined, the team remains the same. And the invitee can only join the team when it is not full.

context 'on student_teams#view page (student end)' do
 before(:each) do
 stub_current_user(@owner, @owner.role.name, @owner.role)
 visit '/student_task/list'
 click_link 'TestAssignment'
 click_link 'Your team'
end
it 'shows a list of students who do not have a team' do
 expect(page).to have_content('student2064')
 expect(page).to have_selector("input[typ1e=submit][value='invite']")
end
context 'when invitee declining the invitation' do
 it 'makes team members remain the same as before' do 
 find("input[type=submit][value='Decline']").click
 end
end
context 'when invitee accepting the invitation' do
 context 'when the team is not full' do
 it 'makes invitee joins the team' do
 allow_any_instance_of(TeamController).to receive(full?).and_return(false)
 end
end
context 'when the team is already full' do
 it 'makes team members remain the same as before' do
 allow_any_instance_of(TeamController).to receive(full?).and_return(true)
 end
end

3) Testing advertisement features.

context 'advertisement feature' do
 before(:each) do
 # team owner creates an advertisement from student_teams#view page
 @owner = User.find_by(name: "student2064")
 stub_current_user(@owner, @owner.role.name, @owner.role)
 visit '/student_task/list'
 click_link 'TestAssignment'
 click_link 'Your team'
 click_link 'Create'
 fill_in 'comments_for_advertisement', with: 'advertisement1'
 click_button 'Create'
 expect(page).to have_content 'advertisement1'
 expect(page).to have_content 'Delete'
 @user = User.find_by(name: "student2065")
 stub_current_user(@user, @user.role.name, @user.role)
 visit '/student_task/list'
 click_link 'TestAssignment'
 click_link 'Signup sheet'
 horn = find(:xpath, "//a[contains(@href,'show_team/2?')]")
 horn.click
 expect(page).to have_content 'Request invitation'
 click_link 'Request invitation'
 fill_in 'comments_', with: 'request_demo'
 expect(page).to have_selector("input[type=submit][value='Create']")
 create(:join_team_request)
 # team owner is able to accept or decline the invitation
 stub_current_user(@owner, @owner.role.name, @owner.role)
 visit '/student_task/list'
 click_link 'TestAssignment'
 click_link 'Your team'
 # expect(page).to have_selector("input[typ1e=submit][value='Accept']")
 # expect(page).to have_selector("input[type=submit][value='Decline']")
end