Skip to content

Commit

Permalink
0.10.6 - improve and fix xdata and disco for router
Browse files Browse the repository at this point in the history
  • Loading branch information
manuel-rubio committed Jun 3, 2022
1 parent 7daa9c6 commit 911618b
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 3 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,17 @@ defmodule Myapp.Router do
end
```

In addition to the identity, you can add extra information, like a XData form, which is very common to the discovery for XEPs like HTTP upload:

```elixir
discovery do
identity category: "component", type: "generic", name: "myapp"
extra UploadForm.new("result", %{"max_file_size" => @max_file_size})
end
```

This way it will be generating also the extra data using an XData form for that.

### Envelope

Because we can configure XMPP to delegate using [XEP-0355](https://xmpp.org/extensions/xep-0355.html), we could configure to receive in a transparent way the incoming messages inside of their envelope and reply them just as if we were inside of the XMPP Server replying directly to the user or component asking.
Expand Down Expand Up @@ -676,6 +687,13 @@ Form01.new()
|> Xdata.validate_form()
```

Or in a shorter way, taking advantage of the `Form01.new/2` parameters, we could use:

```elixir
Form01.new("form", %{"name" => "Manuel", "surname" => "Rubio", "gender" => "M"})
|> Xdata.validate_form()
```

As you can see the validation is delegated to the specification of the data. Even, if you need to fill a form yourself to be sent to another server or even to a client, you can perform the action using the function `Xdata.submit/2`:

```elixir
Expand All @@ -685,6 +703,11 @@ Form01.new()

The difference between _cast_ and _submit_ is the last one is changing the form_type and performing a validation. Cast isn't performing a validation.

The state changes are:

- Form of `form` type is changed to `submit` type.
- Form of `submit` type is changed to `result` type.

## Something goes wrong

There is a monitoring process which is controlling what is happening with our request. If it takes more than the configured time to be attended which could be configured in the connection as `stanza_timeout` (by default it is 5 seconds) it's killing the process and
Expand Down
21 changes: 20 additions & 1 deletion lib/exampple/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ defmodule Exampple.Router do
Module.register_attribute(__MODULE__, :routes, accumulate: true)
Module.register_attribute(__MODULE__, :namespaces, accumulate: true)
Module.register_attribute(__MODULE__, :identities, accumulate: true)
Module.register_attribute(__MODULE__, :disco_extra, accumulate: true)
Module.register_attribute(__MODULE__, :includes, accumulate: true)
Module.register_attribute(__MODULE__, :features, accumulate: true)
@envelopes []
Expand Down Expand Up @@ -208,7 +209,12 @@ defmodule Exampple.Router do
)
end

identity ++ namespaces
extra =
Module.get_attribute(env.module, :disco_extra)
|> List.wrap()
|> List.flatten()

identity ++ namespaces ++ extra
else
[]
end
Expand Down Expand Up @@ -428,6 +434,19 @@ defmodule Exampple.Router do
end
end

defmacro extra(stanzas) do
quote do
unless Module.get_attribute(__MODULE__, :disco, false) do
raise """
identity MUST be inside of a discovery block.
"""
end

stanzas = unquote(stanzas)
Module.put_attribute(__MODULE__, :disco_extra, Macro.escape(stanzas))
end
end

defmacro feature(namespace) do
quote do
@features unquote(namespace)
Expand Down
13 changes: 12 additions & 1 deletion lib/exampple/xmpp/stanza/xdata.ex
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,21 @@ defmodule Exampple.Xmpp.Stanza.Xdata do
Creates a new Xdata structure. See more information in `Exampple.Xmpp.Stanza.Xdata`.
"""
@spec new(String.t(), map()) :: Exampple.Xmpp.Stanza.Xdata.t()
def new(xdata_form_type \\ "form", data \\ %{}) do
def new(xdata_form_type \\ "form", data \\ %{})

def new("form", data) when map_size(data) == 0 do
Exampple.Xmpp.Stanza.Xdata.new(__MODULE__)
end

def new(xdata_form_type, data) when map_size(data) == 0 do
Exampple.Xmpp.Stanza.Xdata.new(__MODULE__, xdata_form_type)
end

def new(xdata_form_type, data) do
Exampple.Xmpp.Stanza.Xdata.new(__MODULE__, xdata_form_type)
|> Exampple.Xmpp.Stanza.Xdata.cast(data)
end

@doc """
Check if a field inside of the definition is multi or not.
See more information in `Exampple.Xmpp.Stanza.Xdata`.
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule Exampple.MixProject do
def project do
[
app: :exampple,
version: "0.10.5",
version: "0.10.6",
description: "eXaMPPle is a XMPP Component Framework",
elixir: "~> 1.9",
elixirc_paths: elixirc_paths(Mix.env()),
Expand Down
1 change: 1 addition & 0 deletions test/router_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ defmodule Exampple.RouterTest do
<feature var="urn:xmpp:forward:0"/>
<feature var="jabber:iq:rpc"/>
<feature var="urn:exampple:test:get:0"/>
<data/>
</query>
</iq>
])
Expand Down
1 change: 1 addition & 0 deletions test/support/testing_full_router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ defmodule TestingFullRouter do

discovery do
identity(category: "component", type: "generic", name: "Testing component")
extra(Exampple.Xml.Xmlel.new("data"))
end

envelope(["urn:xmpp:delegation:1", "urn:xmpp:forward:0"])
Expand Down
48 changes: 48 additions & 0 deletions test/xmpp/stanza/xdata_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,54 @@ defmodule Exampple.Xmpp.Stanza.XdataTest do
assert to_string(xml) == to_string(form)
end

test "casting values in new function" do
defmodule Form25 do
use Exampple.Xmpp.Stanza.Xdata

form "urn:xmpp:mydata", "Personal Details" do
instructions("Fill the whole form, please.")
field("name", :text_single, required: true, label: "Name")
field("surname", :text_single, label: "Surname")

field("gender", :list_single, label: "Gender", options: [{"Male", "M"}, {"Female", "F"}])
end
end

form =
Form25.new("result", %{
"name" => "Manuel",
"surname" => "Rubio",
"gender" => "M",
"age" => "41"
})

xml = ~x[
<x type='result' xmlns='jabber:x:data'>
<title>Personal Details</title>
<instructions>Fill the whole form, please.</instructions>
<field var='FORM_TYPE' type='hidden'>
<value>urn:xmpp:mydata</value>
</field>
<field label='Name' type='text-single' var='name'>
<required/>
<value>Manuel</value>
</field>
<field label='Surname' type='text-single' var='surname'>
<value>Rubio</value>
</field>
<field label='Gender' type='list-single' var='gender'>
<value>M</value>
<option label='Male'><value>M</value></option>
<option label='Female'><value>F</value></option>
</field>
</x>
]

assert is_nil(form.errors)
assert form.valid?
assert to_string(xml) == to_string(form)
end

test "casting multi-values" do
defmodule Form24 do
use Exampple.Xmpp.Stanza.Xdata
Expand Down

0 comments on commit 911618b

Please sign in to comment.