Skip to content

Commit ba6b985

Browse files
committed
fix: add missing nop logic for custom properties plugin
1 parent 1fff61c commit ba6b985

File tree

2 files changed

+169
-123
lines changed

2 files changed

+169
-123
lines changed

lib/plugins/custom_properties.js

Lines changed: 69 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,47 @@
11
const Diffable = require('./diffable')
2+
const NopCommand = require('../nopcommand')
23

34
module.exports = class CustomProperties extends Diffable {
45
constructor (...args) {
56
super(...args)
67

78
if (this.entries) {
8-
// Force all names to lowercase to avoid comparison issues.
9-
this.entries.forEach(prop => {
10-
prop.name = prop.name.toLowerCase()
11-
})
9+
this.normalizeEntries()
1210
}
1311
}
1412

13+
// Force all names to lowercase to avoid comparison issues.
14+
normalizeEntries () {
15+
this.entries = this.entries.map(({ name, value }) => ({
16+
name: name.toLowerCase(),
17+
value
18+
}))
19+
}
20+
1521
async find () {
16-
const data = await this.github.request('GET /repos/:org/:repo/properties/values', {
17-
org: this.repo.owner,
18-
repo: this.repo.repo
19-
})
22+
const { owner, repo } = this.repo
23+
const repoFullName = `${owner}/${repo}`
24+
25+
this.log.debug(`Getting all custom properties for the repo ${repoFullName}`)
26+
27+
const customProperties = await this.github.paginate(
28+
this.github.repos.getCustomPropertiesValues,
29+
{
30+
owner,
31+
repo,
32+
per_page: 100
33+
}
34+
)
35+
this.log.debug(`Found ${customProperties.length} custom properties`)
36+
return this.normalize(customProperties)
37+
}
2038

21-
const properties = data.data.map(d => { return { name: d.property_name, value: d.value } })
22-
return properties
39+
// Force all names to lowercase to avoid comparison issues.
40+
normalize (properties) {
41+
return properties.map(({ property_name: propertyName, value }) => ({
42+
name: propertyName.toLowerCase(),
43+
value
44+
}))
2345
}
2446

2547
comparator (existing, attrs) {
@@ -30,38 +52,47 @@ module.exports = class CustomProperties extends Diffable {
3052
return attrs.value !== existing.value
3153
}
3254

33-
async update (existing, attrs) {
34-
await this.github.request('PATCH /repos/:org/:repo/properties/values', {
35-
org: this.repo.owner,
36-
repo: this.repo.repo,
37-
properties: [{
38-
property_name: attrs.name,
39-
value: attrs.value
40-
}]
41-
})
55+
async update ({ name }, { value }) {
56+
return this.modifyProperty('Update', { name, value })
57+
}
58+
59+
async add ({ name, value }) {
60+
return this.modifyProperty('Create', { name, value })
4261
}
4362

44-
async add (attrs) {
45-
await this.github.request('PATCH /repos/:org/:repo/properties/values', {
46-
org: this.repo.owner,
47-
repo: this.repo.repo,
63+
// Custom Properties on repository does not support deletion, so we set the value to null
64+
async remove ({ name }) {
65+
return this.modifyProperty('Delete', { name, value: null })
66+
}
67+
68+
async modifyProperty (operation, { name, value }) {
69+
const { owner, repo } = this.repo
70+
const repoFullName = `${owner}/${repo}`
71+
72+
const params = {
73+
owner,
74+
repo,
4875
properties: [{
49-
property_name: attrs.name,
50-
value: attrs.value
76+
property_name: name,
77+
value
5178
}]
52-
})
53-
}
79+
}
80+
81+
if (this.nop) {
82+
return new NopCommand(
83+
this.constructor.name,
84+
this.repo,
85+
this.github.repos.createOrUpdateCustomPropertiesValues.endpoint(params),
86+
`${operation} Custom Property`
87+
)
88+
}
5489

55-
async remove (existing) {
56-
await this.github.request('PATCH /repos/:org/:repo/properties/values', {
57-
org: this.repo.owner,
58-
repo: this.repo.repo,
59-
properties: [
60-
{
61-
property_name: existing.name,
62-
value: null
63-
}
64-
]
65-
})
90+
try {
91+
this.log.debug(`${operation} Custom Property "${name}" for the repo ${repoFullName}`)
92+
await this.github.repos.createOrUpdateCustomPropertiesValues(params)
93+
this.log.debug(`Successfully ${operation.toLowerCase()}d Custom Property "${name}" for the repo ${repoFullName}`)
94+
} catch (e) {
95+
this.logError(`Error during ${operation} Custom Property "${name}" for the repo ${repoFullName}: ${e.message || e}`)
96+
}
6697
}
6798
}
Lines changed: 100 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,127 +1,142 @@
11
const CustomProperties = require('../../../../lib/plugins/custom_properties')
22

33
describe('CustomProperties', () => {
4+
const nop = false
45
let github
56
let log
67

8+
const owner = 'test-owner'
9+
const repo = 'test-repo'
10+
711
function configure (config) {
8-
const nop = false
9-
const errors = []
10-
return new CustomProperties(nop, github, { owner: 'bkeepers', repo: 'test' }, config, log, errors)
12+
return new CustomProperties(nop, github, { owner, repo }, config, log, [])
1113
}
1214

1315
beforeEach(() => {
1416
github = {
15-
request: jest.fn()
16-
// .mockResolvedValue({
17-
// data: [
18-
// { property_name: 'test', value: 'test' }
19-
// ]
20-
// })
17+
paginate: jest.fn(),
18+
repos: {
19+
getCustomPropertiesValues: jest.fn(),
20+
createOrUpdateCustomPropertiesValues: jest.fn()
21+
}
2122
}
23+
2224
log = { debug: jest.fn(), error: console.error }
2325
})
2426

25-
describe('sync', () => {
26-
it('syncs custom properties', async () => {
27-
const plugin = configure([
28-
{ name: 'test', value: 'test' }
29-
])
27+
describe('Custom Properties plugin', () => {
28+
it('should normalize entries when be instantiated', () => {
29+
const plugin = configure([{ name: 'Test', value: 'test' }])
30+
expect(plugin.entries).toEqual([{ name: 'test', value: 'test' }])
31+
})
3032

31-
github.request.mockResolvedValue({
32-
data: [
33-
{ property_name: 'test', value: 'test' }
34-
]
35-
})
33+
it('should fetch and normalize custom properties successfully', async () => {
34+
const mockResponse = [
35+
{ property_name: 'Test1', value: 'value1' },
36+
{ property_name: 'Test2', value: 'value2' }
37+
]
3638

37-
return plugin.sync().then(() => {
38-
expect(github.request).toHaveBeenCalledWith('GET /repos/:org/:repo/properties/values', {
39-
org: 'bkeepers',
40-
repo: 'test'
41-
})
42-
})
39+
github.paginate.mockResolvedValue(mockResponse)
40+
41+
const plugin = configure()
42+
const result = await plugin.find()
43+
44+
expect(github.paginate).toHaveBeenCalledWith(
45+
github.repos.getCustomPropertiesValues,
46+
{
47+
owner,
48+
repo,
49+
per_page: 100
50+
}
51+
)
52+
53+
expect(result).toEqual([
54+
{ name: 'test1', value: 'value1' },
55+
{ name: 'test2', value: 'value2' }
56+
])
4357
})
44-
})
45-
describe('sync', () => {
46-
it('add custom properties', async () => {
58+
59+
it('should sync', async () => {
60+
const mockResponse = [
61+
{ property_name: 'no-change', value: 'no-change' },
62+
{ property_name: 'new-value', value: '' },
63+
{ property_name: 'update-value', value: 'update-value' },
64+
{ property_name: 'delete-value', value: 'update-value' }
65+
]
66+
67+
github.paginate.mockResolvedValue(mockResponse)
68+
4769
const plugin = configure([
48-
{ name: 'test', value: 'test' }
70+
{ name: 'no-change', value: 'no-change' },
71+
{ name: 'new-value', value: 'new-value' },
72+
{ name: 'update-value', value: 'new-value' },
73+
{ name: 'delete-value', value: null }
4974
])
5075

51-
github.request.mockResolvedValue({
52-
data: []
53-
})
54-
5576
return plugin.sync().then(() => {
56-
expect(github.request).toHaveBeenNthCalledWith(1, 'GET /repos/:org/:repo/properties/values', {
57-
org: 'bkeepers',
58-
repo: 'test'
59-
})
60-
expect(github.request).toHaveBeenNthCalledWith(2, 'PATCH /repos/:org/:repo/properties/values', {
61-
org: 'bkeepers',
62-
repo: 'test',
77+
expect(github.paginate).toHaveBeenCalledWith(
78+
github.repos.getCustomPropertiesValues,
79+
{
80+
owner,
81+
repo,
82+
per_page: 100
83+
}
84+
)
85+
expect(github.repos.createOrUpdateCustomPropertiesValues).not.toHaveBeenCalledWith({
86+
owner,
87+
repo,
6388
properties: [
6489
{
65-
property_name: 'test',
66-
value: 'test'
90+
property_name: 'no-change',
91+
value: 'no-change'
6792
}
6893
]
6994
})
70-
})
71-
})
72-
})
73-
describe('sync', () => {
74-
it('remove custom properties', async () => {
75-
const plugin = configure([])
76-
77-
github.request.mockResolvedValue({
78-
data: [{ property_name: 'test', value: 'test' }]
79-
})
80-
81-
return plugin.sync().then(() => {
82-
expect(github.request).toHaveBeenNthCalledWith(1, 'GET /repos/:org/:repo/properties/values', {
83-
org: 'bkeepers',
84-
repo: 'test'
85-
})
86-
expect(github.request).toHaveBeenNthCalledWith(2, 'PATCH /repos/:org/:repo/properties/values', {
87-
org: 'bkeepers',
88-
repo: 'test',
95+
expect(github.repos.createOrUpdateCustomPropertiesValues).toHaveBeenCalledWith({
96+
owner,
97+
repo,
8998
properties: [
9099
{
91-
property_name: 'test',
92-
value: null
100+
property_name: 'new-value',
101+
value: 'new-value'
93102
}
94103
]
95104
})
96-
})
97-
})
98-
})
99-
describe('sync', () => {
100-
it('update custom properties', async () => {
101-
const plugin = configure([
102-
{ name: 'test', value: 'foobar' }
103-
])
104-
105-
github.request.mockResolvedValue({
106-
data: [{ property_name: 'test', value: 'test' }]
107-
})
108-
109-
return plugin.sync().then(() => {
110-
expect(github.request).toHaveBeenNthCalledWith(1, 'GET /repos/:org/:repo/properties/values', {
111-
org: 'bkeepers',
112-
repo: 'test'
105+
expect(github.repos.createOrUpdateCustomPropertiesValues).toHaveBeenCalledWith({
106+
owner,
107+
repo,
108+
properties: [
109+
{
110+
property_name: 'update-value',
111+
value: 'new-value'
112+
}
113+
]
113114
})
114-
expect(github.request).toHaveBeenNthCalledWith(2, 'PATCH /repos/:org/:repo/properties/values', {
115-
org: 'bkeepers',
116-
repo: 'test',
115+
expect(github.repos.createOrUpdateCustomPropertiesValues).toHaveBeenCalledWith({
116+
owner,
117+
repo,
117118
properties: [
118119
{
119-
property_name: 'test',
120-
value: 'foobar'
120+
property_name: 'delete-value',
121+
value: null
121122
}
122123
]
123124
})
124125
})
126+
127+
// const plugin = configure([{ name: 'Test', value: 'test' }])
128+
// await plugin.update({ name: 'test', value: 'old' }, { name: 'test', value: 'test' })
129+
130+
// expect(github.repos.createOrUpdateCustomPropertiesValues).toHaveBeenCalledWith({
131+
// owner,
132+
// repo,
133+
// properties: [
134+
// {
135+
// property_name: 'test',
136+
// value: 'test'
137+
// }
138+
// ]
139+
// })
125140
})
126141
})
127142
})

0 commit comments

Comments
 (0)