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

feat: update definitions endpoint #112

Merged
merged 2 commits into from Apr 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 1 addition & 3 deletions .travis.yml
Expand Up @@ -28,13 +28,11 @@ jobs:
env:
- MIX_ENV=test

services:
- postgresql

addons:
apt:
packages:
- rabbitmq-server
postgresql: 9.6

matrix:
include:
Expand Down
3 changes: 3 additions & 0 deletions lib/step_flow/controllers/workflow_definition_controller.ex
Expand Up @@ -15,6 +15,9 @@ defmodule StepFlow.WorkflowDefinitionController do
params =
params
|> Map.put("rights", StepFlow.Map.get_by_key_or_atom(user, :rights, []))
|> Map.put("right_action", StepFlow.Map.get_by_key_or_atom(params, :right_action, "action"))
|> Map.put("versions", StepFlow.Map.get_by_key_or_atom(params, :versions, []))
|> Map.put("mode", StepFlow.Map.get_by_key_or_atom(params, :mode, "full"))

workflow_definitions = WorkflowDefinitions.list_workflow_definitions(params)

Expand Down
38 changes: 36 additions & 2 deletions lib/step_flow/view/workflow_definition_view.ex
Expand Up @@ -2,9 +2,16 @@ defmodule StepFlow.WorkflowDefinitionView do
use StepFlow, :view
alias StepFlow.WorkflowDefinitionView

def render("index.json", %{workflow_definitions: %{data: workflow_definitions, total: total}}) do
def render("index.json", %{
workflow_definitions: %{data: workflow_definitions, total: total, mode: mode}
}) do
%{
data: render_many(workflow_definitions, WorkflowDefinitionView, "workflow_definition.json"),
data:
render_many(
workflow_definitions,
WorkflowDefinitionView,
"workflow_definition_#{mode}.json"
),
total: total
}
end
Expand All @@ -20,6 +27,33 @@ defmodule StepFlow.WorkflowDefinitionView do
}
end

def render("workflow_definition_full.json", %{workflow_definition: workflow_definition}) do
%{
schema_version: workflow_definition.schema_version,
id: workflow_definition.id,
identifier: workflow_definition.identifier,
label: workflow_definition.label,
icon: workflow_definition.icon,
version_major: workflow_definition.version_major,
version_minor: workflow_definition.version_minor,
version_micro: workflow_definition.version_micro,
tags: workflow_definition.tags,
start_parameters: workflow_definition.start_parameters,
parameters: workflow_definition.parameters
}
end

def render("workflow_definition_simple.json", %{workflow_definition: workflow_definition}) do
%{
id: workflow_definition.id,
identifier: workflow_definition.identifier,
label: workflow_definition.label,
version_major: workflow_definition.version_major,
version_minor: workflow_definition.version_minor,
version_micro: workflow_definition.version_micro
}
end

