code clean up for cp module

This commit is contained in:
BinaryWang
2016-08-02 19:49:27 +08:00
parent f7a64a7cf6
commit d05da579a8
58 changed files with 1069 additions and 1027 deletions

View File

@@ -10,17 +10,6 @@ import java.io.InputStream;
public class ApiTestModule implements Module {
@Override
public void configure(Binder binder) {
InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml");
WxXmlCpInMemoryConfigStorage config = fromXml(WxXmlCpInMemoryConfigStorage.class, is1);
WxCpServiceImpl wxService = new WxCpServiceImpl();
wxService.setWxCpConfigStorage(config);
binder.bind(WxCpServiceImpl.class).toInstance(wxService);
binder.bind(WxCpConfigStorage.class).toInstance(config);
}
public static <T> T fromXml(Class<T> clazz, InputStream is) {
XStream xstream = XStreamInitializer.getInstance();
xstream.alias("xml", clazz);
@@ -28,9 +17,20 @@ public class ApiTestModule implements Module {
return (T) xstream.fromXML(is);
}
@Override
public void configure(Binder binder) {
InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml");
WxXmlCpInMemoryConfigStorage config = fromXml(WxXmlCpInMemoryConfigStorage.class, is1);
WxCpServiceImpl wxService = new WxCpServiceImpl();
wxService.setWxCpConfigStorage(config);
binder.bind(WxCpServiceImpl.class).toInstance(wxService);
binder.bind(WxCpConfigStorage.class).toInstance(config);
}
@XStreamAlias("xml")
public static class WxXmlCpInMemoryConfigStorage extends WxCpInMemoryConfigStorage {
protected String userId;
protected String departmentId;
@@ -40,6 +40,7 @@ public class ApiTestModule implements Module {
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
@@ -63,11 +64,11 @@ public class ApiTestModule implements Module {
@Override
public String toString() {
return super.toString() + " > WxXmlCpConfigStorage{" +
"userId='" + userId + '\'' +
", departmentId='" + departmentId + '\'' +
", tagId='" + tagId + '\'' +
'}';
"userId='" + userId + '\'' +
", departmentId='" + departmentId + '\'' +
", tagId='" + tagId + '\'' +
'}';
}
}
}

View File

@@ -9,8 +9,8 @@ import org.testng.annotations.Test;
/**
* 基础API测试
* @author Daniel Qian
*
* @author Daniel Qian
*/
@Test(groups = "baseAPI")
@Guice(modules = ApiTestModule.class)

View File

@@ -14,7 +14,7 @@ import java.util.concurrent.Future;
@Test
public class WxCpBusyRetryTest {
@DataProvider(name="getService")
@DataProvider(name = "getService")
public Object[][] getService() {
WxCpService service = new WxCpServiceImpl() {
@@ -28,8 +28,8 @@ public class WxCpBusyRetryTest {
service.setMaxRetryTimes(3);
service.setRetrySleepMillis(500);
return new Object[][] {
new Object[] { service }
return new Object[][]{
new Object[]{service}
};
}

View File

@@ -44,7 +44,7 @@ public class WxCpDepartAPITest {
}
}
@Test(dependsOnMethods = { "testDepartGet", "testDepartCreate" })
@Test(dependsOnMethods = {"testDepartGet", "testDepartCreate"})
public void testDepartUpdate() throws WxErrorException {
System.out.println("=================更新部门");
depart.setName("子部门改名" + System.currentTimeMillis());

View File

@@ -16,8 +16,8 @@ import java.util.List;
/**
* 测试多媒体文件上传下载
* @author Daniel Qian
*
* @author Daniel Qian
*/
//@Test(groups="mediaAPI", dependsOnGroups="baseAPI")
@Test
@@ -28,15 +28,15 @@ public class WxCpMediaAPITest {
protected WxCpServiceImpl wxService;
private List<String> media_ids = new ArrayList<String>();
@Test(dataProvider="uploadMedia")
@Test(dataProvider = "uploadMedia")
public void testUploadMedia(String mediaType, String fileType, String fileName) throws WxErrorException, IOException {
InputStream inputStream = ClassLoader.getSystemResourceAsStream(fileName);
WxMediaUploadResult res = wxService.mediaUpload(mediaType, fileType, inputStream);
Assert.assertNotNull(res.getType());
Assert.assertNotNull(res.getCreatedAt());
Assert.assertTrue(res.getMediaId() != null || res.getThumbMediaId() != null);
if (res.getMediaId() != null) {
media_ids.add(res.getMediaId());
}
@@ -44,29 +44,29 @@ public class WxCpMediaAPITest {
media_ids.add(res.getThumbMediaId());
}
}
@DataProvider
public Object[][] uploadMedia() {
return new Object[][] {
new Object[] { WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, "mm.jpeg" },
new Object[] { WxConsts.MEDIA_VOICE, WxConsts.FILE_MP3, "mm.mp3" },
new Object[] { WxConsts.MEDIA_VIDEO, WxConsts.FILE_MP4, "mm.mp4" },
new Object[] { WxConsts.MEDIA_FILE, WxConsts.FILE_JPG, "mm.jpeg" }
return new Object[][]{
new Object[]{WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, "mm.jpeg"},
new Object[]{WxConsts.MEDIA_VOICE, WxConsts.FILE_MP3, "mm.mp3"},
new Object[]{WxConsts.MEDIA_VIDEO, WxConsts.FILE_MP4, "mm.mp4"},
new Object[]{WxConsts.MEDIA_FILE, WxConsts.FILE_JPG, "mm.jpeg"}
};
}
@Test(dependsOnMethods = { "testUploadMedia" }, dataProvider="downloadMedia")
@Test(dependsOnMethods = {"testUploadMedia"}, dataProvider = "downloadMedia")
public void testDownloadMedia(String media_id) throws WxErrorException {
wxService.mediaDownload(media_id);
}
@DataProvider
public Object[][] downloadMedia() {
Object[][] params = new Object[this.media_ids.size()][];
for (int i = 0; i < this.media_ids.size(); i++) {
params[i] = new Object[] { this.media_ids.get(i) };
params[i] = new Object[]{this.media_ids.get(i)};
}
return params;
}
}

View File

@@ -12,7 +12,7 @@ import org.testng.annotations.Test;
* @author Daniel Qian
*
*/
@Test(groups="customMessageAPI", dependsOnGroups = "baseAPI")
@Test(groups = "customMessageAPI", dependsOnGroups = "baseAPI")
@Guice(modules = ApiTestModule.class)
public class WxCpMessageAPITest {
@@ -29,11 +29,11 @@ public class WxCpMessageAPITest {
wxService.messageSend(message1);
WxCpMessage message2 = WxCpMessage
.TEXT()
.agentId(configStorage.getAgentId())
.toUser(configStorage.getUserId())
.content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>")
.build();
.TEXT()
.agentId(configStorage.getAgentId())
.toUser(configStorage.getUserId())
.content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>")
.build();
wxService.messageSend(message2);
}

View File

@@ -13,45 +13,45 @@ import java.util.Map;
/**
* 测试消息路由器
* @author Daniel Qian
*
* @author Daniel Qian
*/
@Test
public class WxCpMessageRouterTest {
@Test(enabled = false)
public void prepare(boolean async, StringBuffer sb, WxCpMessageRouter router) {
router
.rule()
.async(async)
.msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1").content("CONTENT_1")
.handler(new WxEchoCpMessageHandler(sb, "COMBINE_4"))
.end()
.rule()
.async(async)
.msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1")
.handler(new WxEchoCpMessageHandler(sb, "COMBINE_3"))
.end()
.rule()
.async(async)
.msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK)
.handler(new WxEchoCpMessageHandler(sb, "COMBINE_2"))
.end()
.rule().async(async).msgType(WxConsts.XML_MSG_TEXT).handler(new WxEchoCpMessageHandler(sb, WxConsts.XML_MSG_TEXT)).end()
.rule().async(async).event(WxConsts.EVT_CLICK).handler(new WxEchoCpMessageHandler(sb, WxConsts.EVT_CLICK)).end()
.rule().async(async).eventKey("KEY_1").handler(new WxEchoCpMessageHandler(sb, "KEY_1")).end()
.rule().async(async).content("CONTENT_1").handler(new WxEchoCpMessageHandler(sb, "CONTENT_1")).end()
.rule().async(async).rContent(".*bc.*").handler(new WxEchoCpMessageHandler(sb, "abcd")).end()
.rule().async(async).matcher(new WxCpMessageMatcher() {
@Override
public boolean match(WxCpXmlMessage message) {
return "strangeformat".equals(message.getFormat());
}
}).handler(new WxEchoCpMessageHandler(sb, "matcher")).end()
.rule().async(async).handler(new WxEchoCpMessageHandler(sb, "ALL")).end();
.rule()
.async(async)
.msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1").content("CONTENT_1")
.handler(new WxEchoCpMessageHandler(sb, "COMBINE_4"))
.end()
.rule()
.async(async)
.msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1")
.handler(new WxEchoCpMessageHandler(sb, "COMBINE_3"))
.end()
.rule()
.async(async)
.msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK)
.handler(new WxEchoCpMessageHandler(sb, "COMBINE_2"))
.end()
.rule().async(async).msgType(WxConsts.XML_MSG_TEXT).handler(new WxEchoCpMessageHandler(sb, WxConsts.XML_MSG_TEXT)).end()
.rule().async(async).event(WxConsts.EVT_CLICK).handler(new WxEchoCpMessageHandler(sb, WxConsts.EVT_CLICK)).end()
.rule().async(async).eventKey("KEY_1").handler(new WxEchoCpMessageHandler(sb, "KEY_1")).end()
.rule().async(async).content("CONTENT_1").handler(new WxEchoCpMessageHandler(sb, "CONTENT_1")).end()
.rule().async(async).rContent(".*bc.*").handler(new WxEchoCpMessageHandler(sb, "abcd")).end()
.rule().async(async).matcher(new WxCpMessageMatcher() {
@Override
public boolean match(WxCpXmlMessage message) {
return "strangeformat".equals(message.getFormat());
}
}).handler(new WxEchoCpMessageHandler(sb, "matcher")).end()
.rule().async(async).handler(new WxEchoCpMessageHandler(sb, "ALL")).end();
}
@Test(dataProvider="messages-1")
@Test(dataProvider = "messages-1")
public void testSync(WxCpXmlMessage message, String expected) {
StringBuffer sb = new StringBuffer();
WxCpMessageRouter router = new WxCpMessageRouter(null);
@@ -59,27 +59,27 @@ public class WxCpMessageRouterTest {
router.route(message);
Assert.assertEquals(sb.toString(), expected);
}
@Test(dataProvider="messages-1")
@Test(dataProvider = "messages-1")
public void testAsync(WxCpXmlMessage message, String expected) throws InterruptedException {
StringBuffer sb = new StringBuffer();
WxCpMessageRouter router = new WxCpMessageRouter(null);
prepare(true, sb, router);
prepare(true, sb, router);
router.route(message);
Thread.sleep(500l);
Assert.assertEquals(sb.toString(), expected);
}
public void testConcurrency() throws InterruptedException {
final WxCpMessageRouter router = new WxCpMessageRouter(null);
router.rule().handler(new WxCpMessageHandler() {
@Override
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService,
WxSessionManager sessionManager) {
WxSessionManager sessionManager) {
return null;
}
}).end();
final WxCpXmlMessage m = new WxCpXmlMessage();
Runnable r = new Runnable() {
@Override
@@ -94,27 +94,27 @@ public class WxCpMessageRouterTest {
for (int i = 0; i < 10; i++) {
new Thread(r).start();
}
Thread.sleep(1000l * 2);
}
@DataProvider(name="messages-1")
@DataProvider(name = "messages-1")
public Object[][] messages2() {
WxCpXmlMessage message1 = new WxCpXmlMessage();
message1.setMsgType(WxConsts.XML_MSG_TEXT);
WxCpXmlMessage message2 = new WxCpXmlMessage();
message2.setEvent(WxConsts.EVT_CLICK);
WxCpXmlMessage message3 = new WxCpXmlMessage();
message3.setEventKey("KEY_1");
WxCpXmlMessage message4 = new WxCpXmlMessage();
message4.setContent("CONTENT_1");
WxCpXmlMessage message5 = new WxCpXmlMessage();
message5.setContent("BLA");
WxCpXmlMessage message6 = new WxCpXmlMessage();
message6.setContent("abcd");
@@ -124,12 +124,12 @@ public class WxCpMessageRouterTest {
WxCpXmlMessage c2 = new WxCpXmlMessage();
c2.setMsgType(WxConsts.XML_MSG_TEXT);
c2.setEvent(WxConsts.EVT_CLICK);
WxCpXmlMessage c3 = new WxCpXmlMessage();
c3.setMsgType(WxConsts.XML_MSG_TEXT);
c3.setEvent(WxConsts.EVT_CLICK);
c3.setEventKey("KEY_1");
WxCpXmlMessage c4 = new WxCpXmlMessage();
c4.setMsgType(WxConsts.XML_MSG_TEXT);
c4.setEvent(WxConsts.EVT_CLICK);
@@ -137,37 +137,18 @@ public class WxCpMessageRouterTest {
c4.setContent("CONTENT_1");
return new Object[][] {
new Object[] { message1, WxConsts.XML_MSG_TEXT + "," },
new Object[] { message2, WxConsts.EVT_CLICK + "," },
new Object[] { message3, "KEY_1," },
new Object[] { message4, "CONTENT_1," },
new Object[] { message5, "ALL," },
new Object[] { message6, "abcd," },
new Object[] { message7, "matcher," },
new Object[] { c2, "COMBINE_2," },
new Object[] { c3, "COMBINE_3," },
new Object[] { c4, "COMBINE_4," }
return new Object[][]{
new Object[]{message1, WxConsts.XML_MSG_TEXT + ","},
new Object[]{message2, WxConsts.EVT_CLICK + ","},
new Object[]{message3, "KEY_1,"},
new Object[]{message4, "CONTENT_1,"},
new Object[]{message5, "ALL,"},
new Object[]{message6, "abcd,"},
new Object[]{message7, "matcher,"},
new Object[]{c2, "COMBINE_2,"},
new Object[]{c3, "COMBINE_3,"},
new Object[]{c4, "COMBINE_4,"}
};
}
public static class WxEchoCpMessageHandler implements WxCpMessageHandler {
private StringBuffer sb;
private String echoStr;
public WxEchoCpMessageHandler(StringBuffer sb, String echoStr) {
this.sb = sb;
this.echoStr = echoStr;
}
@Override
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService,
WxSessionManager sessionManager) {
sb.append(this.echoStr).append(',');
return null;
}
}
@@ -180,8 +161,8 @@ public class WxCpMessageRouterTest {
ism.setProcessExpiresFrequency(1);
ism.setBackgroundProcessorDelay(1);
return new Object[][] {
new Object[] { ism }
return new Object[][]{
new Object[]{ism}
};
}
@@ -193,8 +174,8 @@ public class WxCpMessageRouterTest {
final WxCpMessageRouter router = new WxCpMessageRouter(null);
router.setSessionManager(ism);
router
.rule().async(false).handler(new WxSessionMessageHandler()).next()
.rule().async(false).handler(new WxSessionMessageHandler()).end();
.rule().async(false).handler(new WxSessionMessageHandler()).next()
.rule().async(false).handler(new WxSessionMessageHandler()).end();
WxCpXmlMessage msg = new WxCpXmlMessage();
msg.setFromUserName("abc");
@@ -213,8 +194,8 @@ public class WxCpMessageRouterTest {
final WxCpMessageRouter router = new WxCpMessageRouter(null);
router.setSessionManager(ism);
router
.rule().async(false).handler(new WxSessionMessageHandler()).next()
.rule().async(true).handler(new WxSessionMessageHandler()).end();
.rule().async(false).handler(new WxSessionMessageHandler()).next()
.rule().async(true).handler(new WxSessionMessageHandler()).end();
WxCpXmlMessage msg = new WxCpXmlMessage();
msg.setFromUserName("abc");
@@ -227,8 +208,8 @@ public class WxCpMessageRouterTest {
final WxCpMessageRouter router = new WxCpMessageRouter(null);
router.setSessionManager(ism);
router
.rule().async(true).handler(new WxSessionMessageHandler()).next()
.rule().async(false).handler(new WxSessionMessageHandler()).end();
.rule().async(true).handler(new WxSessionMessageHandler()).next()
.rule().async(false).handler(new WxSessionMessageHandler()).end();
WxCpXmlMessage msg = new WxCpXmlMessage();
msg.setFromUserName("abc");
@@ -247,8 +228,8 @@ public class WxCpMessageRouterTest {
final WxCpMessageRouter router = new WxCpMessageRouter(null);
router.setSessionManager(ism);
router
.rule().async(true).handler(new WxSessionMessageHandler()).next()
.rule().async(true).handler(new WxSessionMessageHandler()).end();
.rule().async(true).handler(new WxSessionMessageHandler()).next()
.rule().async(true).handler(new WxSessionMessageHandler()).end();
WxCpXmlMessage msg = new WxCpXmlMessage();
msg.setFromUserName("abc");
@@ -267,7 +248,7 @@ public class WxCpMessageRouterTest {
final WxCpMessageRouter router = new WxCpMessageRouter(null);
router.setSessionManager(ism);
router
.rule().async(false).handler(new WxSessionMessageHandler()).end();
.rule().async(false).handler(new WxSessionMessageHandler()).end();
WxCpXmlMessage msg = new WxCpXmlMessage();
msg.setFromUserName("abc");
@@ -281,7 +262,7 @@ public class WxCpMessageRouterTest {
final WxCpMessageRouter router = new WxCpMessageRouter(null);
router.setSessionManager(ism);
router
.rule().async(true).handler(new WxSessionMessageHandler()).end();
.rule().async(true).handler(new WxSessionMessageHandler()).end();
WxCpXmlMessage msg = new WxCpXmlMessage();
msg.setFromUserName("abc");
@@ -292,11 +273,30 @@ public class WxCpMessageRouterTest {
}
}
public static class WxSessionMessageHandler implements WxCpMessageHandler {
public static class WxEchoCpMessageHandler implements WxCpMessageHandler {
private StringBuffer sb;
private String echoStr;
public WxEchoCpMessageHandler(StringBuffer sb, String echoStr) {
this.sb = sb;
this.echoStr = echoStr;
}
@Override
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService,
WxSessionManager sessionManager) {
WxSessionManager sessionManager) {
sb.append(this.echoStr).append(',');
return null;
}
}
public static class WxSessionMessageHandler implements WxCpMessageHandler {
@Override
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService,
WxSessionManager sessionManager) {
sessionManager.getSession(wxMessage.getFromUserName());
return null;
}

View File

@@ -41,7 +41,7 @@ public class WxCpTagAPITest {
@Test(dependsOnMethods = "testTagGet")
public void testTagAddUsers() throws Exception {
List<String> userIds = new ArrayList<String>();
userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage)configStorage).getUserId());
userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage) configStorage).getUserId());
wxService.tagAddUsers(tagId, userIds, null);
}
@@ -54,7 +54,7 @@ public class WxCpTagAPITest {
@Test(dependsOnMethods = "testTagGetUsers")
public void testTagRemoveUsers() throws Exception {
List<String> userIds = new ArrayList<String>();
userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage)configStorage).getUserId());
userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage) configStorage).getUserId());
wxService.tagRemoveUsers(tagId, userIds);
}

View File

@@ -28,7 +28,7 @@ public class WxCpUserAPITest {
WxCpUser user = new WxCpUser();
user.setUserId("some.woman");
user.setName("Some Woman");
user.setDepartIds(new Integer[] { 9, 8 });
user.setDepartIds(new Integer[]{9, 8});
user.setEmail("none@none.com");
user.setGender("");
user.setMobile("13560084979");

View File

@@ -1,90 +1,88 @@
package me.chanjar.weixin.cp.api;
import com.google.inject.Inject;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.menu.WxMenu;
import me.chanjar.weixin.common.bean.menu.WxMenuButton;
import me.chanjar.weixin.common.exception.WxErrorException;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import com.google.inject.Inject;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.menu.WxMenu;
import me.chanjar.weixin.common.bean.menu.WxMenuButton;
import me.chanjar.weixin.common.exception.WxErrorException;
/**
* 测试菜单
* @author Daniel Qian
*
* @author Daniel Qian
*/
@Test(groups="menuAPI", dependsOnGroups="baseAPI")
@Test(groups = "menuAPI", dependsOnGroups = "baseAPI")
@Guice(modules = ApiTestModule.class)
public class WxMenuAPITest {
@Inject
protected WxCpServiceImpl wxService;
@Test(dataProvider = "menu")
public void testCreateMenu(WxMenu wxMenu) throws WxErrorException {
wxService.menuCreate(wxMenu);
}
@Test(dependsOnMethods = { "testCreateMenu"})
@Test(dependsOnMethods = {"testCreateMenu"})
public void testGetMenu() throws WxErrorException {
Assert.assertNotNull(wxService.menuGet());
}
@Test(dependsOnMethods = { "testGetMenu"})
@Test(dependsOnMethods = {"testGetMenu"})
public void testDeleteMenu() throws WxErrorException {
wxService.menuDelete();
}
@DataProvider(name="menu")
@DataProvider(name = "menu")
public Object[][] getMenu() {
WxMenu menu = new WxMenu();
WxMenuButton button1 = new WxMenuButton();
button1.setType(WxConsts.BUTTON_CLICK);
button1.setName("今日歌曲");
button1.setKey("V1001_TODAY_MUSIC");
WxMenuButton button2 = new WxMenuButton();
button2.setType(WxConsts.BUTTON_CLICK);
button2.setName("歌手简介");
button2.setKey("V1001_TODAY_SINGER");
WxMenuButton button3 = new WxMenuButton();
button3.setName("菜单");
menu.getButtons().add(button1);
menu.getButtons().add(button2);
menu.getButtons().add(button3);
WxMenuButton button31 = new WxMenuButton();
button31.setType(WxConsts.BUTTON_VIEW);
button31.setName("搜索");
button31.setUrl("http://www.soso.com/");
WxMenuButton button32 = new WxMenuButton();
button32.setType(WxConsts.BUTTON_VIEW);
button32.setName("视频");
button32.setUrl("http://v.qq.com/");
WxMenuButton button33 = new WxMenuButton();
button33.setType(WxConsts.BUTTON_CLICK);
button33.setName("赞一下我们");
button33.setKey("V1001_GOOD");
button3.getSubButtons().add(button31);
button3.getSubButtons().add(button32);
button3.getSubButtons().add(button33);
return new Object[][] {
new Object[] {
menu
}
return new Object[][]{
new Object[]{
menu
}
};
}
}