Commit ee3cf5d6 authored by Filipa Lacerda's avatar Filipa Lacerda

[ci skip] Adds tests to vuex and collapsibe component

Formats dates
Fixes clipboard button
Simplifies HTML
parent 6c63520e
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
'fetchList', 'fetchList',
'deleteRepo', 'deleteRepo',
'deleteRegistry', 'deleteRegistry',
'toggleIsLoading', 'toggleLoading',
]), ]),
fetchRegistryList(repo) { fetchRegistryList(repo) {
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
deleteRepository(repo) { deleteRepository(repo) {
this.deleteRepo(repo) this.deleteRepo(repo)
.then(() => this.fetchRepo()) .then(() => this.fetchRepos())
.catch(() => this.showError(errorMessagesTypes.DELETE_REPO)); .catch(() => this.showError(errorMessagesTypes.DELETE_REPO));
}, },
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
import clipboardButton from '../../vue_shared/components/clipboard_button.vue'; import clipboardButton from '../../vue_shared/components/clipboard_button.vue';
import loadingIcon from '../../vue_shared/components/loading_icon.vue'; import loadingIcon from '../../vue_shared/components/loading_icon.vue';
import tooltip from '../../vue_shared/directives/tooltip'; import tooltip from '../../vue_shared/directives/tooltip';
import timeagoMixin from '../../vue_shared/mixins/timeago';
export default { export default {
name: 'collapsibeContainerRegisty', name: 'collapsibeContainerRegisty',
...@@ -15,6 +16,9 @@ ...@@ -15,6 +16,9 @@
clipboardButton, clipboardButton,
loadingIcon, loadingIcon,
}, },
mixins: [
timeagoMixin,
],
directives: { directives: {
tooltip, tooltip,
}, },
...@@ -28,16 +32,18 @@ ...@@ -28,16 +32,18 @@
const pluralize = gl.text.pluralize('layer', item.layers); const pluralize = gl.text.pluralize('layer', item.layers);
return `${item.layers} ${pluralize}`; return `${item.layers} ${pluralize}`;
}, },
toggleRepo() { toggleRepo() {
if (this.isOpen === false) { if (this.isOpen === false) {
// consider not fetching data the second time it is toggled? :fry:
this.$emit('fetchRegistryList', this.repo); this.$emit('fetchRegistryList', this.repo);
} }
this.isOpen = !this.isOpen; this.isOpen = !this.isOpen;
}, },
handleDeleteRepository() { handleDeleteRepository() {
this.$emit('deleteRepository', this.repo) this.$emit('deleteRepository', this.repo)
}, },
handleDeleteRegistry(registry) { handleDeleteRegistry(registry) {
this.$emit('deleteRegistry', this.repo, registry); this.$emit('deleteRegistry', this.repo, registry);
}, },
...@@ -51,7 +57,8 @@ ...@@ -51,7 +57,8 @@
class="container-image-head"> class="container-image-head">
<a <a
role="button" role="button"
@click="toggleRepo"> @click="toggleRepo"
class="js-toggle-repo">
<i <i
class="fa" class="fa"
:class="{ :class="{
...@@ -63,13 +70,17 @@ ...@@ -63,13 +70,17 @@
{{repo.name}} {{repo.name}}
</a> </a>
<clipboard-button text="foo" title="bar" /> <clipboard-button
v-if="repo.location"
:text="__(`docker pull ${repo.location}`)"
:title="repo.location"
/>
<div class="controls hidden-xs pull-right"> <div class="controls hidden-xs pull-right">
<button <button
v-if="repo.canDelete" v-if="repo.canDelete"
type="button" type="button"
class="btn btn-remove" class="js-remove-repo btn btn-remove"
:title="__('Remove repository')" :title="__('Remove repository')"
v-tooltip v-tooltip
@click="handleDeleteRepository"> @click="handleDeleteRepository">
...@@ -90,14 +101,16 @@ ...@@ -90,14 +101,16 @@
v-else-if="!repo.isLoading && isOpen" v-else-if="!repo.isLoading && isOpen"
class="container-image-tags"> class="container-image-tags">
<table class="table tags" v-if="repo.list.length"> <table
class="table tags"
v-if="repo.list.length">
<thead> <thead>
<tr> <tr>
<th>{{__("Tag")}}</th> <th>{{__("Tag")}}</th>
<th>{{__("Tag ID")}}</th> <th>{{__("Tag ID")}}</th>
<th>{{__("Size")}}</th> <th>{{__("Size")}}</th>
<th>{{__("Created")}}</th> <th>{{__("Created")}}</th>
<th v-if="true"></th> <th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
...@@ -109,16 +122,16 @@ ...@@ -109,16 +122,16 @@
{{item.tag}} {{item.tag}}
<clipboard-button <clipboard-button
:title="item.tag" v-if="item.location"
:text="item.tag" :title="item.location"
:text="__(`docker pull ${item.location}`)"
/> />
</td> </td>
<td> <td>
<span <span
v-tooltip v-tooltip
:title="item.revision" :title="item.revision"
data-placement="bottom" data-placement="bottom">
>
{{item.shortRevision}} {{item.shortRevision}}
</span> </span>
</td> </td>
...@@ -128,34 +141,38 @@ ...@@ -128,34 +141,38 @@
&middot; &middot;
{{layers(item)}} {{layers(item)}}
</template> </template>
<div v-else class="light"> <div
v-else
class="light">
\- \-
</div> </div>
</td> </td>
<td> <td>
<template v-if="item.createdAt"> <template v-if="item.createdAt">
format {{item.createdAt}} {{timeFormated(item.createdAt)}}
</template> </template>
<div v-else class="light"> <div
v-else
class="light">
\- \-
</div> </div>
</td> </td>
<td class="content"> <td class="content">
<div class="controls hidden-xs pull-right"> <button
<button v-if="item.canDelete"
type="button" type="button"
class="btn btn-remove" class="js-delete-registry btn btn-remove hidden-xs pull-right"
title="Remove tag" :title="__('Remove tag')"
v-tooltip data-container="body"
@click="handleDeleteRegistry(item)"> v-tooltip
<i @click="handleDeleteRegistry(item)">
class="fa fa-trash" <i
aria-hidden="true"> class="fa fa-trash"
</i> aria-hidden="true">
</button> </i>
</div> </button>
</td> </td>
</tr> </tr>
</tbody> </tbody>
......
import Vue from 'vue'; import Vue from 'vue';
import Translate from '../vue_shared/translate';
import registryApp from './components/app.vue'; import registryApp from './components/app.vue';
// Vue.use(Translate);
document.addEventListener('DOMContentLoaded', () => new Vue({ document.addEventListener('DOMContentLoaded', () => new Vue({
el: '#js-vue-registry-images', el: '#js-vue-registry-images',
components: { components: {
......
...@@ -27,16 +27,10 @@ export const fetchList = ({ commit }, list) => { ...@@ -27,16 +27,10 @@ export const fetchList = ({ commit }, list) => {
}; };
export const deleteRepo = ({ commit }, repo) => Vue.http.delete(repo.path) export const deleteRepo = ({ commit }, repo) => Vue.http.delete(repo.path)
.then(res => res.json()) .then(res => res.json());
.then(() => {
commit(types.DELETE_REPO, repo);
});
export const deleteRegistry = ({ commit }, image) => Vue.http.delete(image.path) export const deleteRegistry = ({ commit }, image) => Vue.http.delete(image.path)
.then(res => res.json()) .then(res => res.json());
.then(() => {
commit(types.DELETE_IMAGE, image);
});
export const setMainEndpoint = ({ commit }, data) => commit(types.SET_MAIN_ENDPOINT, data); export const setMainEndpoint = ({ commit }, data) => commit(types.SET_MAIN_ENDPOINT, data);
export const toggleIsLoading = ({ commit }) => commit(types.TOGGLE_MAIN_LOADING); export const toggleLoading = ({ commit }) => commit(types.TOGGLE_MAIN_LOADING);
export const isLoading = state => state.isLoading; export const isLoading = state => state.isLoading;
export const repos = state => state.repos; export const repos = state => state.repos;
\ No newline at end of file
export const SET_MAIN_ENDPOINT = 'SET_MAIN_ENDPOINT'; export const SET_MAIN_ENDPOINT = 'SET_MAIN_ENDPOINT';
export const FETCH_REPOS_LIST = 'FETCH_REPOS_LIST';
export const DELETE_REPO = 'DELETE_REPO';
export const SET_REPOS_LIST = 'SET_REPOS_LIST'; export const SET_REPOS_LIST = 'SET_REPOS_LIST';
export const TOGGLE_MAIN_LOADING = 'TOGGLE_MAIN_LOADING'; export const TOGGLE_MAIN_LOADING = 'TOGGLE_MAIN_LOADING';
export const FETCH_IMAGES_LIST = 'FETCH_IMAGES_LIST';
export const SET_REGISTRY_LIST = 'SET_REGISTRY_LIST'; export const SET_REGISTRY_LIST = 'SET_REGISTRY_LIST';
export const DELETE_IMAGE = 'DELETE_IMAGE';
export const TOGGLE_REGISTRY_LIST_LOADING = 'TOGGLE_REGISTRY_LIST_LOADING'; export const TOGGLE_REGISTRY_LIST_LOADING = 'TOGGLE_REGISTRY_LIST_LOADING';
...@@ -11,12 +11,12 @@ export default { ...@@ -11,12 +11,12 @@ export default {
repos: list.map(el => ({ repos: list.map(el => ({
canDelete: !!el.destroy_path, canDelete: !!el.destroy_path,
destroyPath: el.destroy_path, destroyPath: el.destroy_path,
id: el.id,
isLoading: false, isLoading: false,
list: [], list: [],
location: el.location, location: el.location,
name: el.name, name: el.name,
tagsPath: el.tags_path, tagsPath: el.tags_path,
id: el.id,
})), })),
}); });
}, },
...@@ -26,26 +26,6 @@ export default { ...@@ -26,26 +26,6 @@ export default {
}, },
[types.SET_REGISTRY_LIST](state, repo, list) { [types.SET_REGISTRY_LIST](state, repo, list) {
// mock
list = [
{
name: 'centos6',
short_revision: '0b6091a66',
revision: '0b6091a665af68bbbbb36a3e088ec3cd6f35389deebf6d4617042d56722d76fb',
size: 706,
layers: 19,
created_at: 1505828744434,
},
{
name: 'centos7',
short_revision: 'b118ab5b0',
revision: 'b118ab5b0e90b7cb5127db31d5321ac14961d097516a8e0e72084b6cdc783b43',
size: 679,
layers: 19,
created_at: 1505828744434,
},
];
const listToUpdate = state.repos.find(el => el.id === repo.id); const listToUpdate = state.repos.find(el => el.id === repo.id);
listToUpdate.list = list.map(element => ({ listToUpdate.list = list.map(element => ({
...@@ -54,6 +34,7 @@ export default { ...@@ -54,6 +34,7 @@ export default {
shortRevision: element.short_revision, shortRevision: element.short_revision,
size: element.size, size: element.size,
layers: element.layers, layers: element.layers,
location: element.location,
createdAt: element.created_at, createdAt: element.created_at,
destroyPath: element.destroy_path, destroyPath: element.destroy_path,
canDelete: !!element.destroy_path, canDelete: !!element.destroy_path,
......
<script> <script>
import Clipboard from 'vendor/clipboard'; /**
* Falls back to the code used in `copy_to_clipboard.js`
*/
export default { export default {
name: 'clipboardButton', name: 'clipboardButton',
...@@ -13,13 +15,6 @@ ...@@ -13,13 +15,6 @@
required: true, required: true,
}, },
}, },
mounted() {
// return new Clipboard(this.$refs.btn, {
// text: () => {
// return this.text;
// },
// });
}
}; };
</script> </script>
...@@ -28,9 +23,7 @@ ...@@ -28,9 +23,7 @@
type="button" type="button"
class="btn btn-transparent btn-clipboard" class="btn btn-transparent btn-clipboard"
:data-title="title" :data-title="title"
:data-clipboard-text="text" :data-clipboard-text="text">
ref="btn"
>
<i <i
aria-hidden="true" aria-hidden="true"
class="fa fa-clipboard"> class="fa fa-clipboard">
......
...@@ -9,10 +9,6 @@ ...@@ -9,10 +9,6 @@
.container-image-head { .container-image-head {
padding: 0 16px; padding: 0 16px;
line-height: 4em; line-height: 4em;
&:hover {
text-decoration: underline;
}
} }
.table.tags { .table.tags {
......
...@@ -10,7 +10,7 @@ module Projects ...@@ -10,7 +10,7 @@ module Projects
respond_to do |format| respond_to do |format|
format.html format.html
format.json do format.json do
# render json: @images # Remove code below
render json: [ render json: [
{ {
name: 'gitlab-org/omnibus-gitlab/foo', name: 'gitlab-org/omnibus-gitlab/foo',
...@@ -41,13 +41,27 @@ module Projects ...@@ -41,13 +41,27 @@ module Projects
def destroy def destroy
if image.destroy if image.destroy
redirect_to project_container_registry_index_path(@project), respond_to do |format|
status: 302, # TODO: @Kamil, I don't think this is used ever. Should we keep it or remove it?
notice: 'Image repository has been removed successfully!' format.html do
redirect_to project_container_registry_index_path(@project),
status: 302,
notice: 'Image repository has been removed successfully!'
end
format.json { head :no_content }
end
else else
redirect_to project_container_registry_index_path(@project), respond_to do |format|
status: 302, # TODO: @Kamil, I don't think this is used ever. Should we keep it or remove it?
alert: 'Failed to remove image repository!' format.html do
redirect_to project_container_registry_index_path(@project),
status: 302,
alert: 'Failed to remove image repository!'
end
format.json { head :no_content }
end
end end
end end
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
= _('With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images.') = _('With the Docker Container Registry integrated into GitLab, every project can have its own space to store its Docker images.')
%p.append-bottom-0 %p.append-bottom-0
= succeed '.' do = succeed '.' do
Learn more about = _('Learn more about')
= link_to _('Container Registry'), help_page_path('user/project/container_registry'), target: '_blank' = link_to _('Container Registry'), help_page_path('user/project/container_registry'), target: '_blank'
.row .row
.col-lg-12 .col-lg-12
...@@ -20,14 +20,14 @@ ...@@ -20,14 +20,14 @@
%p %p
= _('First log in to GitLab&rsquo;s Container Registry using your GitLab username and password. If you have') = _('First log in to GitLab&rsquo;s Container Registry using your GitLab username and password. If you have')
= link_to _('2FA enabled'), help_page_path('user/profile/account/two_factor_authentication'), target: '_blank' = link_to _('2FA enabled'), help_page_path('user/profile/account/two_factor_authentication'), target: '_blank'
you need to use a = _('you need to use a')
= succeed ':' do = succeed ':' do
= link_to _('personal access token'), help_page_path('user/profile/account/two_factor_authentication', anchor: 'personal-access-tokens'), target: '_blank' = link_to _('personal access token'), help_page_path('user/profile/account/two_factor_authentication', anchor: 'personal-access-tokens'), target: '_blank'
%pre %pre
docker login #{Gitlab.config.registry.host_port} docker login #{Gitlab.config.registry.host_port}
%br %br
%p %p
= _("Once you log in, you&rsquo;re free to create and upload a container image using the common") = _('Once you log in, you&rsquo;re free to create and upload a container image using the common')
%code %code
= _('build') = _('build')
= _('and') = _('and')
...@@ -37,7 +37,6 @@ ...@@ -37,7 +37,6 @@
:plain :plain
docker build -t #{escape_once(@project.container_registry_url)} . docker build -t #{escape_once(@project.container_registry_url)} .
docker push #{escape_once(@project.container_registry_url)} docker push #{escape_once(@project.container_registry_url)}
%hr %hr
%h5.prepend-top-default %h5.prepend-top-default
= _('Use different image names') = _('Use different image names')
...@@ -48,8 +47,6 @@ ...@@ -48,8 +47,6 @@
#{escape_once(@project.container_registry_url)}:tag #{escape_once(@project.container_registry_url)}:tag
#{escape_once(@project.container_registry_url)}/optional-image-name:tag #{escape_once(@project.container_registry_url)}/optional-image-name:tag
#{escape_once(@project.container_registry_url)}/optional-name/optional-image-name:tag #{escape_once(@project.container_registry_url)}/optional-name/optional-image-name:tag
.row .row
.col-lg-12 .col-lg-12
#js-vue-registry-images{ data: { endpoint: project_container_registry_index_path(@project, format: :json)}} #js-vue-registry-images{ data: { endpoint: project_container_registry_index_path(@project, format: :json)}}
......
import * as actions from '~/notes/stores/actions'; import * as actions from '~/notes/stores/actions';
import testAction from './helpers'; import testAction from '../../helpers/vuex_action_helper';
import { discussionMock, notesDataMock, userDataMock, issueDataMock, individualNote } from '../mock_data'; import { discussionMock, notesDataMock, userDataMock, issueDataMock, individualNote } from '../mock_data';
describe('Actions Notes Store', () => { describe('Actions Notes Store', () => {
......
import Vue from 'vue';
import collapsibleComponent from '~/registry/components/collapsible_container.vue';
import mountComponent from '../../helpers/vue_mount_component_helper';
describe('collapsible registry container', () => {
let vm;
let Component;
let mockData;
beforeEach(() => {
Component = Vue.extend(collapsibleComponent);
mockData = {
canDelete: true,
destroyPath: 'path',
id: '123',
isLoading: false,
list: [
{
tag: 'centos6',
revision: 'b118ab5b0e90b7cb5127db31d5321ac14961d097516a8e0e72084b6cdc783b43',
shortRevision: 'b118ab5b0',
size: 19,
layers: 10,
location: 'location',
createdAt: 1505828744434,
destroyPath: 'path',
canDelete: true,
},
],
location: 'location',
name: 'foo',
tagsPath: 'path',
};
vm = mountComponent(Component, { repo: mockData });
});
afterEach(() => {
vm.$destroy();
});
describe('toggle', () => {
it('should be closed by default', () => {
expect(vm.$el.querySelector('.container-image-tags')).toBe(null);
expect(vm.$el.querySelector('.container-image-head i').className).toEqual('fa fa-chevron-right');
});
it('should be open when user clicks on closed repo', (done) => {
vm.$el.querySelector('.js-toggle-repo').click();
Vue.nextTick(() => {
expect(vm.$el.querySelector('.container-image-tags')).toBeDefined();
expect(vm.$el.querySelector('.container-image-head i').className).toEqual('fa fa-chevron-up');
done();
});
});
it('should be closed when the user clicks on an opened repo', (done) => {
vm.$el.querySelector('.js-toggle-repo').click();
Vue.nextTick(() => {
vm.$el.querySelector('.js-toggle-repo').click();
Vue.nextTick(() => {
expect(vm.$el.querySelector('.container-image-tags')).toBe(null);
expect(vm.$el.querySelector('.container-image-head i').className).toEqual('fa fa-chevron-right');
done();
});
});
});
});
describe('delete repo', () => {
it('should be possible to delete a repo', () => {
expect(vm.$el.querySelector('.js-remove-repo')).toBeDefined();
});
});
describe('registry list', () => {
it('should render a table with the registry list', (done) => {
vm.$el.querySelector('.js-toggle-repo').click();
Vue.nextTick(() => {
expect(
vm.$el.querySelectorAll('table tbody tr').length,
).toEqual(mockData.list.length);
done();
});
});
it('should render registry tag', (done) => {
vm.$el.querySelector('.js-toggle-repo').click();
Vue.nextTick(() => {
const textRendered = vm.$el.querySelector('.table tbody tr').textContent.trim().replace(/\s\s+/g, ' ');
expect(textRendered).toContain(mockData.list[0].tag);
expect(textRendered).toContain(mockData.list[0].shortRevision);
expect(textRendered).toContain(mockData.list[0].layers);
expect(textRendered).toContain(mockData.list[0].size);
done();
});
});
it('should be possible to delete a registry', (done) => {
vm.$el.querySelector('.js-toggle-repo').click();
Vue.nextTick(() => {
expect(
vm.$el.querySelector('.table tbody tr .js-delete-registry'),
).toBeDefined();
done();
});
});
});
});
import Vue from 'vue';
import VueResource from 'vue-resource';
import _ from 'underscore';
import * as actions from '~/registry/stores/actions';
import * as types from '~/registry/stores/mutation_types';
import testAction from '../../helpers/vuex_action_helper';
import {
defaultState,
reposServerResponse,
registryServerResponse,
parsedReposServerResponse,
} from './mock_data';
Vue.use(VueResource);
describe('Actions Registry Store', () => {
let interceptor;
let mockedState;
beforeEach(() => {
mockedState = defaultState;
});
describe('server requests', () => {
afterEach(() => {
Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor);
});
describe('fetchRepos', () => {
beforeEach(() => {
interceptor = (request, next) => {
next(request.respondWith(JSON.stringify(reposServerResponse), {
status: 200,
}));
};
Vue.http.interceptors.push(interceptor);
});
it('should set receveived repos', (done) => {
testAction(actions.fetchRepos, null, mockedState, [
{ type: types.TOGGLE_MAIN_LOADING },
{ type: types.SET_REPOS_LIST, payload: reposServerResponse },
], done);
});
});
describe('fetchList', () => {
beforeEach(() => {
interceptor = (request, next) => {
next(request.respondWith(JSON.stringify(registryServerResponse), {
status: 200,
}));
};
Vue.http.interceptors.push(interceptor);
});
it('should set received list', (done) => {
mockedState.repos = parsedReposServerResponse;
testAction(actions.fetchList, mockedState.repos[1], mockedState, [
{ type: types.TOGGLE_REGISTRY_LIST_LOADING },
{ type: types.SET_REGISTRY_LIST, payload: registryServerResponse },
], done);
});
});
});
describe('setMainEndpoint', () => {
it('should commit set main endpoint', (done) => {
testAction(actions.setMainEndpoint, 'endpoint', mockedState, [
{ type: types.SET_MAIN_ENDPOINT, payload: 'endpoint' },
], done);
});
});
describe('toggleLoading', () => {
it('should commit toggle main loading', (done) => {
testAction(actions.toggleLoading, null, mockedState, [
{ type: types.TOGGLE_MAIN_LOADING },
], done);
});
});
});
import * as getters from '~/registry/stores/getters';
describe('Getters Registry Store', () => {
let state;
beforeEach(() => {
state = {
isLoading: false,
endpoint: '/root/empty-project/container_registry.json',
repos: [{
canDelete: true,
destroyPath: 'bar',
id: '134',
isLoading: false,
list: [],
location: 'foo',
name: 'gitlab-org/omnibus-gitlab/foo',
tagsPath: 'foo',
}, {
canDelete: true,
destroyPath: 'bar',
id: '123',
isLoading: false,
list: [],
location: 'foo',
name: 'gitlab-org/omnibus-gitlab',
tagsPath: 'foo',
}],
};
});
describe('isLoading', () => {
it('should return the isLoading property', () => {
expect(getters.isLoading(state)).toEqual(state.isLoading);
});
});
describe('repos', () => {
it('should return the repos', () => {
expect(getters.repos(state)).toEqual(state.repos);
});
});
});
export const defaultState = {
isLoading: false,
endpoint: '',
repos: [],
};
export const reposServerResponse = [
{
destroy_path: 'path',
id: '123',
location: 'location',
name: 'foo',
tags_path: 'tags_path',
},
{
destroy_path: 'path_',
id: '456',
location: 'location_',
name: 'bar',
tags_path: 'tags_path_',
},
];
export const registryServerResponse = [
{
name: 'centos7',
short_revision: 'b118ab5b0',
revision: 'b118ab5b0e90b7cb5127db31d5321ac14961d097516a8e0e72084b6cdc783b43',
size: 679,
layers: 19,
location: 'location',
created_at: 1505828744434,
destroy_path: 'path_',
},
{
name: 'centos6',
short_revision: 'b118ab5b0',
revision: 'b118ab5b0e90b7cb5127db31d5321ac14961d097516a8e0e72084b6cdc783b43',
size: 679,
layers: 19,
location: 'location',
created_at: 1505828744434,
}];
export const parsedReposServerResponse = [
{
canDelete: true,
destroyPath: reposServerResponse[0].destroy_path,
id: reposServerResponse[0].id,
isLoading: false,
list: [],
location: reposServerResponse[0].location,
name: reposServerResponse[0].name,
tagsPath: reposServerResponse[0].tags_path,
},
{
canDelete: true,
destroyPath: reposServerResponse[1].destroy_path,
id: reposServerResponse[1].id,
isLoading: false,
list: [],
location: reposServerResponse[1].location,
name: reposServerResponse[1].name,
tagsPath: reposServerResponse[1].tags_path,
},
];
export const parsedRegistryServerResponse = [
{
tag: registryServerResponse[0].name,
revision: registryServerResponse[0].revision,
shortRevision: registryServerResponse[0].short_revision,
size: registryServerResponse[0].size,
layers: registryServerResponse[0].layers,
location: registryServerResponse[0].location,
createdAt: registryServerResponse[0].created_at,
destroyPath: registryServerResponse[0].destroy_path,
canDelete: true,
},
{
tag: registryServerResponse[1].name,
revision: registryServerResponse[1].revision,
shortRevision: registryServerResponse[1].short_revision,
size: registryServerResponse[1].size,
layers: registryServerResponse[1].layers,
location: registryServerResponse[1].location,
createdAt: registryServerResponse[1].created_at,
destroyPath: registryServerResponse[1].destroy_path,
canDelete: false,
},
];
import mutations from '~/registry/stores/mutations';
import * as types from '~/registry/stores/mutation_types';
import {
defaultState,
reposServerResponse,
registryServerResponse,
parsedReposServerResponse,
parsedRegistryServerResponse,
} from './mock_data';
describe('Mutations Registry Store', () => {
let mockState;
beforeEach(() => {
mockState = defaultState;
});
describe('SET_MAIN_ENDPOINT', () => {
it('should set the main endpoint', () => {
const expectedState = Object.assign({}, mockState, { endpoint: 'foo' });
mutations[types.SET_MAIN_ENDPOINT](mockState, 'foo');
expect(mockState).toEqual(expectedState);
});
});
describe('SET_REPOS_LIST', () => {
it('should set a parsed repository list', () => {
mutations[types.SET_REPOS_LIST](mockState, reposServerResponse);
expect(mockState.repos).toEqual(parsedReposServerResponse);
});
});
describe('TOGGLE_MAIN_LOADING', () => {
it('should set a parsed repository list', () => {
mutations[types.TOGGLE_MAIN_LOADING](mockState);
expect(mockState.isLoading).toEqual(true);
});
});
describe('SET_REGISTRY_LIST', () => {
it('should set a list of registries in a specific repository', () => {
mutations[types.SET_REPOS_LIST](mockState, reposServerResponse);
mutations[types.SET_REGISTRY_LIST](mockState, mockState.repos[0], registryServerResponse);
expect(mockState.repos[0].list).toEqual(parsedRegistryServerResponse);
});
});
describe('TOGGLE_REGISTRY_LIST_LOADING', () => {
it('should toggle isLoading property for a specific repository', () => {
mutations[types.SET_REPOS_LIST](mockState, reposServerResponse);
mutations[types.SET_REGISTRY_LIST](mockState, mockState.repos[0], registryServerResponse);
mutations[types.TOGGLE_REGISTRY_LIST_LOADING](mockState, mockState.repos[0]);
expect(mockState.repos[0].isLoading).toEqual(true);
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment