Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#187382426] Offenses and coverage #76

Merged
merged 5 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions rails_root/.simplecov
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# frozen_string_literal: true

require 'simplecov'

SimpleCov.start 'rails' do
enable_coverage :branch # see https://github.com/colszowka/simplecov#branch-coverage-ruby--25
add_filter '/app/jobs/'
add_filter '/app/mailers/'
add_filter '/app/channels/'
end

SimpleCov.merge_timeout 3600
18 changes: 11 additions & 7 deletions rails_root/app/controllers/home_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,25 @@ def index
return if @survey_profile.nil?

@survey_responses = fetch_survey_responses
@invitations = fetch_invitations
end

private

def fetch_survey_responses
SurveyResponse.where(profile_id: @survey_profile.id).map do |response|
{ response:, invited_by: fetch_invited_by(response) }
SurveyResponse.where(profile_id: @survey_profile.id)
end

def fetch_invitations
@survey_responses.map do |response|
invitation = Invitation.find_by(response_id: response.id)
invitation ? fetch_invited_by(invitation) : 'N/A'
end
end

def fetch_invited_by(response)
invitation = Invitation.find_by(response_id: response.id)
parent_response = SurveyResponse.find(invitation.parent_response_id) if invitation
def fetch_invited_by(invitation)
parent_response = SurveyResponse.find(invitation.parent_response_id)
profile = SurveyProfile.find(parent_response.profile_id) if parent_response
name = "#{profile.first_name} #{profile.last_name}" if profile
name || 'N/A'
"#{profile.first_name} #{profile.last_name}" if profile
end
end
13 changes: 4 additions & 9 deletions rails_root/app/controllers/invitations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ def create
@parent_survey_response = SurveyResponse.find_by!(id: params[:parent_survey_response_id])
@invitation = Invitation.create!(parent_response: @parent_survey_response, last_sent: Time.now, visited: false)

redirect_to invitation_created_invitation_path(@invitation.token)
render json: {
message: "Invitation link created: #{invitation_url(@invitation.token)}",
invitation_url: invitation_url(@invitation.token)
}
end

def show
Expand All @@ -32,14 +35,6 @@ def not_found
render :not_found
end

def invitation_created
@invitation = Invitation.find_by(token: params[:token])

return unless @invitation.nil?

redirect_to not_found_invitations_path
end

private

def claim_invitation(user_profile)
Expand Down
3 changes: 3 additions & 0 deletions rails_root/app/controllers/survey_responses_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ def edit
return return_to_root 'Your profile could not be found. Please complete your profile.' unless SurveyProfile.exists?(user_id: current_user_id)
return return_to_root 'You cannot edit this result.' if current_user_id != @survey_response.profile.user_id

# Initialize page number to 1 if not already set
session[:page_number] = 1 if session[:page_number].nil?

@pagination, @questions, @section = paginate(collection: SurveyQuestion.all, params: { per_page: 10, page: session[:page_number] })
end

Expand Down
52 changes: 25 additions & 27 deletions rails_root/app/models/survey_response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,46 +20,44 @@ class SurveyResponse < ApplicationRecord

def self.create_from_params(user_id, params)
# FIXME: When we look up things and fail, we should use more descriptive exceptions instead of ActiveRecord::RecordNotFound

profile = SurveyProfile.where(user_id:).first!
profile = find_profile(user_id)

# Use provided share_code if exists, else generate a new one
share_code = if params.nil?
SecureRandom.hex(3)
else
params[:share_code] || SecureRandom.hex(3)
end
share_code = generate_share_code(params)

# FIXME: Handle share code already existing
survey_response = SurveyResponse.create(profile:, share_code:)
survey_response = create_survey_response(profile, share_code)

return survey_response if params.nil?

params&.each do |key, choice|
create_survey_answers(params, survey_response)
survey_response
rescue ActiveRecord::RecordNotFound
logger.info 'Survey profile not found!'
nil
end

def self.find_profile(user_id)
SurveyProfile.where(user_id:).first!
end

def self.generate_share_code(params)
params.nil? ? SecureRandom.hex(3) : params[:share_code] || SecureRandom.hex(3)
end

def self.create_survey_response(profile, share_code)
SurveyResponse.create(profile:, share_code:)
end

def self.create_survey_answers(params, survey_response)
params.each do |key, choice|
begin
question = SurveyQuestion.find key
rescue ActiveRecord::RecordNotFound
next
end
SurveyAnswer.create choice:, question:, response: survey_response
SurveyAnswer.create(choice:, question:, response: survey_response)
end
survey_response
rescue ActiveRecord::RecordNotFound
logger.info 'Survey profile not found!'
nil

# 96.times do |i|
# begin
# index = (i+1).to_s
# question = SurveyQuestion.find index
# if params[index].nil?
# choice = "5"
# else
# choice = params[index]
# end
# SurveyAnswer.create choice:, question:, response: survey_response
# end
# end
end

