Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix_function_room.member_#173 #211

Merged
merged 29 commits into from Jan 24, 2017

Conversation

lijiarui
Copy link
Member

@lijiarui lijiarui commented Jan 17, 2017

#173
#104

  1. change parseNickMap, add remark value
  2. add contact.ready() to get full contact, and get contact's remark

@lijiarui
Copy link
Member Author

Sorry, I found I fix what I need, but bring in other bug, so please wait until I fix all

@lijiarui lijiarui closed this Jan 17, 2017
@lijiarui lijiarui reopened this Jan 17, 2017
@lijiarui
Copy link
Member Author

lijiarui commented Jan 18, 2017

this commit can help to find member in room by nick/display/remark

  1. add following type:
type MemberQueryFilter = {
  nick?: string
  remark?: string
  display?: string
}
  1. add following Map:
nickMap,
remarkMap,
displayMap,
  1. add following Functions:
parseNickMap()
parseRemarkMap()
parseDisplayMap()
  1. change the parameter in function room.member(name: string) from public member(quaryArg: MemberQueryFilter)
    we can find member by nick, display, remark, code as follows:
room.member({nick: '李佳芮'})
room.member({remark: '哈哈哈'})
room.member({display: '土'})

@lijiarui
Copy link
Member Author

lijiarui commented Jan 18, 2017

@zixia
I have tested it, it works well with the following function:

async function RoomTest() {
  let room = await Room.find({topic: 'test'})
  await room.ready()
  console.log('member1: ===========')
  console.log(room.member({nick: '李佳芮'}))
  console.log('member2: ')
  console.log(room.member({remark: '哈哈哈'}))
  console.log('member3: ')
  console.log(room.member({display: '土'}))
}

I didn't modify getContact and its related functions, but test shows:

test » room » Room smoking test Error: Cannot read property 'getContact' of undefined

Could you help me to fix? Thanks.

Copy link
Member

@huan huan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your PR looks workable, it's good.

However, part of them need to be redesign, please follow my reviews and follow them.

Thanks.