def render("workflow_definition.json", %{workflow_definition: workflow_definition}) do
%{
schema_version: workflow_definition.schema_version,
Expand Down
132 changes: 116 additions & 16 deletions lib/step_flow/workflow_definitions/workflow_definitions.ex
Expand Up @@ -20,21 +20,16 @@ defmodule StepFlow.WorkflowDefinitions do
Map.get(params, "size", 10)
|> StepFlow.Integer.force()

mode = Map.get(params, "mode", "full")

offset = page * size

query =
case Map.get(params, "rights") do
nil ->
from(workflow_definition in WorkflowDefinition)

user_rights ->
from(
workflow_definition in WorkflowDefinition,
join: rights in assoc(workflow_definition, :rights),
where: rights.action == "view",
where: fragment("?::varchar[] && ?::varchar[]", rights.groups, ^user_rights)
)
end
from(workflow_definition in WorkflowDefinition)
|> check_rights(Map.get(params, "right_action"), Map.get(params, "rights"))
|> filter_by_label_or_identifier(Map.get(params, "search"))
|> filter_by_versions(Map.get(params, "versions"))
|> select_by_mode(mode)

total_query = from(item in subquery(query), select: count(item.id))

Expand All @@ -45,21 +40,126 @@ defmodule StepFlow.WorkflowDefinitions do
query =
from(
workflow_definition in subquery(query),
order_by: [desc: :inserted_at],
offset: ^offset,
limit: ^size
order_by: [
desc: workflow_definition.version_major,
desc: workflow_definition.version_minor,
desc: workflow_definition.version_micro
]
)
|> paginate(offset, size)

workflow_definitions = Repo.all(query)

%{
data: workflow_definitions,
total: total,
page: page,
size: size
size: size,
mode: mode
}
end

defp paginate(query, offset, size) do
case size do
-1 ->
query

_ ->
from(
workflow_definition in subquery(query),
offset: ^offset,
limit: ^size
)
end
end

defp check_rights(query, right_action, user_rights) do
case {right_action, user_rights} do
{nil, _} ->
query

{_, nil} ->
query

{right_action, user_rights} ->
from(
workflow_definition in subquery(query),
join: rights in assoc(workflow_definition, :rights),
where: rights.action == ^right_action,
where: fragment("?::varchar[] && ?::varchar[]", rights.groups, ^user_rights)
)
end
end

def filter_by_versions(query, versions) do
case versions do
["latest"] ->
from(
workflow_definition in subquery(query),
order_by: [
desc: workflow_definition.version_major,
desc: workflow_definition.version_minor,
desc: workflow_definition.version_micro
],
distinct: :identifier
)

versions when is_list(versions) and length(versions) != 0 ->
from(
workflow_definition in subquery(query),
where:
fragment(
"concat(?, '.', ?, '.', ?) = ANY(?)",
workflow_definition.version_major,
workflow_definition.version_minor,
workflow_definition.version_micro,
^versions
)
)

_ ->
query
end
end

defp filter_by_label_or_identifier(query, search) do
case search do
nil ->
query

search ->
from(
workflow_definition in subquery(query),
where:
ilike(workflow_definition.label, ^search) or
ilike(workflow_definition.identifier, ^search)
)
end
end

defp select_by_mode(query, mode) do
case mode do
"simple" ->
from(
workflow_definition in subquery(query),
select: %{
id: workflow_definition.id,
identifier: workflow_definition.identifier,
label: workflow_definition.label,
version_major: workflow_definition.version_major,
version_minor: workflow_definition.version_minor,
version_micro: workflow_definition.version_micro
}
)

"full" ->
query

_ ->
query
end
end

@doc """
Gets a single WorkflowDefinition.

Expand Down
2 changes: 1 addition & 1 deletion test/api/workflow_definitions_test.exs
Expand Up @@ -30,7 +30,7 @@ defmodule StepFlow.Api.WorkflowDefinitionsTest do
@tag capture_log: true
test "GET /definitions with authorized user" do
{status, _headers, body} =
conn(:get, "/definitions")
conn(:get, "/definitions", %{right_action: "view"})
|> assign(:current_user, %{rights: ["user_view"]})
|> Router.call(@opts)
|> sent_resp
Expand Down
2 changes: 1 addition & 1 deletion test/definitions/simple_workflow_v0.1.0.json
@@ -1,7 +1,7 @@
{
"schema_version": "1.8",
"identifier": "simple_workflow",
"label": "Transcription",
"label": "New transcription",
"icon": "subtitles",
"version_major": 0,
"version_minor": 1,
Expand Down
103 changes: 100 additions & 3 deletions test/workflow_definitions/workflow_definitions_test.exs
Expand Up @@ -33,13 +33,20 @@ defmodule StepFlow.WorkflowDefinitionsTest do
size: 10,
total: 1
} =
WorkflowDefinitions.list_workflow_definitions(%{"rights" => ["administrator_view"]})
WorkflowDefinitions.list_workflow_definitions(%{
"right_action" => "view",
"rights" => ["administrator_view"]
})

assert 0 == workflow.version_major
assert 0 == workflow.version_minor
assert 1 == workflow.version_micro

result = WorkflowDefinitions.list_workflow_definitions(%{"rights" => ["user_view"]})
result =
WorkflowDefinitions.list_workflow_definitions(%{
"right_action" => "view",
"rights" => ["user_view"]
})

assert %{
data: [workflow],
Expand All @@ -54,7 +61,8 @@ defmodule StepFlow.WorkflowDefinitionsTest do
end

test "list_workflow_definitions/0 returns workflow_definitions with group unauthorized" do
result = WorkflowDefinitions.list_workflow_definitions(%{"rights" => []})
result =
WorkflowDefinitions.list_workflow_definitions(%{"right_action" => "view", "rights" => []})

assert %{
data: [],
Expand All @@ -63,5 +71,94 @@ defmodule StepFlow.WorkflowDefinitionsTest do
total: 0
} = result
end

test "list_workflow_definitions/0 returns workflow_definitions with version 0.0.1" do
result =
WorkflowDefinitions.list_workflow_definitions(%{
"versions" => ["0.0.1"]
})

assert %{
data: [workflow],
page: 0,
size: 10,
total: 1
} = result

assert 0 == workflow.version_major
assert 0 == workflow.version_minor
assert 1 == workflow.version_micro
end

test "list_workflow_definitions/0 returns workflow_definitions with latest version" do
result =
WorkflowDefinitions.list_workflow_definitions(%{
"versions" => ["latest"]
})

assert %{
data: [workflow],
page: 0,
size: 10,
total: 1
} = result

assert 0 == workflow.version_major
assert 1 == workflow.version_minor
assert 0 == workflow.version_micro
end

test "list_workflow_definitions/0 returns workflow_definitions with label matching 'Transcript%'" do
result =
WorkflowDefinitions.list_workflow_definitions(%{
"search" => "Transcript%"
})

assert %{
data: [_],
page: 0,
size: 10,
total: 1
} = result
end

test "list_workflow_definitions/0 returns workflow_definitions with simple mode" do
result =
WorkflowDefinitions.list_workflow_definitions(%{
"mode" => "simple"
})

assert %{
data: [workfklow | _],
page: 0,
size: 10,
total: 2
} = result

assert Map.has_key?(workfklow, :identifier)
assert not Map.has_key?(workfklow, :steps)
end

test "list_workflow_definitions/0 returns workflow_definitions with complex query" do
result =
WorkflowDefinitions.list_workflow_definitions(%{
"mode" => "simple",
"search" => "Transcript%",
"versions" => ["0.0.1"]
})

assert %{
data: [workflow],
page: 0,
size: 10,
total: 1
} = result

assert not Map.has_key?(workflow, :steps)
assert String.starts_with?(workflow.label, "Transcript")
assert 0 == workflow.version_major
assert 0 == workflow.version_minor
assert 1 == workflow.version_micro
end
end
end