Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auth2 support #3790

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
65 changes: 65 additions & 0 deletions __tests__/fixtures/version-3/auth2-active.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"@context": "http://iiif.io/api/presentation/3/context.json",
"id": "https://iiif.io/api/cookbook/recipe/0005-image-service/manifest.json",
"type": "Manifest",
"label": {
"en": [
"An actively authorized video"
]
},
"items": [
{
"id": "https://auth.example.org/my-video1",
"type": "Canvas",
"label": {
"en": [
"Canvas with a single IIIF video"
]
},
"height": 3024,
"width": 4032,
"items": [
{
"id": "https://auth.example.org/my-video/page",
"type": "AnnotationPage",
"items": [
{
"id": "https://auth.example.org/my-video/annotation",
"type": "Annotation",
"motivation": "painting",
"body": {
"id": "https://auth.example.org/my-video.mp4",
"type": "Video",
"service": [
{
"id": "https://auth.example.org/probe/my-video",
"type": "AuthProbeService2",
"service" : [
{
"id": "https://auth.example.org/login",
"type": "AuthAccessService2",
"profile": "active",
"label": { "en": [ "Login to Example Institution" ] },
"service" : [
{
"id": "https://auth.example.org/token",
"type": "AuthAccessTokenService2"
},
{
"id": "https://auth.example.org/logout",
"type": "AuthLogoutService2",
"label": { "en": [ "Logout from Example Institution" ] }
}
]
}
]
}
]
}
}
]
}
]
}
]
}
69 changes: 69 additions & 0 deletions __tests__/fixtures/version-3/auth2-kiosk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"@context": "http://iiif.io/api/presentation/3/context.json",
"id": "https://iiif.io/api/cookbook/recipe/0005-image-service/manifest.json",
"type": "Manifest",
"label": {
"en": [
"A kiosk-authorized image"
]
},
"items": [
{
"id": "https://iiif.io/api/cookbook/recipe/0005-image-service/canvas/p1",
"type": "Canvas",
"label": {
"en": [
"Canvas with a single IIIF image"
]
},
"height": 3024,
"width": 4032,
"items": [
{
"id": "https://iiif.io/api/cookbook/recipe/0005-image-service/page/p1/1",
"type": "AnnotationPage",
"items": [
{
"id": "https://iiif.io/api/cookbook/recipe/0005-image-service/annotation/p0001-image",
"type": "Annotation",
"motivation": "painting",
"body": {
"id": "https://iiif.io/api/image/3.0/example/reference/918ecd18c2592080851777620de9bcb5-gottingen/full/max/0/default.jpg",
"type": "Image",
"format": "image/jpeg",
"height": 3024,
"width": 4032,
"service": [
{
"id": "https://auth.example.org/probe/918ecd18c2592080851777620de9bcb5-gottingen",
"type": "AuthProbeService2",
"service" : [
{
"id": "https://auth.example.org/kiosk",
"type": "AuthAccessService2",
"profile": "kiosk",
"label": { "en": [ "Kiosk Login" ] },
"service" : [
{
"id": "https://auth.example.org/token/918ecd18c2592080851777620de9bcb5-gottingen",
"type": "AuthAccessTokenService2"
}
]
}
]
},
{
"id": "https://iiif.io/api/image/3.0/example/reference/918ecd18c2592080851777620de9bcb5-gottingen",
"profile": "level1",
"type": "ImageService3"
}
]
},
"target": "https://iiif.io/api/cookbook/recipe/0005-image-service/canvas/p1"
}
]
}
]
}
]
}
52 changes: 52 additions & 0 deletions __tests__/src/actions/probeResponse.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { JSONLDResource } from 'manifesto.js';
import * as actions from '../../../src/state/actions';
import ActionTypes from '../../../src/state/actions/action-types';

