mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
95 lines
3.7 KiB
TypeScript
95 lines
3.7 KiB
TypeScript
import type { ProviderFactory } from '../../../../../src/identity/configuration/ProviderFactory';
|
|
import type { Interaction } from '../../../../../src/identity/interaction/InteractionHandler';
|
|
import { PickWebIdHandler } from '../../../../../src/identity/interaction/oidc/PickWebIdHandler';
|
|
import type { WebIdStore } from '../../../../../src/identity/interaction/webid/util/WebIdStore';
|
|
import { BadRequestHttpError } from '../../../../../src/util/errors/BadRequestHttpError';
|
|
import { FoundHttpError } from '../../../../../src/util/errors/FoundHttpError';
|
|
import type Provider from '../../../../../templates/types/oidc-provider';
|
|
|
|
describe('A PickWebIdHandler', (): void => {
|
|
const accountId = 'accountId';
|
|
const webId1 = 'http://example.com/.account/card1#me';
|
|
const webId2 = 'http://example.com/.account/card2#me';
|
|
let json: unknown;
|
|
let oidcInteraction: Interaction;
|
|
let store: jest.Mocked<WebIdStore>;
|
|
let provider: jest.Mocked<Provider>;
|
|
let providerFactory: jest.Mocked<ProviderFactory>;
|
|
let picker: PickWebIdHandler;
|
|
|
|
beforeEach(async(): Promise<void> => {
|
|
oidcInteraction = {
|
|
lastSubmission: { login: { accountId: 'id' }},
|
|
persist: jest.fn(),
|
|
session: { cookie: 'cookie' },
|
|
returnTo: 'returnTo',
|
|
} as any;
|
|
|
|
json = {
|
|
webId: webId1,
|
|
};
|
|
|
|
store = {
|
|
findLinks: jest.fn().mockResolvedValue([{ id: 'id', webId: webId1 }, { id: 'id2', webId: webId2 }]),
|
|
isLinked: jest.fn().mockResolvedValue(true),
|
|
} satisfies Partial<WebIdStore> as any;
|
|
|
|
provider = {
|
|
Session: {
|
|
find: jest.fn().mockResolvedValue({ persist: jest.fn() }),
|
|
},
|
|
} as any;
|
|
|
|
providerFactory = {
|
|
getProvider: jest.fn().mockResolvedValue(provider),
|
|
};
|
|
|
|
picker = new PickWebIdHandler(store, providerFactory);
|
|
});
|
|
|
|
it('requires a WebID as input and returns the available WebIDs.', async(): Promise<void> => {
|
|
await expect(picker.getView({ accountId } as any)).resolves.toEqual({
|
|
json: {
|
|
fields: {
|
|
webId: { required: true, type: 'string' },
|
|
remember: { required: false, type: 'boolean' },
|
|
},
|
|
webIds: [ webId1, webId2 ],
|
|
},
|
|
});
|
|
expect(store.findLinks).toHaveBeenCalledTimes(1);
|
|
expect(store.findLinks).toHaveBeenLastCalledWith(accountId);
|
|
});
|
|
|
|
it('allows users to pick a WebID.', async(): Promise<void> => {
|
|
const result = picker.handle({ oidcInteraction, accountId, json } as any);
|
|
await expect(result).rejects.toThrow(FoundHttpError);
|
|
await expect(result).rejects.toEqual(expect.objectContaining({ location: oidcInteraction.returnTo }));
|
|
|
|
expect(store.isLinked).toHaveBeenCalledTimes(1);
|
|
expect(store.isLinked).toHaveBeenLastCalledWith(webId1, accountId);
|
|
// eslint-disable-next-line jest/unbound-method
|
|
expect((await jest.mocked(provider.Session.find).mock.results[0].value).persist).toHaveBeenCalledTimes(1);
|
|
expect(oidcInteraction.persist).toHaveBeenCalledTimes(1);
|
|
expect(oidcInteraction.result).toEqual({
|
|
login: {
|
|
accountId: webId1,
|
|
remember: false,
|
|
},
|
|
});
|
|
});
|
|
|
|
it('errors if there is no OIDC interaction.', async(): Promise<void> => {
|
|
await expect(picker.handle({ accountId, json } as any)).rejects.toThrow(BadRequestHttpError);
|
|
});
|
|
|
|
it('errors if the WebID is not part of the account.', async(): Promise<void> => {
|
|
store.isLinked.mockResolvedValueOnce(false);
|
|
await expect(picker.handle({ oidcInteraction, accountId, json } as any))
|
|
.rejects.toThrow('WebID does not belong to this account.');
|
|
expect(store.isLinked).toHaveBeenCalledTimes(1);
|
|
expect(store.isLinked).toHaveBeenLastCalledWith(webId1, accountId);
|
|
expect(oidcInteraction.persist).toHaveBeenCalledTimes(0);
|
|
});
|
|
});
|