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

Add collaborators #264

Closed
wants to merge 10 commits into from
96 changes: 96 additions & 0 deletions lib/atomic/accounts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -350,4 +350,100 @@ defmodule Atomic.Accounts do
{:error, :user, changeset, _} -> {:error, changeset}
end
end

alias Atomic.Accounts.Collaborator

@doc """
Returns the list of collaborators.

## Examples

iex> list_collaborators()
[%Collaborator{}, ...]

"""
def list_collaborators do
Repo.all(Collaborator)
end

@doc """
Gets a single collaborator.

Raises `Ecto.NoResultsError` if the Collaborator does not exist.

## Examples

iex> get_collaborator!(123)
%Collaborator{}

iex> get_collaborator!(456)
** (Ecto.NoResultsError)

"""
def get_collaborator!(id), do: Repo.get!(Collaborator, id)

@doc """
Creates a collaborator.

## Examples

iex> create_collaborator(%{field: value})
{:ok, %Collaborator{}}

iex> create_collaborator(%{field: bad_value})
{:error, %Ecto.Changeset{}}

"""
def create_collaborator(attrs \\ %{}) do
%Collaborator{}
|> Collaborator.changeset(attrs)
|> Repo.insert()
end

@doc """
Updates a collaborator.

## Examples

iex> update_collaborator(collaborator, %{field: new_value})
{:ok, %Collaborator{}}

iex> update_collaborator(collaborator, %{field: bad_value})
{:error, %Ecto.Changeset{}}

"""
def update_collaborator(%Collaborator{} = collaborator, attrs) do
collaborator
|> Collaborator.changeset(attrs)
|> Repo.update()
end

@doc """
Deletes a collaborator.

## Examples

iex> delete_collaborator(collaborator)
{:ok, %Collaborator{}}

iex> delete_collaborator(collaborator)
{:error, %Ecto.Changeset{}}

"""
def delete_collaborator(%Collaborator{} = collaborator) do
Repo.delete(collaborator)
end

@doc """
Returns an `%Ecto.Changeset{}` for tracking collaborator changes.

## Examples

iex> change_collaborator(collaborator)
%Ecto.Changeset{data: %Collaborator{}}

"""
def change_collaborator(%Collaborator{} = collaborator, attrs \\ %{}) do
Collaborator.changeset(collaborator, attrs)
end
end
20 changes: 20 additions & 0 deletions lib/atomic/accounts/collaborator.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
defmodule Atomic.Accounts.Collaborator do
use Atomic.Schema
alias Atomic.Departments.Department
alias Atomic.Accounts.User
alias Atomic.Users.CollaboratorDepartment

@required_fields ~w(name organization_id user_id)a
schema "collaborators" do
many_to_many :departments, Department, join_through: CollaboratorDepartment
belongs_to :user, User
timestamps()
end

@doc false
def changeset(collaborator, attrs) do
collaborator
|> cast(attrs, @required_fields)
|> validate_required(@required_fields)
end
end
30 changes: 30 additions & 0 deletions lib/atomic/accounts/collaborator_department.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
defmodule Atomic.Users.CollaboratorDepartment do
@moduledoc """
An activity speaker
MarioRodrigues10 marked this conversation as resolved.
Show resolved Hide resolved
"""
use Atomic.Schema

alias Atomic.Departments.Department
alias Atomic.Accounts.Collaborator

@required_fields ~w(collaborator_id department_id)a

schema "collaborator_departments" do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we not have a role to identify this relation, e.g.: 'President', 'Vice-President', etc?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about creating another schema "board_users" where i give those roles to an user

Copy link
Member Author

@MarioRodrigues10 MarioRodrigues10 Mar 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inside this schema i can create role field and give it to user , what you think?

belongs_to :collaborator, Collaborator
belongs_to :department, Department

timestamps()
end

def changeset(collaborator_departments, attrs) do
collaborator_departments
|> cast(attrs, @required_fields)
|> validate_required(@required_fields)
end

def create_changeset(collaborator_departments, attrs) do
collaborator_departments
|> cast(attrs, @required_fields)
|> validate_required(@required_fields)
end
end
4 changes: 2 additions & 2 deletions lib/atomic/accounts/user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule Atomic.Accounts.User do
use Atomic.Schema

alias Atomic.Activities.Enrollment

alias Atomic.Accounts.Collaborator
@roles ~w(admin staff student)a

