From 671f2b6f62a6f50bf74a52916fdbb372d3a5af1c Mon Sep 17 00:00:00 2001 From: Bragaz Date: Fri, 6 Mar 2020 16:30:12 +0100 Subject: [PATCH 1/7] implemented the possibility to create an empty-message post with medias --- x/posts/internal/types/msgs.go | 2 +- x/posts/internal/types/msgs_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x/posts/internal/types/msgs.go b/x/posts/internal/types/msgs.go index bbbdf46fce..a7ec4d0ff9 100644 --- a/x/posts/internal/types/msgs.go +++ b/x/posts/internal/types/msgs.go @@ -56,7 +56,7 @@ func (msg MsgCreatePost) ValidateBasic() error { return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, fmt.Sprintf("Invalid creator address: %s", msg.Creator)) } - if len(strings.TrimSpace(msg.Message)) == 0 { + if len(strings.TrimSpace(msg.Message)) == 0 && len(msg.Medias) == 0 { return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Post message cannot be empty nor blank") } diff --git a/x/posts/internal/types/msgs_test.go b/x/posts/internal/types/msgs_test.go index 050ad88705..946107079d 100644 --- a/x/posts/internal/types/msgs_test.go +++ b/x/posts/internal/types/msgs_test.go @@ -75,7 +75,7 @@ func TestMsgCreatePost_ValidateBasic(t *testing.T) { error: sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "Invalid creator address: "), }, { - name: "Empty message returns error", + name: "Empty message returns error if medias are empty", msg: types.NewMsgCreatePost( "", types.PostID(0), @@ -84,7 +84,7 @@ func TestMsgCreatePost_ValidateBasic(t *testing.T) { map[string]string{}, creator, date, - msgCreatePost.Medias, + nil, msgCreatePost.PollData, ), error: sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Post message cannot be empty nor blank"), From 79939ccf1a7631775306f1fc0a3b870da1d7ebcb Mon Sep 17 00:00:00 2001 From: Bragaz Date: Fri, 6 Mar 2020 16:34:51 +0100 Subject: [PATCH 2/7] updated CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d5d0e1acf..568f1fed1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +#Version 0.4.0 +- Added the support for posting empty-message posts with medias (#110) + # Version 0.3.0 ## Changes - Implemented the support for media posts (#36) From 3bdc621af291fe4db3b0937ac43731a974b5a5c1 Mon Sep 17 00:00:00 2001 From: Bragaz Date: Fri, 6 Mar 2020 16:46:49 +0100 Subject: [PATCH 3/7] edited cli medias test with empty message --- cli_test/cli_posts_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli_test/cli_posts_test.go b/cli_test/cli_posts_test.go index c9b6cd76a5..0595531d4b 100644 --- a/cli_test/cli_posts_test.go +++ b/cli_test/cli_posts_test.go @@ -78,7 +78,7 @@ func TestDesmosCLIPostsCreateWithMedias(t *testing.T) { // Later usage variables subspace := "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e" - message := "message" + message := "" fooAcc := f.QueryAccount(fooAddr) startTokens := sdk.TokensFromConsensusPower(140) require.Equal(t, startTokens, fooAcc.GetCoins().AmountOf(denom)) From 8248dfeba489481328e38eb36955e8d9eef92fe7 Mon Sep 17 00:00:00 2001 From: Bragaz Date: Mon, 9 Mar 2020 18:37:41 +0100 Subject: [PATCH 4/7] updated msg tests with all cases for medias --- x/posts/internal/types/msgs.go | 2 +- x/posts/internal/types/msgs_test.go | 49 +++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/x/posts/internal/types/msgs.go b/x/posts/internal/types/msgs.go index a7ec4d0ff9..88d99e6805 100644 --- a/x/posts/internal/types/msgs.go +++ b/x/posts/internal/types/msgs.go @@ -57,7 +57,7 @@ func (msg MsgCreatePost) ValidateBasic() error { } if len(strings.TrimSpace(msg.Message)) == 0 && len(msg.Medias) == 0 { - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Post message cannot be empty nor blank") + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Post message cannot be empty nor blank when there are no medias") } if len(msg.Message) > MaxPostMessageLength { diff --git a/x/posts/internal/types/msgs_test.go b/x/posts/internal/types/msgs_test.go index 946107079d..c6df128e87 100644 --- a/x/posts/internal/types/msgs_test.go +++ b/x/posts/internal/types/msgs_test.go @@ -75,7 +75,7 @@ func TestMsgCreatePost_ValidateBasic(t *testing.T) { error: sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "Invalid creator address: "), }, { - name: "Empty message returns error if medias are empty", + name: "Empty message returns error if medias and message are empty", msg: types.NewMsgCreatePost( "", types.PostID(0), @@ -87,7 +87,52 @@ func TestMsgCreatePost_ValidateBasic(t *testing.T) { nil, msgCreatePost.PollData, ), - error: sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Post message cannot be empty nor blank"), + error: sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Post message cannot be empty nor blank when there are no medias"), + }, + { + name: "Non-empty message returns nil if medias are empty", + msg: types.NewMsgCreatePost( + "message", + types.PostID(0), + false, + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + map[string]string{}, + creator, + date, + nil, + msgCreatePost.PollData, + ), + error: nil, + }, + { + name: "Non-empty message returns nil if medias aren't empty", + msg: types.NewMsgCreatePost( + "message", + types.PostID(0), + false, + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + map[string]string{}, + creator, + date, + msgCreatePost.Medias, + msgCreatePost.PollData, + ), + error: nil, + }, + { + name: "Empty message returns nil if medias aren't empty", + msg: types.NewMsgCreatePost( + "", + types.PostID(0), + false, + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + map[string]string{}, + creator, + date, + msgCreatePost.Medias, + msgCreatePost.PollData, + ), + error: nil, }, { name: "Very long message returns error", From 74108a525d922081acd42d2ef2a7ef742385ddc3 Mon Sep 17 00:00:00 2001 From: Bragaz Date: Mon, 9 Mar 2020 19:02:48 +0100 Subject: [PATCH 5/7] updated validate function and related tests --- x/posts/internal/types/post.go | 4 ++-- x/posts/internal/types/post_test.go | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/x/posts/internal/types/post.go b/x/posts/internal/types/post.go index ea32803348..08b2b3d73c 100644 --- a/x/posts/internal/types/post.go +++ b/x/posts/internal/types/post.go @@ -170,8 +170,8 @@ func (p Post) Validate() error { return fmt.Errorf("invalid post owner: %s", p.Creator) } - if len(strings.TrimSpace(p.Message)) == 0 { - return fmt.Errorf("post message must be non empty and non blank") + if len(strings.TrimSpace(p.Message)) == 0 && len(p.Medias) == 0 { + return fmt.Errorf("post message cannot be empty nor blank when there are no medias") } if len(p.Message) > MaxPostMessageLength { diff --git a/x/posts/internal/types/post_test.go b/x/posts/internal/types/post_test.go index b5337d8e54..3f9b8eec66 100644 --- a/x/posts/internal/types/post_test.go +++ b/x/posts/internal/types/post_test.go @@ -255,12 +255,12 @@ func TestPost_Validate(t *testing.T) { expError: "invalid post owner: ", }, { - post: types.NewPost(types.PostID(1), types.PostID(0), "", true, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", map[string]string{}, date, owner).WithMedias(medias).WithPollData(pollData), - expError: "post message must be non empty and non blank", + post: types.NewPost(types.PostID(1), types.PostID(0), "", true, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", map[string]string{}, date, owner).WithPollData(pollData), + expError: "post message cannot be empty nor blank when there are no medias", }, { - post: types.NewPost(types.PostID(1), types.PostID(0), " ", true, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", map[string]string{}, date, owner).WithMedias(medias).WithPollData(pollData), - expError: "post message must be non empty and non blank", + post: types.NewPost(types.PostID(1), types.PostID(0), " ", true, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", map[string]string{}, date, owner).WithPollData(pollData), + expError: "post message cannot be empty nor blank when there are no medias", }, { post: types.NewPost(types.PostID(1), types.PostID(0), "Message", true, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", map[string]string{}, time.Time{}, owner).WithMedias(medias).WithPollData(pollData), From cd77c5963c34cb71febf7ded027b147c2f09b495 Mon Sep 17 00:00:00 2001 From: Bragaz Date: Tue, 10 Mar 2020 11:05:21 +0100 Subject: [PATCH 6/7] added missing cli tests for post with medias --- cli_test/cli_posts_test.go | 115 ++++++++++++++++++++++++++++++++++++- docker-compose.yml | 3 +- 2 files changed, 115 insertions(+), 3 deletions(-) diff --git a/cli_test/cli_posts_test.go b/cli_test/cli_posts_test.go index 0595531d4b..f35986ee70 100644 --- a/cli_test/cli_posts_test.go +++ b/cli_test/cli_posts_test.go @@ -65,7 +65,7 @@ func TestDesmosCLIPostsCreateNoMediasNoPollData(t *testing.T) { f.Cleanup() } -func TestDesmosCLIPostsCreateWithMedias(t *testing.T) { +func TestDesmosCLIPostsCreateWithMediasAndEmptyMessage(t *testing.T) { t.Parallel() f := InitFixtures(t) @@ -126,6 +126,119 @@ func TestDesmosCLIPostsCreateWithMedias(t *testing.T) { f.Cleanup() } +func TestDesmosCLIPostsCreateWithMediasAndNonEmptyMessage(t *testing.T) { + t.Parallel() + f := InitFixtures(t) + + // Start Desmosd server + proc := f.GDStart() + defer proc.Stop(false) + + // Save key addresses for later use + fooAddr := f.KeyAddress(keyFoo) + + // Later usage variables + subspace := "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e" + message := "message" + fooAcc := f.QueryAccount(fooAddr) + startTokens := sdk.TokensFromConsensusPower(140) + require.Equal(t, startTokens, fooAcc.GetCoins().AmountOf(denom)) + + // Create a post + success, _, sterr := f.TxPostsCreate(subspace, message, true, fooAddr, "-y", + "--media https://example.com/media1,text/plain", + "--media https://example.com/media2,application/json") + require.True(t, success) + require.Empty(t, sterr) + tests.WaitForNextNBlocksTM(1, f.Port) + + // Make sure the post is saved + storedPosts := f.QueryPosts() + require.NotEmpty(t, storedPosts) + post := storedPosts[0] + require.Equal(t, posts.PostID(1), post.PostID) + require.Nil(t, post.PollData) + require.Len(t, post.Medias, 2) + require.Equal(t, post.Medias, posts.NewPostMedias( + posts.NewPostMedia("https://example.com/media1", "text/plain"), + posts.NewPostMedia("https://example.com/media2", "application/json"))) + + // Test --dry-run + success, _, _ = f.TxPostsCreate(subspace, message, true, fooAddr, "--dry-run", + "--media https://second.example.com/media1,text/plain", + "--media https://second.example.com/media2,application/json") + require.True(t, success) + + // Test --generate-only + success, stdout, stderr := f.TxPostsCreate(subspace, message, true, fooAddr, "--generate-only", + "--media https://third.example.com/media1,text/plain", + "--media https://third.example.com/media2,application/json") + require.Empty(t, stderr) + require.True(t, success) + msg := unmarshalStdTx(f.T, stdout) + require.NotZero(t, msg.Fee.Gas) + require.Len(t, msg.Msgs, 1) + require.Len(t, msg.GetSignatures(), 0) + + // Check state didn't change + storedPosts = f.QueryPosts() + require.Len(t, storedPosts, 1) + + f.Cleanup() +} + +func TestDesmosCLIPostsCreateWithNoMediasAndNonEmptyMessage(t *testing.T) { + t.Parallel() + f := InitFixtures(t) + + // Start Desmosd server + proc := f.GDStart() + defer proc.Stop(false) + + // Save key addresses for later use + fooAddr := f.KeyAddress(keyFoo) + + // Later usage variables + subspace := "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e" + message := "message" + fooAcc := f.QueryAccount(fooAddr) + startTokens := sdk.TokensFromConsensusPower(140) + require.Equal(t, startTokens, fooAcc.GetCoins().AmountOf(denom)) + + // Create a post + success, _, sterr := f.TxPostsCreate(subspace, message, true, fooAddr, "-y") + require.True(t, success) + require.Empty(t, sterr) + tests.WaitForNextNBlocksTM(1, f.Port) + + // Make sure the post is saved + storedPosts := f.QueryPosts() + require.NotEmpty(t, storedPosts) + post := storedPosts[0] + require.Equal(t, posts.PostID(1), post.PostID) + require.Nil(t, post.PollData) + require.Len(t, post.Medias, 0) + + // Test --dry-run + success, _, _ = f.TxPostsCreate(subspace, message, true, fooAddr, "--dry-run") + require.True(t, success) + + // Test --generate-only + success, stdout, stderr := f.TxPostsCreate(subspace, message, true, fooAddr, "--generate-only") + require.Empty(t, stderr) + require.True(t, success) + msg := unmarshalStdTx(f.T, stdout) + require.NotZero(t, msg.Fee.Gas) + require.Len(t, msg.Msgs, 1) + require.Len(t, msg.GetSignatures(), 0) + + // Check state didn't change + storedPosts = f.QueryPosts() + require.Len(t, storedPosts, 1) + + f.Cleanup() +} + func TestDesmosCLIPostsCreateWithPoll(t *testing.T) { t.Parallel() f := InitFixtures(t) diff --git a/docker-compose.yml b/docker-compose.yml index cfa01a076f..2e26e5da7f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -71,5 +71,4 @@ networks: ipam: driver: default config: - - - subnet: 192.168.10.0/16 + - subnet: 192.168.10.0/16 From dfa4505534a5730475e01ab82c0fb9348ac0de4b Mon Sep 17 00:00:00 2001 From: Bragaz Date: Wed, 11 Mar 2020 17:52:45 +0100 Subject: [PATCH 7/7] fixed last suggestions --- x/posts/internal/types/msgs.go | 2 +- x/posts/internal/types/msgs_test.go | 8 ++++---- x/posts/internal/types/post.go | 2 +- x/posts/internal/types/post_test.go | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/x/posts/internal/types/msgs.go b/x/posts/internal/types/msgs.go index 88d99e6805..b0f4ab92a7 100644 --- a/x/posts/internal/types/msgs.go +++ b/x/posts/internal/types/msgs.go @@ -57,7 +57,7 @@ func (msg MsgCreatePost) ValidateBasic() error { } if len(strings.TrimSpace(msg.Message)) == 0 && len(msg.Medias) == 0 { - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Post message cannot be empty nor blank when there are no medias") + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Post message or medias are required and cannot be both blank or empty") } if len(msg.Message) > MaxPostMessageLength { diff --git a/x/posts/internal/types/msgs_test.go b/x/posts/internal/types/msgs_test.go index c6df128e87..910be3b9e4 100644 --- a/x/posts/internal/types/msgs_test.go +++ b/x/posts/internal/types/msgs_test.go @@ -87,10 +87,10 @@ func TestMsgCreatePost_ValidateBasic(t *testing.T) { nil, msgCreatePost.PollData, ), - error: sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Post message cannot be empty nor blank when there are no medias"), + error: sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Post message or medias are required and cannot be both blank or empty"), }, { - name: "Non-empty message returns nil if medias are empty", + name: "Non-empty message returns no error if medias are empty", msg: types.NewMsgCreatePost( "message", types.PostID(0), @@ -105,7 +105,7 @@ func TestMsgCreatePost_ValidateBasic(t *testing.T) { error: nil, }, { - name: "Non-empty message returns nil if medias aren't empty", + name: "Non-empty message returns no error if medias aren't empty", msg: types.NewMsgCreatePost( "message", types.PostID(0), @@ -120,7 +120,7 @@ func TestMsgCreatePost_ValidateBasic(t *testing.T) { error: nil, }, { - name: "Empty message returns nil if medias aren't empty", + name: "Empty message returns no error if medias aren't empty", msg: types.NewMsgCreatePost( "", types.PostID(0), diff --git a/x/posts/internal/types/post.go b/x/posts/internal/types/post.go index 08b2b3d73c..01de86b0cd 100644 --- a/x/posts/internal/types/post.go +++ b/x/posts/internal/types/post.go @@ -171,7 +171,7 @@ func (p Post) Validate() error { } if len(strings.TrimSpace(p.Message)) == 0 && len(p.Medias) == 0 { - return fmt.Errorf("post message cannot be empty nor blank when there are no medias") + return fmt.Errorf("post message or medias required, they cannot be both empty") } if len(p.Message) > MaxPostMessageLength { diff --git a/x/posts/internal/types/post_test.go b/x/posts/internal/types/post_test.go index 3f9b8eec66..f2cb357c22 100644 --- a/x/posts/internal/types/post_test.go +++ b/x/posts/internal/types/post_test.go @@ -256,11 +256,11 @@ func TestPost_Validate(t *testing.T) { }, { post: types.NewPost(types.PostID(1), types.PostID(0), "", true, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", map[string]string{}, date, owner).WithPollData(pollData), - expError: "post message cannot be empty nor blank when there are no medias", + expError: "post message or medias required, they cannot be both empty", }, { post: types.NewPost(types.PostID(1), types.PostID(0), " ", true, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", map[string]string{}, date, owner).WithPollData(pollData), - expError: "post message cannot be empty nor blank when there are no medias", + expError: "post message or medias required, they cannot be both empty", }, { post: types.NewPost(types.PostID(1), types.PostID(0), "Message", true, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", map[string]string{}, time.Time{}, owner).WithMedias(medias).WithPollData(pollData),