feat: v2 managed user create default schedule given timeZone (#14727)

* schedules service: function to create default user schedule

* managed user: create default schedule if timeZone provided

* swagger update
This commit is contained in:
Lauris Skraucis authored and GitHub committed 2024-04-26 09:20:29 +00:00
1 parent 5d76bd6b9c
commit d004815a68
5 files changed
+277 -240

No files matched your search

@@ -24,6 +24,16 @@ export class SchedulesService {
private readonly usersRepository: UsersRepository
) {}
async createUserDefaultSchedule(userId: number, timeZone: string) {
const schedule = {
isDefault: true,
name: "Default schedule",
timeZone,
};
return this.createUserSchedule(userId, schedule);
}
async createUserSchedule(userId: number, schedule: CreateScheduleInput) {
const availabilities = schedule.availabilities?.length
? schedule.availabilities
@@ -17,6 +17,7 @@ import { PlatformOAuthClient, Team, User } from "@prisma/client";
import * as request from "supertest";
import { EventTypesRepositoryFixture } from "test/fixtures/repository/event-types.repository.fixture";
import { OAuthClientRepositoryFixture } from "test/fixtures/repository/oauth-client.repository.fixture";
import { SchedulesRepositoryFixture } from "test/fixtures/repository/schedules.repository.fixture";
import { TeamRepositoryFixture } from "test/fixtures/repository/team.repository.fixture";
import { UserRepositoryFixture } from "test/fixtures/repository/users.repository.fixture";
@@ -75,10 +76,12 @@ describe("OAuth Client Users Endpoints", () => {
let oauthClientRepositoryFixture: OAuthClientRepositoryFixture;
let teamRepositoryFixture: TeamRepositoryFixture;
let eventTypesRepositoryFixture: EventTypesRepositoryFixture;
let schedulesRepositoryFixture: SchedulesRepositoryFixture;
let postResponseData: CreateUserResponse;
const userEmail = "oauth-client-user@gmail.com";
const userTimeZone = "Europe/Rome";
beforeAll(async () => {
const moduleRef = await Test.createTestingModule({
@@ -93,6 +96,7 @@ describe("OAuth Client Users Endpoints", () => {
userRepositoryFixture = new UserRepositoryFixture(moduleRef);
teamRepositoryFixture = new TeamRepositoryFixture(moduleRef);
eventTypesRepositoryFixture = new EventTypesRepositoryFixture(moduleRef);
schedulesRepositoryFixture = new SchedulesRepositoryFixture(moduleRef);
organization = await teamRepositoryFixture.create({ name: "organization" });
oAuthClient = await createOAuthClient(organization.id);
@@ -134,6 +138,7 @@ describe("OAuth Client Users Endpoints", () => {
it(`/POST`, async () => {
const requestBody: CreateManagedUserInput = {
email: userEmail,
timeZone: userTimeZone,
};
const response = await request(app.getHttpServer())
@@ -158,6 +163,7 @@ describe("OAuth Client Users Endpoints", () => {
await userConnectedToOAuth(responseBody.data.user.email);
await userHasDefaultEventTypes(responseBody.data.user.id);
await userHasDefaultSchedule(responseBody.data.user.id, responseBody.data.user.defaultScheduleId);
});
async function userConnectedToOAuth(userEmail: string) {
@@ -181,6 +187,17 @@ describe("OAuth Client Users Endpoints", () => {
).toBeTruthy();
}
async function userHasDefaultSchedule(userId: number, scheduleId: number | null) {
expect(scheduleId).toBeDefined();
expect(scheduleId).not.toBeNull();
const user = await userRepositoryFixture.get(userId);
expect(user?.defaultScheduleId).toEqual(scheduleId);
const schedule = scheduleId ? await schedulesRepositoryFixture.getById(scheduleId) : null;
expect(schedule?.userId).toEqual(userId);
}
it(`/GET: return list of managed users`, async () => {
const response = await request(app.getHttpServer())
.get(`/api/v2/oauth-clients/${oAuthClient.id}/users?limit=10&offset=0`)
@@ -1,4 +1,5 @@
import { EventTypesModule } from "@/ee/event-types/event-types.module";
import { SchedulesModule } from "@/ee/schedules/schedules.module";
import { AuthModule } from "@/modules/auth/auth.module";
import { MembershipsModule } from "@/modules/memberships/memberships.module";
import { OAuthClientUsersController } from "@/modules/oauth-clients/controllers/oauth-client-users/oauth-client-users.controller";
@@ -25,6 +26,7 @@ import { Global, Module } from "@nestjs/common";
MembershipsModule,
EventTypesModule,
OrganizationsModule,
SchedulesModule,
],
providers: [
OAuthClientRepository,
@@ -1,4 +1,5 @@
import { EventTypesService } from "@/ee/event-types/services/event-types.service";
import { SchedulesService } from "@/ee/schedules/services/schedules.service";
import { TokensRepository } from "@/modules/tokens/tokens.repository";
import { CreateManagedUserInput } from "@/modules/users/inputs/create-managed-user.input";
import { UpdateManagedUserInput } from "@/modules/users/inputs/update-managed-user.input";
@@ -14,7 +15,8 @@ export class OAuthClientUsersService {
constructor(
private readonly userRepository: UsersRepository,
private readonly tokensRepository: TokensRepository,
private readonly eventTypesService: EventTypesService
private readonly eventTypesService: EventTypesService,
private readonly schedulesService: SchedulesService
) {}
async createOauthClientUser(
@@ -62,8 +64,14 @@ export class OAuthClientUsersService {
oAuthClientId,
user.id
);
await this.eventTypesService.createUserDefaultEventTypes(user.id);
if (body.timeZone) {
const defaultSchedule = await this.schedulesService.createUserDefaultSchedule(user.id, body.timeZone);
user.defaultScheduleId = defaultSchedule.id;
}
return {
user,
tokens: {
+239 -239
View File
@@ -773,155 +773,6 @@
]
}
},
"/v2/gcal/oauth/auth-url": {
"get": {
"operationId": "GcalController_redirect",
"parameters": [
{
"name": "Authorization",
"required": true,
"in": "header",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GcalAuthUrlOutput"
}
}
}
}
},
"tags": [
"Google Calendar"
]
}
},
"/v2/gcal/oauth/save": {
"get": {
"operationId": "GcalController_save",
"parameters": [
{
"name": "state",
"required": true,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "code",
"required": true,
"in": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GcalSaveRedirectOutput"
}
}
}
}
},
"tags": [
"Google Calendar"
]
}
},
"/v2/gcal/check": {
"get": {
"operationId": "GcalController_check",
"parameters": [],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GcalCheckOutput"
}
}
}
}
},
"tags": [
"Google Calendar"
]
}
},
"/v2/provider/{clientId}": {
"get": {
"operationId": "CalProviderController_verifyClientId",
"parameters": [
{
"name": "clientId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProviderVerifyClientOutput"
}
}
}
}
},
"tags": [
"Cal provider"
]
}
},
"/v2/provider/{clientId}/access-token": {
"get": {
"operationId": "CalProviderController_verifyAccessToken",
"parameters": [
{
"name": "clientId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProviderVerifyAccessTokenOutput"
}
}
}
}
},
"tags": [
"Cal provider"
]
}
},
"/v2/schedules": {
"post": {
"operationId": "SchedulesController_createSchedule",
@@ -1089,6 +940,155 @@
]
}
},
"/v2/gcal/oauth/auth-url": {
"get": {
"operationId": "GcalController_redirect",
"parameters": [
{
"name": "Authorization",
"required": true,
"in": "header",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GcalAuthUrlOutput"
}
}
}
}
},
"tags": [
"Google Calendar"
]
}
},
"/v2/gcal/oauth/save": {
"get": {
"operationId": "GcalController_save",
"parameters": [
{
"name": "state",
"required": true,
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "code",
"required": true,
"in": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GcalSaveRedirectOutput"
}
}
}
}
},
"tags": [
"Google Calendar"
]
}
},
"/v2/gcal/check": {
"get": {
"operationId": "GcalController_check",
"parameters": [],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GcalCheckOutput"
}
}
}
}
},
"tags": [
"Google Calendar"
]
}
},
"/v2/provider/{clientId}": {
"get": {
"operationId": "CalProviderController_verifyClientId",
"parameters": [
{
"name": "clientId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProviderVerifyClientOutput"
}
}
}
}
},
"tags": [
"Cal provider"
]
}
},
"/v2/provider/{clientId}/access-token": {
"get": {
"operationId": "CalProviderController_verifyAccessToken",
"parameters": [
{
"name": "clientId",
"required": true,
"in": "path",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProviderVerifyAccessTokenOutput"
}
}
}
}
},
"tags": [
"Cal provider"
]
}
},
"/v2/me": {
"get": {
"operationId": "MeController_getMe",
@@ -2788,96 +2788,6 @@
"data"
]
},
"AuthUrlData": {
"type": "object",
"properties": {
"authUrl": {
"type": "string"
}
},
"required": [
"authUrl"
]
},
"GcalAuthUrlOutput": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": [
"success",
"error"
]
},
"data": {
"$ref": "#/components/schemas/AuthUrlData"
}
},
"required": [
"status",
"data"
]
},
"GcalSaveRedirectOutput": {
"type": "object",
"properties": {
"url": {
"type": "string"
}
},
"required": [
"url"
]
},
"GcalCheckOutput": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": [
"success",
"error"
]
}
},
"required": [
"status"
]
},
"ProviderVerifyClientOutput": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": [
"success",
"error"
]
}
},
"required": [
"status"
]
},
"ProviderVerifyAccessTokenOutput": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": [
"success",
"error"
]
}
},
"required": [
"status"
]
},
"CreateAvailabilityInput": {
"type": "object",
"properties": {
@@ -3347,6 +3257,96 @@
"status"
]
},
"AuthUrlData": {
"type": "object",
"properties": {
"authUrl": {
"type": "string"
}
},
"required": [
"authUrl"
]
},
"GcalAuthUrlOutput": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": [
"success",
"error"
]
},
"data": {
"$ref": "#/components/schemas/AuthUrlData"
}
},
"required": [
"status",
"data"
]
},
"GcalSaveRedirectOutput": {
"type": "object",
"properties": {
"url": {
"type": "string"
}
},
"required": [
"url"
]
},
"GcalCheckOutput": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": [
"success",
"error"
]
}
},
"required": [
"status"
]
},
"ProviderVerifyClientOutput": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": [
"success",
"error"
]
}
},
"required": [
"status"
]
},
"ProviderVerifyAccessTokenOutput": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": [
"success",
"error"
]
}
},
"required": [
"status"
]
},
"MeOutput": {
"type": "object",
"properties": {