Skip to content

Commit

Permalink
Merge branch 'main' into feat/podmanSupport
Browse files Browse the repository at this point in the history
  • Loading branch information
framitdavid authored Feb 12, 2024
2 parents 6a45cdf + fb9e666 commit c93c90f
Show file tree
Hide file tree
Showing 252 changed files with 5,904 additions and 4,842 deletions.
672 changes: 336 additions & 336 deletions .yarn/releases/yarn-4.0.2.cjs → .yarn/releases/yarn-4.1.0.cjs
100644 → 100755

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ enableTelemetry: false

nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-4.0.2.cjs
yarnPath: .yarn/releases/yarn-4.1.0.cjs
4 changes: 2 additions & 2 deletions backend/packagegroups/NuGet.props
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<PackageReference Update="Yuniql.AspNetCore" Version="1.2.25" />
<PackageReference Update="Yuniql.PostgreSql" Version="1.3.15" />
<PackageReference Update="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Update="Polly" Version="8.2.1" />
<PackageReference Update="Polly" Version="8.3.0" />
<PackageReference Update="Altinn.Authorization.ABAC" Version="0.0.7" />
<PackageReference Update="Altinn.ApiClients.Maskinporten" Version="9.1.0" />
<PackageReference Update="MediatR" Version="12.2.0" />
Expand All @@ -43,7 +43,7 @@
<ItemGroup Label="Packages used for testing">
<PackageReference Update="FluentAssertions" Version="6.12.0" />
<PackageReference Update="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.26" />
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<!-- Do not upgrade Moq version from 4.18.4 -->
<PackageReference Update="Moq" Version="4.18.4" />
<PackageReference Update="xunit" Version="2.6.6" />
Expand Down
4 changes: 2 additions & 2 deletions backend/src/Designer/Controllers/ResourceAdminController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,10 @@ public async Task<ActionResult<ServiceResource>> AddResource(string org, [FromBo
public async Task<ActionResult> ImportResource(string org, string serviceCode, int serviceEdition, string environment, [FromBody] string resourceId)
{
string repository = string.Format("{0}-resources", org);
ServiceResource resource = await _altinn2MetadataClient.GetServiceResourceFromService(serviceCode, serviceEdition, environment);
ServiceResource resource = await _resourceRegistry.GetServiceResourceFromService(serviceCode, serviceEdition, environment);
resource.Identifier = resourceId;
_repository.AddServiceResource(org, resource);
XacmlPolicy policy = await _altinn2MetadataClient.GetXacmlPolicy(serviceCode, serviceEdition, resource.Identifier, environment);
XacmlPolicy policy = await _resourceRegistry.GetXacmlPolicy(serviceCode, serviceEdition, resource.Identifier, environment);
await _repository.SavePolicy(org, repository, resource.Identifier, policy);
return Ok(resource);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Xml;
using Altinn.ApiClients.Maskinporten.Interfaces;
using Altinn.ApiClients.Maskinporten.Models;
using Altinn.Authorization.ABAC.Utils;
using Altinn.Authorization.ABAC.Xacml;
using Altinn.Studio.Designer.Configuration;
using Altinn.Studio.Designer.Exceptions;
using Altinn.Studio.Designer.Helpers;
Expand Down Expand Up @@ -252,6 +255,37 @@ public async Task<List<ServiceResource>> GetResourceList(string env)
}
}

public async Task<ServiceResource> GetServiceResourceFromService(string serviceCode, int serviceEditionCode, string environment)
{
string resourceRegisterUrl = GetResourceRegistryBaseUrl(environment);
string url = $"{resourceRegisterUrl}/resourceregistry/api/v1/altinn2export/resource/?serviceCode={serviceCode}&serviceEditionCode={serviceEditionCode}";

HttpResponseMessage response = await _httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();

string contentString = await response.Content.ReadAsStringAsync();
ServiceResource serviceResource = JsonSerializer.Deserialize<ServiceResource>(contentString, _serializerOptions);
return serviceResource;
}

public async Task<XacmlPolicy> GetXacmlPolicy(string serviceCode, int serviceEditionCode, string identifier, string environment)
{
string resourceRegisterUrl = GetResourceRegistryBaseUrl(environment);
string url = $"{resourceRegisterUrl}/resourceregistry/api/v1/altinn2export/policy/?serviceCode={serviceCode}&serviceEditionCode={serviceEditionCode}&resourceIdentifier={identifier}";

HttpResponseMessage response = await _httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();

string contentString = await response.Content.ReadAsStringAsync();
XacmlPolicy policy;
using (XmlReader reader = XmlReader.Create(new StringReader(contentString)))
{
policy = XacmlParser.ParseXacmlPolicy(reader);
}

return policy;
}

private async Task<TokenResponse> GetBearerTokenFromMaskinporten()
{
return await _maskinPortenService.GetToken(_maskinportenClientDefinition.ClientSettings.EncodedJwk, _maskinportenClientDefinition.ClientSettings.Environment, _maskinportenClientDefinition.ClientSettings.ClientId, _maskinportenClientDefinition.ClientSettings.Scope, _maskinportenClientDefinition.ClientSettings.Resource, _maskinportenClientDefinition.ClientSettings.ConsumerOrgNo);
Expand Down
11 changes: 11 additions & 0 deletions backend/src/Designer/Services/Interfaces/IResourceRegistry.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Altinn.Authorization.ABAC.Xacml;
using Altinn.Studio.Designer.Models;
using Microsoft.AspNetCore.Mvc;

Expand Down Expand Up @@ -35,5 +36,15 @@ public interface IResourceRegistry
/// </summary>
/// <returns>The resource full list of all resources if exists</returns>
Task<List<ServiceResource>> GetResourceList(string env);

/// <summary>
/// Get Resource from Altinn 2 service
/// </summary>
Task<ServiceResource> GetServiceResourceFromService(string serviceCode, int serviceEditionCode, string environment);

/// <summary>
/// Get Policy from Altinn 2 Service
/// </summary>
Task<XacmlPolicy> GetXacmlPolicy(string serviceCode, int serviceEditionCode, string identifier, string environment);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Net.Http;
using System.Threading.Tasks;
using Altinn.ResourceRegistry.Core.Models.Altinn2;
using Altinn.Studio.Designer.Models;
using Microsoft.AspNetCore.Mvc.Testing;
using Moq;
using Xunit;
Expand Down Expand Up @@ -36,7 +37,7 @@ public async Task GetFilteredLinkServices()
ExternalServiceCode = "Test2",
ExternalServiceEditionCode = 123
});

