Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions lib/ex_linear/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@ defmodule ExLinear.Client do
}
"""

@create_comment_mutation """
mutation CommentCreate($issueId: String!, $body: String!) {
commentCreate(input: {issueId: $issueId, body: $body}) {
success
}
}
"""

@doc """
Low-level GraphQL request. Uses `config` for API key and endpoint.

Expand Down Expand Up @@ -248,6 +256,23 @@ defmodule ExLinear.Client do
end
end

@doc """
Creates a comment on the given issue.
"""
@spec create_comment(Config.t() | keyword(), String.t(), String.t()) :: :ok | {:error, term()}
def create_comment(config, issue_id, body) when is_binary(issue_id) and is_binary(body) do
c = normalize_config(config)

with {:ok, response} <-
graphql(c, @create_comment_mutation, %{issueId: issue_id, body: body}),
true <- get_in(response, ["data", "commentCreate", "success"]) == true do
:ok
else
false -> {:error, :comment_create_failed}
{:error, reason} -> {:error, reason}
end
end

defp normalize_config(opts) when is_list(opts), do: Config.from_opts(opts)
defp normalize_config(%Config{} = c), do: c

Expand Down
39 changes: 39 additions & 0 deletions test/ex_linear/client_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,45 @@ defmodule ExLinear.ClientTest do
end
end

describe "create_comment/3" do
test "succeeds when commentCreate.success is true" do
set_request_fun(fn _c, payload, _headers ->
vars = payload["variables"] || %{}
assert vars[:issueId] == "issue-1"
assert vars[:body] == "hello"
assert payload["query"] =~ "commentCreate"
{:ok, %{status: 200, body: %{"data" => %{"commentCreate" => %{"success" => true}}}}}
end)

assert :ok = Client.create_comment(@base_config, "issue-1", "hello")
end

test "returns comment_create_failed when success is false" do
set_request_fun(fn _c, _payload, _headers ->
{:ok, %{status: 200, body: %{"data" => %{"commentCreate" => %{"success" => false}}}}}
end)

assert {:error, :comment_create_failed} =
Client.create_comment(@base_config, "issue-1", "body")
end

test "propagates transport error" do
set_request_fun(fn _c, _payload, _headers -> {:error, :timeout} end)

assert {:error, {:linear_api_request, :timeout}} =
Client.create_comment(@base_config, "issue-1", "body")
end

test "returns comment_create_failed when response body is unexpected" do
set_request_fun(fn _c, _payload, _headers ->
{:ok, %{status: 200, body: %{"data" => %{}}}}
end)

assert {:error, :comment_create_failed} =
Client.create_comment(@base_config, "issue-1", "body")
end
end

describe "ExLinear.Issue" do
test "label_names returns labels" do
issue = %Issue{id: "1", labels: ["frontend", "infra"]}
Expand Down
Loading