apple: release type (apple.releaseType, apple release --after-approval|--manual), device-family preflight, TestFlight invite needs an installable build
This commit is contained in:
parent
4763862178
commit
85cf494c0a
24 changed files with 899 additions and 18 deletions
|
|
@ -76,6 +76,10 @@ const LISTS: Record<string, { type: string; one?: boolean }> = {
|
|||
'apps/promotedPurchases': { type: 'promotedPurchases' },
|
||||
'subscriptions/winBackOffers': { type: 'winBackOffers' },
|
||||
'betaGroups/betaTesters': { type: 'betaTesters' },
|
||||
'betaGroups/builds': { type: 'builds' },
|
||||
'builds/buildBetaDetail': { type: 'buildBetaDetails', one: true },
|
||||
'builds/betaAppReviewSubmission': { type: 'betaAppReviewSubmissions', one: true },
|
||||
'buildBundles/buildBundleFileSizes': { type: 'buildBundleFileSizes' },
|
||||
'apps/analyticsReportRequests': { type: 'analyticsReportRequests' },
|
||||
'apps/assetLibrary': { type: 'appAssetLibraries', one: true },
|
||||
'appAssetLibraries/images': { type: 'appAssetLibraryImages' },
|
||||
|
|
@ -162,6 +166,21 @@ export class FakeAsc {
|
|||
return { type: r.type, id: r.id, attributes: r.attributes, relationships };
|
||||
}
|
||||
|
||||
/** Whether a group of the tester has a build its testers can install (external: BETA_APPROVED / IN_BETA_TESTING; internal: READY_FOR_BETA_TESTING / IN_BETA_TESTING). */
|
||||
hasInstallableBuild(testerId: string): boolean {
|
||||
const gids = [this.res.get(testerId)?.rels.betaGroups ?? []].flat();
|
||||
return gids.some(gid => {
|
||||
const g = this.res.get(gid);
|
||||
if (!g) return false;
|
||||
const internal = g.attributes.isInternalGroup === true;
|
||||
const builds = internal && g.attributes.hasAccessToAllBuilds === true ? this.all('builds') : this.children(gid, 'builds');
|
||||
return builds.some(b => {
|
||||
const st = String(this.children(b.id, 'buildBetaDetails')[0]?.attributes[internal ? 'internalBuildState' : 'externalBuildState'] ?? '');
|
||||
return internal ? ['READY_FOR_BETA_TESTING', 'IN_BETA_TESTING'].includes(st) : ['BETA_APPROVED', 'IN_BETA_TESTING'].includes(st);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
children(parent: string, type: string): R[] {
|
||||
return this.all(type).filter(r => Object.values(r.rels).some(v => (Array.isArray(v) ? v.includes(parent) : v === parent)));
|
||||
}
|
||||
|
|
@ -205,6 +224,11 @@ export class FakeAsc {
|
|||
if (v && v.attributes.state === 'DEVELOPER_REJECTED' && v.type !== 'appStoreVersions') v.attributes.state = 'READY_FOR_REVIEW';
|
||||
main.attributes.state ??= 'READY_FOR_REVIEW';
|
||||
}
|
||||
// seen live: inviting a tester whose groups have no installable build (an external build is installable after Beta App
|
||||
// Review) is 409 STATE_ERROR.TESTER_INVITE.NO_INSTALLABLE_BUILDS
|
||||
if (d.type === 'betaTesterInvitations' && !this.hasInstallableBuild(String(main.rels.betaTester)))
|
||||
return json({ errors: [{ id: '00000000-0000-0000-0000-000000000000', status: '409', code: 'STATE_ERROR.TESTER_INVITE.NO_INSTALLABLE_BUILDS', title: 'There are no installable builds',
|
||||
detail: 'The tester cannot be invited because the groups they belong to have no installable builds.' }] }, 409);
|
||||
const u = UNIQUE[d.type];
|
||||
if (u && this.all(d.type).some(r => u(r) === u(main as R)))
|
||||
return json({ errors: [{ status: '409', code: 'ENTITY_ERROR.ATTRIBUTE.INVALID.DUPLICATE', title: 'The provided entity includes an attribute with a value that has already been used', detail: 'already exists' }] }, 409);
|
||||
|
|
@ -267,7 +291,8 @@ export class FakeAsc {
|
|||
}
|
||||
if (!id) return json({ data: this.visible(this.filtered(this.all(type!), u.searchParams)).map(r => this.view(r)), links: {} });
|
||||
const self = this.res.get(id);
|
||||
if (!rel) return self && self.type === type ? json({ data: this.view(self) }) : json({ errors: [{ status: '404' }] }, 404);
|
||||
// include=<relationship>: the children of that type (a build's buildBundles)
|
||||
if (!rel) return self && self.type === type ? json({ data: this.view(self), included: (u.searchParams.get('include') ?? '').split(',').filter(Boolean).flatMap(t => this.children(self.id, t).map(r => this.view(r))) }) : json({ errors: [{ status: '404' }] }, 404);
|
||||
if (rel === 'relationships') return json({ data: this.children(id, rel2!).map(r => ({ type: r.type, id: r.id })) });
|
||||
// an availability's territories are the ids its create named (a to-many relationship, not child resources)
|
||||
if (rel === 'availableTerritories' && self) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue