feat(catalog) : M6 — écran consultation produit + onglets conditionnés + édition sans redirection
Auto Tag Develop / tag (push) Successful in 37s
Auto Tag Develop / tag (push) Successful in 37s
- Nouvel écran de consultation lecture seule /admin/products/{id} (calque
client/fournisseur) : clic sur une ligne ouvre la consultation (plus l'édition
directe), bouton « Modifier » → édition.
- Règle ERP-193 en consultation : champs vides / checkbox non cochées masqués
(isFilled) ; onglets vides masqués → les coquilles Fournisseurs/Clients
(placeholder, module Contrat inexistant) ne sont pas rendues en consultation.
- Onglets Fournisseurs/Clients : non affichés à l'ajout (avant validation du
formulaire principal) ; visibilité conditionnée par l'état (spec C3, « Aucun »
= OTHER) : Fournisseurs si Achat/Aucun, Clients si Vendu/Aucun.
- Édition : après « Enregistrer » on reste sur l'écran (l'utilisateur garde la
main, calque client/fournisseur) ; réaffichage des valeurs normalisées serveur
(RG-6.07) via re-prefill, plus de redirection.
- i18n consultation + tests (consultation, onglets, no-redirect) ; spec écran 8.bis.
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import { describe, it, expect, vi } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { defineComponent, h, nextTick } from 'vue'
|
||||
import ProductPlaceholderTabs from '../ProductPlaceholderTabs.vue'
|
||||
|
||||
// i18n auto-import : retourne la cle telle quelle.
|
||||
vi.stubGlobal('useI18n', () => ({ t: (key: string) => key }))
|
||||
|
||||
// Stub de MalioTabList : expose les `key` des onglets recus (data-tab) pour
|
||||
// verifier la visibilite conditionnee par l'etat, sans dependre de la lib UI.
|
||||
const TabListStub = defineComponent({
|
||||
props: { tabs: { type: Array, default: () => [] }, modelValue: { type: String, default: '' } },
|
||||
setup(props) {
|
||||
return () => h(
|
||||
'div',
|
||||
{ 'data-testid': 'tablist' },
|
||||
(props.tabs as { key: string }[]).map(tab => h('span', { 'data-tab': tab.key })),
|
||||
)
|
||||
},
|
||||
})
|
||||
const PlaceholderStub = defineComponent({ setup() { return () => h('div') } })
|
||||
|
||||
function mountTabs(states: string[]) {
|
||||
return mount(ProductPlaceholderTabs, {
|
||||
props: { states },
|
||||
global: { stubs: { MalioTabList: TabListStub, ComingSoonPlaceholder: PlaceholderStub } },
|
||||
})
|
||||
}
|
||||
|
||||
const tabKeys = (wrapper: ReturnType<typeof mountTabs>): string[] =>
|
||||
wrapper.findAll('[data-tab]').map(node => node.attributes('data-tab') ?? '')
|
||||
|
||||
describe('ProductPlaceholderTabs — visibilite conditionnee par l\'etat', () => {
|
||||
it('Achat (PURCHASE) : affiche uniquement « Fournisseurs »', () => {
|
||||
expect(tabKeys(mountTabs(['PURCHASE']))).toEqual(['suppliers'])
|
||||
})
|
||||
|
||||
it('Vendu (SALE) : affiche uniquement « Clients »', () => {
|
||||
expect(tabKeys(mountTabs(['SALE']))).toEqual(['clients'])
|
||||
})
|
||||
|
||||
it('Aucun (OTHER) : affiche les deux onglets', () => {
|
||||
expect(tabKeys(mountTabs(['OTHER']))).toEqual(['suppliers', 'clients'])
|
||||
})
|
||||
|
||||
it('Achat + Vendu : affiche les deux onglets', () => {
|
||||
expect(tabKeys(mountTabs(['PURCHASE', 'SALE']))).toEqual(['suppliers', 'clients'])
|
||||
})
|
||||
|
||||
it('etat vide : ne rend aucun onglet (MalioTabList absent)', () => {
|
||||
const wrapper = mountTabs([])
|
||||
expect(wrapper.find('[data-testid="tablist"]').exists()).toBe(false)
|
||||
})
|
||||
|
||||
it('retombe sur le premier onglet visible si l\'actif disparait', async () => {
|
||||
// OTHER -> suppliers actif par defaut ; passage a SALE retire « Fournisseurs ».
|
||||
const wrapper = mountTabs(['OTHER'])
|
||||
await wrapper.setProps({ states: ['SALE'] })
|
||||
await nextTick()
|
||||
// Seul « Clients » subsiste : pas d'onglet actif fantome (verifie via le modelValue).
|
||||
const tablist = wrapper.findComponent(TabListStub)
|
||||
expect(tablist.props('modelValue')).toBe('clients')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user