Need to write test case for MongoDB Realm Swift SDK - ios

I am working on MongoDB Realm Swift SDk and I need to write the test case for the login function which is as below:
let params: Document = ["username": "bob"]
app.login(credentials: Credentials.function(payload: params)) { (result) in
switch result {
case .failure(let error):
print("Login failed: \(error.localizedDescription)")
case .success(let user):
print("Successfully logged in as user \(user)")
// Now logged in, do something with user
// Remember to dispatch to main if you are doing anything on the UI thread
}
}
May I know how to write test case for this function with Mock Data so that I can verify that Login is working fine?

Related

"Cannot Parse Response" error when logging in from certain countries - MongoDB Atlas Device Sync (prev. Realm Sync)

I'm using MongoDB's Atlas Device Sync (until recently it was called Realm Sync) to handle login for my iOS app, coded in Swift.
I am UK based, and the app works fine for users in the UK. However, I recently sent the app to contacts in Eastern Europe (Poland, Belarus, potentially other countries as well. One person also tried logging in using a French VPN apparently) and they've all received the same error when creating an account or logging in with an already created account.
The localised description of this error is "cannot parse response".
Unfortunately I am based in the UK so I can't replicate it on my own device. However, I know that the error when creating an account is being thrown from the below code:
app.emailPasswordAuth.registerUser(email: email!, password: password!, completion: { [weak self] (error) in
DispatchQueue.main.async {
guard error == nil else {
self!.signUpFailed(with: error!)
return
}
self!.signIn(with: self!.email!, and: self!.password!)
}
})
And I know that the error when logging in to an already created account is being thrown from the below code:
app.login(credentials: Credentials.emailPassword(email: email, password: password)) { [weak self] (result) in
DispatchQueue.main.async {
switch result {
case .failure(let error):
self!.signInFailed(with: error)
return
case .success(let user):
self!.continueLoggingIn()
}
}
}
I'm at a bit of a loss here. I have no idea why the response can be parsed in the UK but not other countries. I assume it's an issue with Mongo/Realm but I could be wrong. If anyone can shed any light it would be greatly appreciated.

Realm device sync "Action on service 'mongodb-atlas' forbidden: no rules have been configured for this service" error

I'm developing a mobile app using Swift and Realm database.
I configured Realm Device Sync and tried to add custom user data to a cluster I created.
Even though I watched dozens of tutorials about realm permissions I still can't figure out what's wrong with the in-app permissions
here is the authentication function I am using to add Custom User Data
func login() {
isLoading = true
errorMessage = nil
let credentials = Credentials.emailPassword(email: username, password: password)
DispatchQueue.main.async {
app.login(credentials: credentials) { [weak self] result in
switch (result) {
case .failure(let error):
print(String(describing: error))
self?.errorMessage = error.localizedDescription
case .success(let user):
if user.customData.isEmpty {
let client = user.mongoClient("mongodb-atlas")
let database = client.database(named: "UserAPI")
let collection = database.collection(withName: "Users")
// Insert the custom user data object
let customUserData: Document = [
"_id": AnyBSON(user.id),
"email": .string(self!.email),
"province": .string(self!.province),
"_partition": .string(user.id)
]
collection.insertOne(customUserData) {result in
switch result {
case .failure(let error):
print("Failed to insert document: \(error.localizedDescription)")
case .success(let newObjectId):
print("Inserted custom user data document with object ID: \(newObjectId)")
}
}
}
}
self?.isLoading = false
}
}
}
But when I try to create a new user, it successfully creates one. The problem is, when it comes things comes to adding the Custom User Data it returns an error like this:
Failed to insert document: no rule exists for namespace 'UserAPI.Users'
and when I check the MongoDB logs, I can see the error in more detail:
my Custom User Data settings:
and my app permissions:
any help would be appriciated, I'm struggling with this error for 3 days, thanks in advance.
#GrandSirr - have you tried setting "users can read and write all data" permissions template (for development, at least)?
Also, what is your actual 'Users' collection? User custom data should be a separate collection in my opinion as size of user custom data is limited.
My flow - login users with email password - set database triggers to create a new user document with relevant fields that a user can later fill in eg 'profile settings' page of your app and another trigger to create a document in a separate user custom data collection to save some permission roles or subscription to notifications etc.

How to create a new user with custom required fields in Parse

I am using Parse and created a new colums in the User. I set the field to "Required", but now I can't create a user anymore.
Error i get:
Login failed: ParseError code=142 error=myCustomColumn is required
This is how I did it:
do {
let currentUser = try User.signup(username: "user", password: "password")
print("Login succes: \(currentUser)")
} catch {
print("Login failed: \(error)")
}
How can I set my custom field? It's already created in the struct. I just need to set the value.
I am using ParseSwift.
https://github.com/parse-community/Parse-Swift
This can be done by using the instance version of signUp in the documentation. An example is shown in the playgrounds:
//: To add additional information when signing up a user,
//: you should create an instance of your user first.
var newUser = User(username: "parse", password: "aPassword*", email: "parse#parse.com")
//: Add any other additional information.
newUser.targetScore = .init(score: 40)
newUser.signup { result in
switch result {
case .success(let user):
guard let currentUser = User.current else {
assertionFailure("Error: current user not stored locally")
return
}
assert(currentUser.hasSameObjectId(as: user))
print("Successfully signed up as user: \(user)")
case .failure(let error):
print("Error logging in: \(error)")
}
}
Also, in my example above, I’m signing up asynchronously, which is most likely the way you want to signup. In your example, you are signing up synchronously, which can hold up the main queue and cause run-time warnings in Xcode

