Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"dao_test.go",
"memcache_test.go",
"up_test.go",
],
embed = [":go_default_library"],
tags = ["automanaged"],
deps = [
"//app/interface/main/creative/conf:go_default_library",
"//app/interface/main/creative/model/account:go_default_library",
"//app/service/main/account/api:go_default_library",
"//app/service/main/relation/model:go_default_library",
"//app/service/main/relation/rpc/client:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/ecode:go_default_library",
"//vendor/github.com/bouk/monkey:go_default_library",
"//vendor/github.com/golang/mock/gomock:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
"//vendor/gopkg.in/h2non/gock.v1:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"memcache.go",
"up.go",
],
importpath = "go-common/app/interface/main/creative/dao/account",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/creative/conf:go_default_library",
"//app/interface/main/creative/model/account:go_default_library",
"//app/interface/main/creative/model/appeal:go_default_library",
"//app/service/main/account/api:go_default_library",
"//app/service/main/relation/model:go_default_library",
"//app/service/main/relation/rpc/client:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/sync/errgroup:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,390 @@
package account
import (
"context"
"go-common/app/interface/main/creative/conf"
"go-common/app/interface/main/creative/model/appeal"
accapi "go-common/app/service/main/account/api"
relaMdl "go-common/app/service/main/relation/model"
relation "go-common/app/service/main/relation/rpc/client"
"go-common/library/cache/memcache"
"go-common/library/ecode"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
"go-common/library/sync/errgroup"
"net/http"
"net/url"
"time"
)
const (
_pass = "/web/site/userInfo"
_richRelation = "/x/account/relation/rich"
_relation = "/x/internal/relation"
)
// Dao is account dao.
type Dao struct {
c *conf.Config
// rpc
acc accapi.AccountClient
rela *relation.Service
// http client
client *httpx.Client
fastClient *httpx.Client
mc *memcache.Pool
mcExpire int32
// user
passURI string
relationURI string
richRelationURI string
picUpInfoURL string
blinkUpInfoURL string
upInfoURL string
}
// New new a dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
rela: relation.New(c.RelationRPC),
// http client
client: httpx.NewClient(c.HTTPClient.Normal),
fastClient: httpx.NewClient(c.HTTPClient.Fast),
passURI: c.Host.Passport + _pass,
relationURI: c.Host.API + _relation,
richRelationURI: c.Host.API + _richRelation,
picUpInfoURL: c.Host.Live + _picUpInfoURL,
blinkUpInfoURL: c.Host.Live + _blinkUpInfoURL,
upInfoURL: c.Host.API + _upInfoURL,
mc: memcache.NewPool(c.Memcache.Archive.Config),
mcExpire: int32(time.Duration(c.Memcache.Archive.TplExpire) / time.Second),
}
var err error
if d.acc, err = accapi.NewClient(c.AccClient); err != nil {
panic(err)
}
return
}
// Profile get account.
func (d *Dao) Profile(c context.Context, mid int64, ip string) (res *accapi.Profile, err error) {
var (
arg = &accapi.MidReq{
Mid: mid,
}
rpcRes *accapi.ProfileReply
)
if rpcRes, err = d.acc.Profile3(c, arg); err != nil {
log.Error("d.acc.Profile3 error(%v)", err)
err = ecode.CreativeAccServiceErr
}
if rpcRes != nil {
res = rpcRes.Profile
}
return
}
// ProfileWithStat get account.
func (d *Dao) ProfileWithStat(c context.Context, mid int64) (res *accapi.ProfileStatReply, err error) {
var (
arg = &accapi.MidReq{
Mid: mid,
}
)
if res, err = d.acc.ProfileWithStat3(c, arg); err != nil {
log.Error("d.acc.ProfileWithStat3() error(%v)", err)
err = ecode.CreativeAccServiceErr
}
return
}
// Card get account.
func (d *Dao) Card(c context.Context, mid int64, ip string) (res *accapi.Card, err error) {
var (
rpcRes *accapi.CardReply
arg = &accapi.MidReq{
Mid: mid,
}
)
if rpcRes, err = d.acc.Card3(c, arg); err != nil {
log.Error("d.acc.Card3() error(%v)", err)
err = ecode.CreativeAccServiceErr
}
if rpcRes != nil {
res = rpcRes.Card
}
return
}
// Cards get cards from rpc
func (d *Dao) Cards(c context.Context, mids []int64, ip string) (cards map[int64]*accapi.Card, err error) {
if len(mids) == 0 {
return
}
arg := &accapi.MidsReq{
Mids: mids,
}
var reply *accapi.CardsReply
if reply, err = d.acc.Cards3(c, arg); err != nil {
log.Error("d.acc.Cards3 error(%v) | mids(%v) ip(%s) arg(%v)", err, mids, ip, arg)
err = ecode.CreativeAccServiceErr
return
}
cards = reply.Cards
return
}
// PhoneEmail get user email & phone
func (d *Dao) PhoneEmail(c context.Context, ck, ip string) (ct *appeal.Contact, err error) {
params := url.Values{}
params.Set("Cookie", ck)
// init req set cookie
req, err := http.NewRequest("GET", d.passURI, nil)
if err != nil {
log.Error("passport url(%s) error(%v)", d.passURI, err)
return
}
req.Header.Set("Cookie", ck)
req.Header.Set("X-BACKEND-BILI-REAL-IP", ip)
var res struct {
Code int `json:"code"`
Data *appeal.Contact `json:"data"`
}
if err = d.client.Do(c, req, &res); err != nil {
log.Error("passport url(%s) response(%+v) error(%v)", d.passURI+"?"+params.Encode(), res, err)
err = ecode.CreativeAccServiceErr
return
}
if res.Code != 0 {
log.Error("passport url(%s) res(%v)", d.passURI, res)
err = ecode.CreativeAccServiceErr
return
}
ct = res.Data
return
}
// RichRelation get multi user relations
func (d *Dao) RichRelation(c context.Context, owner int64, mids []int64, ip string) (richRel map[int64]int32, err error) {
var rpcRes *accapi.RichRelationsReply
if rpcRes, err = d.acc.RichRelations3(c, &accapi.RichRelationReq{Owner: owner, Mids: mids}); err != nil {
log.Error("d.acc.RichRelations3(%d, %v) error(%v)", owner, mids, err)
err = ecode.CreativeAccServiceErr
}
if rpcRes != nil {
richRel = rpcRes.RichRelations
}
return
}
// Followers get users only follower relation which attr eq 2 with errgroup
func (d *Dao) Followers(c context.Context, owner int64, mids []int64, ip string) (relations map[int64]int, err error) {
relations = make(map[int64]int, len(mids))
type midRel struct {
mid int64
rel int
}
rechan := make(chan midRel, len(mids)) // avoid concurrent write map
g, ctx := errgroup.WithContext(c)
for _, mid := range mids {
var mid2 = mid // for closure, copy to avoid same mid
g.Go(func() error {
rl, e := d.acc.Relation3(ctx, &accapi.RelationReq{Mid: mid2, Owner: owner})
if e != nil || rl == nil || !rl.Following {
if e != nil {
log.Error("d.acc.Relation3(mid:%d,owner:%d,relation:%v) error(%v)", mid2, owner, rl, e)
}
rechan <- midRel{mid2, 1}
} else {
rechan <- midRel{mid2, 2}
}
return nil
})
}
g.Wait()
for i := 0; i < len(mids); i++ {
wc := <-rechan
relations[wc.mid] = wc.rel
}
return
}
// Infos get user info by mids.
func (d *Dao) Infos(c context.Context, mids []int64, ip string) (res map[int64]*accapi.Info, err error) {
res = make(map[int64]*accapi.Info)
if len(mids) == 0 {
return
}
var arg = &accapi.MidsReq{
Mids: mids,
}
var rpcRes *accapi.InfosReply
if rpcRes, err = d.acc.Infos3(c, arg); err != nil {
log.Error("d.acc.Infos3() error(%v)|ip(%s)", err, ip)
err = ecode.CreativeAccServiceErr
}
if rpcRes != nil {
res = rpcRes.Infos
}
return
}
// IdentifyInfo 获取用户实名认证状态
// tel_status int 0未绑定1已绑定有效手机号 2绑定虚拟号段170/171
// identification int 身份证绑定状态0:未绑定 1:已绑定
func (d *Dao) IdentifyInfo(c context.Context, mid int64, phoneOnly int8, ip string) (ret int, err error) {
var (
rpcRes *accapi.ProfileReply
arg = &accapi.MidReq{
Mid: mid,
}
mf *accapi.Profile
)
if rpcRes, err = d.acc.Profile3(c, arg); err != nil {
log.Error("d.acc.Profile3 error(%v) | mid(%d) ip(%s) arg(%v)", err, mid, ip, arg)
err = ecode.CreativeAccServiceErr
return
}
if rpcRes != nil {
mf = rpcRes.Profile
}
//switch for FrontEnd return json format
ret = d.switchPhoneRet(int(mf.TelStatus))
if phoneOnly == 1 {
return
}
if mf.TelStatus == 1 || mf.Identification == 1 {
return 0, err
}
return
}
// MidByName 获取mid
func (d *Dao) MidByName(c context.Context, name string) (mid int64, err error) {
var (
rpcRes *accapi.InfosReply
arg = &accapi.NamesReq{
Names: []string{name},
}
infos map[int64]*accapi.Info
)
if rpcRes, err = d.acc.InfosByName3(c, arg); err != nil {
log.Error("d.acc.InfosByName3 error(%v)", err)
err = ecode.CreativeAccServiceErr
return
}
if rpcRes != nil {
infos = rpcRes.Infos
}
for _, v := range infos {
if v != nil && v.Name == name {
return v.Mid, nil
}
}
err = ecode.AccountInexistence
return
}
// 0: "已实名认证",
// 1: "根据国家实名制认证的相关要求您需要换绑一个非170/171的手机号才能继续进行操作。",
// 2: "根据国家实名制认证的相关要求,您需要绑定手机号,才能继续进行操作。",
func (d *Dao) switchPhoneRet(newV int) (oldV int) {
switch newV {
case 0:
oldV = 2
case 1:
oldV = 0
case 2:
oldV = 1
}
return
}
// CheckIdentify fn
func (d *Dao) CheckIdentify(identify int) (err error) {
switch identify {
case 0:
err = nil
case 1:
err = ecode.UserCheckInvalidPhone
case 2:
err = ecode.UserCheckNoPhone
}
return
}
// RelationFollowers get all relation state.
func (d *Dao) RelationFollowers(c context.Context, mid int64, ip string) (res map[int64]int32, err error) {
var fls []*relaMdl.Following
if fls, err = d.rela.Followers(c, &relaMdl.ArgMid{Mid: mid, RealIP: ip}); err != nil {
log.Error("d.rela.Followers mid(%d)|ip(%s)|error(%v)", mid, ip, err)
return
}
if len(fls) == 0 {
log.Info("d.rela.Followers mid(%d)|ip(%s)", mid, ip)
return
}
res = make(map[int64]int32, len(fls))
for _, v := range fls {
res[v.Mid] = int32(v.Attribute)
}
log.Info("d.rela.Followers mid(%d)|res(%+v)|ip(%s)", mid, res, ip)
return
}
// Relations get all relation state.
func (d *Dao) Relations(c context.Context, mid int64, fids []int64, ip string) (res map[int64]int, err error) {
var rls map[int64]*relaMdl.Following
if rls, err = d.rela.Relations(c, &relaMdl.ArgRelations{Mid: mid, Fids: fids, RealIP: ip}); err != nil {
log.Error("d.rela.Relations mid(%d)|ip(%s)|error(%v)", mid, ip, err)
err = ecode.CreativeAccServiceErr
return
}
if len(rls) == 0 {
log.Info("d.rela.Relations mid(%d)|ip(%s)", mid, ip)
return
}
res = make(map[int64]int, len(rls))
for _, v := range rls {
res[v.Mid] = int(v.Attribute)
}
log.Info("d.rela.Relations mid(%d)|res(%+v)|rls(%+v)|ip(%s)", mid, res, rls, ip)
return
}
// Relations2
func (d *Dao) Relations2(c context.Context, mid int64, fids []int64, ip string) (res map[int64]int, err error) {
if res, err = d.Relations(c, mid, fids, ip); err != nil {
return
}
for k, v := range res {
if v == 2 || v == 6 { //2表示我关注他,6表示双向关注,为了兼容客户端统一吐出6作为已关注状态.
res[k] = 6
} else {
delete(res, k)
}
}
return
}
// ShouldFollow fn
func (d *Dao) ShouldFollow(c context.Context, mid int64, fids []int64, ip string) (shouldMids []int64, err error) {
var rls map[int64]*relaMdl.Following
if rls, err = d.rela.Relations(c, &relaMdl.ArgRelations{Mid: mid, Fids: fids, RealIP: ip}); err != nil {
log.Error("d.rela.Relations mid(%d)|fids(%+v)|ip(%s)|error(%v)", mid, fids, ip, err)
return
}
if len(rls) == 0 {
shouldMids = fids
return
}
shouldMids = make([]int64, 0)
for _, v := range rls {
if v.Attribute == 0 {
shouldMids = append(shouldMids, v.Mid)
}
}
log.Info("d.rela.Relations mid(%d)|shouldMids(%+v)|ip(%s)", mid, shouldMids, ip)
return
}

