Closed NARKOZ closed 7 years ago
Right now, things are a bit weird as there was a recent, breaking change with how controllers operate. The old way (pre 0.4.0-dev) was more custom. The new way relies on the Plug specification. v0.4.0 should be published to Hex in the next few days as I'm currently working on a few bugs that still remain from the recent changes. Considering that, I'll cover testing with the new controllers. (I'm sure the older controllers are testable, but I'm not sure the best of accomplishing that. Holding off just a little bit for the newest version will definitely be worth it.)
Given this controller:
defmodule MyController do
use Sugar.Controller
@doc false
def index(conn, []) do
# Somehow get our content
# Render our "mycontroller/index.html.eex" view
render conn
end
it can be tested as such:
## This is mostly from the Plug documentation over testing plugs.
## It's slightly modified for this case.
defmodule MyControllerTest do
use ExUnit.Case, async: true
use Plug.Test
test "returns hello world" do
# Create a test connection
conn = conn(:get, "/")
opts = MyController.init [ action: :index, args: %{} ]
# Invoke the controller
conn = MyController.call(conn, opts)
# Assert the response and status
assert conn.state == :sent
assert conn.status == 200
assert conn.resp_body == "Hello world"
end
end
opts
should contain an :action
key that contains the desired function for the test and an :args
key with a map of desired inbound arguments (like from URL parameters) for the test.
The documentation for Sugar is pretty out of date, and I apologise for that. I've got plans to update it shortly with all of the newest changes, so let me know if anything is unclear.
@NARKOZ I pushed v0.4.0 earlier, which contains the new style of controllers based on the Plug spec. Let me know if you run into any issues.
@slogsdon Thank you. I'm getting this error after update:
** (FunctionClauseError) no function clause matching in Keyword.put_new/3
(elixir) lib/keyword.ex:320: Keyword.put_new(nil, :ref, Router.HTTPS)
lib/plug/adapters/cowboy.ex:35: Plug.Adapters.Cowboy.args/4
lib/plug/adapters/cowboy.ex:120: Plug.Adapters.Cowboy.run/4
(myapp) lib/myapp/router.ex:1: Router.run/1
lib/mix/tasks/server.ex:27: Mix.Tasks.Server.run/1
(mix) lib/mix/cli.ex:55: Mix.CLI.run_task/2
can't start mix server.
Also how to set custom error pages (404 and 500) and how should I serve static assets?
Templates don't auto update, you need to stop and start server to see changes.
@NARKOZ The FunctionClauseError
you're receiving is from your application not being configured for HTTPS. Take a look at the simple example app for the proper way to accomplish that.
For capturing 500 errors, check out Plug.ErrorHandler
. The code for that should be placed in your router for application-level handling or in a controller for controller-level handling. Currently, the 404 handler isn't configurable (yet). We have something injected into the router by default so that your application doesn't fall on its face when it receives a request to a location it doesn't know about.
Static assets can be served with Plug.Static
.
Thanks for the heads up about the templates not autoupdating. The HotCodeReload
plug and the Templates
library are still in their infancy, so we'll work on getting those up to speed so that feature will work.
@slogsdon Thank you. After config update I'm getting this error:
** (ArgumentError) could not start Cowboy adapter, to use relative certificate with https, the :otp_app option needs to be given to the adapter
lib/plug/adapters/cowboy.ex:204: Plug.Adapters.Cowboy.fail/1
lib/plug/adapters/cowboy.ex:167: Plug.Adapters.Cowboy.normalize_ssl_file/2
(elixir) lib/enum.ex:1261: Enum."-reduce/3-lists^foldl/2-0-"/3
lib/plug/adapters/cowboy.ex:135: Plug.Adapters.Cowboy.normalize_options/2
lib/plug/adapters/cowboy.ex:37: Plug.Adapters.Cowboy.args/4
lib/plug/adapters/cowboy.ex:120: Plug.Adapters.Cowboy.run/4
(myapp) lib/myapp/router.ex:1: Router.run/1
lib/mix/tasks/server.ex:27: Mix.Tasks.Server.run/1
if I change the line to
adapter.http __MODULE__, [], opts[:http]
it works.
My config:
use Mix.Config
config :sugar,
router: Router
config :sugar, Router,
https_only: false
I don't use SSL.
@NARKOZ Apologies for the delay. The router was updated at some point to allow for HTTPS to be optional by setting the router config option for it to false
. Example:
use MixConfig
config :sugar,
router: Router
config :sugar, Router,
https: false
Closing this, but feel free to re-open.
How can I write tests for controllers and test requests?