From de29f973dd9546ccdff4062db43d28374cde5b02 Mon Sep 17 00:00:00 2001 From: Gautam Rege Date: Thu, 15 Sep 2016 10:10:35 +0530 Subject: [PATCH] refs #88 Feature Hackathon Added all controller test cases. --- app/assets/javascripts/hackathons.coffee | 3 + app/assets/stylesheets/hackathons.scss | 3 + app/controllers/hackathons_controller.rb | 9 ++ app/helpers/hackathons_helper.rb | 2 + config/routes.rb | 7 + lib/tasks/utils.rake | 2 +- .../controllers/hackathons_controller_test.rb | 92 ++++++++++++ test/factories/commits.rb | 3 +- test/factories/rounds.rb | 2 +- test/factories/users.rb | 1 + test/helpers/hackathons_helper_test.rb | 7 + test/models/hackathon_test.rb | 134 ++++++++++++++++-- 12 files changed, 252 insertions(+), 13 deletions(-) create mode 100644 app/assets/javascripts/hackathons.coffee create mode 100644 app/assets/stylesheets/hackathons.scss create mode 100644 app/controllers/hackathons_controller.rb create mode 100644 app/helpers/hackathons_helper.rb create mode 100644 test/controllers/hackathons_controller_test.rb create mode 100644 test/helpers/hackathons_helper_test.rb diff --git a/app/assets/javascripts/hackathons.coffee b/app/assets/javascripts/hackathons.coffee new file mode 100644 index 00000000..24f83d18 --- /dev/null +++ b/app/assets/javascripts/hackathons.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/hackathons.scss b/app/assets/stylesheets/hackathons.scss new file mode 100644 index 00000000..7e359262 --- /dev/null +++ b/app/assets/stylesheets/hackathons.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the hackathons controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/hackathons_controller.rb b/app/controllers/hackathons_controller.rb new file mode 100644 index 00000000..9804250d --- /dev/null +++ b/app/controllers/hackathons_controller.rb @@ -0,0 +1,9 @@ +class HackathonsController < ApplicationController + include HackathonsHelper + + before_action :authenticate_user!, except: [ :show ] + + def create + render :success + end +end diff --git a/app/helpers/hackathons_helper.rb b/app/helpers/hackathons_helper.rb new file mode 100644 index 00000000..ce5281b5 --- /dev/null +++ b/app/helpers/hackathons_helper.rb @@ -0,0 +1,2 @@ +module HackathonsHelper +end diff --git a/config/routes.rb b/config/routes.rb index 734bf0a8..403cba40 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -94,6 +94,13 @@ get :resend_invitation end end + + resources :hackathons do + member do + post :repositories + post :join + end + end get 'accept_invitation/:group_id/:token' => 'groups/members#accept_invitation', as: :accept_invitation get 'widgets/repo/:id(/:round_id)' => 'widgets#repo', as: :repo_widget get 'widgets/group/:id(/:round_id)' => 'widgets#group', as: :group_widget diff --git a/lib/tasks/utils.rake b/lib/tasks/utils.rake index 09cb974c..ffc73929 100644 --- a/lib/tasks/utils.rake +++ b/lib/tasks/utils.rake @@ -47,7 +47,7 @@ namespace :utils do task :hackathon, [:group] => :environment do |t, args| group = Group.where(name: args[:group]).first if group # Ignore if incorrect name - type = "all" + type = "daily" round = Round.opened group.members.each do |user| UserReposJob.perform_later(user) diff --git a/test/controllers/hackathons_controller_test.rb b/test/controllers/hackathons_controller_test.rb new file mode 100644 index 00000000..ebdeb207 --- /dev/null +++ b/test/controllers/hackathons_controller_test.rb @@ -0,0 +1,92 @@ +require "test_helper" +require "sidekiq/testing" + +class HackathonsControllerTest < ActionController::TestCase + setup do + Sidekiq::Testing.fake! + @user = FactoryGirl.create(:user, github_handle: "dummy") + sign_in(@user) + end + + teardown do + sign_out(@user) + end + + def create_hackathon + #assert_difference 'Hackathon.count' do + post :create, { name: "My Hack Day", + from: Date.today.beginning_of_day, + end: (Date.today + 2.days).end_of_day + }, xhr: true + #end + assert_response :success + assert_select ".repositories form" + assert_select ".members form" + end + + test "create a hackathon" do + create_hackathon + + round = Round.where(name: "My Hack Day").first + group = Group.where(name: "My Hack Day").first + + assert_includes @user.round, round + assert_equal group.owner, @user + end + + test "create a hackathon with specific respositories" do + create_hackathon + + assert_difference 'Hackathon.last.repositories.count', 2 do + post repositories_hackathon_url(id: Hackathon.last), { + repositories: { "0": { name: 'dummy_repos_url' }, + "1": { name: "dummy_repos_2_url" } + } + }, xhr: true + end + assert_response :success + assert_select "#repositories tr", 2 # there should be 2 repositories in the list + end + + test "add member to hackathon if member registered with CodeCuriosity" do + create_hackathon + + # create a dummy user! + FactoryGirl.create(:user, github_handle: "dummy", email: "dummy@dummy.com") + + assert_difference 'Hackathon.last.group.members.count', 1 do + post join_hackathon(id: Hackathon.last), { + "user_id": "dummy" + }, xhr: true + end + assert_response :success + assert_select "#group-members tr", 2 # owner and new member + end + + test "flash notice if github handle not registered with CodeCuriosity" do + create_hackathon + + assert_no_difference 'Hackathon.last.group.members.count' do + post join_hackathon(id: Hackathon.last), { + "user_id": "dummy" + }, xhr: true + end + assert_response :success + assert_equal "No such user. Invite using email", flash[:notice] + end + + test "invite member to hackathon if email not exist and is not registered with CodeCuriosity" do + create_hackathon + + assert_no_difference 'Hackathon.last.group.members.count' do + post join_hackathon(id: Hackathon.last), { + "user_id": "dummy@dummy.com" + }, xhr: true + end + assert_response :success + # test if email was sent to dummy@dummy.com + end + + test "show hackathon widget" do + end +end diff --git a/test/factories/commits.rb b/test/factories/commits.rb index c4d15f57..b3850563 100644 --- a/test/factories/commits.rb +++ b/test/factories/commits.rb @@ -1,7 +1,8 @@ FactoryGirl.define do factory :commit do + commit_date { Faker::Time.between(DateTime.now - 1.hour, DateTime.now)} message {Faker::Lorem.paragraph} association :user association :repository end -end \ No newline at end of file +end diff --git a/test/factories/rounds.rb b/test/factories/rounds.rb index cc49da96..6e519dc3 100644 --- a/test/factories/rounds.rb +++ b/test/factories/rounds.rb @@ -6,7 +6,7 @@ status {random = ["active","open","inactive"].sample} trait :hackathon do - from_date { Faker::Time.between(DateTime.now + 1, DateTime.now + 2)} + from_date { Faker::Time.between(DateTime.now - 1, DateTime.now + 2)} end_date {Faker::Time.between(DateTime.now + 3, DateTime.now + 5)} end diff --git a/test/factories/users.rb b/test/factories/users.rb index 10f94d56..b31a1700 100644 --- a/test/factories/users.rb +++ b/test/factories/users.rb @@ -6,6 +6,7 @@ sign_in_count {Faker::Number.digit} active {random_boolean = [true, false].sample} is_judge {random_boolean = [true, false].sample} + auth_token { Faker::Crypto.sha256 } github_handle {Faker::Internet.user_name} factory :user_with_transactions do diff --git a/test/helpers/hackathons_helper_test.rb b/test/helpers/hackathons_helper_test.rb new file mode 100644 index 00000000..a63c7daf --- /dev/null +++ b/test/helpers/hackathons_helper_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class HackathonsHelperTest < ActionView::TestCase + def test_sanity + flunk "Need real tests" + end +end diff --git a/test/models/hackathon_test.rb b/test/models/hackathon_test.rb index 7b38e062..b441eae4 100644 --- a/test/models/hackathon_test.rb +++ b/test/models/hackathon_test.rb @@ -8,12 +8,30 @@ def setup @hackathon = create(:hackathon, user: create(:user)) @hackathon_r = create(:hackathon_with_repositories, user: create(:user)) - # Simulate commits and activities for this user (total user points should be: 6) - create_list(:commit, 2, repository: @hackathon_r.repositories.first, - auto_score: 2, user: @hackathon_r.user, round: @hackathon_r.round) - create_list(:activity, 2, repository: @hackathon_r.repositories.last, - auto_score: 1, user: @hackathon_r.user, round: @hackathon_r.round) + simulate_contributions + end + + # Returns the new hackathon object for the new member + def add_member_to_hackathon(hackathon = @hackathon_r, new_user = nil) + hackathon.update_attribute(:status, "open") + new_user = create(:user) unless new_user + + # Post addtion of a member to the hackathon group, + # a hackathon object should be created for that user! + hackathon.group.members << new_user + + # returns the new hackathon object for that user + new_user.subscriptions.where(round: hackathon.round).first + end + + def simulate_contributions(user = @hackathon_r.user, + round = @hackathon_r.round, + repository = @hackathon_r.repositories.first) + # Simulate commits and activities for the user on some random repository + create_list(:commit, 2, repository: repository, auto_score: 2, user: user, round: round) + create_list(:activity, 2, repository: repository, auto_score: 1, user: user, round: round) end + test "is_valid" do assert @hackathon.valid? @@ -76,40 +94,136 @@ def setup test "points_is_updated_if_round_spans_different_months" do # eg. Hackathon is from 30-Mar till 2-Apr end + test "points_is_not_calculated_when_the_hackathon_round_is_inactive" do + # default state of the hackathon is "inactive" + @hackathon_r.update_points + assert_equal 0, @hackathon_r.points + end + + test "points_updation_does_not_create_any_transactions" do + @hackathon_r.update_attribute(:status, "open") + @hackathon_r.update_points + assert_equal 6, @hackathon_r.points + + assert_empty @hackathon_r.transactions + end + test "points_is_updated_for_commits_and_activity_only_for_hackathon_repositories" do dummy = create(:repository_with_activity_and_commits) + @hackathon_r.update_attribute(:status, "open") + @hackathon_r.update_points + assert_equal 6, @hackathon_r.points + end + + test "points_for_user_are_updated_for_commits_and_activity_only_for_hackathon_repositories" do + @hackathon_r.update_attribute(:status, "open") + simulate_contributions(@hackathon_r.user, create(:round), create(:repository)) @hackathon_r.update_points assert_equal 6, @hackathon_r.points end test "points_is_updated_for_all_commits_and_activity_if_hackathon_repositories_is_blank" do + simulate_contributions(@hackathon.user, @hackathon.round, create(:repository)) + assert_empty @hackathon.repositories + + @hackathon.update_attribute(:status, "open") + @hackathon.update_points + assert_equal 6, @hackathon.points end test "points_is_updated_only_for_commits_and_activity_between_start_and_end_of_hackathon_round" do - end + ## Test with @hackathon with empty repositories + @hackathon.update_attribute(:status, "open") - test "points_is_not_calculated_when_the_hackathon_round_is_inactive" do - end + # check for sanity - currenly open hackathon + simulate_contributions(@hackathon.user, @hackathon.round, create(:repository)) + @hackathon.update_points + assert_equal 6, @hackathon.points - test "points_updation_does_not_create_any_transactions" do + @hackathon.update_attribute(:status, "close") + # make more contributions after hackathon has closed + simulate_contributions(@hackathon.user, @hackathon.round, create(:repository)) + + # new contribs should not have impacted hackathon score! + @hackathon.update_points + assert_equal 6, @hackathon.points + + ### Test with @hackathon_r i.e. with repositories. + @hackathon_r.update_attribute(:status, "open") + + # check for sanity - currenly open hackathon + @hackathon_r.update_points + assert_equal 6, @hackathon_r.points + + @hackathon_r.update_attribute(:status, "close") + # make more contributions to hackathon repos + simulate_contributions + + # new contribs should not have impacted hackathon score! + @hackathon_r.update_points + assert_equal 6, @hackathon_r.points end test "sidekiq_job_should_be_enqueued_for_next_fetch_data_after_udpate_interval" do end test "new_member_can_be_added_to_hackathon_group_if_hackathon_round_is_open" do + @hackathon_r.update_attribute(:status, "open") + assert_empty @hackathon_r.group.members + assert_equal @hackathon_r.group.owner, @hackathon_r.user + + # Add 2 members to the hackathon that is open. + @hackathon_r.group.members << create(:user) + @hackathon_r.group.members << create(:user) + assert_equal 2, @hackathon_r.group.members + + # Now we close the hackathon -- no more members should be able to join. + @hackathon_r.update_attribute(:status, "close") + @hackathon_r.group.members << create(:user) + assert_equal 2, @hackathon_r.group.members + end + + test "new_member_should_have_a_valid_hackathon_round_and_group" do + nh = add_member_to_hackathon + + flunk "not yet completed" + + assert nh.valid? + assert_equal nh.group, @hackathon_r.group + assert_equal nh.round, @hackathon_r.round + assert_equal nh.repositories, @hackathon_r.repositories + assert_equal nh.name, @hackathon_r.name end test "new_member_points_is_calculated_from_round_start_datetime_if_hackathon_round_is_open" do + nu = create(:user) + + # create commits worth 4 points in the same repository as that of the hackthon but 1 day prior + create_list(:commit, 2, repository: @hackathon_r.repositories.first, + auto_score: 2, user: nu, round: @hackathon_r.round, + commit_date: @hackathon_r.round.from_date - 1.day) + + nh = add_member_to_hackathon(@hackathon_r, nu) + + flunk "not yet completed" + + # Create contribs worth 12 points. + simulate_contributions(nh.user, nh.round, nh.repositories.first) + simulate_contributions(nh.user, nh.round, nh.repositories.first) + + nh.update_points + assert_equal 12, nh.points end - test "existing_member_points_is_updated_from_last_interval_time_if_hackathon_round_is_open" do + test "widget_shows_only_points_of_members_of_the_hackathon" do end test "widget_shows_points_of_members_with_non_zero_points_only_for_the_hackathon_round" do end test "widget_shows_points_of_members_if_hackathon_round_is_closed" do + # use travel_to to test what happens after the hackathon has closed. + # travel_to @hackthon.round.end_date + 1.day do end # not sure if we need to check this.