Skip to content

Commit

Permalink
Merge branch 'main' into task-1258-form-disclaimer-broken
Browse files Browse the repository at this point in the history
  • Loading branch information
noliveleger committed Nov 26, 2024
2 parents 8bda894 + fe8e7ec commit ab52d05
Show file tree
Hide file tree
Showing 208 changed files with 5,568 additions and 4,406 deletions.
49 changes: 23 additions & 26 deletions .github/workflows/npm-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,8 @@ jobs:
- name: Add "Node ${{ steps.resolved-node-version.outputs.NODE_VERSION }}" to summary
run: echo "${{ matrix.node-version }} → **${{ steps.resolved-node-version.outputs.NODE_VERSION }}**" >> "$GITHUB_STEP_SUMMARY"

# Set up Chrome, for the unit tests
- uses: browser-actions/setup-chrome@latest
- run: chrome --version

# Cache node_modules, keyed on os, node version, package-lock, and patches
# Cache: Use cache for node_modules
# Keyed on os, node version, package-lock, and patches
- uses: actions/cache@v4
name: Check for cached node_modules
id: cache-nodemodules
Expand All @@ -47,37 +44,37 @@ jobs:
path: node_modules
key: ${{ runner.os }}-build-${{ env.cache-name }}-node-v${{ steps.resolved-node-version.outputs.NODE_VERSION }}-${{ hashFiles('**/package-lock.json', 'patches/**/*.patch') }}

# Cache hit: node_modules is copied from a previous run. Run copy-fonts
- if: steps.cache-nodemodules.outputs.cache-hit == 'true'
name: Run copy-fonts (if using cached node_modules)
# Cache hit: If the cache key matches,
# /node_modules/ will have been copied from a previous run.
# (Run the post-install step, `npm run copy-fonts`)
- name: Run copy-fonts (if using cached node_modules)
if: steps.cache-nodemodules.outputs.cache-hit == 'true'
run: npm run copy-fonts

# Cache miss: Run npm install, which does copy-fonts as post-install step
- if: steps.cache-nodemodules.outputs.cache-hit != 'true'
name: Install JavaScript dependencies (npm install)
# Cache miss: If node_modules has not been cached,
# `npm install`
# (This includes `npm run copy-fonts` as post-install step)
- name: Install JavaScript dependencies (npm install)
if: steps.cache-nodemodules.outputs.cache-hit != 'true'
run: npm install

# Build the app!
# Check that the full build succeeds
- name: Build Prod
run: SKIP_TS_CHECK=true npm run build

# Run TypeScript Checks and ESLint
- name: Check TypeScript # Separated for visibility
# Check for TypeScript errors
- name: Check TypeScript
run: npm run check-types

# Check for ESLint messages (errors only)
- name: Check ESLint, errors only
run: npm run lint -- --quiet

# Unit Tests
- name: Build Tests
run: npx webpack --config webpack/test.config.js
# Run the Unit test suite (formbuilder and helpers)
- name: Run unit tests and xlform tests
run: npx jest --config ./jsapp/jest/unit.config.ts --ci

- name: Run Tests, with mocha-chrome
run: npx mocha-chrome test/tests.html --chrome-launcher.connectionPollInterval=5000
# This step takes less than 1 minute if it succeeds, but will hang for
# 6 hours if it fails with 'No inspectable targets'
# Timeout early to make it easier to manually re-run jobs.
# Tracking issue: https://github.com/kobotoolbox/kpi/issues/4337
timeout-minutes: 1
# Run the Jest test suite (React components)
- name: Run component tests with Jest
run: npx jest --config ./jsapp/jest/jest.config.ts --ci

- name: Run components tests with Jest
run: npm run jest
15 changes: 9 additions & 6 deletions hub/admin/extend_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from kobo.apps.trash_bin.models.account import AccountTrash
from kobo.apps.trash_bin.utils import move_to_trash
from kpi.models.asset import AssetDeploymentStatus

from .filters import UserAdvancedSearchFilter
from .mixins import AdvancedSearchMixin

Expand Down Expand Up @@ -167,9 +168,7 @@ class ExtendedUserAdmin(AdvancedSearchMixin, UserAdmin):
actions = ['remove', 'delete']

class Media:
css = {
'all': ('admin/css/inline_as_fieldset.css',)
}
css = {'all': ('admin/css/inline_as_fieldset.css',)}

@admin.action(description='Remove selected users (delete everything but their username)')
def remove(self, request, queryset, **kwargs):
Expand Down Expand Up @@ -293,9 +292,13 @@ def _filter_queryset_for_organization_user(self, queryset):
"""
Displays only users whose organization has a single member.
"""
return queryset.annotate(
user_count=Count('organizations_organization__organization_users')
).filter(user_count__lte=1).order_by('username')
return (
queryset.annotate(
user_count=Count('organizations_organization__organization_users')
)
.filter(user_count__lte=1)
.order_by('username')
)