schema "users" do
Expand All @@ -15,8 +15,8 @@ defmodule Atomic.Accounts.User do
field :confirmed_at, :naive_datetime

field :role, Ecto.Enum, values: @roles

has_many :enrollments, Enrollment
has_one :collaborator, Collaborator, on_replace: :delete_if_exists, on_delete: :delete_all
MarioRodrigues10 marked this conversation as resolved.
Show resolved Hide resolved

timestamps()
end
Expand Down
2 changes: 2 additions & 0 deletions lib/atomic/departments/department.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ defmodule Atomic.Departments.Department do
use Atomic.Schema

alias Atomic.Activities.Activity
alias Atomic.Accounts.Collaborator
alias Atomic.Users.CollaboratorDepartment

@required_fields ~w(name)a

Expand Down
13 changes: 13 additions & 0 deletions priv/repo/migrations/20230114142345_create_collaborators.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
defmodule Atomic.Repo.Migrations.CreateCollaborators do
use Ecto.Migration

def change do
create table(:collaborators, primary_key: false) do
add :id, :binary_id, primary_key: true
add :user_id, references(:users, on_delete: :nothing, type: :binary_id)
timestamps()
end

create unique_index(:collaborators, [:user_id])
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
defmodule Atomic.Repo.Migrations.CreateCollaboratorDepartments do
use Ecto.Migration

def change do
create table(:collaborator_departments, primary_key: false) do
add :id, :binary_id, primary_key: true

add :collaborator_id, references(:collaborators, on_delete: :nothing, type: :binary_id)
add :department_id, references(:departments, on_delete: :nothing, type: :binary_id)

timestamps()
end
end
end
56 changes: 56 additions & 0 deletions test/atomic/accounts_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -505,4 +505,60 @@ defmodule Atomic.AccountsTest do
refute inspect(%User{password: "123456"}) =~ "password: \"123456\""
end
end

describe "collaborators" do
alias Atomic.Accounts.Collaborator

import Atomic.AccountsFixtures

@invalid_attrs %{}

test "list_collaborators/0 returns all collaborators" do
collaborator = collaborator_fixture()
assert Accounts.list_collaborators() == [collaborator]
end

test "get_collaborator!/1 returns the collaborator with given id" do
collaborator = collaborator_fixture()
assert Accounts.get_collaborator!(collaborator.id) == collaborator
end

test "create_collaborator/1 with valid data creates a collaborator" do
valid_attrs = %{}

assert {:ok, %Collaborator{} = collaborator} = Accounts.create_collaborator(valid_attrs)
end

test "create_collaborator/1 with invalid data returns error changeset" do
assert {:error, %Ecto.Changeset{}} = Accounts.create_collaborator(@invalid_attrs)
end

test "update_collaborator/2 with valid data updates the collaborator" do
collaborator = collaborator_fixture()
update_attrs = %{}

assert {:ok, %Collaborator{} = collaborator} =
Accounts.update_collaborator(collaborator, update_attrs)
end

test "update_collaborator/2 with invalid data returns error changeset" do
collaborator = collaborator_fixture()

assert {:error, %Ecto.Changeset{}} =
Accounts.update_collaborator(collaborator, @invalid_attrs)

assert collaborator == Accounts.get_collaborator!(collaborator.id)
end

test "delete_collaborator/1 deletes the collaborator" do
collaborator = collaborator_fixture()
assert {:ok, %Collaborator{}} = Accounts.delete_collaborator(collaborator)
assert_raise Ecto.NoResultsError, fn -> Accounts.get_collaborator!(collaborator.id) end
end

test "change_collaborator/1 returns a collaborator changeset" do
collaborator = collaborator_fixture()
assert %Ecto.Changeset{} = Accounts.change_collaborator(collaborator)
end
end
end
12 changes: 12 additions & 0 deletions test/support/fixtures/accounts_fixtures.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,16 @@ defmodule Atomic.AccountsFixtures do
[_, token | _] = String.split(captured_email.text_body, "[TOKEN]")
token
end

@doc """
Generate a collaborator.
"""
def collaborator_fixture(attrs \\ %{}) do
{:ok, collaborator} =
attrs
|> Enum.into(%{})
|> Atomic.Accounts.create_collaborator()

collaborator
end
MarioRodrigues10 marked this conversation as resolved.
Show resolved Hide resolved
end