ResourceRegistryMock.Setup(r => r.GetResourceList(It.IsAny<string>())).ReturnsAsync(new List<ServiceResource>());
Altinn2MetadataClientMock.Setup(r => r.AvailableServices(It.IsAny<int>(), It.IsAny<string>())).ReturnsAsync(services);

// Act
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ public async Task ExportAltinn2Resource()

XacmlPolicy policy = AuthorizationUtil.ParsePolicy("resource_registry_delegatableapi.xml");

Altinn2MetadataClientMock.Setup(r => r.GetServiceResourceFromService(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<string>())).ReturnsAsync(serviceResource);
Altinn2MetadataClientMock.Setup(r => r.GetXacmlPolicy(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<string>())).ReturnsAsync(policy);
ResourceRegistryMock.Setup(r => r.GetServiceResourceFromService(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<string>())).ReturnsAsync(serviceResource);
ResourceRegistryMock.Setup(r => r.GetXacmlPolicy(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<string>(), It.IsAny<string>())).ReturnsAsync(policy);

// Act
using HttpResponseMessage res = await HttpClient.SendAsync(httpRequestMessage);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public abstract class ResourceAdminControllerTestsBaseClass<TTesetClass> : Disag
{
protected readonly string VersionPrefix = "/designer/api";
protected readonly Mock<IRepository> RepositoryMock;
protected readonly Mock<IResourceRegistry> ResourceRegistryMock;
protected readonly Mock<IAltinn2MetadataClient> Altinn2MetadataClientMock;

protected override void ConfigureTestServices(IServiceCollection services)
Expand All @@ -25,12 +26,14 @@ protected override void ConfigureTestServices(IServiceCollection services)
c.RepositoryLocation = TestRepositoriesLocation);
services.AddSingleton<IGitea, IGiteaMock>();
services.AddTransient(_ => RepositoryMock.Object);
services.AddTransient(_ => ResourceRegistryMock.Object);
services.AddTransient(_ => Altinn2MetadataClientMock.Object);
}

