Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
ab0899b
initial
bourgeoa Apr 16, 2023
d84ea71
some lint
bourgeoa Apr 16, 2023
ec9e90b
updates
bourgeoa Apr 16, 2023
490a364
getBlankMsg
bourgeoa Apr 16, 2023
1911313
getPrivateKey
bourgeoa Apr 17, 2023
1d8b733
key exists
bourgeoa Apr 17, 2023
6df03c8
add first test
bourgeoa Apr 17, 2023
109c494
resolve typescript issues
bourgeoa Apr 17, 2023
2da93f8
tests generate keys with node crypto in setup
bourgeoa Apr 18, 2023
6c8461c
keys.test.ts
bourgeoa Apr 18, 2023
94b70b5
signature.test.ts
bourgeoa Apr 19, 2023
c5b2fb8
updates
bourgeoa Apr 21, 2023
20175fe
update package-lock.json
bourgeoa Apr 21, 2023
a5809dd
missing awaits
bourgeoa Apr 25, 2023
9f7a01d
package-lock.json
bourgeoa Apr 25, 2023
cd2500d
separated helpers for testing
SharonStrats Apr 26, 2023
5975073
updates message.js
bourgeoa Apr 26, 2023
8ec0833
refactored to smaller parts
SharonStrats Apr 27, 2023
9c84c1e
create keys and improvements
bourgeoa Apr 27, 2023
96e84cf
package-lock.json
bourgeoa Apr 27, 2023
2166356
update keyUrl with space:storage
bourgeoa Apr 29, 2023
eed9bea
add key container ACL
bourgeoa Apr 30, 2023
3652e5c
update setAcl key container
bourgeoa May 1, 2023
c239a13
trying to mock store fetcher load function
SharonStrats May 3, 2023
0ba702c
Update src/chat/keys.ts
bourgeoa May 3, 2023
ef25bb1
adding testing to docs
SharonStrats May 4, 2023
098e8a7
Merge branch 'chat-proof' of https://github.com/SolidOS/solid-ui into…
SharonStrats May 4, 2023
89f16fa
update get podRoot, use NamedNode
bourgeoa May 5, 2023
67289c6
Merge branch 'chat-proof' of https://github.com/solidos/solid-ui into…
bourgeoa May 5, 2023
8eed263
skip failing keys.test.ts
bourgeoa May 5, 2023
11c883a
mocked load
SharonStrats May 6, 2023
beea007
Merge branch 'chat-proof' of https://github.com/SolidOS/solid-ui into…
SharonStrats May 6, 2023
282702e
more cleaning
bourgeoa May 6, 2023
17005e6
Merge branch 'chat-proof' of https://github.com/solidos/solid-ui into…
bourgeoa May 6, 2023
0202734
more NamedNode
bourgeoa May 7, 2023
a6ef582
some cleaning
bourgeoa May 7, 2023
a573676
refactored function names
SharonStrats May 10, 2023
4370b23
added tests
SharonStrats May 10, 2023
0493bdd
Merge branch 'chat-proof' of https://github.com/SolidOS/solid-ui into…
SharonStrats May 10, 2023
69ecfab
created a keyhelper dir
SharonStrats May 10, 2023
18070a0
split files up for easier testing
SharonStrats May 10, 2023
aa51d1d
readmes for testing
SharonStrats May 10, 2023
830468e
key file tests
SharonStrats May 10, 2023
50ca84d
keys testing
SharonStrats May 10, 2023
a1b9ed4
updated testing readme
SharonStrats May 10, 2023
70090f2
added tests
SharonStrats May 17, 2023
27b35f4
acl refactor and tests
SharonStrats May 17, 2023
d02c4c2
key tests
SharonStrats May 17, 2023
f7310cd
fixed broken test
SharonStrats May 17, 2023
85020be
access data test
SharonStrats May 17, 2023
12e3adb
Update test/unit/README.md
SharonStrats May 17, 2023
3f1ead6
Update test/unit/README.md
SharonStrats May 17, 2023
90c87cc
Update test/unit/README.md
SharonStrats May 17, 2023
47a7934
Update test/unit/README.md
SharonStrats May 17, 2023
4bbe4cc
Update test/unit/README.md
SharonStrats May 17, 2023
0a40d64
Update test/unit/README.md
SharonStrats May 17, 2023
ea3f761
Update test/unit/README.md
SharonStrats May 17, 2023
15b7da3
rename deleteKey to deleteKeyAcl
bourgeoa May 18, 2023
7506217
getPodRoot returns NamedNode
bourgeoa May 18, 2023
998e1dd
move privateKey to /settings/keys/privateKey.ttl
bourgeoa May 18, 2023
cb30461
replace pop with slice
bourgeoa May 18, 2023
3576458
Update test/unit/README.md
SharonStrats May 20, 2023
d527997
testing
SharonStrats May 22, 2023
0829883
Merge branch 'chat-proof' of https://github.com/SolidOS/solid-ui into…
SharonStrats May 22, 2023
2da9b5c
remove testing debug msg
SharonStrats May 22, 2023
9ee704c
fix lint error
SharonStrats May 22, 2023
3d362e6
restore PUT on 404
bourgeoa May 24, 2023
027eefb
use solid ontology
bourgeoa May 24, 2023
840c347
removed commented out code
SharonStrats May 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 26 additions & 10 deletions src/chat/keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,33 @@ export async function getPrivateKey (webId: NamedNode) {
return privateKey as string
}

