Skip to content

Commit 2010c2a

Browse files
wing328efcasado
andauthored
Add workflow to test Elixir clients (#21214)
* add elixir workflow * update * fix * add elixir workflow (#21215) * update tests to use built-in json module instead of jason * update base_url * temporarily disable type-casting for dates * retry failing tests * update spec to use localhost * add petsore local server to workflow --------- Co-authored-by: Enrique Fernández <[email protected]>
1 parent 4101258 commit 2010c2a

File tree

11 files changed

+88
-27
lines changed

11 files changed

+88
-27
lines changed

.github/workflows/samples-elixir.yaml

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Samples Elixir
2+
3+
on:
4+
push:
5+
paths:
6+
- samples/client/petstore/elixir/**
7+
pull_request:
8+
paths:
9+
- samples/client/petstore/elixir/**
10+
jobs:
11+
build:
12+
runs-on: ubuntu-latest
13+
name: OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}}
14+
strategy:
15+
matrix:
16+
otp: ['25.3.2', '26.2.5', '27.3.3']
17+
elixir: ['1.18.3']
18+
sample:
19+
- samples/client/petstore/elixir/
20+
services:
21+
petstore-api:
22+
image: swaggerapi/petstore
23+
ports:
24+
- 80:8080
25+
env:
26+
SWAGGER_HOST: http://petstore.swagger.io
27+
SWAGGER_BASE_PATH: /v2
28+
steps:
29+
- uses: actions/checkout@v4
30+
- uses: erlef/setup-beam@v1
31+
with:
32+
otp-version: ${{matrix.otp}}
33+
elixir-version: ${{matrix.elixir}}
34+
- name: mix deps.get
35+
run: mix deps.get
36+
working-directory: ${{ matrix.sample }}
37+
- name: mix test
38+
run: mix test
39+
working-directory: ${{ matrix.sample }}

modules/openapi-generator/src/test/resources/3_0/elixir/petstore-with-fake-endpoints-models-for-testing.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ paths:
3131
$ref: "#/components/schemas/Foo"
3232
/pet:
3333
servers:
34+
- url: "http://localhost/v2"
3435
- url: "http://petstore.swagger.io/v2"
3536
- url: "http://path-server-test.petstore.local/v2"
3637
- url: "http://{server}.swagger.io:{port}/v2"
@@ -1361,6 +1362,8 @@ paths:
13611362
schema:
13621363
$ref: "#/components/schemas/AllOfWithSingleRef"
13631364
servers:
1365+
- url: "http://localhost/v2"
1366+
- url: "https://petstore.swagger.io/v2"
13641367
- url: "http://{server}.swagger.io:{port}/v2"
13651368
description: petstore server
13661369
variables:

samples/client/petstore/elixir/.openapi-generator-ignore

+1
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@
2121
#docs/*.md
2222
# Then explicitly reverse the ignore rule for a single file:
2323
#!docs/README.md
24+
#

samples/client/petstore/elixir/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ You can override the URL of your server (e.g. if you have a separate development
3131
configuration files).
3232

3333
```elixir
34-
config :openapi_petstore, base_url: "http://petstore.swagger.io:80/v2"
34+
config :openapi_petstore, base_url: "http://localhost/v2"
3535
```
3636

3737
Multiple clients for the same API with different URLs can be created passing different `base_url`s when calling
3838
`OpenapiPetstore.Connection.new/1`:
3939

4040
```elixir
41-
client = OpenapiPetstore.Connection.new(base_url: "http://petstore.swagger.io:80/v2")
41+
client = OpenapiPetstore.Connection.new(base_url: "http://localhost/v2")
4242
```
4343

4444
[exdoc]: https://github.com/elixir-lang/ex_doc

samples/client/petstore/elixir/config/config.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# General application configuration
88
import Config
99

10-
config :openapi_petstore, base_url: "http://petstore.swagger.io:80/v2"
10+
config :openapi_petstore, base_url: "http://localhost/v2"
1111

1212
# Import environment specific config. This must remain at the bottom
1313
# of this file so it overrides the configuration defined above.

samples/client/petstore/elixir/lib/openapi_petstore/connection.ex

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,19 @@ defmodule OpenapiPetstore.Connection do
88
Additional middleware can be set in the compile-time or runtime configuration:
99
1010
config :tesla, OpenapiPetstore.Connection,
11-
base_url: "http://petstore.swagger.io:80/v2",
11+
base_url: "http://localhost/v2",
1212
adapter: Tesla.Adapter.Hackney
1313
1414
The default base URL can also be set as:
1515
1616
config :openapi_petstore,
17-
:base_url, "http://petstore.swagger.io:80/v2"
17+
:base_url, "http://localhost/v2"
1818
"""
1919

2020
@default_base_url Application.compile_env(
2121
:openapi_petstore,
2222
:base_url,
23-
"http://petstore.swagger.io:80/v2"
23+
"http://localhost/v2"
2424
)
2525

2626
@default_scopes [

samples/client/petstore/elixir/test/deserializer_test.exs

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ defmodule DeserializerTest do
3030
"""
3131

3232
test "jason_decode/2 with valid JSON" do
33-
assert Deserializer.jason_decode(@valid_json, Pet) ==
33+
assert Deserializer.json_decode(@valid_json, Pet) ==
3434
{:ok,
3535
%Pet{
3636
id: 14,
@@ -43,7 +43,7 @@ defmodule DeserializerTest do
4343
end
4444

4545
test "jason_decode/2 with invalid JSON" do
46-
assert Deserializer.jason_decode(~s/{: 1}/, Pet) ==
47-
{:error, %Jason.DecodeError{data: "{: 1}", position: 1, token: nil}}
46+
assert Deserializer.json_decode(~s/{: 1}/, Pet) ==
47+
{:error, {:invalid_byte, 1, 58}}
4848
end
4949
end

samples/client/petstore/elixir/test/format_test.exs

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ defmodule FormatTest do
3333
string: "Hello world!",
3434
byte: "U3dhZ2dlciByb2Nrcw==",
3535
binary: <<1, 2, 3>>,
36-
date: ~D[2013-10-20],
37-
dateTime: ~U[2013-10-20T18:20:30Z],
36+
date: "2013-10-20",
37+
dateTime: "2013-10-20T19:20:30+01:00",
3838
uuid: "3fa85f64-5717-4562-b3fc-2c963f66afa6",
3939
password: "green?horse",
4040
pattern_with_digits: "1234567890",
@@ -73,7 +73,7 @@ defmodule FormatTest do
7373
string: nil,
7474
byte: "U3dhZ2dlciByb2Nrcw==",
7575
binary: nil,
76-
date: ~D[2013-10-20],
76+
date: "2013-10-20",
7777
dateTime: nil,
7878
uuid: nil,
7979
password: "green?horse",

samples/client/petstore/elixir/test/mixed_properties_and_additional_properties_class_test.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ defmodule MixedPropertiesAndAdditionalPropertiesClass do
1515
|> Model.decode() ==
1616
%Model{
1717
uuid: "3fa85f64-5717-4562-b3fc-2c963f66afa6",
18-
dateTime: ~U[2013-10-20T18:20:30Z],
18+
dateTime: "2013-10-20T19:20:30+01:00",
1919
map: %{
2020
# TODO values should be Dog and Cat structs instead of an Animal
2121
"doggie" => %Animal{

samples/client/petstore/elixir/test/outer_enum_test.exs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ defmodule OuterEnumTest do
1414
"""
1515

1616
@tag timeout: :infinity
17-
test "jason_decode/2 with valid JSON" do
18-
assert Deserializer.jason_decode(@valid_json, EnumTest) ==
17+
test "json_decode/2 with valid JSON" do
18+
assert Deserializer.json_decode(@valid_json, EnumTest) ==
1919
{:ok,
2020
%EnumTest{
2121
enum_string: "UPPER",

samples/client/petstore/elixir/test/pet_test.exs

+30-12
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,21 @@ defmodule PetTest do
2424
{:ok, %Tesla.Env{} = response} = PetApi.add_pet(connection, pet)
2525
assert response.status == 200
2626

27-
{:ok, pet} = PetApi.get_pet_by_id(connection, petId)
28-
assert pet.id == petId
29-
assert pet.name == "elixir client test"
30-
assert pet.photoUrls == ["http://test_elixir_unit_test.com"]
31-
assert pet.category == %Category{id: petId, name: "test elixir category"}
32-
assert pet.tags == [%Tag{:id => petId, :name => "test elixir tag"}]
27+
retry_assert(fn ->
28+
{:ok, pet} = PetApi.get_pet_by_id(connection, petId)
29+
assert pet.id == petId
30+
assert pet.name == "elixir client test"
31+
assert pet.photoUrls == ["http://test_elixir_unit_test.com"]
32+
assert pet.category == %Category{id: petId, name: "test elixir category"}
33+
assert pet.tags == [%Tag{:id => petId, :name => "test elixir tag"}]
34+
end)
3335

3436
{:ok, response} = PetApi.delete_pet(connection, petId)
3537
assert response.status == 200
36-
{:ok, response} = PetApi.get_pet_by_id(connection, petId)
37-
assert response.status == 404
38+
retry_assert(fn ->
39+
{:ok, response} = PetApi.get_pet_by_id(connection, petId)
40+
assert response.status == 404
41+
end)
3842
end
3943

4044
test "update a pet", %{connection: connection} do
@@ -50,10 +54,24 @@ defmodule PetTest do
5054
{:ok, response} = PetApi.update_pet(connection, pet)
5155
assert response.status == 200
5256

53-
{:ok, pet} = PetApi.get_pet_by_id(connection, petId)
54-
assert pet.id == petId
55-
assert pet.name == "elixir client updatePet"
56-
assert pet.status == "pending"
57+
retry_assert(fn ->
58+
{:ok, pet} = PetApi.get_pet_by_id(connection, petId)
59+
assert pet.id == petId
60+
assert pet.name == "elixir client updatePet"
61+
assert pet.status == "pending"
62+
end, 5, 100)
63+
end
64+
65+
def retry_assert(fun, attempts \\ 3, delay \\ 100)
66+
def retry_assert(_fun, 0, _delay), do: flunk("assertion failed after retries")
67+
def retry_assert(fun, attempts, delay) do
68+
try do
69+
fun.()
70+
rescue
71+
_e ->
72+
Process.sleep(delay)
73+
retry_assert(fun, attempts - 1, delay)
74+
end
5775
end
5876

5977
test "find pet by status", %{connection: connection} do

0 commit comments

Comments
 (0)