Vlasnik izlazi iz DAL price za ovaj projekat - postaje samostalan proizvod. Preimenovanje je mehanicko (import putanje, imena fajlova/baze/UI naslova), NIJEDNA linija poslovne logike u internal/handler ili internal/service nije dirana - go build, go vet i go test ./... prolaze cisto pod novim imenom. - go.mod: module dal-license-server -> licence-server; 28 import linija u 13 .go fajlova usaglaseno - internal/config/config.go (+test): default DB_NAME licence_db - HTML sabloni (7 stranica) + 7 Playwright e2e spec fajlova: "DAL License Server" -> "Licence Server" u title/nav-brand, testovi usaglaseni u istom prolazu (nista ne moze da se razdvoji) - package.json/package-lock.json/.gitignore/.claude/project.json: ime projekta/binarnog fajla/work_dir - Usput: package.json je u repository.url nosio OTVORENU Gitea lozinku u cistom tekstu - uklonjena (URL sad bez kredencijala). Lozinka je i dalje u staroj git istoriji - preporuka: rotirati je posebno. - CLAUDE.md/README/API/TESTING/docs/SPEC/ARCHITECTURE/SETUP: naslovi, ASCII dijagrami, git clone URL, mysqldump primer, systemd predlozak u SETUP.md zamenjen stvarnim (obrazac terminia.service - journal log + graceful shutdown, ne stari minimalni predlozak) - Debrendiranje: "Univerzalni licencni server za sve DAL proizvode" -> "za vise proizvoda i klijenata"; potpis "Nenad Djukic / DAL d.o.o." -> "Nenad Djukic". NE dirano: nazivi ESIR/ARV/LIGHT_TICKET (tudji proizvodi, ne DAL brend), "DAL" kao stvaran naziv org-a u RBAC modelu (docs/loggerservice/README.md) - to je podatak, ne branding ovog servera. - docs/asp-terminia/, docs/loggerservice/: prozni pomeni imena servera Baza (dal_license_db -> licence_db) i deploy na 151 idu u posebnom koraku, posle preimenovanja Gitea repoa - vidi CLAUDE.md istorijsku belesku na dnu. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
165 lines
6.3 KiB
TypeScript
165 lines
6.3 KiB
TypeScript
import { test, expect, Page } from '@playwright/test';
|
|
|
|
async function login(page: Page) {
|
|
await page.goto('/login');
|
|
await page.fill('input[name="username"]', 'admin');
|
|
await page.fill('input[name="password"]', 'admin123');
|
|
await page.click('button[type="submit"]');
|
|
await expect(page).toHaveURL(/\/dashboard/);
|
|
}
|
|
|
|
test.describe('Lista licenci — stranica', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await login(page);
|
|
});
|
|
|
|
test('prikazuje naslov Licence', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
await expect(page.locator('h1')).toHaveText('Licence');
|
|
});
|
|
|
|
test('ima ispravan title', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
await expect(page).toHaveTitle('Licence - Licence Server');
|
|
});
|
|
|
|
test('prikazuje tabelu sa ispravnim kolonama', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
const headers = page.locator('thead th');
|
|
await expect(headers.nth(0)).toHaveText('Kljuc');
|
|
await expect(headers.nth(1)).toHaveText('Proizvod');
|
|
await expect(headers.nth(2)).toHaveText('Firma');
|
|
await expect(headers.nth(3)).toHaveText('Tip');
|
|
await expect(headers.nth(4)).toHaveText('Istice');
|
|
await expect(headers.nth(5)).toHaveText('Aktivacija');
|
|
await expect(headers.nth(6)).toHaveText('Status');
|
|
});
|
|
|
|
test('ima dugme za novu licencu', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
const btn = page.locator('a[href="/licenses/new"]');
|
|
await expect(btn).toBeVisible();
|
|
await expect(btn).toHaveText('Nova licenca');
|
|
await expect(btn).toHaveClass(/btn-primary/);
|
|
});
|
|
|
|
test('dugme nova licenca vodi na formu', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
await page.click('a[href="/licenses/new"]');
|
|
await expect(page).toHaveURL(/\/licenses\/new/);
|
|
});
|
|
|
|
test('filter dropdown za proizvod sadrzi sve opcije', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
const productSelect = page.locator('select[name="product"]');
|
|
await expect(productSelect).toBeVisible();
|
|
const options = await productSelect.locator('option').allTextContents();
|
|
expect(options).toContain('Svi proizvodi');
|
|
expect(options.some(o => o.includes('ESIR'))).toBe(true);
|
|
expect(options.some(o => o.includes('ARV'))).toBe(true);
|
|
expect(options.some(o => o.includes('Light-Ticket'))).toBe(true);
|
|
});
|
|
|
|
test('filter dropdown za status sadrzi sve opcije', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
const statusSelect = page.locator('select[name="status"]');
|
|
await expect(statusSelect).toBeVisible();
|
|
const options = await statusSelect.locator('option').allTextContents();
|
|
expect(options).toContain('Svi statusi');
|
|
expect(options).toContain('Aktivne');
|
|
expect(options).toContain('Istekle');
|
|
expect(options).toContain('Opozvane');
|
|
expect(options).toContain('Trial');
|
|
});
|
|
|
|
test('pretraga polje postoji', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
const search = page.locator('input[name="search"]');
|
|
await expect(search).toBeVisible();
|
|
await expect(search).toHaveAttribute('placeholder', 'Pretraga po firmi...');
|
|
});
|
|
|
|
test('filtriraj dugme postoji', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
await expect(page.locator('button:has-text("Filtriraj")')).toBeVisible();
|
|
});
|
|
|
|
test('filter po proizvodu — ESIR', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
await page.selectOption('select[name="product"]', 'ESIR');
|
|
await page.click('button:has-text("Filtriraj")');
|
|
await expect(page).toHaveURL(/product=ESIR/);
|
|
});
|
|
|
|
test('filter po proizvodu — ARV', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
await page.selectOption('select[name="product"]', 'ARV');
|
|
await page.click('button:has-text("Filtriraj")');
|
|
await expect(page).toHaveURL(/product=ARV/);
|
|
});
|
|
|
|
test('filter po proizvodu — LIGHT_TICKET', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
await page.selectOption('select[name="product"]', 'LIGHT_TICKET');
|
|
await page.click('button:has-text("Filtriraj")');
|
|
await expect(page).toHaveURL(/product=LIGHT_TICKET/);
|
|
});
|
|
|
|
test('filter po statusu — active', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
await page.selectOption('select[name="status"]', 'active');
|
|
await page.click('button:has-text("Filtriraj")');
|
|
await expect(page).toHaveURL(/status=active/);
|
|
});
|
|
|
|
test('filter po statusu — expired', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
await page.selectOption('select[name="status"]', 'expired');
|
|
await page.click('button:has-text("Filtriraj")');
|
|
await expect(page).toHaveURL(/status=expired/);
|
|
});
|
|
|
|
test('filter po statusu — revoked', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
await page.selectOption('select[name="status"]', 'revoked');
|
|
await page.click('button:has-text("Filtriraj")');
|
|
await expect(page).toHaveURL(/status=revoked/);
|
|
});
|
|
|
|
test('pretraga po firmi', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
await page.fill('input[name="search"]', 'TestFirma');
|
|
await page.click('button:has-text("Filtriraj")');
|
|
await expect(page).toHaveURL(/search=TestFirma/);
|
|
});
|
|
|
|
test('kombinacija filtera — proizvod + status', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
await page.selectOption('select[name="product"]', 'ESIR');
|
|
await page.selectOption('select[name="status"]', 'active');
|
|
await page.click('button:has-text("Filtriraj")');
|
|
await expect(page).toHaveURL(/product=ESIR/);
|
|
await expect(page).toHaveURL(/status=active/);
|
|
});
|
|
|
|
test('filter cuva selekciju posle submit-a', async ({ page }) => {
|
|
await page.goto('/licenses?product=ESIR&status=active');
|
|
const productVal = await page.locator('select[name="product"]').inputValue();
|
|
const statusVal = await page.locator('select[name="status"]').inputValue();
|
|
expect(productVal).toBe('ESIR');
|
|
expect(statusVal).toBe('active');
|
|
});
|
|
|
|
test('navbar licence link je aktivan', async ({ page }) => {
|
|
await page.goto('/licenses');
|
|
const link = page.locator('a[href="/licenses"]');
|
|
await expect(link).toHaveClass(/active/);
|
|
});
|
|
|
|
test('ako nema licenci prikazuje poruku', async ({ page }) => {
|
|
// Pretraga za nepostojeci termin
|
|
await page.goto('/licenses?search=NEPOSTOJECI_TERMIN_12345');
|
|
await expect(page.locator('td', { hasText: 'Nema licenci' })).toBeVisible();
|
|
});
|
|
});
|