diff --git a/elixir/lib/homework/companies.ex b/elixir/lib/homework/companies.ex new file mode 100644 index 00000000..78c6a509 --- /dev/null +++ b/elixir/lib/homework/companies.ex @@ -0,0 +1,124 @@ +defmodule Homework.Companies do + @moduledoc """ + The Companies context + """ + + import Ecto.Query, warn: false + alias Homework.Repo + + alias Homework.Companies.Company + + @doc """ + Returns a list of companies + + ## Examples + + iex> list_companies([]) + [%Company{}, ...] + """ + def list_companies(_args) do + Repo.all(Company) + end + + @doc """ + Gets a single company + + Raises 'Ecto.NoResultsError' if the Company does not exist.any() + + ## Examples + + iex> get_company!(123) + %Company{} + + iex> get_company!(456) + ** (Ecto.NoResultsError) + """ + def get_company!(id), do: Repo.get!(Company, id) + + @doc """ + Gets a company by name. + + ## Example + + iex> get_company_by_name("Divvy") + %Company{} + + iex> get_company_by_name("X") + %[] + + """ + + def get_company_by_name(name) do + Repo.all( + from(c in Company, + where: ilike(c.name, ^"%#{name}%") + ) + ) + end + + @doc """ + Creates a company + + ## Examples + + iex> create_company(%{field: value}) + {:ok, %Company{}} + + iex> create_company(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + """ + def create_company(attrs \\ %{}) do + %Company{} + |> Company.changeset(attrs) + |> Repo.insert() + end + + @doc """ + Updates a company. + + ## Examples + + iex> update_company(company, %{field: new_value}) + {:ok, %User{}} + + iex> update_company(company, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_company(%Company{} = company, attrs) do + company + |> Company.changeset(attrs) + |> Repo.update() + end + + @doc """ + Deletes a company. + + ## Examples + + iex> delete_company(company) + {:ok, %Company{}} + + iex> delete_company(company) + {:error, %Ecto.Changeset{}} + + """ + def delete_company(%Company{} = company) do + Repo.delete(company) + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking company changes. + + ## Examples + + iex> change_company(company) + %Ecto.Changeset{data: %Company{}} + + """ + def change_company(%Company{} = company, attrs \\ %{}) do + Company.changeset(company, attrs) + end + + +end diff --git a/elixir/lib/homework/companies/company.ex b/elixir/lib/homework/companies/company.ex new file mode 100644 index 00000000..6acad63c --- /dev/null +++ b/elixir/lib/homework/companies/company.ex @@ -0,0 +1,21 @@ +defmodule Homework.Companies.Company do + use Ecto.Schema + import Ecto.Changeset + + @primary_key {:id, :binary_id, autogenerate: true} + schema "companies" do + field(:name, :string) + field(:credit_line, :integer) + field(:available_credit, :integer) + + timestamps() + end + + @doc false + def changeset(company, attrs) do + company + |> cast(attrs, [:name, :available_credit, :credit_line]) + |> validate_required([:name, :available_credit, :credit_line]) + end + +end diff --git a/elixir/lib/homework/merchants.ex b/elixir/lib/homework/merchants.ex index a581e33b..f034bd7f 100644 --- a/elixir/lib/homework/merchants.ex +++ b/elixir/lib/homework/merchants.ex @@ -37,6 +37,28 @@ defmodule Homework.Merchants do """ def get_merchant!(id), do: Repo.get!(Merchant, id) + + @doc """ + Gets a merchant by name. + + ## Example + + iex> get_merchant_by_name("Divvy") + %Merchant{} + + iex> get_merchant_by_name("X") + %[] + + """ + + def get_merchant_by_name(name) do + Repo.all( + from(m in Merchant, + where: ilike(m.name, ^"%#{name}%") + ) + ) + end + @doc """ Creates a merchant. diff --git a/elixir/lib/homework/transactions.ex b/elixir/lib/homework/transactions.ex index f7ec3dfb..67f80583 100644 --- a/elixir/lib/homework/transactions.ex +++ b/elixir/lib/homework/transactions.ex @@ -7,6 +7,7 @@ defmodule Homework.Transactions do alias Homework.Repo alias Homework.Transactions.Transaction + alias Homework.Companies.Company @doc """ Returns the list of transactions. @@ -37,6 +38,26 @@ defmodule Homework.Transactions do """ def get_transaction!(id), do: Repo.get!(Transaction, id) + @doc """ + Searches transactions and filters by amount. + + #Examples + + iex> filter_transaction(minimum: 100, maximum: 500) + %Transactions{} + + iex> filter_transaction(minimum: 0, maximum: 0) + %[] + """ + + def filter_transaction(minimum, maximum) do + Repo.all( + from(t in Transaction, + where: t.amount >= ^minimum and t.amount <= ^maximum + ) + ) + end + @doc """ Creates a transaction. @@ -50,9 +71,30 @@ defmodule Homework.Transactions do """ def create_transaction(attrs \\ %{}) do - %Transaction{} - |> Transaction.changeset(attrs) - |> Repo.insert() + transaction = + %Transaction{} + |> Transaction.changeset(attrs) + + case Repo.insert(transaction) do + {:ok, transaction} -> + update_company_credit(transaction) + {:ok, transaction} + + {:error, changeset} -> + {:error, changeset} + end + end + + @doc """ + Updates a companies available_credit each time a new transaction is created + assoicated with the company_id. + """ + + def update_company_credit(transaction) do + company = Repo.get!(Company, transaction.company_id) + new_available_credit = company.available_credit - transaction.amount + result = Company.changeset(company, %{available_credit: new_available_credit}) + Repo.update(result) end @doc """ diff --git a/elixir/lib/homework/transactions/transaction.ex b/elixir/lib/homework/transactions/transaction.ex index e7884314..789e728f 100644 --- a/elixir/lib/homework/transactions/transaction.ex +++ b/elixir/lib/homework/transactions/transaction.ex @@ -3,6 +3,7 @@ defmodule Homework.Transactions.Transaction do import Ecto.Changeset alias Homework.Merchants.Merchant alias Homework.Users.User + alias Homework.Companies.Company @primary_key {:id, :binary_id, autogenerate: true} schema "transactions" do @@ -13,6 +14,7 @@ defmodule Homework.Transactions.Transaction do belongs_to(:merchant, Merchant, type: :binary_id, foreign_key: :merchant_id) belongs_to(:user, User, type: :binary_id, foreign_key: :user_id) + belongs_to(:company, Company, type: :binary_id, foreign_key: :company_id) timestamps() end @@ -20,7 +22,7 @@ defmodule Homework.Transactions.Transaction do @doc false def changeset(transaction, attrs) do transaction - |> cast(attrs, [:user_id, :amount, :debit, :description, :merchant_id]) - |> validate_required([:user_id, :amount, :debit, :description, :merchant_id]) + |> cast(attrs, [:user_id, :amount, :debit, :credit, :description, :merchant_id, :company_id]) + |> validate_required([:user_id, :amount, :debit, :credit, :description, :merchant_id, :company_id]) end end diff --git a/elixir/lib/homework/users.ex b/elixir/lib/homework/users.ex index d481272a..76a1629c 100644 --- a/elixir/lib/homework/users.ex +++ b/elixir/lib/homework/users.ex @@ -37,6 +37,24 @@ defmodule Homework.Users do """ def get_user!(id), do: Repo.get!(User, id) + @doc """ + Gets a user by first and last name. + + ## Examples + + iex> get_by_name("Alex", "Porter") + %User{} + + """ + + def get_user_by_name(first_name, last_name) do + Repo.all( + from(u in User, + where: ilike(u.first_name, ^"%#{first_name}%") and ilike(u.last_name, ^"%#{last_name}%") + ) + ) + end + @doc """ Creates a user. diff --git a/elixir/lib/homework/users/user.ex b/elixir/lib/homework/users/user.ex index 51ea2f95..89ed1651 100644 --- a/elixir/lib/homework/users/user.ex +++ b/elixir/lib/homework/users/user.ex @@ -1,6 +1,7 @@ defmodule Homework.Users.User do use Ecto.Schema import Ecto.Changeset + alias Homework.Companies.Company @primary_key {:id, :binary_id, autogenerate: true} schema "users" do @@ -8,13 +9,19 @@ defmodule Homework.Users.User do field(:first_name, :string) field(:last_name, :string) + belongs_to(:company, Company, type: :binary_id, foreign_key: :company_id) + timestamps() end @doc false def changeset(user, attrs) do user - |> cast(attrs, [:first_name, :last_name, :dob]) - |> validate_required([:first_name, :last_name, :dob]) + |> cast(attrs, [:first_name, :last_name, :dob, :company_id]) + |> validate_required([:first_name, :last_name, :dob, :company_id]) + |> foreign_key_constraint(:company, + name: :users_company_id_fkey, + message: "Company_ID does not exist, make sure you are entering a valid ID" + ) end end diff --git a/elixir/lib/homework_web/resolvers/companies_resolver.ex b/elixir/lib/homework_web/resolvers/companies_resolver.ex new file mode 100644 index 00000000..e00a8041 --- /dev/null +++ b/elixir/lib/homework_web/resolvers/companies_resolver.ex @@ -0,0 +1,72 @@ +defmodule HomeworkWeb.Resolvers.CompaniesResolver do + + alias Homework.Companies + + @doc """ + Get a list of companies + """ + def companies(_root, args, _info) do + {:ok, Companies.list_companies(args)} + end + + @doc """ + Create a new company + """ + + def create_company(_root, args, _info) do + case Companies.create_company(args) do + {:ok, company} -> + {:ok, company} + + error -> + {:error, "could not create company: #{inspect(error)}"} + end + end + + @doc """ + Searches for companies by name. + + Returns the matching companies, if found. + Otherwise results in an empty list. + """ + + def search_company(_root, %{name: name}, _info) do + companies = Companies.get_company_by_name(name) + + if length(companies) > 0 do + {:ok, companies} + else + {:ok, []} + end + end + + @doc """ + Updates a company for an id with args specified. + """ + def update_company(_root, %{id: id} = args, _info) do + company = Companies.get_company!(id) + + case Companies.update_company(company, args) do + {:ok, company} -> + {:ok, company} + + error -> + {:error, "could not update company: #{inspect(error)}"} + end + end + +@doc """ + Deletes a company for an id + """ + def delete_company(_root, %{id: id}, _info) do + company = Companies.get_company!(id) + + case Companies.delete_company(company) do + {:ok, company} -> + {:ok, company} + + error -> + {:error, "could not update company: #{inspect(error)}"} + end + end +end diff --git a/elixir/lib/homework_web/resolvers/merchants_resolver.ex b/elixir/lib/homework_web/resolvers/merchants_resolver.ex index f0274abc..c5abb355 100644 --- a/elixir/lib/homework_web/resolvers/merchants_resolver.ex +++ b/elixir/lib/homework_web/resolvers/merchants_resolver.ex @@ -8,6 +8,23 @@ defmodule HomeworkWeb.Resolvers.MerchantsResolver do {:ok, Merchants.list_merchants(args)} end + @doc """ + Searches for merchants by name. + + Returns the matching merchants, if found. + Otherwise results in an empty list. + """ + + def search_merchant(_root, %{name: name}, _info) do + merchants = Merchants.get_merchant_by_name(name) + + if length(merchants) > 0 do + {:ok, merchants} + else + {:ok, []} + end + end + @doc """ Create a new merchant """ diff --git a/elixir/lib/homework_web/resolvers/transactions_resolver.ex b/elixir/lib/homework_web/resolvers/transactions_resolver.ex index 4b928d62..dc6c07a1 100644 --- a/elixir/lib/homework_web/resolvers/transactions_resolver.ex +++ b/elixir/lib/homework_web/resolvers/transactions_resolver.ex @@ -2,6 +2,7 @@ defmodule HomeworkWeb.Resolvers.TransactionsResolver do alias Homework.Merchants alias Homework.Transactions alias Homework.Users + alias Homework.Companies @doc """ Get a list of transcations @@ -24,6 +25,28 @@ defmodule HomeworkWeb.Resolvers.TransactionsResolver do {:ok, Merchants.get_merchant!(merchant_id)} end + @doc """ + Get the company associated with a transaction + """ + def company(_root, _args, %{source: %{company_id: company_id}}) do + {:ok, Companies.get_company!(company_id)} + end + + @doc """ + Search transactions and filter by amount + """ + def search_transaction(_root, %{minimum: minimum, maximum: maximum}, _info) do + + transactions = Transactions.filter_transaction(minimum, maximum) + + if length(transactions) > 0 do + transactions = Enum.sort(transactions) + {:ok, transactions} + else + {:ok, []} + end + end + @doc """ Create a new transaction """ diff --git a/elixir/lib/homework_web/resolvers/users_resolver.ex b/elixir/lib/homework_web/resolvers/users_resolver.ex index 1e0c4292..a4ea7d64 100644 --- a/elixir/lib/homework_web/resolvers/users_resolver.ex +++ b/elixir/lib/homework_web/resolvers/users_resolver.ex @@ -1,5 +1,6 @@ defmodule HomeworkWeb.Resolvers.UsersResolver do alias Homework.Users + alias Homework.Companies @doc """ Get a list of users @@ -8,6 +9,29 @@ defmodule HomeworkWeb.Resolvers.UsersResolver do {:ok, Users.list_users(args)} end + @doc """ + Get the company associated with the user + """ + + def company(_root, _args, %{source: %{company_id: company_id}}) do + {:ok, Companies.get_company!(company_id)} + end + + @doc """ + Searches for users by first and last name. + + Returns the matching users, if found. + """ + def search_user(_root, %{first_name: first_name, last_name: last_name}, _info) do + users = Users.get_user_by_name(first_name, last_name) + + if length(users) > 0 do + {:ok, users} + else + {:ok, []} + end + end + @doc """ Creates a user """ diff --git a/elixir/lib/homework_web/schema.ex b/elixir/lib/homework_web/schema.ex index 56888d2f..f46af692 100644 --- a/elixir/lib/homework_web/schema.ex +++ b/elixir/lib/homework_web/schema.ex @@ -7,6 +7,8 @@ defmodule HomeworkWeb.Schema do alias HomeworkWeb.Resolvers.MerchantsResolver alias HomeworkWeb.Resolvers.TransactionsResolver alias HomeworkWeb.Resolvers.UsersResolver + alias HomeworkWeb.Resolvers.CompaniesResolver + import_types(HomeworkWeb.Schemas.Types) query do @@ -24,11 +26,17 @@ defmodule HomeworkWeb.Schema do field(:merchants, list_of(:merchant)) do resolve(&MerchantsResolver.merchants/3) end + + @desc "Get all Companies" + field(:companies, list_of(:company)) do + resolve(&CompaniesResolver.companies/3) + end end mutation do import_fields(:transaction_mutations) import_fields(:user_mutations) import_fields(:merchant_mutations) + import_fields(:company_mutations) end end diff --git a/elixir/lib/homework_web/schemas/companies_schema.ex b/elixir/lib/homework_web/schemas/companies_schema.ex new file mode 100644 index 00000000..c77ebf0a --- /dev/null +++ b/elixir/lib/homework_web/schemas/companies_schema.ex @@ -0,0 +1,52 @@ +defmodule HomeworkWeb.Schemas.CompaniesSchema do + @moduledoc """ + Defines the graphql schema for user. + """ + use Absinthe.Schema.Notation + + alias HomeworkWeb.Resolvers.CompaniesResolver + + object :company do + field(:id, non_null(:id)) + field(:name, :string) + field(:credit_line, :integer) + field(:available_credit, :integer) + field(:inserted_at, :naive_datetime) + field(:updated_at, :naive_datetime) + end + + object :company_mutations do + @desc "Create a new company" + field :create_company, :company do + arg(:name, non_null(:string)) + arg(:credit_line, non_null(:integer)) + arg(:available_credit, non_null(:integer)) + + resolve(&CompaniesResolver.create_company/3) + end + + @desc "Search for a company by name" + field :search_company, list_of(:company) do + arg(:name, non_null(:string)) + + resolve(&CompaniesResolver.search_company/3) + end + + @desc "Update a new company" + field :update_company, :company do + arg(:id, non_null(:id)) + arg(:name, non_null(:string)) + arg(:credit_line, non_null(:integer)) + arg(:available_credit, non_null(:integer)) + + resolve(&CompaniesResolver.update_company/3) + end + + @desc "Delete an existing company" + field :delete_company, :company do + arg(:id, non_null(:id)) + + resolve(&CompaniesResolver.delete_company/3) + end + end +end diff --git a/elixir/lib/homework_web/schemas/merchants_schema.ex b/elixir/lib/homework_web/schemas/merchants_schema.ex index 54faf094..e0adcb4c 100644 --- a/elixir/lib/homework_web/schemas/merchants_schema.ex +++ b/elixir/lib/homework_web/schemas/merchants_schema.ex @@ -23,6 +23,13 @@ defmodule HomeworkWeb.Schemas.MerchantsSchema do resolve(&MerchantsResolver.create_merchant/3) end + @desc "Search for a merchant by name" + field :search_merchant, list_of(:merchant) do + arg(:name, non_null(:string)) + + resolve(&MerchantsResolver.search_merchant/3) + end + @desc "Update a new merchant" field :update_merchant, :merchant do arg(:id, non_null(:id)) diff --git a/elixir/lib/homework_web/schemas/transactions_schema.ex b/elixir/lib/homework_web/schemas/transactions_schema.ex index 658deab6..0163fd55 100644 --- a/elixir/lib/homework_web/schemas/transactions_schema.ex +++ b/elixir/lib/homework_web/schemas/transactions_schema.ex @@ -14,6 +14,7 @@ defmodule HomeworkWeb.Schemas.TransactionsSchema do field(:debit, :boolean) field(:description, :string) field(:merchant_id, :id) + field(:company_id, :id) field(:inserted_at, :naive_datetime) field(:updated_at, :naive_datetime) @@ -24,6 +25,10 @@ defmodule HomeworkWeb.Schemas.TransactionsSchema do field(:merchant, :merchant) do resolve(&TransactionsResolver.merchant/3) end + + field(:company, :company) do + resolve(&TransactionsResolver.company/3) + end end object :transaction_mutations do @@ -31,6 +36,7 @@ defmodule HomeworkWeb.Schemas.TransactionsSchema do field :create_transaction, :transaction do arg(:user_id, non_null(:id)) arg(:merchant_id, non_null(:id)) + arg(:company_id, non_null(:id)) @desc "amount is in cents" arg(:amount, non_null(:integer)) arg(:credit, non_null(:boolean)) @@ -40,11 +46,20 @@ defmodule HomeworkWeb.Schemas.TransactionsSchema do resolve(&TransactionsResolver.create_transaction/3) end + @desc "Filter and search transactions by amount" + field :search_transaction, list_of(:transaction) do + arg(:minimum, non_null(:integer)) + arg(:maximum, non_null(:integer)) + + resolve(&TransactionsResolver.search_transaction/3) + end + @desc "Update a new transaction" field :update_transaction, :transaction do arg(:id, non_null(:id)) arg(:user_id, non_null(:id)) arg(:merchant_id, non_null(:id)) + arg(:company_id, non_null(:id)) @desc "amount is in cents" arg(:amount, non_null(:integer)) arg(:credit, non_null(:boolean)) diff --git a/elixir/lib/homework_web/schemas/types.ex b/elixir/lib/homework_web/schemas/types.ex index 75540319..9e3db397 100644 --- a/elixir/lib/homework_web/schemas/types.ex +++ b/elixir/lib/homework_web/schemas/types.ex @@ -5,6 +5,7 @@ defmodule HomeworkWeb.Schemas.Types do use Absinthe.Schema.Notation import_types(Absinthe.Type.Custom) + import_types(HomeworkWeb.Schemas.CompaniesSchema) import_types(HomeworkWeb.Schemas.MerchantsSchema) import_types(HomeworkWeb.Schemas.TransactionsSchema) import_types(HomeworkWeb.Schemas.UsersSchema) diff --git a/elixir/lib/homework_web/schemas/users_schema.ex b/elixir/lib/homework_web/schemas/users_schema.ex index 21bd5a90..964f7843 100644 --- a/elixir/lib/homework_web/schemas/users_schema.ex +++ b/elixir/lib/homework_web/schemas/users_schema.ex @@ -11,8 +11,14 @@ defmodule HomeworkWeb.Schemas.UsersSchema do field(:dob, :string) field(:first_name, :string) field(:last_name, :string) + field(:company_id, :id) field(:inserted_at, :naive_datetime) field(:updated_at, :naive_datetime) + + + field(:company, :company) do + resolve(&UsersResolver.company/3) + end end object :user_mutations do @@ -21,16 +27,26 @@ defmodule HomeworkWeb.Schemas.UsersSchema do arg(:dob, non_null(:string)) arg(:first_name, non_null(:string)) arg(:last_name, non_null(:string)) + arg(:company_id, non_null(:id)) resolve(&UsersResolver.create_user/3) end + @desc "Search for a user by first and last name" + field :search_user, list_of(:user) do + arg(:first_name, non_null(:string)) + arg(:last_name, non_null(:string)) + + resolve(&UsersResolver.search_user/3) + end + @desc "Update a new user" field :update_user, :user do arg(:id, non_null(:id)) arg(:dob, non_null(:string)) arg(:first_name, non_null(:string)) arg(:last_name, non_null(:string)) + arg(:company_id, non_null(:id)) resolve(&UsersResolver.update_user/3) end diff --git a/elixir/priv/repo/migrations/20191207150025_create_companies.exs b/elixir/priv/repo/migrations/20191207150025_create_companies.exs new file mode 100644 index 00000000..fbe84c57 --- /dev/null +++ b/elixir/priv/repo/migrations/20191207150025_create_companies.exs @@ -0,0 +1,14 @@ +defmodule Homework.Repo.Migrations.CreateCompanies do + use Ecto.Migration + + def change do + create table(:companies, primary_key: false) do + add(:id, :uuid, primary_key: true) + add(:name, :string) + add(:credit_line, :integer) + add(:available_credit, :integer) + + timestamps() + end + end +end diff --git a/elixir/priv/repo/migrations/20200826195245_create_users.exs b/elixir/priv/repo/migrations/20200826195245_create_users.exs index b59bf89b..fbb7f176 100644 --- a/elixir/priv/repo/migrations/20200826195245_create_users.exs +++ b/elixir/priv/repo/migrations/20200826195245_create_users.exs @@ -7,6 +7,7 @@ defmodule Homework.Repo.Migrations.CreateUsers do add(:first_name, :string) add(:last_name, :string) add(:dob, :string) + add(:company_id, references(:companies, type: :uuid, on_delete: :nothing)) timestamps() end diff --git a/elixir/priv/repo/migrations/20200826196533_create_transactions.exs b/elixir/priv/repo/migrations/20200826196533_create_transactions.exs index b8785d99..2aef1210 100644 --- a/elixir/priv/repo/migrations/20200826196533_create_transactions.exs +++ b/elixir/priv/repo/migrations/20200826196533_create_transactions.exs @@ -10,6 +10,7 @@ defmodule Homework.Repo.Migrations.CreateTransactions do add(:description, :string) add(:user_id, references(:users, type: :uuid, on_delete: :nothing)) add(:merchant_id, references(:merchants, type: :uuid, on_delete: :nothing)) + add(:company_id, references(:companies, type: :uuid, on_delete: :nothing)) timestamps() end diff --git a/elixir/priv/repo/seeds.exs b/elixir/priv/repo/seeds.exs index 718e38ca..4f828a89 100644 --- a/elixir/priv/repo/seeds.exs +++ b/elixir/priv/repo/seeds.exs @@ -9,3 +9,44 @@ # # We recommend using the bang functions (`insert!`, `update!` # and so on) as they will fail if something goes wrong. + + +# user = %User{first_name: "Test", last_name: "Seeded", dob: "11/14/1992", company_id: company_id} +# Homework.Repo.insert!(user) + + +company = Homework.Repo.insert!(%Homework.Companies.Company{name: "Nvida", credit_line: 50000, available_credit: 50000}) +company1 = Homework.Repo.insert!(%Homework.Companies.Company{name: "company1", credit_line: 10000, available_credit: 10000}) +company2 = Homework.Repo.insert!(%Homework.Companies.Company{name: "company2", credit_line: 20000, available_credit: 20000}) +company3 = Homework.Repo.insert!(%Homework.Companies.Company{name: "company3", credit_line: 30000, available_credit: 30000}) +company4 = Homework.Repo.insert!(%Homework.Companies.Company{name: "company4", credit_line: 40000, available_credit: 40000}) + + +user1 = Homework.Repo.insert!(%Homework.Users.User{first_name: "Randy", last_name: "Johnson", dob: "12/12/1212", company_id: company.id}) +user2 = Homework.Repo.insert!(%Homework.Users.User{first_name: "Patrick", last_name: "Star", dob: "2/2/1212", company_id: company1.id}) +user3 = Homework.Repo.insert!(%Homework.Users.User{first_name: "Rocket", last_name: "Power", dob: "1/1/1212", company_id: company2.id}) +user4 = Homework.Repo.insert!(%Homework.Users.User{first_name: "Book", last_name: "Reader", dob: "3/12/1212", company_id: company3.id}) +user5 = Homework.Repo.insert!(%Homework.Users.User{first_name: "Game", last_name: "Enthusiast", dob: "4/12/1212", company_id: company4.id}) + +merchant = Homework.Repo.insert!(%Homework.Merchants.Merchant{name: "Practice", description: "Makes Perfect!"}) +merchant1 = Homework.Repo.insert!(%Homework.Merchants.Merchant{name: "Another", description: "One!"}) +merchant2 = Homework.Repo.insert!(%Homework.Merchants.Merchant{name: "Almost", description: "Done!"}) +merchant3 = Homework.Repo.insert!(%Homework.Merchants.Merchant{name: "Dream", description: "Job!"}) +merchant4 = Homework.Repo.insert!(%Homework.Merchants.Merchant{name: "Last", description: "Time!"}) + + +Homework.Repo.insert!(%Homework.Transactions.Transaction{ + amount: 1000, debit: false, credit: true, description: "large purchase", merchant_id: merchant.id, user_id: user1.id, company_id: company.id +}) +Homework.Repo.insert!(%Homework.Transactions.Transaction{ + amount: 100, debit: true, credit: false, description: "decent purchase", merchant_id: merchant1.id, user_id: user2.id, company_id: company1.id +}) +Homework.Repo.insert!(%Homework.Transactions.Transaction{ + amount: 10, debit: true, credit: false, description: "small purchase", merchant_id: merchant2.id, user_id: user3.id, company_id: company2.id +}) +Homework.Repo.insert!(%Homework.Transactions.Transaction{ + amount: 1, debit: true, credit: false, description: "tiny purchase", merchant_id: merchant3.id, user_id: user4.id, company_id: company3.id +}) +Homework.Repo.insert!(%Homework.Transactions.Transaction{ + amount: 2000, debit: false, credit: true, description: "huge purchase", merchant_id: merchant4.id, user_id: user5.id, company_id: company4.id +}) diff --git a/elixir/test/homework/companies_test.exs b/elixir/test/homework/companies_test.exs new file mode 100644 index 00000000..81f2b9d5 --- /dev/null +++ b/elixir/test/homework/companies_test.exs @@ -0,0 +1,72 @@ +defmodule Homework.CompaniesTest do + use Homework.DataCase + + alias Homework.Companies + + describe "companies" do + alias Homework.Companies.Company + + @valid_attrs %{name: "some name", credit_line: 1000, available_credit: 1000} + @update_attrs %{ + name: "some updated name", + credit_line: 2000, + available_credit: 2000 + } + @invalid_attrs %{name: nil, credit_line: nil, available_credit: nil} + + def company_fixture(attrs \\ %{}) do + {:ok, company} = + attrs + |> Enum.into(@valid_attrs) + |> Companies.create_company() + + company + end + + test "list_companies/1 returns all companies" do + company = company_fixture() + assert company in Companies.list_companies([]) + end + + test "get_company!/1 returns the company with given id" do + company = company_fixture() + assert Companies.get_company!(company.id) == company + end + + test "create_company/1 with valid data creates a company" do + assert {:ok, %Company{} = company} = Companies.create_company(@valid_attrs) + assert company.credit_line == 1000 + assert company.name == "some name" + assert company.available_credit == 1000 + end + + test "create_company/1 with invalid data returns error changeset" do + assert {:error, %Ecto.Changeset{}} = Companies.create_company(@invalid_attrs) + end + + test "update_company/2 with valid data updates the company" do + company = company_fixture() + assert {:ok, %Company{} = company} = Companies.update_company(company, @update_attrs) + assert company.credit_line == 2000 + assert company.name == "some updated name" + assert company.available_credit == 2000 + end + + test "update_company/2 with invalid data returns error changeset" do + company = company_fixture() + assert {:error, %Ecto.Changeset{}} = Companies.update_company(company, @invalid_attrs) + assert company == Companies.get_company!(company.id) + end + + test "delete_company/1 deletes the company" do + company = company_fixture() + assert {:ok, %Company{}} = Companies.delete_company(company) + assert_raise Ecto.NoResultsError, fn -> Companies.get_company!(company.id) end + end + + test "change_company/1 returns a company changeset" do + company = company_fixture() + assert %Ecto.Changeset{} = Companies.change_company(company) + end + end +end diff --git a/elixir/test/homework/merchants_test.exs b/elixir/test/homework/merchants_test.exs index 2d8ce41d..eced7dd9 100644 --- a/elixir/test/homework/merchants_test.exs +++ b/elixir/test/homework/merchants_test.exs @@ -24,7 +24,7 @@ defmodule Homework.MerchantsTest do test "list_merchants/1 returns all merchants" do merchant = merchant_fixture() - assert Merchants.list_merchants([]) == [merchant] + assert merchant in Merchants.list_merchants([]) end test "get_merchant!/1 returns the merchant with given id" do diff --git a/elixir/test/homework/transactions_test.exs b/elixir/test/homework/transactions_test.exs index 03071aff..822373ac 100644 --- a/elixir/test/homework/transactions_test.exs +++ b/elixir/test/homework/transactions_test.exs @@ -5,11 +5,24 @@ defmodule Homework.TransactionsTest do alias Homework.Merchants alias Homework.Transactions alias Homework.Users + alias Homework.Companies describe "transactions" do alias Homework.Transactions.Transaction setup do + {:ok, company1} = + Companies.create_company(%{ + name: "some name", credit_line: 42, available_credit: 42 + }) + + {:ok, company2} = + Companies.create_company(%{ + name: "some updated name", + credit_line: 43, + available_credit: 43 + }) + {:ok, merchant1} = Merchants.create_merchant(%{description: "some description", name: "some name"}) @@ -23,23 +36,27 @@ defmodule Homework.TransactionsTest do Users.create_user(%{ dob: "some dob", first_name: "some first_name", - last_name: "some last_name" + last_name: "some last_name", + company_id: company1.id }) {:ok, user2} = Users.create_user(%{ dob: "some updated dob", first_name: "some updated first_name", - last_name: "some updated last_name" + last_name: "some updated last_name", + company_id: company2.id }) + valid_attrs = %{ amount: 42, credit: true, debit: true, description: "some description", merchant_id: merchant1.id, - user_id: user1.id + user_id: user1.id, + company_id: company1.id } update_attrs = %{ @@ -48,7 +65,8 @@ defmodule Homework.TransactionsTest do debit: false, description: "some updated description", merchant_id: merchant2.id, - user_id: user2.id + user_id: user2.id, + company_id: company2.id } invalid_attrs = %{ @@ -57,7 +75,8 @@ defmodule Homework.TransactionsTest do debit: nil, description: nil, merchant_id: nil, - user_id: nil + user_id: nil, + company_id: nil } {:ok, @@ -68,7 +87,9 @@ defmodule Homework.TransactionsTest do merchant1: merchant1, merchant2: merchant2, user1: user1, - user2: user2 + user2: user2, + company1: company1, + company2: company2 }} end @@ -83,7 +104,7 @@ defmodule Homework.TransactionsTest do test "list_transactions/1 returns all transactions", %{valid_attrs: valid_attrs} do transaction = transaction_fixture(valid_attrs) - assert Transactions.list_transactions([]) == [transaction] + assert transaction in Transactions.list_transactions([]) end test "get_transaction!/1 returns the transaction with given id", %{valid_attrs: valid_attrs} do @@ -94,7 +115,8 @@ defmodule Homework.TransactionsTest do test "create_transaction/1 with valid data creates a transaction", %{ valid_attrs: valid_attrs, merchant1: merchant1, - user1: user1 + user1: user1, + company1: company1 } do assert {:ok, %Transaction{} = transaction} = Transactions.create_transaction(valid_attrs) assert transaction.amount == 42 @@ -103,6 +125,7 @@ defmodule Homework.TransactionsTest do assert transaction.description == "some description" assert transaction.merchant_id == merchant1.id assert transaction.user_id == user1.id + assert transaction.company_id == company1.id end test "create_transaction/1 with invalid data returns error changeset", %{ @@ -115,7 +138,8 @@ defmodule Homework.TransactionsTest do valid_attrs: valid_attrs, update_attrs: update_attrs, merchant2: merchant2, - user2: user2 + user2: user2, + company2: company2 } do transaction = transaction_fixture(valid_attrs) @@ -128,6 +152,7 @@ defmodule Homework.TransactionsTest do assert transaction.description == "some updated description" assert transaction.merchant_id == merchant2.id assert transaction.user_id == user2.id + assert transaction.company_id == company2.id end test "update_transaction/2 with invalid data returns error changeset", %{ @@ -142,7 +167,9 @@ defmodule Homework.TransactionsTest do assert transaction == Transactions.get_transaction!(transaction.id) end - test "delete_transaction/1 deletes the transaction", %{valid_attrs: valid_attrs} do + test "delete_transaction/1 deletes the transaction", %{ + valid_attrs: valid_attrs + } do transaction = transaction_fixture(valid_attrs) assert {:ok, %Transaction{}} = Transactions.delete_transaction(transaction) assert_raise Ecto.NoResultsError, fn -> Transactions.get_transaction!(transaction.id) end diff --git a/elixir/test/homework/users_test.exs b/elixir/test/homework/users_test.exs index e1ae65c2..28b602ad 100644 --- a/elixir/test/homework/users_test.exs +++ b/elixir/test/homework/users_test.exs @@ -2,70 +2,125 @@ defmodule Homework.UsersTest do use Homework.DataCase alias Homework.Users + alias Homework.Companies describe "users" do alias Homework.Users.User - @valid_attrs %{dob: "some dob", first_name: "some first_name", last_name: "some last_name"} - @update_attrs %{ - dob: "some updated dob", - first_name: "some updated first_name", - last_name: "some updated last_name" - } - @invalid_attrs %{dob: nil, first_name: nil, last_name: nil} + setup do + {:ok, company1} = + Companies.create_company(%{ + name: "some name", credit_line: 42, available_credit: 42 + }) - def user_fixture(attrs \\ %{}) do + {:ok, company2} = + Companies.create_company(%{ + name: "some updated name", + credit_line: 43, + available_credit: 43 + }) + + valid_attrs = %{ + dob: "some dob", + first_name: "some first_name", + last_name: "some last_name", + company_id: company1.id + } + + update_attrs = %{ + dob: "some updated dob", + first_name: "some updated first_name", + last_name: "some updated last_name", + company_id: company2.id + } + + invalid_attrs = %{ + dob: nil, + first_name: nil, + last_name: nil, + company_id: nil + } + + {:ok, + %{ + valid_attrs: valid_attrs, + update_attrs: update_attrs, + invalid_attrs: invalid_attrs, + company1: company1, + company2: company2 + }} + end + + def user_fixture(valid_attrs, attrs \\ %{}) do {:ok, user} = attrs - |> Enum.into(@valid_attrs) + |> Enum.into(valid_attrs) |> Users.create_user() user end - test "list_users/1 returns all users" do - user = user_fixture() - assert Users.list_users([]) == [user] + test "list_users/1 returns all users", %{valid_attrs: valid_attrs} do + user = user_fixture(valid_attrs) + assert user in Users.list_users([]) end - test "get_user!/1 returns the user with given id" do - user = user_fixture() + test "get_user!/1 returns the user with given id", %{valid_attrs: valid_attrs} do + user = user_fixture(valid_attrs) assert Users.get_user!(user.id) == user end - test "create_user/1 with valid data creates a user" do - assert {:ok, %User{} = user} = Users.create_user(@valid_attrs) + test "create_user/1 with valid data creates a user", %{ + valid_attrs: valid_attrs, + company1: company1 + } do + assert {:ok, %User{} = user} = Users.create_user(valid_attrs) assert user.dob == "some dob" assert user.first_name == "some first_name" assert user.last_name == "some last_name" + assert user.company_id == company1.id end - test "create_user/1 with invalid data returns error changeset" do - assert {:error, %Ecto.Changeset{}} = Users.create_user(@invalid_attrs) + test "create_user/1 with invalid data returns error changeset", %{ + invalid_attrs: invalid_attrs + } do + assert {:error, %Ecto.Changeset{}} = Users.create_user(invalid_attrs) end - test "update_user/2 with valid data updates the user" do - user = user_fixture() - assert {:ok, %User{} = user} = Users.update_user(user, @update_attrs) + test "update_user/2 with valid data updates the user", %{ + valid_attrs: valid_attrs, + update_attrs: update_attrs, + company2: company2 + } do + user = user_fixture(valid_attrs) + assert {:ok, %User{} = user} = Users.update_user(user, update_attrs) assert user.dob == "some updated dob" assert user.first_name == "some updated first_name" assert user.last_name == "some updated last_name" + assert user.company_id == company2.id end - test "update_user/2 with invalid data returns error changeset" do - user = user_fixture() - assert {:error, %Ecto.Changeset{}} = Users.update_user(user, @invalid_attrs) + test "update_user/2 with invalid data returns error changeset", %{ + valid_attrs: valid_attrs, + invalid_attrs: invalid_attrs + } do + user = user_fixture(valid_attrs) + assert {:error, %Ecto.Changeset{}} = Users.update_user(user, invalid_attrs) assert user == Users.get_user!(user.id) end - test "delete_user/1 deletes the user" do - user = user_fixture() + test "delete_user/1 deletes the user", %{ + valid_attrs: valid_attrs + } do + user = user_fixture(valid_attrs) assert {:ok, %User{}} = Users.delete_user(user) assert_raise Ecto.NoResultsError, fn -> Users.get_user!(user.id) end end - test "change_user/1 returns a user changeset" do - user = user_fixture() + test "change_user/1 returns a user changeset", %{ + valid_attrs: valid_attrs + } do + user = user_fixture(valid_attrs) assert %Ecto.Changeset{} = Users.change_user(user) end end