CSC/ECE 517 Spring 2024 - E2410 Reimplement View for results of bidding: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 3: Line 3:


== Introduction ==
== Introduction ==
We will be improving the UI for bidding view to appear less cluttered.
The project focuses on decluttering the bidding view interface to offer a more intuitive user experience. This will not only improve readability and maintainability but also ensure the code adheres to design principles such as the Single Responsibility Principle. The initiative promises to reduce redundancy and elevate the overall functionality of the platform, paving the way for a more robust and user-centric application.
We're refactoring the assignment_controller.rb in Expertiza, adding a bidding_logic_controller.rb with a seperate method "topic_wise_bidding_teams" enhancing its codebase to adhere to design principles, improving readability, and reducing redundancy.
 


==Problem Statement==
==Problem Statement==

Revision as of 01:52, 9 April 2024

Expertiza

Expertiza is an open-source web application built on Ruby on Rails that enables instructors to create customized assignments with topic lists for students to choose from. It facilitates team formation, allowing students to collaborate on assignments and projects. Expertiza supports peer review processes where students can provide feedback on each other's submissions across various document formats, including URLs and wiki pages. This freely available platform provides a flexible and comprehensive solution for managing assignments, teamwork, and peer evaluations.

Introduction

The project focuses on decluttering the bidding view interface to offer a more intuitive user experience. This will not only improve readability and maintainability but also ensure the code adheres to design principles such as the Single Responsibility Principle. The initiative promises to reduce redundancy and elevate the overall functionality of the platform, paving the way for a more robust and user-centric application.

Problem Statement

The reimplementation project entails:

  • Enhance the user interface of the bidding view to make it less cluttered and more user-friendly.
  • Refactor the assignment_controller.rb by extracting the bidding logic into a separate controller, bidding_logic_controller.rb, to adhere to SRP.
  • Improve the readability and maintainability of the codebase by implementing meaningful method names and adhering to design principles.
  • Reduce redundancy in the code and promote reusability across different models within the platform.

Plan for Reimplementation of GradesController

Refactoring assignment Controller:

File: app/controllers/assignment_controller.rb  Refactor the bidding_details method to a more clear method nameEnhancing code clarity. Separate the bidding logic from the assignment controller to adhere to the Single Responsibility Principle (SRP).

Improving Bidding View:

Files: app/views/assignments/edit/_topics.html.erb ⁠, ⁠app/views/assignments/n , bidding_details.html.erb Consolidate the bidding details summary view into a single table for improved clarity and organization. Implement interactive features such as modals or tooltips to provide additional context or information.

Meaningful Method Names:

Files: app/controllers/assignment_controller.rb ⁠, app/models/assignment.rb ⁠, ⁠ app/models/team.rb ⁠, ⁠ app/models/bid.rb ⁠ Review existing method names and replace generic or unclear names with descriptive ones that accurately reflect their purpose and functionality ensuring consistency.

Adherence to Design Principles:

Files: app/controllers/assignment_controller.rb ⁠, ⁠ app/models/assignment.rb ⁠, ⁠ app/models/team.rb ⁠, ⁠ app/models/bid.rb ⁠ Refactor code segments to eliminate redundancy and promote code reusability. Stick to the design principles listed below.

Design Principles

Single Responsibility Principle (SRP):

  • Each action in the GradesController will be responsible for a specific task related to managing grades.
  • Actions will be refactored to separate concerns such as data retrieval, computation, and view rendering.
  • For example, the `view` action will focus solely on retrieving grading data and rendering the grading report.

Don't Repeat Yourself (DRY) Principle:

  • Code duplication in the GradesController will be eliminated by extracting common functionality into helper methods or modules.
  • Repetitive logic, such as retrieving questions or calculating penalties, will be refactored to promote code reusability and maintainability.

Dependency Inversion Principle (DIP):

  • The GradesController will depend on abstractions, interfaces, or higher-level modules instead of concrete implementations.
  • Dependency injection or inversion of control will be used to decouple the controller from specific database or service implementations.


RSpec Testing

The assignment_controller_spec.rb has existing automated rspec tests in place. Furthermore following tests were added to the code to ensure the functionality is working as expected and thereby increasing code coverage:-

-> assignment_controller_spec.rb

describe '#bidding_details' do
    it 'assigns necessary variables and renders bidding_details template' do
      allow(Assignment).to receive(:find).with('1').and_return(assignment)
      allow(assignment).to receive(:sign_up_topics).and_return([double('SignUpTopic', id: 1)])
      allow(Bid).to receive(:where).with(topic_id: 1).and_return([])
      allow(assignment).to receive(:calculate_percentage_of_teams_getting_choices).and_return({})
      allow(assignment).to receive(:teams_bidding_for_each_topic).and_return({})
      allow(assignment).to receive(:assigned_teams_for_topics).and_return({})
      
      get :bidding_details, params: { id: 1 }
      
      expect(assigns(:assignment)).to eq(assignment)
      expect(assigns(:bids_by_topic)).to eq({ 1 => [] })
      expect(response).to render_template('bidding_details')
    end
  end

  describe '#bidding_details_for_topic' do
    it 'assigns necessary variables and renders bidding_details_for_topic template' do
      topic = double('SignUpTopic', id: 1)
      bids = [double('Bid')]

      allow(SignUpTopic).to receive(:includes).with(:bids).and_return(SignUpTopic)
      allow(SignUpTopic).to receive(:find).with(1).and_return(topic)
      allow(topic).to receive(:bids).and_return(bids)

      get :bidding_details_for_topic, params: { topic_id: 1 }, format: :js
      
      expect(assigns(:topic)).to eq(topic)
      expect(assigns(:bids)).to eq(bids)
      expect(response).to render_template('bidding_details_for_topic')
    end
  end