How to customize Amplify Auth Error Messages

I am attempting to implement amplify auth on iOS, and what I would like to be able to do is customize the error message that is displayed to a user when authentication fails, as the default error messages are not end-user friendly, but I have no idea how to do this.
For instance, my signIn method is as follows:
func signIn(username: String) {
Amplify.Auth.signIn(username: username, password: "bla") { [weak self] result in
switch result {
case .success (let result):
if case .confirmSignInWithCustomChallenge(_) = result.nextStep {
DispatchQueue.main.async {
self?.showConfirmationSignInView()
}
} else {
print("Sign in succeeded")
}
case .failure(let error):
print (error)
}
}
}
Now in the .failure case, instead of printing the error, I would ideally like to determine if the error is a userNotFound error, or something else. I can't find any info in the docs on this. Any help would be appreciated.
You can do it by checking the error.code. for example, for a user who did not confirm the email if he tries to login then error.code will have UserNotConfirmedException string value. Amplify auth returns different exception codes for different types of errors. You can see all the exceptions from this link. Although it is for flutter, the exception code is identical for any framework. I have used these exception codes in react.

How to post to user's facebook feed

I need to post to user's facebook feed.
Based on several other SO questions I came up with the following posting request:
let request = GraphRequest(graphPath: "me/feed", parameters: ["message" : "Hello world"], accessToken: accessToken, httpMethod: .POST, apiVersion: GraphAPIVersion.defaultVersion)
request.start({ (response, requestResult) in
switch requestResult {
case .failed(let error):
print("error in graph request:", error)
case .success(let graphResponse):
if let responseDictionary = graphResponse.dictionaryValue {
print(responseDictionary)
}
}
})
This fails due to
error = {
code = 200;
"fbtrace_id" = GMp2cebddNb;
message = "(#200) Requires either publish_actions permission, or manage_pages and publish_pages as an admin with sufficient administrative permission";
type = OAuthException;
};
Based on the message, the problem seemed to be an easy to solve - all I need is to get either publish_actions, or manage_pages and publish_pages permissions. Based on this SO question, this seemed easy and I ended up in wrapping the code for posting with this:
let loginManager = LoginManager()
loginManager.logIn([PublishPermission.custom("publish_actions")], viewController: self) { (result) in
print(">> \(AccessToken.current?.grantedPermissions)")
switch result {
case .cancelled:
print(">>>> Cancelled")
case .failed(let error):
print(">>>> Error: \(error)" )
case .success(grantedPermissions: _, declinedPermissions: _, token: let accessToken):
print(">>>> Logged in!")
let request = GraphRequest(graphPath: "me/feed", parameters: ["message" : post], accessToken: accessToken, httpMethod: .POST, apiVersion: GraphAPIVersion.defaultVersion)
request.start({ (response, requestResult) in
switch requestResult {
case .failed(let error):
print("error in graph request:", error)
break
case .success(let graphResponse):
if let responseDictionary = graphResponse.dictionaryValue {
print(responseDictionary)
}
}
})
}
}
Now the "funny" part is, that then the facebook SDK shows a page telling me that I previously logged in to my app using Facebook and asks me if I would like to continue. When I press Continue, the SafariViewController dismisses and the .cancelled branch gets executed. What is going on here? I haven't cancelled, nor have I been asked to grant permissions to publish anything on my feed.
P.S.: I tried logging out first (loginManager.logOut() and/or AccessToken.current = nil), in that case the .success branch executes but again with the same error "(#200) Requires either publish_actions permission, or manage_pages and publish_pages as an admin with sufficient administrative permission".
The AccessToken.current.grantedPermissions in that case contains:
Set([FacebookCore.Permission(name: "user_friends"),
FacebookCore.Permission(name: "publish_pages"),
FacebookCore.Permission(name: "user_location"),
FacebookCore.Permission(name: "email"),
FacebookCore.Permission(name: "user_likes"),
FacebookCore.Permission(name: "pages_show_list"),
FacebookCore.Permission(name: "manage_pages"),
FacebookCore.Permission(name: "user_photos"),
FacebookCore.Permission(name: "public_profile"),
FacebookCore.Permission(name: "user_posts"),
FacebookCore.Permission(name: "user_birthday")])
So no publish_actions permission! Why does the login go through successfully while not granting me the permission that I ask for? Moreover, I obviously have "manage_pages" and "publish_pages", so why is that not enough?
https://developers.facebook.com/docs/graph-api/changelog/breaking-changes#4-24-2018
The publish_actions permission has been removed.
Since they do not mention any alternative, there is no way to post to the user feed anymore.

Resources