Skip to content

Commit 852b4b7

Browse files
committed
Merge branch 'develop'
2 parents 08dcc47 + 3741d3e commit 852b4b7

28 files changed

+843
-120
lines changed

.github/workflows/integrate-and-deploy.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,22 @@ jobs:
4848
node-version: '16.14.0'
4949
cache: 'npm'
5050
-
51-
run: npm install
51+
run: npm ci
5252
-
5353
name: Build app
5454
run: docker-compose build --build-arg ENVIRONMENT=production --build-arg BUILD_VERSION=${{ steps.image.outputs.TAG }} app
5555
-
5656
run: docker-compose run --rm app cat /var/www/html/build-version.txt /var/www/html/version.php
5757
-
58-
name: Check unit tests
58+
name: Unit Tests
5959
run: make unit-tests-ci
60-
# -
61-
# name: Check e2e tests
62-
# run: make e2e-tests-ci
60+
-
61+
name: Playwright E2E Tests
62+
working-directory: .
63+
run: |
64+
docker-compose -f docker/docker-compose.yml up -d app-for-playwright
65+
npx playwright install
66+
npx playwright test
6367
-
6468
name: Log in to Docker Hub
6569
uses: docker/login-action@v1

.github/workflows/pull-request.yml

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
-
2121
uses: actions/checkout@v2
2222
-
23-
name: Run Unit Tests
23+
name: Unit Tests
2424
run: make unit-tests-ci
2525
-
2626
name: Publish Test Results
@@ -31,7 +31,7 @@ jobs:
3131
github_token: ${{ github.token }}
3232
files: docker/PhpUnitTests.xml
3333

34-
build-app:
34+
build-app-run-e2e-tests:
3535
runs-on: ubuntu-latest
3636

3737
steps:
@@ -43,11 +43,20 @@ jobs:
4343
node-version: '16.14.0'
4444
cache: 'npm'
4545
-
46-
run: npm install
46+
name: Build app
47+
run: |
48+
npm ci
49+
docker-compose build app
4750
-
48-
run: docker-compose build app
51+
name: Playwright E2E Tests
52+
working-directory: .
53+
# see https://playwright.dev/docs/ci#github-actions
54+
run: |
55+
docker-compose -f docker/docker-compose.yml up -d app-for-playwright
56+
npx playwright install
57+
npx playwright test
4958
50-
# e2e-tests:
59+
# protractor-tests:
5160
# runs-on: ubuntu-latest
5261

5362
# steps:

.github/workflows/set-backlog-fields.yml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
types: [ opened ]
66

77
jobs:
8-
steve:
8+
add_issue_to_project:
99
if: ${{ !github.event.issue.pull_request }}
1010
runs-on: ubuntu-latest
1111
steps:
@@ -15,18 +15,18 @@ jobs:
1515
with:
1616
app_id: ${{ secrets.LFPROJECTBOARDAUTOMATION_APP_ID }}
1717
private_key: ${{ secrets.LFPROJECTBOARDAUTOMATION_PRIVATE_KEY }}
18-
18+
1919
- name: determine if issue is already on a project
2020
env:
21-
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
2221
ISSUE_NUMBER: ${{ github.event.issue.number }}
2322
REPO: ${{ toJson(github.event.repository.name) }}
2423
ORGANIZATION: sillsdev
24+
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
2525
run: |
2626
echo issue $ISSUE_NUMBER added to $REPO
2727
2828
gh api graphql -f query='
29-
query($issue_number:Int!, $org:ID!) {
29+
query($issue_number:Int!, $org:String!) {
3030
repository(name:"web-languageforge", owner:$org) {
3131
issue(number: $issue_number) {
3232
id
@@ -42,6 +42,9 @@ jobs:
4242
echo 'IN_PROJECT='$(jq '.data.repository.issue.projectNextItems[] | length' project_data.json) >> $GITHUB_ENV
4343
4444
- name: get required info for set operations
45+
env:
46+
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
47+
ORGANIZATION: sillsdev
4548
run: |
4649
gh api graphql -f query='
4750
query($org: String!) {
@@ -60,12 +63,13 @@ jobs:
6063
}' -f org=$ORGANIZATION > project_data.json
6164
6265
echo 'PROJECT_ID='$(jq '.data.organization.projectNext.id' project_data.json) >> $GITHUB_ENV
63-
echo 'FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Backlog") | .id' project_data.json) >> $GITHUB_ENV
64-
echo 'TRIAGE_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Backlog") | .settings | fromjson.options[] | select(.name=="Triage") | .id' project_data.json) >> $GITHUB_ENV
66+
echo 'FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "ProductOwner") | .id' project_data.json) >> $GITHUB_ENV
67+
echo 'TRIAGE_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "ProductOwner") | .settings | fromjson.options[] | select(.name=="Triage") | .id' project_data.json) >> $GITHUB_ENV
6568
6669
- name: Add issue to project
6770
if: env.IN_PROJECT == 0
6871
env:
72+
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
6973
ISSUE_ID: ${{ github.event.issue.node_id }} #use ITEM_ID instead for finding on projects
7074
run: |
7175
item_id="$( gh api graphql -f query='
@@ -79,8 +83,10 @@ jobs:
7983
8084
echo 'ITEM_ID='$item_id >> $GITHUB_ENV
8185
82-
- name: set Backlog field
86+
- name: set project field
8387
if: env.IN_PROJECT == 0
88+
env:
89+
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
8490
run: |
8591
gh api graphql -f query='
8692
mutation(

.vscode/extensions.json

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22
// See http://go.microsoft.com/fwlink/?LinkId=827846
33
// for the documentation about the extensions.json format
44
"recommendations": [
5-
"JuanCasanova.awesometypescriptproblemmatcher",
6-
"msjsdiag.debugger-for-chrome",
7-
"ms-vscode-remote.remote-containers",
8-
"EditorConfig.editorconfig",
9-
"felixfbecker.php-pack",
10-
"dbaeumer.vscode-eslint",
11-
"emallin.phpunit"
12-
]
5+
"juancasanova.awesometypescriptproblemmatcher",
6+
"msjsdiag.debugger-for-chrome",
7+
"ms-vscode-remote.remote-containers",
8+
"editorconfig.editorconfig",
9+
"dbaeumer.vscode-eslint",
10+
"xdebug.php-pack"
11+
]
1312
}

package-lock.json

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