const deleteKey = async (keyDoc: string) => {
await store.fetcher.load(keyDoc)

const keyAclDoc = store.any(store.sym(keyDoc), store.sym('http://www.iana.org/assignments/link-relations/acl'))
if (keyAclDoc) {
// delete READ only keyAclDoc. This is possible if the webId is an owner
try {
const response = await store.fetcher.webOperation('DELETE', keyAclDoc.value) // this may fail if webId is not an owner
debug.log('delete ' + keyAclDoc.value + ' ' + response.status) // should test 404 and 2xx
} catch (err) {
if (err.response.status !== 404) { throw new Error(err) }
debug.log('delete ' + keyAclDoc.value + ' ' + err.response.status) // should test 404 and 2xx
}
}
}

/**
* delete acl if keydoc exists
* create/edit keyDoc
* set keyDoc acl
*/
async function saveKey (keyDoc: string, del, add, me: string = '') {
await store.fetcher.load(keyDoc)
// await store.fetcher.load(keyDoc) //think we can delete this
// delete keyAclDoc
try {
/* try { //here
// get keyAcldoc
const keyAclDoc = store.any(store.sym(keyDoc), store.sym('http://www.iana.org/assignments/link-relations/acl'))
const keyAclDoc = store.any(store.sym(keyDoc), store.sym('http://www.iana.org/assignments/link-relations/acl'))
if (keyAclDoc) {
// delete READ only keyAclDoc. This is possible if the webId is an owner
try {
Expand All @@ -103,12 +119,12 @@ async function saveKey (keyDoc: string, del, add, me: string = '') {
debug.log('delete ' + keyAclDoc.value + ' ' + err.response.status) // should test 404 and 2xx
}
}
*/
await deleteKey(keyDoc)
// save key
await store.updater.updateMany(del, add) // or a promise store.updater.update ?

// save key
await store.updater.updateMany(del, add) // or a promise store.updater.update ?

// create READ only ACL
const aclBody = keyAclBody(keyDoc, me)
await setAcl(keyDoc, aclBody)
} catch (err) { throw new Error(err) }
// create READ only ACL
const aclBody = keyAclBody(keyDoc, me)
await setAcl(keyDoc, aclBody)
}
14 changes: 5 additions & 9 deletions src/utils/keyHelpers/acl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,15 @@ export async function setAcl (keyDoc: string, aclBody: string) {
throw new Error('Key ACL doc not found!')
}