View File

@@ -0,0 +1,344 @@
package account
import (
"context"
"flag"
"go-common/app/interface/main/creative/conf"
accapi "go-common/app/service/main/account/api"
relaMdl "go-common/app/service/main/relation/model"
relation "go-common/app/service/main/relation/rpc/client"
"go-common/library/ecode"
"os"
"reflect"
"strings"
"testing"
"github.com/bouk/monkey"
"github.com/golang/mock/gomock"
. "github.com/smartystreets/goconvey/convey"
gock "gopkg.in/h2non/gock.v1"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.archive.creative")
flag.Set("conf_token", "96b6a6c10bb311e894c14a552f48fef8")
flag.Set("tree_id", "2305")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../../cmd/creative.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
m.Run()
os.Exit(0)
}
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
d.client.SetTransport(gock.DefaultTransport)
d.fastClient.SetTransport(gock.DefaultTransport)
return r
}
func TestIdentifyInfo(t *testing.T) {
Convey("IdentifyInfo", t, WithMock(t, func(mockCtrl *gomock.Controller) {
var (
c = context.TODO()
err error
mid = int64(27515256)
ip = "127.0.0.1"
ret int
)
mock := accapi.NewMockAccountClient(mockCtrl)
d.acc = mock
arg := &accapi.MidReq{
Mid: mid,
}
mock.EXPECT().Profile3(gomock.Any(), arg).Return(nil, ecode.CreativeAccServiceErr)
ret, err = d.IdentifyInfo(c, mid, 1, ip)
So(err, ShouldNotBeNil)
So(ret, ShouldNotBeNil)
}))
}
func TestMidByName(t *testing.T) {
Convey("IdentifyInfo", t, WithMock(t, func(mockCtrl *gomock.Controller) {
var (
c = context.TODO()
err error
ret int64
name = "iamname"
)
mock := accapi.NewMockAccountClient(mockCtrl)
d.acc = mock
arg := &accapi.NamesReq{
Names: []string{name},
}
mock.EXPECT().InfosByName3(gomock.Any(), arg).Return(nil, ecode.CreativeAccServiceErr)
ret, err = d.MidByName(c, name)
So(err, ShouldNotBeNil)
So(ret, ShouldBeZeroValue)
}))
}
func TestInfos(t *testing.T) {
Convey("IdentifyInfo", t, WithMock(t, func(mockCtrl *gomock.Controller) {
var (
c = context.TODO()
err error
mids = []int64{2089809}
ip = "127.0.0.1"
)
mock := accapi.NewMockAccountClient(mockCtrl)
d.acc = mock
mockReq := &accapi.MidsReq{
Mids: mids,
}
mock.EXPECT().Infos3(gomock.Any(), mockReq).Return(nil, ecode.CreativeAccServiceErr)
_, err = d.Infos(c, mids, ip)
So(err, ShouldNotBeNil)
}))
}
func TestProfile(t *testing.T) {
Convey("Profile", t, WithMock(t, func(mockCtrl *gomock.Controller) {
var (
c = context.TODO()
err error
mid = int64(27515256)
ip = "127.0.0.1"
p *accapi.Profile
)
mock := accapi.NewMockAccountClient(mockCtrl)
d.acc = mock
mockReq := &accapi.MidReq{
Mid: mid,
}
mock.EXPECT().Profile3(gomock.Any(), mockReq).Return(nil, ecode.CreativeAccServiceErr)
p, err = d.Profile(c, mid, ip)
So(err, ShouldNotBeNil)
So(p, ShouldBeNil)
}))
}
func TestProfileWithStat(t *testing.T) {
Convey("ProfileWithStat", t, WithMock(t, func(mockCtrl *gomock.Controller) {
var (
c = context.TODO()
err error
mid = int64(27515256)
p *accapi.ProfileStatReply
)
mock := accapi.NewMockAccountClient(mockCtrl)
d.acc = mock
mockReq := &accapi.MidReq{
Mid: mid,
}
mock.EXPECT().ProfileWithStat3(gomock.Any(), mockReq).Return(nil, ecode.CreativeAccServiceErr)
p, err = d.ProfileWithStat(c, mid)
So(err, ShouldNotBeNil)
So(p, ShouldBeNil)
}))
}
func TestCard(t *testing.T) {
Convey("Card", t, WithMock(t, func(mockCtrl *gomock.Controller) {
var (
c = context.TODO()
err error
mid = int64(27515256)
ip = "127.0.0.1"
ret *accapi.Card
)
mock := accapi.NewMockAccountClient(mockCtrl)
d.acc = mock
mockReq := &accapi.MidReq{
Mid: mid,
}
mock.EXPECT().Card3(gomock.Any(), mockReq).Return(nil, ecode.CreativeAccServiceErr)
ret, err = d.Card(c, mid, ip)
So(err, ShouldNotBeNil)
So(ret, ShouldBeNil)
}))
}
func TestRichRelation(t *testing.T) {
Convey("RichRelation", t, WithMock(t, func(mockCtrl *gomock.Controller) {
var (
c = context.TODO()
err error
owner = int64(27515256)
mids = []int64{2089809}
ip = "127.0.0.1"
ret map[int64]int32
)
mock := accapi.NewMockAccountClient(mockCtrl)
d.acc = mock
arg := &accapi.RichRelationReq{
Owner: owner,
Mids: mids,
}
mock.EXPECT().RichRelations3(gomock.Any(), arg).Return(nil, ecode.CreativeAccServiceErr)
ret, err = d.RichRelation(c, owner, mids, ip)
So(err, ShouldNotBeNil)
So(ret, ShouldBeNil)
}))
}
func TestRelationFollowers(t *testing.T) {
Convey("RelationFollowers", t, func(ctx C) {
var (
c = context.TODO()
err error
mid = int64(2089809)
ip = "127.0.0.1"
ret map[int64]int32
)
mock := monkey.PatchInstanceMethod(reflect.TypeOf(d.rela), "Followers",
func(_ *relation.Service, _ context.Context, _ *relaMdl.ArgMid) (res []*relaMdl.Following, err error) {
return nil, ecode.CreativeAccServiceErr
})
defer mock.Unpatch()
ret, err = d.RelationFollowers(c, mid, ip)
ctx.Convey("RelationFollowers", func(ctx C) {
ctx.So(err, ShouldNotBeNil)
ctx.So(ret, ShouldBeNil)
})
})
}
func TestShouldFollow(t *testing.T) {
Convey("ShouldFollow", t, func(ctx C) {
var (
c = context.TODO()
err error
mid = int64(2089809)
fids = []int64{2089809}
ip = "127.0.0.1"
ret []int64
)
mock := monkey.PatchInstanceMethod(reflect.TypeOf(d.rela), "Relations",
func(_ *relation.Service, _ context.Context, _ *relaMdl.ArgRelations) (res map[int64]*relaMdl.Following, err error) {
res = make(map[int64]*relaMdl.Following)
res[2089809] = &relaMdl.Following{
Attribute: 0,
}
return res, nil
})
defer mock.Unpatch()
ret, err = d.ShouldFollow(c, mid, fids, ip)
ctx.Convey("RelationFollowers", func(ctx C) {
ctx.So(err, ShouldBeNil)
ctx.So(ret, ShouldNotBeNil)
})
})
}
func TestSwitchPhoneRet(t *testing.T) {
var (
new, old, identify int
err error
)
new = 1
Convey("switchPhoneRet", t, func(ctx C) {
old = d.switchPhoneRet(new)
ctx.Convey("Then err should be nil.has should not be nil.", func(ctx C) {
ctx.So(old, ShouldBeZeroValue)
})
})
identify = 1
Convey("CheckIdentify", t, func(ctx C) {
err = d.CheckIdentify(identify)
ctx.Convey("Then err should be nil.has should not be nil.", func(ctx C) {
ctx.So(err, ShouldEqual, ecode.UserCheckInvalidPhone)
})
})
}
func TestDao_Followers(t *testing.T) {
Convey("Followers", t, WithMock(t, func(mockCtrl *gomock.Controller) {
var (
c = context.TODO()
err error
mid = int64(2089809)
fid = int64(2089809)
ip = "127.0.0.1"
)
mock := accapi.NewMockAccountClient(mockCtrl)
d.acc = mock
arg := &accapi.RelationReq{
Owner: mid,
Mid: fid,
}
mock.EXPECT().Relation3(gomock.Any(), arg).Return(nil, ecode.CreativeAccServiceErr)
_, err = d.Followers(c, mid, []int64{fid}, ip)
Convey("Followers", func(ctx C) {
ctx.So(err, ShouldBeNil)
})
}))
}
func TestDao_Relations(t *testing.T) {
Convey("Relations", t, func(ctx C) {
var (
c = context.TODO()
err error
mid = int64(2089809)
fids = []int64{2089809}
ip = "127.0.0.1"
ret map[int64]int
)
mock := monkey.PatchInstanceMethod(reflect.TypeOf(d.rela), "Relations",
func(_ *relation.Service, _ context.Context, _ *relaMdl.ArgRelations) (res map[int64]*relaMdl.Following, err error) {
return nil, ecode.CreativeAccServiceErr
})
defer mock.Unpatch()
ret, err = d.Relations(c, mid, fids, ip)
ctx.Convey("RelationFollowers", func(ctx C) {
ctx.So(err, ShouldNotBeNil)
ctx.So(ret, ShouldBeNil)
})
})
}
func TestDao_Relations2(t *testing.T) {
Convey("Relations2", t, func(ctx C) {
var (
c = context.TODO()
err error
mid = int64(2089809)
fids = []int64{2089809}
ip = "127.0.0.1"
ret map[int64]int
)
mock := monkey.PatchInstanceMethod(reflect.TypeOf(d.rela), "Relations",
func(_ *relation.Service, _ context.Context, _ *relaMdl.ArgRelations) (res map[int64]*relaMdl.Following, err error) {
return nil, ecode.CreativeAccServiceErr
})
defer mock.Unpatch()
ret, err = d.Relations2(c, mid, fids, ip)
ctx.Convey("RelationFollowers", func(ctx C) {
ctx.So(err, ShouldNotBeNil)
ctx.So(ret, ShouldBeNil)
})
})
}
func WithMock(t *testing.T, f func(mock *gomock.Controller)) func() {
return func() {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
f(mockCtrl)
}
}

View File

@@ -0,0 +1,87 @@
package account
import (
"context"
"strconv"
accmdl "go-common/app/interface/main/creative/model/account"
"go-common/library/cache/memcache"
"go-common/library/log"
)
const (
_upInfoPrefix = "upinfo_"
_addMidHalfMinPrefix = "add_midhafmin_"
)
func limitMidHafMin(mid int64) string {
return _addMidHalfMinPrefix + strconv.FormatInt(mid, 10)
}
func keyUpInfo(mid int64) string {
return _upInfoPrefix + strconv.FormatInt(mid, 10)
}
// HalfMin fn
func (d *Dao) HalfMin(c context.Context, mid int64) (exist bool, ts uint64, err error) {
var (
conn = d.mc.Get(c)
rp *memcache.Item
)
defer conn.Close()
key := limitMidHafMin(mid)
rp, err = conn.Get(key)
if err != nil {
if err == memcache.ErrNotFound {
err = nil
} else {
log.Error("conn.Get error(%v) | key(%s) mid(%d)", err, key, mid)
}
return
}
if err = conn.Scan(rp, &ts); err != nil {
log.Error("conn.Scan(%s) error(%v)", rp.Value, err)
return
}
log.Info("HalfMin (%d) | key(%s) ts(%d)", mid, key, ts)
if ts != 0 {
exist = true
}
return
}
// UpInfoCache get stat cache.
func (d *Dao) UpInfoCache(c context.Context, mid int64) (st *accmdl.UpInfo, err error) {
var (
conn = d.mc.Get(c)
r *memcache.Item
)
defer conn.Close()
r, err = conn.Get(keyUpInfo(mid))
if err != nil {
if err == memcache.ErrNotFound {
err = nil
} else {
log.Error("conn.Get2(%d) error(%v)", mid, err)
}
return
}
if err = conn.Scan(r, &st); err != nil {
log.Error("json.Unmarshal(%s) error(%v)", r.Value, err)
st = nil
}
return
}
// AddUpInfoCache add stat cache.
func (d *Dao) AddUpInfoCache(c context.Context, mid int64, st *accmdl.UpInfo) (err error) {
var (
key = keyUpInfo(mid)
)
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: key, Object: st, Flags: memcache.FlagJSON, Expiration: d.mcExpire}); err != nil {
log.Error("memcache.Set(%v) error(%v)", key, err)
}
return
}

View File

@@ -0,0 +1,87 @@
package account
import (
"context"
accmdl "go-common/app/interface/main/creative/model/account"
"go-common/library/cache/memcache"
"reflect"
"testing"
"github.com/bouk/monkey"
"github.com/smartystreets/goconvey/convey"
)
func TestAccountlimitMidHafMin(t *testing.T) {
var (
mid = int64(2089809)
)
convey.Convey("limitMidHafMin", t, func(ctx convey.C) {
p1 := limitMidHafMin(mid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestAccountkeyUpInfo(t *testing.T) {
var (
mid = int64(2089809)
)
convey.Convey("keyUpInfo", t, func(ctx convey.C) {
p1 := keyUpInfo(mid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestAccountHalfMin(t *testing.T) {
var (
c = context.TODO()
mid = int64(2089809)
)
convey.Convey("HalfMin", t, func(ctx convey.C) {
exist, ts, err := d.HalfMin(c, mid)
ctx.Convey("Then err should be nil.exist,ts should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(ts, convey.ShouldNotBeNil)
ctx.So(exist, convey.ShouldNotBeNil)
})
})
}
func TestAccountUpInfoCache(t *testing.T) {
var (
c = context.TODO()
mid = int64(2089809)
)
convey.Convey("UpInfoCache", t, func(ctx convey.C) {
connGuard := monkey.PatchInstanceMethod(reflect.TypeOf(d.mc), "Get", func(_ *memcache.Pool, _ context.Context) memcache.Conn {
return memcache.MockWith(memcache.ErrNotFound)
})
defer connGuard.Unpatch()
st, err := d.UpInfoCache(c, mid)
ctx.Convey("Then err should be nil.st should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(st, convey.ShouldBeNil)
})
})
}
func TestAccountAddUpInfoCache(t *testing.T) {
var (
c = context.TODO()
mid = int64(2089809)
st = &accmdl.UpInfo{}
)
convey.Convey("AddUpInfoCache", t, func(ctx convey.C) {
connGuard := monkey.PatchInstanceMethod(reflect.TypeOf(d.mc), "Get", func(_ *memcache.Pool, _ context.Context) memcache.Conn {
return memcache.MockWith(nil)
})
defer connGuard.Unpatch()
err := d.AddUpInfoCache(c, mid, st)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}

View File

@@ -0,0 +1,70 @@
package account
import (
"context"
"net/url"
"strconv"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_picUpInfoURL = "/link_draw_ex/v0/doc/check"
_blinkUpInfoURL = "/clip_ext/v0/video/have"
_upInfoURL = "/x/internal/uper/info"
)
// Pic pic return value
type Pic struct {
Has int `json:"has_doc"`
}
// Blink blink return value
type Blink struct {
Has int `json:"has"`
}
// Pic get pic up info.
func (d *Dao) Pic(c context.Context, mid int64, ip string) (has int, err error) {
params := url.Values{}
params.Set("uid", strconv.FormatInt(mid, 10))
var res struct {
Code int `json:"code"`
Data Pic `json:"data"`
}
err = d.fastClient.Get(c, d.picUpInfoURL, ip, params, &res)
if err != nil {
log.Error("d.fastClient.Get(%s) error(%v)", d.picUpInfoURL+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("Pic url(%s) error(%v)", d.picUpInfoURL+"?"+params.Encode(), err)
err = ecode.Int(res.Code)
return
}
has = res.Data.Has
return
}
// Blink get BLink up info.
func (d *Dao) Blink(c context.Context, mid int64, ip string) (has int, err error) {
params := url.Values{}
params.Set("uid", strconv.FormatInt(mid, 10))
var res struct {
Code int `json:"code"`
Data Blink `json:"data"`
}
err = d.fastClient.Get(c, d.blinkUpInfoURL, ip, params, &res)
if err != nil {
log.Error("d.fastClient.Get(%s) error(%v)", d.blinkUpInfoURL+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("Blink url(%s) error(%v)", d.blinkUpInfoURL+"?"+params.Encode(), err)
err = ecode.Int(res.Code)
return
}
has = res.Data.Has
return
}

View File

@@ -0,0 +1,60 @@
package account
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
gock "gopkg.in/h2non/gock.v1"
)
const (
mid = int64(2089809)
ip = "127.0.0.1"
)
func TestPhoneEmail(t *testing.T) {
var (
c = context.TODO()
ck = "iamck"
)
convey.Convey("PhoneEmail", t, func(ctx convey.C) {
defer gock.OffAll()
httpMock("GET", d.passURI).Reply(200).JSON(`{"code":20007}`)
ret, err := d.PhoneEmail(c, ck, ip)
ctx.Convey("Then err should be nil.ret should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(ret, convey.ShouldBeNil)
})
})
}
func TestAccountPic(t *testing.T) {
var (
c = context.TODO()
)
convey.Convey("Pic", t, func(ctx convey.C) {
defer gock.OffAll()
httpMock("GET", d.picUpInfoURL).Reply(200).JSON(`{"code":0,"data":{"has_doc":100}}`)
has, err := d.Pic(c, mid, ip)
ctx.Convey("Then err should be nil.has should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(has, convey.ShouldNotBeNil)
})
})
}
func TestAccountBlink(t *testing.T) {
var (
c = context.TODO()
)
convey.Convey("Blink", t, func(ctx convey.C) {
defer gock.OffAll()
httpMock("GET", d.blinkUpInfoURL).Reply(200).JSON(`{"code":0,"data":{"has":100}}`)
has, err := d.Blink(c, mid, ip)
ctx.Convey("Then err should be nil.has should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(has, convey.ShouldNotBeNil)
})
})
}