1import chalk from 'chalk'; 2 3import * as Log from '../../../../log'; 4import { selectAsync } from '../../../../utils/prompts'; 5import * as Security from '../Security'; 6import { 7 resolveCertificateSigningIdentityAsync, 8 selectDevelopmentTeamAsync, 9} from '../resolveCertificateSigningIdentity'; 10import * as Settings from '../settings'; 11 12jest.mock('../../../../log'); 13jest.mock('../../../../utils/prompts'); 14const asMock = <T extends (...args: any[]) => any>(fn: T): jest.MockedFunction<T> => 15 fn as jest.MockedFunction<T>; 16 17jest.mock('../../../../utils/interactive', () => ({ 18 isInteractive: jest.fn(() => true), 19})); 20 21jest.mock('../settings', () => ({ 22 getLastDeveloperCodeSigningIdAsync: jest.fn(), 23 setLastDeveloperCodeSigningIdAsync: jest.fn(), 24})); 25 26jest.mock('../Security', () => ({ 27 resolveCertificateSigningInfoAsync: jest.fn(), 28 resolveIdentitiesAsync: jest.fn(), 29})); 30 31describe(selectDevelopmentTeamAsync, () => { 32 it(`formats prompt`, async () => { 33 const identities = [ 34 { 35 developmentTeams: [], 36 signingCertificateId: 'XXX', 37 codeSigningInfo: 'Apple Development: Evan Bacon (XXX)', 38 appleTeamName: '650 Industries, Inc.', 39 appleTeamId: 'A1BCDEF234', 40 }, 41 { 42 developmentTeams: [], 43 signingCertificateId: 'YYY', 44 codeSigningInfo: 'Apple Developer: Nave Nocab (YYY)', 45 appleTeamId: '12345ABCD', 46 }, 47 ]; 48 const preferredId = 'A1BCDEF234'; 49 await selectDevelopmentTeamAsync(identities, preferredId); 50 51 expect(selectAsync).toBeCalledWith('Development team for signing the app', [ 52 { 53 title: '650 Industries, Inc. (A1BCDEF234) - Apple Development: Evan Bacon (XXX)', 54 value: 0, 55 }, 56 { title: ' (12345ABCD) - Apple Developer: Nave Nocab (YYY)', value: 1 }, 57 ]); 58 }); 59}); 60 61describe(resolveCertificateSigningIdentityAsync, () => { 62 it(`asserts when no IDs are provided`, async () => { 63 const ids = []; 64 await expect(resolveCertificateSigningIdentityAsync(ids)).rejects.toThrow( 65 'No code signing certificates are available to use.' 66 ); 67 expect(Log.log).toBeCalledWith( 68 expect.stringMatching(/Your computer requires some additional setup/) 69 ); 70 }); 71 72 it(`prompts when there are more than one signing identities`, async () => { 73 asMock(Settings.getLastDeveloperCodeSigningIdAsync).mockResolvedValue('YYY'); 74 asMock(Security.resolveIdentitiesAsync).mockResolvedValueOnce([ 75 { 76 signingCertificateId: 'XXX', 77 codeSigningInfo: 'Apple Development: Evan Bacon (XXX)', 78 appleTeamName: '650 Industries, Inc.', 79 appleTeamId: 'A1BCDEF234', 80 }, 81 { 82 signingCertificateId: 'YYY', 83 codeSigningInfo: 'Apple Developer: Nave Nocab (YYY)', 84 appleTeamId: '12345ABCD', 85 }, 86 ]); 87 88 asMock(selectAsync).mockResolvedValueOnce(0); 89 90 await expect(resolveCertificateSigningIdentityAsync(['YYY', 'XXX'])).resolves.toEqual({ 91 appleTeamId: expect.any(String), 92 codeSigningInfo: expect.any(String), 93 signingCertificateId: 'YYY', 94 }); 95 96 expect(selectAsync).toBeCalledWith(expect.any(String), [ 97 { 98 // Formatted the preferred ID as bold and sorted it first. 99 title: chalk.bold(' (12345ABCD) - Apple Developer: Nave Nocab (YYY)'), 100 value: 0, 101 }, 102 expect.anything(), 103 ]); 104 105 // Store the preferred ID for the next time. 106 expect(Settings.setLastDeveloperCodeSigningIdAsync).toBeCalledWith('YYY'); 107 }); 108 109 it(`auto selects the first ID when there is only one`, async () => { 110 asMock(Security.resolveCertificateSigningInfoAsync).mockResolvedValue({ 111 signingCertificateId: 'XXX', 112 }); 113 114 await expect(resolveCertificateSigningIdentityAsync(['YYY'])).resolves.toEqual({ 115 signingCertificateId: 'XXX', 116 }); 117 118 // Ensure that we only store the value when the user manually selects it. 119 expect(Settings.setLastDeveloperCodeSigningIdAsync).toBeCalledTimes(0); 120 }); 121}); 122