Page MenuHomePhabricator

D7566.diff
No OneTemporary

D7566.diff

diff --git a/lib/types/media-types.js b/lib/types/media-types.js
--- a/lib/types/media-types.js
+++ b/lib/types/media-types.js
@@ -1,13 +1,21 @@
// @flow
+import t, { type TInterface, type TUnion } from 'tcomb';
+
import type { Shape } from './core.js';
import { type Platform } from './device-types.js';
+import { tShape, tString, tID } from '../utils/validation-utils.js';
export type Dimensions = $ReadOnly<{
+height: number,
+width: number,
}>;
+export const dimensionsValidator: TInterface<Dimensions> = tShape<Dimensions>({
+ height: t.Number,
+ width: t.Number,
+});
+
export type MediaType = 'photo' | 'video';
export type EncryptedMediaType = 'encrypted_photo' | 'encrypted_video';
@@ -246,6 +254,31 @@
+duration: number, // seconds
};
+export const mediaLibrarySelectionValidator: TUnion<MediaLibrarySelection> =
+ t.union([
+ tShape({
+ step: tString('photo_library'),
+ dimensions: dimensionsValidator,
+ filename: t.maybe(t.String),
+ uri: t.String,
+ mediaNativeID: t.maybe(t.String),
+ selectTime: t.Number,
+ sendTime: t.Number,
+ retries: t.Number,
+ }),
+ tShape({
+ step: tString('video_library'),
+ dimensions: dimensionsValidator,
+ filename: t.maybe(t.String),
+ uri: t.String,
+ mediaNativeID: t.maybe(t.String),
+ selectTime: t.Number,
+ sendTime: t.Number,
+ retries: t.Number,
+ duration: t.Number,
+ }),
+ ]);
+
export type PhotoCapture = {
+step: 'photo_capture',
+time: number, // ms
@@ -258,6 +291,19 @@
+retries: number,
};
+export const photoCaptureValidator: TInterface<PhotoCapture> =
+ tShape<PhotoCapture>({
+ step: tString('photo_capture'),
+ time: t.Number,
+ dimensions: dimensionsValidator,
+ filename: t.String,
+ uri: t.String,
+ captureTime: t.Number,
+ selectTime: t.Number,
+ sendTime: t.Number,
+ retries: t.Number,
+ });
+
export type PhotoPaste = {
+step: 'photo_paste',
+dimensions: Dimensions,
@@ -268,11 +314,28 @@
+retries: number,
};
+export const photoPasteValidator: TInterface<PhotoPaste> = tShape<PhotoPaste>({
+ step: tString('photo_paste'),
+ dimensions: dimensionsValidator,
+ filename: t.String,
+ uri: t.String,
+ selectTime: t.Number,
+ sendTime: t.Number,
+ retries: t.Number,
+});
+
export type NativeMediaSelection =
| MediaLibrarySelection
| PhotoCapture
| PhotoPaste;
+export const nativeMediaSelectionValidator: TUnion<NativeMediaSelection> =
+ t.union([
+ mediaLibrarySelectionValidator,
+ photoCaptureValidator,
+ photoPasteValidator,
+ ]);
+
export type MediaMissionStep =
| NativeMediaSelection
| {
@@ -560,6 +623,14 @@
+localMediaSelection?: NativeMediaSelection,
};
+export const imageValidator: TInterface<Image> = tShape<Image>({
+ id: tID,
+ uri: t.String,
+ type: tString('photo'),
+ dimensions: dimensionsValidator,
+ localMediaSelection: t.maybe(nativeMediaSelectionValidator),
+});
+
export type EncryptedImage = {
+id: string,
// a media URI for keyserver uploads / blob holder for Blob service uploads
@@ -569,6 +640,15 @@
+dimensions: Dimensions,
};
+export const encryptedImageValidator: TInterface<EncryptedImage> =
+ tShape<EncryptedImage>({
+ id: tID,
+ holder: t.String,
+ encryptionKey: t.String,
+ type: tString('encrypted_photo'),
+ dimensions: dimensionsValidator,
+ });
+
export type Video = {
+id: string,
+uri: string,
@@ -581,6 +661,17 @@
+localMediaSelection?: NativeMediaSelection,
};
+export const videoValidator: TInterface<Video> = tShape<Video>({
+ id: tID,
+ uri: t.String,
+ type: tString('video'),
+ dimensions: dimensionsValidator,
+ loop: t.maybe(t.Boolean),
+ thumbnailID: tID,
+ thumbnailURI: t.String,
+ localMediaSelection: t.maybe(nativeMediaSelectionValidator),
+});
+
export type EncryptedVideo = {
+id: string,
// a media URI for keyserver uploads / blob holder for Blob service uploads
@@ -594,4 +685,24 @@
+thumbnailEncryptionKey: string,
};
+export const encryptedVideoValidator: TInterface<EncryptedVideo> =
+ tShape<EncryptedVideo>({
+ id: tID,
+ holder: t.String,
+ encryptionKey: t.String,
+ type: tString('encrypted_video'),
+ dimensions: dimensionsValidator,
+ loop: t.maybe(t.Boolean),
+ thumbnailID: tID,
+ thumbnailHolder: t.String,
+ thumbnailEncryptionKey: t.String,
+ });
+
export type Media = Image | Video | EncryptedImage | EncryptedVideo;
+
+export const mediaValidator: TUnion<Media> = t.union([
+ imageValidator,
+ videoValidator,
+ encryptedImageValidator,
+ encryptedVideoValidator,
+]);
diff --git a/lib/types/validation.test.js b/lib/types/validation.test.js
new file mode 100644
--- /dev/null
+++ b/lib/types/validation.test.js
@@ -0,0 +1,44 @@
+// @flow
+
+import {
+ imageValidator,
+ videoValidator,
+ mediaValidator,
+} from './media-types.js';
+
+describe('media validation', () => {
+ const photo = {
+ id: '92696',
+ type: 'photo',
+ uri: 'http://0.0.0.0:3000/comm/upload/92696/0fb272bd1c75d976',
+ dimensions: {
+ width: 340,
+ height: 288,
+ },
+ };
+ const video = {
+ type: 'video',
+ id: '92769',
+ uri: 'http://0.0.0.0:3000/comm/upload/92769/4bcc6987b25b2f66',
+ dimensions: {
+ width: 480,
+ height: 270,
+ },
+ thumbnailID: '92770',
+ thumbnailURI: 'http://0.0.0.0:3000/comm/upload/92770/d56466051dcef1db',
+ };
+
+ it('should validate correct media', () => {
+ expect(mediaValidator.is(photo)).toBe(true);
+ expect(imageValidator.is(photo)).toBe(true);
+ expect(mediaValidator.is(video)).toBe(true);
+ expect(videoValidator.is(video)).toBe(true);
+ });
+
+ it('should not validate incorrect media', () => {
+ expect(imageValidator.is(video)).toBe(false);
+ expect(videoValidator.is(photo)).toBe(false);
+ expect(mediaValidator.is({ ...photo, type: undefined })).toBe(false);
+ expect(mediaValidator.is({ ...video, dimensions: undefined })).toBe(false);
+ });
+});

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 29, 11:45 AM (2 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2596878
Default Alt Text
D7566.diff (5 KB)

Event Timeline