// Copyright 2021 Google LLC // // 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 XCTest @testable import FirebaseCoreInternal import HeartbeatLoggingTestUtils class HeartbeatsBundleTests: XCTestCase { // 2021-11-01 @ 00:00:00 (EST) let date = Date(timeIntervalSince1970: 1_635_739_200) func testInitializesWithDefaultCacheProvider() throws { // Given let heartbeatsBundle = HeartbeatsBundle(capacity: 0) // Then XCTAssertEqual( heartbeatsBundle.lastAddedHeartbeatDates, [ .daily: .distantPast, ] ) } func testAppendingHeartbeatUpdatesCache() throws { // Given var heartbeatsBundle = HeartbeatsBundle(capacity: 1) let heartbeat = Heartbeat(agent: "dummy_agent", date: date, timePeriods: [.daily]) // When heartbeatsBundle.append(heartbeat) // Then let heartbeatsBundleString = heartbeatsBundle .makeHeartbeatsPayload() .headerValue() try HeartbeatLoggingTestUtils.assertEqualPayloadStrings( heartbeatsBundleString, """ { "version": 2, "heartbeats": [ { "agent": "dummy_agent", "dates": ["2021-11-01"] } ] } """ ) XCTAssertEqual(heartbeatsBundle.lastAddedHeartbeatDates, [.daily: heartbeat.date]) } func testAppendingHeartbeat_WhenCapacityIsZero_DoesNothing() throws { // Given var heartbeatsBundle = HeartbeatsBundle(capacity: 0) let preAppendCacheSnapshot = heartbeatsBundle.lastAddedHeartbeatDates let heartbeat = Heartbeat(agent: "dummy_agent", date: date, timePeriods: [.daily]) // When heartbeatsBundle.append(heartbeat) // Then let heartbeatsBundleString = heartbeatsBundle .makeHeartbeatsPayload() .headerValue() try HeartbeatLoggingTestUtils.assertEqualPayloadStrings( heartbeatsBundleString, """ { "version": 2, "heartbeats": [] } """ ) XCTAssertEqual(heartbeatsBundle.lastAddedHeartbeatDates, preAppendCacheSnapshot) } func testAppendingHeartbeat_AtMaxCapacity_RemovesOverwrittenFromCache() throws { // Given var heartbeatsBundle = HeartbeatsBundle(capacity: 1) let heartbeat1 = Heartbeat(agent: "dummy_agent_1", date: date, timePeriods: [.daily]) heartbeatsBundle.append(heartbeat1) XCTAssertEqual(heartbeatsBundle.lastAddedHeartbeatDates, [.daily: heartbeat1.date]) let heartbeat2 = Heartbeat(agent: "dummy_agent_2", date: date, timePeriods: [.daily]) // When heartbeatsBundle.append(heartbeat2) // Then let heartbeatsBundleString = heartbeatsBundle .makeHeartbeatsPayload() .headerValue() try HeartbeatLoggingTestUtils.assertEqualPayloadStrings( heartbeatsBundleString, """ { "version": 2, "heartbeats": [ { "agent": "dummy_agent_2", "dates": ["2021-11-01"] } ] } """ ) XCTAssertEqual(heartbeatsBundle.lastAddedHeartbeatDates, [.daily: heartbeat2.date]) } func testRemovingHeartbeatFromDateDoesNotUpdateCache() throws { // Given var heartbeatsBundle = HeartbeatsBundle(capacity: 1) let heartbeat = Heartbeat(agent: "agent", date: date, timePeriods: [.daily]) heartbeatsBundle.append(heartbeat) // When heartbeatsBundle.removeHeartbeat(from: date) // Then XCTAssertEqual( heartbeatsBundle.lastAddedHeartbeatDates, [ .daily: heartbeat.date, ] ) } func testRemovingHeartbeatFromDate_WhenCapacityIsZero_DoesNothing() throws { // Given var heartbeatsBundle = HeartbeatsBundle(capacity: 0) let preRemoveCacheSnapshot = heartbeatsBundle.lastAddedHeartbeatDates // When let removedHeartbeat = heartbeatsBundle.removeHeartbeat(from: date) // Then XCTAssertNil(removedHeartbeat) let heartbeatsBundleString = heartbeatsBundle .makeHeartbeatsPayload() .headerValue() try HeartbeatLoggingTestUtils.assertEqualPayloadStrings( heartbeatsBundleString, """ { "version": 2, "heartbeats": [] } """ ) XCTAssertEqual(heartbeatsBundle.lastAddedHeartbeatDates, preRemoveCacheSnapshot) } func testRemovingHeartbeatFromDate_WhenHeartbeatFromDateInBundle_RemovesAndReturnsTheHeartbeat() throws { // Given var heartbeatsBundle = HeartbeatsBundle(capacity: 1) let heartbeat = Heartbeat(agent: "dummy_agent", date: date, timePeriods: [.daily]) heartbeatsBundle.append(heartbeat) // When let removedHeartbeat = heartbeatsBundle.removeHeartbeat(from: date) // Then XCTAssertEqual(removedHeartbeat, heartbeat) let heartbeatsBundleString = heartbeatsBundle .makeHeartbeatsPayload() .headerValue() try HeartbeatLoggingTestUtils.assertEqualPayloadStrings( heartbeatsBundleString, """ { "version": 2, "heartbeats": [] } """ ) } func testRemovingHeartbeatFromDate_WhenHeartbeatFromDateNotInBundle_RemovesNothingAndReturnsNil() throws { // Given var heartbeatsBundle = HeartbeatsBundle(capacity: 1) let heartbeat = Heartbeat(agent: "dummy_agent", date: date, timePeriods: [.daily]) heartbeatsBundle.append(heartbeat) // When let removedHeartbeat = heartbeatsBundle.removeHeartbeat(from: .distantPast) // Then XCTAssertNil(removedHeartbeat) let heartbeatsBundleString = heartbeatsBundle .makeHeartbeatsPayload() .headerValue() try HeartbeatLoggingTestUtils.assertEqualPayloadStrings( heartbeatsBundleString, """ { "version": 2, "heartbeats": [ { "agent": "dummy_agent", "dates": ["2021-11-01"] } ] } """ ) } func testRemovingHeartbeatFromDate_DoesNotAlterOrderingForRemainingHeartbeats() throws { // Given var heartbeatsBundle = HeartbeatsBundle(capacity: 3) let yesterdayDate = date.addingTimeInterval(-1 * 60 * 60 * 24) let heartbeat1 = Heartbeat(agent: "dummy_agent_1", date: .distantPast) let heartbeat2 = Heartbeat(agent: "dummy_agent_2", date: yesterdayDate) let heartbeat3 = Heartbeat(agent: "dummy_agent_3", date: date) heartbeatsBundle.append(heartbeat1) // [heartbeat1, __________, __________] heartbeatsBundle.append(heartbeat2) // [heartbeat1, heartbeat1, __________] heartbeatsBundle.append(heartbeat3) // [heartbeat1, heartbeat2, heartbeat3] // When heartbeatsBundle.removeHeartbeat(from: yesterdayDate) // [heartbeat1, heartbeat3, nil] // Then let heartbeat4 = Heartbeat(agent: "dummy_agent_4", date: date) let heartbeat5 = Heartbeat(agent: "dummy_agent_5", date: date) heartbeatsBundle.append(heartbeat4) // [heartbeat1, heartbeat3, heartbeat4] heartbeatsBundle.append(heartbeat5) // [heartbeat5, heartbeat3, heartbeat4] let heartbeatsBundleString = heartbeatsBundle .makeHeartbeatsPayload() .headerValue() try HeartbeatLoggingTestUtils.assertEqualPayloadStrings( heartbeatsBundleString, """ { "version": 2, "heartbeats": [ { "agent": "dummy_agent_3", "dates": ["2021-11-01"] }, { "agent": "dummy_agent_4", "dates": ["2021-11-01"] }, { "agent": "dummy_agent_5", "dates": ["2021-11-01"] } ] } """ ) } func testRemovingHeartbeatFromDate_WhenMultipleHeartbeatFromDateExist_RemovesAndReturnsTheLastHeartbeat() throws { // Given var heartbeatsBundle = HeartbeatsBundle(capacity: 3) let heartbeat1 = Heartbeat(agent: "dummy_agent_1", date: date) let heartbeat2 = Heartbeat(agent: "dummy_agent_2", date: date) let heartbeat3 = Heartbeat(agent: "dummy_agent_3", date: date) heartbeatsBundle.append(heartbeat1) // [heartbeat1, __________, __________] heartbeatsBundle.append(heartbeat2) // [heartbeat1, heartbeat2, __________] heartbeatsBundle.append(heartbeat3) // [heartbeat1, heartbeat2, heartbeat3] // When let removed = heartbeatsBundle .removeHeartbeat(from: date) // [heartbeat1, heartbeat2, __________] // Then XCTAssertEqual(removed, heartbeat3) let heartbeatsBundleString = heartbeatsBundle .makeHeartbeatsPayload() .headerValue() try HeartbeatLoggingTestUtils.assertEqualPayloadStrings( heartbeatsBundleString, """ { "version": 2, "heartbeats": [ { "agent": "dummy_agent_1", "dates": ["2021-11-01"] }, { "agent": "dummy_agent_2", "dates": ["2021-11-01"] } ] } """ ) } func testMakePayload_WithMultipleUserAgents() throws { // Given var heartbeatsBundle = HeartbeatsBundle(capacity: 2) // When let heartbeat1 = Heartbeat(agent: "dummy_agent_1", date: date) heartbeatsBundle.append(heartbeat1) let heartbeat2 = Heartbeat(agent: "dummy_agent_2", date: date) heartbeatsBundle.append(heartbeat2) // Then let heartbeatsBundleString = heartbeatsBundle .makeHeartbeatsPayload() .headerValue() try HeartbeatLoggingTestUtils.assertEqualPayloadStrings( heartbeatsBundleString, """ { "version": 2, "heartbeats": [ { "agent": "dummy_agent_1", "dates": ["2021-11-01"] }, { "agent": "dummy_agent_2", "dates": ["2021-11-01"] } ] } """ ) } }