Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: essiene/mmynapi
base: 8b580a2c5e
...
head fork: essiene/mmynapi
compare: a729aca753
  • 15 commits
  • 8 files changed
  • 0 commit comments
  • 1 contributor
Commits on Sep 07, 2011
@essiene Test #'res.sendsms'{} conversion by to_json/3
Signed-off-by: Essien Ita Essien <essiene@gmail.com>
c17d1e6
@essiene Test #'res.reply'{} conversion by to_json/3
Signed-off-by: Essien Ita Essien <essiene@gmail.com>
74defad
@essiene Test #'req.reply'{} conversion by to_json/3
Signed-off-by: Essien Ita Essien <essiene@gmail.com>
77b81ba
@essiene Test #'res.notify'{} conversion by to_json/3
Signed-off-by: Essien Ita Essien <essiene@gmail.com>
5402d18
@essiene Test #'req.notify'{} conversion with to_json/3
Signed-off-by: Essien Ita Essien <essiene@gmail.com>
5061736
Commits on Sep 08, 2011
@essiene Change req.notify's 'keyword' field to 'keywords'
This is because Mmayen is able to match multiple leading
words as keywords. This field is now specified as an array
of strings

Signed-off-by: Essien Ita Essien <essiene@gmail.com>
9bb39b2
@essiene Update unittests
Signed-off-by: Essien Ita Essien <essiene@gmail.com>
f0b0fb7
@essiene Add TODO file
Signed-off-by: Essien Ita Essien <essiene@gmail.com>
5b561b7
@essiene Start work on mmynapi_decode module
Signed-off-by: Essien Ita Essien <essiene@gmail.com>
d397162
@essiene Change the definition of the message version
Using a list of integers, allows us to easily do comparisons,
without having to split a string at the time we want to compare
it

Signed-off-by: Essien Ita Essien <essiene@gmail.com>
52a12b5
@essiene Update the header version
Signed-off-by: Essien Ita Essien <essiene@gmail.com>
39c605e
@essiene Update unittests
Signed-off-by: Essien Ita Essien <essiene@gmail.com>
10ee232
@essiene Rename mmynapi_decode functions
instead of calling the functions like:
  mmynapi_decode:decode_header

It looks better to do:
  mmynapi_decode:to_header

Signed-off-by: Essien Ita Essien <essiene@gmail.com>
56fa6e8
@essiene Start work on mmynapi_decode unittests
Signed-off-by: Essien Ita Essien <essiene@gmail.com>
84813c9
@essiene More unittests for mmynapi_decode:to_header
Test all error checking paths in to_header/1

