AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Nextcloud Impl Testing

skill-impertio-studio-nextcloud-claude-skill-package-nextcloud-impl-testing · by Impertio-Studio

>

No reviews yet
0 installs
13 views
0.0% view→install

Install

$ agentstack add skill-impertio-studio-nextcloud-claude-skill-package-nextcloud-impl-testing

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-impertio-studio-nextcloud-claude-skill-package-nextcloud-impl-testing)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Nextcloud Impl Testing? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

nextcloud-impl-testing

Quick Reference

Test Types

| Type | Base Class | Bootstrap | Location | |------|-----------|-----------|----------| | Unit | \Test\TestCase | ../../tests/bootstrap.php | tests/Unit/ | | Integration | \Test\TestCase | ../../tests/bootstrap.php | tests/Integration/ | | Frontend | Jest + @vue/test-utils | jest.config.js | tests/js/ or src/__tests__/ |

PHPUnit Configuration (phpunit.xml)


    
        
            ./tests/Unit
        
        
            ./tests/Integration
        
    
    
        
            ./lib
        
    

Test Directory Structure

myapp/
├── phpunit.xml
├── tests/
│   ├── Unit/
│   │   ├── Controller/
│   │   │   └── NoteControllerTest.php
│   │   └── Service/
│   │       └── NoteServiceTest.php
│   └── Integration/
│       └── Service/
│           └── NoteServiceIntegrationTest.php
├── src/
│   └── __tests__/
│       └── NoteList.spec.ts
└── jest.config.js

Mock Methods (PHPUnit)

| Method | Purpose | |--------|---------| | $this->createMock(ClassName::class) | Create mock with all methods stubbed | | $mock->method('name')->willReturn($val) | Stub return value | | $mock->expects($this->once())->method('name') | Assert method called once | | $mock->expects($this->never())->method('name') | Assert method never called | | $mock->method('name')->willThrowException($e) | Stub to throw exception | | $mock->method('name')->with($this->equalTo($v)) | Assert parameter value |

Critical Warnings

ALWAYS call parent::setUp() in your setUp() method -- Nextcloud's TestCase performs essential initialization (database transaction start, cleanup hooks). Omitting it causes test pollution and random failures.

ALWAYS call parent::tearDown() in your tearDown() method -- Nextcloud's TestCase rolls back database transactions. Omitting it leaves test data in the database.

ALWAYS use ../../tests/bootstrap.php as the PHPUnit bootstrap path -- this path is relative from your app's root to the Nextcloud server tests/ directory. Without it, no Nextcloud classes are autoloaded.

NEVER use \OCP\Server::get() in tests to resolve services -- use constructor injection and mocks. Static container access makes tests non-isolated and order-dependent.

NEVER write to the real database in unit tests -- use mocks for IDBConnection and mappers. Reserve real database access for integration tests only.

NEVER skip the phpunit.xml configuration file -- without it, the bootstrap path is not set and test suites cannot be selected.


Decision Tree: Which Test Type?

Need to test?
├── Pure logic (service, helper, utility)
│   └── UNIT TEST: Mock all dependencies
├── Controller request handling
│   └── UNIT TEST: Mock services, test return types/status codes
├── Database queries / mapper behavior
│   └── INTEGRATION TEST: Use real DI container + DB transactions
├── Multi-service interaction with real DI
│   └── INTEGRATION TEST: Resolve services from container
├── Vue component rendering
│   └── FRONTEND TEST: Jest + @vue/test-utils mount/shallowMount
└── API endpoint end-to-end
    └── INTEGRATION TEST: Use TestCase with real HTTP or container

Essential Patterns

Pattern 1: Unit Test with Mocks

mapper = $this->createMock(NoteMapper::class);
        $this->service = new NoteService($this->mapper);
    }

    public function testFind(): void {
        $note = new Note();
        $note->setId(1);
        $note->setTitle('Test');

        $this->mapper->expects($this->once())
            ->method('find')
            ->with($this->equalTo(1), $this->equalTo('user1'))
            ->willReturn($note);

        $result = $this->service->find(1, 'user1');
        $this->assertEquals('Test', $result->getTitle());
    }

    public function testFindNotFound(): void {
        $this->mapper->expects($this->once())
            ->method('find')
            ->willThrowException(new DoesNotExistException(''));

        $this->expectException(NotFoundException::class);
        $this->service->find(999, 'user1');
    }
}

Pattern 2: Controller Unit Test

