• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

realm / realm-core / 1691

20 Sep 2023 01:57AM UTC coverage: 91.217% (+0.05%) from 91.168%
1691

push

Evergreen

web-flow
Merge pull request #6837 from realm/tg/user-provider

Fix handling of users with multiple identities

95990 of 175908 branches covered (0.0%)

799 of 830 new or added lines in 24 files covered. (96.27%)

44 existing lines in 15 files now uncovered.

233732 of 256237 relevant lines covered (91.22%)

6741306.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.89
/test/object-store/util/unit_test_transport.cpp
1
////////////////////////////////////////////////////////////////////////////
2
//
3
// Copyright 2023 Realm Inc.
4
//
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing, software
12
// distributed under the License is distributed on an "AS IS" BASIS,
13
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
// See the License for the specific language governing permissions and
15
// limitations under the License.
16
//
17
////////////////////////////////////////////////////////////////////////////
18

19
#include "util/unit_test_transport.hpp"
20

21
#include <realm/object-store/util/uuid.hpp>
22
#include <realm/object-store/sync/app_credentials.hpp>
23
#include <realm/object-store/sync/app_utils.hpp>
24
#include <realm/util/platform_info.hpp>
25

26
#include <catch2/catch_all.hpp>
27

28
using namespace realm;
29
using namespace realm::app;
30

31
std::string UnitTestTransport::access_token =
32
    "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
33
    "eyJleHAiOjE1ODE1MDc3OTYsImlhdCI6MTU4MTUwNTk5NiwiaXNzIjoiNWU0M2RkY2M2MzZlZTEwNmVhYTEyYmRjIiwic3RpdGNoX2RldklkIjoi"
34
    "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIiwic3RpdGNoX2RvbWFpbklkIjoiNWUxNDk5MTNjOTBiNGFmMGViZTkzNTI3Iiwic3ViIjoiNWU0M2Rk"
35
    "Y2M2MzZlZTEwNmVhYTEyYmRhIiwidHlwIjoiYWNjZXNzIn0.0q3y9KpFxEnbmRwahvjWU1v9y1T1s3r2eozu93vMc3s";
36
const std::string UnitTestTransport::api_key = "lVRPQVYBJSIbGos2ZZn0mGaIq1SIOsGaZ5lrcp8bxlR5jg4OGuGwQq1GkektNQ3i";
37
const std::string UnitTestTransport::api_key_id = "5e5e6f0abe4ae2a2c2c2d329";
38
const std::string UnitTestTransport::api_key_name = "some_api_key_name";
39
const std::string UnitTestTransport::auth_route = "https://mongodb.com/unittests";
40
const std::string UnitTestTransport::identity_0_id = "Ursus arctos isabellinus";
41
const std::string UnitTestTransport::identity_1_id = "Ursus arctos horribilis";
42

43
UnitTestTransport::UnitTestTransport(const std::string& provider_type, uint64_t request_timeout)
44
    : m_provider_type(provider_type)
45
    , m_request_timeout(request_timeout)
46
    , m_options({{"device",
47
                  {{"appId", "app_id"},
48
                   {"platform", util::get_library_platform()},
49
                   {"platformVersion", "Object Store Test Platform Version"},
50
                   {"sdk", "SDK Name"},
51
                   {"sdkVersion", "SDK Version"},
52
                   {"cpuArch", util::get_library_cpu_arch()},
53
                   {"deviceName", "Device Name"},
54
                   {"deviceVersion", "Device Version"},
55
                   {"frameworkName", "Framework Name"},
56
                   {"frameworkVersion", "Framework Version"},
57
                   {"coreVersion", REALM_VERSION_STRING},
58
                   {"bundleId", "Bundle Id"}}}})
59
{
22✔
60
}
22✔
61

62
void UnitTestTransport::handle_profile(const Request& request,
63
                                       util::UniqueFunction<void(const Response&)>&& completion)
