Skip to content

Commit

Permalink
[NO-ISSUE] feat(users): allow to provide external userId (uuid) (#17)
Browse files Browse the repository at this point in the history
* refactor: adapt/update js client

* chore: update justfile

* ci: adapt JS client lib's CI

* test: start adding integration tests for our use cases

* ci: fix actions/setup-node usage for pnpm

* ci: update actions + install pnpm

* ci: remove cache on actions/setup-node as it's pretty fast

* test: add more tests to integration tests

* refactor: rename file + adapt requirements' tests

* feat(users): allow to provide external userId (uuid)

* chore: fix formatting

* test(requirements): provide userUuid
  • Loading branch information
GuillaumeDecMeetsMore authored Jul 25, 2024
1 parent 45f9700 commit 6951dcb
Show file tree
Hide file tree
Showing 30 changed files with 194 additions and 55 deletions.
1 change: 1 addition & 0 deletions scheduler/clients/javascript/lib/userClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type UpdateUserRequest = {

type CreateUserRequest = {
metadata?: Metadata;
userId?: string;
};

type UserResponse = {
Expand Down
4 changes: 3 additions & 1 deletion scheduler/clients/javascript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@
"@types/jest": "^29.5.12",
"@types/jsonwebtoken": "9.0.6",
"@types/node": "20.14.10",
"@types/uuid": "10.0.0",
"jest": "29.7.0",
"jsonwebtoken": "9.0.2",
"ts-jest": "29.2.2",
"typescript": "5.5.3"
"typescript": "5.5.3",
"uuid": "10.0.0"
}
}
17 changes: 17 additions & 0 deletions scheduler/clients/javascript/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Calendar, INettuClient, User, CalendarEvent } from "../../lib";
import { setupAccount } from "../helpers/fixtures";
import { v4 } from "uuid";

// This test suite is testing the specifications for our use cases