def update_from_params(user_id, params)
Expand Down
10 changes: 5 additions & 5 deletions rails_root/app/views/home/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
</thead>
<% if !@survey_responses.nil?%>
<tbody>
<% @survey_responses.each do |response_hash| %>
<% @survey_responses.zip(@invitations).each do |response, invited_by| %>
<tr>
<td><%= response_hash[:response].created_at %></td>
<td><%= response_hash[:invited_by] %></td>
<td><%= response_hash[:response].share_code %></td>
<td><%= link_to "Show", survey_response_path(response_hash[:response]) %></td>
<td><%= response.created_at %></td>
<td><%= invited_by %></td>
<td><%= response.share_code %></td>
<td><%= link_to "Show", survey_response_path(response) %></td>
</tr>
<% end %>
</tbody>
Expand Down
3 changes: 0 additions & 3 deletions rails_root/app/views/invitations/invitation_created.html.erb

This file was deleted.

132 changes: 94 additions & 38 deletions rails_root/app/views/survey_responses/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<p style="color: green"><%= notice %></p>

<%# FIXME: Move this to a stylesheet when we have time %>
<style>
.section-header {
Expand Down Expand Up @@ -28,7 +27,6 @@
transition: height 0.0s ease;
}
</style>

<div class="container-lg">
<h1 class="text-center">Your leadership type is: (tbd)</h1>
<div class="row d-flex justify-content-center">
Expand Down Expand Up @@ -93,54 +91,112 @@
<td><%= ans.question.text %></td>
<td><%= choices[ans.choice] %></td>
<% 4.times do |i| %>
<td>
<input
<td>
<input
type="radio"
disabled="disabled"
<%= 'checked="checked"' if i == ans.choice %>
>
</td>
<% end %>
</tr>
<tr class="collapse" id="<%= question_collapse_id %>">
<td colspan="6">
</td>
<% end %>
</tr>
<tr class="collapse" id="<%= question_collapse_id %>">
<td colspan="6">
<%= ans.question.explanation %>
</td>
</tr>
<% end %>
</table>
</td>
</tr>
<% end %>
</table>
</div>
<% end %>
</div>
</div>
<hr>
<%# this is the view containing the link %>
<div id="invitation-link-container" class="mt-4" style="display: none;">
<div class="card">
<div class="card-body">
<h5 class="card-title">Invitation Link Created</h5>
<p class="card-text">
<span id="invitation-link"></span>
</p>
<button class="btn btn-primary" onclick="copyToClipboard()">Copy Link</button>
</div>
<% end %>
</div>
<hr>
</div>
</div>
<hr>
<div class="row d-flex justify-content-center">
<div class="col-8 btn-group" role="group">
<%= link_to "Edit Response",
<script>
function copyToClipboard() {
var linkText = document.getElementById("invitation-link").innerText;
navigator.clipboard.writeText(linkText)
.then(() => {
alert("Link copied to clipboard!");
})
.catch((error) => {
console.error("Failed to copy link: ", error);
});
}
</script>
<div class="row d-flex justify-content-center">
<div class="col-8 btn-group" role="group">
<%= link_to "Edit Response",
edit_survey_response_path(@survey_response),
class: "btn btn-outline-primary"
%>
<%= button_to "Create Invitation",
invitations_path(parent_survey_response_id: @survey_response.id),
method: :post,
id: "invitation-button",
form_class: "btn btn-outline-success",
class: "btn-passthrough"
%>
<%= button_to "Delete Response",
%>
<%= button_tag "Create Invitation",
data: { parent_survey_response_id: @survey_response.id },
id: "invitation-button",
class: "btn btn-outline-success"
%>
<%= button_to "Delete Response",
@survey_response,
method: :delete,

form_class: "btn btn-outline-danger",
class: "btn-passthrough"
%>
%>
</div>
</div>
</div>
<br>
<div class="row d-flex justify-content-center">
<div class="col-6 text-center">
<%= link_to "Back to survey responses", survey_responses_path %>
<%= link_to "Back to home", root_path %>
<div>
</div>
</div>
<%# show invitation link if it exist %>
<script>
function initializeInvitation() {
var invitationButton = document.getElementById('invitation-button');
var invitationLinkContainer = document.getElementById('invitation-link-container');
var invitationLink = document.getElementById('invitation-link');

invitationButton.addEventListener('click', function() {
var parentSurveyResponseId = this.getAttribute('data-parent-survey-response-id');

fetch('/invitations', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
},
body: JSON.stringify({ parent_survey_response_id: parentSurveyResponseId })
})
.then(response => response.json())
.then(data => {
invitationLink.textContent = data.invitation_url;
invitationLinkContainer.style.display = 'block';
})
.catch(error => {
console.error('Error:', error);
});
});
}

if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initializeInvitation);
} else {
initializeInvitation();
}
</script>
<br>
<div class="row d-flex justify-content-center">
<div class="col-6 text-center">
<%= link_to "Back to survey responses", survey_responses_path %>
<%= link_to "Back to home", root_path %>
<div>
</div>
</div>
4 changes: 0 additions & 4 deletions rails_root/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@
collection do
get :not_found
end

member do
get :invitation_created
end
end

get '/auth/auth0/callback' => 'auth0#callback'
Expand Down
1 change: 0 additions & 1 deletion rails_root/features/invitation.feature
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ Feature: Invitation
When I create an invitation at the bottom of the response page
Then the invitation's sharecode should be set to the response's sharecode
And the invitation's parent_response_id should be set to the response's id
And I should see a link that can be copied

Scenario: Generate unique invitation URL
Given an invitation exists
Expand Down
Loading
Loading