data_export: add more context to answers

This commit is contained in:
Jyrki Gadinger 2024-08-06 10:48:12 +02:00 committed by Andreas Nedbal
parent 652df25186
commit ce69ec7cec
2 changed files with 337 additions and 7 deletions

View File

@ -5,17 +5,76 @@ module UseCase
class Answers < UseCase::DataExport::Base class Answers < UseCase::DataExport::Base
def files = { def files = {
"answers.json" => json_file!( "answers.json" => json_file!(
answers: user.answers.map(&method(:collect_answer)) answers: user.answers.map(&method(:collect_answer)),
) ),
} }
def collect_answer(answer) def collect_answer(answer)
{}.tap do |h| {}.tap do |h|
column_names(::Answer).each do |field| column_names(::Answer).each do |field|
h[field] = answer[field] h[field] = answer[field]
h[:related] = related_fields(answer)
end end
end end
end end
def related_fields(answer) = {
question: question_for(answer),
comments: comments_for(answer),
}
def question_for(answer)
return unless answer.question
question = answer.question
{}.tap do |q|
q.merge!(
id: nil,
anonymous: false,
generated: false,
direct: false,
author: nil,
content: nil,
created_at: nil,
)
%i[id direct content created_at].each do |field|
q[field] = question[field]
end
if question.generated?
q[:generated] = true
q[:anonymous] = true
elsif question.author_is_anonymous
q[:anonymous] = true
else
q[:author] = lean_user(question.user)
end
end
end
def comments_for(answer) = [].tap do |c|
next if answer.comments.empty?
answer.comments.order(:created_at).each do |comment|
c << {
id: comment.id,
author: lean_user(comment.user),
smile_count: comment.smile_count,
content: comment.content,
created_at: comment.created_at,
}
end
end
def lean_user(user)
return unless user
{
id: user.id,
screen_name: user.screen_name,
}
end
end end
end end
end end

View File

