Skip to content

Commit c564e18

Browse files
authored
feat(extension): initial per-extension provisioning (#5749)
1 parent c40e217 commit c564e18

File tree

2 files changed

+122
-35
lines changed

2 files changed

+122
-35
lines changed

lib/services/ios/export-options-plist-service.ts

+33-1
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,39 @@ import { IProjectData, IBuildConfig } from "../../definitions/project";
44
import { IFileSystem } from "../../common/declarations";
55
import { injector } from "../../common/yok";
66
import { ITempService } from "../../definitions/temp-service";
7+
import * as constants from "../../constants";
78

89
export class ExportOptionsPlistService implements IExportOptionsPlistService {
9-
constructor(private $fs: IFileSystem, private $tempService: ITempService) {}
10+
constructor(
11+
private $fs: IFileSystem,
12+
private $tempService: ITempService,
13+
private $projectData: IProjectData
14+
) {}
15+
16+
private getExtensionProvisions() {
17+
const provisioningJSONPath = path.join(
18+
this.$projectData.getAppResourcesDirectoryPath(),
19+
"iOS",
20+
constants.NATIVE_EXTENSION_FOLDER,
21+
"provisioning.json"
22+
);
23+
if (!this.$fs.exists(provisioningJSONPath)) {
24+
return "";
25+
}
26+
27+
interface IProvisioningJSON {
28+
[identifier: string]: string;
29+
}
30+
const provisioningJSON = this.$fs.readJson(
31+
provisioningJSONPath
32+
) as IProvisioningJSON;
33+
34+
return Object.entries(provisioningJSON)
35+
.map(([id, provision]) => {
36+
return `<key>${id}</key>\n <string>${provision}</string>`;
37+
})
38+
.join("\n");
39+
}
1040

1141
public async createDevelopmentExportOptionsPlist(
1242
archivePath: string,
@@ -31,6 +61,7 @@ export class ExportOptionsPlistService implements IExportOptionsPlistService {
3161
<dict>
3262
<key>${projectData.projectIdentifiers.ios}</key>
3363
<string>${provision}</string>
64+
${this.getExtensionProvisions()}
3465
</dict>`;
3566
}
3667
plistTemplate += `
@@ -87,6 +118,7 @@ export class ExportOptionsPlistService implements IExportOptionsPlistService {
87118
<dict>
88119
<key>${projectData.projectIdentifiers.ios}</key>
89120
<string>${provision}</string>
121+
${this.getExtensionProvisions()}
90122
</dict>`;
91123
}
92124
plistTemplate += ` <key>method</key>

test/services/ios/export-options-plist-service.ts

+89-34
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,49 @@ import { Yok } from "../../../lib/common/yok";
22
import { ExportOptionsPlistService } from "../../../lib/services/ios/export-options-plist-service";
33
import { assert } from "chai";
44
import * as _ from "lodash";
5-
import { TempServiceStub } from "../../stubs";
5+
import { TempServiceStub, ProjectDataStub } from "../../stubs";
66

77
let actualPlistTemplate: string = null;
88
const projectName = "myProjectName";
99
const projectRoot = "/my/test/project/platforms/ios";
1010
const archivePath = "/my/test/archive/path";
1111

12+
let provisioningJSON: Record<string, any> | undefined;
13+
1214
function createTestInjector() {
1315
const injector = new Yok();
16+
provisioningJSON = undefined;
1417
injector.register("fs", {
18+
exists(path: string) {
19+
return path.endsWith("provisioning.json");
20+
},
1521
writeFile: (exportPath: string, plistTemplate: string) => {
1622
actualPlistTemplate = plistTemplate;
1723
},
24+
readJson() {
25+
return provisioningJSON ?? {};
26+
},
1827
});
1928
injector.register("exportOptionsPlistService", ExportOptionsPlistService);
2029
injector.register("tempService", TempServiceStub);
30+
const projectData = new ProjectDataStub();
31+
projectData.initializeProjectData(projectRoot);
32+
projectData.projectName = projectName;
33+
34+
injector.register("projectData", projectData);
2135

2236
return injector;
2337
}
2438

39+
function expectPlistTemplateToContain(template: string, expected: string) {
40+
const trimmedTemplate = template.replace(/\s/g, "");
41+
const trimmedExpected = expected.replace(/\s/g, "");
42+
assert.isTrue(
43+
trimmedTemplate.indexOf(trimmedExpected) !== -1,
44+
`Expected plist template to contain:\n\n${expected}\n\nbut it was:\n\n${template}`
45+
);
46+
}
47+
2548
describe("ExportOptionsPlistService", () => {
2649
describe("createDevelopmentExportOptionsPlist", () => {
2750
const testCases = [
@@ -33,21 +56,29 @@ describe("ExportOptionsPlistService", () => {
3356
name: "should create export options plist with provision",
3457
buildConfig: { provision: "myTestProvision" },
3558
expectedPlist:
36-
"<key>provisioningProfiles</key> <dict> <key>org.nativescript.myTestApp</key> <string>myTestProvision</string> </dict>",
59+
"<key>provisioningProfiles</key><dict><key>org.nativescript.myTestApp</key><string>myTestProvision</string></dict>",
3760
},
3861
{
39-
name:
40-
"should create export options plist with mobileProvisionIdentifier",
62+
name: "should create export options plist with mobileProvisionIdentifier",
4163
buildConfig: { mobileProvisionIdentifier: "myTestProvision" },
4264
expectedPlist:
43-
"<key>provisioningProfiles</key> <dict> <key>org.nativescript.myTestApp</key> <string>myTestProvision</string> </dict>",
65+
"<key>provisioningProfiles</key><dict><key>org.nativescript.myTestApp</key><string>myTestProvision</string></dict>",
4466
},
4567
{
46-
name:
47-
"should create export options plist with Production iCloudContainerEnvironment",
68+
name: "should create export options plist with Production iCloudContainerEnvironment",
4869
buildConfig: { iCloudContainerEnvironment: "Production" },
4970
expectedPlist:
50-
"<key>iCloudContainerEnvironment</key> <string>Production</string>",
71+
"<key>iCloudContainerEnvironment</key><string>Production</string>",
72+
},
73+
{
74+
name: "should add extension provisioning profiles if there are any",
75+
buildConfig: { provision: "myTestProvision" },
76+
provisioningJSON: {
77+
"org.nativescript.myTestApp.SampleExtension":
78+
"mySampleExtensionTestProvision",
79+
},
80+
expectedPlist:
81+
"<key>provisioningProfiles</key><dict><key>org.nativescript.myTestApp</key><string>myTestProvision</string><key>org.nativescript.myTestApp.SampleExtension</key><string>mySampleExtensionTestProvision</string></dict>",
5182
},
5283
];
5384

@@ -57,6 +88,9 @@ describe("ExportOptionsPlistService", () => {
5788
(provisionType) => {
5889
it(testCase.name, async () => {
5990
const injector = createTestInjector();
91+
if (testCase.provisioningJSON) {
92+
provisioningJSON = testCase.provisioningJSON;
93+
}
6094
const exportOptionsPlistService = injector.resolve(
6195
"exportOptionsPlistService"
6296
);
@@ -73,20 +107,23 @@ describe("ExportOptionsPlistService", () => {
73107
testCase.buildConfig
74108
);
75109

76-
const template = actualPlistTemplate.split("\n").join(" ");
77-
assert.isTrue(
78-
template.indexOf(
79-
`<key>method</key> <string>${provisionType}</string>`
80-
) > 0
110+
expectPlistTemplateToContain(
111+
actualPlistTemplate,
112+
`<key>method</key><string>${provisionType}</string>`
81113
);
82-
assert.isTrue(
83-
template.indexOf("<key>uploadBitcode</key> <false/>") > 0
114+
expectPlistTemplateToContain(
115+
actualPlistTemplate,
116+
`<key>uploadBitcode</key><false/>`
84117
);
85-
assert.isTrue(
86-
template.indexOf("<key>compileBitcode</key> <false/>") > 0
118+
expectPlistTemplateToContain(
119+
actualPlistTemplate,
120+
`<key>compileBitcode</key><false/>`
87121
);
88122
if (testCase.expectedPlist) {
89-
assert.isTrue(template.indexOf(testCase.expectedPlist) > 0);
123+
expectPlistTemplateToContain(
124+
actualPlistTemplate,
125+
testCase.expectedPlist
126+
);
90127
}
91128
});
92129
}
@@ -103,25 +140,37 @@ describe("ExportOptionsPlistService", () => {
103140
name: "should create export options plist with provision",
104141
buildConfig: { provision: "myTestProvision" },
105142
expectedPlist:
106-
"<key>provisioningProfiles</key> <dict> <key>org.nativescript.myTestApp</key> <string>myTestProvision</string> </dict>",
143+
"<key>provisioningProfiles</key><dict><key>org.nativescript.myTestApp</key><string>myTestProvision</string></dict>",
107144
},
108145
{
109-
name:
110-
"should create export options plist with mobileProvisionIdentifier",
146+
name: "should create export options plist with mobileProvisionIdentifier",
111147
buildConfig: { mobileProvisionIdentifier: "myTestProvision" },
112148
expectedPlist:
113-
"<key>provisioningProfiles</key> <dict> <key>org.nativescript.myTestApp</key> <string>myTestProvision</string> </dict>",
149+
"<key>provisioningProfiles</key><dict><key>org.nativescript.myTestApp</key><string>myTestProvision</string></dict>",
114150
},
115151
{
116152
name: "should create export options plist with teamID",
117153
buildConfig: { teamId: "myTeamId" },
118-
expectedPlist: "<key>teamID</key> <string>myTeamId</string>",
154+
expectedPlist: "<key>teamID</key><string>myTeamId</string>",
155+
},
156+
{
157+
name: "should add extension provisioning profiles if there are any",
158+
buildConfig: { provision: "myTestProvision" },
159+
provisioningJSON: {
160+
"org.nativescript.myTestApp.SampleExtension":
161+
"mySampleExtensionTestProvision",
162+
},
163+
expectedPlist:
164+
"<key>provisioningProfiles</key><dict><key>org.nativescript.myTestApp</key><string>myTestProvision</string><key>org.nativescript.myTestApp.SampleExtension</key><string>mySampleExtensionTestProvision</string></dict>",
119165
},
120166
];
121167

122168
_.each(testCases, (testCase) => {
123169
it(testCase.name, async () => {
124170
const injector = createTestInjector();
171+
if (testCase.provisioningJSON) {
172+
provisioningJSON = testCase.provisioningJSON;
173+
}
125174
const exportOptionsPlistService = injector.resolve(
126175
"exportOptionsPlistService"
127176
);
@@ -137,22 +186,28 @@ describe("ExportOptionsPlistService", () => {
137186
testCase.buildConfig
138187
);
139188

140-
const template = actualPlistTemplate.split("\n").join(" ");
141-
assert.isTrue(
142-
template.indexOf("<key>method</key> <string>app-store</string>") >
143-
0
189+
expectPlistTemplateToContain(
190+
actualPlistTemplate,
191+
`<key>method</key><string>app-store</string>`
144192
);
145-
assert.isTrue(
146-
template.indexOf("<key>uploadBitcode</key> <false/>") > 0
193+
expectPlistTemplateToContain(
194+
actualPlistTemplate,
195+
`<key>uploadBitcode</key><false/>`
147196
);
148-
assert.isTrue(
149-
template.indexOf("<key>compileBitcode</key> <false/>") > 0
197+
expectPlistTemplateToContain(
198+
actualPlistTemplate,
199+
`<key>compileBitcode</key><false/>`
150200
);
151-
assert.isTrue(
152-
template.indexOf("<key>uploadSymbols</key> <false/>") > 0
201+
expectPlistTemplateToContain(
202+
actualPlistTemplate,
203+
`<key>uploadSymbols</key><false/>`
153204
);
205+
154206
if (testCase.expectedPlist) {
155-
assert.isTrue(template.indexOf(testCase.expectedPlist) > 0);
207+
expectPlistTemplateToContain(
208+
actualPlistTemplate,
209+
testCase.expectedPlist
210+
);
156211
}
157212
});
158213
});

0 commit comments

Comments
 (0)