protected ResourceAdminControllerTestsBaseClass(WebApplicationFactory<Program> factory) : base(factory)
{
RepositoryMock = new Mock<IRepository>();
ResourceRegistryMock = new Mock<IResourceRegistry>();
Altinn2MetadataClientMock = new Mock<IAltinn2MetadataClient>();
}

Expand Down
2 changes: 1 addition & 1 deletion development/azure-devops-mock/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"version": "1.0.0",
"author": "The Altinn Studio Team",
"dependencies": {
"axios": "1.6.5",
"axios": "1.6.7",
"cors": "2.8.5",
"express": "4.18.2",
"morgan": "1.10.0",
Expand Down
33 changes: 24 additions & 9 deletions development/utils/wait-for.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,37 @@
const { get } = require('http');
module.exports = (url) =>
new Promise(function (resolve, reject) {
let attemts = 0;
let attempts = 0;

const checkAttempts = () => {
attempts++;
if (attempts > 10) {
clearInterval(intervalId);
console.log('Giving up: ', url);
reject('Giving up this');
} else {
console.log('Waiting for:', url);
}
};

const intervalId = setInterval(function () {
get(url, (res) => {
const req = get(url, (res) => {
if (res.statusCode === 200) {
console.log(url, ' is up!');
clearInterval(intervalId);
resolve();
} else {
console.log('Waiting for:', url);
checkAttempts();
}
if (attemts > 10) {
clearInterval(intervalId);
console.log('Giving up: ', url);
reject('Giving up this');
});

req.on('error', (err) => {
if (err.code !== 'ECONNREFUSED') {
console.error(err);
reject();
} else {
checkAttempts();
}
attemts++;
}).end();
});
}, 1000);
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,37 @@ import type { ServicesContextProps } from 'app-shared/contexts/ServicesContext';
import { act, screen, waitFor, waitForElementToBeRemoved } from '@testing-library/react';
import { textMock } from '../../../../testing/mocks/i18nMock';
import { createQueryClientMock } from 'app-shared/mocks/queryClientMock';
import { datamodelNameMock } from 'app-shared/mocks/datamodelMetadataMocks';
import {
createJsonMetadataMock,
createXsdMetadataMock,
} from 'app-shared/mocks/datamodelMetadataMocks';
import userEvent from '@testing-library/user-event';
import { dataMock } from '@altinn/schema-editor/mockData';
import { AUTOSAVE_DEBOUNCE_INTERVAL_MILLISECONDS } from 'app-shared/constants';
import type { SchemaEditorAppProps } from '@altinn/schema-editor/SchemaEditorApp';
import { QueryKey } from 'app-shared/types/QueryKey';
import { createApiErrorMock } from 'app-shared/mocks/apiErrorMock';
import { createJsonModelPathMock } from 'app-shared/mocks/modelPathMocks';
import type {
DatamodelMetadataJson,
DatamodelMetadataXsd,
} from 'app-shared/types/DatamodelMetadata';
import { verifyNeverOccurs } from '../../../../testing/testUtils';

const user = userEvent.setup();

// Test data:
const modelPath = datamodelNameMock;
const model1Name = 'model1';
const model2name = 'model2';
const model1Path = createJsonModelPathMock(model1Name);
const model2Path = createJsonModelPathMock(model2name);
const model1MetadataJson: DatamodelMetadataJson = createJsonMetadataMock(model1Name);
const model1MetadataXsd: DatamodelMetadataXsd = createXsdMetadataMock(model1Name);
const model2MetadataJson: DatamodelMetadataJson = createJsonMetadataMock(model2name);
const model2MetadataXsd: DatamodelMetadataXsd = createXsdMetadataMock(model2name);

const defaultProps: SelectedSchemaEditorProps = {
modelPath,
modelPath: model1Path,
};
const org = 'org';
const app = 'app';
Expand Down Expand Up @@ -72,6 +89,7 @@ describe('SelectedSchemaEditor', () => {
const getDatamodel = jest.fn().mockImplementation(() => Promise.resolve(dataMock));

render({ getDatamodel, saveDatamodel });

await waitForElementToBeRemoved(() => screen.queryByTitle(textMock('general.loading')));

const button = screen.getByTestId(saveButtonTestId);
Expand All @@ -80,7 +98,7 @@ describe('SelectedSchemaEditor', () => {

act(() => jest.advanceTimersByTime(AUTOSAVE_DEBOUNCE_INTERVAL_MILLISECONDS));
await waitFor(() => expect(saveDatamodel).toHaveBeenCalledTimes(1));
expect(saveDatamodel).toHaveBeenCalledWith(org, app, modelPath, dataMock);
expect(saveDatamodel).toHaveBeenCalledWith(org, app, model1Path, dataMock);
});

it('Autosaves when changing between models that are not present in the cache', async () => {
Expand All @@ -92,22 +110,19 @@ describe('SelectedSchemaEditor', () => {
await waitForElementToBeRemoved(() => screen.queryByTitle(textMock('general.loading')));
expect(saveDatamodel).not.toHaveBeenCalled();

const updatedProps = {
...defaultProps,
modelPath: 'newModel',
};
const updatedProps = { ...defaultProps, modelPath: model2Path };
rerender(<SelectedSchemaEditor {...updatedProps} />);
jest.advanceTimersByTime(AUTOSAVE_DEBOUNCE_INTERVAL_MILLISECONDS);
await waitFor(() => expect(saveDatamodel).toHaveBeenCalledTimes(1));
expect(saveDatamodel).toHaveBeenCalledWith(org, app, datamodelNameMock, dataMock);
expect(saveDatamodel).toHaveBeenCalledWith(org, app, model1Path, dataMock);
});

it('Autosaves when changing between models that are already present in the cache', async () => {
const saveDatamodel = jest.fn();
const queryClient = createQueryClientMock();
const newModelPath = 'newModel';
queryClient.setQueryData([QueryKey.JsonSchema, org, app, datamodelNameMock], dataMock);
queryClient.setQueryData([QueryKey.JsonSchema, org, app, newModelPath], dataMock);
queryClient.setQueryData([QueryKey.JsonSchema, org, app, model1Path], dataMock);
queryClient.setQueryData([QueryKey.JsonSchema, org, app, model1Path], dataMock);
const {
renderResult: { rerender },
} = render({ saveDatamodel }, queryClient);
Expand All @@ -120,17 +135,48 @@ describe('SelectedSchemaEditor', () => {
rerender(<SelectedSchemaEditor {...updatedProps} />);
jest.advanceTimersByTime(AUTOSAVE_DEBOUNCE_INTERVAL_MILLISECONDS);
await waitFor(() => expect(saveDatamodel).toHaveBeenCalledTimes(1));
expect(saveDatamodel).toHaveBeenCalledWith(org, app, datamodelNameMock, dataMock);
expect(saveDatamodel).toHaveBeenCalledWith(org, app, model1Path, dataMock);
});

it('Does not save when model is deleted', async () => {
const saveDatamodel = jest.fn();
const queryClient = createQueryClientMock();

queryClient.setQueryData([QueryKey.JsonSchema, org, app, model1Path], dataMock);
queryClient.setQueryData([QueryKey.JsonSchema, org, app, model2Path], dataMock);
const {
renderResult: { rerender },
} = render({ saveDatamodel }, queryClient);
expect(saveDatamodel).not.toHaveBeenCalled();

const updatedProps = {
...defaultProps,
modelPath: model2Path,
};
queryClient.setQueryData([QueryKey.DatamodelsJson, org, app], [model2MetadataJson]);
queryClient.setQueryData([QueryKey.DatamodelsXsd, org, app], [model2MetadataXsd]);
rerender(<SelectedSchemaEditor {...updatedProps} />);
jest.advanceTimersByTime(AUTOSAVE_DEBOUNCE_INTERVAL_MILLISECONDS);
await verifyNeverOccurs(() => expect(saveDatamodel).toHaveBeenCalled());
});
});

const render = (
queries: Partial<ServicesContextProps> = {},
queryClient = createQueryClientMock(),
props: Partial<SelectedSchemaEditorProps> = {},
) =>
renderWithMockStore(
) => {
queryClient.setQueryData(
[QueryKey.DatamodelsJson, org, app],
[model1MetadataJson, model2MetadataJson],
);
queryClient.setQueryData(
[QueryKey.DatamodelsXsd, org, app],
[model1MetadataXsd, model2MetadataXsd],
);
return renderWithMockStore(
{},
queries,
queryClient,
)(<SelectedSchemaEditor {...defaultProps} {...props} />);
};
Loading

0 comments on commit c93c90f

Please sign in to comment.