def _remove_or_delete(
self,
Expand Down
44 changes: 44 additions & 0 deletions jsapp/jest/coffeeTransformer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const coffeescript = require('coffeescript');
const createCacheKeyFunction = require('@jest/create-cache-key-function').default;
/**
* @typedef {import('@jest/transform').SyncTransformer} SyncTransformer
* @typedef {import('@jest/transform').TransformedSource} TransformedSource
*/

/**
* Transform CoffeeScript files for Jest
* See: https://jestjs.io/docs/code-transformation
*
* @implements { SyncTransformer }
*/
module.exports = {
/**
* Process coffee files
*
* @param {string} sourceText
* @param {string} filename
* @returns {TransformedSource}
*/
process(sourceText, filename) {
const {js, sourceMap, v3SourceMap } = coffeescript.compile(
sourceText,
// ☕ CoffeeScript 1.12.7 compiler options
{
// 📜 For source maps
filename,
sourceMap: true,

// 📦 Same default as coffee-loader
bare: true,
}
);
return {
code: js,
map: JSON.parse(v3SourceMap),
};
},

getCacheKey: createCacheKeyFunction(
[__filename, require.resolve('coffeescript')],
),
};
17 changes: 17 additions & 0 deletions jsapp/jest/setupUnitTest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import chai from 'chai';
import $ from 'jquery';

// Polyfill global fetch (for Node 20 and older)
import 'whatwg-fetch';

// Add global t() mock (see /static/js/global_t.js)
global.t = (str: string) => str;

// @ts-expect-error: ℹ️ Add chai global for BDD-style tests
global.chai = chai;

// @ts-expect-error: ℹ️ Use chai's version of `expect`
global.expect = chai.expect;

// @ts-expect-error: ℹ️ Add jQuery globals for xlform code
global.jQuery = global.$ = $;
58 changes: 58 additions & 0 deletions jsapp/jest/unit.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import type {Config} from 'jest';
import {defaults} from 'jest-config';

// Config to run ☕ unit tests using the Jest runner
//
// To run the unit tests: 🏃
//
// npx jest --config ./jsapp/jest/unit.config.ts
//

const config: Config = {
// Naming convention (*.tests.*)
testMatch: ['**/?(*.)+(tests).(js|jsx|ts|tsx|es6|coffee)'],

// Where to find tests. <rootDir> = 'kpi/jsapp/jest'
roots: [
'<rootDir>/../js/', // unit tests 🛠️ 'jsapp/js/**/*.tests.{ts,es6}'
'<rootDir>/../../test/', // xlform/coffee ☕ 'test/**/*.tests.coffee'
],

// Where to resolve module imports
moduleNameMapper: {
// ℹ️ same aliases as in webpack.common.js (module.resolve.alias)
'^jsapp/(.+)$': '<rootDir>/../$1', // 📁 'jsapp/*'
'^js/(.*)$': '<rootDir>/../js/$1', // 📁 'js/*'
'^test/(.*)$': '<rootDir>/../../test/$1', // 📁 'test/*'
'^utils$': '<rootDir>/../js/utils', // 📄 'utils'
// 🎨 mock all CSS modules imported (styles.root = 'root')
'\\.(css|scss)$': 'identity-obj-proxy',
},

// Extensions to try in order (for import statements with no extension)
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'es6', 'coffee'],

// Transformers (SWC for JS/TS, CoffeeScript for .coffee)
transform: {
'^.+\\.(js|jsx|ts|tsx|es6)$': '@swc/jest',
'^.+\\.coffee$': '<rootDir>/coffeeTransformer.js',
},

// Exclude these files, even if they contain tests
testPathIgnorePatterns: [
'test/xlform/integration.tests.coffee$', // 📄 skipped in `ee98aebe631b`
...defaults.testPathIgnorePatterns, // 📦 exclude '/node_modules/'
],

// Set up test environment
testEnvironment: 'jsdom',

// Make Chai and jQuery globals available in the test environment
setupFilesAfterEnv: ['<rootDir>/setupUnitTest.ts'],

// Appearance options (for console output)
verbose: true,
displayName: {name: 'UNIT', color: 'black'},
};

export default config;
7 changes: 3 additions & 4 deletions jsapp/js/account/accountSidebar.module.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
@use 'scss/colors';

.accountSidebar {
margin-top: 10px;
padding: 14px 20px 20px 0;
padding: 24px 20px 20px 0;
overflow-y: auto;
overflow-x: hidden;
flex: 1;
Expand Down Expand Up @@ -33,7 +32,7 @@
color: inherit;
padding: 0 0 0 18px !important;
border-left: 3px solid transparent;
margin-bottom: 18px;
margin-bottom: 16px;
cursor: pointer;

.newLinkLabelText {
Expand All @@ -59,7 +58,7 @@
}

.subhead {
padding: 0 0 0 18px !important;
padding: 0 0 0 20px !important;
margin-bottom: 16px;
font-size: 12px;
font-weight: 600;
Expand Down
Loading

0 comments on commit ab52d05

Please sign in to comment.