diff --git a/test/chronoscope/nts/certificate_test.exs b/test/chronoscope/nts/certificate_test.exs index 2d5f4da..53cd835 100644 --- a/test/chronoscope/nts/certificate_test.exs +++ b/test/chronoscope/nts/certificate_test.exs @@ -8,36 +8,40 @@ defmodule Chronoscope.NTS.CertificateTest do setup :verify_on_exit! - test "parses the expiration date of a certificate" do - {:ok, expiration, _} = - :secp256r1 - |> X509.PrivateKey.new_ec() - |> X509.Certificate.self_signed("/C=US/ST=CA/L=San Francisco/O=Acme/CN=Test", validity: 12) - |> X509.Certificate.to_der() - |> expiration_date() - |> DateTime.from_iso8601() + describe "Chronoscope.NTS.Certificate.expiration_date()" do + test "parses the expiration date of a certificate" do + {:ok, expiration, _} = + :secp256r1 + |> X509.PrivateKey.new_ec() + |> X509.Certificate.self_signed("/C=US/ST=CA/L=San Francisco/O=Acme/CN=Test", validity: 12) + |> X509.Certificate.to_der() + |> expiration_date() + |> DateTime.from_iso8601() - assert DateTime.diff(expiration, DateTime.utc_now(), :day) == 12 + assert DateTime.diff(expiration, DateTime.utc_now(), :day) == 12 + end end - test "converts certificate datetime to iso8601" do - DateTimeMock - |> expect(:utc_now, fn -> ~U[2024-03-31 01:23:45Z] end) + describe "Chronoscope.NTS.Certificate.cert_time_to_iso8601()" do + test "converts certificate datetime to iso8601" do + DateTimeMock + |> expect(:utc_now, fn -> ~U[2024-03-31 01:23:45Z] end) - assert cert_time_to_iso8601("240326110000Z") == "2024-03-26T11:00:00Z" - end + assert cert_time_to_iso8601("240326110000Z") == "2024-03-26T11:00:00Z" + end - test "handles century rollover" do - DateTimeMock - |> expect(:utc_now, fn -> ~U[2024-03-31 01:23:45Z] end) + test "handles century rollover" do + DateTimeMock + |> expect(:utc_now, fn -> ~U[2024-03-31 01:23:45Z] end) - assert cert_time_to_iso8601("010326110000Z") == "2101-03-26T11:00:00Z" - end + assert cert_time_to_iso8601("010326110000Z") == "2101-03-26T11:00:00Z" + end - test "handles millenium rollover" do - DateTimeMock - |> expect(:utc_now, fn -> ~U[2999-03-31 01:23:45Z] end) + test "handles millenium rollover" do + DateTimeMock + |> expect(:utc_now, fn -> ~U[2999-03-31 01:23:45Z] end) - assert cert_time_to_iso8601("010326110000Z") == "3001-03-26T11:00:00Z" + assert cert_time_to_iso8601("010326110000Z") == "3001-03-26T11:00:00Z" + end end end diff --git a/test/chronoscope/nts/key_establishment_request_test.exs b/test/chronoscope/nts/key_establishment_request_test.exs index 39fa524..b75769d 100644 --- a/test/chronoscope/nts/key_establishment_request_test.exs +++ b/test/chronoscope/nts/key_establishment_request_test.exs @@ -3,8 +3,10 @@ defmodule Chronoscope.NTS.KeyEstablishmentRequestTest do import Chronoscope.NTS.KeyEstablishmentRequest - test "builds request" do - assert create() == - <<0x80, 0x01, 0x00, 0x02, 0x00, 0x00, 0x80, 0x04, 0x00, 0x04, 0x00, 0x1E, 0x00, 0x0F, 0x80, 0x00, 0x00, 0x00>> + describe "Chronoscope.NTS.KeyEstablishmentRequest.create()" do + test "builds request" do + assert create() == + <<0x80, 0x01, 0x00, 0x02, 0x00, 0x00, 0x80, 0x04, 0x00, 0x04, 0x00, 0x1E, 0x00, 0x0F, 0x80, 0x00, 0x00, 0x00>> + end end end diff --git a/test/chronoscope/nts/key_establishment_response_test.exs b/test/chronoscope/nts/key_establishment_response_test.exs index 0421629..e52e8f6 100644 --- a/test/chronoscope/nts/key_establishment_response_test.exs +++ b/test/chronoscope/nts/key_establishment_response_test.exs @@ -3,142 +3,144 @@ defmodule Chronoscope.NTS.KeyEstablishmentResponseTest do import Chronoscope.NTS.KeyEstablishmentResponse - test "handles empty response" do - assert parse([]) == {:ok, %{}} - end + describe "Chronoscope.NTS.KeyEstablishmentResponse.parse()" do + test "handles empty response" do + assert parse([]) == {:ok, %{}} + end - test "ignores unkown record" do - assert parse([0x80, 0x21, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03]) == {:ok, %{}} - end + test "ignores unkown record" do + assert parse([0x80, 0x21, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03]) == {:ok, %{}} + end - test "handles end of message record" do - assert parse([0x80, 0x00, 0x00, 0x00]) == {:ok, %{}} - end + test "handles end of message record" do + assert parse([0x80, 0x00, 0x00, 0x00]) == {:ok, %{}} + end - test "handles next protocol negotiation record" do - assert parse([0x80, 0x01, 0x00, 0x02, 0x00, 0x00]) == {:ok, %{next_protocols: ["NTPv4"]}} - end + test "handles next protocol negotiation record" do + assert parse([0x80, 0x01, 0x00, 0x02, 0x00, 0x00]) == {:ok, %{next_protocols: ["NTPv4"]}} + end - test "does not handle next protocol negotiation record without critical bit" do - assert parse([0x00, 0x01, 0x00, 0x02, 0x00, 0x00]) == {:ok, %{}} - end + test "does not handle next protocol negotiation record without critical bit" do + assert parse([0x00, 0x01, 0x00, 0x02, 0x00, 0x00]) == {:ok, %{}} + end - test "handles empty next protocols" do - assert parse([0x80, 0x01, 0x00, 0x00]) == {:ok, %{next_protocols: []}} - end + test "handles empty next protocols" do + assert parse([0x80, 0x01, 0x00, 0x00]) == {:ok, %{next_protocols: []}} + end - test "handles multiple next protocols" do - assert parse([0x80, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00]) == - {:ok, %{next_protocols: ["NTPv4", "UNASSIGNED", "NTPv4"]}} - end + test "handles multiple next protocols" do + assert parse([0x80, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00]) == + {:ok, %{next_protocols: ["NTPv4", "UNASSIGNED", "NTPv4"]}} + end - test "handles aead algorithm negotiation record" do - assert parse([0x80, 0x04, 0x00, 0x02, 0x00, 0x0F]) == {:ok, %{aead_algorithms: ["AEAD_AES_SIV_CMAC_256"]}} - end + test "handles aead algorithm negotiation record" do + assert parse([0x80, 0x04, 0x00, 0x02, 0x00, 0x0F]) == {:ok, %{aead_algorithms: ["AEAD_AES_SIV_CMAC_256"]}} + end - test "handles aead algorithm negotiation record without critical bit" do - assert parse([0x00, 0x04, 0x00, 0x02, 0x00, 0x1E]) == {:ok, %{aead_algorithms: ["AEAD_AES_128_GCM_SIV"]}} - end + test "handles aead algorithm negotiation record without critical bit" do + assert parse([0x00, 0x04, 0x00, 0x02, 0x00, 0x1E]) == {:ok, %{aead_algorithms: ["AEAD_AES_128_GCM_SIV"]}} + end - test "handles empty aead algorithms" do - assert parse([0x80, 0x04, 0x00, 0x00]) == {:ok, %{aead_algorithms: []}} - end + test "handles empty aead algorithms" do + assert parse([0x80, 0x04, 0x00, 0x00]) == {:ok, %{aead_algorithms: []}} + end - test "handles multiple aead algorithms" do - assert parse([0x80, 0x04, 0x00, 0x06, 0x00, 0x1E, 0x00, 0x01, 0x00, 0x0F]) == - {:ok, %{aead_algorithms: ["AEAD_AES_SIV_CMAC_256", "UNKNOWN", "AEAD_AES_128_GCM_SIV"]}} - end + test "handles multiple aead algorithms" do + assert parse([0x80, 0x04, 0x00, 0x06, 0x00, 0x1E, 0x00, 0x01, 0x00, 0x0F]) == + {:ok, %{aead_algorithms: ["AEAD_AES_SIV_CMAC_256", "UNKNOWN", "AEAD_AES_128_GCM_SIV"]}} + end - test "handles error record" do - assert parse([0x80, 0x02, 0x00, 0x02, 0x00, 0x01]) == {:ok, %{error: "Bad Request"}} - end + test "handles error record" do + assert parse([0x80, 0x02, 0x00, 0x02, 0x00, 0x01]) == {:ok, %{error: "Bad Request"}} + end - test "handles unknown error record" do - assert parse([0x80, 0x02, 0x00, 0x02, 0x00, 0x99]) == {:ok, %{error: "153"}} - end + test "handles unknown error record" do + assert parse([0x80, 0x02, 0x00, 0x02, 0x00, 0x99]) == {:ok, %{error: "153"}} + end - test "does not handle error record without critical bit" do - assert parse([0x00, 0x02, 0x00, 0x02, 0x00, 0x01]) == {:ok, %{}} - end + test "does not handle error record without critical bit" do + assert parse([0x00, 0x02, 0x00, 0x02, 0x00, 0x01]) == {:ok, %{}} + end - test "handles warning record" do - assert parse([0x80, 0x03, 0x00, 0x02, 0x00, 0x01]) == {:ok, %{warning: "1"}} - end + test "handles warning record" do + assert parse([0x80, 0x03, 0x00, 0x02, 0x00, 0x01]) == {:ok, %{warning: "1"}} + end - test "does not handle warning record without critical bit" do - assert parse([0x00, 0x03, 0x00, 0x02, 0x00, 0x01]) == {:ok, %{}} - end + test "does not handle warning record without critical bit" do + assert parse([0x00, 0x03, 0x00, 0x02, 0x00, 0x01]) == {:ok, %{}} + end - test "handles server record" do - assert parse([0x80, 0x06, 0x00, 0x09, ?1, ?2, ?7, ?., ?0, ?., ?0, ?., ?1]) == {:ok, %{server: "127.0.0.1"}} - end + test "handles server record" do + assert parse([0x80, 0x06, 0x00, 0x09, ?1, ?2, ?7, ?., ?0, ?., ?0, ?., ?1]) == {:ok, %{server: "127.0.0.1"}} + end - test "handles server record without critical bit" do - assert parse([0x00, 0x06, 0x00, 0x09, ?1, ?2, ?7, ?., ?0, ?., ?0, ?., ?1]) == {:ok, %{server: "127.0.0.1"}} - end + test "handles server record without critical bit" do + assert parse([0x00, 0x06, 0x00, 0x09, ?1, ?2, ?7, ?., ?0, ?., ?0, ?., ?1]) == {:ok, %{server: "127.0.0.1"}} + end - test "handles port record" do - assert parse([0x80, 0x07, 0x00, 0x02, 0x04, 0xCE]) == {:ok, %{port: 1230}} - end + test "handles port record" do + assert parse([0x80, 0x07, 0x00, 0x02, 0x04, 0xCE]) == {:ok, %{port: 1230}} + end - test "handles port record without critical bit" do - assert parse([0x00, 0x07, 0x00, 0x02, 0x04, 0xCE]) == {:ok, %{port: 1230}} - end + test "handles port record without critical bit" do + assert parse([0x00, 0x07, 0x00, 0x02, 0x04, 0xCE]) == {:ok, %{port: 1230}} + end - test "handles cookie record" do - assert parse([0x80, 0x05, 0x00, 0x0E, ?c, ?h, ?o, ?c, ?o, ?l, ?a, ?t, ?e, ?_, ?c, ?h, ?i, ?p]) == - {:ok, %{cookies: [~c"chocolate_chip"], cookie_length: 14}} - end + test "handles cookie record" do + assert parse([0x80, 0x05, 0x00, 0x0E, ?c, ?h, ?o, ?c, ?o, ?l, ?a, ?t, ?e, ?_, ?c, ?h, ?i, ?p]) == + {:ok, %{cookies: [~c"chocolate_chip"], cookie_length: 14}} + end - test "handles cookie record without critical bit" do - assert parse([0x00, 0x05, 0x00, 0x0E, ?c, ?h, ?o, ?c, ?o, ?l, ?a, ?t, ?e, ?_, ?c, ?h, ?i, ?p]) == - {:ok, %{cookies: [~c"chocolate_chip"], cookie_length: 14}} - end + test "handles cookie record without critical bit" do + assert parse([0x00, 0x05, 0x00, 0x0E, ?c, ?h, ?o, ?c, ?o, ?l, ?a, ?t, ?e, ?_, ?c, ?h, ?i, ?p]) == + {:ok, %{cookies: [~c"chocolate_chip"], cookie_length: 14}} + end - test "sets cookie length to longest cookie" do - assert parse( - [0x80, 0x05, 0x00, 0x01, ?c] ++ - [0x80, 0x05, 0x00, 0x03, ?c, ?c, ?c] ++ - [0x80, 0x05, 0x00, 0x01, ?c] - ) == - {:ok, %{cookies: [~c"c", ~c"ccc", ~c"c"], cookie_length: 3}} - end - - test "handles full response" do - assert parse( - [0x80, 0x01, 0x00, 0x02, 0x00, 0x00] ++ - [0x80, 0x04, 0x00, 0x06, 0x00, 0x1E, 0x00, 0x01, 0x00, 0x0F] ++ + test "sets cookie length to longest cookie" do + assert parse( [0x80, 0x05, 0x00, 0x01, ?c] ++ - [0x00, 0x21, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03] ++ - [0x80, 0x06, 0x00, 0x09, ?1, ?2, ?7, ?., ?0, ?., ?0, ?., ?1] ++ - [0x80, 0x07, 0x00, 0x02, 0x04, 0xCE] ++ - [0x80, 0x00, 0x00, 0x00] - ) == - {:ok, - %{ - cookies: [~c"c"], - aead_algorithms: ["AEAD_AES_SIV_CMAC_256", "UNKNOWN", "AEAD_AES_128_GCM_SIV"], - cookie_length: 1, - next_protocols: ["NTPv4"], - port: 1230, - server: "127.0.0.1" - }} - end + [0x80, 0x05, 0x00, 0x03, ?c, ?c, ?c] ++ + [0x80, 0x05, 0x00, 0x01, ?c] + ) == + {:ok, %{cookies: [~c"c", ~c"ccc", ~c"c"], cookie_length: 3}} + end - test "doesn't read past end of message record" do - assert parse( - [0x80, 0x01, 0x00, 0x02, 0x00, 0x00] ++ - [0x00, 0x21, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03] ++ - [0x80, 0x04, 0x00, 0x02, 0x00, 0x1E] ++ - [0x80, 0x00, 0x00, 0x00] ++ - [0x80, 0x05, 0x00, 0x01, ?c] ++ - [0x80, 0x06, 0x00, 0x09, ?1, ?2, ?7, ?., ?0, ?., ?0, ?., ?1] ++ - [0x80, 0x07, 0x00, 0x02, 0x04, 0xCE] - ) == - {:ok, - %{ - aead_algorithms: ["AEAD_AES_128_GCM_SIV"], - next_protocols: ["NTPv4"] - }} + test "handles full response" do + assert parse( + [0x80, 0x01, 0x00, 0x02, 0x00, 0x00] ++ + [0x80, 0x04, 0x00, 0x06, 0x00, 0x1E, 0x00, 0x01, 0x00, 0x0F] ++ + [0x80, 0x05, 0x00, 0x01, ?c] ++ + [0x00, 0x21, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03] ++ + [0x80, 0x06, 0x00, 0x09, ?1, ?2, ?7, ?., ?0, ?., ?0, ?., ?1] ++ + [0x80, 0x07, 0x00, 0x02, 0x04, 0xCE] ++ + [0x80, 0x00, 0x00, 0x00] + ) == + {:ok, + %{ + cookies: [~c"c"], + aead_algorithms: ["AEAD_AES_SIV_CMAC_256", "UNKNOWN", "AEAD_AES_128_GCM_SIV"], + cookie_length: 1, + next_protocols: ["NTPv4"], + port: 1230, + server: "127.0.0.1" + }} + end + + test "doesn't read past end of message record" do + assert parse( + [0x80, 0x01, 0x00, 0x02, 0x00, 0x00] ++ + [0x00, 0x21, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03] ++ + [0x80, 0x04, 0x00, 0x02, 0x00, 0x1E] ++ + [0x80, 0x00, 0x00, 0x00] ++ + [0x80, 0x05, 0x00, 0x01, ?c] ++ + [0x80, 0x06, 0x00, 0x09, ?1, ?2, ?7, ?., ?0, ?., ?0, ?., ?1] ++ + [0x80, 0x07, 0x00, 0x02, 0x04, 0xCE] + ) == + {:ok, + %{ + aead_algorithms: ["AEAD_AES_128_GCM_SIV"], + next_protocols: ["NTPv4"] + }} + end end end diff --git a/test/chronoscope_web/controllers/api/v1/health_controller_test.exs b/test/chronoscope_web/controllers/api/v1/health_controller_test.exs index 7d7ccf2..8d50d05 100644 --- a/test/chronoscope_web/controllers/api/v1/health_controller_test.exs +++ b/test/chronoscope_web/controllers/api/v1/health_controller_test.exs @@ -1,12 +1,14 @@ defmodule ChronoscopeWeb.API.V1.HealthControllerTest do use ChronoscopeWeb.ConnCase, async: true - test "indicates health", %{conn: conn} do - response = - conn - |> get(~p"/api/v1/health") - |> json_response(200) + describe "GET /api/v1/health" do + test "is healthy", %{conn: conn} do + response = + conn + |> get(~p"/api/v1/health") + |> json_response(200) - assert %{"healthy" => true} == response + assert %{"healthy" => true} == response + end end end diff --git a/test/chronoscope_web/controllers/api/v1/nts/key_establishment_controller_test.exs b/test/chronoscope_web/controllers/api/v1/nts/key_establishment_controller_test.exs index 03703a6..a873e10 100644 --- a/test/chronoscope_web/controllers/api/v1/nts/key_establishment_controller_test.exs +++ b/test/chronoscope_web/controllers/api/v1/nts/key_establishment_controller_test.exs @@ -5,7 +5,7 @@ defmodule ChronoscopeWeb.API.V1.NTS.KeyEstablishmentControllerTest do setup :verify_on_exit! - describe "/api/v1/nts/key-establishment" do + describe "GET /api/v1/nts/key-establishment" do test "requires a host name", %{conn: conn} do response = conn