playwright.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const config: PlaywrightTestConfig = {
3030
/* Opt out of parallel tests on CI. */
3131
workers: process.env.CI ? 1 : undefined,
3232
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
33-
reporter: 'html',
33+
reporter: process.env.CI ? 'github' : 'html',
3434
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
3535
use: {
3636
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */

src/Api/Model/Shared/DeepDiff/DeepDiffDecoder.php

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -72,18 +72,47 @@ public static function applySingleDiff($model, $diff)
7272
$path = $diff->path;
7373
$allButLast = $path; // This is a copy
7474
$last = array_pop($allButLast);
75-
$isLexValue = false;
76-
if ($last === 'value') {
77-
$isLexValue = true;
78-
$last = array_pop($allButLast);
79-
}
8075
$target = $model;
76+
$value = $diff->getValue();
77+
$customFieldsIdx = array_search('customFields', $allButLast, true);
78+
$customFieldData = [];
79+
if ($customFieldsIdx !== false && $customFieldsIdx+2 <= count($path)) {
80+
// Custom fields need special handling
81+
$allButLast = array_slice($path, 0, $customFieldsIdx+2);
82+
$customFieldName = $path[$customFieldsIdx+1];
83+
$rest = array_slice($path, $customFieldsIdx+2);
84+
foreach (\array_reverse($rest) as $step) {
85+
$customFieldData = [$step => $customFieldData];
86+
}
87+
}
88+
// Custom fields need to call MapOf->generate() with a specific shape in order to work:
89+
// For LexValue fields (list fields with a single value): ['value' => (anything)]
90+
// For LexMultiValue fields (list fields where you can choose multiple values): ['values' => (anything)]
91+
// For LexMultiParagraph fields: ['paragraphs' => (anything)] *or* ['type' => 'multiparagraph']
92+
// For LexMultiText fields: ['en' => ['value' => (anything)]], where any writing system can be in place of 'en' here
93+
94+
// The tricky part is distinguishing LexMultiText fields from LexValue fields, hence the slightly-convoluted construction of $customFieldData
95+
96+
$prevStep = '';
8197
foreach ($allButLast as $step) {
82-
$target = static::getNextStep($target, $step);
98+
if ($prevStep === 'customFields') {
99+
$target = static::getCustomFieldStep($target, $step, $customFieldData);
100+
} else {
101+
$target = static::getNextStep($target, $step, $last, $value);
102+
}
103+
if ($target instanceof \Api\Model\Languageforge\Lexicon\LexMultiText && $last === 'value') {
104+
// For MultiText fields, we need $last to be NEXT-to-last step (the writing system), not "value"
105+
$last = $path[count($path) - 2];
106+
// $last = $step;
107+
break;
108+
}
109+
// For a custom single-line MultiText field: [customFields, cf_entry_Cust_Single_Line, en, value] and value is "what was typed"
110+
// For a custom list field, [customFields, cf_entry_Cust_Single_ListRef, value] and value is "what was selected"
111+
$prevStep = $step;
83112
}
84113
if ($diff instanceof ArrayDiff) {
85114
if ($diff->item['kind'] == 'N') {
86-
static::pushValue($target, $last, $diff->getValue());
115+
static::pushValue($target, $last, $value);
87116
} elseif ($diff->item['kind'] == 'D') {
88117
if ($target instanceof \ArrayObject) {
89118
array_pop($target[$last]);
@@ -94,25 +123,23 @@ public static function applySingleDiff($model, $diff)
94123
// Invalid ArrayDiff; do nothing
95124
}
96125
} else {
97-
static::setValue($target, $last, $diff->getValue());
126+
static::setValue($target, $last, $value);
98127
// TODO: Verify that this works as desired for deletions
99128
}
100129
}
101130

131+
private static function getCustomFieldStep($target, $step, $customFieldData) {
132+
if (isset($target[$step])) {
133+
return $target[$step];
134+
} else {
135+
$object = $target->generate($customFieldData);
136+
$target[$step] = $object;
137+
return $object;
138+
}
139+
}
140+
102141
private static function getNextStep($target, $step) {
103-
if ($target instanceof \Api\Model\Shared\Mapper\MapOf && strpos($step, 'customField_') === 0) {
104-
// Custom fields should be created if they do not exist
105-
if (isset($target[$step])) {
106-
return $target[$step];
107-
} else {
108-
if ($target->hasGenerator()) {
109-
return $target->generate([$step]);
110-
} else {
111-
// This will probably fail
112-
return $target[$step];
113-
}
114-
}
115-
} else if ($target instanceof \ArrayObject) {
142+
if ($target instanceof \ArrayObject) {
116143
return $target[$step];
117144
} else {
118145
return $target->$step;
@@ -122,10 +149,16 @@ private static function getNextStep($target, $step) {
122149
private static function setValue(&$target, $last, $value) {
123150
if ($target instanceof \Api\Model\Languageforge\Lexicon\LexMultiText) {
124151
$target->form($last, $value);
152+
} else if ($target instanceof \Api\Model\Languageforge\Lexicon\LexValue) {
153+
$target->value($value); // TODO: Test this
125154
} else if ($target instanceof \ArrayObject) {
126155
$target[$last] = $value;
127156
} else {
128-
$target->$last = $value;
157+
if ($target->$last instanceof \Api\Model\Languageforge\Lexicon\LexValue) {
158+
$target->$last->value($value);
159+
} else {
160+
$target->$last = $value;
161+
}
129162
}
130163
}
131164

0 commit comments

Comments
 (0)