diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c
index 030557456e3c1f38e41427c399a439df85709c19..6979a608f1d133f68df5e0ffd69a2bfb18546166 100644
--- a/coreapi/callbacks.c
+++ b/coreapi/callbacks.c
@@ -948,6 +948,18 @@ static void on_expire(SalOp *op) {
 	} else if (linphone_event_get_subscription_state(lev) == LinphoneSubscriptionActive) {
 		linphone_event_set_state(lev, LinphoneSubscriptionExpiring);
 	}
+
+	void *user_data = linphone_event_get_user_data(lev);
+	const char *event_name = linphone_event_get_name(lev);
+	if (user_data && event_name && linphone_event_is_internal(lev) && strcmp(event_name, "presence") == 0) {
+		LinphoneCore *lc = (LinphoneCore *)op->getSal()->getUserPointer();
+		LinphoneAddress *identity_address = (LinphoneAddress *)user_data;
+		LinphoneAccount *account = linphone_core_find_account_by_identity_address(lc, identity_address);
+		if (account) {
+			lInfo() << "Presence publish about to expire, manually refreshing it for account [" << account << "]";
+			LinphonePrivate::Account::toCpp(account)->sendPublish();
+		}
+	}
 }
 
 static void on_notify_response(SalOp *op) {
diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c
index a80592af966906fa739a34ec050007c465b0052b..0f777c8fe7666983d4ee3f26bbd31572adcf5acd 100644
--- a/coreapi/linphonecore.c
+++ b/coreapi/linphonecore.c
@@ -5201,7 +5201,8 @@ int linphone_core_send_publish(LinphoneCore *lc, LinphonePresenceModel *presence
 	for (elem = linphone_core_get_account_list(lc); elem != NULL; elem = bctbx_list_next(elem)) {
 		LinphoneAccount *acc = (LinphoneAccount *)elem->data;
 		if (linphone_account_params_get_publish_enabled(linphone_account_get_params(acc))) {
-			Account::toCpp(acc)->sendPublish(presence);
+			Account::toCpp(acc)->setPresenceModel(presence);
+			Account::toCpp(acc)->sendPublish();
 		}
 	}
 	return 0;
@@ -9598,3 +9599,23 @@ void linphone_core_enable_empty_chatrooms_deletion(LinphoneCore *core, bool_t en
 	linphone_config_set_bool(core->config, "misc", "empty_chat_room_deletion", enable);
 	L_GET_CPP_PTR_FROM_C_OBJECT(core)->enableEmptyChatroomsDeletion(enable);
 }
+
+LinphoneAccount *linphone_core_find_account_by_identity_address(const LinphoneCore *core,
+                                                                const LinphoneAddress *identity_address) {
+	LinphoneAccount *found = NULL;
+	if (identity_address == NULL) return found;
+
+	bctbx_list_t *account_it;
+	for (account_it = (bctbx_list_t *)linphone_core_get_account_list(core); account_it != NULL;
+	     account_it = account_it->next) {
+		LinphoneAccount *account = (LinphoneAccount *)(account_it->data);
+		const LinphoneAccountParams *params = linphone_account_get_params(account);
+		const LinphoneAddress *address = linphone_account_params_get_identity_address(params);
+		if (linphone_address_weak_equal(address, identity_address)) {
+			found = account;
+			break;
+		}
+	}
+
+	return found;
+}
diff --git a/coreapi/presence.c b/coreapi/presence.c
index 8360afb3322e4b097342102a5d26d53d4ba86423..f43bbafbfb6f2a5c678aa5282530a54f94f1e388 100644
--- a/coreapi/presence.c
+++ b/coreapi/presence.c
@@ -758,6 +758,12 @@ linphone_presence_service_new(const char *id, LinphonePresenceBasicStatus basic_
 	return service;
 }
 
+void linphone_presence_service_set_timestamp(LinphonePresenceService *service, time_t timestamp) {
+	if (service) {
+		service->timestamp = timestamp;
+	}
+}
+
 char *linphone_presence_service_get_id(const LinphonePresenceService *service) {
 	if (service == NULL) return NULL;
 	return ms_strdup(service->id);
diff --git a/coreapi/private_functions.h b/coreapi/private_functions.h
index fb9e6468c6b77c3ac747ec2c47c4584c300074b1..357875b5950942144d3fe427c815378a787756ab 100644
--- a/coreapi/private_functions.h
+++ b/coreapi/private_functions.h
@@ -174,6 +174,8 @@ const LinphoneAuthInfo *_linphone_core_find_auth_info(LinphoneCore *lc,
                                                       const char *domain,
                                                       const char *algorithm,
                                                       bool_t ignore_realm);
+LinphoneAccount *linphone_core_find_account_by_identity_address(const LinphoneCore *core,
+                                                                const LinphoneAddress *identity_address);
 void linphone_auth_info_fill_belle_sip_event(const LinphoneAuthInfo *auth_info, belle_sip_auth_event *event);
 void linphone_core_fill_belle_sip_auth_event(LinphoneCore *lc,
                                              belle_sip_auth_event *event,
@@ -231,6 +233,7 @@ void linphone_friend_remove_incoming_subscription(LinphoneFriend *lf, LinphonePr
 const char *linphone_friend_phone_number_to_sip_uri(LinphoneFriend *lf, const char *phone_number);
 const char *linphone_friend_sip_uri_to_phone_number(LinphoneFriend *lf, const char *uri);
 void linphone_friend_clear_presence_models(LinphoneFriend *lf);
+void linphone_presence_service_set_timestamp(LinphonePresenceService *service, time_t timestamp);
 LinphoneFriend *linphone_friend_list_find_friend_by_inc_subscribe(const LinphoneFriendList *list,
                                                                   LinphonePrivate::SalOp *op);
 LinphoneFriend *linphone_friend_list_find_friend_by_out_subscribe(const LinphoneFriendList *list,
@@ -648,6 +651,7 @@ LinphoneEvent *_linphone_core_create_publish(
     LinphoneCore *lc, LinphoneAccount *account, const LinphoneAddress *resource, const char *event, int expires);
 void linphone_event_unpublish(LinphoneEvent *lev);
 void linphone_event_set_current_callbacks(LinphoneEvent *ev, LinphoneEventCbs *cbs);
+void linphone_event_set_manual_refresher_mode(LinphoneEvent *lev, bool_t manual);
 /**
  * Useful for out of dialog notify
  * */
diff --git a/coreapi/proxy.c b/coreapi/proxy.c
index f7e05030b3b20c0f4719800a35be0b91eea1fcbc..be508b46b85e877d2fe91b36a5174cc56569961e 100644
--- a/coreapi/proxy.c
+++ b/coreapi/proxy.c
@@ -524,7 +524,8 @@ void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, const char *realm
 }
 
 int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, LinphonePresenceModel *presence) {
-	return Account::toCpp(proxy->account)->sendPublish(presence);
+	Account::toCpp(proxy->account)->setPresenceModel(presence);
+	return Account::toCpp(proxy->account)->sendPublish();
 }
 
 void _linphone_proxy_config_unpublish(LinphoneProxyConfig *obj) {
diff --git a/src/account/account.cpp b/src/account/account.cpp
index 84dc5832e789cfedbad777711ff7a2e51bbae513..9b5274184145851de82da937f593fbb71ad9ff21 100644
--- a/src/account/account.cpp
+++ b/src/account/account.cpp
@@ -68,6 +68,7 @@ Account::~Account() {
 	if (mServiceRouteAddress) linphone_address_unref(mServiceRouteAddress);
 	if (mContactAddress) linphone_address_unref(mContactAddress);
 	if (mContactAddressWithoutParams) linphone_address_unref(mContactAddressWithoutParams);
+	if (mPresenceModel) linphone_presence_model_unref(mPresenceModel);
 
 	releaseOps();
 }
@@ -974,7 +975,10 @@ void Account::update() {
 		}
 	}
 	if (mSendPublish && (mState == LinphoneRegistrationOk || mState == LinphoneRegistrationCleared)) {
-		sendPublish(mCore->presence_model);
+		if (mPresenceModel == nullptr) {
+			setPresenceModel(mCore->presence_model);
+		}
+		sendPublish();
 		mSendPublish = false;
 	}
 }
@@ -1008,64 +1012,110 @@ shared_ptr<EventPublish> Account::createPublish(const char *event, int expires)
 	    Event::toCpp(_linphone_core_create_publish(mCore, this->toC(), NULL, event, expires))->getSharedFromThis());
 }
 
-int Account::sendPublish(LinphonePresenceModel *presence) {
-	int err = 0;
-	LinphoneAddress *presentity_address = NULL;
-	char *contact = NULL;
+void Account::setPresenceModel(LinphonePresenceModel *presence) {
+	if (mPresenceModel) {
+		linphone_presence_model_unref(mPresenceModel);
+		mPresenceModel = nullptr;
+	}
+	if (presence) mPresenceModel = linphone_presence_model_ref(presence);
+}
 
+int Account::sendPublish() {
+	if (mPresenceModel == nullptr) {
+		lError() << "No presence model has been set for this account, can't send the PUBLISH";
+		return -1;
+	}
+
+	int err = 0;
 	if (mState == LinphoneRegistrationOk || mState == LinphoneRegistrationCleared) {
-		LinphoneContent *content;
-		char *presence_body;
+		int publishExpires = mParams->getPublishExpires();
+
+		if (mPresencePublishEvent != nullptr) {
+			LinphonePublishState state = mPresencePublishEvent->getState();
+			if (state != LinphonePublishOk && state != LinphonePublishProgress) {
+				lInfo() << "Presence publish state is [" << linphone_publish_state_to_string(state)
+				        << "], destroying it and creating a new one instead";
+				mPresencePublishEvent->unref();
+				mPresencePublishEvent = nullptr;
+			}
+		}
+
 		if (mPresencePublishEvent == nullptr) {
-			mPresencePublishEvent = createPublish("presence", mParams->getPublishExpires());
+			mPresencePublishEvent = createPublish("presence", publishExpires);
 		}
+
 		mPresencePublishEvent->setInternal(true);
+		if (publishExpires != 1) {
+			// Force manual refresh mode so we can go through this method again
+			// when PUBLISH is about to expire, so we can update the presence model timestamp
+			mPresencePublishEvent->setManualRefresherMode(true);
+		}
+		mPresencePublishEvent->setUserData(mParams->getIdentityAddress());
+
+		LinphoneConfig *config = linphone_core_get_config(mCore);
+		if (linphone_config_get_bool(config, "sip", "update_presence_model_timestamp_before_publish_expires_refresh",
+		                             FALSE)) {
+			unsigned int nbServices = linphone_presence_model_get_nb_services(mPresenceModel);
+			if (nbServices > 0) {
+				LinphonePresenceService *latest_service =
+				    linphone_presence_model_get_nth_service(mPresenceModel, nbServices - 1);
+				linphone_presence_service_set_timestamp(latest_service, ms_time(NULL));
+			}
+		}
 
-		if (linphone_presence_model_get_presentity(presence) == NULL) {
-			lInfo() << "No presentity set for model [" << presence << "], using identity from account [" << this->toC()
-			        << "]";
-			linphone_presence_model_set_presentity(presence, mParams->getIdentityAddress());
+		if (linphone_presence_model_get_presentity(mPresenceModel) == NULL) {
+			lInfo() << "No presentity set for model [" << mPresenceModel << "], using identity from account ["
+			        << this->toC() << "]";
+			linphone_presence_model_set_presentity(mPresenceModel, mParams->getIdentityAddress());
 		}
 
-		if (!linphone_address_equal(linphone_presence_model_get_presentity(presence), mParams->getIdentityAddress())) {
-			lInfo() << "Presentity for model [" << presence << "] differ account [" << this->toC()
+		LinphoneAddress *presentity_address = NULL;
+		char *contact = NULL;
+		if (!linphone_address_equal(linphone_presence_model_get_presentity(mPresenceModel),
+		                            mParams->getIdentityAddress())) {
+			lInfo() << "Presentity for model [" << mPresenceModel << "] differ account [" << this->toC()
 			        << "], using account";
 			presentity_address =
-			    linphone_address_clone(linphone_presence_model_get_presentity(presence)); /*saved, just in case*/
-			if (linphone_presence_model_get_contact(presence)) {
-				contact = bctbx_strdup(linphone_presence_model_get_contact(presence));
+			    linphone_address_clone(linphone_presence_model_get_presentity(mPresenceModel)); /*saved, just in case*/
+			if (linphone_presence_model_get_contact(mPresenceModel)) {
+				contact = bctbx_strdup(linphone_presence_model_get_contact(mPresenceModel));
 			}
-			linphone_presence_model_set_presentity(presence, mParams->getIdentityAddress());
-			linphone_presence_model_set_contact(presence, NULL); /*it will be automatically computed*/
+			linphone_presence_model_set_presentity(mPresenceModel, mParams->getIdentityAddress());
+			linphone_presence_model_set_contact(mPresenceModel, NULL); /*it will be automatically computed*/
 		}
-		if (!(presence_body = linphone_presence_model_to_xml(presence))) {
-			lError() << "Cannot publish presence model [" << presence << "] for account [" << this->toC()
+
+		char *presence_body;
+		if (!(presence_body = linphone_presence_model_to_xml(mPresenceModel))) {
+			lError() << "Cannot publish presence model [" << mPresenceModel << "] for account [" << this->toC()
 			         << "] because of xml serialization error";
 			return -1;
 		}
 
-		content = linphone_content_new();
-		linphone_content_set_buffer(content, (const uint8_t *)presence_body, strlen(presence_body));
-		linphone_content_set_type(content, "application");
-		linphone_content_set_subtype(content, "pidf+xml");
 		if (!mSipEtag.empty()) {
 			mPresencePublishEvent->addCustomHeader("SIP-If-Match", mSipEtag);
 			mSipEtag = "";
 		}
+
+		LinphoneContent *content = linphone_content_new();
+		linphone_content_set_buffer(content, (const uint8_t *)presence_body, strlen(presence_body));
+		linphone_content_set_type(content, "application");
+		linphone_content_set_subtype(content, "pidf+xml");
+
 		err = mPresencePublishEvent->send(content);
 		linphone_content_unref(content);
 		ms_free(presence_body);
+
 		if (presentity_address) {
-			linphone_presence_model_set_presentity(presence, presentity_address);
+			linphone_presence_model_set_presentity(mPresenceModel, presentity_address);
 			linphone_address_unref(presentity_address);
 		}
 		if (contact) {
-			linphone_presence_model_set_contact(presence, contact);
+			linphone_presence_model_set_contact(mPresenceModel, contact);
 			bctbx_free(contact);
 		}
-
 	} else
 		mSendPublish = true; /*otherwise do not send publish if registration is in progress, this will be done later*/
+
 	return err;
 }
 
diff --git a/src/account/account.h b/src/account/account.h
index aea24718b47cd9130edc3f8b5405d3ce836a28a4..b70ac211487a81267c11a97fa5c5702694dc22b3 100644
--- a/src/account/account.h
+++ b/src/account/account.h
@@ -97,7 +97,8 @@ public:
 	bool check();
 	bool isAvpfEnabled() const;
 	int getUnreadChatMessageCount() const;
-	int sendPublish(LinphonePresenceModel *presence);
+	void setPresenceModel(LinphonePresenceModel *presence);
+	int sendPublish();
 	void apply(LinphoneCore *lc);
 	void notifyPublishStateChanged(LinphonePublishState state);
 	void pauseRegister();
@@ -173,6 +174,7 @@ private:
 	SalCustomHeader *mSentHeaders = nullptr;
 
 	std::shared_ptr<EventPublish> mPresencePublishEvent = nullptr;
+	LinphonePresenceModel *mPresenceModel = nullptr;
 
 	std::shared_ptr<Account> mDependency = nullptr;
 
@@ -196,4 +198,4 @@ private:
 
 LINPHONE_END_NAMESPACE
 
-#endif // ifndef _L_ACCOUNT_H_
+#endif // ifndef _L_ACCOUNT_H_
\ No newline at end of file
diff --git a/src/event/event.cpp b/src/event/event.cpp
index 1ebc477e8d13a2d2bbe7fd8de1767632470e269f..7e675e279be5775495a913b6141616303f69dae8 100644
--- a/src/event/event.cpp
+++ b/src/event/event.cpp
@@ -174,4 +174,8 @@ void Event::setUnrefWhenTerminated(bool unrefWhenTerminated) {
 	mUnrefWhenTerminated = unrefWhenTerminated;
 }
 
+void Event::setManualRefresherMode(bool manual) {
+	mOp->setManualRefresherMode(manual);
+}
+
 LINPHONE_END_NAMESPACE
\ No newline at end of file
diff --git a/src/event/event.h b/src/event/event.h
index cd5aea6097f599c73ed3f9f10afa51a3b76fd178..768f54895efdee5d45e3df71c24c047a576e48b5 100644
--- a/src/event/event.h
+++ b/src/event/event.h
@@ -76,6 +76,7 @@ public:
 	const LinphoneAddress *getResource() const;
 
 	LinphonePrivate::SalEventOp *getOp() const;
+	void setManualRefresherMode(bool manual);
 
 	int getExpires() const;
 	void setExpires(int expires);
diff --git a/tester/presence_server_tester.c b/tester/presence_server_tester.c
index f2e485fe5c7e797768d6255366ebcb0b8e84740e..a4a9d5b00636b7414d6f03ef97ee515f40987a0a 100644
--- a/tester/presence_server_tester.c
+++ b/tester/presence_server_tester.c
@@ -350,7 +350,8 @@ static void subscribe_with_late_publish(void) {
 	BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &pauline->stat.number_of_LinphonePresenceActivityBusy, 3,
 	                              5000)); /*re- schedule marie to clean up things*/
 
-	/*simulate a rapid presence change to make sure only first and last are transmited*/
+	/*simulate a rapid presence change to make sure only first and last are transmited */
+	/* this tests if SIP-If-Match header based mechanism works */
 	presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityAway, NULL);
 	linphone_core_set_presence_model(marie->lc, presence);
 	linphone_presence_model_unref(presence);
@@ -1573,6 +1574,110 @@ static void publish_with_expires(void) {
 	simple_publish_with_expire(2);
 }
 
+static void publish_with_expire_timestamp_refresh_base(bool_t refresh_timestamps,
+                                                       bool_t each_friend_subscribes_to_the_other) {
+	LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
+	LinphoneCoreManager *pauline =
+	    linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
+
+	LinphoneConfig *marie_config = linphone_core_get_config(marie->lc);
+	linphone_config_set_bool(marie_config, "sip", "update_presence_model_timestamp_before_publish_expires_refresh",
+	                         refresh_timestamps);
+
+	LinphoneAccount *marie_account = linphone_core_get_default_account(marie->lc);
+	const LinphoneAccountParams *marie_account_params = linphone_account_get_params(marie_account);
+	LinphoneAccountParams *new_params = linphone_account_params_clone(marie_account_params);
+	linphone_account_params_set_publish_expires(new_params, 10);
+	linphone_account_set_params(marie_account, new_params);
+	linphone_account_params_unref(new_params);
+
+	const char *rls_uri = "sip:rls@sip.example.org";
+
+	// This is currently necessary for the refresh timestamp case!!!
+	if (each_friend_subscribes_to_the_other) {
+		// Marie adds Pauline as Friend
+		LinphoneFriendList *marie_lfl = linphone_core_create_friend_list(marie->lc);
+		linphone_friend_list_set_rls_uri(marie_lfl, rls_uri);
+		linphone_core_add_friend_list(marie->lc, marie_lfl);
+
+		char *pauline_identity = linphone_address_as_string(pauline->identity);
+		LinphoneFriend *marie_pauline_friend = linphone_core_create_friend_with_address(marie->lc, pauline_identity);
+
+		linphone_friend_list_add_friend(marie_lfl, marie_pauline_friend);
+		linphone_friend_list_update_subscriptions(marie_lfl);
+		linphone_friend_list_unref(marie_lfl);
+
+		linphone_friend_unref(marie_pauline_friend);
+	}
+
+	// Pauline adds Marie as Friend
+	LinphoneFriendList *pauline_lfl = linphone_core_create_friend_list(pauline->lc);
+	linphone_friend_list_set_rls_uri(pauline_lfl, rls_uri);
+	linphone_core_add_friend_list(pauline->lc, pauline_lfl);
+
+	char *marie_identity = linphone_address_as_string(marie->identity);
+	LinphoneFriend *pauline_marie_friend = linphone_core_create_friend_with_address(pauline->lc, marie_identity);
+
+	ms_free(marie_identity);
+	BC_ASSERT_PTR_NOT_NULL(pauline_marie_friend);
+	BC_ASSERT_EQUAL(linphone_friend_get_consolidated_presence(pauline_marie_friend),
+	                LinphoneConsolidatedPresenceOffline, int, "%d");
+
+	linphone_friend_list_add_friend(pauline_lfl, pauline_marie_friend);
+	linphone_friend_list_update_subscriptions(pauline_lfl);
+	linphone_friend_list_unref(pauline_lfl);
+
+	LinphoneCoreCbs *callbacks = linphone_factory_create_core_cbs(linphone_factory_get());
+	linphone_core_cbs_set_publish_state_changed(callbacks, linphone_publish_state_changed);
+	_linphone_core_add_callbacks(marie->lc, callbacks, TRUE);
+	linphone_core_cbs_unref(callbacks);
+
+	linphone_core_set_consolidated_presence(marie->lc, LinphoneConsolidatedPresenceOnline);
+	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphonePublishOk, 2));
+	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneConsolidatedPresenceOnline, 2));
+
+	BC_ASSERT_EQUAL(linphone_friend_get_consolidated_presence(pauline_marie_friend), LinphoneConsolidatedPresenceOnline,
+	                int, "%d");
+	const LinphonePresenceModel *model = linphone_friend_get_presence_model(pauline_marie_friend);
+	time_t first_timestamp = linphone_presence_model_get_timestamp(model);
+
+	// Wait for PUBLISH refresh
+	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphonePublishOk, 3));
+	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneConsolidatedPresenceOnline, 3));
+	model = linphone_friend_get_presence_model(pauline_marie_friend);
+	time_t next_timestamp = linphone_presence_model_get_timestamp(model);
+	if (refresh_timestamps) {
+		BC_ASSERT_FALSE(first_timestamp == next_timestamp);
+	} else {
+		BC_ASSERT_TRUE(first_timestamp == next_timestamp);
+	}
+
+	// Wait for PUBLISH refresh
+	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphonePublishOk, 4));
+	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneConsolidatedPresenceOnline, 4));
+	model = linphone_friend_get_presence_model(pauline_marie_friend);
+	next_timestamp = linphone_presence_model_get_timestamp(model);
+	if (refresh_timestamps) {
+		BC_ASSERT_FALSE(first_timestamp == next_timestamp);
+	} else {
+		BC_ASSERT_TRUE(first_timestamp == next_timestamp);
+	}
+
+	linphone_friend_unref(pauline_marie_friend);
+	linphone_core_manager_stop(marie);
+	linphone_core_manager_stop(pauline);
+	linphone_core_manager_destroy(marie);
+	linphone_core_manager_destroy(pauline);
+}
+
+static void publish_without_expire_timestamp_refresh(void) {
+	publish_with_expire_timestamp_refresh_base(FALSE, TRUE);
+}
+
+static void publish_with_expire_timestamp_refresh(void) {
+	publish_with_expire_timestamp_refresh_base(TRUE, TRUE);
+}
+
 static void publish_with_dual_identity(void) {
 	LinphoneCoreManager *pauline = linphone_core_manager_new("multi_account_rc");
 	const bctbx_list_t *proxies;
@@ -2429,6 +2534,10 @@ test_t presence_server_tests[] = {
     TEST_NO_TAG("Simple Publish", simple_publish),
     TEST_NO_TAG("Publish with 2 identities", publish_with_dual_identity),
     TEST_NO_TAG("Simple Publish with expires", publish_with_expires),
+    TEST_ONE_TAG(
+        "Publish presence refresher without updated timestamps", publish_without_expire_timestamp_refresh, "presence"),
+    TEST_ONE_TAG(
+        "Publish presence refresher with updated timestamps", publish_with_expire_timestamp_refresh, "presence"),
     TEST_ONE_TAG("Publish with network state changes", publish_with_network_state_changes, "presence"),
     TEST_NO_TAG("Simple", simple),
     TEST_NO_TAG("Fast activity change", fast_activity_change),