// 
// Copyright 2022 The Matrix.org Foundation C.I.C
//
// 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 Foundation

import XCTest
@testable import MatrixSDK

class MXLocationServiceTests: XCTestCase {

    private var testData: MatrixSDKTestsData!
    
    override func setUp() {
        testData = MatrixSDKTestsData()
        MXSDKOptions.sharedInstance().enableThreads = true
    }

    override func tearDown() {
        testData = nil
    }
    
    /// Test: Expect the location service is initialized after creating a session
    /// - Create a Bob session
    /// - Expect location service is initialized
    func testInitialization() {
        testData.doMXSessionTest(withBob: self) { bobSession, expectation in
            guard let bobSession = bobSession,
                  let expectation = expectation else {
                XCTFail("Failed to setup test conditions")
                return
            }
            
            XCTAssertNotNil(bobSession.locationService, "Location service must be created")
            
            expectation.fulfill()
        }
    }
    
    /// Test: Expect beacon info state event is created after user has started to share is location
    /// - Create a Bob session
    /// - Create an initial room
    /// - Start location sharing
    /// - Expect a beacon info state event created in the room
    func testStartingThread() {
        let store = MXMemoryStore()
        testData.doMXSessionTest(withBobAndARoom: self, andStore: store) { bobSession, initialRoom, expectation in
            guard let bobSession = bobSession,
                  let initialRoom = initialRoom,
                  let expectation = expectation else {
                XCTFail("Failed to setup test conditions")
                return
            }
            
            let locationService: MXLocationService = bobSession.locationService
            
            let expectedBeaconInfoDescription = "Live location description"
            let expectedBeaconInfoTimeout: TimeInterval = 600000
            let expectedBeaconInfoIsLive = true
            
            locationService.startUserLocationSharing(withRoomId: initialRoom.roomId, description: expectedBeaconInfoDescription, timeout: expectedBeaconInfoTimeout) { response in
                
                switch response {
                case .success(let eventId):
                    
                    initialRoom.state { roomState in
                        
                        let beaconInfo = roomState?.beaconInfoEvents.last
                        
                        let beaconInfoStateEvent = roomState?.stateEvents.first(where: { event in
                            event.eventId == eventId
                        })
                        
                        XCTAssertNotNil(beaconInfoStateEvent)
                        
                        XCTAssertNotNil(beaconInfo)
                        
                        if let beaconInfo = beaconInfo {
                            
                            XCTAssertEqual(beaconInfo.desc, expectedBeaconInfoDescription)
                            XCTAssertEqual(beaconInfo.timeout, expectedBeaconInfoTimeout)
                            XCTAssertEqual(beaconInfo.isLive, expectedBeaconInfoIsLive)
                        }
                        
                        expectation.fulfill()
                    }
                case .failure(let error):
                    XCTFail("Start location sharing fails with error: \(error)")
                    expectation.fulfill()
                }
            }
        }
    }
}

Add location service integration tests.
Add location service integration tests.
