/*
 *  Copyright 2017 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#import <OCMock/OCMock.h>

#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
#endif

#include "rtc_base/gunit.h"

#import <WebRTC/RTCCameraVideoCapturer.h>
#import <WebRTC/RTCDispatcher.h>
#import <WebRTC/RTCVideoFrame.h>
#import "AVCaptureSession+DevicePosition.h"

#if TARGET_OS_IPHONE
// Helper method.
CMSampleBufferRef createTestSampleBufferRef() {

  // This image is already in the testing bundle.
  UIImage *image = [UIImage imageNamed:@"Default.png"];
  CGSize size = image.size;
  CGImageRef imageRef = [image CGImage];

  CVPixelBufferRef pixelBuffer = nullptr;
  CVPixelBufferCreate(kCFAllocatorDefault, size.width, size.height, kCVPixelFormatType_32ARGB, nil,
                      &pixelBuffer);

  CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
  // We don't care about bitsPerComponent and bytesPerRow so arbitrary value of 8 for both.
  CGContextRef context = CGBitmapContextCreate(nil, size.width, size.height, 8, 8 * size.width,
                                               rgbColorSpace, kCGImageAlphaPremultipliedFirst);

  CGContextDrawImage(
      context, CGRectMake(0, 0, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)), imageRef);

  CGColorSpaceRelease(rgbColorSpace);
  CGContextRelease(context);

  // We don't really care about the timing.
  CMSampleTimingInfo timing = {kCMTimeInvalid, kCMTimeInvalid, kCMTimeInvalid};
  CMVideoFormatDescriptionRef description = nullptr;
  CMVideoFormatDescriptionCreateForImageBuffer(NULL, pixelBuffer, &description);

  CMSampleBufferRef sampleBuffer = nullptr;
  CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, YES, NULL, NULL, description,
                                     &timing, &sampleBuffer);
  CFRelease(pixelBuffer);

  return sampleBuffer;

}
#endif
@interface RTCCameraVideoCapturer (Tests)<AVCaptureVideoDataOutputSampleBufferDelegate>
- (instancetype)initWithDelegate:(__weak id<RTCVideoCapturerDelegate>)delegate
                  captureSession:(AVCaptureSession *)captureSession;
@end

@interface RTCCameraVideoCapturerTests : NSObject
@property(nonatomic, strong) id delegateMock;
@property(nonatomic, strong) id deviceMock;
@property(nonatomic, strong) id captureConnectionMock;
@property(nonatomic, strong) id captureSessionMock;
@property(nonatomic, strong) RTCCameraVideoCapturer *capturer;
@end

@implementation RTCCameraVideoCapturerTests
@synthesize delegateMock = _delegateMock;
@synthesize deviceMock = _deviceMock;
@synthesize captureConnectionMock = _captureConnectionMock;
@synthesize captureSessionMock = _captureSessionMock;
@synthesize capturer = _capturer;

- (void)setup {
  self.delegateMock = OCMProtocolMock(@protocol(RTCVideoCapturerDelegate));
  self.captureConnectionMock = OCMClassMock([AVCaptureConnection class]);
  self.capturer = [[RTCCameraVideoCapturer alloc] initWithDelegate:self.delegateMock];
  self.deviceMock = [self createDeviceMock];
}

- (void)setupWithMockedCaptureSession {
  self.captureSessionMock = OCMStrictClassMock([AVCaptureSession class]);
  OCMStub([self.captureSessionMock setSessionPreset:[OCMArg any]]);
  OCMStub([self.captureSessionMock setUsesApplicationAudioSession:NO]);
  OCMStub([self.captureSessionMock canAddOutput:[OCMArg any]]).andReturn(YES);
  OCMStub([self.captureSessionMock addOutput:[OCMArg any]]);
  OCMStub([self.captureSessionMock beginConfiguration]);
  OCMStub([self.captureSessionMock commitConfiguration]);
  self.delegateMock = OCMProtocolMock(@protocol(RTCVideoCapturerDelegate));
  self.captureConnectionMock = OCMClassMock([AVCaptureConnection class]);
  self.capturer = [[RTCCameraVideoCapturer alloc] initWithDelegate:self.delegateMock
                                                    captureSession:self.captureSessionMock];
  self.deviceMock = [self createDeviceMock];
}

- (void)tearDown {
  [self.delegateMock stopMocking];
  [self.deviceMock stopMocking];
  self.delegateMock = nil;
  self.deviceMock = nil;
  self.capturer = nil;
}

#pragma mark - utils

- (id)createDeviceMock {
  return OCMClassMock([AVCaptureDevice class]);
}

#pragma mark - test cases

- (void)testSetupSession {
  AVCaptureSession *session = self.capturer.captureSession;
  EXPECT_TRUE(session != nil);

#if TARGET_OS_IPHONE
  EXPECT_EQ(session.sessionPreset, AVCaptureSessionPresetInputPriority);
  EXPECT_EQ(session.usesApplicationAudioSession, NO);
#endif
  EXPECT_EQ(session.outputs.count, 1u);
}

- (void)testSetupSessionOutput {
  AVCaptureVideoDataOutput *videoOutput = self.capturer.captureSession.outputs[0];
  EXPECT_EQ(videoOutput.alwaysDiscardsLateVideoFrames, NO);
  EXPECT_EQ(videoOutput.sampleBufferDelegate, self.capturer);
}

- (void)testSupportedFormatsForDevice {
  // given
  id validFormat1 = OCMClassMock([AVCaptureDeviceFormat class]);
  CMVideoFormatDescriptionRef format;

  // We don't care about width and heigth so arbitrary 123 and 456 values.
  int width = 123;
  int height = 456;
  CMVideoFormatDescriptionCreate(nil, kCVPixelFormatType_420YpCbCr8PlanarFullRange, width, height,
                                 nil, &format);
  OCMStub([validFormat1 formatDescription]).andReturn(format);

  id validFormat2 = OCMClassMock([AVCaptureDeviceFormat class]);
  CMVideoFormatDescriptionCreate(nil, kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, width,
                                 height, nil, &format);
  OCMStub([validFormat2 formatDescription]).andReturn(format);

  id invalidFormat = OCMClassMock([AVCaptureDeviceFormat class]);
  CMVideoFormatDescriptionCreate(nil, kCVPixelFormatType_422YpCbCr8_yuvs, width, height, nil,
                                 &format);
  OCMStub([invalidFormat formatDescription]).andReturn(format);

  NSArray *formats = @[ validFormat1, validFormat2, invalidFormat ];
  OCMStub([self.deviceMock formats]).andReturn(formats);

  // when
  NSArray *supportedFormats = [RTCCameraVideoCapturer supportedFormatsForDevice:self.deviceMock];

  // then
  EXPECT_EQ(supportedFormats.count, 3u);
  EXPECT_TRUE([supportedFormats containsObject:validFormat1]);
  EXPECT_TRUE([supportedFormats containsObject:validFormat2]);
  EXPECT_TRUE([supportedFormats containsObject:invalidFormat]);

  // cleanup
  [validFormat1 stopMocking];
  [validFormat2 stopMocking];
  [invalidFormat stopMocking];
  validFormat1 = nil;
  validFormat2 = nil;
  invalidFormat = nil;
}

- (void)testCaptureDevices {
  OCMStub([self.deviceMock devicesWithMediaType:AVMediaTypeVideo]).andReturn(@[ [NSObject new] ]);
  OCMStub([self.deviceMock devicesWithMediaType:AVMediaTypeAudio]).andReturn(@[ [NSObject new] ]);

  NSArray *captureDevices = [RTCCameraVideoCapturer captureDevices];

  EXPECT_EQ(captureDevices.count, 1u);
}

- (void)testDelegateCallbackNotCalledWhenInvalidBuffer {
  // given
  CMSampleBufferRef sampleBuffer = nullptr;
  [[self.delegateMock reject] capturer:[OCMArg any] didCaptureVideoFrame:[OCMArg any]];

  // when
  [self.capturer captureOutput:self.capturer.captureSession.outputs[0]
         didOutputSampleBuffer:sampleBuffer
                fromConnection:self.captureConnectionMock];

  // then
  [self.delegateMock verify];
}


- (void)testDelegateCallbackWithValidBufferAndOrientationUpdate {
#if TARGET_OS_IPHONE
  // given
  UIDevice *currentDeviceMock = OCMClassMock([UIDevice class]);
  // UpsideDown -> RTCVideoRotation_270.
  OCMStub(currentDeviceMock.orientation).andReturn(UIDeviceOrientationPortraitUpsideDown);
  id classMock = OCMClassMock([UIDevice class]);
  OCMStub([classMock currentDevice]).andReturn(currentDeviceMock);

  CMSampleBufferRef sampleBuffer = createTestSampleBufferRef();

  // then
  [[self.delegateMock expect] capturer:self.capturer
                  didCaptureVideoFrame:[OCMArg checkWithBlock:^BOOL(RTCVideoFrame *expectedFrame) {
                    EXPECT_EQ(expectedFrame.rotation, RTCVideoRotation_270);
                    return YES;
                  }]];

  // when
  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
  [center postNotificationName:UIDeviceOrientationDidChangeNotification object:nil];

  // We need to wait for the dispatch to finish.
  WAIT(0, 1000);

  [self.capturer captureOutput:self.capturer.captureSession.outputs[0]
         didOutputSampleBuffer:sampleBuffer
                fromConnection:self.captureConnectionMock];

  [self.delegateMock verify];

  [(id)currentDeviceMock stopMocking];
  currentDeviceMock = nil;
  [classMock stopMocking];
  classMock = nil;
  CFRelease(sampleBuffer);
#endif
}

- (void)testRotationCamera:(AVCaptureDevicePosition)camera
           withOrientation:(UIDeviceOrientation)deviceOrientation {
#if TARGET_OS_IPHONE
  // Mock the AVCaptureConnection as we will get the camera position from the connection's
  // input ports.
  AVCaptureDeviceInput *inputPortMock = OCMClassMock([AVCaptureDeviceInput class]);
  AVCaptureInputPort *captureInputPort = OCMClassMock([AVCaptureInputPort class]);
  NSArray *inputPortsArrayMock = @[captureInputPort];
  AVCaptureDevice *captureDeviceMock = OCMClassMock([AVCaptureDevice class]);
  OCMStub(((AVCaptureConnection *)self.captureConnectionMock).inputPorts).
      andReturn(inputPortsArrayMock);
  OCMStub(captureInputPort.input).andReturn(inputPortMock);
  OCMStub(inputPortMock.device).andReturn(captureDeviceMock);
  OCMStub(captureDeviceMock.position).andReturn(camera);

  // UpsideDown -> RTCVideoRotation_0.
  UIDevice *currentDeviceMock = OCMClassMock([UIDevice class]);
  OCMStub(currentDeviceMock.orientation).andReturn(deviceOrientation);
  id classMock = OCMClassMock([UIDevice class]);
  OCMStub([classMock currentDevice]).andReturn(currentDeviceMock);

  CMSampleBufferRef sampleBuffer = createTestSampleBufferRef();

  [[self.delegateMock expect] capturer:self.capturer
                  didCaptureVideoFrame:[OCMArg checkWithBlock:^BOOL(RTCVideoFrame *expectedFrame) {
    if (camera == AVCaptureDevicePositionFront) {
      if (deviceOrientation == UIDeviceOrientationLandscapeLeft) {
        EXPECT_EQ(expectedFrame.rotation, RTCVideoRotation_180);
      } else if (deviceOrientation == UIDeviceOrientationLandscapeRight) {
        EXPECT_EQ(expectedFrame.rotation, RTCVideoRotation_0);
      }
    } else if (camera == AVCaptureDevicePositionBack) {
      if (deviceOrientation == UIDeviceOrientationLandscapeLeft) {
        EXPECT_EQ(expectedFrame.rotation, RTCVideoRotation_0);
      } else if (deviceOrientation == UIDeviceOrientationLandscapeRight) {
        EXPECT_EQ(expectedFrame.rotation, RTCVideoRotation_180);
      }
    }
    return YES;
  }]];

  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
  [center postNotificationName:UIDeviceOrientationDidChangeNotification object:nil];

  // We need to wait for the dispatch to finish.
  WAIT(0, 1000);

  [self.capturer captureOutput:self.capturer.captureSession.outputs[0]
         didOutputSampleBuffer:sampleBuffer
                fromConnection:self.captureConnectionMock];

  [self.delegateMock verify];

  [(id)currentDeviceMock stopMocking];
  currentDeviceMock = nil;
  [classMock stopMocking];
  classMock = nil;
  CFRelease(sampleBuffer);
#endif
}

- (void)setExif:(CMSampleBufferRef)sampleBuffer {
  CFMutableDictionaryRef exif = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL);
  CFDictionarySetValue(exif, CFSTR("LensModel"), CFSTR("iPhone SE back camera 4.15mm f/2.2"));
  CMSetAttachment(sampleBuffer, CFSTR("{Exif}"), exif, kCMAttachmentMode_ShouldPropagate);
}

- (void)testRotationFrame {
#if TARGET_OS_IPHONE
  // Mock the AVCaptureConnection as we will get the camera position from the connection's
  // input ports.
  AVCaptureDeviceInput *inputPortMock = OCMClassMock([AVCaptureDeviceInput class]);
  AVCaptureInputPort *captureInputPort = OCMClassMock([AVCaptureInputPort class]);
  NSArray *inputPortsArrayMock = @[captureInputPort];
  AVCaptureDevice *captureDeviceMock = OCMClassMock([AVCaptureDevice class]);
  OCMStub(((AVCaptureConnection *)self.captureConnectionMock).inputPorts).
      andReturn(inputPortsArrayMock);
  OCMStub(captureInputPort.input).andReturn(inputPortMock);
  OCMStub(inputPortMock.device).andReturn(captureDeviceMock);
  OCMStub(captureDeviceMock.position).andReturn(AVCaptureDevicePositionFront);

  // UpsideDown -> RTCVideoRotation_0.
  UIDevice *currentDeviceMock = OCMClassMock([UIDevice class]);
  OCMStub(currentDeviceMock.orientation).andReturn(UIDeviceOrientationLandscapeLeft);
  id classMock = OCMClassMock([UIDevice class]);
  OCMStub([classMock currentDevice]).andReturn(currentDeviceMock);

  CMSampleBufferRef sampleBuffer = createTestSampleBufferRef();

  [[self.delegateMock expect] capturer:self.capturer
                  didCaptureVideoFrame:[OCMArg checkWithBlock:^BOOL(RTCVideoFrame *expectedFrame) {
    // Front camera and landscape left should return 180. But the frame says its from the back
    // camera, so rotation should be 0.
    EXPECT_EQ(expectedFrame.rotation, RTCVideoRotation_0);
    return YES;
  }]];

  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
  [center postNotificationName:UIDeviceOrientationDidChangeNotification object:nil];

  // We need to wait for the dispatch to finish.
  WAIT(0, 1000);

  [self setExif:sampleBuffer];

  [self.capturer captureOutput:self.capturer.captureSession.outputs[0]
         didOutputSampleBuffer:sampleBuffer
                fromConnection:self.captureConnectionMock];

  [self.delegateMock verify];

  [(id)currentDeviceMock stopMocking];
  currentDeviceMock = nil;
  [classMock stopMocking];
  classMock = nil;
  CFRelease(sampleBuffer);
#endif
}

- (void)testImageExif {
#if TARGET_OS_IPHONE
  CMSampleBufferRef sampleBuffer = createTestSampleBufferRef();
  [self setExif:sampleBuffer];

  AVCaptureDevicePosition cameraPosition = [AVCaptureSession
                                            devicePositionForSampleBuffer:sampleBuffer];
  EXPECT_EQ(cameraPosition, AVCaptureDevicePositionBack);
#endif
}

- (void)testStartingAndStoppingCapture {
  id expectedDeviceInputMock = OCMClassMock([AVCaptureDeviceInput class]);
  id captureDeviceInputMock = OCMClassMock([AVCaptureDeviceInput class]);
  OCMStub([captureDeviceInputMock deviceInputWithDevice:self.deviceMock error:[OCMArg setTo:nil]])
      .andReturn(expectedDeviceInputMock);

  OCMStub([self.deviceMock lockForConfiguration:[OCMArg setTo:nil]]).andReturn(YES);
  OCMStub([self.deviceMock unlockForConfiguration]);
  OCMStub([_captureSessionMock canAddInput:expectedDeviceInputMock]).andReturn(YES);
  OCMStub([_captureSessionMock inputs]).andReturn(@[ expectedDeviceInputMock ]);
  OCMStub([_captureSessionMock removeInput:expectedDeviceInputMock]);

  // Set expectation that the capture session should be started with correct device.
  OCMExpect([_captureSessionMock addInput:expectedDeviceInputMock]);
  OCMExpect([_captureSessionMock startRunning]);
  OCMExpect([_captureSessionMock stopRunning]);

  id format = OCMClassMock([AVCaptureDeviceFormat class]);
  [self.capturer startCaptureWithDevice:self.deviceMock format:format fps:30];
  [self.capturer stopCapture];

  // Start capture code is dispatched async.
  OCMVerifyAllWithDelay(_captureSessionMock, 15);
}

- (void)testStartCaptureFailingToLockForConfiguration {
  // The captureSessionMock is a strict mock, so this test will crash if the startCapture
  // method does not return when failing to lock for configuration.
  OCMExpect([self.deviceMock lockForConfiguration:[OCMArg setTo:nil]]).andReturn(NO);

  id format = OCMClassMock([AVCaptureDeviceFormat class]);
  [self.capturer startCaptureWithDevice:self.deviceMock format:format fps:30];

  // Start capture code is dispatched async.
  OCMVerifyAllWithDelay(self.deviceMock, 15);
}

- (void)testStartingAndStoppingCaptureWithCallbacks {
  id expectedDeviceInputMock = OCMClassMock([AVCaptureDeviceInput class]);
  id captureDeviceInputMock = OCMClassMock([AVCaptureDeviceInput class]);
  OCMStub([captureDeviceInputMock deviceInputWithDevice:self.deviceMock error:[OCMArg setTo:nil]])
      .andReturn(expectedDeviceInputMock);

  OCMStub([self.deviceMock lockForConfiguration:[OCMArg setTo:nil]]).andReturn(YES);
  OCMStub([self.deviceMock unlockForConfiguration]);
  OCMStub([_captureSessionMock canAddInput:expectedDeviceInputMock]).andReturn(YES);
  OCMStub([_captureSessionMock inputs]).andReturn(@[ expectedDeviceInputMock ]);
  OCMStub([_captureSessionMock removeInput:expectedDeviceInputMock]);

  // Set expectation that the capture session should be started with correct device.
  OCMExpect([_captureSessionMock addInput:expectedDeviceInputMock]);
  OCMExpect([_captureSessionMock startRunning]);
  OCMExpect([_captureSessionMock stopRunning]);

  dispatch_semaphore_t completedStopSemaphore = dispatch_semaphore_create(0);

  __block BOOL completedStart = NO;
  id format = OCMClassMock([AVCaptureDeviceFormat class]);
  [self.capturer startCaptureWithDevice:self.deviceMock
                                 format:format
                                    fps:30
                      completionHandler:^(NSError *error) {
                        EXPECT_EQ(error, nil);
                        completedStart = YES;
                      }];

  __block BOOL completedStop = NO;
  [self.capturer stopCaptureWithCompletionHandler:^{
    completedStop = YES;
    dispatch_semaphore_signal(completedStopSemaphore);
  }];

  dispatch_semaphore_wait(completedStopSemaphore,
                          dispatch_time(DISPATCH_TIME_NOW, 15.0 * NSEC_PER_SEC));
  OCMVerifyAllWithDelay(_captureSessionMock, 15);
  EXPECT_TRUE(completedStart);
  EXPECT_TRUE(completedStop);
}

- (void)testStartCaptureFailingToLockForConfigurationWithCallback {
  id expectedDeviceInputMock = OCMClassMock([AVCaptureDeviceInput class]);
  id captureDeviceInputMock = OCMClassMock([AVCaptureDeviceInput class]);
  OCMStub([captureDeviceInputMock deviceInputWithDevice:self.deviceMock error:[OCMArg setTo:nil]])
      .andReturn(expectedDeviceInputMock);

  id errorMock = OCMClassMock([NSError class]);

  OCMStub([self.deviceMock lockForConfiguration:[OCMArg setTo:errorMock]]).andReturn(NO);
  OCMStub([_captureSessionMock canAddInput:expectedDeviceInputMock]).andReturn(YES);
  OCMStub([self.deviceMock unlockForConfiguration]);

  OCMExpect([_captureSessionMock addInput:expectedDeviceInputMock]);

  dispatch_semaphore_t completedStartSemaphore = dispatch_semaphore_create(0);
  __block NSError *callbackError = nil;

  id format = OCMClassMock([AVCaptureDeviceFormat class]);
  [self.capturer startCaptureWithDevice:self.deviceMock
                                 format:format
                                    fps:30
                      completionHandler:^(NSError *error) {
                        callbackError = error;
                        dispatch_semaphore_signal(completedStartSemaphore);
                      }];

  long ret = dispatch_semaphore_wait(completedStartSemaphore,
                                     dispatch_time(DISPATCH_TIME_NOW, 15.0 * NSEC_PER_SEC));
  EXPECT_EQ(ret, 0);
  EXPECT_EQ(callbackError, errorMock);
}

@end

TEST(RTCCameraVideoCapturerTests, SetupSession) {
  RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
  [test setup];
  [test testSetupSession];
  [test tearDown];
}

TEST(RTCCameraVideoCapturerTests, SetupSessionOutput) {
  RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
  [test setup];
  [test testSetupSessionOutput];
  [test tearDown];
}

TEST(RTCCameraVideoCapturerTests, SupportedFormatsForDevice) {
  RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
  [test setup];
  [test testSupportedFormatsForDevice];
  [test tearDown];
}

TEST(RTCCameraVideoCapturerTests, CaptureDevices) {
  RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
  [test setup];
  [test testCaptureDevices];
  [test tearDown];
}

TEST(RTCCameraVideoCapturerTests, DelegateCallbackNotCalledWhenInvalidBuffer) {
  RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
  [test setup];
  [test testDelegateCallbackNotCalledWhenInvalidBuffer];
  [test tearDown];
}

TEST(RTCCameraVideoCapturerTests, DelegateCallbackWithValidBufferAndOrientationUpdate) {
  RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
  [test setup];
  [test testDelegateCallbackWithValidBufferAndOrientationUpdate];
  [test tearDown];
}

TEST(RTCCameraVideoCapturerTests, RotationCameraBackLandscapeLeft) {
  RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
  [test setup];
  [test testRotationCamera:AVCaptureDevicePositionBack
           withOrientation:UIDeviceOrientationLandscapeLeft];
  [test tearDown];
}

TEST(RTCCameraVideoCapturerTests, RotationCameraFrontLandscapeLeft) {
  RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
  [test setup];
  [test testRotationCamera:AVCaptureDevicePositionFront
           withOrientation:UIDeviceOrientationLandscapeLeft];
  [test tearDown];
}

TEST(RTCCameraVideoCapturerTests, RotationCameraBackLandscapeRight) {
  RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
  [test setup];
  [test testRotationCamera:AVCaptureDevicePositionBack
           withOrientation:UIDeviceOrientationLandscapeRight];
  [test tearDown];
}

TEST(RTCCameraVideoCapturerTests, RotationCameraFrontLandscapeRight) {
  RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
  [test setup];
  [test testRotationCamera:AVCaptureDevicePositionFront
           withOrientation:UIDeviceOrientationLandscapeRight];
  [test tearDown];
}

TEST(RTCCameraVideoCapturerTests, RotationCameraFrame) {
  RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
  [test setup];
  [test testRotationFrame];
  [test tearDown];
}

TEST(RTCCameraVideoCapturerTests, ImageExif) {
  RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
  [test setup];
  [test testImageExif];
  [test tearDown];
}

TEST(RTCCameraVideoCapturerTests, StartAndStopCapture) {
  RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
  [test setupWithMockedCaptureSession];
  [test testStartingAndStoppingCapture];
  [test tearDown];
}

TEST(RTCCameraVideoCapturerTests, StartCaptureFailingToLockForConfiguration) {
  RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
  [test setupWithMockedCaptureSession];
  [test testStartCaptureFailingToLockForConfiguration];
  [test tearDown];
}

TEST(RTCCameraVideoCapturerTests, StartAndStopCaptureWithCallbacks) {
  RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
  [test setupWithMockedCaptureSession];
  [test testStartingAndStoppingCaptureWithCallbacks];
  [test tearDown];
}

TEST(RTCCameraVideoCapturerTests, StartCaptureFailingToLockForConfigurationWithCallback) {
  RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
  [test setupWithMockedCaptureSession];
  [test testStartCaptureFailingToLockForConfigurationWithCallback];
  [test tearDown];
}