@ -9,15 +9,15 @@ describe UseCase::DataExport::Answers, :data_export do
it "returns an empty set of answers" do it "returns an empty set of answers" do
expect(json_file("answers.json")).to eq( expect(json_file("answers.json")).to eq(
{ {
answers: [] answers: [],
} },
) )
end end
end end
context "when user has made some answer" do context "when user has made some answer" do
let!(:answer) do let!(:answer) do
travel_to(Time.utc(2022, 12, 10, 13, 37, 42)) { FactoryBot.create(:answer, user:, content: "Yay, data export!") } travel_to(Time.utc(2022, 12, 10, 13, 37, 42)) { FactoryBot.create(:answer, user:, content: "Yay, data export!", question: FactoryBot.build(:question, content: "awoo?")) }
end end
it "returns the answers as json" do it "returns the answers as json" do
@ -34,9 +34,280 @@ describe UseCase::DataExport::Answers, :data_export do
updated_at: "2022-12-10T13:37:42.000Z", updated_at: "2022-12-10T13:37:42.000Z",
smile_count: 0, smile_count: 0,
pinned_at: nil, pinned_at: nil,
related: {
question: {
id: answer.question.id,
anonymous: true,
generated: false,
direct: true,
author: nil,
content: "awoo?",
created_at: "2022-12-10T13:37:42.000Z",
},
comments: [],
},
} }
],
},
)
end
end
context "when user has made plenty of answers to many different question types" do
let(:other_user) { FactoryBot.create(:user, screen_name: "TomTurbo") }
let!(:questions) do
[
travel_to(Time.utc(2024, 8, 6, 13, 12, 0)) { FactoryBot.create(:question, user: other_user, content: "Sieben Zwiebeln sieden Bienen auf Trieben", author_is_anonymous: false, direct: false) },
travel_to(Time.utc(2024, 8, 6, 13, 37, 42)) { FactoryBot.create(:question, user:, content: "Direct question from myself, to myself!", author_is_anonymous: false, direct: true) },
travel_to(Time.utc(2024, 8, 6, 13, 37, 42)) { FactoryBot.create(:question, user:, content: "The funny lasaganga in oven question", author_is_anonymous: true, direct: true, author_identifier: "justask") },
travel_to(Time.utc(2024, 8, 6, 13, 37, 42)) { FactoryBot.create(:question, user:, content: "Export is ready", author_is_anonymous: true, direct: true, author_identifier: "retrospring_exporter") },
travel_to(Time.utc(2024, 8, 6, 13, 37, 50)) { FactoryBot.create(:question, user:, content: "delete your account", author_is_anonymous: true, direct: true) }
] ]
end
let!(:answers) do
questions.map.with_index do |question, i|
travel_to(Time.utc(2024, 8, 6, 13, 37, i)) do
FactoryBot.create(:answer, user:, content: "Yay, data export!", question:)
end
end
end
let!(:answer_with_unknown_question) do
travel_to(Time.utc(2024, 8, 6, 13, 38, 0)) do
FactoryBot.create(:answer, user:, content: "aeeeugh???").tap { _1.update_column(:question_id, 666) } # rubocop:disable Rails/SkipsModelValidations
end
end
it "returns the answers as json" do
expect(json_file("answers.json")).to eq(
{
answers: [
{
id: answers[0].id,
content: "Yay, data export!",
question_id: questions[0].id,
comment_count: 0,
user_id: user.id,
created_at: "2024-08-06T13:37:00.000Z",
updated_at: "2024-08-06T13:37:00.000Z",
smile_count: 0,
pinned_at: nil,
related: {
question: {
id: questions[0].id,
anonymous: false,
generated: false,
direct: false,
author: {
id: other_user.id,
screen_name: "TomTurbo",
},
content: "Sieben Zwiebeln sieden Bienen auf Trieben",
created_at: "2024-08-06T13:12:00.000Z",
},
comments: [],
},
},
{
id: answers[1].id,
content: "Yay, data export!",
question_id: questions[1].id,
comment_count: 0,
user_id: user.id,
created_at: "2024-08-06T13:37:01.000Z",
updated_at: "2024-08-06T13:37:01.000Z",
smile_count: 0,
pinned_at: nil,
related: {
question: {
id: questions[1].id,
anonymous: false,
generated: false,
direct: true,
author: {
id: user.id,
screen_name: user.screen_name,
},
content: "Direct question from myself, to myself!",
created_at: "2024-08-06T13:37:42.000Z",
},
comments: [],
},
},
{
id: answers[2].id,
content: "Yay, data export!",
question_id: questions[2].id,
comment_count: 0,
user_id: user.id,
created_at: "2024-08-06T13:37:02.000Z",
updated_at: "2024-08-06T13:37:02.000Z",
smile_count: 0,
pinned_at: nil,
related: {
question: {
id: questions[2].id,
anonymous: true,
generated: true,
direct: true,
author: nil,
content: "The funny lasaganga in oven question",
created_at: "2024-08-06T13:37:42.000Z",
},
comments: [],
},
},
{
id: answers[3].id,
content: "Yay, data export!",
question_id: questions[3].id,
comment_count: 0,
user_id: user.id,
created_at: "2024-08-06T13:37:03.000Z",
updated_at: "2024-08-06T13:37:03.000Z",
smile_count: 0,
pinned_at: nil,
related: {
question: {
id: questions[3].id,
anonymous: true,
generated: true,
direct: true,
author: nil,
content: "Export is ready",
created_at: "2024-08-06T13:37:42.000Z",
},
comments: [],
},
},
{
id: answers[4].id,
content: "Yay, data export!",
question_id: questions[4].id,
comment_count: 0,
user_id: user.id,
created_at: "2024-08-06T13:37:04.000Z",
updated_at: "2024-08-06T13:37:04.000Z",
smile_count: 0,
pinned_at: nil,
related: {
question: {
id: questions[4].id,
anonymous: true,
generated: false,
direct: true,
author: nil,
content: "delete your account",
created_at: "2024-08-06T13:37:50.000Z",
},
comments: [],
},
},
{
id: answer_with_unknown_question.id,
content: "aeeeugh???",
question_id: 666,
comment_count: 0,
user_id: user.id,
created_at: "2024-08-06T13:38:00.000Z",
updated_at: "2024-08-06T13:38:00.000Z",
smile_count: 0,
pinned_at: nil,
related: {
question: nil,
comments: [],
},
} }
],
},
)
end
end
context "when user has made an answers that received comments" do
let(:other_user) { FactoryBot.create(:user, screen_name: "TomTurbo") }
let!(:question) do
travel_to(Time.utc(2024, 8, 6, 13, 12, 0)) { FactoryBot.create(:question, user: other_user, content: "Sieben Zwiebeln sieden Bienen auf Trieben", author_is_anonymous: false, direct: false) }
end
let!(:answer) do
travel_to(Time.utc(2024, 8, 6, 13, 38, 0)) { FactoryBot.create(:answer, user:, content: "Interessante Frage", question:) }
end
let!(:comments) do
[
travel_to(Time.utc(2024, 8, 6, 13, 40, 0)) { FactoryBot.create(:comment, user:, answer:, content: "Kein Kommentar") },
travel_to(Time.utc(2024, 8, 6, 13, 42, 0)) { FactoryBot.create(:comment, user:, answer:, content: "Sehr witzig") },
travel_to(Time.utc(2024, 8, 6, 13, 41, 0)) { FactoryBot.create(:comment, user: other_user, answer:, content: "Jo eh.", smile_count: 1) }
]
end
it "returns the answers as json" do
expect(json_file("answers.json")).to eq(
{
answers: [
{
id: answer.id,
content: "Interessante Frage",
question_id: answer.question.id,
comment_count: 3,
user_id: user.id,
created_at: "2024-08-06T13:38:00.000Z",
updated_at: "2024-08-06T13:38:00.000Z",
smile_count: 0,
pinned_at: nil,
related: {
question: {
id: answer.question.id,
anonymous: false,
generated: false,
direct: false,
author: {
id: other_user.id,
screen_name: "TomTurbo",
},
content: "Sieben Zwiebeln sieden Bienen auf Trieben",
created_at: "2024-08-06T13:12:00.000Z",
},
comments: [
{
id: comments[0].id,
author: {
id: user.id,
screen_name: user.screen_name,
},
smile_count: 0,
content: "Kein Kommentar",
created_at: "2024-08-06T13:40:00.000Z",
},
{
id: comments[2].id,
author: {
id: other_user.id,
screen_name: other_user.screen_name,
},
smile_count: 1,
content: "Jo eh.",
created_at: "2024-08-06T13:41:00.000Z",
},
{
id: comments[1].id,
author: {
id: user.id,
screen_name: user.screen_name,
},
smile_count: 0,
content: "Sehr witzig",
created_at: "2024-08-06T13:42:00.000Z",
}
],
},
}
],
},
) )
end end
end end