// delete READ only keyAclDoc. This is possible if the webId is an owner
try {
const response = await store.fetcher.webOperation('DELETE', keyAclDoc.value) // this may fail if webId is not an owner
debug.log('delete ' + keyAclDoc.value + ' ' + response.status) // should test 404 and 2xx
await store.fetcher.webOperation('PUT', keyAclDoc.value, {
data: aclBody,
contentType: 'text/turtle'
})
} catch (err) {
if (err.response.status !== 404) { throw new Error(err) }
if (err?.response?.status !== 404) { throw new Error(err) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bourgeoa I'm wondering, if it errors with a 404, should we create the resource in that case?

And otherwise if it errors would it be because the user is not logged in? If so I will mock that data for testing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PUT should never error with 404 so we should remove the if
The reason for failing could be 401 or 403 (not authenticated or not authorized)

debug.log('delete ' + keyAclDoc.value + ' ' + err.response.status) // should test 404 and 2xx
}

const aclResponse = await store.fetcher.webOperation('PUT', keyAclDoc.value, {
data: aclBody,
contentType: 'text/turtle'
})
}

/**
Expand Down
25 changes: 15 additions & 10 deletions test/unit/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Solid-UI Unit Testing
The purpose of this README is to provide guidance on how to write tests for solid-ui for beginners.

Although we would love to have 100% test coverage, we realize that this is not a commericial product. solid-ui is an open source, volunteer built library that houses UI components that can be used to build Solid applications. We are working to increase test coverage on existing code, any help is much appreciated. If you add a new component to solid-ui, you should write tests to test the main functionality of your component in order for your PR to be merged.
Although we would love to have 100% test coverage, we realize that this is not a commericial product. `solid-ui` is an open source, volunteer built library that houses UI components that can be used to build Solid applications. We are working to increase test coverage on existing code, and any help is much appreciated. If you add a new component to `solid-ui`, you should write tests to test the main functionality of your component before your PR will be merged.

## Running Tests

Expand All @@ -10,30 +10,35 @@ The following command will run all the tests.
`npm run test`

### One file at a time
There are a lot of tests in `solid-ui` so you will most likely want to run only the test you are working on at the moment. In order to do that you can use the following command.
There are a lot of tests in `solid-ui`, so you will most likely want to run only the test you are working on at the moment. You can use the commands like the following to do that:
`npm test <filetobetested>`
`npm test test/unit/utils/keyHelpers/accessData.test.ts`

### Coverage
Run the following command:
`npm run coverage`

Then you can see the results in `coverage/lcov-report/index.html`. If you are using VSCode you can right click and select to `Open in Browser Preview`. Otherwise, you can type the path in your browswer, for instance `file:///Users/<yourhomedirectory>/2023Development/solid-ui/coverage/lcov-report/index.html` is an example.
The results will be found in `coverage/lcov-report/index.html`. If you are using VSCode, you can right click and select `Open in Browser Preview`. Alternatively, you can type the path in your browser; for instance, the following:
```
file:///Users/<yourhomedirectory>/2023Development/solid-ui/coverage/lcov-report/index.html
```

## Tips and Tricks
The following are some tips and tricks in hopes to make testing easier.
The following are some tips and tricks to make your testing easier.

### VSCode Debugging
There is an extension that can be used to aide in debugging jest tests. To find out more about it you can look at [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner)
There is an extension that can be used to aide in debugging `jest` tests. To find out more about it, you can look at [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner).

### Mocking
In solid-ui we do not currently follow a MVC pattern therefore there can be some difficulty in testing. The following are patterns to help with this.
In `solid-ui`, we do not currently follow a MVC pattern, so testing is not always easy. The following are patterns to help with this.
#### Store methods
##### Load
In SolidOS we use [rdflib.js](https://github.com/linkeddata/rdflib.js/) to work with LinkedData. The way this works is that you first load the document you need to work with into the store. Once the document is loaded you can then access the data by using additional methods on the store such as `any, each,...`. Since the data that gets returned will need to be mocked, `load` doesn't need to do anything. See below for what you need to put in the top of your file in order to mock the `load` method.
`import { store } from 'solid-logic'` at the top of your file.

`store.fetcher.load = jest.fn().mockImplementation(() => {})`
In SolidOS, we use [`rdflib.js`](https://github.com/linkeddata/rdflib.js/) to work with LinkedData. First, you load the document you need to work with into the store. Once the document is loaded, you can access the data by using additional methods on the store such as `any`, `each`, etc. Since the data that gets returned will need to be mocked, `load` doesn't need to do anything. You need to put the following into your file to mock the `load` method:
```
import { store } from 'solid-logic' /* at the top of your file */
...
store.fetcher.load = jest.fn().mockImplementation(() => {})
```

##### Any

Expand Down
12 changes: 4 additions & 8 deletions test/unit/utils/keyHelpers/accessData.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ describe('cryptoKeyHelpers', () => {
})
describe.skip('privKeyUrl', () => {
it('returns...', () => {
const result = privKeyUrl('https://alice.solid.example/profile/card#me')
const result = privKeyUrl(new NamedNode('https://alice.solid.example/profile/card#me'))
expect(result).toEqual('https://alice.solid.example/profile/keys/privateKey.ttl')
})
})
Expand All @@ -61,20 +61,16 @@ describe('cryptoKeyHelpers', () => {
const result = await getKeyIfExists(webId, PUB_KEY, 'PublicKey')
expect(result).toBe(PUB_KEY)
})
it.skip('does something the key can not be found.. need to ask Alain', async () => {
it.skip('throws an error when load fails', async () => {
// need to check if 'any' can throw an error
const webId = new NamedNode('https://alice.solid.example/profile/card#me')
const result = await getKeyIfExists(webId, 'testing', 'PublicKey')
expect(result).toBe('testing')
})
it.skip('throws an error if the key can not be stored', async () => {
it.skip('returns undefined if key not found', async () => {
const webId = new NamedNode('https://alice.solid.example/profile/card#me')
const result = await getKeyIfExists(webId, PUB_KEY, 'PublicKey')
expect(result).toBe(PUB_KEY)
})
it.skip('throws an error if key is not found', async () => {
const webId = new NamedNode('https://alice.solid.example/profile/card#me')
const result = await getKeyIfExists(webId, 'testing', 'PublicKey')
expect(result).toBe('testing')
})
})
})
27 changes: 23 additions & 4 deletions test/unit/utils/keyHelpers/acl.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,36 @@ import { setAcl, keyAclBody } from '../../../../src/utils/keyHelpers/acl'

store.fetcher.load = jest.fn().mockImplementation(() => {})
store.any = jest.fn()
store.fetcher.webOperation = jest.fn()

const keyDoc = 'https://alice.solidcommunity.net/profile/keys/publicKey.ttl'
const keyAclDoc = 'https://alice.solidcommunity.net/profile/keys/publicKey.ttl'
const error404 = {
response: {
status: 404
}
}

describe('ACL Helpers', () => {
describe('setAcl', () => {
it('throws an error if an ACL document is NOT found', async () => {
/* @ts-ignore */
store.any.mockReturnValue('')
const keyDoc = 'https://alice.solidcommunity.net/profile/keys/publicKey.ttl'
store.any.mockReturnValueOnce('')
await expect(setAcl(keyDoc, keyAclBody(keyDoc, ''))).rejects.toThrowError('Key ACL doc not found!')
})
it.skip('want to find out why we delete and then re-add', () => {

it('throws error if acl can not be written', async () => {
/* @ts-ignore */
store.any.mockReturnValueOnce(keyAclDoc)
/* @ts-ignore */
store.fetcher.webOperation.mockRejectedValueOnce()
await expect(setAcl(keyDoc, keyAclBody(keyDoc, ''))).rejects.toThrowError('')
})
it('continues if error is because acl doc can not be found.', async () => {
/* @ts-ignore */
store.any.mockReturnValueOnce(keyAclDoc)
/* @ts-ignore */
store.fetcher.webOperation.mockRejectedValueOnce(error404)
await expect(setAcl(keyDoc, keyAclBody(keyDoc, ''))).resolves.toBeUndefined
})
})
})