diff options
author | Ezekiel Kigbo <ekigbo@gitlab.com> | 2019-04-30 18:56:22 +0200 |
---|---|---|
committer | Ezekiel Kigbo <ekigbo@gitlab.com> | 2019-04-30 18:56:22 +0200 |
commit | 6ffaeecd6c0119bf7c0331efefe6d32de1728f66 (patch) | |
tree | 894350853dcaf222fe80d28f6cb258d3b786ac9f | |
parent | e6f548fcd87a9e724c80980098c9137081b96be4 (diff) | |
download | gitlab-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.vue | 43 | ||||
-rw-r--r-- | spec/javascripts/vue_shared/components/projects_list/project_visibility_level_spec.js | 134 |
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 }); + }); + }); + }); +}); |