64
{
56✔
65
    CHECK(request.method == HttpMethod::get);
56!
66
    auto content_type = AppUtils::find_header("Content-Type", request.headers);
56✔
67
    CHECK(content_type);
56!
68
    CHECK(content_type->second == "application/json;charset=utf-8");
56!
69
    auto authorization = AppUtils::find_header("Authorization", request.headers);
56✔
70
    CHECK(authorization);
56!
71
    CHECK(authorization->second == "Bearer " + access_token);
56!
72
    CHECK(request.body.empty());
56!
73
    CHECK(request.timeout_ms == m_request_timeout);
56!
74

28✔
75
    std::string user_id = util::uuid_string();
56✔
76
    std::string response;
56✔
77
    if (m_provider_type == IdentityProviderAnonymous) {
56✔
78
        response = nlohmann::json({{"user_id", user_id},
34✔
79
                                   {"identities", {{{"id", identity_0_id}, {"provider_type", m_provider_type}}}},
34✔
80
                                   {"data", m_user_profile}})
34✔
81
                       .dump();
34✔
82
    }
34✔
83
    else {
22✔
84
        response = nlohmann::json({{"user_id", user_id},
22✔
85
                                   {"identities",
22✔
86
                                    {{{"id", identity_0_id}, {"provider_type", m_provider_type}},
22✔
87
                                     {{"id", identity_1_id}, {"provider_type", "lol_wut"}}}},
22✔
88
                                   {"data", m_user_profile}})
22✔
89
                       .dump();
22✔
90
    }
22✔
91

28✔
92
    completion(Response{200, 0, {}, response});
56✔
93
}
56✔
94

95
void UnitTestTransport::handle_login(const Request& request, util::UniqueFunction<void(const Response&)>&& completion)
96
{
56✔
97
    CHECK(request.method == HttpMethod::post);
56!
98
    auto item = AppUtils::find_header("Content-Type", request.headers);
56✔
99
    CHECK(item);
56!
100
    CHECK(item->second == "application/json;charset=utf-8");
56!
101
    CHECK(nlohmann::json::parse(request.body)["options"] == m_options);
56!
102

28✔
103
    CHECK(request.timeout_ms == m_request_timeout);
56!
104

28✔
105
    std::string response = nlohmann::json({{"access_token", access_token},
56✔
106
                                           {"refresh_token", access_token},
56✔
107
                                           {"user_id", util::uuid_string()},
56✔
108
                                           {"device_id", "Panda Bear"}})
56✔
109
                               .dump();
56✔
110

28✔
111
    completion(Response{200, 0, {}, response});
56✔
112
}
56✔
113

114
void UnitTestTransport::handle_location(const Request& request,
115
                                        util::UniqueFunction<void(const Response&)>&& completion)
116
{
50✔
117
    CHECK(request.method == HttpMethod::get);
50!
118
    CHECK(request.timeout_ms == m_request_timeout);
50!
119

25✔
120
    std::string response = nlohmann::json({{"deployment_model", "this"},
50✔
121
                                           {"hostname", "field"},
50✔
122
                                           {"ws_hostname", "shouldn't"},
50✔
123
                                           {"location", "matter"}})
50✔
124
                               .dump();
50✔
125

25✔
126
    completion(Response{200, 0, {}, response});
50✔
127
}
50✔
128

129
void UnitTestTransport::handle_create_api_key(const Request& request,
130
                                              util::UniqueFunction<void(const Response&)>&& completion)
131
{
2✔
132
    CHECK(request.method == HttpMethod::post);
2!
133
    auto item = AppUtils::find_header("Content-Type", request.headers);
2✔
134
    CHECK(item);
2!
135
    CHECK(item->second == "application/json;charset=utf-8");
2!
136
    CHECK(nlohmann::json::parse(request.body) == nlohmann::json({{"name", api_key_name}}));
2!
137
    CHECK(request.timeout_ms == m_request_timeout);
2!
138

1✔
139
    std::string response =
2✔
140
        nlohmann::json({{"_id", api_key_id}, {"key", api_key}, {"name", api_key_name}, {"disabled", false}}).dump();
2✔
141

1✔
142
    completion(Response{200, 0, {}, response});
2✔
143
}
2✔
144

145
void UnitTestTransport::handle_fetch_api_key(const Request& request,
146
                                             util::UniqueFunction<void(const Response&)>&& completion)
