diff --git a/android/app/src/test/java/com/hyzq/boss/BossUiConversationRowTest.java b/android/app/src/test/java/com/hyzq/boss/BossUiConversationRowTest.java index ffeb1e1..2f1b738 100644 --- a/android/app/src/test/java/com/hyzq/boss/BossUiConversationRowTest.java +++ b/android/app/src/test/java/com/hyzq/boss/BossUiConversationRowTest.java @@ -1,5 +1,6 @@ package com.hyzq.boss; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import android.content.Context; @@ -17,45 +18,50 @@ import org.robolectric.RuntimeEnvironment; @Config(sdk = 34) public class BossUiConversationRowTest { @Test - public void conversationRow_keepsCenterTextsVisibleWhenMeasured() { + public void buildConversationRow_usesWechatListSpacingInsteadOfCardChrome() { Context context = RuntimeEnvironment.getApplication(); WechatSurfaceMapper.ConversationRow row = new WechatSurfaceMapper.ConversationRow( "北区试产线回归", "归档确认", "现场摄像头关键帧", "09:26", - 0, + 2, "置顶", - 1, + 2, false, "M", "W", new WechatSurfaceMapper.GroupAvatarMember[0] ); - LinearLayout card = BossUi.buildConversationRow(context, row, null); + LinearLayout rowView = BossUi.buildConversationRow(context, row, null); int width = View.MeasureSpec.makeMeasureSpec(BossUi.dp(context, 320), View.MeasureSpec.EXACTLY); int height = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - card.measure(width, height); - card.layout(0, 0, card.getMeasuredWidth(), card.getMeasuredHeight()); + rowView.measure(width, height); + rowView.layout(0, 0, rowView.getMeasuredWidth(), rowView.getMeasuredHeight()); - LinearLayout centerColumn = (LinearLayout) card.getChildAt(1); - LinearLayout trailingColumn = (LinearLayout) card.getChildAt(2); + LinearLayout centerColumn = (LinearLayout) rowView.getChildAt(1); + LinearLayout trailingColumn = (LinearLayout) rowView.getChildAt(2); TextView titleView = (TextView) centerColumn.getChildAt(0); TextView previewView = (TextView) centerColumn.getChildAt(centerColumn.getChildCount() - 1); String metrics = String.format( - "card=%d center=%d trailing=%d title=%d preview=%d", - card.getMeasuredWidth(), + "row=%d center=%d trailing=%d title=%d preview=%d", + rowView.getMeasuredWidth(), centerColumn.getMeasuredWidth(), trailingColumn.getMeasuredWidth(), titleView.getMeasuredWidth(), previewView.getMeasuredWidth() ); + assertEquals("列表项应使用微信式扁平 padding: " + metrics, BossUi.dp(context, 16), rowView.getPaddingLeft()); + assertEquals("列表项应使用微信式扁平 padding: " + metrics, BossUi.dp(context, 12), rowView.getPaddingTop()); + assertEquals("列表项应使用微信式扁平 padding: " + metrics, BossUi.dp(context, 16), rowView.getPaddingRight()); + assertEquals("列表项应使用微信式扁平 padding: " + metrics, BossUi.dp(context, 12), rowView.getPaddingBottom()); + assertEquals("列表项不应保持卡片式浮层感: " + metrics, 0f, rowView.getElevation(), 0.01f); assertTrue("中间文字列不应被挤成 0 宽: " + metrics, centerColumn.getMeasuredWidth() > 0); assertTrue("标题需要保留可见宽度: " + metrics, titleView.getMeasuredWidth() > 0); assertTrue("预览需要保留可见宽度: " + metrics, previewView.getMeasuredWidth() > 0); - assertTrue("右侧信息列不应吞掉中间内容: " + metrics, trailingColumn.getMeasuredWidth() < card.getMeasuredWidth() / 2); + assertTrue("右侧信息列不应吞掉中间内容: " + metrics, trailingColumn.getMeasuredWidth() < rowView.getMeasuredWidth() / 2); } } diff --git a/android/app/src/test/java/com/hyzq/boss/BossUiRootSurfaceTest.java b/android/app/src/test/java/com/hyzq/boss/BossUiRootSurfaceTest.java new file mode 100644 index 0000000..4c1942a --- /dev/null +++ b/android/app/src/test/java/com/hyzq/boss/BossUiRootSurfaceTest.java @@ -0,0 +1,71 @@ +package com.hyzq.boss; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.view.View; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.json.JSONObject; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.robolectric.util.ReflectionHelpers; + +@RunWith(RobolectricTestRunner.class) +@Config(sdk = 34) +public class BossUiRootSurfaceTest { + @Test + public void renderMeRoot_usesWechatProfileHeaderAndFlatMenuRows() throws Exception { + MainActivity activity = Robolectric.buildActivity(MainActivity.class).setup().get(); + + ReflectionHelpers.setField( + activity, + "sessionData", + new JSONObject() + .put("displayName", "Kris") + .put("account", "17600003315") + .put("role", "最高管理员") + ); + ReflectionHelpers.callInstanceMethod(activity, "renderMeRoot"); + + LinearLayout content = activity.findViewById(R.id.screen_content); + assertEquals("我的页应是资料头 + 6 条菜单", 7, content.getChildCount()); + + View header = content.getChildAt(0); + assertEquals("资料头不应保留浮层卡片感", 0f, header.getElevation(), 0.01f); + assertTrue(viewTreeContainsText(header, "Kris")); + assertTrue(viewTreeContainsText(header, "17600003315")); + assertTrue(viewTreeContainsText(header, "ChatGPT Plus · 主账号")); + assertTrue(viewTreeContainsText(header, "主控账号已启用安全保护")); + + assertTrue(viewTreeContainsText(content, "账号与安全")); + assertTrue(viewTreeContainsText(content, "设置")); + assertTrue(viewTreeContainsText(content, "运维与修复")); + assertTrue(viewTreeContainsText(content, "AI 账号")); + assertTrue(viewTreeContainsText(content, "技能")); + assertTrue(viewTreeContainsText(content, "关于")); + } + + private static boolean viewTreeContainsText(View root, String expectedText) { + if (root instanceof TextView) { + CharSequence text = ((TextView) root).getText(); + if (expectedText.contentEquals(text)) { + return true; + } + } + if (!(root instanceof LinearLayout)) { + return false; + } + LinearLayout group = (LinearLayout) root; + for (int index = 0; index < group.getChildCount(); index += 1) { + if (viewTreeContainsText(group.getChildAt(index), expectedText)) { + return true; + } + } + return false; + } +}