Skip to content

Commit f478ffe

Browse files
Add Membership status and type (#29)
Add Membership status and type fields. Now Membership has dedicated struct ChatMembershipData - the same as User and Channel. Fix other failing unit tests. Fix == and != String operators to return correct values when compared strings are invalid.
1 parent 96e063e commit f478ffe

14 files changed

+131
-63
lines changed

include/pubnub_chat/membership.hpp

+11
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ namespace Pubnub
1919
{
2020
class Message;
2121

22+
struct ChatMembershipData
23+
{
24+
Pubnub::String custom_data_json = "";
25+
Pubnub::String status = "";
26+
Pubnub::String type = "";
27+
};
28+
2229
PN_CHAT_EXPORT class Membership
2330
{
2431
public:
@@ -30,9 +37,13 @@ namespace Pubnub
3037

3138
PN_CHAT_EXPORT Pubnub::Membership& operator =(const Pubnub::Membership& other);
3239

40+
[[deprecated("Replaced by membership_data() which contains more membership information")]]
3341
PN_CHAT_EXPORT Pubnub::String custom_data() const;
42+
PN_CHAT_EXPORT Pubnub::ChatMembershipData membership_data() const;
3443

44+
//TODO:: Mark as deprecated??
3545
PN_CHAT_EXPORT Pubnub::Membership update(const Pubnub::String& custom_object_json) const;
46+
PN_CHAT_EXPORT Pubnub::Membership update(const Pubnub::ChatMembershipData& membership_data) const;
3647
PN_CHAT_EXPORT Pubnub::String last_read_message_timetoken() const;
3748
PN_CHAT_EXPORT Pubnub::Membership set_last_read_message_timetoken(const Pubnub::String& timetoken) const;
3849
PN_CHAT_EXPORT Pubnub::Membership set_last_read_message(const Pubnub::Message& message) const;

src/application/callback_service.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -579,8 +579,8 @@ CCoreCallbackData CallbackService::to_c_memberships_updates_callback(const std::
579579
custom_field
580580
);
581581

582-
MembershipEntity stream_membership_entity = MembershipDAO(stream_membership->custom_data()).to_entity();
583-
MembershipEntity membership_entity = MembershipDAO(membership_obj.custom_data()).to_entity();
582+
MembershipEntity stream_membership_entity = MembershipDAO(stream_membership->membership_data()).to_entity();
583+
MembershipEntity membership_entity = MembershipDAO(membership_obj.membership_data()).to_entity();
584584
auto updated_membership = chat->membership_service->create_membership_object(stream_membership->user, stream_membership->channel, MembershipEntity::from_base_and_updated_membership(stream_membership_entity, membership_entity));
585585

586586
std::vector<Pubnub::Membership> updated_memberships;

src/application/channel_service.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ std::tuple<Channel, Membership, std::vector<Membership>> ChannelService::create_
6060
auto pubnub_handle = this->pubnub->lock();
6161

6262
//TODO: Add filter when it will be supported in C-Core
63-
String include_string = "custom,channel,totalCount,customChannel";
63+
String include_string = "custom,channel,totalCount,channel.custom";
6464
user_id = pubnub_handle->get_user_id();
6565
pubnub_handle->set_memberships(pubnub_handle->get_user_id(), create_set_memberships_object(final_channel_id), include_string);
6666
}
@@ -90,7 +90,7 @@ std::tuple<Channel, Membership, std::vector<Membership>> ChannelService::create_
9090
user_id = pubnub_handle->get_user_id();
9191

9292
//TODO: Add filter when it will be supported in C-Core
93-
String include_string = "custom,channel,totalCount,customChannel";
93+
String include_string = "custom,channel,totalCount,custom.channel";
9494
String memberships_response = pubnub_handle->set_memberships(user_id, create_set_memberships_object(final_channel_id), include_string);
9595
}
9696

src/application/dao/membership_dao.cpp

+17-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#include "membership_dao.hpp"
22
#include "domain/membership_entity.hpp"
33

4-
MembershipDAO::MembershipDAO(const Pubnub::String& custom_data) :
5-
entity({custom_data})
4+
MembershipDAO::MembershipDAO(const Pubnub::ChatMembershipData& membership_data) :
5+
entity(entity_from_membership_data(membership_data))
66
{}
77

88
MembershipDAO::MembershipDAO(const MembershipEntity& entity) :
@@ -17,7 +17,20 @@ const MembershipEntity& MembershipDAO::get_entity() const {
1717
return this->entity;
1818
}
1919

20-
Pubnub::String MembershipDAO::to_custom_data() const {
21-
return this->entity.custom_field;
20+
Pubnub::ChatMembershipData MembershipDAO::to_membership_data() const {
21+
Pubnub::ChatMembershipData membership_data;
22+
membership_data.custom_data_json = this->entity.custom_field;
23+
membership_data.status = this->entity.status;
24+
membership_data.type = this->entity.type;
25+
26+
return membership_data;
2227
}
2328

29+
MembershipEntity MembershipDAO::entity_from_membership_data(const Pubnub::ChatMembershipData& membership_data){
30+
MembershipEntity entity;
31+
entity.custom_field = membership_data.custom_data_json;
32+
entity.status = membership_data.status;
33+
entity.type = membership_data.type;
34+
35+
return entity;
36+
}

src/application/dao/membership_dao.hpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@
66

77
class MembershipDAO {
88
public:
9-
MembershipDAO(const Pubnub::String& custom_data);
9+
MembershipDAO(const Pubnub::ChatMembershipData& membership_data);
1010
MembershipDAO(const MembershipEntity& entity);
1111
~MembershipDAO() = default;
1212

13-
Pubnub::String to_custom_data() const;
13+
Pubnub::ChatMembershipData to_membership_data() const;
1414
const MembershipEntity& get_entity() const;
1515
MembershipEntity to_entity() const;
1616

1717
private:
18+
static MembershipEntity entity_from_membership_data(const Pubnub::ChatMembershipData& membership_data);
19+
1820
MembershipEntity entity;
1921
};
2022

src/application/membership_service.cpp

+16-23
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ std::tuple<std::vector<Pubnub::Membership>, Pubnub::Page, int, Pubnub::String> M
3434
throw std::invalid_argument("can't get members, limit has to be within 0 - " + std::to_string(PN_MAX_LIMIT) + " range");
3535
}
3636

37-
String include_string = "custom,channel,totalCount,customChannel";
37+
String include_string = "custom,channel,totalCount,channel.custom,status,type";
3838

3939
auto get_channel_members_response = [this, channel_id, include_string, limit, filter, sort, page] {
4040
auto pubnub_handle = this->pubnub->lock();
@@ -81,7 +81,7 @@ std::tuple<std::vector<Pubnub::Membership>, Pubnub::Page, int, Pubnub::String> M
8181
throw std::invalid_argument("can't get memberships, limit has to be within 0 - " + std::to_string(PN_MAX_LIMIT) + " range");
8282
}
8383

84-
String include_string = "totalCount,custom,channel,customChannel,channelType,status,channelStatus";
84+
String include_string = "totalCount,custom,channel,channel.custom,type,channel.type,status,channel.status";
8585

8686
auto get_memberships_response = [this, user_id, include_string, filter, sort, limit, page] {
8787
auto pubnub_handle = this->pubnub->lock();
@@ -138,7 +138,7 @@ Membership MembershipService::invite_to_channel(const String& channel_id, const
138138
return members[0];
139139
}
140140

141-
String include_string = "custom,channel,totalCount,customChannel";
141+
String include_string = "custom,channel,totalCount,channel.custom,status,type";
142142
String set_memeberships_obj = create_set_memberships_object(channel_id, "");
143143

144144
auto user_id = user.user_id();
@@ -181,7 +181,7 @@ std::vector<Membership> MembershipService::invite_multiple_to_channel(const Stri
181181
}
182182
}
183183

184-
String include_string = "custom,channel,totalCount,customChannel";
184+
String include_string = "custom,channel,totalCount,channel.custom,status,type";
185185
String set_memebers_obj = create_set_members_object(users_ids, "");
186186

187187
auto set_members_response = [this, channel_id, set_memebers_obj, include_string, filter] {
@@ -215,9 +215,11 @@ std::vector<Membership> MembershipService::invite_multiple_to_channel(const Stri
215215
return invitees_memberships;
216216
}
217217

218-
Membership MembershipService::update(const User& user, const Channel& channel, const String& custom_object_json) const {
218+
Membership MembershipService::update(const User& user, const Channel& channel, MembershipDAO membership_data) const {
219+
auto entity = membership_data.to_entity();
220+
219221
String custom_object_json_string;
220-
custom_object_json.empty() ? custom_object_json_string = "{}" : custom_object_json_string = custom_object_json;
222+
entity.custom_field.empty() ? custom_object_json_string = "{}" : custom_object_json_string = entity.custom_field;
221223

222224
json response_json = json::parse(custom_object_json_string);
223225

@@ -226,18 +228,16 @@ Membership MembershipService::update(const User& user, const Channel& channel, c
226228
throw std::invalid_argument("Can't update membership, custom_object_json is not valid json object");
227229
}
228230

229-
String set_memberships_string = String("[{\"channel\": {\"id\": \"") + channel.channel_id() + String("\"}, \"custom\": ") + custom_object_json_string + String("}]");
230-
231231
{
232232
auto pubnub_handle = pubnub->lock();
233-
pubnub_handle->set_memberships(user.user_id(), set_memberships_string);
233+
pubnub_handle->set_memberships(user.user_id(), entity.get_set_memberships_json_string(channel.channel_id()));
234234
}
235235

236-
return create_membership_object(user, channel, create_domain_membership(custom_object_json_string));
236+
return create_membership_object(user, channel, entity);
237237
}
238238

239239
String MembershipService::last_read_message_timetoken(const Membership& membership) const {
240-
String custom_data = membership.custom_data();
240+
String custom_data = membership.membership_data().custom_data_json;
241241
if(custom_data.empty())
242242
{
243243
return String();
@@ -250,7 +250,7 @@ String MembershipService::last_read_message_timetoken(const Membership& membersh
250250

251251
Pubnub::Membership MembershipService::set_last_read_message_timetoken(const Membership& membership, const String& timetoken) const {
252252

253-
String custom_data = membership.custom_data().empty() ? "{}" : membership.custom_data();
253+
String custom_data = membership.membership_data().custom_data_json.empty() ? "{}" : membership.membership_data().custom_data_json;
254254

255255
Json custom_data_json = Json::parse(custom_data);
256256
custom_data_json.insert_or_update("lastReadMessageTimetoken", timetoken);
@@ -360,7 +360,7 @@ std::tuple<Pubnub::Page, int, int, std::vector<Pubnub::Membership>> MembershipSe
360360
{
361361
relevant_channel_ids.push_back(membership.channel.channel_id());
362362

363-
String custom_object_json_string = membership.custom_data().empty() ? String("{}") : membership.custom_data();
363+
String custom_object_json_string = membership.membership_data().custom_data_json.empty() ? String("{}") : membership.membership_data().custom_data_json;
364364
json custom_object_json = json::parse(custom_object_json_string);
365365
custom_object_json["lastReadMessageTimetoken"] = now_timetoken.c_str();
366366

@@ -380,7 +380,7 @@ std::tuple<Pubnub::Page, int, int, std::vector<Pubnub::Membership>> MembershipSe
380380

381381
auto memberships_response = [this, current_user, set_memberships_string] {
382382
auto pubnub_handle = pubnub->lock();
383-
String include_string = "custom,channel,totalCount,customChannel";
383+
String include_string = "custom,channel,totalCount,custom.channel,status,type";
384384
return pubnub_handle->set_memberships(current_user.user_id(), set_memberships_string, include_string);
385385
}();
386386

@@ -479,16 +479,9 @@ Membership MembershipService::create_membership_object(const User& user, const C
479479
throw std::runtime_error("Can't create membership, chat service pointer is invalid");
480480
}
481481

482-
MembershipEntity MembershipService::create_domain_membership(const String& custom_object_json) const {
483-
MembershipEntity new_membership_entity;
484-
new_membership_entity.custom_field = custom_object_json;
485-
return new_membership_entity;
486-
487-
}
488-
489482
Pubnub::Membership MembershipService::update_membership_with_base(const Pubnub::Membership& membership, const Pubnub::Membership& base_membership) const {
490-
MembershipEntity base_entity = MembershipDAO(base_membership.custom_data()).to_entity();
491-
MembershipEntity membership_entity = MembershipDAO(membership.custom_data()).to_entity();
483+
MembershipEntity base_entity = MembershipDAO(base_membership.membership_data()).to_entity();
484+
MembershipEntity membership_entity = MembershipDAO(membership.membership_data()).to_entity();
492485

493486
return create_membership_object(
494487
base_membership.user,

src/application/membership_service.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class MembershipService : public std::enable_shared_from_this<MembershipService>
2828
Pubnub::Membership invite_to_channel(const Pubnub::String& channel_id, const ChannelDAO& channel_data, const Pubnub::User& user) const;
2929
std::vector<Pubnub::Membership> invite_multiple_to_channel(const Pubnub::String& channel_id, const ChannelDAO& channel_data, const std::vector<Pubnub::User>& users) const;
3030

31-
Pubnub::Membership update(const Pubnub::User& user, const Pubnub::Channel& channel, const Pubnub::String& custom_object_json) const;
31+
Pubnub::Membership update(const Pubnub::User& user, const Pubnub::Channel& channel, MembershipDAO membership_data) const;
3232
Pubnub::String last_read_message_timetoken(const Pubnub::Membership& membership) const;
3333
Pubnub::Membership set_last_read_message_timetoken(const Pubnub::Membership& membership, const Pubnub::String& timetoken) const;
3434
int get_unread_messages_count_one_channel(const Pubnub::Membership& membership) const;

src/domain/membership_entity.cpp

+32-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,45 @@
11
#include "membership_entity.hpp"
2+
#include "domain/json.hpp"
3+
4+
Pubnub::String MembershipEntity::get_set_memberships_json_string(Pubnub::String channel_id){
5+
Json channel_json;
6+
channel_json.insert_or_update("id", channel_id);
7+
8+
Json set_memberships_json;
9+
10+
set_memberships_json.insert_or_update("channel", channel_json);
11+
12+
if(!custom_field.empty()) {
13+
Json custom_json = Json::parse(custom_field);
14+
set_memberships_json.insert_or_update("custom", custom_json);
15+
}
16+
else
17+
{
18+
set_memberships_json.insert_or_update("custom", "{}");
19+
}
20+
if(!status.empty()) {
21+
set_memberships_json.insert_or_update("status", status);
22+
}
23+
if(!type.empty()) {
24+
set_memberships_json.insert_or_update("type", type);
25+
}
26+
27+
return Pubnub::String("[" + set_memberships_json.dump() + "]");
28+
}
229

330
MembershipEntity MembershipEntity::from_json(Json membership_json) {
431
return MembershipEntity{
5-
membership_json.contains("custom") ? membership_json["custom"].dump() : Pubnub::String("")
32+
membership_json.contains("custom") ? membership_json["custom"].dump() : Pubnub::String(""),
33+
membership_json.get_string("status").value_or(Pubnub::String("")),
34+
membership_json.get_string("type").value_or(Pubnub::String(""))
635
};
736
}
837

938
MembershipEntity MembershipEntity::from_base_and_updated_membership(MembershipEntity base_membership, MembershipEntity updated_membership)
1039
{
1140
MembershipEntity new_entity;
1241
new_entity.custom_field = updated_membership.custom_field.empty() ? base_membership.custom_field : updated_membership.custom_field;
42+
new_entity.status = updated_membership.status.empty() ? base_membership.status : updated_membership.status;
43+
new_entity.type = updated_membership.type.empty() ? base_membership.type : updated_membership.type;
1344
return new_entity;
1445
}

src/domain/membership_entity.hpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@
66
#include "membership.hpp"
77

88
struct MembershipEntity {
9-
Pubnub::String custom_field;
9+
Pubnub::String custom_field = "";
10+
Pubnub::String status = "";
11+
Pubnub::String type = "";
1012

11-
static MembershipEntity from_json(Json membership_json);
13+
Pubnub::String get_set_memberships_json_string(Pubnub::String channel_id);
1214

15+
static MembershipEntity from_json(Json membership_json);
1316
static MembershipEntity from_base_and_updated_membership(MembershipEntity base_membership, MembershipEntity updated_membership);
17+
1418
};
1519

1620
#endif // PN_CHAT_MEMBERSHIP_ENTITY_HPP

src/presentation/membership.cpp

+12-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ user(other.user),
1919
channel(other.channel),
2020
chat_service(other.chat_service),
2121
membership_service(other.membership_service),
22-
data(std::make_unique<MembershipDAO>(other.data->to_custom_data()))
22+
data(std::make_unique<MembershipDAO>(other.data->to_membership_data()))
2323
{}
2424

2525
Membership& Membership::operator =(const Membership& other)
@@ -30,7 +30,7 @@ Membership& Membership::operator =(const Membership& other)
3030
}
3131
this->user = other.user;
3232
this->channel = other.channel;
33-
this->data = std::make_unique<::MembershipDAO>(other.data->to_custom_data());
33+
this->data = std::make_unique<::MembershipDAO>(other.data->to_membership_data());
3434
this->chat_service = other.chat_service;
3535
this->membership_service = other.membership_service;
3636

@@ -40,11 +40,19 @@ Membership& Membership::operator =(const Membership& other)
4040
Membership::~Membership() = default;
4141

4242
String Membership::custom_data() const {
43-
return this->data->to_custom_data();
43+
return this->data->to_membership_data().custom_data_json;
44+
}
45+
46+
ChatMembershipData Membership::membership_data() const {
47+
return this->data->to_membership_data();
4448
}
4549

4650
Membership Membership::update(const String& custom_object_json) const {
47-
return this->membership_service->update(user, channel, custom_object_json);
51+
return this->membership_service->update(user, channel, MembershipDAO(ChatMembershipData{custom_object_json, "", ""}));
52+
}
53+
54+
Membership Membership::update(const Pubnub::ChatMembershipData& membership_data) const {
55+
return this->membership_service->update(user, channel, MembershipDAO(membership_data));
4856
}
4957

5058
String Membership::last_read_message_timetoken() const {

src/string.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,10 @@ String operator+(const String& lhs, const String& rhs) {
425425
}
426426

427427
bool operator==(const String& lhs, const String& rhs) {
428+
if(lhs.c_str() == nullptr && rhs.c_str() == nullptr) {
429+
return true;
430+
}
431+
428432
if(lhs.c_str() == nullptr || rhs.c_str() == nullptr) {
429433
return false;
430434
}
@@ -433,6 +437,13 @@ bool operator==(const String& lhs, const String& rhs) {
433437
}
434438

435439
bool operator!=(const String& lhs, const String& rhs) {
440+
if(lhs.c_str() == nullptr && rhs.c_str() == nullptr) {
441+
return false;
442+
}
443+
444+
if(lhs.c_str() == nullptr || rhs.c_str() == nullptr) {
445+
return true;
446+
}
436447
return strcmp(lhs.c_str(), rhs.c_str()) != 0;
437448
}
438449

test/unit/membership_entity_unit.cpp

+9-3
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,25 @@ BeforeEach(MembershipEntities) {/* no setup needed */}
1010
AfterEach(MembershipEntities) {/* no cleanup needed */}
1111

1212
Ensure(MembershipEntities, should_be_parsed_from_json) {
13-
auto result = MembershipEntity::from_json(Json::parse("{\"custom\":\"data\"}"));
13+
auto result = MembershipEntity::from_json(Json::parse("{\"custom\":\"data\",\"status\":\"status\",\"type\":\"type\"}"));
1414

1515
assert_string_equal(result.custom_field.c_str(), "\"data\"");
16+
assert_string_equal(result.status.c_str(), "status");
17+
assert_string_equal(result.type.c_str(), "type");
1618
}
1719

1820
Ensure(MembershipEntities, should_update) {
19-
MembershipEntity base {"base"};
20-
MembershipEntity update {"update"};
21+
MembershipEntity base {"base", "base_status", "base_type"};
22+
MembershipEntity update {"update", "update_status", "update_type"};
2123
MembershipEntity empty_update {""};
2224

2325
auto updated = MembershipEntity::from_base_and_updated_membership(base, update);
2426
auto empty_updated = MembershipEntity::from_base_and_updated_membership(base, empty_update);
2527

2628
assert_string_equal(updated.custom_field.c_str(), "update");
2729
assert_string_equal(empty_updated.custom_field.c_str(), "base");
30+
assert_string_equal(updated.status.c_str(), "update_status");
31+
assert_string_equal(empty_updated.status.c_str(), "base_status");
32+
assert_string_equal(updated.type.c_str(), "update_type");
33+
assert_string_equal(empty_updated.type.c_str(), "base_type");
2834
}

0 commit comments

Comments
 (0)