Skip to content

Commit a51cd2b

Browse files
authored
Added optional FeatureSet parameter to eligibility interface (#2623)
* Adding optional feature sets to eligibility data * changefile * updating interface * adding UTs * Adding UT * make the feature set property readyOnly
1 parent 4d7dacc commit a51cd2b

File tree

4 files changed

+94
-1
lines changed

4 files changed

+94
-1
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "minor",
3+
"comment": "Added optional `FeatureSet` field to `AppEligibilityInformation` interface",
4+
"packageName": "@microsoft/teams-js",
5+
"email": "email not defined",
6+
"dependentChangeType": "patch"
7+
}

packages/teams-js/src/private/copilot/eligibility.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ function isEligibilityInfoValid(eligibilityInfo: AppEligibilityInformation): boo
8080
eligibilityInfo.userClassification === undefined ||
8181
eligibilityInfo.isCopilotEligible === undefined ||
8282
eligibilityInfo.isCopilotEnabledRegion === undefined ||
83-
eligibilityInfo.isOptedOutByAdmin === undefined
83+
eligibilityInfo.isOptedOutByAdmin === undefined ||
84+
(eligibilityInfo.featureSet &&
85+
(eligibilityInfo.featureSet.serverFeatures === undefined || eligibilityInfo.featureSet.uxFeatures === undefined))
8486
) {
8587
return false;
8688
}

packages/teams-js/src/public/interfaces.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,11 @@ export interface AppEligibilityInformation {
11321132
* A user will be in at most one cohort.
11331133
*/
11341134
cohort: Cohort | null;
1135+
/**
1136+
* Feature Sets
1137+
* If this property is undefined, it indicates that the host is an older version that doesn't support this property.
1138+
*/
1139+
featureSet?: FeatureSet;
11351140
/**
11361141
* Indicates that the user is eligible for Microsoft Entra ID Authenticated Copilot experience.
11371142
*/
@@ -1150,6 +1155,22 @@ export interface AppEligibilityInformation {
11501155
userClassification: UserClassification | null;
11511156
}
11521157

1158+
/**
1159+
* @hidden
1160+
* @beta
1161+
* Represents the feature set available to the user.
1162+
*/
1163+
export interface FeatureSet {
1164+
/**
1165+
* Server Feature set
1166+
*/
1167+
serverFeatures: ReadonlyArray<string>;
1168+
/**
1169+
* UX Feature set
1170+
*/
1171+
uxFeatures: ReadonlyArray<string>;
1172+
}
1173+
11531174
/**
11541175
* @hidden
11551176
*

packages/teams-js/test/private/copilot.spec.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const mockedAppEligibilityInformation = {
1616
persona: Persona.Student,
1717
eduType: EduType.HigherEducation,
1818
},
19+
featureSet: { serverFeatures: ['feature1', 'feature2'], uxFeatures: ['feature3'] },
1920
};
2021

2122
const mockedAppEligibilityInformationUserClassificationNull = {
@@ -188,6 +189,24 @@ describe('copilot', () => {
188189
return expect(promise).resolves.toEqual(mockedAppEligibilityInformation);
189190
});
190191

192+
it(`should not throw if featureSet in response is undefined - with context ${frameContext}`, async () => {
193+
await utils.initializeWithContext(frameContext);
194+
utils.setRuntimeConfig(copilotRuntimeConfig);
195+
196+
const promise = copilot.eligibility.getEligibilityInfo();
197+
const message = utils.findMessageByFunc('copilot.eligibility.getEligibilityInfo');
198+
const mockedAppEligibilityInformationWithUndefinedFeatureSet = {
199+
...mockedAppEligibilityInformation,
200+
featureSet: undefined,
201+
};
202+
expect(message).not.toBeNull();
203+
if (message) {
204+
utils.respondToMessage(message, mockedAppEligibilityInformationWithUndefinedFeatureSet);
205+
}
206+
207+
return expect(promise).resolves.toEqual(mockedAppEligibilityInformationWithUndefinedFeatureSet);
208+
});
209+
191210
it(`should throw error if host returns error - with context ${frameContext}`, async () => {
192211
await utils.initializeWithContext(frameContext);
193212
utils.setRuntimeConfig(copilotRuntimeConfig);
@@ -319,6 +338,50 @@ describe('copilot', () => {
319338

320339
await expect(promise).rejects.toThrowError('Error deserializing eligibility information');
321340
});
341+
342+
it('getEligibilityInfo should throw if AppEligibilityInformation.featureSet.serverFeatures is undefined', async () => {
343+
await utils.initializeWithContext(FrameContexts.content);
344+
utils.setRuntimeConfig(copilotRuntimeConfig);
345+
346+
const mockedInvalidAppEligibilityInformationWithInvalidUxFeatures = {
347+
...mockedAppEligibilityInformation,
348+
featureSet: {
349+
serverFeatures: undefined,
350+
uxFeatures: [],
351+
},
352+
};
353+
354+
const promise = copilot.eligibility.getEligibilityInfo();
355+
const message = utils.findMessageByFunc('copilot.eligibility.getEligibilityInfo');
356+
expect(message).not.toBeNull();
357+
if (message) {
358+
utils.respondToMessage(message, mockedInvalidAppEligibilityInformationWithInvalidUxFeatures);
359+
}
360+
361+
await expect(promise).rejects.toThrowError('Error deserializing eligibility information');
362+
});
363+
364+
it('getEligibilityInfo should throw if AppEligibilityInformation.featureSet.uxFeatures is undefined', async () => {
365+
await utils.initializeWithContext(FrameContexts.content);
366+
utils.setRuntimeConfig(copilotRuntimeConfig);
367+
368+
const mockedInvalidAppEligibilityInformationWithInvalidUxFeatures = {
369+
...mockedAppEligibilityInformation,
370+
featureSet: {
371+
serverFeatures: [],
372+
uxFeatures: undefined,
373+
},
374+
};
375+
376+
const promise = copilot.eligibility.getEligibilityInfo();
377+
const message = utils.findMessageByFunc('copilot.eligibility.getEligibilityInfo');
378+
expect(message).not.toBeNull();
379+
if (message) {
380+
utils.respondToMessage(message, mockedInvalidAppEligibilityInformationWithInvalidUxFeatures);
381+
}
382+
383+
await expect(promise).rejects.toThrowError('Error deserializing eligibility information');
384+
});
322385
});
323386
});
324387
});

0 commit comments

Comments
 (0)