describe('probeResponse actions', () => {
describe('requestProbeResponse', () => {
it('requests a probeResponse from given a url', () => {
const id = 'abc123';
const expectedAction = {
probeId: id,
type: ActionTypes.REQUEST_PROBE_RESPONSE,
};
expect(actions.requestProbeResponse(id)).toEqual(expectedAction);
});
});
describe('receiveProbeResponse', () => {
it('receives a probeResponse', () => {
const id = 'abc123';
const json = {
content: 'probe service request',
id,
};
const expectedAction = {
probeId: id,
probeJson: json,
type: ActionTypes.RECEIVE_PROBE_RESPONSE,
};
expect(actions.receiveProbeResponse(id, json)).toEqual(expectedAction);
});
});
describe('fetchProbeResponse', () => {
describe('success response', () => {
it('dispatches the REQUEST_PROBE_RESPONSE action', () => {
const resource = new JSONLDResource({ services: [{ id: 'someUrl', type: 'AuthProbeService2' }] });
expect(actions.fetchProbeResponse({ resource })).toEqual({
probeId: 'someUrl',
resource,
type: 'mirador/REQUEST_PROBE_RESPONSE',
});
});
});
});
describe('removeProbeResponse', () => {
it('removes an existing probeResponse', () => {
const expectedAction = {
probeId: 'foo',
type: ActionTypes.REMOVE_PROBE_RESPONSE,
};
expect(actions.removeProbeResponse('foo')).toEqual(expectedAction);
});
});
});
24 changes: 24 additions & 0 deletions __tests__/src/lib/MiradorCanvas.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import fragmentFixtureV3 from '../../fixtures/version-3/hamilton.json';
import audioFixture from '../../fixtures/version-3/0002-mvm-audio.json';
import videoFixture from '../../fixtures/version-3/0015-start.json';
import videoWithAnnoCaptions from '../../fixtures/version-3/video_with_annotation_captions.json';
import auth2WithImage from '../../fixtures/version-3/auth2-kiosk.json';
import auth2WithVideo from '../../fixtures/version-3/auth2-active.json';

describe('MiradorCanvas', () => {
let instance;
Expand Down Expand Up @@ -133,4 +135,26 @@ describe('MiradorCanvas', () => {
expect(instance.v3VttContent.length).toEqual(1);
});
});
describe('iiifImageResources', () => {
it('returns image resources', () => {
instance = new MiradorCanvas(
Utils.parseManifest(auth2WithImage).getSequences()[0].getCanvases()[0],
);
expect(instance.iiifImageResources.length).toEqual(1);
});
it('returns only image resources', () => {
instance = new MiradorCanvas(
Utils.parseManifest(auth2WithVideo).getSequences()[0].getCanvases()[0],
);
expect(instance.iiifImageResources.length).toEqual(0);
});
});
describe('imageServiceIds', () => {
it('returns image service IDs', () => {
instance = new MiradorCanvas(
Utils.parseManifest(auth2WithImage).getSequences()[0].getCanvases()[0],
);
expect(instance.imageServiceIds[0]).toEqual('https://iiif.io/api/image/3.0/example/reference/918ecd18c2592080851777620de9bcb5-gottingen');
});
});
});
90 changes: 90 additions & 0 deletions __tests__/src/lib/getServices.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { v4 as uuid } from 'uuid';
import {
anyAuthServices, getLogoutService, getProbeService, getTokenService,
} from '../../../src/lib/getServices';

/**
*/
function resourceFixtureWithService(props) {
return {
id: uuid(),
services: [
{ ...props },
],
type: 'Dataset',
};
}

/**
*/
function actualLogoutServiceId(resource) {
const service = getLogoutService(resource);
return service
&& service.id;
}

/**
*/
function actualTokenServiceId(resource) {
const service = getTokenService(resource);
return service
&& service.id;
}

/**
*/
function actualProbeServiceId(resource) {
const service = getProbeService(resource);
return service
&& service.id;
}

describe('anyAuthServices', () => {
it('returns a filtered list', () => {
const serviceId = uuid();
const auth0 = resourceFixtureWithService({ id: serviceId, profile: 'http://iiif.io/api/auth/0/anyService' });
expect(anyAuthServices(auth0).length).toEqual(1);
const auth1 = resourceFixtureWithService({ id: serviceId, profile: 'http://iiif.io/api/auth/1/anyService' });
expect(anyAuthServices(auth1).length).toEqual(1);
const auth2 = resourceFixtureWithService({ id: serviceId, type: 'AuthAnyService2' });
expect(anyAuthServices(auth2).length).toEqual(1);
const notAuthProfile = resourceFixtureWithService({ id: serviceId, profile: 'http://iiif.io/api/not-auth/1/anyService' });
expect(anyAuthServices(notAuthProfile).length).toEqual(0);
const notAuthType = resourceFixtureWithService({ id: serviceId, type: 'NotAuthAnyService2' });
expect(anyAuthServices(notAuthType).length).toEqual(0);
});
});

describe('getLogoutService', () => {
it('returns a Service', () => {
const serviceId = uuid();
const auth0 = resourceFixtureWithService({ id: serviceId, profile: 'http://iiif.io/api/auth/0/logout' });
expect(actualLogoutServiceId(auth0)).toEqual(serviceId);
const auth1 = resourceFixtureWithService({ id: serviceId, profile: 'http://iiif.io/api/auth/1/logout' });
expect(actualLogoutServiceId(auth1)).toEqual(serviceId);
const auth2 = resourceFixtureWithService({ id: serviceId, type: 'AuthLogoutService2' });
expect(actualLogoutServiceId(auth2)).toEqual(serviceId);
});
});

