summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEzekiel Kigbo <ekigbo@gitlab.com>2019-04-30 18:56:22 +0200
committerEzekiel Kigbo <ekigbo@gitlab.com>2019-04-30 18:56:22 +0200
commit6ffaeecd6c0119bf7c0331efefe6d32de1728f66 (patch)
tree894350853dcaf222fe80d28f6cb258d3b786ac9f
parente6f548fcd87a9e724c80980098c9137081b96be4 (diff)
downloadgitlab-ce-56992-project-visibility-level-component.tar.gz
Added project visibility level component56992-project-visibility-level-component
-rw-r--r--app/assets/javascripts/vue_shared/components/projects_list/project_visibility_level.vue43
-rw-r--r--spec/javascripts/vue_shared/components/projects_list/project_visibility_level_spec.js134
2 files changed, 177 insertions, 0 deletions
diff --git a/app/assets/javascripts/vue_shared/components/projects_list/project_visibility_level.vue b/app/assets/javascripts/vue_shared/components/projects_list/project_visibility_level.vue
new file mode 100644
index 00000000000..c257806df3e
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/projects_list/project_visibility_level.vue
@@ -0,0 +1,43 @@
+<script>
+import { visibilityOptions } from '~/pages/projects/shared/permissions/constants';
+
+export const visibilityIconClass = (level = -1) => {
+ if (level < visibilityOptions.INTERNAL) return 'fa-lock';
+ else if (level < visibilityOptions.PUBLIC) return 'fa-shield';
+ else return 'fa-globe';
+};
+
+export default {
+ props: {
+ level: {
+ // TODO: not sure what to default to, private?
+ type: Number,
+ default: visibilityOptions.PRIVATE,
+ },
+ description: {
+ type: String,
+ default: '',
+ },
+ },
+ computed: {
+ title: function() {
+ return this.$props.description;
+ },
+ iconClass: function() {
+ const { level = null } = this.$props;
+ return `fa ${visibilityIconClass(level)} fa-fw`;
+ },
+ },
+};
+</script>
+<template>
+ <span
+ class="metadata-info visibility-icon append-right-10 prepend-top-8 has-tooltip"
+ data-container="body"
+ data-placement="top"
+ :title="title"
+ >
+ <!-- TODO: should this be SVG? -->
+ <i aria-hidden="true" data-hidden="true" :class="iconClass"></i>
+ </span>
+</template>
diff --git a/spec/javascripts/vue_shared/components/projects_list/project_visibility_level_spec.js b/spec/javascripts/vue_shared/components/projects_list/project_visibility_level_spec.js
new file mode 100644
index 00000000000..b05197eb9b7
--- /dev/null
+++ b/spec/javascripts/vue_shared/components/projects_list/project_visibility_level_spec.js
@@ -0,0 +1,134 @@
+import Vue from 'vue';
+import mountComponent from 'spec/helpers/vue_mount_component_helper';
+import { visibilityOptions } from '~/pages/projects/shared/permissions/constants';
+import ProjectVisibilityLevel, {
+ visibilityIconClass,
+} from '~/vue_shared/components/projects_list/project_visibility_level.vue';
+
+const createComponent = (props, defaultComponent = ProjectVisibilityLevel) => {
+ const Component = Vue.extend(defaultComponent);
+
+ return mountComponent(Component, props);
+};
+
+function expectIconAndDescription(dom, { icon, description }) {
+ expect(dom.$el.querySelector('i').getAttribute('class')).toContain(icon);
+ expect(dom.$el.getAttribute('title')).toBe(description);
+}
+
+let vm = '';
+
+describe('ProjectVisibilityLevel', () => {
+ describe('visibilityIconClass', () => {
+ it(`returns 'fa-lock' for level '${visibilityOptions.PRIVATE}'`, () => {
+ expect(visibilityIconClass(visibilityOptions.PRIVATE)).toBe('fa-lock');
+ });
+
+ it(`returns 'fa-shield' for level '${visibilityOptions.INTERNAL}'`, () => {
+ expect(visibilityIconClass(visibilityOptions.INTERNAL)).toBe('fa-shield');
+ });
+
+ it(`returns 'fa-globe' for level '${visibilityOptions.PUBLIC}'`, () => {
+ expect(visibilityIconClass(visibilityOptions.PUBLIC)).toBe('fa-globe');
+ });
+ });
+
+ describe('computed', () => {});
+
+ describe('template', () => {
+ describe('renders a lock', () => {
+ const privateIcon = 'fa-lock';
+ const privateDescription = 'This is private';
+
+ beforeEach(() => {
+ vm = null;
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it(`with level -1`, () => {
+ vm = createComponent({
+ level: -1,
+ description: privateDescription,
+ });
+ expectIconAndDescription(vm, { icon: privateIcon, description: privateDescription });
+ });
+
+ it(`with level 0`, () => {
+ vm = createComponent({
+ level: 0,
+ description: privateDescription,
+ });
+ expectIconAndDescription(vm, { icon: privateIcon, description: privateDescription });
+ });
+
+ it(`with level 5`, () => {
+ vm = createComponent({
+ level: 5,
+ description: privateDescription,
+ });
+ expectIconAndDescription(vm, { icon: privateIcon, description: privateDescription });
+ });
+ });
+
+ describe('renders a shield', () => {
+ const internalIcon = 'fa-shield';
+ const internalDescription = 'This is internal';
+
+ beforeEach(() => {
+ vm = null;
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it(`with level 10`, () => {
+ vm = createComponent({
+ level: 10,
+ description: internalDescription,
+ });
+ expectIconAndDescription(vm, { icon: internalIcon, description: internalDescription });
+ });
+
+ it(`with level 15`, () => {
+ vm = createComponent({
+ level: 15,
+ description: internalDescription,
+ });
+ expectIconAndDescription(vm, { icon: internalIcon, description: internalDescription });
+ });
+ });
+
+ describe('renders a globe', () => {
+ const publicIcon = 'fa-globe';
+ const publicDescription = 'This is public 🚀⚡️';
+
+ beforeEach(() => {
+ vm = null;
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it(`with level 20`, () => {
+ vm = createComponent({
+ level: 20,
+ description: publicDescription,
+ });
+ expectIconAndDescription(vm, { icon: publicIcon, description: publicDescription });
+ });
+
+ it(`with level 25`, () => {
+ vm = createComponent({
+ level: 25,
+ description: publicDescription,
+ });
+ expectIconAndDescription(vm, { icon: publicIcon, description: publicDescription });
+ });
+ });
+ });
+});