Onboarding live apps without owner questions for what the stores and the code prove: storebound onboard imports the live products and subscriptions with USD / base prices (catalog diff clean), contact values, the App Review contact and demo account (credentials.json, masked), sign-in for review from Apple's review detail and auth code, and the account deletion page from the app's site; App Store keywords count characters (live fields up to 265 bytes accepted); validate accepts the 6.5-inch iPhone set and Play's default-language graphics fallback; Play Reporting API off gives the project's enable link and apps list falls back to local apps; accounts default <profile>; store-only apps (apps add --store --app-id) shown read-only in the desktop (pitfalls 43-52)
This commit is contained in:
parent
d2ce185441
commit
e5f148e534
55 changed files with 1648 additions and 158 deletions
|
|
@ -22,8 +22,10 @@ describe('rules', () => {
|
|||
expect(long.text.length).toBeLessThanOrEqual(100);
|
||||
expect(long.text.endsWith(',')).toBe(false);
|
||||
expect(long.dropped.at(-1)!.why).toBe('over 100');
|
||||
// multi-byte: 100 bytes, not characters
|
||||
expect(Buffer.byteLength(normalizeKeywords(Array.from({ length: 20 }, (_, i) => `日本語${i}`).join(',')).text)).toBeLessThanOrEqual(100);
|
||||
// multi-byte: 100 characters, not bytes (App Store Connect counts characters; pitfall 43)
|
||||
const ja = normalizeKeywords(Array.from({ length: 30 }, (_, i) => `日本語${i}`).join(',')).text;
|
||||
expect([...ja].length).toBeLessThanOrEqual(100);
|
||||
expect(Buffer.byteLength(ja)).toBeGreaterThan(100);
|
||||
});
|
||||
test('limits per store field, keyword rules, untranslated and identical text', () => {
|
||||
const c = checkFields('apple', { subtitle: 'x'.repeat(31), keywords: 'a, b,a', description: 'Same long description text' }, { description: 'Same long description text' }, 'draft');
|
||||
|
|
@ -98,11 +100,21 @@ describe('listing commands', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('listing check counts App Store keywords in UTF-8 bytes, the other fields in characters', () => {
|
||||
test('listing check counts App Store keywords in characters, like App Store Connect (pitfall 43)', () => {
|
||||
const ru = 'игра,бег,прыжки,монеты,уровни,рекорд,аркада,быстро'; // 50 characters, 93 bytes
|
||||
const kw = checkFields('apple', { keywords: ru, subtitle: 'Быстрая аркада' }).find(c => c.field === 'keywords')!;
|
||||
expect(kw).toMatchObject({ chars: 93, unit: 'bytes', problems: [] });
|
||||
expect(checkFields('apple', { keywords: ru + ',звук' }).find(c => c.field === 'keywords')!.problems).toContain('102 > 100 bytes');
|
||||
expect(kw).toMatchObject({ chars: 50, unit: 'chars', problems: [] });
|
||||
// live shape: a Thai field of 95 characters / 265 bytes, READY_FOR_SALE on the App Store
|
||||
const th = [...'ปลา,ตกปลา,เกมปลา,ทะเล,มหาสมุทร,ตู้ปลา,สัตว์น้ำ,ผ่อนคลาย,สะสม,ฉลาม,ปลาวาฬ,ปะการัง,ดำน้ำ,ฟาร์มปลา,เลี้ยงปลา'].slice(0, 95).join('');
|
||||
expect([...th].length).toBe(95);
|
||||
expect(Buffer.byteLength(th)).toBeGreaterThan(100);
|
||||
expect(checkFields('apple', { keywords: th }).find(c => c.field === 'keywords')!.problems).toEqual([]);
|
||||
// Turkish 100 characters / 105 bytes (live) passes; 101 characters does not
|
||||
const tr = 'balık,akvaryum,okyanus,deniz,köpekbalığı,mercan,dalış,sakin,rahatlatıcı,koleksiyon,çiftlik,yüzme,su'.slice(0, 100).padEnd(100, 'a');
|
||||
expect([...tr].length).toBe(100);
|
||||
expect(Buffer.byteLength(tr)).toBeGreaterThan(100);
|
||||
expect(checkFields('apple', { keywords: tr }).find(c => c.field === 'keywords')!.problems).toEqual([]);
|
||||
expect(checkFields('apple', { keywords: tr + 'b' }).find(c => c.field === 'keywords')!.problems).toContain('101 > 100 characters');
|
||||
expect(checkFields('apple', { subtitle: 'Быстрая аркада' })[0]).toMatchObject({ chars: 14, unit: 'chars' });
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue