Merge branch 'feature/list-users' into 'master'
Add ability to list users See merge request framasoft/mobilizon!83
This commit is contained in:
commit
bacd1bfb02
|
@ -266,8 +266,21 @@ defmodule Mobilizon.Actors do
|
||||||
[%Mobilizon.Actors.User{}]
|
[%Mobilizon.Actors.User{}]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def list_users do
|
def list_users(page \\ nil, limit \\ nil, sort \\ nil, direction \\ nil) do
|
||||||
Repo.all(User)
|
Repo.all(
|
||||||
|
User
|
||||||
|
|> paginate(page, limit)
|
||||||
|
|> sort(sort, direction)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def count_users() do
|
||||||
|
Repo.one(
|
||||||
|
from(
|
||||||
|
u in User,
|
||||||
|
select: count(u.id)
|
||||||
|
)
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def insert_or_update_actor(data, preload \\ false) do
|
def insert_or_update_actor(data, preload \\ false) do
|
||||||
|
@ -300,15 +313,6 @@ defmodule Mobilizon.Actors do
|
||||||
# update_and_set_cache(cs)
|
# update_and_set_cache(cs)
|
||||||
# end
|
# end
|
||||||
|
|
||||||
def count_users() do
|
|
||||||
Repo.one(
|
|
||||||
from(
|
|
||||||
u in User,
|
|
||||||
select: count(u.id)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Gets a single user.
|
Gets a single user.
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,16 @@ defmodule Mobilizon.Ecto do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Add sort to the query
|
||||||
|
"""
|
||||||
|
def sort(query, sort, direction) do
|
||||||
|
from(
|
||||||
|
query,
|
||||||
|
order_by: [{^direction, ^sort}]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
def increment_slug(slug) do
|
def increment_slug(slug) do
|
||||||
case List.pop_at(String.split(slug, "-"), -1) do
|
case List.pop_at(String.split(slug, "-"), -1) do
|
||||||
{nil, _} ->
|
{nil, _} ->
|
||||||
|
|
|
@ -24,6 +24,20 @@ defmodule MobilizonWeb.Resolvers.User do
|
||||||
{:error, "You need to be logged-in to view current user"}
|
{:error, "You need to be logged-in to view current user"}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
List instance users
|
||||||
|
"""
|
||||||
|
def list_and_count_users(
|
||||||
|
_parent,
|
||||||
|
%{page: page, limit: limit, sort: sort, direction: direction},
|
||||||
|
_resolution
|
||||||
|
) do
|
||||||
|
total = Task.async(&Actors.count_users/0)
|
||||||
|
elements = Task.async(fn -> Actors.list_users(page, limit, sort, direction) end)
|
||||||
|
|
||||||
|
{:ok, %{total: Task.await(total), elements: Task.await(elements)}}
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Login an user. Returns a token and the user
|
Login an user. Returns a token and the user
|
||||||
"""
|
"""
|
||||||
|
|
12
lib/mobilizon_web/schema/sort.ex
Normal file
12
lib/mobilizon_web/schema/sort.ex
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
defmodule MobilizonWeb.Schema.SortType do
|
||||||
|
@moduledoc """
|
||||||
|
Allows sorting a collection of elements
|
||||||
|
"""
|
||||||
|
use Absinthe.Schema.Notation
|
||||||
|
|
||||||
|
@desc "Available sort directions"
|
||||||
|
enum :sort_direction do
|
||||||
|
value(:asc)
|
||||||
|
value(:desc)
|
||||||
|
end
|
||||||
|
end
|
|
@ -6,6 +6,8 @@ defmodule MobilizonWeb.Schema.UserType do
|
||||||
alias MobilizonWeb.Resolvers.User
|
alias MobilizonWeb.Resolvers.User
|
||||||
import MobilizonWeb.Schema.Utils
|
import MobilizonWeb.Schema.Utils
|
||||||
|
|
||||||
|
import_types(MobilizonWeb.Schema.SortType)
|
||||||
|
|
||||||
@desc "A local user of Mobilizon"
|
@desc "A local user of Mobilizon"
|
||||||
object :user do
|
object :user do
|
||||||
field(:id, non_null(:id), description: "The user's ID")
|
field(:id, non_null(:id), description: "The user's ID")
|
||||||
|
@ -36,6 +38,17 @@ defmodule MobilizonWeb.Schema.UserType do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@desc "Users list"
|
||||||
|
object :users do
|
||||||
|
field(:total, non_null(:integer), description: "Total elements")
|
||||||
|
field(:elements, non_null(list_of(:user)), description: "User elements")
|
||||||
|
end
|
||||||
|
|
||||||
|
@desc "The list of possible options for the event's status"
|
||||||
|
enum :sortable_user_field do
|
||||||
|
value(:id)
|
||||||
|
end
|
||||||
|
|
||||||
object :user_queries do
|
object :user_queries do
|
||||||
@desc "Get an user"
|
@desc "Get an user"
|
||||||
field :user, :user do
|
field :user, :user do
|
||||||
|
@ -47,6 +60,17 @@ defmodule MobilizonWeb.Schema.UserType do
|
||||||
field :logged_user, :user do
|
field :logged_user, :user do
|
||||||
resolve(&User.get_current_user/3)
|
resolve(&User.get_current_user/3)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@desc "List instance users"
|
||||||
|
field :users, :users do
|
||||||
|
arg(:page, :integer, default_value: 1)
|
||||||
|
arg(:limit, :integer, default_value: 10)
|
||||||
|
|
||||||
|
arg(:sort, :sortable_user_field, default_value: :id)
|
||||||
|
arg(:direction, :sort_direction, default_value: :desc)
|
||||||
|
|
||||||
|
resolve(&User.list_and_count_users/3)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
object :user_mutations do
|
object :user_mutations do
|
||||||
|
|
|
@ -274,7 +274,7 @@ defmodule Mobilizon.ActorsTest do
|
||||||
|
|
||||||
test "list_users/0 returns all users" do
|
test "list_users/0 returns all users" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
users = Actors.list_users()
|
users = Actors.list_users(nil, nil, :id, :desc)
|
||||||
assert [user.id] == users |> Enum.map(& &1.id)
|
assert [user.id] == users |> Enum.map(& &1.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,114 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "Resolver: List users" do
|
||||||
|
test "list_users/3 returns a list of users", context do
|
||||||
|
insert(:user, email: "riri@example.com")
|
||||||
|
insert(:user, email: "fifi@example.com")
|
||||||
|
insert(:user, email: "loulou@example.com")
|
||||||
|
|
||||||
|
query = """
|
||||||
|
{
|
||||||
|
users {
|
||||||
|
total,
|
||||||
|
elements {
|
||||||
|
email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
res =
|
||||||
|
context.conn
|
||||||
|
|> get("/api", AbsintheHelpers.query_skeleton(query, "user"))
|
||||||
|
|
||||||
|
assert json_response(res, 200)["errors"] == nil
|
||||||
|
assert json_response(res, 200)["data"]["users"]["total"] == 3
|
||||||
|
assert json_response(res, 200)["data"]["users"]["elements"] |> length == 3
|
||||||
|
|
||||||
|
assert json_response(res, 200)["data"]["users"]["elements"]
|
||||||
|
|> Enum.map(& &1["email"]) == [
|
||||||
|
"loulou@example.com",
|
||||||
|
"fifi@example.com",
|
||||||
|
"riri@example.com"
|
||||||
|
]
|
||||||
|
|
||||||
|
query = """
|
||||||
|
{
|
||||||
|
users(page: 2, limit: 1) {
|
||||||
|
total,
|
||||||
|
elements {
|
||||||
|
email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
res =
|
||||||
|
context.conn
|
||||||
|
|> get("/api", AbsintheHelpers.query_skeleton(query, "user"))
|
||||||
|
|
||||||
|
assert json_response(res, 200)["errors"] == nil
|
||||||
|
assert json_response(res, 200)["data"]["users"]["total"] == 3
|
||||||
|
assert json_response(res, 200)["data"]["users"]["elements"] |> length == 1
|
||||||
|
|
||||||
|
assert json_response(res, 200)["data"]["users"]["elements"] |> Enum.map(& &1["email"]) == [
|
||||||
|
"fifi@example.com"
|
||||||
|
]
|
||||||
|
|
||||||
|
query = """
|
||||||
|
{
|
||||||
|
users(page: 3, limit: 1, sort: ID, direction: DESC) {
|
||||||
|
total,
|
||||||
|
elements {
|
||||||
|
email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
res =
|
||||||
|
context.conn
|
||||||
|
|> get("/api", AbsintheHelpers.query_skeleton(query, "user"))
|
||||||
|
|
||||||
|
assert json_response(res, 200)["errors"] == nil
|
||||||
|
assert json_response(res, 200)["data"]["users"]["total"] == 3
|
||||||
|
assert json_response(res, 200)["data"]["users"]["elements"] |> length == 1
|
||||||
|
|
||||||
|
assert json_response(res, 200)["data"]["users"]["elements"] |> Enum.map(& &1["email"]) == [
|
||||||
|
"riri@example.com"
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
test "get_current_user/3 returns the current logged-in user", context do
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
query = """
|
||||||
|
{
|
||||||
|
loggedUser {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
res =
|
||||||
|
context.conn
|
||||||
|
|> get("/api", AbsintheHelpers.query_skeleton(query, "logged_user"))
|
||||||
|
|
||||||
|
assert json_response(res, 200)["data"]["loggedUser"] == nil
|
||||||
|
|
||||||
|
assert hd(json_response(res, 200)["errors"])["message"] ==
|
||||||
|
"You need to be logged-in to view current user"
|
||||||
|
|
||||||
|
res =
|
||||||
|
context.conn
|
||||||
|
|> auth_conn(user)
|
||||||
|
|> get("/api", AbsintheHelpers.query_skeleton(query, "logged_user"))
|
||||||
|
|
||||||
|
assert json_response(res, 200)["data"]["loggedUser"]["id"] == to_string(user.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "Resolver: Create an user & actor" do
|
describe "Resolver: Create an user & actor" do
|
||||||
@user_creation %{
|
@user_creation %{
|
||||||
email: "test@demo.tld",
|
email: "test@demo.tld",
|
||||||
|
|
Loading…
Reference in a new issue