Skip to content

Commit 551bdae

Browse files
committed
fix CloseNotebook not removing record from session config
Closing a notebook removed it from the in-memory map but didn't remove the NotebookRecord from session_config_.notebooks before saving. This caused closed notebooks to reappear after application restart. Added unit test to verify the fix by simulating app restart with a new context.
1 parent 24aeff4 commit 551bdae

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

src/core/notebook_manager.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,14 @@ VxCoreError NotebookManager::CloseNotebook(const std::string &notebook_id) {
187187

188188
notebooks_.erase(it);
189189

190+
// Remove notebook record from session config
191+
auto &session_config = config_manager_->GetSessionConfig();
192+
auto rec_it = std::find_if(session_config.notebooks.begin(), session_config.notebooks.end(),
193+
[&notebook_id](const NotebookRecord &r) { return r.id == notebook_id; });
194+
if (rec_it != session_config.notebooks.end()) {
195+
session_config.notebooks.erase(rec_it);
196+
}
197+
190198
config_manager_->SaveSessionConfig();
191199

192200
VXCORE_LOG_INFO("Notebook closed successfully: id=%s", notebook_id.c_str());

tests/test_notebook.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,66 @@ int test_notebook_close_releases_db_lock() {
10381038
return 0;
10391039
}
10401040

1041+
// Test that closing a notebook removes it from session config
1042+
// so it doesn't reappear after creating a new context (restart simulation)
1043+
int test_notebook_close_removes_from_session() {
1044+
std::cout << " Running test_notebook_close_removes_from_session..." << std::endl;
1045+
cleanup_test_dir(get_test_path("test_nb_close_session"));
1046+
1047+
// Create first context and notebook
1048+
VxCoreContextHandle ctx1 = nullptr;
1049+
VxCoreError err = vxcore_context_create(nullptr, &ctx1);
1050+
ASSERT_EQ(err, VXCORE_OK);
1051+
1052+
char *notebook_id = nullptr;
1053+
err = vxcore_notebook_create(ctx1, get_test_path("test_nb_close_session").c_str(),
1054+
"{\"name\":\"Session Test\"}", VXCORE_NOTEBOOK_BUNDLED,
1055+
&notebook_id);
1056+
ASSERT_EQ(err, VXCORE_OK);
1057+
ASSERT_NOT_NULL(notebook_id);
1058+
1059+
std::string saved_id(notebook_id);
1060+
1061+
// Verify notebook appears in list
1062+
char *list_json1 = nullptr;
1063+
err = vxcore_notebook_list(ctx1, &list_json1);
1064+
ASSERT_EQ(err, VXCORE_OK);
1065+
ASSERT_NE(std::string(list_json1).find(saved_id), std::string::npos);
1066+
vxcore_string_free(list_json1);
1067+
1068+
// Close the notebook
1069+
err = vxcore_notebook_close(ctx1, notebook_id);
1070+
ASSERT_EQ(err, VXCORE_OK);
1071+
1072+
// Verify notebook no longer appears in list after close
1073+
char *list_json2 = nullptr;
1074+
err = vxcore_notebook_list(ctx1, &list_json2);
1075+
ASSERT_EQ(err, VXCORE_OK);
1076+
ASSERT_EQ(std::string(list_json2).find(saved_id), std::string::npos);
1077+
vxcore_string_free(list_json2);
1078+
1079+
vxcore_string_free(notebook_id);
1080+
vxcore_context_destroy(ctx1);
1081+
1082+
// Create NEW context (simulates app restart)
1083+
VxCoreContextHandle ctx2 = nullptr;
1084+
err = vxcore_context_create(nullptr, &ctx2);
1085+
ASSERT_EQ(err, VXCORE_OK);
1086+
1087+
// CRITICAL: Closed notebook should NOT appear in new context's list
1088+
// This was the bug - notebook record wasn't removed from session config
1089+
char *list_json3 = nullptr;
1090+
err = vxcore_notebook_list(ctx2, &list_json3);
1091+
ASSERT_EQ(err, VXCORE_OK);
1092+
ASSERT_EQ(std::string(list_json3).find(saved_id), std::string::npos);
1093+
vxcore_string_free(list_json3);
1094+
1095+
vxcore_context_destroy(ctx2);
1096+
cleanup_test_dir(get_test_path("test_nb_close_session"));
1097+
std::cout << " ✓ test_notebook_close_removes_from_session passed" << std::endl;
1098+
return 0;
1099+
}
1100+
10411101
int main() {
10421102
std::cout << "Running notebook tests..." << std::endl;
10431103

@@ -1072,6 +1132,7 @@ int main() {
10721132
RUN_TEST(test_tag_create_path_partial_exists);
10731133
RUN_TEST(test_tag_create_path_empty);
10741134
RUN_TEST(test_tag_create_path_trailing_slash);
1135+
RUN_TEST(test_notebook_close_removes_from_session);
10751136

10761137
std::cout << "✓ All notebook tests passed" << std::endl;
10771138
return 0;

0 commit comments

Comments
 (0)