Expand All @@ -20,14 +21,15 @@ describe("Requirements", () => {
let user1Calendar1: Calendar | undefined;

it("should create a user", async () => {
// TODO: we cannot provide an ID for the user
// For our use case, we would like to provide our own ID
// To be adapted
const res = await client?.user.create();
const userUuid = v4();
const res = await client?.user.create({
userId: userUuid,
});
if (!res?.data) {
throw new Error("User not created");
}
expect(res?.status).toBe(201);
expect(res?.data.user.id).toEqual(userUuid);

user1 = res.data.user;
});
Expand Down
28 changes: 28 additions & 0 deletions scheduler/clients/javascript/tests/user.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { INettuClient, NettuClient, Frequenzy, INettuUserClient } from "../lib";
import { setupUserClient } from "./helpers/fixtures";
import { v4 } from "uuid";

describe("User API", () => {
let userId: string;
Expand Down Expand Up @@ -43,6 +44,33 @@ describe("User API", () => {
expect(res.status).toBe(404);
});

it("should create a 2nd user, and provide the ID", async () => {
const userId = v4();
let res = await accountClient.user.create({
userId,
});
expect(res.status).toBe(201);
if (!res.data) {
throw new Error("User not created");
}
const { user } = res.data;

expect(user.id).toBe(userId);

res = await accountClient.user.find(userId);
expect(res.status).toBe(200);
if (!res.data) {
throw new Error("User not found");
}
expect(res.data.user.id).toBe(userId);

res = await accountClient.user.remove(userId);
expect(res.status).toBe(200);

res = await accountClient.user.find(userId);
expect(res.status).toBe(404);
});

it("should not show any freebusy with no events", async () => {
const res = await accountClient.user.freebusy(userId, {
endTs: 1000 * 60 * 60 * 24 * 4,
Expand Down
2 changes: 1 addition & 1 deletion scheduler/crates/api/src/calendar/update_calendar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ mod test {
let ctx = setup_context().await;
let account = Account::default();
ctx.repos.accounts.insert(&account).await.unwrap();
let user = User::new(account.id.clone());
let user = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user).await.unwrap();
let calendar = Calendar::new(&user.id, &account.id);
ctx.repos.calendars.insert(&calendar).await.unwrap();
Expand Down
2 changes: 1 addition & 1 deletion scheduler/crates/api/src/event/create_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ mod test {
let ctx = setup_context().await;
let account = Account::default();
ctx.repos.accounts.insert(&account).await.unwrap();
let user = User::new(account.id.clone());
let user = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user).await.unwrap();
let calendar = Calendar::new(&user.id, &account.id);
ctx.repos.calendars.insert(&calendar).await.unwrap();
Expand Down
2 changes: 1 addition & 1 deletion scheduler/crates/api/src/event/get_upcoming_reminders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ mod tests {
let account = Account::default();
ctx.repos.accounts.insert(&account).await.unwrap();

let user = User::new(account.id.clone());
let user = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user).await.unwrap();
let mut calendar = Calendar::new(&user.id, &account.id);
calendar.settings.timezone = chrono_tz::Europe::Oslo;
Expand Down
4 changes: 2 additions & 2 deletions scheduler/crates/api/src/service/get_service_bookingslots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,8 +515,8 @@ mod test {
}

async fn setup_service_users(ctx: &NettuContext, service: &mut Service, account_id: &ID) {
let user1 = User::new(account_id.clone());
let user2 = User::new(account_id.clone());
let user1 = User::new(account_id.clone(), None);
let user2 = User::new(account_id.clone(), None);
ctx.repos.users.insert(&user1).await.unwrap();
ctx.repos.users.insert(&user2).await.unwrap();
let mut resource1 = ServiceResource {
Expand Down
12 changes: 6 additions & 6 deletions scheduler/crates/api/src/shared/auth/route_guards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ mod test {
async fn decodes_valid_token_for_existing_user_in_account() {
let ctx = setup_context().await;
let account = setup_account(&ctx).await;
let user = User::new(account.id.clone());
let user = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user).await.unwrap();
let token = get_token(false, user.id.clone());

Expand All @@ -309,7 +309,7 @@ mod test {
let ctx = setup_context().await;
let account = setup_account(&ctx).await;
let account2 = setup_account(&ctx).await;
let user = User::new(account2.id.clone()); // user belongs to account2
let user = User::new(account2.id.clone(), None); // user belongs to account2
ctx.repos.users.insert(&user).await.unwrap();
// account1 tries to sign a token with user_id that belongs to account2
let token = get_token(false, user.id.clone());
Expand All @@ -327,7 +327,7 @@ mod test {
async fn rejects_expired_token() {
let ctx = setup_context().await;
let account = setup_account(&ctx).await;
let user = User::new(account.id.clone());
let user = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user).await.unwrap();
let token = get_token(true, user.id.clone());

Expand All @@ -344,7 +344,7 @@ mod test {
async fn rejects_valid_token_without_account_header() {
let ctx = setup_context().await;
let account = setup_account(&ctx).await;
let user = User::new(account.id.clone());
let user = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user).await.unwrap();
let token = get_token(true, user.id.clone());

Expand All @@ -360,7 +360,7 @@ mod test {
async fn rejects_valid_token_with_invalid_account_header() {
let ctx = setup_context().await;
let account = setup_account(&ctx).await;
let user = User::new(account.id.clone());
let user = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user).await.unwrap();
let token = get_token(true, user.id.clone());

Expand Down Expand Up @@ -391,7 +391,7 @@ mod test {
async fn rejects_invalid_authz_header() {
let ctx = setup_context().await;
let account = setup_account(&ctx).await;
let user = User::new(account.id.clone());
let user = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user).await.unwrap();

let req = TestRequest::default()
Expand Down
4 changes: 3 additions & 1 deletion scheduler/crates/api/src/user/create_user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub async fn create_user_controller(
let usecase = CreateUserUseCase {
account_id: account.id,
metadata: body.0.metadata.unwrap_or_default(),
user_id: body.0.user_id,
};

execute(usecase, &ctx)
Expand All @@ -27,6 +28,7 @@ pub async fn create_user_controller(
pub struct CreateUserUseCase {
pub account_id: ID,
pub metadata: Metadata,
pub user_id: Option<ID>,
}

#[derive(Debug)]
Expand Down Expand Up @@ -58,7 +60,7 @@ impl UseCase for CreateUserUseCase {
const NAME: &'static str = "CreateUser";

async fn execute(&mut self, ctx: &NettuContext) -> Result<Self::Response, Self::Error> {
let mut user = User::new(self.account_id.clone());
let mut user = User::new(self.account_id.clone(), self.user_id.clone());
user.metadata = self.metadata.clone();

if let Some(_existing_user) = ctx.repos.users.find(&user.id).await {
Expand Down
2 changes: 1 addition & 1 deletion scheduler/crates/api/src/user/get_user_freebusy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ mod test {
let ctx = setup_context().await;
let account = Account::default();
ctx.repos.accounts.insert(&account).await.unwrap();
let user = User::new(account.id.clone());
let user = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user).await.unwrap();
let calendar = Calendar::new(&user.id(), &user.account_id);
ctx.repos.calendars.insert(&calendar).await.unwrap();
Expand Down
2 changes: 2 additions & 0 deletions scheduler/crates/api_structs/src/user/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ pub mod create_user {
pub struct RequestBody {
#[serde(default)]
pub metadata: Option<Metadata>,

pub user_id: Option<ID>,
}

pub type APIResponse = UserResponse;
Expand Down
3 changes: 2 additions & 1 deletion scheduler/crates/domain/src/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ pub struct User {
}

impl User {
pub fn new(account_id: ID) -> Self {
pub fn new(account_id: ID, user_id: Option<ID>) -> Self {
Self {
account_id,
id: user_id.unwrap_or_default(),
..Default::default()
}
}
Expand Down
6 changes: 3 additions & 3 deletions scheduler/crates/infra/src/repos/calendar/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ mod tests {
let ctx = setup_context().await;
let account = Account::default();
ctx.repos.accounts.insert(&account).await.unwrap();
let user = User::new(account.id.clone());
let user = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user).await.unwrap();
let calendar = Calendar::new(&user.id, &account.id);

Expand All @@ -50,7 +50,7 @@ mod tests {
let ctx = setup_context().await;
let account = Account::default();
ctx.repos.accounts.insert(&account).await.unwrap();
let user = User::new(account.id.clone());
let user = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user).await.unwrap();
let mut calendar = Calendar::new(&user.id, &account.id);

Expand All @@ -73,7 +73,7 @@ mod tests {
let ctx = setup_context().await;
let account = Account::default();
ctx.repos.accounts.insert(&account).await.unwrap();
let user = User::new(account.id.clone());
let user = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user).await.unwrap();
let calendar = Calendar::new(&user.id, &account.id);

Expand Down
2 changes: 1 addition & 1 deletion scheduler/crates/infra/src/repos/calendar_synced/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ mod tests {
.await
.expect("To insert account");

let user = User::new(account.id.clone());
let user = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user).await.expect("To insert user");

for provider in [IntegrationProvider::Google, IntegrationProvider::Outlook] {
Expand Down
10 changes: 5 additions & 5 deletions scheduler/crates/infra/src/repos/event/calendar_event/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ mod tests {
let ctx = setup_context().await;
let account = Account::default();
ctx.repos.accounts.insert(&account).await.unwrap();
let user = User::new(account.id.clone());
let user = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user).await.unwrap();
let calendar = Calendar::new(&user.id, &account.id);
ctx.repos.calendars.insert(&calendar).await.unwrap();
Expand Down Expand Up @@ -431,19 +431,19 @@ mod tests {
ctx.repos.services.insert(&other_service).await.unwrap();

// User 1
let user1 = User::new(account.id.clone());
let user1 = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user1).await.unwrap();
let calendar1 = Calendar::new(&user1.id, &account.id);
ctx.repos.calendars.insert(&calendar1).await.unwrap();

// User 2
let user2 = User::new(account.id.clone());
let user2 = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user2).await.unwrap();
let calendar2 = Calendar::new(&user2.id, &account.id);
ctx.repos.calendars.insert(&calendar2).await.unwrap();

// User 3
let user3 = User::new(account.id.clone());
let user3 = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user3).await.unwrap();
let calendar3 = Calendar::new(&user3.id, &account.id);
ctx.repos.calendars.insert(&calendar3).await.unwrap();
Expand Down Expand Up @@ -546,7 +546,7 @@ mod tests {
ctx.repos.services.insert(&other_service).await.unwrap();

// User 1
let user1 = User::new(account.id.clone());
let user1 = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user1).await.unwrap();
let calendar1 = Calendar::new(&user1.id, &account.id);
ctx.repos.calendars.insert(&calendar1).await.unwrap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ mod tests {
let ctx = setup_context().await;
let account = Account::default();
ctx.repos.accounts.insert(&account).await.unwrap();
let user = User::new(account.id.clone());
let user = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user).await.unwrap();
let calendar = Calendar::new(&user.id, &account.id);
ctx.repos.calendars.insert(&calendar).await.unwrap();
Expand Down
2 changes: 1 addition & 1 deletion scheduler/crates/infra/src/repos/event/event_synced/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ mod tests {
.await
.expect("To insert account");

let user = User::new(account.id.clone());
let user = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user).await.expect("To insert user");

for provider in [IntegrationProvider::Google, IntegrationProvider::Outlook] {
Expand Down
2 changes: 1 addition & 1 deletion scheduler/crates/infra/src/repos/event/reminder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ mod tests {
let ctx = setup_context().await;
let account = Account::default();
ctx.repos.accounts.insert(&account).await.unwrap();
let user = User::new(account.id.clone());
let user = User::new(account.id.clone(), None);
ctx.repos.users.insert(&user).await.unwrap();
let calendar = Calendar::new(&user.id, &account.id);
ctx.repos.calendars.insert(&calendar).await.unwrap();
Expand Down
Loading

0 comments on commit 6951dcb

Please sign in to comment.