Skip to content

Commit

Permalink
Merge pull request #14 from deskpro/develop
Browse files Browse the repository at this point in the history
Merge develop into main branch
  • Loading branch information
qsd-faris authored Feb 16, 2024
2 parents 43134f4 + d1646ba commit 400192f
Show file tree
Hide file tree
Showing 12 changed files with 223 additions and 111 deletions.
89 changes: 5 additions & 84 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ DeskPro iOS Messenger is a Chat/AI/Messaging product. You can embed a “widget
- Swift 5.7+
- Xcode 14.0+

## Running the tests

Once you're in the root directory of the package, you can run the tests using the Swift Package Manager's `swift test` command. This will compile the package and its tests, and then run the tests. This command will execute all test cases defined in the Swift Package.

## Installation

- File > Swift Packages > Add Package Dependency
- Add `https://github.com/deskpro/messenger-sdk-ios`
- Select "Up to Next Major" version

## Manual installation
Although we recommend using SPM, it is also possible to clone this repository manually, and drag and drop it into the root folder of the application.

## Setup and Initialization
First, import the SDK:
```
Expand All @@ -40,7 +40,6 @@ var messenger: DeskPro?

Replace `YOUR_APP_URL` and `YOUR_APP_ID` with your app's URL and ID.

The messenger variable is initialized in viewDidLoad and is responsible for handling the WebView presentation:
```
override func viewDidLoad() {
super.viewDidLoad()
Expand All @@ -49,91 +48,13 @@ override func viewDidLoad() {
```


To trigger the WebView to open, paste this line in the desired place:
To open a Messenger, paste this line example in the desired place:
```
messenger?.present().show()
```




### Branch Naming
A git branch should be named coherently to make sure the connection to Trello is given.
Generally, most projects have 2 branches 'main' and 'develop', whereas 'main' is the code-base that is currently deployed to production and 'develop' is the somewhat stable development base for new features and the current code-base for the test system.
New features branch from the develop branch and should be named feat/[TrelloTicket]-a-good-description.
Bugfixes should be named bugfix/[TrelloTicket]-a-good-description or fix/[TrelloTicket]-a-good-description.

### Commit Guidelines
Commits should be written in English.
Commits should have the Trello Ticket number as a prefix. e.g.:
DP-123 Add some awesome feature
How to write good commits is often hard but necessary. Generally, there are 7 rules of great git commit messages:
* Separate subject from body with a blank line
* Limit the subject line to 50 characters
* Capitalize the subject line
* Do not end the subject line with a period
* Use the imperative mood in the subject line
* Wrap the body at 72 characters
* Use the body to explain what and why vs. how
Further readings and examples are in this [blogpost](https://chris.beams.io/posts/git-commit/)

### Pull Request Guidelines
A pull request should be opened when the developer has finished developing his/her User Stories and thinks the acceptance criteria are met. Once opened, the developer should assign reviewers who review the code. Incorporate feasible feedback and try to resolve the occurring discussions.

#### Merge Guidelines
After enough approves for the Pull Request are gathered and all the automated checks pass the Pull Request can be merged.
GitHub offers 3 options on how to merge a Pull Request:
* Merge pull request
* Squash and merge
* Rebase and merge

The first option merge pull request will do a normal no fast forward merge into the target branch.
The second option will squash all your commits in the source branch into one commit and then merge this one commit into the target branch.
The third option will replay all your commits in the source branch on top of the target branch. Errors can occur more easily here so this approach is not recommended.

We will leave it optional whether to merge via the first or second approach. However, developers should adhere to the conventional commit guidelines when merging a Pull Request. This makes it easier to automate semantic version bumps and changelog creation.
A conventional commit has this basic structure:

<type>[(optional scope)]: <description>

[optional body]

[optional footer]


available types:

* feat - when adding a new feature minor (1.x.0)
* fix - when fixing a bug patch (1.1.x)
* perf - performance improvement without adding features or changing interfaces patch (1.1.x)
* chore - when doing some chores e.g. removing old references, doing a release
* refactor - refactorings
* ci - changes to the continuous integration
* docs - adding documentation
* build - when updating build scripts
* style - improve code style (changing indents, bracket placements, ...)

If a breaking change is within the pull request please add BREAKING CHANGE: to the optional body and describe what and why it is one. This triggers a major version bump no matter which <type> is used.

For <description> and <optional body> our normal commit guidelines are still valid.

Examples:
Commit message with description and breaking change in body
feat: DP-123 Allow provided config object to extend other configs (#12)

BREAKING CHANGE: The `extends` key in the config file is now used for extending other config files

Closes #12, DP-123
Commit message with scope
feat(lang): DP-143 Add german language (#21)

Closes #21, DP-143
Commit message for a fix
fix: DP-432 Fix minor typos in the Deskpro description (#41)

Fixes #41, DP-432
Note: You can create multiple Messenger instances.

## Versioning

We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/deskpro/messenger-sdk-ios/tags).

6 changes: 5 additions & 1 deletion Sources/Data/User.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import Foundation

/// - Tag: User
public class User: Codable {
public class User: Codable, Equatable {

public var name: String? = nil
public var firstName: String? = nil
Expand All @@ -20,4 +20,8 @@ public class User: Codable {
self.lastName = lastName
self.email = email
}

public static func == (lhs: User, rhs: User) -> Bool {
return lhs.name == rhs.name && lhs.firstName == rhs.firstName && lhs.lastName == rhs.lastName && lhs.email == rhs.email
}
}
34 changes: 27 additions & 7 deletions Sources/Deskpro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public final class DeskPro: Messenger {
private var coordinator: PresentCoordinator

/// User defaults manager for storing user-related information.
private var appUserDefaults: AppUserDefaults?
var appUserDefaults: AppUserDefaults

/// Each Deskpro instance is having its own eventRouter to handle events in chat.
public var eventRouter: EventRouter
Expand All @@ -42,7 +42,7 @@ public final class DeskPro: Messenger {
/// The method is intended to simulate a test scenario and provide a String result based on the outcome of the test.
///
/// - Returns: A String representing the result of the test operation.
public final func test() -> String {
public static func test() -> String {
return "Hello world from Messenger!"
}

Expand All @@ -54,7 +54,17 @@ public final class DeskPro: Messenger {
/// - Parameter user: The [User](x-source-tag://User) object containing the user information.
///
public final func setUserInfo(user: User) {
appUserDefaults?.setUserInfo(user)
appUserDefaults.setUserInfo(user)
}

/// Getter method for user info, should only be used for testing.
final func getUserInfo() -> User? {
return appUserDefaults.getUserInfo()
}

/// Getter method for user info in JSON format, should only be used for testing.
final func getUserInfoJson() -> String? {
return appUserDefaults.getUserInfoJson()
}

/// Sets a user JWT token that enables Messenger to treat this user as a logged-in user.
Expand All @@ -64,18 +74,23 @@ public final class DeskPro: Messenger {
/// - Returns: `true` if the token is successfully saved, `false` otherwise.
@discardableResult
public final func authorizeUser(userJwt: String) -> Bool {
appUserDefaults?.setJwtToken(userJwt)
appUserDefaults.setJwtToken(userJwt)
return true
}

/// Getter method for JWT token, should only be used for testing.
func getJwtToken() -> String? {
return appUserDefaults.getJwtToken()
}

/// Logs out the current user from the SDK session.
///
/// This method performs a logout operation, ending the current user's session with the SDK. After calling this method, the user will need to log in again to use the SDK features.
///
/// - Returns: `true` if the logout operation is successful; `false` otherwise.
@discardableResult
public final func forgetUser() -> Bool {
appUserDefaults?.clear()
appUserDefaults.clear()
return true
}

Expand All @@ -88,10 +103,15 @@ public final class DeskPro: Messenger {
/// - Returns: `true` if the push registration token is successfully set; `false` otherwise.
@discardableResult
public final func setPushRegistrationToken(token: String) -> Bool {
appUserDefaults?.setDeviceToken(token)
appUserDefaults.setDeviceToken(token)
return true
}

/// Getter method for device token, should only be used for testing.
func getPushRegistrationToken() -> String? {
return appUserDefaults.getDeviceToken()
}

/// Checks whether a push notification is related to the DeskPro SDK.
///
/// This method examines the provided push notification data to determine whether it is intended for the DeskPro SDK.
Expand All @@ -101,7 +121,7 @@ public final class DeskPro: Messenger {
/// - Returns: `true` if the push notification is related to DeskPro; `false` otherwise.
///
/// - Tag: isDeskProPushNotification
public final func isDeskProPushNotification(data: [AnyHashable: Any]) -> Bool {
public static func isDeskProPushNotification(data: [AnyHashable: Any]) -> Bool {
if let issuer = data["issuer"] as? String {
return issuer == "deskpro-messenger"
} else {
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions Sources/Messenger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ protocol Messenger {
/// The method is intended to simulate a test scenario and provide a String result based on the outcome of the test.
///
/// - Returns: A String representing the result of the test operation.
func test() -> String
static func test() -> String

/// Sets user information for the application.
///
Expand Down Expand Up @@ -57,7 +57,7 @@ protocol Messenger {
/// - Returns: `true` if the push notification is related to DeskPro; `false` otherwise.
///
/// - Tag: isDeskProPushNotification
func isDeskProPushNotification(data: [AnyHashable: Any]) -> Bool
static func isDeskProPushNotification(data: [AnyHashable: Any]) -> Bool

/// Handles the incoming push notification data if it is related to DeskPro.
///
Expand Down
4 changes: 4 additions & 0 deletions Sources/PresentBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public final class PresentBuilder {

/// Represents the constructed path for the URL.
private var path = ""

func getPath() -> String {
return path
}

/// This method is a constructor for creating Deskpro objects
///
Expand Down
6 changes: 0 additions & 6 deletions Sources/messenger-sdk-ios/messenger_sdk_ios.swift

This file was deleted.

110 changes: 110 additions & 0 deletions Tests/messenger-sdk-iosTests/DeskProSetup/DeskProSetupTest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
//
// DeskproSetupTest.swift
//
//
// Created by QSD BiH on 14. 2. 2024..
//

import XCTest
@testable import messenger_sdk_ios

final class DeskproSetupTest: XCTestCase {

var messenger: DeskPro!
let appUrl = "test/url/data"
let appId = "1"
let vc = UIViewController()

let user = User(name: "John Doe", firstName: "John", lastName: "Doe", email: "[email protected]")
let jwtToken = "some-jwt-token"
let deviceToken = "some-device-token"

override func setUp() {
let messengerConfig = MessengerConfig(appUrl: appUrl, appId: appId)
messenger = DeskPro(messengerConfig: messengerConfig, containingViewController: vc)
}

override func tearDown() {
messenger = nil
}

func testSetAndGetUserInfo() {
messenger.setUserInfo(user: user)

XCTAssertEqual(user, messenger.getUserInfo(), ErrorMessages.usersNotMatching)
}

func testSetAndGetUserInfoJson() {
messenger.setUserInfo(user: user)

if let jsonString = messenger.getUserInfoJson(),
let jsonData = jsonString.data(using: .utf8) {
let savedUser = try? JSONDecoder().decode(User.self, from: jsonData)
XCTAssertEqual(user, savedUser, ErrorMessages.usersNotMatching)
}
}

func testSetAndGetJwtToken() {
messenger.authorizeUser(userJwt: jwtToken)

XCTAssertEqual(jwtToken, messenger.getJwtToken(), ErrorMessages.tokensNotMatching)
}

func testSetAndGetPushRegistrationToken() {
messenger.setPushRegistrationToken(token: deviceToken)

XCTAssertEqual(deviceToken, messenger.getPushRegistrationToken(), ErrorMessages.tokensNotMatching)
}

func testClearData() {
messenger.setUserInfo(user: user)
messenger.authorizeUser(userJwt: jwtToken)
messenger.setPushRegistrationToken(token: deviceToken)

messenger.forgetUser()

XCTAssertNil(messenger.getUserInfo(), ErrorMessages.userInfoNotNil)
XCTAssertNil(messenger.getUserInfoJson(), ErrorMessages.userInfoJsonNotNil)
XCTAssertNil(messenger.getJwtToken(), ErrorMessages.jwtTokenNotNil)
XCTAssertNil(messenger.getPushRegistrationToken(), ErrorMessages.deviceTokenNotNil)
}

func testSetAndGetMultipleDeskProInstances() {
let messengerConfig2 = MessengerConfig(appUrl: "some_url", appId: "2")
let messenger2 = DeskPro(messengerConfig: messengerConfig2, containingViewController: vc)
let user2 = User(name: "John Doe 2", firstName: "John 2", lastName: "Doe 2", email: "[email protected]")
let jwtToken2 = "another-jwt-token"
let deviceToken2 = "another-device-token"

messenger.setUserInfo(user: user)
messenger.authorizeUser(userJwt: jwtToken)
messenger.setPushRegistrationToken(token: deviceToken)

messenger2.setUserInfo(user: user2)
messenger2.authorizeUser(userJwt: jwtToken2)
messenger2.setPushRegistrationToken(token: deviceToken2)

XCTAssertEqual(user2, messenger2.getUserInfo(), ErrorMessages.usersNotMatching)
if let jsonString = messenger2.getUserInfoJson(),
let jsonData = jsonString.data(using: .utf8) {
let savedUser = try? JSONDecoder().decode(User.self, from: jsonData)
XCTAssertEqual(user2, savedUser, ErrorMessages.usersNotMatching)
}
XCTAssertEqual(jwtToken2, messenger2.getJwtToken(), ErrorMessages.tokensNotMatching)
XCTAssertEqual(deviceToken2, messenger2.getPushRegistrationToken(), ErrorMessages.tokensNotMatching)
}

func testPresentBuilder() {
let presentBuilder = PresentBuilder(url: appUrl, appId: appId, coordinator: PresentCoordinator(containingViewController: vc, eventRouter: EventRouter()))
XCTAssertEqual(appUrl, presentBuilder.getPath(), ErrorMessages.pathsNotMatching)

_ = presentBuilder.chatHistory(1)
XCTAssertEqual("\(appUrl)/chat_history/1", presentBuilder.getPath(), ErrorMessages.pathsNotMatching)

_ = presentBuilder.article(1)
XCTAssertEqual("\(appUrl)/chat_history/1/article/1", presentBuilder.getPath(), ErrorMessages.pathsNotMatching)

_ = presentBuilder.comments()
XCTAssertEqual("\(appUrl)/chat_history/1/article/1/comments", presentBuilder.getPath(), ErrorMessages.pathsNotMatching)
}
}
Loading

0 comments on commit 400192f

Please sign in to comment.