diff --git a/README.md b/README.md index 678657f..f274111 100644 --- a/README.md +++ b/README.md @@ -122,8 +122,7 @@ Claper is passwordless, so you don't have to create an account. Just login with ## Roadmap -- [ ] Add Changelog -- [ ] Remove dead code +- [x] Add Changelog - [ ] Add additional tests for better coverage - [ ] Add more docs diff --git a/lib/claper/accounts.ex b/lib/claper/accounts.ex index 71f6525..5222254 100644 --- a/lib/claper/accounts.ex +++ b/lib/claper/accounts.ex @@ -136,11 +136,11 @@ defmodule Claper.Accounts do end @doc """ - Delivers the update email instructions to the given user. + Delivers the magic link email to the given user. ## Examples - iex> deliver_update_email_instructions(user, current_email, &Routes.user_update_email_url(conn, :edit, &1)) + iex> deliver_magic_link(user, &Routes.user_confirmation_url(conn, :confirm_magic, &1)) {:ok, %{to: ..., body: ...}} """ @@ -152,6 +152,15 @@ defmodule Claper.Accounts do UserNotifier.deliver_magic_link(email, magic_link_url_fun.(encoded_token)) end + @doc """ + Delivers the update email instructions to the given user. + + ## Examples + + iex> deliver_update_email_instructions(user, current_email, &Routes.user_update_email_url(conn, :edit, &1)) + {:ok, %{to: ..., body: ...}} + + """ def deliver_update_email_instructions(%User{} = user, current_email, update_email_url_fun) when is_function(update_email_url_fun, 1) do {encoded_token, user_token} = UserToken.build_email_token(user, "change:#{current_email}") @@ -179,6 +188,9 @@ defmodule Claper.Accounts do Repo.one(query) end + @doc """ + Verify the token for a given user email is valid. + """ def magic_token_valid?(email) do query = UserToken.user_magic_and_contexts_expiry_query(email) Repo.exists?(query) diff --git a/lib/claper/events.ex b/lib/claper/events.ex index 2aa943f..779a006 100644 --- a/lib/claper/events.ex +++ b/lib/claper/events.ex @@ -1,6 +1,8 @@ defmodule Claper.Events do @moduledoc """ The Events context. + + An activity leader is a facilitator, a user invited to manage an event. """ import Ecto.Query, warn: false @@ -9,11 +11,11 @@ defmodule Claper.Events do alias Claper.Events.{Event, ActivityLeader} @doc """ - Returns the list of events. + Returns the list of events of a given user. ## Examples - iex> list_events() + iex> list_events(123) [%Event{}, ...] """ @@ -23,6 +25,15 @@ defmodule Claper.Events do |> Repo.preload(preload) end + @doc """ + Returns the list of events managed by a given user email. + + ## Examples + + iex> list_managed_events_by("email@example.com") + [%Event{}, ...] + + """ def list_managed_events_by(email, preload \\ []) do from(a in ActivityLeader, join: u in Claper.Accounts.User, @@ -58,16 +69,30 @@ defmodule Claper.Events do ## Examples - iex> get_event!(123) + iex> get_event!("123e4567-e89b-12d3-a456-426614174000") %Event{} - iex> get_event!(456) + iex> get_event!("123e4567-e89b-12d3-a456-4266141740111") ** (Ecto.NoResultsError) """ def get_event!(id, preload \\ []), do: Repo.get_by!(Event, uuid: id) |> Repo.preload(preload) + @doc """ + Gets a single managed event. + + Raises `Ecto.NoResultsError` if the Event does not exist. + + ## Examples + + iex> get_managed_event!(user, "123e4567-e89b-12d3-a456-426614174000") + %Event{} + + iex> get_managed_event!(another_user, "123e4567-e89b-12d3-a456-426614174000") + ** (Ecto.NoResultsError) + + """ def get_managed_event!(current_user, id, preload \\ []) do event = Repo.get_by!(Event, uuid: id) is_leader = Claper.Events.is_leaded_by(current_user.email, event) || event.user_id == current_user.id @@ -78,9 +103,37 @@ defmodule Claper.Events do end end + @doc """ + Gets a single user's event. + + Raises `Ecto.NoResultsError` if the Event does not exist. + + ## Examples + + iex> get_user_event!(user, "123e4567-e89b-12d3-a456-426614174000") + %Event{} + + iex> get_user_event!(another_user, "123e4567-e89b-12d3-a456-426614174000") + ** (Ecto.NoResultsError) + + """ def get_user_event!(user_id, id, preload \\ []), do: Repo.get_by!(Event, uuid: id, user_id: user_id) |> Repo.preload(preload) + @doc """ + Gets a single event by code. + + Raises `Ecto.NoResultsError` if the Event does not exist. + + ## Examples + + iex> get_event_with_code!("Hello") + %Event{} + + iex> get_event_with_code!("Old event") + ** (Ecto.NoResultsError) + + """ def get_event_with_code!(code, preload \\ []) do now = NaiveDateTime.utc_now() @@ -97,6 +150,16 @@ defmodule Claper.Events do |> Repo.preload(preload) end + @doc """ + Get a single event with the same code excluding a specific event. + + ## Examples + + iex> get_different_event_with_code("Hello", 123) + %Event{} + + + """ def get_different_event_with_code(nil, _event_id), do: nil def get_different_event_with_code(code, event_id) do @@ -106,6 +169,16 @@ defmodule Claper.Events do |> Repo.one() end + @doc """ + Check if a user is a facilitator of a specific event. + + ## Examples + + iex> is_leaded_by("email@example.com", 123) + true + + + """ def is_leaded_by(email, event) do from(a in ActivityLeader, join: u in Claper.Accounts.User, @@ -214,20 +287,7 @@ defmodule Claper.Events do alias Claper.Events.ActivityLeader @doc """ - Returns the list of activity_leaders. - - ## Examples - - iex> list_activity_leaders() - [%ActivityLeader{}, ...] - - """ - def list_activity_leaders do - Repo.all(ActivityLeader) - end - - @doc """ - Gets a single activity_leader. + Gets a single facilitator. Raises `Ecto.NoResultsError` if the Activity leader does not exist. @@ -242,6 +302,15 @@ defmodule Claper.Events do """ def get_activity_leader!(id), do: Repo.get!(ActivityLeader, id) + @doc """ + Gets all facilitators for a given event. + + ## Examples + + iex> get_activity_leaders_for_event!(event) + [%ActivityLeader{}, ...] + + """ def get_activity_leaders_for_event(event_id) do from(a in ActivityLeader, left_join: u in Claper.Accounts.User, @@ -253,7 +322,7 @@ defmodule Claper.Events do end @doc """ - Returns an `%Ecto.Changeset{}` for tracking activity_leader changes. + Returns an `%Ecto.Changeset{}` for tracking facilitator changes. ## Examples diff --git a/lib/claper/polls.ex b/lib/claper/polls.ex index c335549..ffff02b 100644 --- a/lib/claper/polls.ex +++ b/lib/claper/polls.ex @@ -11,11 +11,11 @@ defmodule Claper.Polls do alias Claper.Polls.PollVote @doc """ - Returns the list of polls. + Returns the list of polls for a given presentation file. ## Examples - iex> list_polls() + iex> list_polls(123) [%Poll{}, ...] """ @@ -28,6 +28,15 @@ defmodule Claper.Polls do |> Repo.preload([:poll_opts]) end + @doc """ + Returns the list of polls for a given presentation file and a given position. + + ## Examples + + iex> list_polls_at_position(123, 0) + [%Poll{}, ...] + + """ def list_polls_at_position(presentation_file_id, position) do from(p in Poll, where: p.presentation_file_id == ^presentation_file_id and p.position == ^position, @@ -38,7 +47,7 @@ defmodule Claper.Polls do end @doc """ - Gets a single poll. + Gets a single poll and set percentages for each poll options. Raises `Ecto.NoResultsError` if the Poll does not exist. @@ -63,6 +72,15 @@ defmodule Claper.Polls do ) |> set_percentages() + @doc """ + Gets a single poll for a given position. + + ## Examples + + iex> get_poll!(123, 0) + %Poll{} + + """ def get_poll_current_position(presentation_file_id, position) do from(p in Poll, where: @@ -80,6 +98,15 @@ defmodule Claper.Polls do |> set_percentages() end + @doc """ + Calculate percentage of all poll options for a given poll. + + ## Examples + + iex> set_percentages(poll) + %Poll{} + + """ def set_percentages(%Poll{poll_opts: poll_opts} = poll) when is_list(poll_opts) do total = Enum.map(poll.poll_opts, fn e -> e.vote_count end) |> Enum.sum() @@ -122,10 +149,10 @@ defmodule Claper.Polls do ## Examples - iex> update_poll(poll, %{field: new_value}) + iex> update_poll("123e4567-e89b-12d3-a456-426614174000", poll, %{field: new_value}) {:ok, %Poll{}} - iex> update_poll(poll, %{field: bad_value}) + iex> update_poll("123e4567-e89b-12d3-a456-426614174000", poll, %{field: bad_value}) {:error, %Ecto.Changeset{}} """ @@ -148,10 +175,10 @@ defmodule Claper.Polls do ## Examples - iex> delete_poll(poll) + iex> delete_poll("123e4567-e89b-12d3-a456-426614174000", poll) {:ok, %Poll{}} - iex> delete_poll(poll) + iex> delete_poll("123e4567-e89b-12d3-a456-426614174000", poll) {:error, %Ecto.Changeset{}} """ @@ -283,16 +310,12 @@ defmodule Claper.Polls do @doc """ Gets a single poll_vote. - Raises `Ecto.NoResultsError` if the Poll vote does not exist. ## Examples - iex> get_poll_vote!(123) + iex> get_poll_vote!(321, 123) %PollVote{} - iex> get_poll_vote!(456) - ** (Ecto.NoResultsError) - """ def get_poll_vote(user_id, poll_id) when is_number(user_id), do: Repo.get_by(PollVote, poll_id: poll_id, user_id: user_id) diff --git a/lib/claper/posts.ex b/lib/claper/posts.ex index e59c7f9..314f47a 100644 --- a/lib/claper/posts.ex +++ b/lib/claper/posts.ex @@ -55,10 +55,10 @@ defmodule Claper.Posts do ## Examples - iex> get_post!(123) + iex> get_post!("123e4567-e89b-12d3-a456-426614174000") %Post{} - iex> get_post!(456) + iex> get_post!("123e4567-e89b-12d3-a456-426614174123") ** (Ecto.NoResultsError) """ @@ -69,10 +69,10 @@ defmodule Claper.Posts do ## Examples - iex> create_post(%{field: value}) + iex> create_post(event, %{field: value}) {:ok, %Post{}} - iex> create_post(%{field: bad_value}) + iex> create_post(event, %{field: bad_value}) {:error, %Ecto.Changeset{}} """ diff --git a/lib/claper/presentations.ex b/lib/claper/presentations.ex index c87ac75..b44540b 100644 --- a/lib/claper/presentations.ex +++ b/lib/claper/presentations.ex @@ -51,10 +51,10 @@ defmodule Claper.Presentations do ## Examples - iex> update_presentation_file(presentation_files, %{field: new_value}) + iex> update_presentation_file(presentation_file, %{field: new_value}) {:ok, %PresentationFile{}} - iex> update_presentation_file(presentation_files, %{field: bad_value}) + iex> update_presentation_file(presentation_file, %{field: bad_value}) {:error, %Ecto.Changeset{}} """ diff --git a/mix.exs b/mix.exs index 9d3f035..7b552d9 100644 --- a/mix.exs +++ b/mix.exs @@ -37,8 +37,29 @@ defmodule Claper.MixProject do Usage: ~r/guides\/usage\/.?/ ], groups_for_modules: [ - Authentication: [ - Claper.Accounts + "User management": [ + ~r/Claper\.Account\.?/, + ~r/ClaperWeb\.UserRegistration\.?/, + ~r/ClaperWeb\.UserSession\.?/, + ~r/ClaperWeb\.UserLiveAuth\.?/, + ~r/ClaperWeb\.UserConfirmation\.?/, + ~r/ClaperWeb\.UserSettings\.?/, + ~r/ClaperWeb\.UserReset\.?/, + ~r/ClaperWeb\.Attendee\.?/, + ~r/ClaperWeb\.UserAuth\.?/, + ~r/ClaperWeb\.UserView\.?/, + ], + "Events": [ + ~r/Claper\.Event\.?/, + ~r/ClaperWeb\.Event\.?/, + ], + "Polls": [ + ~r/Claper\.Polls\.?/, + ~r/ClaperWeb\.Poll\.?/, + ], + "Posts": [ + ~r/Claper\.Posts\.?/, + ~r/ClaperWeb\.Post\.?/, ] ] ]