createMock(IRequest::class);
        $this->service = $this->createMock(NoteService::class);
        $this->controller = new NoteController(
            'myapp', $request, $this->service, 'user1'
        );
    }

    public function testShow(): void {
        $this->service->method('find')->willReturn(['id' => 1]);
        $result = $this->controller->show(1);
        $this->assertEquals(Http::STATUS_OK, $result->getStatus());
    }

    public function testShowNotFound(): void {
        $this->service->method('find')
            ->willThrowException(new NotFoundException());
        $result = $this->controller->show(999);
        $this->assertEquals(Http::STATUS_NOT_FOUND, $result->getStatus());
    }
}

Pattern 3: Integration Test with DI Container

getContainer();
        $this->service = $container->get(NoteService::class);
        $this->mapper = $container->get(NoteMapper::class);
    }

    public function testCreateAndFind(): void {
        $note = $this->service->create('Integration Test', 'content', 'testuser');
        $this->assertNotNull($note->getId());

        $found = $this->service->find($note->getId(), 'testuser');
        $this->assertEquals('Integration Test', $found->getTitle());
    }

    protected function tearDown(): void {
        parent::tearDown(); // CRITICAL: ALWAYS call parent (rolls back transaction)
    }
}

Pattern 4: Frontend Test with Vue Test Utils

// src/__tests__/NoteList.spec.ts
import { shallowMount } from '@vue/test-utils'
import NoteList from '../components/NoteList.vue'
import axios from '@nextcloud/axios'

jest.mock('@nextcloud/axios')
const mockedAxios = axios as jest.Mocked

describe('NoteList', () => {
    beforeEach(() => {
        jest.clearAllMocks()
    })

    it('renders notes after fetch', async () => {
        mockedAxios.get.mockResolvedValue({
            data: [{ id: 1, title: 'Note 1' }, { id: 2, title: 'Note 2' }],
        })

        const wrapper = shallowMount(NoteList)
        await wrapper.vm.$nextTick()
        await wrapper.vm.$nextTick() // Wait for async data

        expect(wrapper.findAll('.note-item')).toHaveLength(2)
    })

    it('shows empty state when no notes', async () => {
        mockedAxios.get.mockResolvedValue({ data: [] })

        const wrapper = shallowMount(NoteList)
        await wrapper.vm.$nextTick()
        await wrapper.vm.$nextTick()

        expect(wrapper.find('.empty-content').exists()).toBe(true)
    })
})

Pattern 5: Jest Configuration

// jest.config.js
module.exports = {
    testEnvironment: 'jsdom',
    moduleFileExtensions: ['js', 'ts', 'vue'],
    transform: {
        '^.+\\.ts$': 'ts-jest',
        '^.+\\.vue$': '@vue/vue3-jest',
        '^.+\\.js$': 'babel-jest',
    },
    moduleNameMapper: {
        '^@nextcloud/axios$': '/src/__mocks__/@nextcloud/axios.ts',
        '^@nextcloud/router$': '/src/__mocks__/@nextcloud/router.ts',
    },
    collectCoverageFrom: ['src/**/*.{ts,vue}', '!src/**/*.d.ts'],
}

Running Tests

PHP Tests

# Run all tests from app directory
cd apps/myapp
../../lib/composer/bin/phpunit

# Run specific test suite
../../lib/composer/bin/phpunit --testsuite unit
../../lib/composer/bin/phpunit --testsuite integration

# Run single test file
../../lib/composer/bin/phpunit tests/Unit/Service/NoteServiceTest.php

# Run single test method
../../lib/composer/bin/phpunit --filter testFind tests/Unit/Service/NoteServiceTest.php

Frontend Tests

# Run from app directory
cd apps/myapp
npm test

# Run with coverage
npm test -- --coverage

# Run specific test file
npx jest src/__tests__/NoteList.spec.ts

Reference Links

  • [references/methods.md](references/methods.md) -- TestCase base class, mock methods, assertion methods, phpunit.xml options
  • [references/examples.md](references/examples.md) -- Complete unit test, integration test, and frontend test examples
  • [references/anti-patterns.md](references/anti-patterns.md) -- Common testing mistakes and corrections

Official Sources

  • https://docs.nextcloud.com/server/latest/developermanual/diggingdeeper/testing.html
  • https://docs.nextcloud.com/server/latest/developer_manual/basics/front-end/testing.html
  • https://phpunit.de/documentation.html
  • https://test-utils.vuejs.org/

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.