/* * Copyright 2017 Google * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #import "FIRMessagingFakeConnection.h" #import #import "Protos/GtalkCore.pbobjc.h" #import "FIRMessagingSecureSocket.h" #import "FIRMessagingUtilities.h" static NSString *const kHost = @"localhost"; static const int kPort = 6234; @interface FIRMessagingSecureSocket () @property(nonatomic, readwrite, assign) FIRMessagingSecureSocketState state; @end @interface FIRMessagingConnection () @property(nonatomic, readwrite, strong) FIRMessagingSecureSocket *socket; - (void)setupConnectionSocket; - (void)connectToSocket:(FIRMessagingSecureSocket *)socket; - (NSTimeInterval)connectionTimeoutInterval; - (void)sendHeartbeatPing; - (void)secureSocket:(FIRMessagingSecureSocket *)socket didReceiveData:(NSData *)data withTag:(int8_t)tag; @end @implementation FIRMessagingFakeConnection - (void)signIn { // use this if you don't really want to mock/stub the login behaviour. In case // you want to stub the login behavoiur you should do these things manually in // your test and add custom logic in between as required for your testing. [self setupConnectionSocket]; id socketMock = OCMPartialMock(self.socket); self.socket = socketMock; [[[socketMock stub] andDo:^(NSInvocation *invocation) { if (self.shouldFakeSuccessLogin) { [self willFakeSuccessfulLoginToFCM]; } self.socket.state = kFIRMessagingSecureSocketOpen; [self.socket.delegate secureSocketDidConnect:self.socket]; }] connectToHost:kHost port:kPort onRunLoop:[OCMArg any]]; [self connectToSocket:socketMock]; } - (NSTimeInterval)connectionTimeoutInterval { if (self.fakeConnectionTimeout) { return self.fakeConnectionTimeout; } else { return 0.5; // 0.5s } } - (void)mockSocketDisconnect { id mockSocket = self.socket; [[[mockSocket stub] andDo:^(NSInvocation *invocation) { self.socket.state = kFIRMessagingSecureSocketClosed; }] disconnect]; } - (void)disconnectNow { [self.socket disconnect]; [self.socket.delegate didDisconnectWithSecureSocket:self.socket]; } + (NSString *)fakeHost { return @"localhost"; } + (int)fakePort { return 6234; } - (void)willFakeSuccessfulLoginToFCM { id mockSocket = self.socket; [[[mockSocket stub] andDo:^(NSInvocation *invocation) { // mock successful login GtalkLoginResponse *response = [[GtalkLoginResponse alloc] init]; [response setId_p:@""]; [self secureSocket:self.socket didReceiveData:[response data] withTag:kFIRMessagingProtoTagLoginResponse]; }] sendData:[OCMArg any] withTag:kFIRMessagingProtoTagLoginRequest rmqId:[OCMArg isNil]]; } @end @implementation FIRMessagingFakeFailConnection - (void)signIn { self.signInRequests++; [self setupConnectionSocket]; id mockSocket = OCMPartialMock(self.socket); self.socket = mockSocket; [[[mockSocket stub] andDo:^(NSInvocation *invocation) { [self mockSocketDisconnect]; if (self.signInRequests <= self.failCount) { // do nothing -- should timeout } else { // since we will always fail once we would disconnect the socket before // we ever try again thus mock the disconnect to change the state and // prevent any assertions [self willFakeSuccessfulLoginToFCM]; self.socket.state = kFIRMessagingSecureSocketOpen; [self.socket.delegate secureSocketDidConnect:self.socket]; } }] connectToHost:kHost port:kPort onRunLoop:[OCMArg any]]; [self connectToSocket:mockSocket]; } @end