Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BC-5598 - Generalization of image overlay component #2881

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ jobs:
run: npm run test:unit:ci
env:
NODE_OPTIONS: "--unhandled-rejections=warn"
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- name: SonarCloud upload coverage
uses: SonarSource/sonarcloud-github-action@v1.9
uses: SonarSource/sonarcloud-github-action@v2.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONARCLOUD_TOKEN }}
Expand Down
56 changes: 32 additions & 24 deletions src/components/administration/AdminMigrationSection.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
<template>
<div>
<h2 class="text-h4 mb-10">
{{ t("components.administration.adminMigrationSection.headers") }}
</h2>
<div v-if="!isGracePeriodExpired" data-testId="migration-control-section">
<RenderHTML
data-testid="text-description"
Expand All @@ -14,32 +11,36 @@
component="p"
/>
<div v-if="isStartButtonVisible">
<v-alert light prominent text type="info">
<RenderHTML
data-testid="migration-info-text"
:html="
t('components.administration.adminMigrationSection.infoText')
"
component="span"
/>
<v-alert light text type="info">
<div class="alert-text">
<RenderHTML
data-testid="migration-info-text"
:html="
t('components.administration.adminMigrationSection.infoText')
"
component="span"
/>
</div>
</v-alert>
</div>
<div v-else-if="isMigrationActive">
<v-alert light prominent text type="info">
<RenderHTML
data-testid="migration-active-status"
:html="
t(
'components.administration.adminMigrationSection.migrationActive'
)
"
component="span"
/>
<v-alert light text type="info">
<div class="alert-text">
<RenderHTML
data-testid="migration-active-status"
:html="
t(
'components.administration.adminMigrationSection.migrationActive'
)
"
component="span"
/>
</div>
</v-alert>
</div>
<v-btn
v-if="isStartButtonVisible"
class="my-5 button-start"
class="my-4 button-start"
color="primary"
depressed
:disabled="!officialSchoolNumber"
Expand All @@ -54,7 +55,7 @@
</v-btn>
<v-btn
v-if="isEndButtonVisible"
class="my-5 button-end"
class="my-4 button-end"
color="primary"
depressed
:disabled="!oauthMigration.startedAt"
Expand Down Expand Up @@ -161,7 +162,7 @@

<script lang="ts">
import { MigrationBody } from "@/serverApi/v3";
import { OauthMigration, School } from "@/store/types/schools";
import { School } from "@/store/types/schools";
import {
ENV_CONFIG_MODULE_KEY,
injectStrict,
Expand Down Expand Up @@ -364,3 +365,10 @@ export default defineComponent({
},
});
</script>

<style lang="scss" scoped>
.alert-text {
color: var(--v-black-base) !important;
line-height: var(--line-height-lg) !important;
}
</style>
40 changes: 19 additions & 21 deletions src/components/administration/ExternalToolSection.unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,26 +82,6 @@ describe("ExternalToolSection", () => {
});
});

describe("headers is called", () => {
describe("when table is rendered", () => {
it("should display dataTableHeaders in v-data-table", () => {
const { wrapper } = setup();

const vueWrapperArray = wrapper
.find(".v-data-table-header")
.findAll("th");

expect(vueWrapperArray.at(0).find("span").text()).toEqual(
"common.labels.name"
);
expect(vueWrapperArray.at(1).find("span").text()).toEqual(
"components.administration.externalToolsSection.table.header.status"
);
expect(vueWrapperArray.at(2).find("span").text()).toEqual("");
});
});
});

describe("items is called", () => {
const setupItems = () => {
const firstToolName = "Test";
Expand Down Expand Up @@ -136,6 +116,24 @@ describe("ExternalToolSection", () => {
};
};

describe("when table is rendered", () => {
it("should display dataTableHeaders in v-data-table", () => {
const { wrapper } = setupItems();

const vueWrapperArray = wrapper
.find(".v-data-table-header")
.findAll("th");

expect(vueWrapperArray.at(0).find("span").text()).toEqual(
"common.labels.name"
);
expect(vueWrapperArray.at(1).find("span").text()).toEqual(
"components.administration.externalToolsSection.table.header.status"
);
expect(vueWrapperArray.at(2).find("span").text()).toEqual("");
});
});

describe("when external tools were loaded", () => {
it("names should be rendered in the datatable", () => {
const { wrapper, firstToolName, secondToolName } = setupItems();
Expand Down Expand Up @@ -209,7 +207,7 @@ describe("ExternalToolSection", () => {

await deleteButton.trigger("click");

expect(wrapper.find("p").text()).toContain(firstToolName);
expect(wrapper.findAll("p").at(1).text()).toContain(firstToolName);
});
});

Expand Down
9 changes: 5 additions & 4 deletions src/components/administration/ExternalToolSection.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<template>
<div>
<h2 class="text-h4 mb-10">
{{ t("components.administration.externalToolsSection.header") }}
</h2>
<p class="mb-6">
{{ t("components.administration.externalToolsSection.info") }}
</p>
<v-data-table
v-if="items.length"
:disable-pagination="true"
:hide-default-footer="true"
:items="items"
Expand Down Expand Up @@ -36,7 +37,7 @@
</template>
</v-data-table>
<v-btn
class="my-5 button-save"
class="mt-8 mb-4 button-save float-right"
color="primary"
depressed
:to="{ name: 'administration-tool-config-overview' }"
Expand Down
22 changes: 22 additions & 0 deletions src/components/data-group/GroupApi.composable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { $axios } from "@/utils/api";
import { GroupApiFactory, GroupResponse } from "@/serverApi/v3";
import { AxiosResponse } from "axios";
import { GroupMapper } from "./GroupMapper";
import { Group } from "@data-group";

export const useGroupApi = () => {
const groupApi = GroupApiFactory(undefined, "/v3", $axios);

const getGroup = async (groupId: string): Promise<Group> => {
const response: AxiosResponse<GroupResponse> =
await groupApi.groupControllerGetGroup(groupId);

const group: Group = GroupMapper.mapToGroup(response.data);

return group;
};

return {
getGroup,
};
};
64 changes: 64 additions & 0 deletions src/components/data-group/GroupApi.composable.unit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import * as serverApi from "@/serverApi/v3/api";
import { GroupResponse } from "@/serverApi/v3/api";
import { mockApiResponse } from "@@/tests/test-utils";
import { createMock, DeepMocked } from "@golevelup/ts-jest";
import { groupResponseFactory } from "@@/tests/test-utils/factory/groupResponseFactory";
import { Group, GroupType, GroupUserRole, useGroupApi } from "@data-group";

describe("GroupApi.composable", () => {
let groupApi: DeepMocked<serverApi.GroupApiInterface>;

beforeEach(() => {
groupApi = createMock<serverApi.GroupApiInterface>();

jest.spyOn(serverApi, "GroupApiFactory").mockReturnValue(groupApi);
});

afterEach(() => {
jest.clearAllMocks();
});

describe("getGroup", () => {
const setup = () => {
const group: GroupResponse = groupResponseFactory.build();

groupApi.groupControllerGetGroup.mockResolvedValue(
mockApiResponse({ data: group })
);

return {
group,
};
};

it("should call the api for groups", async () => {
setup();

await useGroupApi().getGroup("groupId");

expect(groupApi.groupControllerGetGroup).toHaveBeenCalledWith("groupId");
});

it("should return a group", async () => {
const { group } = setup();

const result: Group = await useGroupApi().getGroup("groupId");

expect(result).toEqual<Group>({
id: group.id,
name: group.name,
type: GroupType.Class,
organizationId: group.organizationId,
users: [
{
id: group.users[0].id,
firstName: group.users[0].firstName,
lastName: group.users[0].lastName,
role: GroupUserRole.Student,
},
],
externalSource: group.externalSource,
});
});
});
});
62 changes: 62 additions & 0 deletions src/components/data-group/GroupMapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {
GroupResponse,
GroupResponseTypeEnum,
GroupUserResponse,
GroupUserResponseRoleEnum,
} from "@/serverApi/v3";
import { Group, GroupType, GroupUser, GroupUserRole } from "./types";

export const GroupTypeMapping: Record<GroupResponseTypeEnum, GroupType> = {
[GroupResponseTypeEnum.Class]: GroupType.Class,
};

export const GroupUserRoleMapping: Partial<
Record<GroupUserResponseRoleEnum, GroupUserRole>
> = {
[GroupUserResponseRoleEnum.Administrator]: GroupUserRole.Administrator,
[GroupUserResponseRoleEnum.Student]: GroupUserRole.Student,
[GroupUserResponseRoleEnum.Teacher]: GroupUserRole.Teacher,
};

export const GroupUserRoleNameTranslationMapping: Record<
GroupUserRole,
string
> = {
[GroupUserRole.Administrator]: "common.roleName.administrator",
[GroupUserRole.Student]: "common.roleName.student",
[GroupUserRole.Teacher]: "common.roleName.teacher",
[GroupUserRole.Unknown]: "common.labels.unknown",
};

export class GroupMapper {
static mapToGroup(groupResponse: GroupResponse): Group {
return {
id: groupResponse.id,
name: groupResponse.name,
type: GroupTypeMapping[groupResponse.type],
users: groupResponse.users.map((user) =>
GroupMapper.mapToGroupUser(user)
),
externalSource: groupResponse.externalSource,
organizationId: groupResponse.organizationId,
};
}

private static mapToGroupUser(
groupUserResponse: GroupUserResponse
): GroupUser {
return {
id: groupUserResponse.id,
firstName: groupUserResponse.firstName,
lastName: groupUserResponse.lastName,
role:
GroupUserRoleMapping[groupUserResponse.role] ?? GroupUserRole.Unknown,
};
}

static getTranslationKey(role: GroupUserRole): string {
const translationKey: string = GroupUserRoleNameTranslationMapping[role];

return translationKey;
}
}
34 changes: 34 additions & 0 deletions src/components/data-group/GroupState.composable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useErrorHandler } from "@/components/error-handling/ErrorHandler.composable";
import { ref, Ref } from "vue";
import { Group, useGroupApi } from "@data-group";

export const useGroupState = () => {
const { handleError } = useErrorHandler();
const { getGroup } = useGroupApi();

const isLoading: Ref<boolean> = ref(false);
const group: Ref<Group | undefined> = ref();

const fetchGroup = async (groupId: string): Promise<void> => {
isLoading.value = true;

try {
const fetchedGroup: Group = await getGroup(groupId);
group.value = fetchedGroup;
} catch (error) {
// TODO: fix this
handleError(error, {
404: undefined,
500: undefined,
});
}

isLoading.value = false;
};

return {
isLoading,
group,
fetchGroup,
};
};
Loading