fix: make Android tasks use extensions automatically and populate marketplace

This commit is contained in:
chenmingxuan committed 2026-10-14 22:32:38 +08:00
1 parent 6663233ab8
commit 9c82a40cbf
32 files changed
+341 -131

No files matched your search

@@ -0,0 +1,59 @@
import { TestBed } from '@angular/core/testing';
import { provideRouter } from '@angular/router';
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting, HttpTestingController } from '@angular/common/http/testing';
import { TaskPluginsComponent } from './task-plugins.component';
describe('TaskPluginsComponent', () => {
let http: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({ imports: [TaskPluginsComponent], providers: [provideRouter([]), provideHttpClient(), provideHttpClientTesting()] });
http = TestBed.inject(HttpTestingController);
});
afterEach(() => http.verify());
it('starts collapsed and automatic without an execution target selector', async () => {
const fixture = TestBed.createComponent(TaskPluginsComponent);
fixture.detectChanges();
http.expectNone('/api/plugins');
expect(fixture.nativeElement.textContent).toContain('自动');
expect(fixture.nativeElement.textContent).not.toContain('执行目标');
expect(fixture.nativeElement.querySelector('select')).toBeNull();
const emitted = jasmine.createSpy('changed');
fixture.componentInstance.changed.subscribe(emitted);
fixture.nativeElement.querySelector('button').click(); fixture.detectChanges();
http.expectOne('/api/plugins').flush({ plugins: [] });
await fixture.whenStable(); fixture.detectChanges();
fixture.nativeElement.querySelector('input').click(); fixture.detectChanges();
expect(emitted).toHaveBeenCalledWith({ plugins: [] });
fixture.nativeElement.querySelector('input').click(); fixture.detectChanges();
expect(emitted).toHaveBeenCalledWith({});
});
it('offers authorized cross-device connections and uses the default profile', async () => {
const fixture = TestBed.createComponent(TaskPluginsComponent);
const component = fixture.componentInstance;
component.toggle();
const plugin = { enabled: true, manifest: { id: 'desktop', name: '电脑控制', targets: ['computer', 'mixed'] }, profiles: [
{ name: 'default', label: '旧配置', authorized: false },
{ name: 'lab', label: '实验室', authorized: true, is_default: true }
] };
http.expectOne('/api/plugins').flush({ plugins: [plugin, { ...plugin, enabled: false, manifest: { ...plugin.manifest, id: 'disabled' } }] });
component.automatic = false; fixture.detectChanges(); await fixture.whenStable();
const emitted = jasmine.createSpy('changed'); component.changed.subscribe(emitted);
const checkbox = fixture.nativeElement.querySelector('.choice input');
checkbox.click(); fixture.detectChanges(); await fixture.whenStable();
expect(emitted).toHaveBeenCalledWith({ plugins: [{ id: 'desktop', profile: 'lab' }] });
expect(fixture.nativeElement.querySelectorAll('.choice').length).toBe(1);
expect(fixture.nativeElement.querySelector('select').textContent).not.toContain('旧配置');
});
it('shows a retryable error and keeps automatic mode on lookup failure', () => {
const fixture = TestBed.createComponent(TaskPluginsComponent);
fixture.componentInstance.toggle();
http.expectOne('/api/plugins').flush({}, { status: 503, statusText: 'Unavailable' });
fixture.detectChanges();
expect(fixture.nativeElement.textContent).toContain('重试');
expect(fixture.componentInstance.automatic).toBeTrue();
});
});