Similarly, the file assignment_spec.rb have the automated rspec tests in them, Few more test case were added to verify the functionalities added.

-> assignment_spec.rb

describe '#calculate_percentage_of_teams_getting_choices' do
  it 'calculates the percentage of teams getting their choices' do
    # Mock necessary objects for the test
    assignment = build(:assignment)
    team1 = build(:team)
    team2 = build(:team)
    topic1 = build(:sign_up_topic, assignment_id: assignment.id)
    topic2 = build(:sign_up_topic, assignment_id: assignment.id)
    bid1 = build(:bid, team: team1, topic: topic1)
    bid2 = build(:bid, team: team1, topic: topic2)
    bid3 = build(:bid, team: team2, topic: topic2)
    allow(assignment).to receive(:sign_up_topics).and_return([topic1, topic2])
    allow(Team).to receive(:where).and_return([team1, team2])
    allow(team1).to receive(:bid_for_topic).with(topic1).and_return(bid1)
    allow(team1).to receive(:bid_for_topic).with(topic2).and_return(bid2)
    allow(team2).to receive(:bid_for_topic).with(topic2).and_return(bid3)

    # Perform the calculation
    percentages = assignment.calculate_percentage_of_teams_getting_choices

    # Perform your assertions here
    expect(percentages[1]).to eq(50.0)
    expect(percentages[2]).to eq(100.0)
  end
end

describe '#teams_bidding_for_each_topic' do
  it 'returns teams bidding for each topic' do
    # Mock necessary objects for the test
    assignment = build(:assignment)
    topic1 = build(:sign_up_topic, id: 1)
    topic2 = build(:sign_up_topic, id: 2)
    team1 = build(:team)
    team2 = build(:team)
    bid1 = build(:bid, team: team1, topic: topic1)
    bid2 = build(:bid, team: team1, topic: topic2)
    bid3 = build(:bid, team: team2, topic: topic2)
    allow(assignment).to receive_message_chain(:sign_up_topics, :includes).and_return([topic1, topic2])
    allow(topic1).to receive_message_chain(:bids, :map).and_return([['Team1', 1]])
    allow(topic2).to receive_message_chain(:bids, :map).and_return([['Team1', 1], ['Team2', 2]])

    # Call the method
    result = assignment.teams_bidding_for_each_topic

    # Perform assertions
    expect(result[1]).to eq([['Team1', 1]])
    expect(result[2]).to eq([['Team1', 1], ['Team2', 2]])
  end
end

describe '#bidding_info_by_topic' do
  it 'returns bidding information by topic' do
    # Mock necessary objects for the test
    assignment = build(:assignment)
    topic1 = build(:sign_up_topic, id: 1)
    topic2 = build(:sign_up_topic, id: 2)
    team1 = build(:team, name: 'Team1')
    team2 = build(:team, name: 'Team2')
    bid1 = build(:bid, team: team1, priority: 1)
    bid2 = build(:bid, team: team2, priority: 2)
    allow(assignment).to receive_message_chain(:sign_up_topics, :includes).and_return([topic1, topic2])
    allow(topic1).to receive_message_chain(:bids, :includes, :map).and_return([{ team_name: 'Team1', bid_priority: 1 }])
    allow(topic2).to receive_message_chain(:bids, :includes, :map).and_return([{ team_name: 'Team2', bid_priority: 2 }])

    # Call the method
    result = assignment.bidding_info_by_topic

    # Perform assertions
    expect(result[1]).to eq([{ team_name: 'Team1', bid_priority: 1 }])
    expect(result[2]).to eq([{ team_name: 'Team2', bid_priority: 2 }])
  end
end

describe '#assigned_teams_for_topics' do
  it 'returns assigned teams for each topic' do
    # Mock necessary objects for the test
    assignment = build(:assignment)
    topic1 = build(:sign_up_topic, id: 1)
    topic2 = build(:sign_up_topic, id: 2)
    team1 = build(:team, name: 'Team1')
    team2 = build(:team, name: 'Team2')
    allow(assignment).to receive_message_chain(:sign_up_topics, :includes).and_return([topic1, topic2])
    allow(topic1).to receive_message_chain(:assigned_teams, :map).and_return(['Team1'])
    allow(topic2).to receive_message_chain(:assigned_teams, :map).and_return(['Team2'])

    # Call the method
    result = assignment.assigned_teams_for_topics

    # Perform assertions
    expect(result[1]).to eq(['Team1'])
    expect(result[2]).to eq(['Team2'])
  end
end


Team

Mentor:

  • Anvitha Reddy Gutha (agutha@ncsu.edu)

Members:

  • Shiva Vara Prasad Kandhagatla (skandha@ncsu.edu)
  • Sai Santhosh Garlapati (sgarlap@ncsu.edu)
  • Chinmay Walinjkar (cpwalinj@ncsu.edu)