|
|
@@ -16,12 +16,12 @@ import { HomeDailyCacheService } from './home-daily-cache.service';
|
|
|
|
|
|
describe('appointment workflow screens',()=>{
|
|
|
let dataChanges:Subject<{source:'local'|'broadcast';changedAt:string}>;
|
|
|
- let failFeedback:boolean;
|
|
|
+ let failFeedback:boolean,failStart:boolean;
|
|
|
let order:Record<string,unknown>,failDetail:boolean,failCourses:boolean,courses:Record<string,unknown>[]|null,delayedUnits:Subject<unknown>|null,calls:Array<{action:string;params:Record<string,unknown>}>;
|
|
|
const user=signal({userId:30,groupId:3}),student=signal<unknown>(null),groupId=signal(3);
|
|
|
const response=(result:unknown)=>of({retcode:0,result});
|
|
|
beforeEach(()=>{
|
|
|
- localStorage.clear();sessionStorage.clear();calls=[];failFeedback=false;failDetail=false;failCourses=false;courses=null;delayedUnits=null;dataChanges=new Subject();user.set({userId:30,groupId:3});groupId.set(3);
|
|
|
+ localStorage.clear();sessionStorage.clear();calls=[];failFeedback=false;failStart=false;failDetail=false;failCourses=false;courses=null;delayedUnits=null;dataChanges=new Subject();user.set({userId:30,groupId:3});groupId.set(3);
|
|
|
order={GeneralID:901,szyh:20,pl:30,HoneyName:'测试学员',kcid:801,bindingId:'binding-1',courseCategoryKey:'word',yykcmc:'词表',dszt:0,bxrq:'2099-10-11',sdsd:'19:00',allowedActions:['start'],updatedAt:'2026-10-11T00:00:00Z'};
|
|
|
const invoke=(action:string,params:Record<string,unknown>={})=>{
|
|
|
calls.push({action,params});
|
|
|
@@ -32,7 +32,7 @@ describe('appointment workflow screens',()=>{
|
|
|
if(action==='app_lesson_courses')return failCourses?throwError(()=>new ApiError('课程读取失败')):response({items:courses||[{bindingId:'binding-1',GeneralID:5801,kcid:801,Title:'词表',categoryKey:order['courseCategoryKey'],scheduled:true,syjd:'{}'},{bindingId:'binding-2',GeneralID:5802,kcid:802,Title:'另一词库',categoryKey:'word',syjd:'{"822":"822@Unit 2@1"}'}]});
|
|
|
if(action==='app_lesson_unit_complete')return response({nodeId:params['nodeId'],total:300,learned:300,percent:100,syjd:JSON.stringify({[String(params['nodeId'])]:params['nodeId']+'@Unit@1'})});
|
|
|
if(action==='node_list')return delayedUnits||response([{NodeID:params['pid']==='802'?822:811,NodeName:'Unit 1'}]);
|
|
|
- if(action==='e_order_update_v2'){order={...order,dszt:10,allowedActions:['continue','complete']};return response({status:10});}
|
|
|
+ if(action==='e_order_update_v2'){if(failStart)return throwError(()=>new ApiError('学员账号已停用,请联系管理员核对账号状态'));order={...order,dszt:10,allowedActions:['continue','complete']};return response({status:10});}
|
|
|
if(action==='app_lesson_complete'){order={...order,dszt:30,allowedActions:['editFeedback'],reviewStatus:'pending',feedback:params['feedback']?{...JSON.parse(String(params['feedback'])),feedbackStatus:'submitted'}:{feedbackStatus:'pending',revision:'2026-10-13T00:00:00Z'}};return response({status:30});}
|
|
|
if(action==='app_lesson_feedback_update'){if(failFeedback)return throwError(()=>new ApiError('报告已被更新,请刷新详情后重试'));order={...order,feedback:{...JSON.parse(String(params['feedback'])),revision:'2026-10-13T00:00:00Z'}};return response({saved:true});}
|
|
|
if(action==='app_lesson_review'){order={...order,allowedActions:[],reviewStatus:'submitted',studentReview:{score:params['score'],comment:params['comment']}};return response({status:30});}
|
|
|
@@ -188,6 +188,23 @@ describe('appointment workflow screens',()=>{
|
|
|
component.toggleUnit({NodeID:811});component.startOrContinue();await harness.fixture.whenStable();
|
|
|
expect(TestBed.inject(Router).url).toContain('orderId=901');expect(TestBed.inject(Router).url).toContain('bindingId=binding-1');
|
|
|
});
|
|
|
+ it('keeps a start failure beside the fixed action button while preserving selected units for retry',async()=>{
|
|
|
+ failStart=true;
|
|
|
+ const {harness,component}=await screen();component.toggleUnit({NodeID:811});
|
|
|
+ (harness.routeNativeElement?.querySelector('.appointment-actions .primary-button') as HTMLButtonElement).click();
|
|
|
+ await harness.fixture.whenStable();harness.fixture.detectChanges();
|
|
|
+ expect(harness.routeNativeElement?.querySelector('.appointment-actions [role="alert"]')?.textContent).toContain('学员账号已停用');
|
|
|
+ expect(component.selectedUnits().has('811')).toBeTrue();expect(component.submitting()).toBeFalse();
|
|
|
+ expect(TestBed.inject(Router).url).not.toContain('/pages/stu/stu_abc');
|
|
|
+ failStart=false;component.startOrContinue();await harness.fixture.whenStable();
|
|
|
+ expect(TestBed.inject(Router).url).toContain('/pages/stu/stu_abc');
|
|
|
+ });
|
|
|
+ it('shows a blocked student account in the fixed action area without offering start',async()=>{
|
|
|
+ order={...order,allowedActions:[],blockedReason:'学员账号已停用,请联系管理员核对账号状态'};
|
|
|
+ const {harness}=await screen();
|
|
|
+ expect(harness.routeNativeElement?.querySelector('.appointment-actions [role="alert"]')?.textContent).toContain('学员账号已停用');
|
|
|
+ expect(harness.routeNativeElement?.querySelector('.appointment-actions .primary-button')).toBeNull();
|
|
|
+ });
|
|
|
it('lists every opened enrollment and switches units, progress and the classroom binding together',async()=>{
|
|
|
const {harness,component}=await screen();
|
|
|
const select=harness.routeNativeElement?.querySelector('select[aria-label="本次学习课本或词库"]') as HTMLSelectElement;
|