describe('getProbeService', () => {
it('returns a Service', () => {
const serviceId = uuid();
const auth1 = resourceFixtureWithService({ id: serviceId, profile: 'http://iiif.io/api/auth/1/probe' });
expect(actualProbeServiceId(auth1)).toEqual(serviceId);
const auth2 = resourceFixtureWithService({ id: serviceId, type: 'AuthProbeService2' });
expect(actualProbeServiceId(auth2)).toEqual(serviceId);
});
});

describe('getTokenService', () => {
it('returns a Service', () => {
const serviceId = uuid();
const auth0 = resourceFixtureWithService({ id: serviceId, profile: 'http://iiif.io/api/auth/0/token' });
expect(actualTokenServiceId(auth0)).toEqual(serviceId);
const auth1 = resourceFixtureWithService({ id: serviceId, profile: 'http://iiif.io/api/auth/1/token' });
expect(actualTokenServiceId(auth1)).toEqual(serviceId);
const auth2 = resourceFixtureWithService({ id: serviceId, type: 'AuthAccessTokenService2' });
expect(actualTokenServiceId(auth2)).toEqual(serviceId);
});
});
52 changes: 52 additions & 0 deletions __tests__/src/lib/typeFilters.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { JSONLDResource } from 'manifesto.js';
import { v4 as uuid } from 'uuid';
import {
filterByTypes, audioResourcesFrom, anyImageServices, hasImageService,

Check warning on line 4 in __tests__/src/lib/typeFilters.test.js

View workflow job for this annotation

GitHub Actions / build (16.x)

'anyImageServices' is defined but never used

Check warning on line 4 in __tests__/src/lib/typeFilters.test.js

View workflow job for this annotation

GitHub Actions / build (16.x)

'hasImageService' is defined but never used

Check warning on line 4 in __tests__/src/lib/typeFilters.test.js

View workflow job for this annotation

GitHub Actions / build (18.x)

'anyImageServices' is defined but never used

Check warning on line 4 in __tests__/src/lib/typeFilters.test.js

View workflow job for this annotation

GitHub Actions / build (18.x)

'hasImageService' is defined but never used

Check warning on line 4 in __tests__/src/lib/typeFilters.test.js

View workflow job for this annotation

GitHub Actions / build (19.x)

'anyImageServices' is defined but never used

Check warning on line 4 in __tests__/src/lib/typeFilters.test.js

View workflow job for this annotation

GitHub Actions / build (19.x)

'hasImageService' is defined but never used
iiifImageResourcesFrom, textResourcesFrom, videoResourcesFrom,

Check warning on line 5 in __tests__/src/lib/typeFilters.test.js

View workflow job for this annotation

GitHub Actions / build (16.x)

'iiifImageResourcesFrom' is defined but never used

Check warning on line 5 in __tests__/src/lib/typeFilters.test.js

View workflow job for this annotation

GitHub Actions / build (18.x)

'iiifImageResourcesFrom' is defined but never used

Check warning on line 5 in __tests__/src/lib/typeFilters.test.js

View workflow job for this annotation

GitHub Actions / build (19.x)

'iiifImageResourcesFrom' is defined but never used
} from '../../../src/lib/typeFilters';

/**
*/
function resourceFixtureForProps(props) {
return new JSONLDResource({
id: uuid(),
...props,
});
}

describe('filterByTypes', () => {
it('returns a resource of one type', () => {
const typeFixture = 'someType';
const resourceFixture = resourceFixtureForProps({ '@type': typeFixture });
expect(filterByTypes([resourceFixture], typeFixture)).toEqual([resourceFixture]);
});
it('returns a resource of any given types', () => {
const typeFixture = 'someType';
const resourceFixture = resourceFixtureForProps({ '@type': typeFixture });
expect(filterByTypes([resourceFixture], ['anotherType', typeFixture])).toEqual([resourceFixture]);
});
});

describe('audioResourcesFrom', () => {
it('returns a resource of audio type', () => {
const typeFixture = 'Audio';
const resourceFixture = resourceFixtureForProps({ '@type': typeFixture });
expect(audioResourcesFrom([resourceFixture])).toEqual([resourceFixture]);
});
});

describe('videoResourcesFrom', () => {
it('returns a resource of audio type', () => {
const typeFixture = 'Video';
const resourceFixture = resourceFixtureForProps({ '@type': typeFixture });
expect(videoResourcesFrom([resourceFixture])).toEqual([resourceFixture]);
});
});

describe('textResourcesFrom', () => {
it('returns a resource of audio type', () => {
const typeFixture = 'Document';
const resourceFixture = resourceFixtureForProps({ '@type': typeFixture });
expect(textResourcesFrom([resourceFixture])).toEqual([resourceFixture]);
});
});
Loading