Signed-off-by: Essien Ita Essien <essiene@gmail.com>
a729aca
View
4 README
@@ -26,7 +26,7 @@ mmyn-message() =
req.notify(), res.notify()
};
-mmyn-msg-vsn() = 2.0.1;
+mmyn-msg-vsn() = [Major,Minor,PatchLevel]; //current version is [2,0,1]
mmyn-msg-type() = "req.sendsms" | "req.reply" |
"req.notify" | "res.sendsms" |
@@ -63,7 +63,7 @@ req.notify() =
{
"id" = string(),
"shortcode" = integer(),
- "keyword" = string(),
+ "keywords" = array(),
"msisdn" = string(),
"message" = string(),
"max_ttl" = integer()
View
13 TODO
@@ -0,0 +1,13 @@
+Add a generic fault message body type that is returned when an exception is encountered.
+
+An exception is defined as any situation that occurs during processing that prevents the
+requested message type to start processing. Examples are:
+
+1. Wrong message vsn in header
+2. invalid types in header
+3. Missing mandatory fields in messages
+4. Server exceptions thrown during processing.
+
+The only time a valid response is received from a message is when that routine has been
+processed and the response is as a direct result of processing that message. Any other
+situation that arises, is considered an exception
View
4 include/mmynapi.hrl
@@ -1,7 +1,7 @@
-ifndef(mmynapi).
-define(mmynapi, true).
--define(MMYN_MSG_VSN, '2.0.1').
+-define(MMYN_MSG_VSN, [2,0,1]).
-define(MMYN_REQ_SENDSMS, "request.sendsms").
-define(MMYN_RES_SENDSMS, "response.sendsms").
@@ -40,7 +40,7 @@
-record('req.notify', {
id,
shortcode,
- keyword,
+ keywords,
msisdn,
message,
max_ttl}).
View
70 src/mmynapi_decode.erl
@@ -0,0 +1,70 @@
+-module(mmynapi_decode).
+-export([to_message/1, to_header/1, to_body/2]).
+-include("mmynapi.hrl").
+
+
+to_message({PropList}) ->
+ case proplists:get_value(<<"header">>, PropList) of
+ undefined ->
+ {error, no_header};
+ Header ->
+ case to_header(Header) of
+ {error, Reason} ->
+ {error, Reason};
+ {ok, #'mmyn.header'{type=MsgType}=Hrecord} ->
+ case proplists:get_value(<<"body">>, PropList) of
+ undefined ->
+ {error, no_body};
+ Body ->
+ case to_body(MsgType, Body) of
+ {error, Reason} ->
+ {error, Reason};
+ {ok, Brecord} ->
+ {ok, #'mmyn.message'{h=Hrecord, b=Brecord}}
+ end
+ end
+ end
+ end.
+
+to_header({PropList}) ->
+ case proplists:get_value(<<"vsn">>, PropList) of
+ undefined ->
+ {error, no_version};
+ ?MMYN_MSG_VSN->
+ case proplists:get_value(<<"type">>, PropList) of
+ undefined ->
+ {error, no_type};
+ Type ->
+ case proplists:get_value(<<"system">>, PropList) of
+ undefined ->
+ {error, no_system};
+ Sid ->
+ case proplists:get_value(<<"transaction_id">>, PropList) of
+ undefined ->
+ {error, no_transaction_id};
+ Tid ->
+ {ok, #'mmyn.header'{vsn=?MMYN_MSG_VSN, type=Type, system=Sid, transaction_id=Tid}}
+ end
+ end
+ end;
+ N ->
+ {error, {wrong_msg_vsn, [{current_msg_vsn, ?MMYN_MSG_VSN}, {parsed_msg_vsn, N}]}}
+ end.
+
+to_body(<<"req.sendsms">>, {PropList}) ->
+ case proplists:get_value(<<"sender">>, PropList) of
+ undefined ->
+ {error, no_sender};
+ Sender ->
+ case proplists:get_value(<<"msisdn">>, PropList) of
+ undefined ->
+ {error, no_msisdn};
+ Msisdn ->
+ case proplists:get_value(<<"message">>, PropList) of
+ undefined ->
+ {error, no_message};
+ Message ->
+ {ok, #'req.sendsms'{sender=Sender, msisdn=Msisdn, message=Message}}
+ end
+ end
+ end.
View
4 src/mmynapi_encode.erl
@@ -32,11 +32,11 @@ to_json_form(#'res.reply'{status=S, detail=D}) ->
{[
{<<"status">>, to_json_form(S)},
{<<"detail">>, to_json_form(D)}]};
-to_json_form(#'req.notify'{id=Id, shortcode=S, keyword=K, msisdn=M, message=Msg, max_ttl=MaxTtl}) ->
+to_json_form(#'req.notify'{id=Id, shortcode=S, keywords=K, msisdn=M, message=Msg, max_ttl=MaxTtl}) ->
{[
{<<"id">>, to_json_form(Id)},
{<<"shortcode">>, to_json_form(S)},
- {<<"keyword">>, to_json_form(K)},
+ {<<"keywords">>, to_json_form(K)},
{<<"msisdn">>, to_json_form(M)},
{<<"message">>, to_json_form(Msg)},
{<<"max_ttl">>, to_json_form(MaxTtl)}]};
View
47 test/mmynapi_decode_tests.erl
@@ -0,0 +1,47 @@
+-module(mmynapi_decode_tests).
+-include("../include/mmynapi.hrl").
+-include_lib("eunit/include/eunit.hrl").
+
+decode_header_test_() ->
+ [
+ {"Convert a correct header in JSON form to #'mmyn.header'{} record",
+ ?_assertEqual({ok, #'mmyn.header'{vsn=?MMYN_MSG_VSN, type= <<"req.sendsms">>,
+ system= <<"mmyn">>, transaction_id= <<"0xdeadbeef">>}},
+ mmynapi_decode:to_header({[
+ {<<"vsn">>, [2,0,1]},
+ {<<"type">>, <<"req.sendsms">>},
+ {<<"system">>, <<"mmyn">>},
+ {<<"transaction_id">>, <<"0xdeadbeef">>}]}))},
+ {"Error out when header JSON form is missing a 'vsn' field",
+ ?_assertEqual({error, no_version},
+ mmynapi_decode:to_header({[
+ {<<"type">>, <<"req.sendsms">>},
+ {<<"system">>, <<"mmyn">>},
+ {<<"transaction_id">>, <<"0xdeadbeef">>}]}))},
+ {"Error out when header 'vsn' field is wrong",
+ ?_assertEqual({error, {wrong_msg_vsn, [{current_msg_vsn, [2,0,1]}, {parsed_msg_vsn,[3,2,1]}]}},
+ mmynapi_decode:to_header({[
+ {<<"type">>, <<"req.sendsms">>},
+ {<<"vsn">>, [3,2,1]},
+ {<<"system">>, <<"mmyn">>},
+ {<<"transaction_id">>, <<"0xdeadbeef">>}]}))},
+ {"Error out when header JSON form is missing a 'type' field",
+ ?_assertEqual({error, no_type},
+ mmynapi_decode:to_header({[
+ {<<"vsn">>, [2,0,1]},
+ {<<"system">>, <<"mmyn">>},
+ {<<"transaction_id">>, <<"0xdeadbeef">>}]}))},
+ {"Error out when header JSON form is missing a 'system' field",
+ ?_assertEqual({error, no_system},
+ mmynapi_decode:to_header({[
+ {<<"vsn">>, [2,0,1]},
+ {<<"type">>, <<"res.sendsms">>},
+ {<<"transaction_id">>, <<"0xdeadbeef">>}]}))},
+ {"Error out when header JSON form is missing a 'transaction_id' field",
+ ?_assertEqual({error, no_transaction_id},
+ mmynapi_decode:to_header({[
+ {<<"vsn">>, [2,0,1]},
+ {<<"system">>, <<"mmyn">>},
+ {<<"type">>, <<"res.sendsms">>}]}))}
+ ].
+
View
27 test/mmynapi_encode_tests.erl
@@ -30,18 +30,31 @@ to_json_form_test_() ->
mmynapi_encode:to_json_form(#'res.notify'{
status=0,detail = <<"All okay">>,
wait_for_reply=true, ttl=30}))},
- {"Convert '#req.notify{}' record",
+ {"Convert '#req.notify{}' record, with single keyword",
?_assertEqual(
{[
{<<"id">>, <<"0xdeadbeef">>},
{<<"shortcode">>, 4000},
- {<<"keyword">>, <<"akeyword">>},
+ {<<"keywords">>, [<<"akeyword">>]},
{<<"msisdn">>, <<"+1234567">>},
{<<"message">>, <<"some dumb message">>},
{<<"max_ttl">>, 30}]},
mmynapi_encode:to_json_form(#'req.notify'{
id= <<"0xdeadbeef">>, shortcode=4000,
- keyword= <<"akeyword">>, msisdn= <<"+1234567">>,
+ keywords= [<<"akeyword">>], msisdn= <<"+1234567">>,
+ message= <<"some dumb message">>, max_ttl=30}))},
+ {"Convert '#req.notify{}' record, with multiple keywords",
+ ?_assertEqual(
+ {[
+ {<<"id">>, <<"0xdeadbeef">>},
+ {<<"shortcode">>, 4000},
+ {<<"keywords">>, [<<"kwd1">>, <<"kwd2">>]},
+ {<<"msisdn">>, <<"+1234567">>},
+ {<<"message">>, <<"some dumb message">>},
+ {<<"max_ttl">>, 30}]},
+ mmynapi_encode:to_json_form(#'req.notify'{
+ id= <<"0xdeadbeef">>, shortcode=4000,
+ keywords= [<<"kwd1">>, <<"kwd2">>], msisdn= <<"+1234567">>,
message= <<"some dumb message">>, max_ttl=30}))},
{"Convert '#res.reply{}' record",
?_assertEqual(
@@ -88,19 +101,19 @@ to_json_form_test_() ->
{"Convert '#mmyn.header{}' record",
?_assertEqual(
{[
- {<<"vsn">>, <<"2.0.1">>},
+ {<<"vsn">>, [2,0,1]},
{<<"type">>, <<"res.sendsms">>},
{<<"system">>, <<"mmyn">>},
{<<"transaction_id">>, <<"0xdeadbeef">>}]},
mmynapi_encode:to_json_form(#'mmyn.header'{
- vsn= <<"2.0.1">>, type= <<"res.sendsms">>,
+ vsn=[2,0,1], type= <<"res.sendsms">>,
system= <<"mmyn">>, transaction_id= <<"0xdeadbeef">>}))},
{"Convert '#mmyn.message{}' record",
?_assertEqual(
{[
{<<"header">>,
{[
- {<<"vsn">>, <<"2.0.1">>},
+ {<<"vsn">>, [2,0,1]},
{<<"type">>, <<"req.sendsms">>},
{<<"system">>, <<"mmyn">>},
{<<"transaction_id">>, <<"0xdeadbeef">>}]}},
@@ -111,7 +124,7 @@ to_json_form_test_() ->
{<<"message">>, <<"a dumb message">>}]}}]},
mmynapi_encode:to_json_form(#'mmyn.message'{
h=#'mmyn.header'{
- vsn= <<"2.0.1">>, type= <<"req.sendsms">>,
+ vsn= [2,0,1], type= <<"req.sendsms">>,
system= <<"mmyn">>, transaction_id= <<"0xdeadbeef">>},
b=#'req.sendsms'{
sender= <<"ASENDER">>, msisdn= <<"+23481618">>,
View
34 test/mmynapi_tests.erl
@@ -5,18 +5,42 @@
to_json_test_() ->
[
{"Convert '#mmyn.message{}' to JSON document",
- ?_assertEqual(<<"{\"header\":{\"vsn\":\"2.0.1\",\"type\":\"req.sendsms\",\"system\":\"mmyn\",\"transaction_id\":\"0xdeadbeef\"},\"body\":{\"sender\":\"ASENDER\",\"msisdn\":\"+23481618\",\"message\":\"a dumb message\"}}">>,
+ ?_assertEqual(<<"{\"header\":{\"vsn\":[2,0,1],\"type\":\"req.sendsms\",\"system\":\"mmyn\",\"transaction_id\":\"0xdeadbeef\"},\"body\":{\"sender\":\"ASENDER\",\"msisdn\":\"+23481618\",\"message\":\"a dumb message\"}}">>,
mmynapi:to_json(#'mmyn.message'{
h=#'mmyn.header'{
- vsn= <<"2.0.1">>, type= <<"req.sendsms">>,
+ vsn= [2,0,1], type= <<"req.sendsms">>,
system= <<"mmyn">>, transaction_id= <<"0xdeadbeef">>},
b=#'req.sendsms'{
sender= <<"ASENDER">>, msisdn= <<"+23481618">>,
message= <<"a dumb message">>}}))},
- {"Test mmynapi:to_json/3",
- ?_assertEqual(<<"{\"header\":{\"vsn\":\"2.0.1\",\"type\":\"req.sendsms\",\"system\":\"mmyn\",\"transaction_id\":\"0xdeadbeef\"},\"body\":{\"sender\":\"ASENDER\",\"msisdn\":\"+23481618\",\"message\":\"a dumb message\"}}">>,
+ {"Convert #'req.sendsms'{} to JSON via mmynapi:to_json/3",
+ ?_assertEqual(<<"{\"header\":{\"vsn\":[2,0,1],\"type\":\"req.sendsms\",\"system\":\"mmyn\",\"transaction_id\":\"0xdeadbeef\"},\"body\":{\"sender\":\"ASENDER\",\"msisdn\":\"+23481618\",\"message\":\"a dumb message\"}}">>,
mmynapi:to_json('mmyn', '0xdeadbeef', #'req.sendsms'{
sender= <<"ASENDER">>, msisdn= <<"+23481618">>,
- message= <<"a dumb message">>}))}
+ message= <<"a dumb message">>}))},
+ {"Convert #'res.sendsms'{} to JSON via mmynapi:to_json/3",
+ ?_assertEqual(<<"{\"header\":{\"vsn\":[2,0,1],\"type\":\"res.sendsms\",\"system\":\"mmyn\",\"transaction_id\":\"0xdeadbeef\"},\"body\":{\"status\":0,\"detail\":\"All Okay\"}}">>,
+ mmynapi:to_json('mmyn', '0xdeadbeef', #'res.sendsms'{
+ status=0, detail= <<"All Okay">>}))},
+ {"Convert #'req.reply'{} to JSON via mmynapi:to_json/3",
+ ?_assertEqual(<<"{\"header\":{\"vsn\":[2,0,1],\"type\":\"req.reply\",\"system\":\"mmyn\",\"transaction_id\":\"0xdeadbeef\"},\"body\":{\"id\":\"0xcafebabe\",\"sender\":\"ASENDER\",\"msisdn\":\"+23481618\",\"message\":\"a dumb message\"}}">>,
+ mmynapi:to_json('mmyn', '0xdeadbeef', #'req.reply'{
+ id= <<"0xcafebabe">>, sender= <<"ASENDER">>, msisdn= <<"+23481618">>,
+ message= <<"a dumb message">>}))},
+ {"Convert #'res.reply'{} to JSON via mmynapi:to_json/3",
+ ?_assertEqual(<<"{\"header\":{\"vsn\":[2,0,1],\"type\":\"res.reply\",\"system\":\"mmyn\",\"transaction_id\":\"0xdeadbeef\"},\"body\":{\"status\":0,\"detail\":\"All Okay\"}}">>,
+ mmynapi:to_json('mmyn', '0xdeadbeef', #'res.reply'{
+ status=0, detail= <<"All Okay">>}))},
+ {"Convert #'req.notify'{} to JSON via mmynapi:to_json/3",
+ ?_assertEqual(<<"{\"header\":{\"vsn\":[2,0,1],\"type\":\"req.notify\",\"system\":\"mmyn\",\"transaction_id\":\"0xdeadbeef\"},\"body\":{\"id\":\"0xcafebabe\",\"shortcode\":4000,\"keywords\":[\"kwd\"],\"msisdn\":\"+23481618\",\"message\":\"a dumb message\",\"max_ttl\":30}}">>,
+ mmynapi:to_json('mmyn', '0xdeadbeef', #'req.notify'{
+ id= <<"0xcafebabe">>, shortcode=4000,
+ keywords= [<<"kwd">>], msisdn= <<"+23481618">>,
+ message= <<"a dumb message">>, max_ttl=30}))},
+ {"Convert #'res.notify'{} to JSON via mmynapi:to_json/3",
+ ?_assertEqual(<<"{\"header\":{\"vsn\":[2,0,1],\"type\":\"res.notify\",\"system\":\"mmyn\",\"transaction_id\":\"0xdeadbeef\"},\"body\":{\"status\":0,\"detail\":\"All Okay\",\"wait_for_reply\":false,\"ttl\":60}}">>,
+ mmynapi:to_json('mmyn', '0xdeadbeef', #'res.notify'{
+ status=0, detail= <<"All Okay">>,
+ wait_for_reply=false, ttl=60}))}
].

No commit comments for this range

Something went wrong with that request. Please try again.