From 6f34a031d020576acc173e615c0742f9fe84644d Mon Sep 17 00:00:00 2001 From: Juan Wajnerman Date: Fri, 13 Oct 2017 17:00:39 -0300 Subject: [PATCH 1/3] Version bump (0.10.4) --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index fb039d6f4..a44a36c2d 100644 --- a/mix.exs +++ b/mix.exs @@ -3,7 +3,7 @@ defmodule Ask.Mixfile do def project do [app: :ask, - version: "0.10.3", + version: "0.10.4", elixir: "~> 1.2", elixirc_paths: elixirc_paths(Mix.env), compilers: [:phoenix, :gettext] ++ Mix.compilers, From bb1d43633dd7f7674001ccbbe5b446db300f6efa Mon Sep 17 00:00:00 2001 From: Juan Wajnerman Date: Fri, 13 Oct 2017 17:13:43 -0300 Subject: [PATCH 2/3] Fix respondent stats that were breaking sometimes when a respondent is in "completed" disposition but still active --- .../respondent_controller_test.exs | 35 +++++++++++++------ web/controllers/respondent_controller.ex | 24 ++++++------- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/test/controllers/respondent_controller_test.exs b/test/controllers/respondent_controller_test.exs index bebf39d89..db0828d5c 100644 --- a/test/controllers/respondent_controller_test.exs +++ b/test/controllers/respondent_controller_test.exs @@ -69,9 +69,9 @@ defmodule Ask.RespondentControllerTest do survey = insert(:survey, project: project, cutoff: 10, started_at: t) questionnaire = insert(:questionnaire, name: "test", project: project, steps: @dummy_steps) insert_list(10, :respondent, survey: survey, questionnaire: questionnaire, disposition: "partial") - insert(:respondent, survey: survey, disposition: "completed", questionnaire: questionnaire, completed_at: Timex.parse!("2016-01-01T10:00:00Z", "{ISO:Extended}")) - insert(:respondent, survey: survey, disposition: "completed", questionnaire: questionnaire, completed_at: Timex.parse!("2016-01-01T11:00:00Z", "{ISO:Extended}")) - insert_list(3, :respondent, survey: survey, disposition: "completed", questionnaire: questionnaire, completed_at: Timex.parse!("2016-01-02T10:00:00Z", "{ISO:Extended}")) + insert(:respondent, survey: survey, disposition: "completed", questionnaire: questionnaire, updated_at: Ecto.DateTime.cast!("2016-01-01T10:00:00Z")) + insert(:respondent, survey: survey, disposition: "completed", questionnaire: questionnaire, updated_at: Ecto.DateTime.cast!("2016-01-01T11:00:00Z")) + insert_list(3, :respondent, survey: survey, disposition: "completed", questionnaire: questionnaire, updated_at: Ecto.DateTime.cast!("2016-01-02T10:00:00Z")) conn = get conn, project_survey_respondents_stats_path(conn, :stats, project.id, survey.id) data = json_response(conn, 200)["data"] @@ -122,6 +122,21 @@ defmodule Ask.RespondentControllerTest do assert data["total_respondents"] == 15 end + test "stats do not crash when a respondent has 'completed' disposition but no 'completed_at'", %{conn: conn, user: user} do + t = Timex.parse!("2016-01-01T10:00:00Z", "{ISO:Extended}") + project = create_project_for_user(user) + survey = insert(:survey, project: project, cutoff: 1, started_at: t) + questionnaire = insert(:questionnaire, name: "test", project: project, steps: @dummy_steps) + insert(:respondent, survey: survey, disposition: "completed", questionnaire: questionnaire, updated_at: t |> Timex.to_erl |> Ecto.DateTime.from_erl) + + conn = get conn, project_survey_respondents_stats_path(conn, :stats, project.id, survey.id) + data = json_response(conn, 200)["data"] + + cumulative_percentages = data["cumulative_percentages"][to_string(questionnaire.id)] + assert Enum.at(cumulative_percentages, 0)["date"] == "2016-01-01" + assert Enum.at(cumulative_percentages, 0)["percent"] == 100 + end + test "lists stats for a given survey with quotas", %{conn: conn, user: user} do t = Timex.parse!("2016-01-01T10:00:00Z", "{ISO:Extended}") project = create_project_for_user(user) @@ -130,10 +145,10 @@ defmodule Ask.RespondentControllerTest do bucket_2 = insert(:quota_bucket, survey: survey, quota: 3, count: 3) questionnaire = insert(:questionnaire, name: "test", project: project, steps: @dummy_steps) insert_list(10, :respondent, survey: survey, questionnaire: questionnaire, disposition: "partial") - insert(:respondent, survey: survey, questionnaire: questionnaire, disposition: "completed", completed_at: Timex.parse!("2016-01-01T10:00:00Z", "{ISO:Extended}"), quota_bucket: bucket_1) - insert(:respondent, survey: survey, questionnaire: questionnaire, disposition: "completed", completed_at: Timex.parse!("2016-01-01T11:00:00Z", "{ISO:Extended}"), quota_bucket: bucket_1) - insert(:respondent, survey: survey, questionnaire: questionnaire, disposition: "rejected", completed_at: Timex.parse!("2016-01-02T10:00:00Z", "{ISO:Extended}"), quota_bucket: bucket_2) - insert_list(3, :respondent, survey: survey, questionnaire: questionnaire, disposition: "completed", completed_at: Timex.parse!("2016-01-02T10:00:00Z", "{ISO:Extended}"), quota_bucket: bucket_2) + insert(:respondent, survey: survey, questionnaire: questionnaire, disposition: "completed", updated_at: Ecto.DateTime.cast!("2016-01-01T10:00:00Z"), quota_bucket: bucket_1) + insert(:respondent, survey: survey, questionnaire: questionnaire, disposition: "completed", updated_at: Ecto.DateTime.cast!("2016-01-01T11:00:00Z"), quota_bucket: bucket_1) + insert(:respondent, survey: survey, questionnaire: questionnaire, disposition: "rejected", updated_at: Ecto.DateTime.cast!("2016-01-02T10:00:00Z"), quota_bucket: bucket_2) + insert_list(3, :respondent, survey: survey, questionnaire: questionnaire, disposition: "completed", updated_at: Ecto.DateTime.cast!("2016-01-02T10:00:00Z"), quota_bucket: bucket_2) conn = get conn, project_survey_respondents_stats_path(conn, :stats, project.id, survey.id) data = json_response(conn, 200)["data"] @@ -189,9 +204,9 @@ defmodule Ask.RespondentControllerTest do survey = insert(:survey, project: project, cutoff: 10, started_at: t) questionnaire = insert(:questionnaire, name: "test", project: project, steps: @dummy_steps) insert_list(10, :respondent, survey: survey, state: "pending", disposition: "registered") - insert(:respondent, survey: survey, state: "completed", questionnaire: questionnaire, disposition: "partial", completed_at: Timex.parse!("2016-01-01T10:00:00Z", "{ISO:Extended}")) - insert(:respondent, survey: survey, state: "completed", questionnaire: questionnaire, disposition: "completed", completed_at: Timex.parse!("2016-01-01T11:00:00Z", "{ISO:Extended}")) - insert_list(3, :respondent, survey: survey, state: "completed", questionnaire: questionnaire, disposition: "ineligible", completed_at: Timex.parse!("2016-01-02T10:00:00Z", "{ISO:Extended}")) + insert(:respondent, survey: survey, state: "completed", questionnaire: questionnaire, disposition: "partial", updated_at: Ecto.DateTime.cast!("2016-01-01T10:00:00Z")) + insert(:respondent, survey: survey, state: "completed", questionnaire: questionnaire, disposition: "completed", updated_at: Ecto.DateTime.cast!("2016-01-01T11:00:00Z")) + insert_list(3, :respondent, survey: survey, state: "completed", questionnaire: questionnaire, disposition: "ineligible", updated_at: Ecto.DateTime.cast!("2016-01-02T10:00:00Z")) conn = get conn, project_survey_respondents_stats_path(conn, :stats, project.id, survey.id) data = json_response(conn, 200)["data"] diff --git a/web/controllers/respondent_controller.ex b/web/controllers/respondent_controller.ex index 6454710c7..223645e1f 100644 --- a/web/controllers/respondent_controller.ex +++ b/web/controllers/respondent_controller.ex @@ -335,17 +335,17 @@ defmodule Ask.RespondentController do defp respondents_by_questionnaire_and_completed_at(survey) do Repo.all( from r in Respondent, where: r.survey_id == ^survey.id and r.disposition == "completed", - group_by: fragment("questionnaire_id, DATE(completed_at)"), - order_by: fragment("DATE(completed_at) ASC"), - select: {r.questionnaire_id, fragment("DATE(completed_at)"), count("*")}) + group_by: fragment("questionnaire_id, DATE(updated_at)"), + order_by: fragment("DATE(updated_at) ASC"), + select: {r.questionnaire_id, fragment("DATE(updated_at)"), count("*")}) end defp respondents_by_questionnaire_mode_and_completed_at(survey) do Repo.all( from r in Respondent, where: r.survey_id == ^survey.id and r.disposition == "completed", - group_by: fragment("questionnaire_id, mode, DATE(completed_at)"), - order_by: fragment("DATE(completed_at) ASC"), - select: {r.questionnaire_id, r.mode, fragment("DATE(completed_at)"), count("*")}) + group_by: fragment("questionnaire_id, mode, DATE(updated_at)"), + order_by: fragment("DATE(updated_at) ASC"), + select: {r.questionnaire_id, r.mode, fragment("DATE(updated_at)"), count("*")}) |> Enum.map(fn({questionnaire_id, mode, completed_at, count}) -> reference_id = if mode && questionnaire_id do "#{questionnaire_id}#{mode |> Enum.join("")}" @@ -360,17 +360,17 @@ defmodule Ask.RespondentController do defp respondents_by_mode_and_completed_at(survey) do Repo.all( from r in Respondent, where: r.survey_id == ^survey.id and r.disposition == "completed", - group_by: fragment("mode, DATE(completed_at)"), - order_by: fragment("DATE(completed_at) ASC"), - select: {r.mode, fragment("DATE(completed_at)"), count("*")}) + group_by: fragment("mode, DATE(updated_at)"), + order_by: fragment("DATE(updated_at) ASC"), + select: {r.mode, fragment("DATE(updated_at)"), count("*")}) end defp respondents_by_quota_bucket_and_completed_at(survey) do Repo.all( from r in Respondent, where: r.survey_id == ^survey.id and r.disposition == "completed", - group_by: fragment("quota_bucket_id, DATE(completed_at)"), - order_by: fragment("DATE(completed_at) ASC"), - select: {r.quota_bucket_id, fragment("DATE(completed_at)"), count("*")}) + group_by: fragment("quota_bucket_id, DATE(updated_at)"), + order_by: fragment("DATE(updated_at) ASC"), + select: {r.quota_bucket_id, fragment("DATE(updated_at)"), count("*")}) end defp add_disposition_percent(respondents_count_by_disposition_and_questionnaire, total_respondents) do From 1c4380c7212c16d7741eb5fe4888ff0e00c3da2b Mon Sep 17 00:00:00 2001 From: Juan Wajnerman Date: Fri, 13 Oct 2017 17:14:31 -0300 Subject: [PATCH 3/3] Updated changelog (0.10.4) --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 217e8bb65..4ef51c667 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # InSTEDD Surveda Changelog +## Juniper 0.10.4 + +### Bugfixes + +* Fix respondent stats that were breaking sometimes when a respondent is in "completed" disposition but still active + ## Juniper 0.10.3 ### Features