147
{
2✔
148
    CHECK(request.method == HttpMethod::get);
2!
149
    auto item = AppUtils::find_header("Content-Type", request.headers);
2✔
150
    CHECK(item);
2!
151
    CHECK(item->second == "application/json;charset=utf-8");
2!
152

1✔
153
    CHECK(request.body == "");
2!
154
    CHECK(request.timeout_ms == m_request_timeout);
2!
155

1✔
156
    std::string response = nlohmann::json({{"_id", api_key_id}, {"name", api_key_name}, {"disabled", false}}).dump();
2✔
157

1✔
158
    completion(Response{200, 0, {}, response});
2✔
159
}
2✔
160

161
void UnitTestTransport::handle_fetch_api_keys(const Request& request,
162
                                              util::UniqueFunction<void(const Response&)>&& completion)
163
{
2✔
164
    CHECK(request.method == HttpMethod::get);
2!
165
    auto item = AppUtils::find_header("Content-Type", request.headers);
2✔
166
    CHECK(item);
2!
167
    CHECK(item->second == "application/json;charset=utf-8");
2!
168

1✔
169
    CHECK(request.body == "");
2!
170
    CHECK(request.timeout_ms == m_request_timeout);
2!
171

1✔
172
    auto elements = std::vector<nlohmann::json>();
2✔
173
    for (int i = 0; i < 2; i++) {
6✔
174
        elements.push_back({{"_id", api_key_id}, {"name", api_key_name}, {"disabled", false}});
4✔
175
    }
4✔
176

1✔
177
    completion(Response{200, 0, {}, nlohmann::json(elements).dump()});
2✔
178
}
2✔
179

180
void UnitTestTransport::handle_token_refresh(const Request& request,
181
                                             util::UniqueFunction<void(const Response&)>&& completion)
NEW
182
{
×
NEW
183
    CHECK(request.method == HttpMethod::post);
×
NEW
184
    auto item = AppUtils::find_header("Content-Type", request.headers);
×
NEW
185
    CHECK(item);
×
NEW
186
    CHECK(item->second == "application/json;charset=utf-8");
×
187

NEW
188
    CHECK(request.body == "");
×
NEW
189
    CHECK(request.timeout_ms == m_request_timeout);
×
190

NEW
191
    auto elements = std::vector<nlohmann::json>();
×
NEW
192
    nlohmann::json json{{"access_token", access_token}};
×
193

NEW
194
    completion(Response{200, 0, {}, json.dump()});
×
NEW
195
}
×
196

197
void UnitTestTransport::send_request_to_server(const Request& request,
198
                                               util::UniqueFunction<void(const Response&)>&& completion)
199
{
188✔
200
    if (request.url.find("/login") != std::string::npos) {
188✔
201
        handle_login(request, std::move(completion));
56✔
202
    }
56✔
203
    else if (request.url.find("/profile") != std::string::npos) {
132✔
204
        handle_profile(request, std::move(completion));
56✔
205
    }
56✔
206
    else if (request.url.find("/session") != std::string::npos && request.method != HttpMethod::post) {
76✔
207
        completion(Response{200, 0, {}, ""});
20✔
208
    }
20✔
209
    else if (request.url.find("/api_keys") != std::string::npos && request.method == HttpMethod::post) {
56✔
210
        handle_create_api_key(request, std::move(completion));
2✔
211
    }
2✔
212
    else if (request.url.find(util::format("/api_keys/%1", api_key_id)) != std::string::npos &&
54✔
213
             request.method == HttpMethod::get) {
28✔
214
        handle_fetch_api_key(request, std::move(completion));
2✔
215
    }
2✔
216
    else if (request.url.find("/api_keys") != std::string::npos && request.method == HttpMethod::get) {
52✔
217
        handle_fetch_api_keys(request, std::move(completion));
2✔
218
    }
2✔
219
    else if (request.url.find("/session") != std::string::npos && request.method == HttpMethod::post) {
50!
NEW
220
        handle_token_refresh(request, std::move(completion));
×
NEW
221
    }
×
222
    else if (request.url.find("/location") != std::string::npos && request.method == HttpMethod::get) {
50✔
223
        handle_location(request, std::move(completion));
50✔
224
    }
50✔
NEW
225
    else {
×
NEW
226
        completion(Response{200, 0, {}, "something arbitrary"});
×
NEW
227
    }
×
228
}
188✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc