fix: complete folder archive action handling
This commit is contained in:
@@ -163,20 +163,19 @@ public class ConversationFolderActivity extends BossScreenActivity {
|
||||
targetIndices.add(i);
|
||||
}
|
||||
}
|
||||
return targetIndices;
|
||||
}
|
||||
|
||||
if (targetProjectId != null && !targetProjectId.isEmpty()) {
|
||||
if (targetIndices.isEmpty() && targetProjectId != null && !targetProjectId.isEmpty()) {
|
||||
for (int i = 0; i < threads.length(); i++) {
|
||||
JSONObject item = threads.optJSONObject(i);
|
||||
if (item != null && targetProjectId.equals(item.optString("projectId", ""))) {
|
||||
targetIndices.add(i);
|
||||
return targetIndices;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (targetProjectLabel != null && !targetProjectLabel.isEmpty()) {
|
||||
if (targetIndices.isEmpty() && targetProjectLabel != null && !targetProjectLabel.isEmpty()) {
|
||||
for (int i = 0; i < threads.length(); i++) {
|
||||
JSONObject item = threads.optJSONObject(i);
|
||||
if (item != null && targetProjectLabel.equals(item.optString("threadTitle", ""))) {
|
||||
|
||||
@@ -91,6 +91,32 @@ public class ConversationFolderActivityTest {
|
||||
assertEquals(0, countTextOccurrences(content, "project-1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void conversationFolderFallsBackFromMissingSearchTargetsToProjectIdThenLabel() throws Exception {
|
||||
Intent intent = new Intent()
|
||||
.putExtra(ConversationFolderActivity.EXTRA_FOLDER_KEY, "talking")
|
||||
.putExtra(ConversationFolderActivity.EXTRA_FOLDER_NAME, "Talking")
|
||||
.putExtra(ConversationFolderActivity.EXTRA_TARGET_PROJECT_ID, "project-3")
|
||||
.putExtra(ConversationFolderActivity.EXTRA_TARGET_PROJECT_IDS, new String[]{"project-99", "project-100"})
|
||||
.putExtra(ConversationFolderActivity.EXTRA_TARGET_PROJECT_LABEL, "日志收口");
|
||||
TestConversationFolderActivity activity = Robolectric
|
||||
.buildActivity(TestConversationFolderActivity.class, intent)
|
||||
.setup()
|
||||
.get();
|
||||
|
||||
ReflectionHelpers.callInstanceMethod(
|
||||
activity,
|
||||
"renderFolder",
|
||||
ReflectionHelpers.ClassParameter.from(JSONObject.class, buildFolderPayload())
|
||||
);
|
||||
|
||||
LinearLayout content = activity.findViewById(R.id.screen_content);
|
||||
assertTrue(viewTreeContainsText(content, "已定位到目标线程"));
|
||||
assertTrue(viewTreeContainsText(content, "日志收口"));
|
||||
assertEquals(0, countTextOccurrences(content, "project-99"));
|
||||
assertEquals(1, countTextOccurrences(content, "目标线程"));
|
||||
}
|
||||
|
||||
private static JSONObject buildFolderPayload() throws Exception {
|
||||
JSONArray threads = new JSONArray()
|
||||
.put(new JSONObject()
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.robolectric.Shadows;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -260,6 +261,27 @@ public class MainActivityRealtimeTest {
|
||||
assertEquals("flat-thread", conversationsData.optJSONObject(0).optString("projectId", ""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refreshConversationsData_fallsBackToFlatConversationsFeedWhenHomeFeedThrowsIOException() throws Exception {
|
||||
MainActivity activity = Robolectric.buildActivity(MainActivity.class).setup().resume().get();
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
|
||||
RecordingIOExceptionConversationSourceClient apiClient = new RecordingIOExceptionConversationSourceClient(
|
||||
activity.getSharedPreferences("test-boss-api", Context.MODE_PRIVATE)
|
||||
);
|
||||
ReflectionHelpers.setField(activity, "apiClient", apiClient);
|
||||
ReflectionHelpers.callInstanceMethod(activity, "showContent");
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
|
||||
activity.refreshConversationsData();
|
||||
waitFor(() -> apiClient.homeCalls > 0 && apiClient.conversationsCalls > 0);
|
||||
|
||||
assertEquals(1, apiClient.homeCalls);
|
||||
assertEquals(1, apiClient.conversationsCalls);
|
||||
JSONArray conversationsData = ReflectionHelpers.getField(activity, "conversationsData");
|
||||
assertEquals("flat-thread", conversationsData.optJSONObject(0).optString("projectId", ""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refreshAllData_prefersConversationHomeFeedOverFlatConversationsFeed() throws Exception {
|
||||
MainActivity activity = Robolectric.buildActivity(MainActivity.class).setup().resume().get();
|
||||
@@ -308,6 +330,31 @@ public class MainActivityRealtimeTest {
|
||||
assertEquals("flat-thread", conversationsData.optJSONObject(0).optString("projectId", ""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refreshAllData_fallsBackToFlatConversationsFeedWhenHomeFeedThrowsIOException() throws Exception {
|
||||
MainActivity activity = Robolectric.buildActivity(MainActivity.class).setup().resume().get();
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
|
||||
RecordingIOExceptionConversationSourceClient apiClient = new RecordingIOExceptionConversationSourceClient(
|
||||
activity.getSharedPreferences("test-boss-api", Context.MODE_PRIVATE)
|
||||
);
|
||||
ReflectionHelpers.setField(activity, "apiClient", apiClient);
|
||||
ReflectionHelpers.callInstanceMethod(activity, "showContent");
|
||||
Shadows.shadowOf(activity.getMainLooper()).idle();
|
||||
|
||||
ReflectionHelpers.callInstanceMethod(
|
||||
activity,
|
||||
"refreshAllData",
|
||||
ReflectionHelpers.ClassParameter.from(JSONObject.class, new JSONObject())
|
||||
);
|
||||
waitFor(() -> apiClient.homeCalls > 0 && apiClient.conversationsCalls > 0);
|
||||
|
||||
assertEquals(1, apiClient.homeCalls);
|
||||
assertEquals(1, apiClient.conversationsCalls);
|
||||
JSONArray conversationsData = ReflectionHelpers.getField(activity, "conversationsData");
|
||||
assertEquals("flat-thread", conversationsData.optJSONObject(0).optString("projectId", ""));
|
||||
}
|
||||
|
||||
private static void waitFor(BooleanSupplier condition) throws Exception {
|
||||
long deadlineAt = System.currentTimeMillis() + 2_000L;
|
||||
while (System.currentTimeMillis() < deadlineAt) {
|
||||
@@ -506,4 +553,77 @@ public class MainActivityRealtimeTest {
|
||||
.put("latestReplyLabel", "11:00"));
|
||||
}
|
||||
}
|
||||
|
||||
private static final class RecordingIOExceptionConversationSourceClient extends BossApiClient {
|
||||
int homeCalls;
|
||||
int conversationsCalls;
|
||||
int sessionCalls;
|
||||
int devicesCalls;
|
||||
int settingsCalls;
|
||||
int otaCalls;
|
||||
|
||||
RecordingIOExceptionConversationSourceClient(android.content.SharedPreferences prefs) {
|
||||
super(prefs, "https://boss.hyzq.net");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse getConversationHome() throws IOException, org.json.JSONException {
|
||||
homeCalls += 1;
|
||||
throw new IOException("HOME_TIMEOUT");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse getConversations() throws IOException, org.json.JSONException {
|
||||
conversationsCalls += 1;
|
||||
return new ApiResponse(200, new JSONObject()
|
||||
.put("ok", true)
|
||||
.put("conversations", buildFlatConversations()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse getSession() throws IOException, org.json.JSONException {
|
||||
sessionCalls += 1;
|
||||
return new ApiResponse(200, new JSONObject()
|
||||
.put("ok", true)
|
||||
.put("session", new JSONObject()
|
||||
.put("account", "17600003315")
|
||||
.put("displayName", "Boss 超级管理员")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse getDevices() throws IOException, org.json.JSONException {
|
||||
devicesCalls += 1;
|
||||
return new ApiResponse(200, new JSONObject()
|
||||
.put("ok", true)
|
||||
.put("devices", new JSONArray()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse getSettings() throws IOException, org.json.JSONException {
|
||||
settingsCalls += 1;
|
||||
return new ApiResponse(200, new JSONObject()
|
||||
.put("ok", true)
|
||||
.put("settings", new JSONObject().put("preferredEntryPoint", "conversations"))
|
||||
.put("user", new JSONObject()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse getOtaStatus() throws IOException, org.json.JSONException {
|
||||
otaCalls += 1;
|
||||
return new ApiResponse(200, new JSONObject()
|
||||
.put("ok", true)
|
||||
.put("hasOta", false));
|
||||
}
|
||||
|
||||
private static JSONArray buildFlatConversations() throws org.json.JSONException {
|
||||
return new JSONArray().put(new JSONObject()
|
||||
.put("projectId", "flat-thread")
|
||||
.put("conversationType", "single_device")
|
||||
.put("projectTitle", "发布回滚")
|
||||
.put("threadTitle", "发布回滚")
|
||||
.put("folderLabel", "Boss")
|
||||
.put("lastMessagePreview", "最近:发布回滚")
|
||||
.put("latestReplyLabel", "11:00"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user