@@ -114,7 +122,7 @@ export class Room extends EventEmitter implements Sayable {
const data = await contactGetter(this.id)
log.silly('Room', `contactGetter(${this.id}) resolved`)
this.rawObj = data
this.obj = this.parse(data)
this.obj = await this.parse(data)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Create a new async function named readyAllMembers() , use it make all members ready() for furture use.
  2. Put await readyAllMembers() after this.rawObj = data
  3. Please keep parse() to be sync function instand of change it to be an async function. Also parseNickMap() parseRemarkMap() parseDisplayName() should not be async function too. Because after introduced readyAllMembers() they are all ready to use.
   this.rawObj = data
   await this.readyAllMembers(this.rawObj.MemberList)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you typo here..

Also parseNickMap() parseRemarkMap() parseDisplayName() should not be async function too.

you mean parseNickMap() parseRemarkMap() parseDisplayName() should be sync function?

const nickMap = this.parseNickMap(rawObj.MemberList)
const nickMap = await this.parseNickMap(rawObj.MemberList)
const remarkMap = await this.parseRemarkMap(rawObj.MemberList)
const displayMap = await this.parseDisplayName(rawObj.MemberList)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get rid of await(s) for parse... functions.

member.DisplayName || member.NickName
// @rui: cannot use argument NickName because it mix real nick and remark
contact = Contact.load(member.UserName)
await contact.ready()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete ready() here, move the logic to readyAllMembers()

if (memberList && memberList.map) {
for (let member of memberList) {
contact = Contact.load(member.UserName)
await contact.ready()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete ready() here, move the logic to readyAllMembers()

*/
public member(name: string): Contact | null {
log.verbose('Room', 'member(%s)', name)
public member(quaryArg: MemberQueryFilter): Contact | null {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. When we rewrite a function, the best practice is to keep the old function parameters still work. So please keep member(name: string) for compatible.
  2. when call member(name:string), please search name as remark/display/nick, until we get the Contact(or null)

@@ -234,7 +234,7 @@ async function checkRoomJoin(m: Message): Promise<void> {
}

if (!inviterContact) {
inviterContact = room.member(inviter)
inviterContact = room.member({remark: inviter}) || room.member({nick: inviter})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can keep room.member(inviteeList[i]) here, after you follow the review for member() parameters suggestion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can keep room.member(inviteeList[i]) here, after you follow the review for member() parameters suggestion.

I don't agree with this suggestion, because of the following reason:

We keep function room.member() work, but it should work only with the function find member by nickName.
We cannot use it both find remark and nickName, because one can set a remark same as nick, then it would be confused.

So, what do you think about it?

@@ -316,7 +316,7 @@ async function checkRoomLeave(m: Message): Promise<void> {
/**
* FIXME: leaver maybe is a list
*/
let leaverContact = room.member(leaver)
let leaverContact = room.member({remark: leaver}) || room.member({nick: leaver})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can keep room.member(leaver) here, after you follow the review for member() parameters suggestion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can keep room.member(inviteeList[i]) here, after you follow the review for member() parameters suggestion.

I don't agree with this suggestion, because of the following reason:

We keep function room.member() work, but it should work only with the function find member by nickName.
We cannot use it both find remark and nickName, because one can set a remark same as nick, then it would be confused.

So, what do you think about it?

@@ -367,7 +366,7 @@ async function checkRoomTopic(m: Message): Promise<void> {
if (/^You$/.test(changer) || /^你$/.test(changer)) {
changerContact = Contact.load(this.userId)
} else {
changerContact = room.member(changer)
changerContact = room.member({remark: changer}) || room.member({nick: changer})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can keep room.member(changer) here, after you follow the review for member() parameters suggestion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can keep room.member(inviteeList[i]) here, after you follow the review for member() parameters suggestion.

I don't agree with this suggestion, because of the following reason:

We keep function room.member() work, but it should work only with the function find member by nickName.
We cannot use it both find remark and nickName, because one can set a remark same as nick, then it would be confused.

So, what do you think about it?

Copy link
Member

@huan huan Jan 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you copy/paste the same answer four times here?

I comment more than one times because I want to point out the position for you where needs to change.

What you were arguing about is not wrong, but it's not entirely right. Remember always to KISS(Keep It Simple, Stupid).

The most scenario is we just want to get a member by name(whatever remark/nick/display). I do not agree with you that "it should work only with the function find the member by nickname", instead it should return a contact with name match nick/display/remark. And If "one set a remark same as nick", then it's the time to use the new QueryFilter as the parameter to be more precise.

So just change it to what I said.

Copy link
Member Author

@lijiarui lijiarui Jan 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have two questions:

1. room.member() should use which order?

I have found the rules of the name display order in wechat group's in #173 as follows:

Display order:
@ Event: displayName > nickName
system message remark > nickName
on-screen Names:remark > displayName > nickName

I suggest choosing on-screen Name, because it contains system message and it is useful in firer.ts

2. Now room.member can just return one contact, should it return a contact list?

@@ -209,21 +221,53 @@ export class Room extends EventEmitter implements Sayable {
return rawMemberList.map(m => Contact.load(m.UserName))
}

private parseNickMap(memberList: RoomRawMember[]): Map<string, string> {
private async parseNickMap(memberList: RoomRawMember[]): Promise<Map<string, string>> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not use async here. use readyMembers() in my review suggestion instead.

@@ -182,14 +190,16 @@ export class Room extends EventEmitter implements Sayable {

public get(prop): string { return (this.obj && this.obj[prop]) || (this.dirtyObj && this.dirtyObj[prop]) }

private parse(rawObj: RoomRawObj): RoomObj | null {
private async parse(rawObj: RoomRawObj): Promise<RoomObj | null> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep parse() a sync function is better.

@lijiarui
Copy link
Member Author

@zixia done for what you request

Copy link
Member

@huan huan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please follow my new reviews.

@@ -90,6 +98,15 @@ export class Room extends EventEmitter implements Sayable {
// return this.load(contactGetter)
// }

private async readyAllMembers(memberList: RoomRawMember[]): Promise<void> {
let contact: Contact
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get rid of this line

private async readyAllMembers(memberList: RoomRawMember[]): Promise<void> {
let contact: Contact
for (let member of memberList) {
contact = Contact.load(member.UserName)
Copy link
Member

@huan huan Jan 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change this line to:
let contact = Contact.load(member.UserName)
because it's only used inside this closure.

@@ -114,6 +131,7 @@ export class Room extends EventEmitter implements Sayable {
const data = await contactGetter(this.id)
log.silly('Room', `contactGetter(${this.id}) resolved`)
this.rawObj = data
await this.readyAllMembers(this.rawObj.MemberList)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good

if (memberList && memberList.map) {
memberList.forEach(member => {
/**
* ISSUE #64 emoji need to be striped
* ISSUE #104 never use remark name because sys group message will never use that
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep the original comments in the code, and add new comments if needed, for keep the history clear.(until someday we decide to clean them)

private parseNickMap(memberList: RoomRawMember[]): Map<string, string> {
const nickMap: Map<string, string> = new Map<string, string>()

let contact: Contact
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move let to be inside the closure.

private parseRemarkMap(memberList: RoomRawMember[]): Map<string, string> {
const remarkMap: Map<string, string> = new Map<string, string>()
let contact: Contact
let remark: string | null
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move let to be inside the closure.

return remarkMap
}

private parseDisplayName(memberList: RoomRawMember[]): Map<string, string> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parseRemarkMap & parseDisplayName has many duplicated code.

Please consider to be not duplicated that much.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parseRemarkMap & parseDisplayName has many duplicated code.

/**
* ISSUE #64 emoji need to be striped
* ISSUE #104 never use remark name because sys group message will never use that
*/

Actually, parseRemarkMap & parseDisplayName & parseNickMap has many duplicated code. So should I not duplicated all? Then maybe I cannot keep the original comments in the code...

log.verbose('Room', 'member(%s)', name)
public member(queryArg: MemberQueryFilter | string): Contact | null {
let query: MemberQueryFilter
if (typeof queryArg === 'string') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to support member(name: string) here, which name could be any of remark/display/nick.

/**
* ISSUE #64 emoji need to be striped
*/
name = UtilLib.stripEmoji(name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep the comments.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

notice this.

@lijiarui
Copy link
Member Author

lijiarui commented Jan 19, 2017

@zixia done as what you said.

function room.member() can find contact by nick/remark/display,

use the order : remark> display>nick

Copy link
Member

@huan huan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are almost done! Please apply the new suggestions.

Please also pay attention to the CI tests: at least you should pass one of them(Circle/Travis/Appveyor).

* ISSUE #104 never use remark name because sys group message will never use that
* @rui: cannot use argument NickName because it mix real nick and remark
*/
private parseMap(memberList: RoomRawMember[], parseContent: string): Map<string, string> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add

type NameType = 'nick' | 'display' | 'remark'

Then change

parseContent: string

to

parseContent: NameType

if (parseContent === 'nick') {
mapList[member.UserName] = UtilLib.stripEmoji(contact.name())
} else if (parseContent === 'remark') {
mapList[member.UserName] = UtilLib.stripEmoji(contact.remark() || '')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change this part of code to this way:

       let tmpName: string
       switch (parseContent) {
       case 'nick':
          tmpName = contact.name()
          break
       case 'remark':
          tmpName = contact.remark() || ''
          break
       default:
          throw new Error('not found')
       }
       mapList[member.UserName] = UtilLib.stripEmoji(tmpName)

}

private parseDisplayName(memberList: RoomRawMember[]): Map<string, string> {
return this.parseMap(memberList, 'display')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Get rid of unnessesary functions: parseNickMap / parseRemarkMap / parseDisplayName

use this.parseMap(memberList, 'display') directly

@@ -190,6 +207,8 @@ export class Room extends EventEmitter implements Sayable {

const memberList = this.parseMemberList(rawObj.MemberList)
const nickMap = this.parseNickMap(rawObj.MemberList)
const remarkMap = this.parseRemarkMap(rawObj.MemberList)
const displayMap = this.parseDisplayName(rawObj.MemberList)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of introduce new functions, use this.parseMap(memberList, 'display') directly at here.

log.verbose('Room', 'member(%s)', name)
public member(queryArg: MemberQueryFilter | string): Contact | null {
if (typeof queryArg === 'string') {
log.error('Room', 'function member should use member(queryArg: MemberQueryFilter)')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not use log.error() here because it is not a bug/error, it's a feature.

@lijiarui
Copy link
Member Author

@zixia Thanks for you advice, and I have done what you said.

I'm sorry for not passing CI tests, I didn't use function getContact and I found it is used in function room.ready() in the following function:

    if (!contactGetter) {
      contactGetter = Config.puppetInstance()
                            .getContact.bind(Config.puppetInstance())
    }

Could you help me? Thanks!

Copy link
Member

@huan huan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your code looks cleaner now!

Please make the last change, and confirm the code is work without problem(also pass at least one CI test).

Then I'm going to merge it to master.

if (typeof queryArg === 'string') {
log.verbose('Room', 'function member should use member(queryArg: MemberQueryFilter)')
return this.member({remark: queryArg}) || this.member({display: queryArg}) || this.member({nick: queryArg})
} else {
Copy link
Member

@huan huan Jan 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove else here, and get all the code in this block out.

*/
public member(name: string): Contact | null {
log.verbose('Room', 'member(%s)', name)
public member(queryArg: MemberQueryFilter | string): Contact | null {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add function declarations before function implement like this:

+ public member(filter: MemberQueryFilter): Contact | null
+ public member(name: string): Contact | null
+ 
public member(queryArg: MemberQueryFilter | string): Contact | null {

/**
* ISSUE #64 emoji need to be striped
*/
name = UtilLib.stripEmoji(name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

notice this.

huan added a commit that referenced this pull request Jan 20, 2017
Copy link
Member

@huan huan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with contactGetter is solved by the latest master with commit 279ff97

Now there's another bug with your PR at here: https://ci.appveyor.com/project/Wechaty/wechaty/build/283#L80

 1. test » room » Room smoking test
  AssertionError: should get nick1 from DisplayName   
    ""              "田美坤"
        test/room.spec.ts:104:5

Please fix it, and then check the CI result again.

@lijiarui
Copy link
Member Author

lijiarui commented Jan 20, 2017

the following bug is caused by room.nick(contact: Contact), you have defined its return value is displayName before, but after I changed the code, its return value is nickName.

 1. test » room » Room smoking test
  AssertionError: should get nick1 from DisplayName   
    ""              "田美坤"
        test/room.spec.ts:104:5

And I changed as you designed before, function room.nick() return displayName, if user doesn't have displayName, it will return nickName.

@lijiarui
Copy link
Member Author

lijiarui commented Jan 20, 2017

After the commit, the error above disappear, but it still has an error:

✖ test › room › Room smoking test should get nick2 from NickName because there is no DisplayName,    
  t.is(nick2, EXPECTED.memberNick2, 'should get nick2 from NickName because there is no DisplayName, ')
       |               |                                                                               
       ""              "李竹~英诺天使(此号已满)"          

Actually, I have tested, using function room.nick() if one doesn't have a displayName in the room, it will return nickName correctly. But it still failed this test.

I thought because I changed some structure of the member obj, so the test data maybe outdated...
@zixia need your help, thanks.

@huan
Copy link
Member

huan commented Jan 20, 2017

After you fixed this, I believe this PR could be ready for merging.

@lijiarui
Copy link
Member Author

lijiarui commented Jan 22, 2017

@zixia Finally, I found the reason for not passing the test....

I added contact.ready() in new PR, because the contact data in Class Contact is not the same as the the member in room, so contact.ready() cannot get the full contact data, then it cannot get the correct nickMap and remarkMap...

Maybe you should mock some contact data corresponding the room member, then it can get the full contact data, and get the nickMap, then pass the test...

@huan
Copy link
Member

huan commented Jan 22, 2017

Great. Could you modify the mock data in the unit test to add support for your new code?

Copy link
Member

@huan huan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Congratulations, you had your first version PR which passed CI test.

However, your unit test has not set the mock data correctly(some test code also need to be corrected).

Please follow all the reviews, and correct the mock data format.

Tip: Normally, I just use a console.log(JSON.stringify(contact)) to generate the json data, then I use this REAL data to be my mock data.

Looking forward to seeing your new unit test with the correct mock data!


public member(queryArg: MemberQueryFilter | string): Contact | null {
if (typeof queryArg === 'string') {
log.warn('Room', 'member(%s) DEPRECATED, use member(queryArg: MemberQueryFilter) instead.')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be neither warn nor DEPRECATED.

@@ -356,26 +392,59 @@ export class Room extends EventEmitter implements Sayable {
}

/**
* NickName / DisplayName / RemarkName of member
* find member by `nick`(NickName) / `display`(DisplayName) / `remark`(RemarkName)
* when use member(name:string), find member by nickName by default
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should by all name by default.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you missed this review.

const RAW_OBJ = JSON.parse(`
{"RemarkPYQuanPin":"","RemarkPYInitial":"","PYInitial":"TZZGQNTSHGFJ","PYQuanPin":"tongzhizhongguoqingniantianshihuiguanfangjia","Uin":0,"UserName":"@@e2355db381dc46a77c0b95516d05e7486135cb6370d8a6af66925d89d50ec278","NickName":"(通知)中国青年天使会官方家","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgetheadimg?seq=670397504&username=@@e2355db381dc46a77c0b95516d05e7486135cb6370d8a6af66925d89d50ec278&skey=","ContactFlag":2,"MemberCount":146,"MemberList":[{"Uin":0,"UserName":"@ecff4a7a86f23455dc42317269aa36ab","NickName":"童玮亮","AttrStatus":103423,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"dap","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@ecff4a7a86f23455dc42317269aa36ab&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@eac4377ecfd59e4321262f892177169f","NickName":"麦刚","AttrStatus":33674247,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"mai","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@eac4377ecfd59e4321262f892177169f&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@ad85207730aa94e006ddce28f74e6878","NickName":"田美坤Maggie","AttrStatus":112679,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"田美坤","KeyWord":"tia","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@ad85207730aa94e006ddce28f74e6878&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":2351423900,"UserName":"@33cc239d22b20d56395bbbd0967b28b9","NickName":"周宏光","AttrStatus":327869,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"周宏光","KeyWord":"acc","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@33cc239d22b20d56395bbbd0967b28b9&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@5e77381e1e3b5641ddcee44670b6e83a","NickName":"牛文文","AttrStatus":100349,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"niu","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@5e77381e1e3b5641ddcee44670b6e83a&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@56941ef97f3e9c70af88667fdd613b44","NickName":"羊东 东方红酒窖","AttrStatus":33675367,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"Yan","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@56941ef97f3e9c70af88667fdd613b44&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@72c4767ce32db488871fdd1c27173b81","NickName":"李竹~英诺天使(此号已满)","AttrStatus":235261,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"liz","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@72c4767ce32db488871fdd1c27173b81&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@0b0e2eb9501ab2d84f9f800f6a0b4216","NickName":"周静彤 杨宁助理","AttrStatus":230885,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"zlo","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@0b0e2eb9501ab2d84f9f800f6a0b4216&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@4bfa767be0cd3fb78409b9735d1dcc57","NickName":"周哲 Jeremy","AttrStatus":33791995,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"zho","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@4bfa767be0cd3fb78409b9735d1dcc57&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@ad954bf2159a572b7743a5bc134739f4","NickName":"vicky张","AttrStatus":100477,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"hua","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@ad954bf2159a572b7743a5bc134739f4&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"}],"RemarkName":"","HideInputBarFlag":0,"Sex":0,"Signature":"","VerifyFlag":0,"OwnerUin":2351423900,"StarFriend":0,"AppAccountFlag":0,"Statues":0,"AttrStatus":0,"Province":"","City":"","Alias":"","SnsFlag":0,"UniFriend":0,"DisplayName":"","ChatRoomId":0,"KeyWord":"","EncryChatRoomId":"@4b8baa99bdfc354443711412126d2aaf","MMFromBatchGet":true,"MMOrderSymbol":"TONGZHIZHONGGUOQINGNIANTIANSHIHUIGUANFANGJIA","MMFromBatchget":true,"MMInChatroom":true}
`)
const RAW_OBJ = JSON.parse(`{"@@e2355db381dc46a77c0b95516d05e7486135cb6370d8a6af66925d89d50ec278":{"RemarkPYQuanPin":"","RemarkPYInitial":"","PYInitial":"TZZGQNTSHGFJ","PYQuanPin":"tongzhizhongguoqingniantianshihuiguanfangjia","Uin":0,"UserName":"@@e2355db381dc46a77c0b95516d05e7486135cb6370d8a6af66925d89d50ec278","NickName":"(通知)中国青年天使会官方家","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgetheadimg?seq=670397504&username=@@e2355db381dc46a77c0b95516d05e7486135cb6370d8a6af66925d89d50ec278&skey=","ContactFlag":2,"MemberCount":146,"MemberList":[{"Uin":0,"UserName":"@ecff4a7a86f23455dc42317269aa36ab","NickName":"童玮亮","AttrStatus":103423,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"dap","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@ecff4a7a86f23455dc42317269aa36ab&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@eac4377ecfd59e4321262f892177169f","NickName":"麦刚","AttrStatus":33674247,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"mai","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@eac4377ecfd59e4321262f892177169f&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@ad85207730aa94e006ddce28f74e6878","NickName":"田美坤Maggie","AttrStatus":112679,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"田美坤","KeyWord":"tia","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@ad85207730aa94e006ddce28f74e6878&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":2351423900,"UserName":"@33cc239d22b20d56395bbbd0967b28b9","NickName":"周宏光","AttrStatus":327869,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"周宏光","KeyWord":"acc","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@33cc239d22b20d56395bbbd0967b28b9&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@5e77381e1e3b5641ddcee44670b6e83a","NickName":"牛文文","AttrStatus":100349,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"niu","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@5e77381e1e3b5641ddcee44670b6e83a&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@56941ef97f3e9c70af88667fdd613b44","NickName":"羊东 东方红酒窖","AttrStatus":33675367,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"Yan","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@56941ef97f3e9c70af88667fdd613b44&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@72c4767ce32db488871fdd1c27173b81","NickName":"李竹~英诺天使(此号已满)","AttrStatus":235261,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"liz","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@72c4767ce32db488871fdd1c27173b81&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@0b0e2eb9501ab2d84f9f800f6a0b4216","NickName":"周静彤 杨宁助理","AttrStatus":230885,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"zlo","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@0b0e2eb9501ab2d84f9f800f6a0b4216&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@4bfa767be0cd3fb78409b9735d1dcc57","NickName":"周哲 Jeremy","AttrStatus":33791995,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"zho","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@4bfa767be0cd3fb78409b9735d1dcc57&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"},{"Uin":0,"UserName":"@ad954bf2159a572b7743a5bc134739f4","NickName":"vicky张","AttrStatus":100477,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"","KeyWord":"hua","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@ad954bf2159a572b7743a5bc134739f4&skey=@crypt_f9cec94b_f23a307a23231cfb5098faf91ff759ca&chatroomid=@4b8baa99bdfc354443711412126d2aaf"}],"RemarkName":"","HideInputBarFlag":0,"Sex":0,"Signature":"","VerifyFlag":0,"OwnerUin":2351423900,"StarFriend":0,"AppAccountFlag":0,"Statues":0,"AttrStatus":0,"Province":"","City":"","Alias":"","SnsFlag":0,"UniFriend":0,"DisplayName":"","ChatRoomId":0,"KeyWord":"","EncryChatRoomId":"@4b8baa99bdfc354443711412126d2aaf","MMFromBatchGet":true,"MMOrderSymbol":"TONGZHIZHONGGUOQINGNIANTIANSHIHUIGUANFANGJIA","MMFromBatchget":true,"MMInChatroom":true},"@ad85207730aa94e006ddce28f74e6878":{"UserName": "@ad85207730aa94e006ddce28f74e6878","NickName": "田美坤Maggie","RemarkName": ""},"@72c4767ce32db488871fdd1c27173b81":{"UserName":"@72c4767ce32db488871fdd1c27173b81","NickName": "李竹~英诺天使(此号已满)","RemarkName": ""},"@ecff4a7a86f23455dc42317269aa36ab":{"UserName": "@ecff4a7a86f23455dc42317269aa36ab","NickName": "童玮亮","RemarkName": "童玮亮备注"}}`)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your modification made RAW_OBJ data wrong.

RAW_OBJ should be the same structure with the JSON data comes from webwxApp. You can put any data in the struct, as long as your structure is the same as webwxApp.

What you changed here, is just make you happy and make your test code happy.

Please change the RAW_OBJ with a real room data instead.

throw new Error('no a or b')
}
t.is(contactA.id, EXPECTED.memberId1, 'should get the right id from nick 1')
t.is(contactB.id, EXPECTED.memberId2, 'should get the right id from nick 2')
t.is(contactC.id, EXPECTED.memberId3, 'should get the right id from nick 2')
Copy link
Member

@huan huan Jan 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please correct the descript, and let it include more details with your test purpose.


public member(queryArg: MemberQueryFilter | string): Contact | null {
if (typeof queryArg === 'string') {
log.warn('Room', 'member(%s) DEPRECATED, use member(queryArg: MemberQueryFilter) instead.', queryArg)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Get rid of this log.

member(string) should not be DEPRECATED. it is a convenience way to find a contact by match name(display/remark/nick).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, I don't think so, it can confused the user... especially in the real using case....

but I will do as what you said, it's your code...

return this.member({remark: queryArg}) || this.member({display: queryArg}) || this.member({nick: queryArg})
}

log.verbose('Room', 'member({ %s })'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use log.silly instead of verbose here.

verbose should be used only once per function, usually at the beginning of the function, to log the function is run and all parameters it has received.

Any other log should be silly

@lijiarui
Copy link
Member Author

Done as what you said, but I'm a little bit confused by the following code:

  const mockContactGetter = function (id) {
    return new Promise((resolve, reject) => {
      // if (id !== EXPECTED.id && !(id in CONTACT_LIST)) return resolve({})
      if (id === EXPECTED.id) {
        setTimeout(() => {
          return resolve(RAW_OBJ)
        }, 10)
      }
      if (id in CONTACT_LIST) {
        setTimeout(() => {
          return resolve(CONTACT_LIST[id])
        }, 10)
      }
      return resolve({})
    })
  }

it gets the following error:

✖ Room smoking test Error: Cannot read property 'Symbol(Symbol.iterator)' of undefined

But when I change the code to the following:

  const mockContactGetter = function (id) {
    return new Promise((resolve, reject) => {
      if (id !== EXPECTED.id && !(id in CONTACT_LIST)) return resolve({})
      if (id === EXPECTED.id) {
        setTimeout(() => {
          return resolve(RAW_OBJ)
        }, 10)
      }
      if (id in CONTACT_LIST) {
        setTimeout(() => {
          return resolve(CONTACT_LIST[id])
        }, 10)
      }
    })
  }

all works well.

What I change is just adjust return resolve({}) order.

I googled the error and find this: this

Initialize items to an empty array.

But I still fell confused..

@huan
Copy link
Member

huan commented Jan 24, 2017

Great work!

It is not perfect, but I think it mergeable now.

BTW:

  • You will only feel confusing when you know you do not know.
  • You will never feel confusing when you do not know you do not know.

@huan huan merged commit 87f94d3 into wechaty:master Jan 24, 2017
@lijiarui lijiarui deleted the fix_function_room.member_#173 branch February 17, 2017 05:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants