package rond import "testing" // 地点/活动冲突此前一条用例都没有:只造过「新增」,所以 placePick / activityPick // 与 UpdPlaces / UpdActs 分支始终没被执行过。差异页线上确实会提交这两类选择。 func TestBuildMergePlanPlaceClash(t *testing.T) { keyA := PlaceCoordKey(30.123456, 120.654321) keyB := PlaceCoordKey(31.000001, 121.000002) keyC := PlaceCoordKey(32.000003, 122.000004) pd := PlaceDiff{Changed: []PlaceConflict{ {Backup: Location{SrcPK: 11, Name: "备份名A"}, DB: StoredPlace{SrcPK: 1, Key: keyA, Name: "站内名A"}}, {Backup: Location{SrcPK: 12, Name: "备份名B"}, DB: StoredPlace{SrcPK: 2, Key: keyB, Name: "站内名B"}}, {Backup: Location{SrcPK: 13, Name: "备份名C"}, DB: StoredPlace{SrcPK: 3, Key: keyC, Name: "站内名C"}}, }} p := BuildMergePlan(VisitDiff{}, pd, ActivityDiff{}, Choices{ PlaceClash: map[string]string{keyA: PickBackup, keyB: PickDB}, }) if len(p.UpdPlaces) != 1 { t.Fatalf("只有选了「用实机」的地点该更新: %+v", p.UpdPlaces) } // 带的是备份侧那条的整份值;「改库里的哪一行」由配对(MatchPlaces)决定,计划里不再存键 if p.UpdPlaces[0].L.Name != "备份名A" { t.Fatalf("应带备份侧的值: %+v", p.UpdPlaces[0]) } if len(p.UpdVisits)+len(p.AddVisits)+len(p.UpdActs)+len(p.AddActs) != 0 { t.Fatal("没勾新增就不该带出到访/活动改动") } } func TestBuildMergePlanActivityClash(t *testing.T) { ad := ActivityDiff{Changed: []ActivityConflict{ {Backup: Activity{SrcPK: 21, Name: "散步"}, DB: StoredActivity{SrcPK: 3, Name: "走路", UUID: uuidC}}, {Backup: Activity{SrcPK: 22, Name: "跑步"}, DB: StoredActivity{SrcPK: 4, Name: "跑步"}}, {Backup: Activity{SrcPK: 23, Name: "游泳"}, DB: StoredActivity{SrcPK: 5, Name: "游泳", UUID: uuidA}}, }} p := BuildMergePlan(VisitDiff{}, PlaceDiff{}, ad, Choices{ ActClash: map[string]string{uuidC: PickBackup, "n:跑步": PickSkip}, }) if len(p.UpdActs) != 1 { t.Fatalf("只有选了「用实机」的活动该更新: %+v", p.UpdActs) } // 改名也能对上:选择是按「UUID(没有才退回名称)」提交的,配对早就发生在比对阶段 if p.UpdActs[0].A.Name != "散步" { t.Fatalf("应带备份侧的值: %+v", p.UpdActs[0]) } } // 删除是逐条勾选的事:没勾的「仅站内有」绝不顺手删掉,勾了的才进计划。 func TestBuildMergePlanDeletesOnlyWhenChecked(t *testing.T) { vd := VisitDiff{Removed: []StoredVisit{{SrcPK: 51}, {SrcPK: 52}}} pd := PlaceDiff{Removed: []StoredPlace{{SrcPK: 31}, {SrcPK: 32}}} ad := ActivityDiff{Removed: []StoredActivity{{SrcPK: 41}, {SrcPK: 42}}} p := BuildMergePlan(vd, pd, ad, Choices{ DelVisits: map[int]bool{52: true}, DelPlaces: map[int]bool{31: true}, DelActs: map[int]bool{42: true}, }) if len(p.DelVisits) != 1 || p.DelVisits[0].SrcPK != 52 { t.Fatalf("只该删勾了的那条到访: %+v", p.DelVisits) } if len(p.DelPlaces) != 1 || p.DelPlaces[0].SrcPK != 31 { t.Fatalf("只该删勾了的那个地点: %+v", p.DelPlaces) } if len(p.DelActs) != 1 || p.DelActs[0].SrcPK != 42 { t.Fatalf("只该删勾了的那个活动: %+v", p.DelActs) } } func TestAppendMissingDedupesBySrcPK(t *testing.T) { places := appendMissingPlaces( []Location{{SrcPK: 1, Name: "甲"}}, []Location{{SrcPK: 1, Name: "甲"}, {SrcPK: 2, Name: "乙"}}, ) if len(places) != 2 || places[1].SrcPK != 2 { t.Fatalf("同 src_pk 不该重复加入: %+v", places) } acts := appendMissingActs( []Activity{{SrcPK: 7, Name: "通勤"}}, []Activity{{SrcPK: 7, Name: "通勤"}, {SrcPK: 8, Name: "散步"}}, ) if len(acts) != 2 || acts[1].SrcPK != 8 { t.Fatalf("同 src_pk 不该重复加入: %+v", acts) } }