Commit f6d8fb6e authored by Phil Hughes's avatar Phil Hughes

Merge branch '39727-registry' into 'master'

Replaces vue-resource with axios for registry code

See merge request gitlab-org/gitlab-ce!23545
parents 5c5a5992 213557fa
<script> <script>
import { mapGetters, mapActions } from 'vuex'; import { mapGetters, mapActions } from 'vuex';
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } from '@gitlab/ui';
import Flash from '../../flash';
import store from '../stores'; import store from '../stores';
import collapsibleContainer from './collapsible_container.vue'; import CollapsibleContainer from './collapsible_container.vue';
import { errorMessages, errorMessagesTypes } from '../constants';
export default { export default {
name: 'RegistryListApp', name: 'RegistryListApp',
components: { components: {
collapsibleContainer, CollapsibleContainer,
GlLoadingIcon, GlLoadingIcon,
}, },
props: { props: {
...@@ -26,7 +24,7 @@ export default { ...@@ -26,7 +24,7 @@ export default {
this.setMainEndpoint(this.endpoint); this.setMainEndpoint(this.endpoint);
}, },
mounted() { mounted() {
this.fetchRepos().catch(() => Flash(errorMessages[errorMessagesTypes.FETCH_REPOS])); this.fetchRepos();
}, },
methods: { methods: {
...mapActions(['setMainEndpoint', 'fetchRepos']), ...mapActions(['setMainEndpoint', 'fetchRepos']),
...@@ -38,9 +36,9 @@ export default { ...@@ -38,9 +36,9 @@ export default {
<gl-loading-icon v-if="isLoading" :size="3" /> <gl-loading-icon v-if="isLoading" :size="3" />
<collapsible-container <collapsible-container
v-for="(item, index) in repos" v-for="item in repos"
v-else-if="!isLoading && repos.length" v-else-if="!isLoading && repos.length"
:key="index" :key="item.id"
:repo="item" :repo="item"
/> />
......
<script> <script>
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon, GlButton, GlTooltipDirective } from '@gitlab/ui';
import Flash from '../../flash'; import createFlash from '../../flash';
import clipboardButton from '../../vue_shared/components/clipboard_button.vue'; import ClipboardButton from '../../vue_shared/components/clipboard_button.vue';
import tooltip from '../../vue_shared/directives/tooltip'; import Icon from '../../vue_shared/components/icon.vue';
import tableRegistry from './table_registry.vue'; import TableRegistry from './table_registry.vue';
import { errorMessages, errorMessagesTypes } from '../constants'; import { errorMessages, errorMessagesTypes } from '../constants';
import { __ } from '../../locale'; import { __ } from '../../locale';
export default { export default {
name: 'CollapsibeContainerRegisty', name: 'CollapsibeContainerRegisty',
components: { components: {
clipboardButton, ClipboardButton,
tableRegistry, TableRegistry,
GlLoadingIcon, GlLoadingIcon,
GlButton,
Icon,
}, },
directives: { directives: {
tooltip, GlTooltip: GlTooltipDirective,
}, },
props: { props: {
repo: { repo: {
...@@ -29,30 +31,30 @@ export default { ...@@ -29,30 +31,30 @@ export default {
isOpen: false, isOpen: false,
}; };
}, },
computed: {
iconName() {
return this.isOpen ? 'angle-up' : 'angle-right';
},
},
methods: { methods: {
...mapActions(['fetchRepos', 'fetchList', 'deleteRepo']), ...mapActions(['fetchRepos', 'fetchList', 'deleteRepo']),
toggleRepo() { toggleRepo() {
this.isOpen = !this.isOpen; this.isOpen = !this.isOpen;
if (this.isOpen) { if (this.isOpen) {
this.fetchList({ repo: this.repo }).catch(() => this.fetchList({ repo: this.repo });
this.showError(errorMessagesTypes.FETCH_REGISTRY),
);
} }
}, },
handleDeleteRepository() { handleDeleteRepository() {
this.deleteRepo(this.repo) this.deleteRepo(this.repo)
.then(() => { .then(() => {
Flash(__('This container registry has been scheduled for deletion.'), 'notice'); createFlash(__('This container registry has been scheduled for deletion.'), 'notice');
this.fetchRepos(); this.fetchRepos();
}) })
.catch(() => this.showError(errorMessagesTypes.DELETE_REPO)); .catch(() => this.showError(errorMessagesTypes.DELETE_REPO));
}, },
showError(message) { showError(message) {
Flash(errorMessages[message]); createFlash(errorMessages[message]);
}, },
}, },
}; };
...@@ -61,18 +63,9 @@ export default { ...@@ -61,18 +63,9 @@ export default {
<template> <template>
<div class="container-image"> <div class="container-image">
<div class="container-image-head"> <div class="container-image-head">
<button type="button" class="js-toggle-repo btn-link" @click="toggleRepo"> <gl-button class="js-toggle-repo btn-link align-baseline" @click="toggleRepo">
<i <icon :name="iconName" /> {{ repo.name }}
:class="{ </gl-button>
'fa-chevron-right': !isOpen,
'fa-chevron-up': isOpen,
}"
class="fa"
aria-hidden="true"
>
</i>
{{ repo.name }}
</button>
<clipboard-button <clipboard-button
v-if="repo.location" v-if="repo.location"
...@@ -82,17 +75,17 @@ export default { ...@@ -82,17 +75,17 @@ export default {
/> />
<div class="controls d-none d-sm-block float-right"> <div class="controls d-none d-sm-block float-right">
<button <gl-button
v-if="repo.canDelete" v-if="repo.canDelete"
v-tooltip v-gl-tooltip
:title="s__('ContainerRegistry|Remove repository')" :title="s__('ContainerRegistry|Remove repository')"
:aria-label="s__('ContainerRegistry|Remove repository')" :aria-label="s__('ContainerRegistry|Remove repository')"
type="button" class="js-remove-repo"
class="js-remove-repo btn btn-danger" variant="danger"
@click="handleDeleteRepository" @click="handleDeleteRepository"
> >
<i class="fa fa-trash" aria-hidden="true"> </i> <icon name="remove" />
</button> </gl-button>
</div> </div>
</div> </div>
......
<script> <script>
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
import { GlButton, GlTooltipDirective } from '@gitlab/ui';
import { n__ } from '../../locale'; import { n__ } from '../../locale';
import Flash from '../../flash'; import createFlash from '../../flash';
import clipboardButton from '../../vue_shared/components/clipboard_button.vue'; import ClipboardButton from '../../vue_shared/components/clipboard_button.vue';
import tablePagination from '../../vue_shared/components/table_pagination.vue'; import TablePagination from '../../vue_shared/components/table_pagination.vue';
import tooltip from '../../vue_shared/directives/tooltip'; import Icon from '../../vue_shared/components/icon.vue';
import timeagoMixin from '../../vue_shared/mixins/timeago'; import timeagoMixin from '../../vue_shared/mixins/timeago';
import { errorMessages, errorMessagesTypes } from '../constants'; import { errorMessages, errorMessagesTypes } from '../constants';
import { numberToHumanSize } from '../../lib/utils/number_utils'; import { numberToHumanSize } from '../../lib/utils/number_utils';
export default { export default {
components: { components: {
clipboardButton, ClipboardButton,
tablePagination, TablePagination,
GlButton,
Icon,
}, },
directives: { directives: {
tooltip, GlTooltip: GlTooltipDirective,
}, },
mixins: [timeagoMixin], mixins: [timeagoMixin],
props: { props: {
...@@ -31,29 +34,24 @@ export default { ...@@ -31,29 +34,24 @@ export default {
}, },
methods: { methods: {
...mapActions(['fetchList', 'deleteRegistry']), ...mapActions(['fetchList', 'deleteRegistry']),
layers(item) { layers(item) {
return item.layers ? n__('%d layer', '%d layers', item.layers) : ''; return item.layers ? n__('%d layer', '%d layers', item.layers) : '';
}, },
formatSize(size) { formatSize(size) {
return numberToHumanSize(size); return numberToHumanSize(size);
}, },
handleDeleteRegistry(registry) { handleDeleteRegistry(registry) {
this.deleteRegistry(registry) this.deleteRegistry(registry)
.then(() => this.fetchList({ repo: this.repo })) .then(() => this.fetchList({ repo: this.repo }))
.catch(() => this.showError(errorMessagesTypes.DELETE_REGISTRY)); .catch(() => this.showError(errorMessagesTypes.DELETE_REGISTRY));
}, },
onPageChange(pageNumber) { onPageChange(pageNumber) {
this.fetchList({ repo: this.repo, page: pageNumber }).catch(() => this.fetchList({ repo: this.repo, page: pageNumber }).catch(() =>
this.showError(errorMessagesTypes.FETCH_REGISTRY), this.showError(errorMessagesTypes.FETCH_REGISTRY),
); );
}, },
showError(message) { showError(message) {
Flash(errorMessages[message]); createFlash(errorMessages[message]);
}, },
}, },
}; };
...@@ -71,10 +69,9 @@ export default { ...@@ -71,10 +69,9 @@ export default {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="(item, i) in repo.list" :key="i"> <tr v-for="item in repo.list" :key="item.tag">
<td> <td>
{{ item.tag }} {{ item.tag }}
<clipboard-button <clipboard-button
v-if="item.location" v-if="item.location"
:title="item.location" :title="item.location"
...@@ -83,37 +80,34 @@ export default { ...@@ -83,37 +80,34 @@ export default {
/> />
</td> </td>
<td> <td>
<span v-tooltip :title="item.revision" data-placement="bottom"> <span v-gl-tooltip.bottom :title="item.revision">{{ item.shortRevision }}</span>
{{ item.shortRevision }}
</span>
</td> </td>
<td> <td>
{{ formatSize(item.size) }} {{ formatSize(item.size) }}
<template v-if="item.size && item.layers"> <template v-if="item.size && item.layers"
&middot; >&middot;</template
</template> >
{{ layers(item) }} {{ layers(item) }}
</td> </td>
<td> <td>
<span v-tooltip :title="tooltipTitle(item.createdAt)" data-placement="bottom"> <span v-gl-tooltip.bottom :title="tooltipTitle(item.createdAt)">{{
{{ timeFormated(item.createdAt) }} timeFormated(item.createdAt)
</span> }}</span>
</td> </td>
<td class="content"> <td class="content">
<button <gl-button
v-if="item.canDelete" v-if="item.canDelete"
v-tooltip v-gl-tooltip
:title="s__('ContainerRegistry|Remove tag')" :title="s__('ContainerRegistry|Remove tag')"
:aria-label="s__('ContainerRegistry|Remove tag')" :aria-label="s__('ContainerRegistry|Remove tag')"
type="button" variant="danger"
class="js-delete-registry btn btn-danger d-none d-sm-block float-right" class="js-delete-registry d-none d-sm-block float-right"
data-container="body"
@click="handleDeleteRegistry(item);" @click="handleDeleteRegistry(item);"
> >
<i class="fa fa-trash" aria-hidden="true"> </i> <icon name="remove" />
</button> </gl-button>
</td> </td>
</tr> </tr>
</tbody> </tbody>
......
import Vue from 'vue'; import axios from '~/lib/utils/axios_utils';
import VueResource from 'vue-resource'; import createFlash from '~/flash';
import * as types from './mutation_types'; import * as types from './mutation_types';
import { errorMessages, errorMessagesTypes } from '../constants';
Vue.use(VueResource);
export const fetchRepos = ({ commit, state }) => { export const fetchRepos = ({ commit, state }) => {
commit(types.TOGGLE_MAIN_LOADING); commit(types.TOGGLE_MAIN_LOADING);
return Vue.http return axios
.get(state.endpoint) .get(state.endpoint)
.then(res => res.json()) .then(({ data }) => {
.then(response => { commit(types.TOGGLE_MAIN_LOADING);
commit(types.SET_REPOS_LIST, data);
})
.catch(() => {
commit(types.TOGGLE_MAIN_LOADING); commit(types.TOGGLE_MAIN_LOADING);
commit(types.SET_REPOS_LIST, response); createFlash(errorMessages[errorMessagesTypes.FETCH_REPOS]);
}); });
}; };
export const fetchList = ({ commit }, { repo, page }) => { export const fetchList = ({ commit }, { repo, page }) => {
commit(types.TOGGLE_REGISTRY_LIST_LOADING, repo); commit(types.TOGGLE_REGISTRY_LIST_LOADING, repo);
return Vue.http.get(repo.tagsPath, { params: { page } }).then(response => { return axios
const { headers } = response; .get(repo.tagsPath, { params: { page } })
.then(response => {
const { headers, data } = response;
return response.json().then(resp => {
commit(types.TOGGLE_REGISTRY_LIST_LOADING, repo); commit(types.TOGGLE_REGISTRY_LIST_LOADING, repo);
commit(types.SET_REGISTRY_LIST, { repo, resp, headers }); commit(types.SET_REGISTRY_LIST, { repo, resp: data, headers });
}); })
.catch(() => {
commit(types.TOGGLE_REGISTRY_LIST_LOADING, repo);
createFlash(errorMessages[errorMessagesTypes.FETCH_REGISTRY]);
}); });
}; };
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
export const deleteRepo = ({ commit }, repo) => Vue.http.delete(repo.destroyPath); export const deleteRepo = ({ commit }, repo) => axios.delete(repo.destroyPath);
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
export const deleteRegistry = ({ commit }, image) => Vue.http.delete(image.destroyPath); export const deleteRegistry = ({ commit }, image) => axios.delete(image.destroyPath);
export const setMainEndpoint = ({ commit }, data) => commit(types.SET_MAIN_ENDPOINT, data); export const setMainEndpoint = ({ commit }, data) => commit(types.SET_MAIN_ENDPOINT, data);
export const toggleLoading = ({ commit }) => commit(types.TOGGLE_MAIN_LOADING); export const toggleLoading = ({ commit }) => commit(types.TOGGLE_MAIN_LOADING);
......
...@@ -3,36 +3,12 @@ import Vuex from 'vuex'; ...@@ -3,36 +3,12 @@ import Vuex from 'vuex';
import * as actions from './actions'; import * as actions from './actions';
import * as getters from './getters'; import * as getters from './getters';
import mutations from './mutations'; import mutations from './mutations';
import createState from './state';
Vue.use(Vuex); Vue.use(Vuex);
export default new Vuex.Store({ export default new Vuex.Store({
state: { state: createState(),
isLoading: false,
endpoint: '', // initial endpoint to fetch the repos list
/**
* Each object in `repos` has the following strucure:
* {
* name: String,
* isLoading: Boolean,
* tagsPath: String // endpoint to request the list
* destroyPath: String // endpoit to delete the repo
* list: Array // List of the registry images
* }
*
* Each registry image inside `list` has the following structure:
* {
* tag: String,
* revision: String
* shortRevision: String
* size: Number
* layers: Number
* createdAt: String
* destroyPath: String // endpoit to delete each image
* }
*/
repos: [],
},
actions, actions,
getters, getters,
mutations, mutations,
......
...@@ -48,6 +48,7 @@ export default { ...@@ -48,6 +48,7 @@ export default {
[types.TOGGLE_REGISTRY_LIST_LOADING](state, list) { [types.TOGGLE_REGISTRY_LIST_LOADING](state, list) {
const listToUpdate = state.repos.find(el => el.id === list.id); const listToUpdate = state.repos.find(el => el.id === list.id);
listToUpdate.isLoading = !listToUpdate.isLoading; listToUpdate.isLoading = !listToUpdate.isLoading;
}, },
}; };
export default () => ({
isLoading: false,
endpoint: '', // initial endpoint to fetch the repos list
/**
* Each object in `repos` has the following strucure:
* {
* name: String,
* isLoading: Boolean,
* tagsPath: String // endpoint to request the list
* destroyPath: String // endpoit to delete the repo
* list: Array // List of the registry images
* }
*
* Each registry image inside `list` has the following structure:
* {
* tag: String,
* revision: String
* shortRevision: String
* size: Number
* layers: Number
* createdAt: String
* destroyPath: String // endpoit to delete each image
* }
*/
repos: [],
});
import _ from 'underscore'; import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import Vue from 'vue'; import Vue from 'vue';
import registry from '~/registry/components/app.vue'; import registry from '~/registry/components/app.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper'; import mountComponent from 'spec/helpers/vue_mount_component_helper';
import { TEST_HOST } from 'spec/test_constants';
import { reposServerResponse } from '../mock_data'; import { reposServerResponse } from '../mock_data';
describe('Registry List', () => { describe('Registry List', () => {
const Component = Vue.extend(registry);
let vm; let vm;
let Component; let mock;
beforeEach(() => { beforeEach(() => {
Component = Vue.extend(registry); mock = new MockAdapter(axios);
}); });
afterEach(() => { afterEach(() => {
mock.restore();
vm.$destroy(); vm.$destroy();
}); });
describe('with data', () => { describe('with data', () => {
const interceptor = (request, next) => {
next(
request.respondWith(JSON.stringify(reposServerResponse), {
status: 200,
}),
);
};
beforeEach(() => { beforeEach(() => {
Vue.http.interceptors.push(interceptor); mock.onGet(`${TEST_HOST}/foo`).replyOnce(200, reposServerResponse);
vm = mountComponent(Component, { endpoint: 'foo' });
});
afterEach(() => { vm = mountComponent(Component, { endpoint: `${TEST_HOST}/foo` });
Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor);
}); });
it('should render a list of repos', done => { it('should render a list of repos', done => {
...@@ -64,9 +57,9 @@ describe('Registry List', () => { ...@@ -64,9 +57,9 @@ describe('Registry List', () => {
Vue.nextTick(() => { Vue.nextTick(() => {
vm.$el.querySelector('.js-toggle-repo').click(); vm.$el.querySelector('.js-toggle-repo').click();
Vue.nextTick(() => { Vue.nextTick(() => {
expect(vm.$el.querySelector('.js-toggle-repo i').className).toEqual( expect(
'fa fa-chevron-up', vm.$el.querySelector('.js-toggle-repo use').getAttribute('xlink:href'),
); ).toContain('angle-up');
done(); done();
}); });
}); });
...@@ -76,21 +69,10 @@ describe('Registry List', () => { ...@@ -76,21 +69,10 @@ describe('Registry List', () => {
}); });
describe('without data', () => { describe('without data', () => {
const interceptor = (request, next) => {
next(
request.respondWith(JSON.stringify([]), {
status: 200,
}),
);
};
beforeEach(() => { beforeEach(() => {
Vue.http.interceptors.push(interceptor); mock.onGet(`${TEST_HOST}/foo`).replyOnce(200, []);
vm = mountComponent(Component, { endpoint: 'foo' });
});
afterEach(() => { vm = mountComponent(Component, { endpoint: `${TEST_HOST}/foo` });
Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor);
}); });
it('should render empty message', done => { it('should render empty message', done => {
...@@ -109,21 +91,10 @@ describe('Registry List', () => { ...@@ -109,21 +91,10 @@ describe('Registry List', () => {
}); });
describe('while loading data', () => { describe('while loading data', () => {
const interceptor = (request, next) => {
next(
request.respondWith(JSON.stringify(reposServerResponse), {
status: 200,
}),
);
};
beforeEach(() => { beforeEach(() => {
Vue.http.interceptors.push(interceptor); mock.onGet(`${TEST_HOST}/foo`).replyOnce(200, []);
vm = mountComponent(Component, { endpoint: 'foo' });
});
afterEach(() => { vm = mountComponent(Component, { endpoint: `${TEST_HOST}/foo` });
Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor);
}); });
it('should render a loading spinner', done => { it('should render a loading spinner', done => {
......
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import Vue from 'vue'; import Vue from 'vue';
import collapsibleComponent from '~/registry/components/collapsible_container.vue'; import collapsibleComponent from '~/registry/components/collapsible_container.vue';
import store from '~/registry/stores'; import store from '~/registry/stores';
import { repoPropsData } from '../mock_data'; import * as types from '~/registry/stores/mutation_types';
import { repoPropsData, registryServerResponse, reposServerResponse } from '../mock_data';
describe('collapsible registry container', () => { describe('collapsible registry container', () => {
let vm; let vm;
let Component; let mock;
const Component = Vue.extend(collapsibleComponent);
beforeEach(() => { beforeEach(() => {
Component = Vue.extend(collapsibleComponent); mock = new MockAdapter(axios);
mock.onGet(repoPropsData.tagsPath).replyOnce(200, registryServerResponse, {});
store.commit(types.SET_REPOS_LIST, reposServerResponse);
vm = new Component({ vm = new Component({
store, store,
propsData: { propsData: {
...@@ -18,24 +28,23 @@ describe('collapsible registry container', () => { ...@@ -18,24 +28,23 @@ describe('collapsible registry container', () => {
}); });
afterEach(() => { afterEach(() => {
mock.restore();
vm.$destroy(); vm.$destroy();
}); });
describe('toggle', () => { describe('toggle', () => {
it('should be closed by default', () => { it('should be closed by default', () => {
expect(vm.$el.querySelector('.container-image-tags')).toBe(null); expect(vm.$el.querySelector('.container-image-tags')).toBe(null);
expect(vm.$el.querySelector('.container-image-head i').className).toEqual( expect(vm.iconName).toEqual('angle-right');
'fa fa-chevron-right',
);
}); });
it('should be open when user clicks on closed repo', done => { it('should be open when user clicks on closed repo', done => {
vm.$el.querySelector('.js-toggle-repo').click(); vm.$el.querySelector('.js-toggle-repo').click();
Vue.nextTick(() => { Vue.nextTick(() => {
expect(vm.$el.querySelector('.container-image-tags')).toBeDefined(); expect(vm.$el.querySelector('.container-image-tags')).not.toBeNull();
expect(vm.$el.querySelector('.container-image-head i').className).toEqual( expect(vm.iconName).toEqual('angle-up');
'fa fa-chevron-up',
);
done(); done();
}); });
}); });
...@@ -45,20 +54,20 @@ describe('collapsible registry container', () => { ...@@ -45,20 +54,20 @@ describe('collapsible registry container', () => {
Vue.nextTick(() => { Vue.nextTick(() => {
vm.$el.querySelector('.js-toggle-repo').click(); vm.$el.querySelector('.js-toggle-repo').click();
setTimeout(() => {
Vue.nextTick(() => { Vue.nextTick(() => {
expect(vm.$el.querySelector('.container-image-tags')).toBe(null); expect(vm.$el.querySelector('.container-image-tags')).toBe(null);
expect(vm.$el.querySelector('.container-image-head i').className).toEqual( expect(vm.iconName).toEqual('angle-right');
'fa fa-chevron-right',
);
done(); done();
}); });
}); });
}); });
}); });
});
describe('delete repo', () => { describe('delete repo', () => {
it('should be possible to delete a repo', () => { it('should be possible to delete a repo', () => {
expect(vm.$el.querySelector('.js-remove-repo')).toBeDefined(); expect(vm.$el.querySelector('.js-remove-repo')).not.toBeNull();
}); });
}); });
}); });
import Vue from 'vue'; import MockAdapter from 'axios-mock-adapter';
import VueResource from 'vue-resource'; import axios from '~/lib/utils/axios_utils';
import _ from 'underscore';
import * as actions from '~/registry/stores/actions'; import * as actions from '~/registry/stores/actions';
import * as types from '~/registry/stores/mutation_types'; import * as types from '~/registry/stores/mutation_types';
import state from '~/registry/stores/state';
import { TEST_HOST } from 'spec/test_constants';
import testAction from '../../helpers/vuex_action_helper'; import testAction from '../../helpers/vuex_action_helper';
import { import {
defaultState,
reposServerResponse, reposServerResponse,
registryServerResponse, registryServerResponse,
parsedReposServerResponse, parsedReposServerResponse,
} from '../mock_data'; } from '../mock_data';
Vue.use(VueResource);
describe('Actions Registry Store', () => { describe('Actions Registry Store', () => {
let interceptor;
let mockedState; let mockedState;
let mock;
beforeEach(() => { beforeEach(() => {
mockedState = defaultState; mockedState = state();
mockedState.endpoint = `${TEST_HOST}/endpoint.json`;
mock = new MockAdapter(axios);
}); });
describe('server requests', () => {
afterEach(() => { afterEach(() => {
Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor); mock.restore();
}); });
describe('server requests', () => {
describe('fetchRepos', () => { describe('fetchRepos', () => {
beforeEach(() => { beforeEach(() => {
interceptor = (request, next) => { mock.onGet(`${TEST_HOST}/endpoint.json`).replyOnce(200, reposServerResponse, {});
next(
request.respondWith(JSON.stringify(reposServerResponse), {
status: 200,
}),
);
};
Vue.http.interceptors.push(interceptor);
}); });
it('should set receveived repos', done => { it('should set receveived repos', done => {
...@@ -56,23 +48,15 @@ describe('Actions Registry Store', () => { ...@@ -56,23 +48,15 @@ describe('Actions Registry Store', () => {
}); });
describe('fetchList', () => { describe('fetchList', () => {
let repo;
beforeEach(() => { beforeEach(() => {
interceptor = (request, next) => { mockedState.repos = parsedReposServerResponse;
next( [, repo] = mockedState.repos;
request.respondWith(JSON.stringify(registryServerResponse), {
status: 200,
}),
);
};
Vue.http.interceptors.push(interceptor); mock.onGet(repo.tagsPath).replyOnce(200, registryServerResponse, {});
}); });
it('should set received list', done => { it('should set received list', done => {
mockedState.repos = parsedReposServerResponse;
const repo = mockedState.repos[1];
testAction( testAction(
actions.fetchList, actions.fetchList,
{ repo }, { repo },
......
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